Esempio n. 1
0
    def __init__(self, host, changelog_paths):
        self._changelog_paths = changelog_paths
        self._filesystem = host.filesystem
        self._contribution_areas = ContributionAreas(host.filesystem)
        self._scm = host.scm()
        self._parsed_revisions = {}

        self._contributors_statistics = {}
        self._areas_statistics = dict([(area, {'reviewed': 0, 'unreviewed': 0, 'contributors': {}}) for area in self._contribution_areas.names()])
        self._summary = {'reviewed': 0, 'unreviewed': 0}

        self._longest_filename = max([len(path) - len(self._scm.checkout_root) for path in changelog_paths])
        self._filename = ''
        self._length_of_previous_output = 0
Esempio n. 2
0
    def __init__(self, host, changelog_paths):
        self._changelog_paths = changelog_paths
        self._filesystem = host.filesystem
        self._contribution_areas = ContributionAreas(host.filesystem)
        self._scm = host.scm()
        self._parsed_revisions = {}

        self._contributors_statistics = {}
        self._areas_statistics = dict([(area, {'reviewed': 0, 'unreviewed': 0, 'contributors': {}}) for area in self._contribution_areas.names()])
        self._summary = {'reviewed': 0, 'unreviewed': 0}

        self._longest_filename = max([len(path) - len(self._scm.checkout_root) for path in changelog_paths])
        self._filename = ''
        self._length_of_previous_output = 0
 def test_areas_for_touched_files(self):
     areas = ContributionAreas(MockFileSystem(), [
         _Area('CSS'),
         _Area('HTML'),
         _Area('Forms', ['forms', 'input']),
         _Area('CSS Transforms', [_Intersection('css', 'transforms')]),
     ])
     self._assert_areas_for_touched_files(areas, [], [])
     self._assert_areas_for_touched_files(areas, ['WebCore/css'], ['CSS'])
     self._assert_areas_for_touched_files(areas, ['WebCore/html/'],
                                          ['HTML'])
     self._assert_areas_for_touched_files(areas, [
         'WebCore/css/CSSStyleSelector.cpp',
         'WebCore/html/HTMLIFrameElement.h'
     ], ['CSS', 'HTML'])
     self._assert_areas_for_touched_files(areas, ['WebCore'], [])
     self._assert_areas_for_touched_files(areas, ['WebCore/html2'], [])
     self._assert_areas_for_touched_files(
         areas, ['WebCore/html/HTMLInputElement.cpp'], ['HTML', 'Forms'])
     self._assert_areas_for_touched_files(areas, ['WebCore/svg/transforms'],
                                          [])
     self._assert_areas_for_touched_files(areas, ['WebCore/css/transforms'],
                                          ['CSS', 'CSS Transforms'])
Esempio n. 4
0
class ChangeLogAnalyzer(object):
    def __init__(self, host, changelog_paths):
        self._changelog_paths = changelog_paths
        self._filesystem = host.filesystem
        self._contribution_areas = ContributionAreas(host.filesystem)
        self._scm = host.scm()
        self._parsed_revisions = {}

        self._contributors_statistics = {}
        self._areas_statistics = dict([(area, {'reviewed': 0, 'unreviewed': 0, 'contributors': {}}) for area in self._contribution_areas.names()])
        self._summary = {'reviewed': 0, 'unreviewed': 0}

        self._longest_filename = max([len(path) - len(self._scm.checkout_root) for path in changelog_paths])
        self._filename = ''
        self._length_of_previous_output = 0

    def contributors_statistics(self):
        return self._contributors_statistics

    def areas_statistics(self):
        return self._areas_statistics

    def summary(self):
        return self._summary

    def _print_status(self, status):
        if self._length_of_previous_output:
            print("\r" + " " * self._length_of_previous_output, end=' ')
        new_output = ('%' + str(self._longest_filename) + 's: %s') % (self._filename, status)
        print("\r" + new_output, end=' ')
        self._length_of_previous_output = len(new_output)

    def _set_filename(self, filename):
        if self._filename:
            print()
        self._filename = filename

    def analyze(self):
        for path in self._changelog_paths:
            self._set_filename(self._filesystem.relpath(path, self._scm.checkout_root))
            with self._filesystem.open_text_file_for_reading(path) as changelog:
                self._print_status('Parsing entries...')
                number_of_parsed_entries = self._analyze_entries(ChangeLog.parse_entries_from_file(changelog), path)
            self._print_status('Done (%d entries)' % number_of_parsed_entries)
        print()
        self._summary['contributors'] = len(self._contributors_statistics)
        self._summary['contributors_with_reviews'] = sum([1 for contributor in self._contributors_statistics.values() if contributor['reviews']['total']])
        self._summary['contributors_without_reviews'] = self._summary['contributors'] - self._summary['contributors_with_reviews']

    def _collect_statistics_for_contributor_area(self, area, contributor, contribution_type, reviewed):
        area_contributors = self._areas_statistics[area]['contributors']
        if contributor not in area_contributors:
            area_contributors[contributor] = {'reviews': 0, 'reviewed': 0, 'unreviewed': 0}
        if contribution_type == 'patches':
            contribution_type = 'reviewed' if reviewed else 'unreviewed'
        area_contributors[contributor][contribution_type] += 1

    def _collect_statistics_for_contributor(self, contributor, contribution_type, areas, touched_files, reviewed):
        if contributor not in self._contributors_statistics:
            self._contributors_statistics[contributor] = {
                'reviews': {'total': 0, 'areas': {}, 'files': {}},
                'patches': {'reviewed': 0, 'unreviewed': 0, 'areas': {}, 'files': {}}}
        statistics = self._contributors_statistics[contributor][contribution_type]

        if contribution_type == 'reviews':
            statistics['total'] += 1
        elif reviewed:
            statistics['reviewed'] += 1
        else:
            statistics['unreviewed'] += 1

        for area in areas:
            self._increment_dictionary_value(statistics['areas'], area)
            self._collect_statistics_for_contributor_area(area, contributor, contribution_type, reviewed)
        for touchedfile in touched_files:
            self._increment_dictionary_value(statistics['files'], touchedfile)

    def _increment_dictionary_value(self, dictionary, key):
        dictionary[key] = dictionary.get(key, 0) + 1

    def _analyze_entries(self, entries, changelog_path):
        dirname = self._filesystem.dirname(changelog_path)
        i = 0
        for i, entry in enumerate(entries):
            self._print_status('(%s) entries' % i)
            assert(entry.authors())

            touchedfiles_for_entry = [self._filesystem.relpath(self._filesystem.join(dirname, name), self._scm.checkout_root) for name in entry.touched_files()]
            areas_for_entry = self._contribution_areas.areas_for_touched_files(touchedfiles_for_entry)
            authors_for_entry = entry.authors()
            reviewers_for_entry = entry.reviewers()

            for reviewer in reviewers_for_entry:
                self._collect_statistics_for_contributor(reviewer.full_name, 'reviews', areas_for_entry, touchedfiles_for_entry, reviewed=True)

            for author in authors_for_entry:
                self._collect_statistics_for_contributor(author['name'], 'patches', areas_for_entry, touchedfiles_for_entry,
                    reviewed=bool(reviewers_for_entry))

            for area in areas_for_entry:
                self._areas_statistics[area]['reviewed' if reviewers_for_entry else 'unreviewed'] += 1

            self._summary['reviewed' if reviewers_for_entry else 'unreviewed'] += 1

        self._print_status('(%s) entries' % i)
        return i
Esempio n. 5
0
class ChangeLogAnalyzer(object):
    def __init__(self, host, changelog_paths):
        self._changelog_paths = changelog_paths
        self._filesystem = host.filesystem
        self._contribution_areas = ContributionAreas(host.filesystem)
        self._scm = host.scm()
        self._parsed_revisions = {}

        self._contributors_statistics = {}
        self._areas_statistics = dict([(area, {'reviewed': 0, 'unreviewed': 0, 'contributors': {}}) for area in self._contribution_areas.names()])
        self._summary = {'reviewed': 0, 'unreviewed': 0}

        self._longest_filename = max([len(path) - len(self._scm.checkout_root) for path in changelog_paths])
        self._filename = ''
        self._length_of_previous_output = 0

    def contributors_statistics(self):
        return self._contributors_statistics

    def areas_statistics(self):
        return self._areas_statistics

    def summary(self):
        return self._summary

    def _print_status(self, status):
        if self._length_of_previous_output:
            print "\r" + " " * self._length_of_previous_output,
        new_output = ('%' + str(self._longest_filename) + 's: %s') % (self._filename, status)
        print "\r" + new_output,
        self._length_of_previous_output = len(new_output)

    def _set_filename(self, filename):
        if self._filename:
            print
        self._filename = filename

    def analyze(self):
        for path in self._changelog_paths:
            self._set_filename(self._filesystem.relpath(path, self._scm.checkout_root))
            with self._filesystem.open_text_file_for_reading(path) as changelog:
                self._print_status('Parsing entries...')
                number_of_parsed_entries = self._analyze_entries(ChangeLog.parse_entries_from_file(changelog), path)
            self._print_status('Done (%d entries)' % number_of_parsed_entries)
        print
        self._summary['contributors'] = len(self._contributors_statistics)
        self._summary['contributors_with_reviews'] = sum([1 for contributor in self._contributors_statistics.values() if contributor['reviews']['total']])
        self._summary['contributors_without_reviews'] = self._summary['contributors'] - self._summary['contributors_with_reviews']

    def _collect_statistics_for_contributor_area(self, area, contributor, contribution_type, reviewed):
        area_contributors = self._areas_statistics[area]['contributors']
        if contributor not in area_contributors:
            area_contributors[contributor] = {'reviews': 0, 'reviewed': 0, 'unreviewed': 0}
        if contribution_type == 'patches':
            contribution_type = 'reviewed' if reviewed else 'unreviewed'
        area_contributors[contributor][contribution_type] += 1

    def _collect_statistics_for_contributor(self, contributor, contribution_type, areas, touched_files, reviewed):
        if contributor not in self._contributors_statistics:
            self._contributors_statistics[contributor] = {
                'reviews': {'total': 0, 'areas': {}, 'files': {}},
                'patches': {'reviewed': 0, 'unreviewed': 0, 'areas': {}, 'files': {}}}
        statistics = self._contributors_statistics[contributor][contribution_type]

        if contribution_type == 'reviews':
            statistics['total'] += 1
        elif reviewed:
            statistics['reviewed'] += 1
        else:
            statistics['unreviewed'] += 1

        for area in areas:
            self._increment_dictionary_value(statistics['areas'], area)
            self._collect_statistics_for_contributor_area(area, contributor, contribution_type, reviewed)
        for touchedfile in touched_files:
            self._increment_dictionary_value(statistics['files'], touchedfile)

    def _increment_dictionary_value(self, dictionary, key):
        dictionary[key] = dictionary.get(key, 0) + 1

    def _analyze_entries(self, entries, changelog_path):
        dirname = self._filesystem.dirname(changelog_path)
        for i, entry in enumerate(entries):
            self._print_status('(%s) entries' % i)
            assert(entry.authors())

            touchedfiles_for_entry = [self._filesystem.relpath(self._filesystem.join(dirname, name), self._scm.checkout_root) for name in entry.touched_files()]
            areas_for_entry = self._contribution_areas.areas_for_touched_files(touchedfiles_for_entry)
            authors_for_entry = entry.authors()
            reviewers_for_entry = entry.reviewers()

            for reviewer in reviewers_for_entry:
                self._collect_statistics_for_contributor(reviewer.full_name, 'reviews', areas_for_entry, touchedfiles_for_entry, reviewed=True)

            for author in authors_for_entry:
                self._collect_statistics_for_contributor(author['name'], 'patches', areas_for_entry, touchedfiles_for_entry,
                    reviewed=bool(reviewers_for_entry))

            for area in areas_for_entry:
                self._areas_statistics[area]['reviewed' if reviewers_for_entry else 'unreviewed'] += 1

            self._summary['reviewed' if reviewers_for_entry else 'unreviewed'] += 1

            i += 1
        self._print_status('(%s) entries' % i)
        return i