Exemple #1
0
    def get_commits(self, repository, start=None):
        results = []

        resource = "commits"
        url = self._build_api_url(self._get_repo_api_url(repository), resource)

        if start:
            url += "&sha=%s" % start

        try:
            rsp = self._api_get(url)
        except Exception as e:
            logging.warning("Failed to fetch commits from %s: %s", url, e)
            return results

        for item in rsp:
            commit = Commit(
                item["commit"]["author"]["name"],
                item["sha"],
                item["commit"]["committer"]["date"],
                item["commit"]["message"],
            )
            if item["parents"]:
                commit.parent = item["parents"][0]["sha"]

            results.append(commit)

        return results
Exemple #2
0
    def get_change(self, revision, cache_key):
        """Get an individual change.

        This returns a tuple with the commit message and the diff contents.
        """
        revision = int(revision)

        commit = cache.get(cache_key)
        if commit:
            message = commit.message
            author_name = commit.author_name
            date = commit.date
            base_revision = commit.parent
        else:
            commits = list(self.ra.iter_log(None, revision, 0, limit=2))
            rev, props = commits[0][1:3]
            message = props[SVN_LOG]
            author_name = props[SVN_AUTHOR]
            date = props[SVN_DATE]

            if len(commits) > 1:
                base_revision = commits[1][1]
            else:
                base_revision = 0

        out, err = self.client.diff(base_revision,
                                    revision,
                                    self.repopath,
                                    self.repopath,
                                    diffopts=DIFF_UNIFIED)

        commit = Commit(author_name, six.text_type(revision), date, message,
                        six.text_type(base_revision))
        commit.diff = out.read()
        return commit
Exemple #3
0
    def get_commits(self, repository, start=None):
        results = []

        resource = 'commits'
        url = self._build_api_url(self._get_repo_api_url(repository), resource)

        if start:
            url += '&sha=%s' % start

        try:
            rsp = self._api_get(url)
        except Exception as e:
            logging.warning('Failed to fetch commits from %s: %s', url, e)
            return results

        for item in rsp:
            commit = Commit(item['commit']['author']['name'], item['sha'],
                            item['commit']['committer']['date'],
                            item['commit']['message'])
            if item['parents']:
                commit.parent = item['parents'][0]['sha']

            results.append(commit)

        return results
Exemple #4
0
    def get_commits(self, start):
        """Returns a list of commits."""
        commits = self.client.log(self.repopath,
                                  revision_start=Revision(
                                      opt_revision_kind.number, int(start)),
                                  limit=31)

        results = []

        # We fetch one more commit than we care about, because the entries in
        # the svn log doesn't include the parent revision.
        for i in range(len(commits) - 1):
            commit = commits[i]
            parent = commits[i + 1]

            date = datetime.utcfromtimestamp(commit['date'])
            results.append(
                Commit(commit.get('author', ''),
                       six.text_type(commit['revision'].number),
                       date.isoformat(), commit['message'],
                       six.text_type(parent['revision'].number)))

        # If there were fewer than 31 commits fetched, also include the last
        # one in the list so we don't leave off the initial revision.
        if len(commits) < 31:
            commit = commits[-1]
            date = datetime.utcfromtimestamp(commit['date'])
            results.append(
                Commit(commit['author'],
                       six.text_type(commit['revision'].number),
                       date.isoformat(), commit['message']))

        return results
Exemple #5
0
    def get_commits(self, repository, branch=None, start=None):
        url = self._build_repository_api_url(repository,
                                             'changesets/?limit=20')

        start = start or branch

        if start:
            url += '&start=%s' % start

        results = []

        # The API returns them in order from oldest to newest.
        for changeset in reversed(self._api_get(url)['changesets']):
            commit = Commit(
                author_name=changeset['author'],
                id=changeset['raw_node'],
                date=self._parse_timestamp(changeset['utctimestamp']),
                message=changeset['message'],
                base_commit_id=changeset['raw_node'])

            if changeset['parents']:
                commit.parent = changeset['parents'][0]

            results.append(commit)

        return results
    def test_get_commits(self):
        """Testing Gerrit.get_commits"""
        payload = self._make_json_rsp([
            {
                'message': 'Backport a fix for screenshot commenting.\n',
                'revision': '77c174669b7018936f16b98547445624c6738e1e',
                'author': 'David Trowbridge',
                'parents': [
                    'ecfbf578d31f550a135580cee26fa20fbaea36d9',
                ],
                'time': '2016-09-05T23:28:30-07:00',
            },
            {
                'message': 'Fix some issues with screenshot commenting.'
                '\n',
                'revision': '8a39b87f0124f27225234014a87914e434b223a9',
                'author': 'David Trowbridge',
                'parents': [
                    '3fb32c83993cd8c07fbbb605cf0cc523010da7c8',
                ],
                'time': '2016-09-05T22:58:29-07:00',
            },
            {
                'message': 'Fix draggability of the comment dialog.\n',
                'revision': '3fb32c83993cd8c07fbbb605cf0cc523010da7c8',
                'author': 'David Trowbridge',
                'parents': [
                    '7619f51371b55bfcdf4cb3fccf5d3c76bf5002c0',
                ],
                'time': '2016-09-05T22:47:55-07:00',
            },
        ])

        with self.setup_http_test(payload=payload,
                                  expected_http_calls=1) as ctx:
            commits = ctx.service.get_commits(ctx.create_repository())

        ctx.assertHTTPCall(
            0, url='http://gerrit.example.com/a/projects/Project/all-commits/')

        self.assertEqual(commits, [
            Commit(author_name='David Trowbridge',
                   id='77c174669b7018936f16b98547445624c6738e1e',
                   date='2016-09-05T23:28:30-07:00',
                   message='Backport a fix for screenshot commenting.\n',
                   parent='ecfbf578d31f550a135580cee26fa20fbaea36d9'),
            Commit(author_name='David Trowbridge',
                   id='8a39b87f0124f27225234014a87914e434b223a9',
                   date='2016-09-05T22:58:29-07:00',
                   message='Fix some issues with screenshot commenting.\n',
                   parent='3fb32c83993cd8c07fbbb605cf0cc523010da7c8'),
            Commit(author_name='David Trowbridge',
                   id='3fb32c83993cd8c07fbbb605cf0cc523010da7c8',
                   date='2016-09-05T22:47:55-07:00',
                   message='Fix draggability of the comment dialog.\n',
                   parent='7619f51371b55bfcdf4cb3fccf5d3c76bf5002c0'),
        ])

        for commit in commits:
            self.assertIsNone(commit.diff)
Exemple #7
0
    def get_change(self, revision):
        """Get an individual change.

        This returns a Commit object containing the details of the commit.
        """
        revision = int(revision)

        commits = self.client.get_log('/', start=revision, limit=2)

        commit = commits[0]
        message = commit.get('message', b'').decode('utf-8', 'replace')
        author_name = commit.get('author', b'').decode('utf-8', 'replace')
        date = commit['date'].isoformat()

        if len(commits) > 1:
            base_revision = commits[1]['revision']
        else:
            base_revision = 0

        try:
            enc, diff = convert_to_unicode(
                self.client.diff(base_revision, revision),
                self.repository.get_encoding_list())
        except Exception as e:
            raise self.normalize_error(e)

        commit = Commit(author_name, six.text_type(revision), date, message,
                        six.text_type(base_revision))
        commit.diff = diff

        return commit
Exemple #8
0
    def get_commits(self, repository, branch=None, start=None):
        url = self._build_repository_api_url(repository,
                                             'changesets/?limit=20')

        start = start or branch

        if start:
            url += '&start=%s' % start

        results = []

        # The API returns them in order from oldest to newest.
        for changeset in reversed(self._api_get(url)['changesets']):
            commit = Commit(author_name=changeset['author'],
                            id=changeset['raw_node'],
                            date=self._parse_timestamp(
                                changeset['utctimestamp']),
                            message=changeset['message'],
                            base_commit_id=changeset['raw_node'])

            if changeset['parents']:
                commit.parent = changeset['parents'][0]

            results.append(commit)

        return results
    def get_change(self, revision):
        """Get an individual change.

        This returns a Commit object containing the details of the commit.
        """
        revision = int(revision)

        commits = self.client.get_log('/', start=revision, limit=2)

        commit = commits[0]
        message = commit.get('message', b'').decode('utf-8', 'replace')
        author_name = commit.get('author', b'').decode('utf-8', 'replace')
        date = commit['date'].isoformat()

        if len(commits) > 1:
            base_revision = commits[1]['revision']
        else:
            base_revision = 0

        try:
            enc, diff = convert_to_unicode(
                self.client.diff(base_revision, revision),
                self.repository.get_encoding_list())
        except Exception as e:
            raise self.normalize_error(e)

        commit = Commit(author_name, six.text_type(revision), date,
                        message, six.text_type(base_revision))
        commit.diff = diff

        return commit
    def _parse_commit(self, meta, diff=None):
        """Parse and return the meta response and return a Commit.

        Args:
            meta (dict):
                A member of the JSON response from the ``all-commits``
                endpoint corresponding to a single commit.

            diff (bytes, optional):
                The diff corresponding to the commit.

        Returns:
            reviewboard.scmtools.core.Commit:
            The parsed commit.
        """
        commit = Commit(
            author_name=meta['author'],
            id=meta['revision'],
            date=meta['time'],
            message=meta['message'],
            diff=diff
        )

        if meta['parents']:
            commit.parent = meta['parents'][0]

        return commit
Exemple #11
0
    def get_commits(self, repository, start=None):
        results = []

        resource = 'commits'
        url = self._build_api_url(self._get_repo_api_url(repository), resource)

        if start:
            url += '&sha=%s' % start

        try:
            rsp = self._api_get(url)
        except Exception as e:
            logging.warning('Failed to fetch commits from %s: %s',
                            url, e)
            return results

        for item in rsp:
            commit = Commit(
                item['commit']['author']['name'],
                item['sha'],
                item['commit']['committer']['date'],
                item['commit']['message'])
            if item['parents']:
                commit.parent = item['parents'][0]['sha']

            results.append(commit)

        return results
    def get_change(self, revision, cache_key):
        """Get an individual change.

        This returns a tuple with the commit message and the diff contents.
        """
        revision = int(revision)

        commit = cache.get(cache_key)
        if commit:
            message = commit.message
            author_name = commit.author_name
            date = commit.date
            base_revision = commit.parent
        else:
            commits = list(self.ra.iter_log(None, revision, 0, limit=2))
            rev, props = commits[0][1:3]
            message = props[SVN_LOG]
            author_name = props[SVN_AUTHOR]
            date = props[SVN_DATE]

            if len(commits) > 1:
                base_revision = commits[1][1]
            else:
                base_revision = 0

        out, err = self.client.diff(base_revision, revision, self.repopath,
                                    self.repopath, diffopts=DIFF_UNIFIED)

        commit = Commit(author_name, six.text_type(revision), date,
                        message, six.text_type(base_revision))
        commit.diff = out.read()
        return commit
Exemple #13
0
    def get_commits(self, branch=None, start=None):
        """Return a list of commits."""
        commits = self.client.get_log(branch or '/',
                                      start=start,
                                      limit=self.COMMITS_PAGE_LIMIT,
                                      limit_to_path=False)

        results = []

        # We fetch one more commit than we care about, because the entries in
        # the svn log doesn't include the parent revision.
        for i in range(len(commits) - 1):
            commit = commits[i]
            parent = commits[i + 1]

            results.append(
                Commit(commit.get('author', ''),
                       commit['revision'], commit['date'].isoformat(),
                       commit.get('message', ''), parent['revision']))

        # If there were fewer than the requested number of commits fetched,
        # also include the last one in the list so we don't leave off the
        # initial revision.
        if len(commits) < self.COMMITS_PAGE_LIMIT:
            commit = commits[-1]
            results.append(
                Commit(commit.get('author', ''), commit['revision'],
                       commit['date'].isoformat(), commit.get('message', '')))

        return results
Exemple #14
0
    def _parse_commit(self, meta, diff=None):
        """Parse and return the meta response and return a Commit.

        Args:
            meta (dict):
                A member of the JSON response from the ``all-commits``
                endpoint corresponding to a single commit.

            diff (bytes, optional):
                The diff corresponding to the commit.

        Returns:
            reviewboard.scmtools.core.Commit:
            The parsed commit.
        """
        commit = Commit(
            author_name=meta['author'],
            id=meta['revision'],
            date=meta['time'],
            message=meta['message'],
            diff=diff
        )

        if meta['parents']:
            commit.parent = meta['parents'][0]

        return commit
Exemple #15
0
    def test_get_commits_with_branch(self):
        """Testing SVN (<backend>) get_commits with branch"""
        commits = self.tool.get_commits(branch='/branches/branch1', start='5')

        self.assertEqual(len(commits), 5)
        self.assertEqual(
            commits[0],
            Commit('chipx86',
                   '5',
                   '2010-05-21T09:33:40.893946',
                   'Add an unterminated keyword for testing bug #1523\n',
                   '4'))

        commits = self.tool.get_commits(branch='/branches/branch1', start='7')
        self.assertEqual(len(commits), 6)
        self.assertEqual(
            commits[0],
            Commit('david',
                   '7',
                   '2013-06-13T07:43:27.259554',
                   'Add a branch',
                   '5'))
        self.assertEqual(
            commits[1],
            Commit('chipx86',
                   '5',
                   '2010-05-21T09:33:40.893946',
                   'Add an unterminated keyword for testing bug #1523\n',
                   '4'))
        def get_change(repository, commit_to_get):
            commit = Commit(
                message='* This is a summary\n\n* This is a description.')
            diff_filename = os.path.join(self.testdata_dir, 'git_readme.diff')

            with open(diff_filename, 'r') as f:
                commit.diff = f.read()

            return commit
        def get_change(repository, commit_to_get):
            commit = Commit(
                message='* This is a summary\n\n* This is a description.')
            diff_filename = os.path.join(self.testdata_dir, 'git_readme.diff')

            with open(diff_filename, 'r') as f:
                commit.diff = f.read()

            return commit
        def get_change(repository, commit_to_get):
            self.assertEqual(commit_id, commit_to_get)

            commit = Commit(message='This is my commit message\n\n'
                                    'With a summary line too.')
            diff_filename = os.path.join(self.testdata_dir, 'git_readme.diff')

            with open(diff_filename, 'r') as f:
                commit.diff = f.read()

            return commit
        def get_change(repository, commit_to_get):
            self.assertEqual(commit_id, commit_to_get)

            commit = Commit(message='This is my commit message\n\n'
                            'With a summary line too.')
            diff_filename = os.path.join(self.testdata_dir, 'git_readme.diff')

            with open(diff_filename, 'r') as f:
                commit.diff = f.read()

            return commit
Exemple #20
0
    def get_commits(self, repository, branch=None, start=None):
        repo_api_url = self._get_repo_api_url(repository)
        commits = self.client.api_get_commits(repo_api_url, start=start)

        results = []
        for item in commits:
            commit = Commit(item['commit']['author']['name'], item['sha'],
                            item['commit']['committer']['date'],
                            item['commit']['message'])
            if item['parents']:
                commit.parent = item['parents'][0]['sha']

            results.append(commit)

        return results
Exemple #21
0
    def get_change(self, revision):
        """Get an individual change.

        This returns a tuple with the commit message and the diff contents.
        """
        cache_key = self.repository.get_commit_cache_key(revision)

        revision = int(revision)
        head_revision = Revision(opt_revision_kind.number, revision)

        commit = cache.get(cache_key)
        if commit:
            message = commit.message
            author_name = commit.author_name
            date = commit.date
            base_revision = Revision(opt_revision_kind.number, commit.parent)
        else:
            commits = self.client.log(
                self.repopath,
                revision_start=head_revision,
                limit=2)
            commit = commits[0]
            message = commit['message']
            author_name = commit['author']
            date = datetime.datetime.utcfromtimestamp(commit['date']).\
                isoformat()

            try:
                commit = commits[1]
                base_revision = commit['revision']
            except IndexError:
                base_revision = Revision(opt_revision_kind.number, 0)

        tmpdir = mkdtemp(prefix='reviewboard-svn.')

        diff = self.client.diff(
            tmpdir,
            self.repopath,
            revision1=base_revision,
            revision2=head_revision,
            diff_options=['-u'])

        rmtree(tmpdir)

        commit = Commit(author_name, six.text_type(head_revision.number), date,
                        message, six.text_type(base_revision.number))
        commit.diff = diff
        return commit
Exemple #22
0
    def get_commits(self, repository, branch=None, start=None):
        if start is not None:
            url = ('%s/repos/%s/branches/%s/commits?start=%s'
                   % (self.account.hosting_url,
                      repository.extra_data['rbgateway_repo_name'],
                      branch,
                      start))
        else:
            url = ('%s/repos/%s/branches/%s/commits'
                   % (self.account.hosting_url,
                      repository.extra_data['rbgateway_repo_name'],
                      branch))

        try:
            data, headers = self._api_get(url)
            commits = json.loads(data)

            results = []

            for commit in commits:
                results.append(Commit(commit['author'],
                                      commit['id'],
                                      commit['date'],
                                      commit['message'],
                                      commit['parent_id']))

            return results
        except Exception as e:
            logger.exception('Failed to fetch commits from %s: %s', url, e)
            raise SCMError(six.text_type(e))
Exemple #23
0
 def get_commits(self, branch=None, start=None):
     return [
         Commit('user%d' % i, six.text_type(i),
                '2013-01-01T%02d:00:00.0000000' % i, 'Commit %d' % i,
                six.text_type(i - 1))
         for i in range(int(start or 10), 0, -1)
     ]
Exemple #24
0
    def _get_commits(self, revset):
        """Return a list of commit objects.

        This method calls the given revset and parses the returned
        JSON data to retrieve detailed information about changesets.

        Args:
            revset (list of unicode):
                Hg command line that will be executed with JSON
                template as log command.

        Returns:
            list of reviewboard.scmtools.core.Commit:
            The list of commit objects.
        """
        cmd = ['log'] + revset + ['--template', 'json']
        p = self._run_hg(cmd)

        if p.wait() != 0:
            raise SCMError('Cannot load commits: %s' % p.stderr.read())

        results = []

        for data in json.load(p.stdout):
            p = data['parents'][0]
            results.append(
                Commit(id=data['node'],
                       message=data['desc'],
                       author_name=data['user'],
                       date=HgTool.date_tuple_to_iso8601(data['date']),
                       parent=p,
                       base_commit_id=p))

        return results
Exemple #25
0
    def _get_commit(self, revision):
        """Return detailed information about a single changeset.

        Receive changeset from hgweb in JSON format.

        Args:
            revision (unicode):
                An identifier of changeset.

        Returns:
            reviewboard.scmtools.core.Commit:
            The commit object.
        """
        try:
            url = '%s/json-rev/%s' % (self.path_stripped, revision)
            contents = self.get_file_http(url, '', '', 'application/json')
        except Exception as e:
            logging.exception('Cannot load detail of changeset from hgweb: %s',
                              e)
            return None

        if contents:
            data = json.loads(contents)
            parent = data['parents'][0]
            return Commit(id=data['node'],
                          message=data['desc'],
                          author_name=data['user'],
                          date=HgTool.date_tuple_to_iso8601(data['date']),
                          parent=parent,
                          base_commit_id=parent)

        return None
Exemple #26
0
    def _get_commit(self, revision):
        """Return detailed information about a single changeset.

        Receive changeset from hgweb in JSON format.

        Args:
            revision (unicode):
                An identifier of changeset.

        Returns:
            reviewboard.scmtools.core.Commit:
            The commit object.
        """
        try:
            rsp = self._get_http_json('%s/json-rev/%s' %
                                      (self.path_stripped, revision))
        except Exception as e:
            logging.exception('Cannot load detail of changeset from hgweb: %s',
                              e)
            return None

        if not rsp:
            return None

        try:
            parent = rsp['parents'][0]
        except IndexError:
            parent = None

        return Commit(id=rsp['node'],
                      message=rsp['desc'],
                      author_name=rsp['user'],
                      date=HgTool.date_tuple_to_iso8601(rsp['date']),
                      parent=parent)
Exemple #27
0
    def get_change(self, repository, revision):
        # We try to pull the commit's metadata out of the cache. The diff API
        # endpoint is just the raw content of the diff and contains no
        # metadata.
        commit = cache.get(repository.get_commit_cache_key(revision))

        if not commit:
            # However, if it is not in the cache, we have to hit the API to
            # get the metadata.
            commit = self.get_commits(repository, revision)[0]

        url = self._build_repository_api_url(repository,
                                             'diff/%s' % revision,
                                             version='2.0')

        diff = self._api_get(url, raw_content=True)

        if not diff.endswith('\n'):
            diff += '\n'

        return Commit(author_name=commit.author_name,
                      id=commit.id,
                      date=commit.date,
                      message=commit.message,
                      diff=diff,
                      base_commit_id=commit.base_commit_id)
Exemple #28
0
    def get_change(self, repository, revision):
        # We try to pull the commit's metadata out of the cache. The diff API
        # endpoint is just the raw content of the diff and contains no
        # metadata.
        commit = cache.get(repository.get_commit_cache_key(revision))

        if not commit:
            # However, if it is not in the cache, we have to hit the API to
            # get the metadata.
            commit_rsp = self.api_get(
                self._build_repository_api_url(
                    repository,
                    'commit/%s' % revision,
                    query={
                        'fields': self._get_commit_fields_query(),
                    }))
            commit = self._build_commit_from_rsp(commit_rsp)

        # Now fetch the diff and normalize it to always end with a newline,
        # so patch is happy.
        diff_url = self._build_repository_api_url(repository,
                                                  'diff/%s' % revision)
        diff = self.api_get(diff_url, raw_content=True)

        if not diff.endswith(b'\n'):
            diff += b'\n'

        return Commit(author_name=commit.author_name,
                      id=commit.id,
                      date=commit.date,
                      message=commit.message,
                      diff=diff,
                      parent=commit.parent)
    def get_commits(self, repository, branch, start=None):
        """Return a list of commits for a repository.

        Args:
            repository (reviewboard.scmtools.models.Repository):
                The repository to fetch commits on.

            branch (unicode):
                The name of the branch to list commits on.

            start (unicode, optional):
                The optional starting commit ID for the list. This is used
                for pagination purposes.

        Returns:
            list of reviewboard.scmtools.core.Commit:
            The list of commits in the repository.

        Raises:
            reviewboard.hostingsvcs.errors.HostingServiceError:
                Error retrieving the branch information. There may be a more
                specific subclass raised.
        """
        repo_name = self._get_repo_name(repository)

        return [
            Commit(author_name=commit_info['author'],
                   id=commit_info['id'],
                   date=commit_info['date'],
                   message=commit_info['message'],
                   parent=commit_info['parent_id'])
            for commit_info in self.client.api_get_commits(repo_name, branch)
        ]
Exemple #30
0
    def test_get_commits(self):
        """Testing SVN (<backend>) get_commits"""
        commits = self.tool.get_commits(start='5')

        self.assertEqual(len(commits), 5)
        self.assertEqual(
            commits[0],
            Commit('chipx86', '5', '2010-05-21T09:33:40.893946',
                   'Add an unterminated keyword for testing bug #1523\n', '4'))

        commits = self.tool.get_commits(start='7')
        self.assertEqual(len(commits), 7)
        self.assertEqual(
            commits[1],
            Commit('david', '6', '2013-06-13T07:43:04.725088',
                   'Add a branches directory', '5'))
    def get_change(self, repository, revision):
        """Return a commit at a given revision/commit ID.

        Args:
            repository (reviewboard.scmtools.models.Repository):
                The repository to fetch the commit from.

            revision (unicode):
                The revision/ID of the commit to fetch.

        Returns:
            reviewboard.scmtools.core.Commit:
            The commit from the repository.

        Raises:
            reviewboard.hostingsvcs.errors.HostingServiceError:
                Error retrieving the branch information. There may be a more
                specific subclass raised.
        """
        repo_name = self._get_repo_name(repository)
        commit_info = self.client.api_get_commit(repo_name, revision)

        return Commit(author_name=commit_info['author'],
                      id=commit_info['id'],
                      date=commit_info['date'],
                      message=commit_info['message'],
                      parent=commit_info['parent_id'],
                      diff=commit_info['diff'].encode('utf-8'))
Exemple #32
0
    def get_change(self, revision, cache_key):
        """Get an individual change.

        This returns a tuple with the commit message and the diff contents.
        """
        revision = int(revision)
        head_revision = Revision(opt_revision_kind.number, revision)

        commit = cache.get(cache_key)
        if commit:
            message = commit.message
            author_name = commit.author_name
            date = commit.date
            base_revision = Revision(opt_revision_kind.number, commit.parent)
        else:
            commits = self.client.log(
                self.repopath,
                revision_start=head_revision,
                limit=2)
            commit = commits[0]
            message = commit['message'].decode('utf-8', 'replace')
            author_name = commit['author'].decode('utf-8', 'replace')
            date = datetime.utcfromtimestamp(commit['date']).\
                isoformat()

            try:
                commit = commits[1]
                base_revision = commit['revision']
            except IndexError:
                base_revision = Revision(opt_revision_kind.number, 0)

        tmpdir = mkdtemp(prefix='reviewboard-svn.')

        diff = self.client.diff(
            tmpdir,
            self.repopath,
            revision1=base_revision,
            revision2=head_revision,
            header_encoding='utf-8',
            diff_options=['-u']).decode('utf-8')

        rmtree(tmpdir)

        commit = Commit(author_name, six.text_type(head_revision.number), date,
                        message, six.text_type(base_revision.number))
        commit.diff = diff
        return commit
Exemple #33
0
        def get_change(repository, commit_to_get):
            self.assertEqual(commit_id, commit_to_get)

            commit = Commit(message='This is my commit message\n\n'
                            'With a summary line too.',
                            diff=self.DEFAULT_GIT_README_DIFF)

            return commit
Exemple #34
0
    def _build_commit(self, data, parent=''):
        date = data.get('date', '')

        if date:
            date = date.isoformat()

        return Commit(data.get('author', ''), data['revision'], date,
                      data.get('message', ''), parent)
Exemple #35
0
    def get_commits(self, repository, branch=None, start=None):
        repo_api_url = self._get_repo_api_url(repository)
        commits = self.client.api_get_commits(repo_api_url, start=start)

        results = []
        for item in commits:
            commit = Commit(
                item['commit']['author']['name'],
                item['sha'],
                item['commit']['committer']['date'],
                item['commit']['message'])
            if item['parents']:
                commit.parent = item['parents'][0]['sha']

            results.append(commit)

        return results
Exemple #36
0
    def get_commits(self, repository, branch=None, start=None):
        repo_api_url = self._get_repo_api_url(repository)
        commits = self.client.api_get_commits(repo_api_url, start=start)

        results = []
        for item in commits:
            commit = Commit(
                item["commit"]["author"]["name"],
                item["sha"],
                item["commit"]["committer"]["date"],
                item["commit"]["message"],
            )
            if item["parents"]:
                commit.parent = item["parents"][0]["sha"]

            results.append(commit)

        return results
Exemple #37
0
    def get_commits(self, repository, branch=None, start=None):
        """Get a list of commits

        This will perform an API request to fetch a list of commits.
        The start parameter is a 40-character commit id.
        """

        # Ask GitLab for 21 commits per page. GitLab's API doesn't
        # include the parent IDs, so we use subsequent commits to fill
        # them in (allowing us to return 20 commits with parent IDs).
        page_size = self.COMMITS_PER_PAGE + 1

        repo_api_url = ('%s/repository/commits?private_token=%s&per_page=%s'
                        % (self._get_repo_api_url(repository),
                           self._get_private_token(),
                           page_size))

        if start:
            # If start parameter is given, use it as the latest commit to log
            # from, so that we fetch a page of commits, and the first commit id
            # on the page is the start parameter.
            repo_api_url += '&ref_name=%s' % start
        elif branch:
            # The branch is optional. If it is not given, use the default
            # branch. The default branch is set to 'master' in get_branches()
            repo_api_url += '&ref_name=%s' % branch

        # The GitLab API will return a tuple consists of two elements.
        # The first one is a list of commits, and the other one is an instance
        # type object containing all kinds of headers, which is not required.
        commits = self._api_get(repo_api_url)[0]

        results = []

        for idx, item in enumerate(commits):
            commit = Commit(
                author_name=item['author_name'],
                id=item['id'],
                date=item['created_at'],
                message=item.get('message', ''),
                parent='')

            if idx > 0:
                # Note that GitLab API documents do not show any returned
                # 'parent_id' from the query for a list of commits. So we use
                # the current commit id as the previous commit's parent id, and
                # remove the last commit from results.
                results[idx - 1].parent = commit.id

            results.append(commit)

        # Strip off the last commit since we don't know its parent id yet.
        if len(commits) == page_size:
            results.pop()

        return results
Exemple #38
0
    def get_commits(self, repository, start=None):
        resource = 'commits'
        url = self._build_api_url(repository, resource)
        if start:
            url += '&sha=%s' % start

        rsp = self._api_get(url)

        results = []
        for item in rsp:
            commit = Commit(item['commit']['author']['name'], item['sha'],
                            item['commit']['committer']['date'],
                            item['commit']['message'])
            if item['parents']:
                commit.parent = item['parents'][0]['sha']

            results.append(commit)

        return results
Exemple #39
0
    def get_commits(self, branch=None, start=None):
        if branch == 'bad:hosting-service-error':
            raise HostingServiceError('This is a HostingServiceError')
        elif branch == 'bad:scm-error':
            raise SCMError('This is a SCMError')

        return [
            Commit('user%d' % i, str(i),
                   '2013-01-01T%02d:00:00.0000000' % i, 'Commit %d' % i,
                   str(i - 1)) for i in range(int(start or 10), 0, -1)
        ]
Exemple #40
0
    def get_commits(self, repository, start=None):
        resource = 'commits'
        url = self._build_api_url(repository, resource)
        if start:
            url += '&sha=%s' % start

        rsp = self._api_get(url)

        results = []
        for item in rsp:
            commit = Commit(
                item['commit']['author']['name'],
                item['sha'],
                item['commit']['committer']['date'],
                item['commit']['message'])
            if item['parents']:
                commit.parent = item['parents'][0]['sha']

            results.append(commit)

        return results
    def _build_commit(self, data, parent=''):
        date = data.get('date', '')

        if date:
            date = date.isoformat()

        return Commit(
            author_name=force_text(data.get('author', ''), errors='replace'),
            id=force_text(data['revision']),
            date=force_text(date),
            message=force_text(data.get('message', ''), errors='replace'),
            parent=force_text(parent))
Exemple #42
0
    def get_commits(self, branch=None, start=None):
        """Return detailed information about a changeset.

        Receive changeset from hgweb in JSON format.

        Args:
            branch (unicode, optional):
                An optional branch name to filter by.

            start (unicode, optional):
                An optional changeset revision to start with.

        Returns:
            list of reviewboard.scmtools.core.Commit:
            The list of commit objects.
        """
        query_parts = []

        if start:
            query_parts.append('ancestors(%s)' % start)

        query_parts.append('branch(%s)' % (branch or '.'))

        query = '+and+'.join(query_parts)

        try:
            url = '%s/json-log/?rev=%s' % (self.path_stripped, query)
            contents = self.get_file_http(url, '', '', 'application/json')
        except Exception as e:
            logging.exception('Cannot load commits from hgweb: %s', e)
            return []

        results = []

        if contents and contents != '"not yet implemented"':
            for data in json.loads(contents)['entries']:
                try:
                    parent = data['parents'][0]
                except IndexError:
                    parent = None

                iso8601 = HgTool.date_tuple_to_iso8601(data['date'])
                changeset = Commit(id=data['node'],
                                   message=data['desc'],
                                   author_name=data['user'],
                                   date=iso8601,
                                   parent=parent,
                                   base_commit_id=parent)
                results.append(changeset)

        return results
Exemple #43
0
    def _build_commit_from_rsp(self, commit_rsp):
        """Return a Commit from an API reesponse.

        This will parse a response from the API and return a structured
        commit.

        Args:
            commit_rsp (dict):
                The API payload for a commit.

        Returns:
            reviewboard.scmtools.core.Commit:
            A commit based on the payload.
        """
        commit = Commit(
            author_name=commit_rsp['author']['raw'],
            id=commit_rsp['hash'],
            date=commit_rsp['date'],
            message=commit_rsp['message'])

        if commit_rsp['parents']:
            commit.parent = commit_rsp['parents'][0]['hash']

        return commit
Exemple #44
0
    def get_change(self, repository, revision):
        repo_api_url = self._get_repo_api_url(repository)

        # Step 1: fetch the commit itself that we want to review, to get
        # the parent SHA and the commit message. Hopefully this information
        # is still in cache so we don't have to fetch it again.
        commit = cache.get(repository.get_commit_cache_key(revision))
        if commit:
            author_name = commit.author_name
            date = commit.date
            parent_revision = commit.parent
            message = commit.message
        else:
            url = self._build_api_url(repo_api_url, "commits")
            url += "&sha=%s" % revision

            commit = self._api_get(url)[0]

            author_name = commit["commit"]["author"]["name"]
            date = (commit["commit"]["committer"]["date"],)
            parent_revision = commit["parents"][0]["sha"]
            message = commit["commit"]["message"]

        # Step 2: fetch the "compare two commits" API to get the diff.
        url = self._build_api_url(repo_api_url, "compare/%s...%s" % (parent_revision, revision))
        comparison = self._api_get(url)

        tree_sha = comparison["base_commit"]["commit"]["tree"]["sha"]
        files = comparison["files"]

        # Step 3: fetch the tree for the original commit, so that we can get
        # full blob SHAs for each of the files in the diff.
        url = self._build_api_url(repo_api_url, "git/trees/%s" % tree_sha)
        url += "&recursive=1"
        tree = self._api_get(url)

        file_shas = {}
        for file in tree["tree"]:
            file_shas[file["path"]] = file["sha"]

        diff = []

        for file in files:
            filename = file["filename"]
            status = file["status"]
            patch = file["patch"]

            diff.append("diff --git a/%s b/%s" % (filename, filename))

            if status == "modified":
                old_sha = file_shas[filename]
                new_sha = file["sha"]
                diff.append("index %s..%s 100644" % (old_sha, new_sha))
                diff.append("--- a/%s" % filename)
                diff.append("+++ b/%s" % filename)
            elif status == "added":
                new_sha = file["sha"]

                diff.append("new file mode 100644")
                diff.append("index %s..%s" % ("0" * 40, new_sha))
                diff.append("--- /dev/null")
                diff.append("+++ b/%s" % filename)
            elif status == "removed":
                old_sha = file_shas[filename]

                diff.append("deleted file mode 100644")
                diff.append("index %s..%s" % (old_sha, "0" * 40))
                diff.append("--- a/%s" % filename)
                diff.append("+++ /dev/null")

            diff.append(patch)

        diff = "\n".join(diff)

        # Make sure there's a trailing newline
        if not diff.endswith("\n"):
            diff += "\n"

        commit = Commit(author_name, revision, date, message, parent_revision)
        commit.diff = diff
        return commit
Exemple #45
0
        resource = 'commits'
        url = self._build_api_url(repository, resource)
        if start:
            url += '&sha=%s' % start

        try:
            rsp = self._api_get(url)
        except Exception, e:
            logging.warning('Failed to fetch commits from %s: %s',
                            url, e)
            return results

        for item in rsp:
            commit = Commit(
                item['commit']['author']['name'],
                item['sha'],
                item['commit']['committer']['date'],
                item['commit']['message'])
            if item['parents']:
                commit.parent = item['parents'][0]['sha']

            results.append(commit)

        return results

    def get_change(self, repository, revision):
        # Step 1: fetch the commit itself that we want to review, to get
        # the parent SHA and the commit message. Hopefully this information
        # is still in cache so we don't have to fetch it again.
        commit = cache.get(repository.get_commit_cache_key(revision))
        if commit:
Exemple #46
0
    def get_change(self, repository, revision):
        # Step 1: fetch the commit itself that we want to review, to get
        # the parent SHA and the commit message. Hopefully this information
        # is still in cache so we don't have to fetch it again.
        commit = cache.get(repository.get_commit_cache_key(revision))
        if commit:
            author_name = commit.author_name
            date = commit.date
            parent_revision = commit.parent
            message = commit.message
        else:
            url = self._build_api_url(repository, 'commits')
            url += '&sha=%s' % revision

            commit = self._api_get(url)[0]

            author_name = commit['commit']['author']['name']
            date = commit['commit']['committer']['date'],
            parent_revision = commit['parents'][0]['sha']
            message = commit['commit']['message']

        # Step 2: fetch the "compare two commits" API to get the diff.
        url = self._build_api_url(
            repository, 'compare/%s...%s' % (parent_revision, revision))
        comparison = self._api_get(url)

        tree_sha = comparison['base_commit']['commit']['tree']['sha']
        files = comparison['files']

        # Step 3: fetch the tree for the original commit, so that we can get
        # full blob SHAs for each of the files in the diff.
        url = self._build_api_url(repository, 'git/trees/%s' % tree_sha)
        url += '&recursive=1'
        tree = self._api_get(url)

        file_shas = {}
        for file in tree['tree']:
            file_shas[file['path']] = file['sha']

        diff = []

        for file in files:
            filename = file['filename']
            status = file['status']
            patch = file['patch']

            diff.append('diff --git a/%s b/%s' % (filename, filename))

            if status == 'modified':
                old_sha = file_shas[filename]
                new_sha = file['sha']
                diff.append('index %s..%s 100644' % (old_sha, new_sha))
                diff.append('--- a/%s' % filename)
                diff.append('+++ b/%s' % filename)
            elif status == 'added':
                new_sha = file['sha']

                diff.append('new file mode 100644')
                diff.append('index %s..%s' % ('0' * 40, new_sha))
                diff.append('--- /dev/null')
                diff.append('+++ b/%s' % filename)
            elif status == 'removed':
                old_sha = file_shas[filename]

                diff.append('deleted file mode 100644')
                diff.append('index %s..%s' % (old_sha, '0' * 40))
                diff.append('--- a/%s' % filename)
                diff.append('+++ /dev/null')

            diff.append(patch)

        diff = '\n'.join(diff)

        # Make sure there's a trailing newline
        if not diff.endswith('\n'):
            diff += '\n'

        commit = Commit(author_name, revision, date, message, parent_revision)
        commit.diff = diff
        return commit