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

Create class wrappers for git concepts.

Besides facilitating a more OO approach, the wrapper will make code
completion in IDEs possible.
parent 997b3474
No related branches found
No related tags found
No related merge requests found
......@@ -3,5 +3,6 @@ class Course:
gitlab_namespace = 'csce_361/sandbox'
# Canvas course information
canvas_course_id = None
# canvas_course_id = '73696' # Software Engineering Sandbox
canvas_course_id = '66898' # CSCE 361-1198
......@@ -156,6 +156,9 @@ def create_issue(project, title, description):
if __name__ == '__main__':
git = gitlab.Gitlab(Config.gitlab_url, private_token=Config.gitlab_api_key)
project = get_project_by_id(git, '5484')
student = get_user_by_id(git, project.creator_id)
print(f'{student.name} forked repo at {project.created_at}')
print('getting a user, by name')
print(get_user_by_name(git, 'bohn'))
print('getting a user by user ID and printing only the user\'s name')
......
from datetime import datetime
import gitlab
from config import Config
def gitlab_timestamp_to_datetime(timestamp):
return datetime.fromisoformat(timestamp)
class Session:
__instance = None
@staticmethod
def get_session():
if Session.__instance is None:
Session.__instance = gitlab.Gitlab(Config.gitlab_url, private_token=Config.gitlab_api_key)
return Session.__instance
class User:
def __init__(self, user):
"""
Creates a User object, populating the backing git_user instance with the appropriate gitlab.User object
:param user: must be either a gitlab.User object, an integer representing the user ID, or a string containing
the username
"""
super().__init__()
if isinstance(user, int): # by user id
self.git_user = Session.get_session().users.get(user)
elif isinstance(user, str): # by username
self.git_user = Session.get_session().users.list(username=user)[0]
else:
self.git_user = user
def get_user_id(self):
return self.git_user.id
def get_name(self):
return self.git_user.name
def get_username(self):
return self.git_user.username
def get_site(self):
return self.git_user.web_url
class Issue:
def __init__(self, issue):
"""
Creates an Issue object, populating the backing git_issue instance with the appropriate gitlab.Issue object
:param issue: must be a gitlab.Issue object
"""
super().__init__()
self.git_issue = issue
def get_universal_issue_id(self):
"""
:return: universally-unique identifier
"""
return self.git_issue.id
def get_project_issue_id(self):
"""
:return: project-unique identifier
"""
return self.git_issue.iid
def get_state(self):
"""
:return: opened or closed
"""
return self.git_issue.state
def get_created_at(self):
"""
:return: an "aware" datetime object representing the creation date/time
"""
created_at = self.git_issue.created_at
if created_at[-1] in ('z', 'Z'): # Didn't encounter this problem with created_at
created_at = created_at[:-1] + '+00:00'
return datetime.fromisoformat(created_at)
def get_updated_at(self):
"""
:return: an "aware" datetime object representing the last date/time the issue was updated
"""
updated_at = self.git_issue.updated_at
if updated_at[-1] in ('z', 'Z'): # Didn't encounter this problem with updated_at
updated_at = updated_at[:-1] + '+00:00'
return datetime.fromisoformat(updated_at)
def get_closed_at(self):
"""
:return: an "aware" datetime object representing the last date/time the issue was closed, or None if the issue
is open
"""
closed_at = self.git_issue.closed_at
if closed_at is None:
return None
else:
if closed_at[-1] in ('z', 'Z'): # Did encounter this problem with closed_at
closed_at = closed_at[:-1] + '+00:00'
return datetime.fromisoformat(closed_at)
def get_labels(self):
"""
:return: list of labels
"""
return self.git_issue.labels.list(all=True)
def get_page(self):
"""
:return: HTTPS URL to issue's page
"""
return self.git_issue.web_url
# other git_issue fields:
# project_id
# title
# description
# closed_by user
# milestone
# assignees list of users
# author user
# assignee user
# user_notes_count
# merge_requests_count
# upvotes
# downvotes
# due_date same date format, or None
# confidential
# discussion_locked
# time_stats
# task_completion_status
# has_tasks
# _links
# notes
# award_emoji
# project
# subscribed
class Project:
def __init__(self, project):
"""
Creates a Project object, populating the backing git_project instance with the appropriate gitlab.Project object
:param project: must be either a gitlab.Project object, an integer representing the project ID, or a string
containing the project's path (namespace and name, such as 'csce_361/sandbox/HelloWorld')
"""
super().__init__()
if isinstance(project, int): # by project id
self.git_project = Session.get_session().projects.get(project)
elif isinstance(project, str): # by path
self.git_project = Session.get_session().projects.get(project)
else:
self.git_project = project
@staticmethod
def get_projects_by_group(group_id):
gitlab_projects = Session.get_session().groups.get(group_id).projects.list(all=True)
projects = []
for project in gitlab_projects:
projects.append(Project(project))
return projects
@staticmethod
def get_projects_by_keyword(search_term):
gitlab_projects = Session.get_session().projects.list(search=search_term, all=True)
projects = []
for project in gitlab_projects:
projects.append(Project(project))
return projects
@staticmethod
def create_project(project_name):
return Session.get_session().projects.create({'name': project_name})
@staticmethod
def create_project_in_group(group_name, project_name):
group_id = Session.get_session().groups.get(group_name).id
return Session.get_session().projects.create({'name': project_name, 'namespace_id': group_id})
def get_project_id(self):
return self.git_project.id
def get_name(self):
"""
:return: project name without namespace
"""
return self.git_project.name
def get_name_with_namespace(self):
"""
:return: project name with namespace, spaces around slashes
"""
return self.git_project.name_with_namespace
def get_path(self):
"""
:return: path without namespace (may differ from name if name has spaces)
"""
return self.git_project.path
def get_path_with_namespace(self):
"""
:return: path with namespace, no spaces around slashes
"""
return self.git_project.path_with_namespace
def get_cloning_url(self):
"""
:return: SSH URL to clone repository
"""
return self.git_project.ssh_url_to_repo
def get_site(self):
"""
:return: HTTPS URL to git site
"""
return self.git_project.web_url
def get_readme_url(self):
"""
:return: HTTPS URL to README.md
"""
return self.git_project.readme_url
def get_visibility(self):
"""
:return: 'private', etc.
"""
return self.git_project.visibility
def get_creator(self):
"""
:return: User object backed by the gitlab.User object representing the user who created the repo
"""
return User(self.git_project.creator_id)
def get_users(self):
"""
:return: List of User objects representing the project's members (not including inherited members)
"""
gitlab_users = self.git_project.members.list(all=True)
users = []
for user in gitlab_users:
users.append(User(user))
return users
def get_all_users(self):
"""
:return: List of User objects representing all of the project's members (including inherited members)
"""
gitlab_users = self.git_project.members.all(all=True)
users = []
for user in gitlab_users:
users.append(User(user))
return users
def add_user_as_maintainer(self, user):
self.git_project.members.create({'user_id': user.get_user_id(), 'access_level': gitlab.MAINTAINER_ACCESS})
def get_issues(self):
"""
:return: List of Issue objects representing project's issues, sorted by creation date
"""
gitlab_issues = self.git_project.issues.list(order_by='created_at', sort='asc', all=True)
issues = []
for issue in gitlab_issues:
issues.append(Issue(issue))
return issues
def create_issue(self, title, description):
gitlab_issue = self.git_project.issues.create({'title': title, 'description': description})
return Issue(gitlab_issue)
# other git_project fields:
# description
# created_at
# default_branch
# tag_list
# http_url_to_repo https URL to clone repository
# avatar_url
# star_count
# forks_count
# last_activity_at
# namespace namespace's JSON object
# _links JSON object with api/v4 links to self, issues, merge_requests,
# repo_branches, labels, events, members
# empty_repo
# archived
# resolve_outdated_diff_discussions
# container_registry_enabled
# issues_enabled
# merge_requests_enabled
# jobs_enabled
# snippets_enabled
# issues_access_level
# repository_access_level,
# wiki_access_level
# builds_access_level
# snippets_access_level
# shared_runners_enabled
# lfs_enabled
# import_status
# import_error
# open_issues_count
# runners_token
# ci_default_git_depth
# public_jobs
# build_git_strategy
# build_timeout
# auto_cancel_pending_pipelines
# build_coverage_regex
# ci_config_path
# shared_with_groups
# only_allow_merge_if_pipeline_succeeds
# request_access_enabled
# only_allow_merge_if_all_discussions_are_resolved
# printing_merge_request_link_enabled
# merge_method
# auto_devops_enabled
# auto_devops_deploy_strategy
# permissions
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment