Skip to content
Snippets Groups Projects
Commit aec77cab authored by Christopher Bohn's avatar Christopher Bohn :thinking:
Browse files

added code to examine git commits

parent 91fa7ddd
No related branches found
No related tags found
No related merge requests found
......@@ -168,6 +168,61 @@ class GitlabIssue:
# subscribed
class GitlabCommit:
def __init__(self, commit):
super().__init__()
self.gitlab_commit = commit
def get_author(self):
return {'name': self.gitlab_commit.author_name, 'email': self.gitlab_commit.author_email}
def get_timestamp(self):
return self.gitlab_commit.created_at
def get_message(self):
return self.gitlab_commit.message
def is_merge(self):
return len(self.gitlab_commit.parent_ids) > 1
def get_diffs(self):
diffs = []
gitlab_diffs = self.gitlab_commit.diff()
for diff in gitlab_diffs:
diffs.append({'file': diff['new_path'], 'text': diff['diff'],
'+': diff['diff'].count('\n+'), '-': diff['diff'].count('\n-')})
return diffs
def get_diff_size(self):
insertions = 0
deletions = 0
if not self.is_merge():
for diff in self.get_diffs():
insertions += diff['+']
deletions += diff['-']
return max(insertions, deletions)
# git_commit fields:
# comments
# discussions
# manager
# statuses
# attributes:
# id
# short_id
# created_at
# parent_ids
# title
# message
# author_name
# author_email
# authored_date
# committer_name
# committer_email
# committed_date
# project_id
class GitlabProject:
def __init__(self, project):
"""
......@@ -320,6 +375,32 @@ class GitlabProject:
gitlab_issue = self.git_project.issues.create({'title': title, 'description': description})
return GitlabIssue(gitlab_issue)
def get_commits(self, branch_name = '', after_date ='1970-01-01', before_date ='9999-12-31'):
"""
:param branch_name: the branch to retrieve commits from; if an empty string (default) then retrieves commits
from all branches
:param after_date: the earliest date of any retrieved commit; if '1970-01-01' (Unix epoch) then treated as
having no earliest-bound
:param before_date: the latest date of any retrieved commit; if '9999-12-31' (Y10K problem) then treated a
having no latest-bound
:return: List of Commit objects representing the project's commits that meet the specified constraints
"""
filters = {}
if branch_name != '':
filters['ref_name'] = branch_name
if after_date != '1970-01-01':
filters['since'] = after_date
if before_date != '9999-12-31':
filters['until'] = before_date
if len(filters) == 0:
gitlab_commits = self.git_project.commits.list(all=True)
else:
gitlab_commits = self.git_project.commits.list(all=True, query_parameters=filters)
commits = []
for commit in gitlab_commits:
commits.append(GitlabCommit(commit))
return commits
def __repr__(self):
return self.get_name_with_namespace()
......@@ -378,6 +459,18 @@ if __name__ == '__main__':
print('All projects in sandbox:')
for test_project in test_projects:
print(test_project)
print('Selecting last project. Here are the commits:')
test_project = test_projects[-1]
commits = test_project.get_commits()
diff = commits[-5].get_diffs()
print(diff)
print(commits[0].get_author())
for commit in commits:
print(commit.get_message())
print(f'is a merge? {commit.is_merge()}')
print(f'size: {commit.get_diff_size()}')
print()
"""
print('Selecting second project. Here are the members:')
test_project = test_projects[1]
members = test_project.get_users()
......@@ -401,3 +494,4 @@ if __name__ == '__main__':
print(f'after culling, there are {new_number_of_projects} projects that were created in/after August 2019')
print(f'including {test_projects[0]} created by {test_projects[0].get_creator()} at '
f'{test_projects[0].get_created_at()}.')
"""
import textwrap
from api.canvas_classes import *
from api.gitlab_classes import *
from course import Course
......@@ -34,28 +35,40 @@ def display_peer_reviews(assignment, students):
print(f'\t\t{line}'.expandtabs(4))
def display_git_contributions():
def get_project_prefix(canvas_groups):
name_segments = canvas_groups[0].get_name().split()
prefix = input(f'What is the prefix of the gitlab project names? [{name_segments[0]}] ')
if prefix == '':
prefix = name_segments[0]
return prefix
def display_git_contributions(project):
print('Review git contributions offline')
# TODO: recognize that this only works for projects in namespace; will need to ask whether project should be retrieved.
def grade(assignment1, assignment2, students):
pass
print('Enter grades through Canvas gradebook')
if __name__ == '__main__':
course = CanvasCourse(Course.canvas_course_id)
print('First, select the Canvas assignment to review and grade.\n')
projects = GitlabProject.get_projects_by_group(Course.gitlab_namespace)
print('First, select the "peer review" assignment to review and grade.\n')
assignment_groups = course.get_assignment_groups()
assignment_group = select_from_list(assignment_groups, 'assignment group')
print()
assignments = assignment_group.get_assignments()
peer_review_assignment = select_from_list(assignments, 'assignment')
print(f'\nSelected {peer_review_assignment}.')
# TODO: select second assignment (git history)
print('Now select the student groupset with the teams.\n')
student_groupsets = course.get_user_groupsets()
student_groupset = select_from_list(student_groupsets, 'groupset')
print(f'\nSelected {student_groupset}.\n')
student_groups = student_groupset.get_groups()
project_prefix = get_project_prefix(student_groups)
print('Are you grading all groups, or are you revisiting a specific group?')
options = ['All groups', 'Specific group']
option = select_from_list(options, 'option')
......@@ -65,7 +78,8 @@ if __name__ == '__main__':
for student_group in student_groups:
input(f'\n\nPress any key to grade {student_group}')
display_peer_reviews(peer_review_assignment, student_group.get_students())
display_git_contributions()
project_name = f'{project_prefix}{student_group.get_name().split()[1]}'
display_git_contributions(list(filter(lambda p: p.get_name() == project_name, projects))[0])
# TODO: Ask if you want to grade (keep track of groups that you don't grade)
if True:
grade(peer_review_assignment, None, student_group.get_students())
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment