Пример #1
0
def run(path):
    project = Project(path)

    issues_grouped_by_type = project.group_issues_by_type(project.issues)
    issues_grouped_by_status = project.group_issues_by_status(project.issues)

    # Level of detail
    for issue_type, issue_type_list in issues_grouped_by_type.items():
        title('%s (%s)' % (issue_type, len(issue_type_list)))

        average_description_size = round(
            mean([
                issue.get_size_of_description() for issue in issue_type_list
            ]), 2)
        average_acceptance_criteria_size = round(
            mean([
                issue.get_size_of_acceptance_criteria()
                for issue in issue_type_list
            ]), 2)
        average_how_to_test_size = round(
            mean([
                issue.get_size_of_how_to_test() for issue in issue_type_list
            ]), 2)

        print('Average description size: %s lines' % average_description_size)
        print('Average acceptance criteria size: %s lines' %
              average_acceptance_criteria_size)
        print('Average how to test size: %s lines' % average_how_to_test_size)

    # Type and status distribution
    title('Issue distribution by status (overall)')
    issue_status_distribution = {
        issue_type: len(issue_type_list)
        for issue_type, issue_type_list in issues_grouped_by_status.items()
    }
    for issue, count in issue_status_distribution.items():
        print('- %s: %s' % (issue, count))

    title('Issue distribution by type and status')
    for issue_type, issue_type_list in issues_grouped_by_type.items():
        print('+ %s: %s' % (issue_type, len(issue_type_list)))
        issue_type_status_distribution = project.group_issues_by_status(
            issue_type_list)
        for issue, count in issue_type_status_distribution.items():
            print(' - %s: %s' % (issue, len(count)))

    # Activity distribution by status
    description_updates = Counter()
    acceptance_criteria_updates = Counter()
    how_to_test_updates = Counter()
    comments = Counter()

    for issue in project.issues:
        description_updates += Counter(
            issue.get_description_update_by_status_distribution())
        acceptance_criteria_updates += Counter(
            issue.get_acceptance_criteria_update_by_status_distribution())
        how_to_test_updates += Counter(
            issue.get_how_to_test_update_by_status_distribution())
        comments += Counter(issue.get_comments_by_status_distribution())

    # Update distribution
    title('Number of updates in status')

    def display_updates(title, counter):
        print('+ %s' % title)
        for k, v in dict(counter).items():
            print(' - %s: %s' % (k, v))

    display_updates('Description', description_updates)
    display_updates('Acceptance criteria', acceptance_criteria_updates)
    display_updates('How to test', how_to_test_updates)
    display_updates('Comments', comments)

    # Time distribution

    # Filter only issues that have been through 'Todo', meaning they were ready to be dragged into 'In Progress'
    issues = [
        issue for issue in project.issues if 'Todo' in issue.get_status_flow()
    ]
    issues_grouped_by_type = project.group_issues_by_type(issues)

    title('Average time spent in status')
    for issue_type, issue_type_list in issues_grouped_by_type.items():
        status_date_distributions = [
            issue.get_status_date_distribution() for issue in issue_type_list
        ]
        dd = defaultdict(list)
        for d in status_date_distributions:
            for key, value in d.items():
                dd[key].append(value)

        print('+ %s' % issue_type)
        for key, value in project.sort_issue_status(dd).items():
            print(' - %s: %s' % (key, seconds_to_human(round(mean(value), 2))))