Beispiel #1
0
    def main(self, folder, message):
        commit_result = run_command_method_with_kwargs("commit",
                                                       folder=folder,
                                                       message=message)
        push_result = run_command_method_with_kwargs("push", folder=folder)

        return commit_result, push_result
Beispiel #2
0
    def test_push_basic(self):
        status_result = {
            'ready': {
                'files': [],
                'fields': {
                    'somefield': ('one', 'two', 'two', ),
                    'otherfield': ('one', 'three', 'three', )
                },
                'links': {},
            }
        }

        with patch.object(self.ticketfolder, 'status') as status:
            status.return_value = status_result
            with patch.object(self.ticketfolder.issue, 'update') as update:
                with patch('jirafs.commands.pull.Command.pull') as pull:
                    pull.return_value = True, True
                    run_command_method_with_kwargs(
                        'push',
                        folder=self.ticketfolder,
                    )

                self.assertEqual(1, len(update.call_args_list))
                self.assertEqual(
                    update.call_args,
                    call(
                        **{
                            field_name: value[1]
                            for field_name, value
                            in status_result['ready']['fields'].items()
                        }
                    )
                )
Beispiel #3
0
    def main(self, folder, message):
        commit_result = run_command_method_with_kwargs(
            'commit', folder=folder, message=message
        )
        push_result = run_command_method_with_kwargs(
            'push', folder=folder
        )

        return commit_result, push_result
Beispiel #4
0
    def test_push_no_changes(self):
        with patch.object(self.ticketfolder.issue, 'update') as update:
            with patch('jirafs.commands.pull.Command.pull') as pull:
                pull.return_value = True, True
                run_command_method_with_kwargs(
                    'push',
                    folder=self.ticketfolder,
                )

            self.assertEqual(0, len(update.call_args_list))
Beispiel #5
0
 def setUp(self):
     try:
         import jirafs_list_table  # noqa
     except ImportError:
         raise SkipTest("Push command macropatch tests require the "
                        "jira-list-table package to be installed.")
     super(TestPushCommandWithMacropatch, self).setUp()
     run_command_method_with_kwargs('plugins',
                                    folder=self.ticketfolder,
                                    args=Mock(enable='list_table', ))
Beispiel #6
0
    def clone_from_issue(self, match, ticket_url, path, jira):
        if not path:
            path = match.group(1)
        path = os.path.realpath(path)
        os.mkdir(path)
        folder = TicketFolder.initialize_ticket_folder(ticket_url, path, jira)

        utils.run_command_method_with_kwargs('pull', folder=folder)

        return folder
Beispiel #7
0
    def test_push_no_changes(self):
        with patch.object(self.ticketfolder.issue, "update") as update:
            with patch("jirafs.commands.pull.Command.main") as pull:
                pull.return_value = True, True
                run_command_method_with_kwargs(
                    "push",
                    folder=self.ticketfolder,
                )

            self.assertEqual(0, len(update.call_args_list))
Beispiel #8
0
    def clone_from_issue(self, match, ticket_url, path, jira):
        if not path:
            path = match.group(1)
        path = os.path.realpath(path)
        os.mkdir(path)
        folder = TicketFolder.initialize_ticket_folder(ticket_url, path, jira)

        utils.run_command_method_with_kwargs('pull', folder=folder)

        return folder
Beispiel #9
0
    def test_push_rejected_if_updated(self):
        src_path = self.get_asset_path("test_fetch/fetched.jira")
        dst_path = self.ticketfolder.get_shadow_path("fields.jira")
        shutil.copyfile(
            src_path, dst_path,
        )

        self.ticketfolder.run_git_command("add", "-A", shadow=True)
        self.ticketfolder.run_git_command("commit", "-m", "Changed", shadow=True)
        self.ticketfolder.run_git_command("push", "origin", "jira", shadow=True)
        with self.assertRaises(exceptions.LocalCopyOutOfDate):
            run_command_method_with_kwargs("push", folder=self.ticketfolder)
Beispiel #10
0
    def test_push_change_patched_content(self):
        # First, let's write out a patch
        description_one = u"""
            {list-table}
            * -
            ** Location
            ** Company
            * @coddingtonbear
            ** Portland, OR
            ** Urban Airship
            {list-table}
        """
        description_path = self.ticketfolder.get_path('description.jira')

        with io.open(description_path, 'w', encoding='utf-8') as out:
            out.write(description_one)

        run_command_method_with_kwargs(
            'commit',
            folder=self.ticketfolder,
            message='No me importa',
        )
        with patch.object(self.ticketfolder.issue, 'update'):
            with patch('jirafs.commands.pull.Command.pull') as pull:
                pull.return_value = True, True
                run_command_method_with_kwargs(
                    'push',
                    folder=self.ticketfolder,
                )

        description_two = u"""
            {list-table:horizontal}
            * -
            ** Location
            ** Company
            * @coddingtonbear
            ** Portland, OR
            ** Urban Airship
            * @ralphbean
            ** New York, NY
            ** RedHat
            {list-table}
        """

        with io.open(description_path, 'w', encoding='utf-8') as out:
            out.write(description_two)

        run_command_method_with_kwargs(
            'commit',
            folder=self.ticketfolder,
            message='No me importa',
        )
        with patch.object(self.ticketfolder.issue, 'update'):
            with patch('jirafs.commands.pull.Command.pull') as pull:
                pull.return_value = True, True
                run_command_method_with_kwargs(
                    'push',
                    folder=self.ticketfolder,
                )
Beispiel #11
0
    def test_push_change_patched_content(self):
        # First, let's write out a patch
        description_one = u"""
            {list-table}
            * -
            ** Location
            ** Company
            * @coddingtonbear
            ** Portland, OR
            ** Urban Airship
            {list-table}
        """
        description_path = self.ticketfolder.get_path('description.jira')

        with io.open(description_path, 'w', encoding='utf-8') as out:
            out.write(description_one)

        run_command_method_with_kwargs(
            'commit',
            folder=self.ticketfolder,
            message='No me importa',
        )
        with patch.object(self.ticketfolder.issue, 'update'):
            with patch('jirafs.commands.pull.Command.pull') as pull:
                pull.return_value = True, True
                run_command_method_with_kwargs(
                    'push',
                    folder=self.ticketfolder,
                )

        description_two = u"""
            {list-table:horizontal}
            * -
            ** Location
            ** Company
            * @coddingtonbear
            ** Portland, OR
            ** Urban Airship
            * @ralphbean
            ** New York, NY
            ** RedHat
            {list-table}
        """

        with io.open(description_path, 'w', encoding='utf-8') as out:
            out.write(description_two)

        run_command_method_with_kwargs(
            'commit',
            folder=self.ticketfolder,
            message='No me importa',
        )
        with patch.object(self.ticketfolder.issue, 'update'):
            with patch('jirafs.commands.pull.Command.pull') as pull:
                pull.return_value = True, True
                run_command_method_with_kwargs(
                    'push',
                    folder=self.ticketfolder,
                )
Beispiel #12
0
 def setUp(self):
     try:
         import jirafs_list_table  # noqa
     except ImportError:
         raise SkipTest(
             "Push command macropatch tests require the "
             "jira-list-table package to be installed."
         )
     super(TestPushCommandWithMacropatch, self).setUp()
     run_command_method_with_kwargs(
         'plugins',
         folder=self.ticketfolder,
         args=Mock(
             enable='list_table',
         )
     )
Beispiel #13
0
    def handle(self, args, jira, path, parser, **kwargs):
        server = args.server
        if not server:
            server = utils.get_default_jira_server()

        issue_data = {}

        for field in self.FIELDS:
            if getattr(args, field['name']) is not None:
                self.set_field_value(
                    issue_data, field, getattr(args, field['name'])
                )
            elif args.quiet:
                self.set_field_value(issue_data, field, field.get('default'))
            else:
                self.set_field_value(
                    issue_data,
                    field,
                    self.prompt_for_input(field)
                )

        jira_client = jira(server)
        issue = jira_client.create_issue(issue_data)

        return run_command_method_with_kwargs(
            'clone',
            path=None,
            url=issue.permalink(),
            jira=jira,
        )
Beispiel #14
0
    def test_fetch(self):
        self.ticketfolder._issue = (
            self.rehydrate_issue('test_fetch/fetched.json')
        )
        with patch.object(self.ticketfolder, 'clear_cache') as clear_cache:
            run_command_method_with_kwargs(
                'fetch',
                folder=self.ticketfolder,
            )
            self.assertTrue(clear_cache.called)

        expected_result = self.get_asset_contents('test_fetch/fetched.jira')
        with open(self.ticketfolder.get_shadow_path('fields.jira')) as _in:
            actual_result = _in.read()

        self.assertEqual(actual_result, expected_result)
Beispiel #15
0
    def main(self, args, jira, path, parser, **kwargs):
        server = args.server
        if not server:
            server = utils.get_default_jira_server()

        issue_data = {}

        for field in self.FIELDS:
            if getattr(args, field["name"]) is not None:
                self.set_field_value(issue_data, field,
                                     getattr(args, field["name"]))
            elif args.quiet:
                self.set_field_value(issue_data, field, field.get("default"))
            else:
                self.set_field_value(issue_data, field,
                                     self.prompt_for_input(field))

        jira_client = jira(server)
        issue = jira_client.create_issue(issue_data)

        return run_command_method_with_kwargs(
            "clone",
            path=None,
            url=issue.permalink(),
            jira=jira,
        )
Beispiel #16
0
    def test_push(self):
        changed_field = u"description"
        changed_value = u"Something Else"

        status = self.get_empty_status()
        status["ready"]["fields"][changed_field] = (
            u"Something",
            changed_value,
            changed_value,
        )
        with patch("jirafs.commands.pull.Command.main") as pull:
            with patch.object(self.ticketfolder, "status") as status_method:
                status_method.return_value = status
                with patch.object(self.ticketfolder.issue, "update") as out:
                    run_command_method_with_kwargs("push", folder=self.ticketfolder)
                    self.assertTrue(pull.called)
                    out.assert_called_with(**{"description": changed_value})
Beispiel #17
0
    def test_push(self):
        changed_field = 'description'
        changed_value = 'Something Else'

        status = self.get_empty_status()
        status['ready']['fields'][changed_field] = (
            'Something',
            changed_value,
        )
        with patch('jirafs.commands.pull.Command.pull') as pull:
            with patch.object(self.ticketfolder, 'status') as status_method:
                status_method.return_value = status
                with patch.object(self.ticketfolder.issue, 'update') as out:
                    run_command_method_with_kwargs('push',
                                                   folder=self.ticketfolder)
                    self.assertTrue(pull.called)
                    out.assert_called_with(**{'description': changed_value})
Beispiel #18
0
    def test_fetch(self):
        self.ticketfolder._issue = self.rehydrate_issue("test_fetch/fetched.json")
        with patch.object(self.ticketfolder, "clear_cache") as clear_cache:
            run_command_method_with_kwargs(
                "fetch", folder=self.ticketfolder,
            )
            self.assertTrue(clear_cache.called)

        expected_result = JiraFieldManager(
            self.get_asset_contents("test_fetch/fetched.jira")
        )
        with io.open(
            self.ticketfolder.get_shadow_path("fields.jira"), encoding="utf-8"
        ) as _in:
            actual_result = JiraFieldManager(_in.read())

        self.assertEqual(actual_result, expected_result)
Beispiel #19
0
    def test_push_rejected_if_updated(self):
        src_path = self.get_asset_path('test_fetch/fetched.jira')
        dst_path = self.ticketfolder.get_shadow_path('fields.jira')
        shutil.copyfile(
            src_path,
            dst_path,
        )

        self.ticketfolder.run_git_command('add', '-A', shadow=True)
        self.ticketfolder.run_git_command('commit',
                                          '-m',
                                          'Changed',
                                          shadow=True)
        self.ticketfolder.run_git_command('push',
                                          'origin',
                                          'jira',
                                          shadow=True)
        with self.assertRaises(exceptions.LocalCopyOutOfDate):
            run_command_method_with_kwargs('push', folder=self.ticketfolder)
Beispiel #20
0
    def test_push_rejected_if_updated(self):
        src_path = self.get_asset_path('test_fetch/fetched.jira')
        dst_path = self.ticketfolder.get_shadow_path('fields.jira')
        shutil.copyfile(
            src_path,
            dst_path,
        )

        self.ticketfolder.run_git_command('add', '-A', shadow=True)
        self.ticketfolder.run_git_command(
            'commit', '-m', 'Changed', shadow=True
        )
        self.ticketfolder.run_git_command(
            'push', 'origin', 'jira', shadow=True
        )
        with self.assertRaises(exceptions.LocalCopyOutOfDate):
            run_command_method_with_kwargs(
                'push',
                folder=self.ticketfolder
            )
Beispiel #21
0
    def test_push_basic(self):
        status_result = {
            "ready": {
                "files": [],
                "fields": {
                    "somefield": (
                        "one",
                        "two",
                        "two",
                    ),
                    "otherfield": (
                        "one",
                        "three",
                        "three",
                    ),
                },
                "links": {},
                "deleted": [],
            }
        }

        with patch.object(self.ticketfolder, "status") as status:
            status.return_value = status_result
            with patch.object(self.ticketfolder.issue, "update") as update:
                with patch("jirafs.commands.pull.Command.main") as pull:
                    pull.return_value = True, True
                    run_command_method_with_kwargs(
                        "push",
                        folder=self.ticketfolder,
                    )

                self.assertEqual(1, len(update.call_args_list))
                self.assertEqual(
                    update.call_args,
                    call(
                        **{
                            field_name: value[1]
                            for field_name, value in status_result["ready"]
                            ["fields"].items()
                        }),
                )
Beispiel #22
0
    def clone_from_issue(self, match, ticket_url, path, jira):
        if not path:
            path = match.group(1)
        path = os.path.realpath(path)
        os.mkdir(path)

        try:
            folder = TicketFolder.initialize_ticket_folder(
                ticket_url, path, jira)

            utils.run_command_method_with_kwargs("pull", folder=folder)
        except BaseException:
            shutil.rmtree(path)
            raise

        folder.log("Issue %s cloned successfully to %s", (
            folder.issue_url,
            folder.path,
        ))

        return folder
Beispiel #23
0
    def test_push(self):
        changed_field = 'description'
        changed_value = 'Something Else'

        status = self.get_empty_status()
        status['ready']['fields'][changed_field] = (
            'Something', changed_value,
        )
        with patch('jirafs.commands.pull.Command.pull') as pull:
            with patch.object(self.ticketfolder, 'status') as status_method:
                status_method.return_value = status
                with patch.object(self.ticketfolder.issue, 'update') as out:
                    run_command_method_with_kwargs(
                        'push',
                        folder=self.ticketfolder
                    )
                    self.assertTrue(pull.called)
                    out.assert_called_with(
                        **{
                            'description': changed_value
                        }
                    )
Beispiel #24
0
    def test_push_basic(self):
        status_result = {
            'ready': {
                'files': [],
                'fields': {
                    'somefield': (
                        'one',
                        'two',
                        'two',
                    ),
                    'otherfield': (
                        'one',
                        'three',
                        'three',
                    )
                },
                'links': {},
            }
        }

        with patch.object(self.ticketfolder, 'status') as status:
            status.return_value = status_result
            with patch.object(self.ticketfolder.issue, 'update') as update:
                with patch('jirafs.commands.pull.Command.main') as pull:
                    pull.return_value = True, True
                    run_command_method_with_kwargs(
                        'push',
                        folder=self.ticketfolder,
                    )

                self.assertEqual(1, len(update.call_args_list))
                self.assertEqual(
                    update.call_args,
                    call(
                        **{
                            field_name: value[1]
                            for field_name, value in status_result['ready']
                            ['fields'].items()
                        }))
Beispiel #25
0
    def clone_from_issue(self, match, ticket_url, path, jira):
        if not path:
            path = match.group(1)
        path = os.path.realpath(path)
        os.mkdir(path)

        try:
            folder = TicketFolder.initialize_ticket_folder(ticket_url, path, jira)

            utils.run_command_method_with_kwargs('pull', folder=folder)
        except Exception:
            shutil.rmtree(path)
            raise

        folder.log(
            "Issue %s cloned successfully to %s",
            (
                folder.issue_url,
                folder.path,
            )
        )

        return folder
Beispiel #26
0
    def setUp(self):
        self.arbitrary_ticket_number = "ALPHA-123"
        self.root_folder = tempfile.mkdtemp()
        self.mock_jira = mock.MagicMock()
        self.mock_jira.issue.return_value = self.rehydrate_issue("basic.issue.json")
        self.mock_get_jira = lambda _, config=None: self.mock_jira

        with patch(
            "jirafs.ticketfolder.TicketFolder.get_remotely_changed"
        ) as get_remotely_changed:
            get_remotely_changed.return_value = []
            self.ticketfolder = run_command_method_with_kwargs(
                "clone",
                url="http://arbitrary.com/browse/ALPHA-123",
                jira=self.mock_get_jira,
                path=os.path.join(self.root_folder, self.arbitrary_ticket_number,),
            )
Beispiel #27
0
    def main(self, folder, state_id):
        folder.jira.transition_issue(folder.issue, state_id)
        starting_status = folder.get_fields()["status"]
        pull_result = run_command_method_with_kwargs("pull", folder=folder)

        if starting_status == folder.get_fields()["status"]:
            # I'd love it if we could instead just check the response code
            # from the transitions API, but that API returns a 204 whether
            # or not the issue itself can be successfully transitioned.
            raise JiraInteractionFailed(
                "Jira was not able to successfully transition this issue "
                "into the requested state.  This type of failure usually "
                "occurs when one's Jira configuration requires that certain "
                "fields be specified before transitioning into a "
                "given state.  Unfortunately, no details regarding what "
                "fields may be required are provided via Jira's API.")

        return pull_result[1]
Beispiel #28
0
    def main(self, folder, state_id):
        folder.jira.transition_issue(folder.issue, state_id)
        starting_status = folder.get_fields()['status']
        pull_result = run_command_method_with_kwargs('pull', folder=folder)

        if starting_status == folder.get_fields()['status']:
            # I'd love it if we could instead just check the response code
            # from the transitions API, but that API returns a 204 whether
            # or not the issue itself can be successfully transitioned.
            raise JiraInteractionFailed(
                "JIRA was not able to successfully transition this issue "
                "into the requested state.  This type of failure usually "
                "occurs when one's JIRA configuration requires that certain "
                "fields be specified before transitioning into a "
                "given state.  Unfortunately, no details regarding what "
                "fields may be required are provided via JIRA's API."
            )

        return pull_result[1]
Beispiel #29
0
    def setUp(self):
        super(BaseCommandTestCase, self).setUp()
        self.arbitrary_ticket_number = 'ALPHA-123'
        self.root_folder = tempfile.mkdtemp()
        self.mock_jira = mock.MagicMock()
        self.mock_jira.issue.return_value = self.rehydrate_issue(
            'basic.issue.json')
        self.mock_get_jira = lambda _, config=None: self.mock_jira

        with patch('jirafs.ticketfolder.TicketFolder.get_remotely_changed'
                   ) as get_remotely_changed:
            get_remotely_changed.return_value = []
            self.ticketfolder = run_command_method_with_kwargs(
                'clone',
                url='http://arbitrary.com/browse/ALPHA-123',
                jira=self.mock_get_jira,
                path=os.path.join(
                    self.root_folder,
                    self.arbitrary_ticket_number,
                ))
Beispiel #30
0
    def main(
        self, folder, field_name, field_value, isjson,
        negate, raw, quiet, execute, execute_here
    ):
        actual_value = run_command_method_with_kwargs(
            'field',
            method='get_field_value_by_dotpath',
            folder=folder,
            field_name=field_name,
            raw=raw,
        )

        if isjson:
            field_value = json.loads(field_value)

        success = actual_value == field_value

        comparison_result = u" != "
        if success:
            comparison_result = u" == "
        message = u"{left} {comparison} {right}".format(
            left=actual_value,
            comparison=comparison_result,
            right=field_value,
        )

        if negate:
            success = not success

        if execute and success:
            execute = execute.replace('{}', folder.path)
            subprocess.call(
                execute,
                shell=True,
                cwd=os.getcwd() if execute_here else folder.path
            )

        return (
            message if not quiet else None,
            0 if success else 1,
        )
Beispiel #31
0
    def setUp(self):
        self.arbitrary_ticket_number = 'ALPHA-123'
        self.root_folder = tempfile.mkdtemp()
        self.mock_jira = mock.MagicMock()
        self.mock_jira.issue.return_value = self.rehydrate_issue(
            'basic.issue.json'
        )
        self.mock_get_jira = lambda _, config=None: self.mock_jira

        with patch(
            'jirafs.ticketfolder.TicketFolder.get_remotely_changed'
        ) as get_remotely_changed:
            get_remotely_changed.return_value = []
            self.ticketfolder = run_command_method_with_kwargs(
                'clone',
                url='http://arbitrary.com/browse/ALPHA-123',
                jira=self.mock_get_jira,
                path=os.path.join(
                    self.root_folder,
                    self.arbitrary_ticket_number,
                )
            )
Beispiel #32
0
    def main(self, folder, field_name, field_value, isjson, negate, raw, quiet,
             execute, execute_here):
        actual_value = run_command_method_with_kwargs(
            'field',
            method='get_field_value_by_dotpath',
            folder=folder,
            field_name=field_name,
            raw=raw,
        )

        if isjson:
            field_value = json.loads(field_value)

        success = actual_value == field_value

        comparison_result = u" != "
        if success:
            comparison_result = u" == "
        message = u"{left} {comparison} {right}".format(
            left=actual_value,
            comparison=comparison_result,
            right=field_value,
        )

        if negate:
            success = not success

        if execute and success:
            execute = execute.replace('{}', folder.path)
            subprocess.call(execute,
                            shell=True,
                            cwd=os.getcwd() if execute_here else folder.path)

        return (
            message if not quiet else None,
            0 if success else 1,
        )
Beispiel #33
0
    def main(self, folder, **kwargs):
        self.validate_issue(folder)
        with utils.stash_local_changes(folder):
            status = folder.status()

            if not folder.is_up_to_date():
                raise exceptions.LocalCopyOutOfDate(
                    "Your local copy is out-of-date.  You must use "
                    "the 'merge' command to update your local copy "
                    "before pushing changes.")

            file_meta = folder.get_remote_file_metadata(shadow=False)

            deleted = set()
            for filename in status["ready"]["deleted"]:
                folder.log(
                    'Deleting file "%s"',
                    (filename, ),
                )
                for attachment in folder.issue.fields.attachment:
                    if attachment.filename == filename and attachment.id not in deleted:
                        folder.jira.delete_attachment(attachment.id)
                        deleted.add(id)

            for filename in status["ready"]["files"]:
                upload = io.BytesIO(
                    folder.get_local_file_at_revision(filename,
                                                      "HEAD",
                                                      binary=True))
                folder.log(
                    'Uploading file "%s"',
                    (filename, ),
                )
                # Delete the existing issue if there is one
                for attachment in folder.issue.fields.attachment:
                    if attachment.filename == filename:
                        attachment.delete()
                upload.seek(0)
                attachment = folder.jira.add_attachment(
                    folder.ticket_number,
                    upload,
                    filename=filename,
                )
                file_meta[filename] = attachment.created

            folder.set_remote_file_metadata(file_meta, shadow=False)

            comment = folder.get_new_comment(clear=True, ready=True)
            if comment:
                folder.log(u'Adding comment "{comment}"'.format(
                    comment=self.truncate_field_value(comment)))
                folder.jira.add_comment(folder.ticket_number, comment)

            collected_updates = {}
            for field, diff_values in status["ready"]["fields"].items():
                collected_updates[field] = diff_values[1]

            if collected_updates:
                folder.log('Updating fields "%s"', (collected_updates, ))
                folder.issue.update(**collected_updates)

            links = status["ready"]["links"]
            statuses = self.get_valid_issue_link_types(folder)
            for target, data in links.get("issue", {}).items():
                orig = data[0]
                new = data[1]
                other = folder.jira.issue(target)
                if orig is None:
                    # New links
                    status_data = statuses[new["status"]]
                    args = [
                        status_data[1].name,
                    ]
                    if status_data[0] == "inward":
                        args.extend([other, folder.issue])
                    elif status_data[0] == "outward":
                        args.extend([folder.issue, other])
                    folder.jira.create_issue_link(*args)
                elif new is None:
                    # Deleted links
                    for existing_link in folder.issue.fields.issuelinks:
                        if (hasattr(existing_link, "inwardIssue")
                                and existing_link.inwardIssue.key == target):
                            existing_link.delete()
                        if (hasattr(existing_link, "outwardIssue")
                                and existing_link.outwardIssue.key == target):
                            existing_link.delete()
                else:
                    # Changed links
                    for existing_link in folder.issue.fields.issuelinks:
                        if (hasattr(existing_link, "inwardIssue")
                                and existing_link.inwardIssue.key == target):
                            existing_link.type = statuses[new["status"]][1]
                            existing_link.update()
                        if (hasattr(existing_link, "outwardIssue")
                                and existing_link.outwardIssue.key == target):
                            existing_link.type = statuses[new["status"]][1]
                            existing_link.update()

            links = status["ready"]["links"]
            remote_links = folder.jira.remote_links(folder.issue)
            # Workaround for bug in python-jira:
            folder.jira._applicationlinks = []
            for target, data in links.get("remote", {}).items():
                orig = data[0]
                new = data[1]
                if orig is None:
                    # New links
                    link_object = {
                        "url": target,
                        "title": new["description"],
                    }
                    folder.jira.add_remote_link(folder.issue, link_object)
                elif new is None:
                    # Deleted links
                    for existing_link in remote_links:
                        if existing_link.object.url == target:
                            existing_link.delete()
                else:
                    # Changed links
                    for existing_link in remote_links:
                        if existing_link.object.url == target:
                            existing_link.update({
                                "url": target,
                                "title": new["description"]
                            })

            # Commit local copy
            folder.run_git_command("reset", "--soft", failure_ok=True)
            folder.run_git_command(
                "add",
                folder.get_path(".jirafs/remote_files.json"),
                failure_ok=True)
            folder.run_git_command("add",
                                   folder.get_path(
                                       constants.TICKET_NEW_COMMENT),
                                   failure_ok=True)
            folder.run_git_command("commit",
                                   "-m",
                                   "Pushed local changes",
                                   failure_ok=True)

            # Commit changes to remote copy, too, so we record remote
            # file metadata.
            folder.run_git_command("fetch", shadow=True)
            folder.run_git_command("merge", "origin/master", shadow=True)
            folder.run_git_command("add", "-A", shadow=True)
            folder.run_git_command("commit",
                                   "-m",
                                   "Pulled remote changes",
                                   failure_ok=True,
                                   shadow=True)
            folder.run_git_command("push", "origin", "jira", shadow=True)
            pull_result = run_command_method_with_kwargs("pull", folder=folder)
            return pull_result[1]
Beispiel #34
0
 def run_command(self, name, **kwargs):
     return run_command_method_with_kwargs(name, **kwargs)
Beispiel #35
0
    def main(self, folder, **kwargs):
        fetch_result = run_command_method_with_kwargs('fetch', folder=folder)
        merge_result = run_command_method_with_kwargs('merge', folder=folder)

        return fetch_result, merge_result
Beispiel #36
0
 def run_command(self, name, **kwargs):
     return run_command_method_with_kwargs(name, **kwargs)
Beispiel #37
0
    def push(self, folder):
        self.validate_issue(folder)
        with utils.stash_local_changes(folder):
            status = folder.status()

            if not folder.is_up_to_date():
                raise exceptions.LocalCopyOutOfDate()

            file_meta = folder.get_remote_file_metadata(shadow=False)

            for filename in status['ready']['files']:
                upload = six.BytesIO(
                    folder.get_local_file_at_revision(
                        filename,
                        'HEAD',
                        binary=True
                    )
                )
                filename, upload = folder.execute_plugin_method_series(
                    'alter_file_upload',
                    args=((filename, upload, ), ),
                    single_response=True,
                )
                folder.log(
                    'Uploading file "%s"',
                    (filename, ),
                )
                # Delete the existing issue if there is one
                for attachment in folder.issue.fields.attachment:
                    if attachment.filename == filename:
                        attachment.delete()
                upload.seek(0)
                attachment = folder.jira.add_attachment(
                    folder.ticket_number,
                    upload,
                    filename=filename,
                )
                file_meta[filename] = attachment.created

            folder.set_remote_file_metadata(file_meta, shadow=False)

            comment = folder.get_new_comment(clear=True, ready=True)
            if comment:
                folder.log(
                    'Adding comment "%s..."' % comment[0:30].replace('%', '%%')
                )
                folder.jira.add_comment(folder.ticket_number, comment)

            collected_updates = {}
            for field, diff_values in status['ready']['fields'].items():
                collected_updates[field] = diff_values[1]

            if collected_updates:
                folder.log(
                    'Updating fields "%s"',
                    (collected_updates, )
                )
                folder.issue.update(**collected_updates)

            links = status['ready']['links']
            statuses = self.get_valid_issue_link_types(folder)
            for target, data in links.get('issue', {}).items():
                orig = data[0]
                new = data[1]
                other = folder.jira.issue(target)
                if orig is None:
                    # New links
                    status_data = statuses[new['status']]
                    args = [
                        status_data[1].name,
                    ]
                    if status_data[0] == 'inward':
                        args.extend([
                            other,
                            folder.issue
                        ])
                    elif status_data[0] == 'outward':
                        args.extend([
                            folder.issue,
                            other,
                        ])
                    folder.jira.create_issue_link(*args)
                elif new is None:
                    # Deleted links
                    for existing_link in folder.issue.fields.issuelinks:
                        if (
                            hasattr(existing_link, 'inwardIssue') and
                            existing_link.inwardIssue.key == target
                        ):
                            existing_link.delete()
                        if (
                            hasattr(existing_link, 'outwardIssue') and
                            existing_link.outwardIssue.key == target
                        ):
                            existing_link.delete()
                else:
                    # Changed links
                    for existing_link in folder.issue.fields.issuelinks:
                        if (
                            hasattr(existing_link, 'inwardIssue') and
                            existing_link.inwardIssue.key == target
                        ):
                            existing_link.type = statuses[new['status']][1]
                            existing_link.update()
                        if (
                            hasattr(existing_link, 'outwardIssue') and
                            existing_link.outwardIssue.key == target
                        ):
                            existing_link.type = statuses[new['status']][1]
                            existing_link.update()

            links = status['ready']['links']
            remote_links = folder.jira.remote_links(folder.issue)
            # Workaround for bug in python-jira:
            folder.jira._applicationlinks = []
            for target, data in links.get('remote', {}).items():
                orig = data[0]
                new = data[1]
                if orig is None:
                    # New links
                    link_object = {
                        'url': target,
                        'title': new['description'],
                    }
                    folder.jira.add_remote_link(folder.issue, link_object)
                elif new is None:
                    # Deleted links
                    for existing_link in remote_links:
                        if existing_link.object.url == target:
                            existing_link.delete()
                else:
                    # Changed links
                    for existing_link in remote_links:
                        if existing_link.object.url == target:
                            existing_link.update({
                                'url': target,
                                'title': new['description']
                            })

            # Commit local copy
            folder.run_git_command('reset', '--soft', failure_ok=True)
            folder.run_git_command(
                'add', '.jirafs/remote_files.json', failure_ok=True
            )
            folder.run_git_command(
                'add', constants.TICKET_NEW_COMMENT, failure_ok=True
            )
            folder.run_git_command(
                'commit', '-m', 'Pushed local changes', failure_ok=True
            )

            # Commit changes to remote copy, too, so we record remote
            # file metadata.
            folder.run_git_command('fetch', shadow=True)
            folder.run_git_command('merge', 'origin/master', shadow=True)
            folder.run_git_command('add', '-A', shadow=True)
            folder.run_git_command(
                'commit', '-m', 'Pulled remote changes',
                failure_ok=True, shadow=True
            )
            folder.run_git_command('push', 'origin', 'jira', shadow=True)
            pull_result = run_command_method_with_kwargs('pull', folder=folder)
            return pull_result[1]
Beispiel #38
0
    def main(self, folder, **kwargs):
        self.validate_issue(folder)
        with utils.stash_local_changes(folder):
            status = folder.status()

            if not folder.is_up_to_date():
                raise exceptions.LocalCopyOutOfDate()

            file_meta = folder.get_remote_file_metadata(shadow=False)

            for filename in status['ready']['files']:
                upload = six.BytesIO(
                    folder.get_local_file_at_revision(
                        filename,
                        'HEAD',
                        binary=True
                    )
                )
                filename, upload = folder.execute_plugin_method_series(
                    'alter_file_upload',
                    args=((filename, upload, ), ),
                    single_response=True,
                )
                folder.log(
                    'Uploading file "%s"',
                    (filename, ),
                )
                # Delete the existing issue if there is one
                for attachment in folder.issue.fields.attachment:
                    if attachment.filename == filename:
                        attachment.delete()
                upload.seek(0)
                attachment = folder.jira.add_attachment(
                    folder.ticket_number,
                    upload,
                    filename=filename,
                )
                file_meta[filename] = attachment.created

            folder.set_remote_file_metadata(file_meta, shadow=False)

            comment = folder.get_new_comment(clear=True, ready=True)
            if comment:
                folder.log(
                    u'Adding comment "{comment}"'.format(
                        comment=self.truncate_field_value(comment)
                    )
                )
                folder.jira.add_comment(folder.ticket_number, comment)

            collected_updates = {}
            for field, diff_values in status['ready']['fields'].items():
                collected_updates[field] = diff_values[1]

            if collected_updates:
                folder.log(
                    'Updating fields "%s"',
                    (collected_updates, )
                )
                folder.issue.update(**collected_updates)

            links = status['ready']['links']
            statuses = self.get_valid_issue_link_types(folder)
            for target, data in links.get('issue', {}).items():
                orig = data[0]
                new = data[1]
                other = folder.jira.issue(target)
                if orig is None:
                    # New links
                    status_data = statuses[new['status']]
                    args = [
                        status_data[1].name,
                    ]
                    if status_data[0] == 'inward':
                        args.extend([
                            other,
                            folder.issue
                        ])
                    elif status_data[0] == 'outward':
                        args.extend([
                            folder.issue,
                            other,
                        ])
                    folder.jira.create_issue_link(*args)
                elif new is None:
                    # Deleted links
                    for existing_link in folder.issue.fields.issuelinks:
                        if (
                            hasattr(existing_link, 'inwardIssue') and
                            existing_link.inwardIssue.key == target
                        ):
                            existing_link.delete()
                        if (
                            hasattr(existing_link, 'outwardIssue') and
                            existing_link.outwardIssue.key == target
                        ):
                            existing_link.delete()
                else:
                    # Changed links
                    for existing_link in folder.issue.fields.issuelinks:
                        if (
                            hasattr(existing_link, 'inwardIssue') and
                            existing_link.inwardIssue.key == target
                        ):
                            existing_link.type = statuses[new['status']][1]
                            existing_link.update()
                        if (
                            hasattr(existing_link, 'outwardIssue') and
                            existing_link.outwardIssue.key == target
                        ):
                            existing_link.type = statuses[new['status']][1]
                            existing_link.update()

            links = status['ready']['links']
            remote_links = folder.jira.remote_links(folder.issue)
            # Workaround for bug in python-jira:
            folder.jira._applicationlinks = []
            for target, data in links.get('remote', {}).items():
                orig = data[0]
                new = data[1]
                if orig is None:
                    # New links
                    link_object = {
                        'url': target,
                        'title': new['description'],
                    }
                    folder.jira.add_remote_link(folder.issue, link_object)
                elif new is None:
                    # Deleted links
                    for existing_link in remote_links:
                        if existing_link.object.url == target:
                            existing_link.delete()
                else:
                    # Changed links
                    for existing_link in remote_links:
                        if existing_link.object.url == target:
                            existing_link.update({
                                'url': target,
                                'title': new['description']
                            })

            # Commit local copy
            folder.run_git_command('reset', '--soft', failure_ok=True)
            folder.run_git_command(
                'add',
                folder.get_path('.jirafs/remote_files.json'),
                failure_ok=True
            )
            folder.run_git_command(
                'add',
                folder.get_path(constants.TICKET_NEW_COMMENT),
                failure_ok=True
            )
            folder.run_git_command(
                'commit', '-m', 'Pushed local changes', failure_ok=True
            )

            # Apply macros and record the changes so we can reverse
            # them a little later.
            macro_patch_filename = folder.get_path(
                '.jirafs/macros_applied.patch'
            )
            folder.run_git_command(
                'apply',
                macro_patch_filename,
                failure_ok=True
            )
            fields = folder.get_fields()
            for field, value in collected_updates.items():
                fields[field] = value
            fields.write()

            field_data_files = fields.get_field_data_files()
            result = folder.run_git_command('diff', *field_data_files)
            if result.strip():
                with io.open(macro_patch_filename, 'w', encoding='utf-8') as o:
                    o.write(result)
                    o.write(u'\n\n')
                folder.run_git_command(
                    'add',
                    macro_patch_filename,
                    failure_ok=True
                )
                folder.run_git_command(
                    'commit', '-m', 'Updating macro patch', failure_ok=True
                )
                # Re-set the applied changes we just made above
                folder.run_git_command(
                    'checkout', '--', '.'
                )
            else:
                with io.open(macro_patch_filename, 'w', encoding='utf-8') as o:
                    o.write(u'\n\n')

            # Commit changes to remote copy, too, so we record remote
            # file metadata.
            folder.run_git_command('fetch', shadow=True)
            folder.run_git_command('merge', 'origin/master', shadow=True)
            folder.run_git_command('add', '-A', shadow=True)
            folder.run_git_command(
                'commit', '-m', 'Pulled remote changes',
                failure_ok=True, shadow=True
            )
            folder.run_git_command('push', 'origin', 'jira', shadow=True)
            pull_result = run_command_method_with_kwargs('pull', folder=folder)
            return pull_result[1]
Beispiel #39
0
    def push(self, folder):
        with utils.stash_local_changes(folder):
            status = folder.status()

            if not folder.is_up_to_date():
                raise exceptions.LocalCopyOutOfDate()

            file_meta = folder.get_remote_file_metadata(shadow=False)

            for filename in status['ready']['files']:
                upload = six.BytesIO(
                    folder.get_local_file_at_revision(
                        filename,
                        'HEAD',
                        binary=True
                    )
                )
                filename, upload = folder.execute_plugin_method_series(
                    'alter_file_upload',
                    args=((filename, upload, ), ),
                    single_response=True,
                )
                folder.log(
                    'Uploading file "%s"',
                    (filename, ),
                )
                # Delete the existing issue if there is one
                for attachment in folder.issue.fields.attachment:
                    if attachment.filename == filename:
                        attachment.delete()
                upload.seek(0)
                attachment = folder.jira.add_attachment(
                    folder.ticket_number,
                    upload,
                    filename=filename,
                )
                file_meta[filename] = attachment.created

            folder.set_remote_file_metadata(file_meta, shadow=False)

            comment = folder.get_new_comment(clear=True, ready=True)
            if comment:
                folder.log(
                    'Adding comment "%s..."' % comment[0:30].replace('%', '%%')
                )
                folder.jira.add_comment(folder.ticket_number, comment)

            collected_updates = {}
            for field, diff_values in status['ready']['fields'].items():
                collected_updates[field] = diff_values[1]

            if collected_updates:
                folder.log(
                    'Updating fields "%s"',
                    (collected_updates, )
                )
                folder.issue.update(**collected_updates)

            # Commit local copy
            folder.run_git_command('reset', '--soft', failure_ok=True)
            folder.run_git_command(
                'add', '.jirafs/remote_files.json', failure_ok=True
            )
            folder.run_git_command(
                'add', constants.TICKET_NEW_COMMENT, failure_ok=True
            )
            folder.run_git_command(
                'commit', '-m', 'Pushed local changes', failure_ok=True
            )

            # Commit changes to remote copy, too, so we record remote
            # file metadata.
            folder.run_git_command('fetch', shadow=True)
            folder.run_git_command('merge', 'origin/master', shadow=True)
            folder.run_git_command('add', '-A', shadow=True)
            folder.run_git_command(
                'commit', '-m', 'Pulled remote changes',
                failure_ok=True, shadow=True
            )
            folder.run_git_command('push', 'origin', 'jira', shadow=True)
            pull_result = run_command_method_with_kwargs('pull', folder=folder)
            return pull_result[1]
Beispiel #40
0
    def main(self, folder, **kwargs):
        self.validate_issue(folder)
        with utils.stash_local_changes(folder):
            status = folder.status()

            if not folder.is_up_to_date():
                raise exceptions.LocalCopyOutOfDate(
                    "Your local copy is out-of-date.  You must use "
                    "the 'merge' command to update your local copy "
                    "before pushing changes."
                )

            file_meta = folder.get_remote_file_metadata(shadow=False)

            for filename in status['ready']['files']:
                upload = six.BytesIO(
                    folder.get_local_file_at_revision(
                        filename,
                        'HEAD',
                        binary=True
                    )
                )
                filename, upload = folder.execute_plugin_method_series(
                    'alter_file_upload',
                    args=((filename, upload, ), ),
                    single_response=True,
                )
                folder.log(
                    'Uploading file "%s"',
                    (filename, ),
                )
                # Delete the existing issue if there is one
                for attachment in folder.issue.fields.attachment:
                    if attachment.filename == filename:
                        attachment.delete()
                upload.seek(0)
                attachment = folder.jira.add_attachment(
                    folder.ticket_number,
                    upload,
                    filename=filename,
                )
                file_meta[filename] = attachment.created

            folder.set_remote_file_metadata(file_meta, shadow=False)

            comment = folder.get_new_comment(clear=True, ready=True)
            if comment:
                folder.log(
                    u'Adding comment "{comment}"'.format(
                        comment=self.truncate_field_value(comment)
                    )
                )
                folder.jira.add_comment(folder.ticket_number, comment)

            collected_updates = {}
            for field, diff_values in status['ready']['fields'].items():
                collected_updates[field] = diff_values[1]

            if collected_updates:
                folder.log(
                    'Updating fields "%s"',
                    (collected_updates, )
                )
                folder.issue.update(**collected_updates)

            links = status['ready']['links']
            statuses = self.get_valid_issue_link_types(folder)
            for target, data in links.get('issue', {}).items():
                orig = data[0]
                new = data[1]
                other = folder.jira.issue(target)
                if orig is None:
                    # New links
                    status_data = statuses[new['status']]
                    args = [
                        status_data[1].name,
                    ]
                    if status_data[0] == 'inward':
                        args.extend([
                            other,
                            folder.issue
                        ])
                    elif status_data[0] == 'outward':
                        args.extend([
                            folder.issue,
                            other,
                        ])
                    folder.jira.create_issue_link(*args)
                elif new is None:
                    # Deleted links
                    for existing_link in folder.issue.fields.issuelinks:
                        if (
                            hasattr(existing_link, 'inwardIssue') and
                            existing_link.inwardIssue.key == target
                        ):
                            existing_link.delete()
                        if (
                            hasattr(existing_link, 'outwardIssue') and
                            existing_link.outwardIssue.key == target
                        ):
                            existing_link.delete()
                else:
                    # Changed links
                    for existing_link in folder.issue.fields.issuelinks:
                        if (
                            hasattr(existing_link, 'inwardIssue') and
                            existing_link.inwardIssue.key == target
                        ):
                            existing_link.type = statuses[new['status']][1]
                            existing_link.update()
                        if (
                            hasattr(existing_link, 'outwardIssue') and
                            existing_link.outwardIssue.key == target
                        ):
                            existing_link.type = statuses[new['status']][1]
                            existing_link.update()

            links = status['ready']['links']
            remote_links = folder.jira.remote_links(folder.issue)
            # Workaround for bug in python-jira:
            folder.jira._applicationlinks = []
            for target, data in links.get('remote', {}).items():
                orig = data[0]
                new = data[1]
                if orig is None:
                    # New links
                    link_object = {
                        'url': target,
                        'title': new['description'],
                    }
                    folder.jira.add_remote_link(folder.issue, link_object)
                elif new is None:
                    # Deleted links
                    for existing_link in remote_links:
                        if existing_link.object.url == target:
                            existing_link.delete()
                else:
                    # Changed links
                    for existing_link in remote_links:
                        if existing_link.object.url == target:
                            existing_link.update({
                                'url': target,
                                'title': new['description']
                            })

            # Commit local copy
            folder.run_git_command('reset', '--soft', failure_ok=True)
            folder.run_git_command(
                'add',
                folder.get_path('.jirafs/remote_files.json'),
                failure_ok=True
            )
            folder.run_git_command(
                'add',
                folder.get_path(constants.TICKET_NEW_COMMENT),
                failure_ok=True
            )
            folder.run_git_command(
                'commit', '-m', 'Pushed local changes', failure_ok=True
            )

            # Apply macros and record the changes so we can reverse
            # them a little later.
            macro_patch_filename = folder.get_path(
                '.jirafs/macros_applied.patch'
            )
            folder.run_git_command(
                'apply',
                macro_patch_filename,
                failure_ok=True
            )
            fields = folder.get_fields()
            for field, value in collected_updates.items():
                fields[field] = value
            fields.write()

            field_data_files = fields.get_field_data_files()
            result = folder.run_git_command('diff', *field_data_files)
            if result.strip():
                with io.open(macro_patch_filename, 'w', encoding='utf-8') as o:
                    o.write(result)
                    o.write(u'\n\n')
                folder.run_git_command(
                    'add',
                    macro_patch_filename,
                    failure_ok=True
                )
                folder.run_git_command(
                    'commit', '-m', 'Updating macro patch', failure_ok=True
                )
                # Re-set the applied changes we just made above
                folder.run_git_command(
                    'checkout', '--', '.'
                )
            else:
                with io.open(macro_patch_filename, 'w', encoding='utf-8') as o:
                    o.write(u'\n\n')

            # Commit changes to remote copy, too, so we record remote
            # file metadata.
            folder.run_git_command('fetch', shadow=True)
            folder.run_git_command('merge', 'origin/master', shadow=True)
            folder.run_git_command('add', '-A', shadow=True)
            folder.run_git_command(
                'commit', '-m', 'Pulled remote changes',
                failure_ok=True, shadow=True
            )
            folder.run_git_command('push', 'origin', 'jira', shadow=True)
            pull_result = run_command_method_with_kwargs('pull', folder=folder)
            return pull_result[1]