|
Pierre-Yves Chibon |
1e2e25 |
#-*- coding: utf-8 -*-
|
|
Pierre-Yves Chibon |
1e2e25 |
|
|
Pierre-Yves Chibon |
1e2e25 |
"""
|
|
Pierre-Yves Chibon |
1e2e25 |
(c) 2014 - Copyright Red Hat Inc
|
|
Pierre-Yves Chibon |
1e2e25 |
|
|
Pierre-Yves Chibon |
1e2e25 |
Authors:
|
|
Pierre-Yves Chibon |
1e2e25 |
Pierre-Yves Chibon <pingou@pingoured.fr></pingou@pingoured.fr>
|
|
Pierre-Yves Chibon |
1e2e25 |
|
|
Pierre-Yves Chibon |
1e2e25 |
"""
|
|
Pierre-Yves Chibon |
1e2e25 |
|
|
Pierre-Yves Chibon |
1e2e25 |
|
|
Pierre-Yves Chibon |
f7d963 |
import json
|
|
Pierre-Yves Chibon |
d8110b |
import os
|
|
Pierre-Yves Chibon |
d133cd |
import shutil
|
|
Pierre-Yves Chibon |
d133cd |
import tempfile
|
|
Pierre-Yves Chibon |
9cb884 |
import uuid
|
|
Pierre-Yves Chibon |
d8110b |
|
|
Pierre-Yves Chibon |
1e2e25 |
import sqlalchemy
|
|
Pierre-Yves Chibon |
1e2e25 |
from datetime import timedelta
|
|
Pierre-Yves Chibon |
1e2e25 |
from sqlalchemy.orm import sessionmaker
|
|
Pierre-Yves Chibon |
1e2e25 |
from sqlalchemy.orm import scoped_session
|
|
Pierre-Yves Chibon |
1e2e25 |
from sqlalchemy.orm.exc import NoResultFound
|
|
Pierre-Yves Chibon |
1e2e25 |
from sqlalchemy.exc import SQLAlchemyError
|
|
Pierre-Yves Chibon |
1e2e25 |
|
|
Pierre-Yves Chibon |
d8110b |
import pygit2
|
|
Pierre-Yves Chibon |
d8110b |
|
|
Pierre-Yves Chibon |
d8110b |
import progit.exceptions
|
|
Pierre-Yves Chibon |
1e2e25 |
from progit import model
|
|
Pierre-Yves Chibon |
1e2e25 |
|
|
Pierre-Yves Chibon |
1e2e25 |
|
|
Pierre-Yves Chibon |
1e2e25 |
def create_session(db_url, debug=False, pool_recycle=3600):
|
|
Pierre-Yves Chibon |
695ef6 |
''' Create the Session object to use to query the database.
|
|
Pierre-Yves Chibon |
1e2e25 |
|
|
Pierre-Yves Chibon |
1e2e25 |
:arg db_url: URL used to connect to the database. The URL contains
|
|
Pierre-Yves Chibon |
1e2e25 |
information with regards to the database engine, the host to connect
|
|
Pierre-Yves Chibon |
1e2e25 |
to, the user and password and the database name.
|
|
Pierre-Yves Chibon |
1e2e25 |
ie: <engine>://<user>:<password>@<host>/<dbname></dbname></host></password></user></engine>
|
|
Pierre-Yves Chibon |
1e2e25 |
:kwarg debug: a boolean specifying wether we should have the verbose
|
|
Pierre-Yves Chibon |
1e2e25 |
output of sqlalchemy or not.
|
|
Pierre-Yves Chibon |
1e2e25 |
:return a Session that can be used to query the database.
|
|
Pierre-Yves Chibon |
1e2e25 |
|
|
Pierre-Yves Chibon |
695ef6 |
'''
|
|
Pierre-Yves Chibon |
1e2e25 |
engine = sqlalchemy.create_engine(
|
|
Pierre-Yves Chibon |
1e2e25 |
db_url, echo=debug, pool_recycle=pool_recycle)
|
|
Pierre-Yves Chibon |
1e2e25 |
scopedsession = scoped_session(sessionmaker(bind=engine))
|
|
Pierre-Yves Chibon |
1e2e25 |
return scopedsession
|
|
Pierre-Yves Chibon |
1e2e25 |
|
|
Pierre-Yves Chibon |
1e2e25 |
|
|
Pierre-Yves Chibon |
03c11f |
def get_user(session, username):
|
|
Pierre-Yves Chibon |
03c11f |
''' Return the user corresponding to this username, or None. '''
|
|
Pierre-Yves Chibon |
03c11f |
user = session.query(
|
|
Pierre-Yves Chibon |
e1372f |
model.User
|
|
Pierre-Yves Chibon |
e1372f |
).filter(
|
|
Pierre-Yves Chibon |
03c11f |
model.User.user == username
|
|
Pierre-Yves Chibon |
e1372f |
).first()
|
|
Pierre-Yves Chibon |
03c11f |
return user
|
|
Pierre-Yves Chibon |
03c11f |
|
|
Pierre-Yves Chibon |
03c11f |
|
|
Pierre-Yves Chibon |
b81780 |
def get_user_by_email(session, user_mail):
|
|
Pierre-Yves Chibon |
b81780 |
''' Return the user corresponding to this email, or None. '''
|
|
Pierre-Yves Chibon |
b81780 |
mail = session.query(
|
|
Pierre-Yves Chibon |
b81780 |
model.UserEmail
|
|
Pierre-Yves Chibon |
b81780 |
).filter(
|
|
Pierre-Yves Chibon |
b81780 |
model.UserEmail.email == user_mail
|
|
Pierre-Yves Chibon |
b81780 |
).first()
|
|
Pierre-Yves Chibon |
b81780 |
if mail:
|
|
Pierre-Yves Chibon |
b81780 |
return mail.user
|
|
Pierre-Yves Chibon |
b81780 |
|
|
Pierre-Yves Chibon |
b81780 |
|
|
Pierre-Yves Chibon |
556d85 |
def get_all_users(session):
|
|
Pierre-Yves Chibon |
556d85 |
''' Return the user corresponding to this username, or None. '''
|
|
Pierre-Yves Chibon |
556d85 |
users = session.query(
|
|
Pierre-Yves Chibon |
556d85 |
model.User
|
|
Pierre-Yves Chibon |
556d85 |
).all()
|
|
Pierre-Yves Chibon |
556d85 |
return users
|
|
Pierre-Yves Chibon |
556d85 |
|
|
Pierre-Yves Chibon |
556d85 |
|
|
Pierre-Yves Chibon |
a34835 |
def add_issue_comment(session, issue, comment, user, ticketfolder):
|
|
Pierre-Yves Chibon |
03c11f |
''' Add a comment to an issue. '''
|
|
Pierre-Yves Chibon |
3ddae1 |
user_obj = get_user(session, user)
|
|
Pierre-Yves Chibon |
496a35 |
if not user_obj:
|
|
Pierre-Yves Chibon |
496a35 |
user_obj = get_user_by_email(session, user)
|
|
Pierre-Yves Chibon |
e1372f |
|
|
Pierre-Yves Chibon |
e1372f |
if not user_obj:
|
|
Pierre-Yves Chibon |
e1372f |
raise progit.exceptions.ProgitException(
|
|
Pierre-Yves Chibon |
e1372f |
'No user "%s" found' % user
|
|
Pierre-Yves Chibon |
e1372f |
)
|
|
Pierre-Yves Chibon |
e1372f |
|
|
Pierre-Yves Chibon |
359db9 |
isse_comment = model.IssueComment(
|
|
Pierre-Yves Chibon |
359db9 |
issue_id=issue.id,
|
|
Pierre-Yves Chibon |
359db9 |
comment=comment,
|
|
Pierre-Yves Chibon |
e1372f |
user_id=user_obj.id,
|
|
Pierre-Yves Chibon |
359db9 |
)
|
|
Pierre-Yves Chibon |
359db9 |
session.add(isse_comment)
|
|
Pierre-Yves Chibon |
359db9 |
# Make sure we won't have SQLAlchemy error before we create the repo
|
|
Pierre-Yves Chibon |
359db9 |
session.flush()
|
|
Pierre-Yves Chibon |
359db9 |
|
|
Pierre-Yves Chibon |
a34835 |
update_git_ticket(issue, repo=issue.project, ticketfolder=ticketfolder)
|
|
Pierre-Yves Chibon |
a34835 |
|
|
Pierre-Yves Chibon |
359db9 |
return 'Comment added'
|
|
Pierre-Yves Chibon |
359db9 |
|
|
Pierre-Yves Chibon |
359db9 |
|
|
Pierre-Yves Chibon |
2c11b4 |
def add_pull_request_comment(session, request, commit, row, comment, user):
|
|
Pierre-Yves Chibon |
2c11b4 |
''' Add a comment to a pull-request. '''
|
|
Pierre-Yves Chibon |
2c11b4 |
user_obj = get_user(session, user)
|
|
Pierre-Yves Chibon |
2c11b4 |
if not user_obj:
|
|
Pierre-Yves Chibon |
2c11b4 |
user_obj = get_user_by_email(session, user)
|
|
Pierre-Yves Chibon |
2c11b4 |
|
|
Pierre-Yves Chibon |
2c11b4 |
if not user_obj:
|
|
Pierre-Yves Chibon |
2c11b4 |
raise progit.exceptions.ProgitException(
|
|
Pierre-Yves Chibon |
2c11b4 |
'No user "%s" found' % user
|
|
Pierre-Yves Chibon |
2c11b4 |
)
|
|
Pierre-Yves Chibon |
2c11b4 |
|
|
Pierre-Yves Chibon |
2c11b4 |
pr_comment = model.PullRequestComment(
|
|
Pierre-Yves Chibon |
2c11b4 |
pull_request_id=request.id,
|
|
Pierre-Yves Chibon |
2c11b4 |
commit_id=commit,
|
|
Pierre-Yves Chibon |
2c11b4 |
line=row,
|
|
Pierre-Yves Chibon |
2c11b4 |
comment=comment,
|
|
Pierre-Yves Chibon |
2c11b4 |
user_id=user_obj.id,
|
|
Pierre-Yves Chibon |
2c11b4 |
)
|
|
Pierre-Yves Chibon |
2c11b4 |
session.add(pr_comment)
|
|
Pierre-Yves Chibon |
2c11b4 |
# Make sure we won't have SQLAlchemy error before we create the repo
|
|
Pierre-Yves Chibon |
2c11b4 |
session.flush()
|
|
Pierre-Yves Chibon |
2c11b4 |
|
|
Pierre-Yves Chibon |
2c11b4 |
return 'Comment added'
|
|
Pierre-Yves Chibon |
2c11b4 |
|
|
Pierre-Yves Chibon |
2c11b4 |
|
|
Pierre-Yves Chibon |
1e2e25 |
def get_user_project(session, username):
|
|
Pierre-Yves Chibon |
1e2e25 |
''' Retrieve the list of projects managed by a user.
|
|
Pierre-Yves Chibon |
1e2e25 |
|
|
Pierre-Yves Chibon |
1e2e25 |
'''
|
|
Pierre-Yves Chibon |
1e2e25 |
|
|
Pierre-Yves Chibon |
1e2e25 |
query = session.query(
|
|
Pierre-Yves Chibon |
1e2e25 |
model.Project
|
|
Pierre-Yves Chibon |
1e2e25 |
).filter(
|
|
Pierre-Yves Chibon |
1e2e25 |
model.Project.user == username
|
|
Pierre-Yves Chibon |
1e2e25 |
)
|
|
Pierre-Yves Chibon |
1e2e25 |
|
|
Pierre-Yves Chibon |
1e2e25 |
return query.all()
|
|
Pierre-Yves Chibon |
d8110b |
|
|
Pierre-Yves Chibon |
d8110b |
|
|
Pierre-Yves Chibon |
49b899 |
def new_project(session, user, name, gitfolder, docfolder, ticketfolder,
|
|
Pierre-Yves Chibon |
d8110b |
description=None, parent_id=None):
|
|
Pierre-Yves Chibon |
d8110b |
''' Create a new project based on the information provided.
|
|
Pierre-Yves Chibon |
d8110b |
'''
|
|
Pierre-Yves Chibon |
6160b6 |
gitrepo = os.path.join(gitfolder, '%s.git' % name)
|
|
Pierre-Yves Chibon |
d8110b |
if os.path.exists(gitrepo):
|
|
Pierre-Yves Chibon |
d8110b |
raise progit.exceptions.RepoExistsException(
|
|
Pierre-Yves Chibon |
ca47fa |
'The project repo "%s" already exists' % name
|
|
Pierre-Yves Chibon |
d8110b |
)
|
|
Pierre-Yves Chibon |
d8110b |
|
|
Pierre-Yves Chibon |
3ddae1 |
user_obj = get_user(session, user)
|
|
Pierre-Yves Chibon |
e1372f |
|
|
Pierre-Yves Chibon |
e1372f |
if not user_obj:
|
|
Pierre-Yves Chibon |
e1372f |
raise progit.exceptions.ProgitException(
|
|
Pierre-Yves Chibon |
e1372f |
'No user "%s" found' % user
|
|
Pierre-Yves Chibon |
e1372f |
)
|
|
Pierre-Yves Chibon |
e1372f |
|
|
Pierre-Yves Chibon |
d8110b |
project = model.Project(
|
|
Pierre-Yves Chibon |
d8110b |
name=name,
|
|
Pierre-Yves Chibon |
d8110b |
description=description,
|
|
Pierre-Yves Chibon |
e1372f |
user_id=user_obj.id,
|
|
Pierre-Yves Chibon |
d8110b |
parent_id=parent_id
|
|
Pierre-Yves Chibon |
d8110b |
)
|
|
Pierre-Yves Chibon |
d8110b |
session.add(project)
|
|
Pierre-Yves Chibon |
d8110b |
# Make sure we won't have SQLAlchemy error before we create the repo
|
|
Pierre-Yves Chibon |
d8110b |
session.flush()
|
|
Pierre-Yves Chibon |
d8110b |
|
|
Pierre-Yves Chibon |
d8110b |
pygit2.init_repository(gitrepo, bare=True)
|
|
Pierre-Yves Chibon |
d8110b |
|
|
Pierre-Yves Chibon |
6160b6 |
gitrepo = os.path.join(docfolder, project.path)
|
|
Pierre-Yves Chibon |
6160b6 |
if os.path.exists(gitrepo):
|
|
Pierre-Yves Chibon |
6160b6 |
raise progit.exceptions.RepoExistsException(
|
|
Pierre-Yves Chibon |
ca47fa |
'The docs repo "%s" already exists' % project.path
|
|
Pierre-Yves Chibon |
6160b6 |
)
|
|
Pierre-Yves Chibon |
6160b6 |
pygit2.init_repository(gitrepo, bare=True)
|
|
Pierre-Yves Chibon |
6160b6 |
|
|
Pierre-Yves Chibon |
49b899 |
gitrepo = os.path.join(ticketfolder, project.path)
|
|
Pierre-Yves Chibon |
49b899 |
if os.path.exists(gitrepo):
|
|
Pierre-Yves Chibon |
49b899 |
raise progit.exceptions.RepoExistsException(
|
|
Pierre-Yves Chibon |
49b899 |
'The tickets repo "%s" already exists' % project.path
|
|
Pierre-Yves Chibon |
49b899 |
)
|
|
Pierre-Yves Chibon |
49b899 |
pygit2.init_repository(gitrepo, bare=True)
|
|
Pierre-Yves Chibon |
49b899 |
|
|
Pierre-Yves Chibon |
d8110b |
return 'Project "%s" created' % name
|
|
Mathieu Bridon |
eb729c |
|
|
Pierre-Yves Chibon |
f74093 |
|
|
Pierre-Yves Chibon |
a34835 |
def new_issue(session, repo, title, content, user, ticketfolder):
|
|
Pierre-Yves Chibon |
33ff2c |
''' Create a new issue for the specified repo. '''
|
|
Pierre-Yves Chibon |
3ddae1 |
user_obj = get_user(session, user)
|
|
Pierre-Yves Chibon |
e1372f |
|
|
Pierre-Yves Chibon |
e1372f |
if not user_obj:
|
|
Pierre-Yves Chibon |
e1372f |
raise progit.exceptions.ProgitException(
|
|
Pierre-Yves Chibon |
e1372f |
'No user "%s" found' % user
|
|
Pierre-Yves Chibon |
e1372f |
)
|
|
Pierre-Yves Chibon |
e1372f |
|
|
Pierre-Yves Chibon |
33ff2c |
issue = model.Issue(
|
|
Pierre-Yves Chibon |
33ff2c |
project_id=repo.id,
|
|
Pierre-Yves Chibon |
33ff2c |
title=title,
|
|
Pierre-Yves Chibon |
33ff2c |
content=content,
|
|
Pierre-Yves Chibon |
e1372f |
user_id=user_obj.id,
|
|
Pierre-Yves Chibon |
9cb884 |
uid=uuid.uuid4().hex,
|
|
Pierre-Yves Chibon |
33ff2c |
)
|
|
Pierre-Yves Chibon |
33ff2c |
session.add(issue)
|
|
Pierre-Yves Chibon |
057ee1 |
# Make sure we won't have SQLAlchemy error before we create the issue
|
|
Pierre-Yves Chibon |
33ff2c |
session.flush()
|
|
Pierre-Yves Chibon |
33ff2c |
|
|
Pierre-Yves Chibon |
e1690f |
global_id = model.GlobalId(
|
|
Pierre-Yves Chibon |
e1690f |
project_id=repo.id,
|
|
Pierre-Yves Chibon |
e1690f |
issue_id=issue.id,
|
|
Pierre-Yves Chibon |
e1690f |
)
|
|
Pierre-Yves Chibon |
e1690f |
|
|
Pierre-Yves Chibon |
e1690f |
session.add(global_id)
|
|
Pierre-Yves Chibon |
e1690f |
session.flush()
|
|
Pierre-Yves Chibon |
e1690f |
|
|
Pierre-Yves Chibon |
a34835 |
update_git_ticket(issue, repo=repo, ticketfolder=ticketfolder)
|
|
Pierre-Yves Chibon |
a34835 |
|
|
Pierre-Yves Chibon |
33ff2c |
return 'Issue created'
|
|
Pierre-Yves Chibon |
33ff2c |
|
|
Pierre-Yves Chibon |
33ff2c |
|
|
Pierre-Yves Chibon |
62ec72 |
def new_pull_request(
|
|
Pierre-Yves Chibon |
62ec72 |
session, repo, repo_from, title, user, stop_id, start_id=None):
|
|
Pierre-Yves Chibon |
472a61 |
''' Create a new pull request on the specified repo. '''
|
|
Pierre-Yves Chibon |
3ddae1 |
user_obj = get_user(session, user)
|
|
Pierre-Yves Chibon |
7d23c0 |
|
|
Pierre-Yves Chibon |
7d23c0 |
if not user_obj:
|
|
Pierre-Yves Chibon |
7d23c0 |
raise progit.exceptions.ProgitException(
|
|
Pierre-Yves Chibon |
7d23c0 |
'No user "%s" found' % user
|
|
Pierre-Yves Chibon |
7d23c0 |
)
|
|
Pierre-Yves Chibon |
7d23c0 |
|
|
Pierre-Yves Chibon |
472a61 |
request = model.PullRequest(
|
|
Pierre-Yves Chibon |
472a61 |
project_id=repo.id,
|
|
Pierre-Yves Chibon |
62ec72 |
project_id_from=repo_from.id,
|
|
Pierre-Yves Chibon |
472a61 |
title=title,
|
|
Pierre-Yves Chibon |
472a61 |
start_id=start_id,
|
|
Pierre-Yves Chibon |
472a61 |
stop_id=stop_id,
|
|
Pierre-Yves Chibon |
7d23c0 |
user_id=user_obj.id,
|
|
Pierre-Yves Chibon |
472a61 |
)
|
|
Pierre-Yves Chibon |
472a61 |
session.add(request)
|
|
Pierre-Yves Chibon |
472a61 |
# Make sure we won't have SQLAlchemy error before we create the request
|
|
Pierre-Yves Chibon |
472a61 |
session.flush()
|
|
Pierre-Yves Chibon |
472a61 |
|
|
Pierre-Yves Chibon |
3a3f5e |
global_id = model.GlobalId(
|
|
Pierre-Yves Chibon |
3a3f5e |
project_id=repo.id,
|
|
Pierre-Yves Chibon |
3a3f5e |
request_id=request.id,
|
|
Pierre-Yves Chibon |
3a3f5e |
)
|
|
Pierre-Yves Chibon |
3a3f5e |
|
|
Pierre-Yves Chibon |
3a3f5e |
session.add(global_id)
|
|
Pierre-Yves Chibon |
3a3f5e |
session.flush()
|
|
Pierre-Yves Chibon |
3a3f5e |
|
|
Pierre-Yves Chibon |
472a61 |
return 'Request created'
|
|
Pierre-Yves Chibon |
472a61 |
|
|
Pierre-Yves Chibon |
472a61 |
|
|
Pierre-Yves Chibon |
a34835 |
def edit_issue(session, issue, ticketfolder,
|
|
Pierre-Yves Chibon |
a34835 |
title=None, content=None, status=None):
|
|
Pierre-Yves Chibon |
c71370 |
''' Edit the specified issue.
|
|
Pierre-Yves Chibon |
c71370 |
'''
|
|
Pierre-Yves Chibon |
c71370 |
edit = []
|
|
Pierre-Yves Chibon |
fb8b6c |
if title and title != issue.title:
|
|
Pierre-Yves Chibon |
c71370 |
issue.title = title
|
|
Pierre-Yves Chibon |
c71370 |
edit.append('title')
|
|
Pierre-Yves Chibon |
fb8b6c |
if content and content != issue.content:
|
|
Pierre-Yves Chibon |
c71370 |
issue.content = content
|
|
Pierre-Yves Chibon |
c71370 |
edit.append('content')
|
|
Pierre-Yves Chibon |
fb8b6c |
if status and status != issue.status:
|
|
Pierre-Yves Chibon |
4d1cbe |
issue.status = status
|
|
Pierre-Yves Chibon |
4d1cbe |
edit.append('status')
|
|
Pierre-Yves Chibon |
c71370 |
|
|
Pierre-Yves Chibon |
65c8d7 |
update_git_ticket(issue, repo=issue.project, ticketfolder=ticketfolder)
|
|
Pierre-Yves Chibon |
a34835 |
|
|
Pierre-Yves Chibon |
c71370 |
if not edit:
|
|
Pierre-Yves Chibon |
c71370 |
return 'No changes to edit'
|
|
Pierre-Yves Chibon |
c71370 |
else:
|
|
Pierre-Yves Chibon |
c71370 |
session.add(issue)
|
|
Pierre-Yves Chibon |
c71370 |
session.flush()
|
|
Pierre-Yves Chibon |
c71370 |
return 'Edited successfully issue #%s' % issue.id
|
|
Pierre-Yves Chibon |
c71370 |
|
|
Pierre-Yves Chibon |
c71370 |
|
|
Pierre-Yves Chibon |
b39aa4 |
def update_project_settings(session, repo, issue_tracker, project_docs):
|
|
Pierre-Yves Chibon |
b39aa4 |
''' Update the settings of a project. '''
|
|
Pierre-Yves Chibon |
b39aa4 |
update = []
|
|
Pierre-Yves Chibon |
b39aa4 |
if issue_tracker != repo.issue_tracker:
|
|
Pierre-Yves Chibon |
b39aa4 |
repo.issue_tracker = issue_tracker
|
|
Pierre-Yves Chibon |
b39aa4 |
update.append('issue_tracker')
|
|
Pierre-Yves Chibon |
b39aa4 |
if project_docs != repo.project_docs:
|
|
Pierre-Yves Chibon |
b39aa4 |
repo.project_docs = project_docs
|
|
Pierre-Yves Chibon |
b39aa4 |
update.append('project_docs')
|
|
Pierre-Yves Chibon |
b39aa4 |
|
|
Pierre-Yves Chibon |
b39aa4 |
if not update:
|
|
Pierre-Yves Chibon |
b39aa4 |
return 'No settings to change'
|
|
Pierre-Yves Chibon |
b39aa4 |
else:
|
|
Pierre-Yves Chibon |
b39aa4 |
session.add(repo)
|
|
Pierre-Yves Chibon |
b39aa4 |
session.flush()
|
|
Pierre-Yves Chibon |
b39aa4 |
return 'Edited successfully setting of repo: %s' % repo.fullname
|
|
Pierre-Yves Chibon |
b39aa4 |
|
|
Pierre-Yves Chibon |
b39aa4 |
|
|
Pierre-Yves Chibon |
a33978 |
def fork_project(session, user, repo, gitfolder,
|
|
Pierre-Yves Chibon |
a33978 |
forkfolder, docfolder,ticketfolder):
|
|
Pierre-Yves Chibon |
652c2c |
''' Fork a given project into the user's forks. '''
|
|
Pierre-Yves Chibon |
df2470 |
if repo.is_fork:
|
|
Pierre-Yves Chibon |
df2470 |
reponame = os.path.join(forkfolder, repo.path)
|
|
Pierre-Yves Chibon |
df2470 |
else:
|
|
Pierre-Yves Chibon |
df2470 |
reponame = os.path.join(gitfolder, repo.path)
|
|
Pierre-Yves Chibon |
df2470 |
forkreponame = '%s.git' % os.path.join(forkfolder, user, repo.name)
|
|
Pierre-Yves Chibon |
652c2c |
|
|
Pierre-Yves Chibon |
9e91eb |
if repo.user.user == user:
|
|
Pierre-Yves Chibon |
9e91eb |
raise progit.exceptions.RepoExistsException(
|
|
Pierre-Yves Chibon |
9e91eb |
'You may not fork your own repo')
|
|
Pierre-Yves Chibon |
9e91eb |
|
|
Pierre-Yves Chibon |
652c2c |
if os.path.exists(forkreponame):
|
|
Pierre-Yves Chibon |
652c2c |
raise progit.exceptions.RepoExistsException(
|
|
Pierre-Yves Chibon |
652c2c |
'Repo "%s/%s" already exists' % (user, repo.name))
|
|
Pierre-Yves Chibon |
652c2c |
|
|
Pierre-Yves Chibon |
3ddae1 |
user_obj = get_user(session, user)
|
|
Pierre-Yves Chibon |
e1372f |
|
|
Pierre-Yves Chibon |
e1372f |
if not user_obj:
|
|
Pierre-Yves Chibon |
e1372f |
raise progit.exceptions.ProgitException(
|
|
Pierre-Yves Chibon |
e1372f |
'No user "%s" found' % user
|
|
Pierre-Yves Chibon |
e1372f |
)
|
|
Pierre-Yves Chibon |
e1372f |
|
|
Pierre-Yves Chibon |
652c2c |
project = model.Project(
|
|
Pierre-Yves Chibon |
652c2c |
name=repo.name,
|
|
Pierre-Yves Chibon |
652c2c |
description=repo.description,
|
|
Pierre-Yves Chibon |
e1372f |
user_id=user_obj.id,
|
|
Pierre-Yves Chibon |
652c2c |
parent_id=repo.id
|
|
Pierre-Yves Chibon |
652c2c |
)
|
|
Pierre-Yves Chibon |
652c2c |
session.add(project)
|
|
Pierre-Yves Chibon |
652c2c |
# Make sure we won't have SQLAlchemy error before we create the repo
|
|
Pierre-Yves Chibon |
652c2c |
session.flush()
|
|
Pierre-Yves Chibon |
652c2c |
|
|
Pierre-Yves Chibon |
d01de7 |
pygit2.clone_repository(reponame, forkreponame, bare=True)
|
|
Pierre-Yves Chibon |
652c2c |
|
|
Pierre-Yves Chibon |
6160b6 |
gitrepo = os.path.join(docfolder, project.path)
|
|
Pierre-Yves Chibon |
6160b6 |
if os.path.exists(gitrepo):
|
|
Pierre-Yves Chibon |
6160b6 |
raise progit.exceptions.RepoExistsException(
|
|
Pierre-Yves Chibon |
4b7a7d |
'The docs "%s" already exists' % project.path
|
|
Pierre-Yves Chibon |
6160b6 |
)
|
|
Pierre-Yves Chibon |
a33978 |
pygit2.init_repository(gitrepo, bare=True)
|
|
Pierre-Yves Chibon |
a33978 |
|
|
Pierre-Yves Chibon |
a33978 |
gitrepo = os.path.join(ticketfolder, project.path)
|
|
Pierre-Yves Chibon |
a33978 |
if os.path.exists(gitrepo):
|
|
Pierre-Yves Chibon |
a33978 |
raise progit.exceptions.RepoExistsException(
|
|
Pierre-Yves Chibon |
a33978 |
'The tickets repo "%s" already exists' % project.path
|
|
Pierre-Yves Chibon |
a33978 |
)
|
|
Pierre-Yves Chibon |
6160b6 |
pygit2.init_repository(gitrepo, bare=True)
|
|
Pierre-Yves Chibon |
6160b6 |
|
|
Pierre-Yves Chibon |
652c2c |
return 'Repo "%s" cloned to "%s/%s"' % (repo.name, user, repo.name)
|
|
Pierre-Yves Chibon |
652c2c |
|
|
Pierre-Yves Chibon |
652c2c |
|
|
Pierre-Yves Chibon |
ea0ee1 |
def list_projects(
|
|
Pierre-Yves Chibon |
7752a8 |
session, username=None, fork=None,
|
|
Pierre-Yves Chibon |
ea0ee1 |
start=None, limit=None, count=False):
|
|
Pierre-Yves Chibon |
695ef6 |
'''List existing projects
|
|
Pierre-Yves Chibon |
695ef6 |
'''
|
|
Pierre-Yves Chibon |
0b9290 |
projects = session.query(
|
|
Pierre-Yves Chibon |
0b9290 |
model.Project
|
|
Pierre-Yves Chibon |
0b9290 |
).order_by(
|
|
Pierre-Yves Chibon |
0b9290 |
model.Project.date_created
|
|
Pierre-Yves Chibon |
0b9290 |
)
|
|
Mathieu Bridon |
eb729c |
|
|
Pierre-Yves Chibon |
ea0ee1 |
if username is not None:
|
|
Pierre-Yves Chibon |
e1372f |
projects = projects.filter(
|
|
Pierre-Yves Chibon |
e1372f |
model.User.user == username
|
|
Pierre-Yves Chibon |
e1372f |
).filter(
|
|
Pierre-Yves Chibon |
e1372f |
model.User.id == model.Project.user_id
|
|
Pierre-Yves Chibon |
ea0ee1 |
)
|
|
Pierre-Yves Chibon |
ea0ee1 |
|
|
Pierre-Yves Chibon |
7752a8 |
if fork is not None:
|
|
Pierre-Yves Chibon |
7752a8 |
if fork is True:
|
|
Pierre-Yves Chibon |
7752a8 |
projects = projects.filter(
|
|
Pierre-Yves Chibon |
7752a8 |
model.Project.parent_id != None
|
|
Pierre-Yves Chibon |
7752a8 |
)
|
|
Pierre-Yves Chibon |
7752a8 |
elif fork is False:
|
|
Pierre-Yves Chibon |
2f8732 |
projects = projects.filter(
|
|
Pierre-Yves Chibon |
2f8732 |
model.Project.parent_id == None
|
|
Pierre-Yves Chibon |
7752a8 |
)
|
|
Pierre-Yves Chibon |
7752a8 |
|
|
Mathieu Bridon |
eb729c |
if start is not None:
|
|
Mathieu Bridon |
eb729c |
projects = projects.offset(start)
|
|
Mathieu Bridon |
eb729c |
|
|
Mathieu Bridon |
eb729c |
if limit is not None:
|
|
Mathieu Bridon |
eb729c |
projects = projects.limit(limit)
|
|
Mathieu Bridon |
eb729c |
|
|
Pierre-Yves Chibon |
f74093 |
if count:
|
|
Pierre-Yves Chibon |
f74093 |
return projects.count()
|
|
Pierre-Yves Chibon |
f74093 |
else:
|
|
Pierre-Yves Chibon |
f74093 |
return projects.all()
|
|
Mathieu Bridon |
eb729c |
|
|
Mathieu Bridon |
998605 |
|
|
Pierre-Yves Chibon |
929595 |
def get_project(session, name, user=None):
|
|
Pierre-Yves Chibon |
695ef6 |
'''Get a project from the database
|
|
Pierre-Yves Chibon |
695ef6 |
'''
|
|
Pierre-Yves Chibon |
929595 |
query = session.query(
|
|
Pierre-Yves Chibon |
f74093 |
model.Project
|
|
Pierre-Yves Chibon |
178d6f |
).filter(
|
|
Pierre-Yves Chibon |
178d6f |
model.Project.name == name
|
|
Pierre-Yves Chibon |
929595 |
)
|
|
Pierre-Yves Chibon |
1ac00b |
|
|
Pierre-Yves Chibon |
929595 |
if user is not None:
|
|
Pierre-Yves Chibon |
929595 |
query = query.filter(
|
|
Pierre-Yves Chibon |
e1372f |
model.User.user == user
|
|
Pierre-Yves Chibon |
e1372f |
).filter(
|
|
Pierre-Yves Chibon |
e1372f |
model.User.id == model.Project.user_id
|
|
Pierre-Yves Chibon |
1ac00b |
).filter(
|
|
Pierre-Yves Chibon |
1ac00b |
model.Project.parent_id != None
|
|
Pierre-Yves Chibon |
929595 |
)
|
|
Pierre-Yves Chibon |
1ac00b |
else:
|
|
Pierre-Yves Chibon |
1ac00b |
query = query.filter(
|
|
Pierre-Yves Chibon |
1ac00b |
model.Project.parent_id == None
|
|
Pierre-Yves Chibon |
1ac00b |
)
|
|
Pierre-Yves Chibon |
1ac00b |
|
|
Pierre-Yves Chibon |
929595 |
return query.first()
|
|
Pierre-Yves Chibon |
562d75 |
|
|
Pierre-Yves Chibon |
562d75 |
|
|
Pierre-Yves Chibon |
b6df7d |
def get_issues(session, repo, status=None, closed=False):
|
|
Pierre-Yves Chibon |
562d75 |
''' Retrieve all the issues associated to a project
|
|
Pierre-Yves Chibon |
b6df7d |
|
|
Pierre-Yves Chibon |
b6df7d |
Watch out that the closed argument is incompatible with the status
|
|
Pierre-Yves Chibon |
b6df7d |
argument. The closed argument will return all the issues whose status
|
|
Pierre-Yves Chibon |
b6df7d |
is not 'Open', otherwise it will return the issues having the specified
|
|
Pierre-Yves Chibon |
b6df7d |
status.
|
|
Pierre-Yves Chibon |
562d75 |
'''
|
|
Pierre-Yves Chibon |
77e16c |
subquery = session.query(
|
|
Pierre-Yves Chibon |
77e16c |
model.GlobalId,
|
|
Pierre-Yves Chibon |
77e16c |
sqlalchemy.over(
|
|
Pierre-Yves Chibon |
77e16c |
sqlalchemy.func.row_number(),
|
|
Pierre-Yves Chibon |
77e16c |
partition_by=model.GlobalId.project_id,
|
|
Pierre-Yves Chibon |
77e16c |
order_by=model.GlobalId.id
|
|
Pierre-Yves Chibon |
77e16c |
).label('global_id')
|
|
Pierre-Yves Chibon |
77e16c |
).subquery()
|
|
Pierre-Yves Chibon |
77e16c |
|
|
Pierre-Yves Chibon |
562d75 |
query = session.query(
|
|
Pierre-Yves Chibon |
77e16c |
model.Issue,
|
|
Pierre-Yves Chibon |
77e16c |
subquery.c.global_id
|
|
Pierre-Yves Chibon |
77e16c |
).filter(
|
|
Pierre-Yves Chibon |
77e16c |
subquery.c.issue_id == model.Issue.id
|
|
Pierre-Yves Chibon |
562d75 |
).filter(
|
|
Pierre-Yves Chibon |
77e16c |
subquery.c.project_id == model.Issue.project_id
|
|
Pierre-Yves Chibon |
95f042 |
).filter(
|
|
Pierre-Yves Chibon |
95f042 |
model.Issue.project_id == repo.id
|
|
Pierre-Yves Chibon |
3a2a1c |
).order_by(
|
|
Pierre-Yves Chibon |
3a2a1c |
model.Issue.id
|
|
Pierre-Yves Chibon |
562d75 |
)
|
|
Pierre-Yves Chibon |
562d75 |
|
|
Pierre-Yves Chibon |
b6df7d |
if status is not None and not closed:
|
|
Pierre-Yves Chibon |
4d1cbe |
query = query.filter(
|
|
Pierre-Yves Chibon |
4d1cbe |
model.Issue.status == status
|
|
Pierre-Yves Chibon |
4d1cbe |
)
|
|
Pierre-Yves Chibon |
b6df7d |
if closed:
|
|
Pierre-Yves Chibon |
b6df7d |
query = query.filter(
|
|
Pierre-Yves Chibon |
b6df7d |
model.Issue.status != 'Open'
|
|
Pierre-Yves Chibon |
b6df7d |
)
|
|
Pierre-Yves Chibon |
4d1cbe |
|
|
Pierre-Yves Chibon |
562d75 |
return query.all()
|
|
Pierre-Yves Chibon |
562d75 |
|
|
Pierre-Yves Chibon |
562d75 |
|
|
Pierre-Yves Chibon |
feb7c1 |
def get_issue(session, issueid):
|
|
Pierre-Yves Chibon |
562d75 |
''' Retrieve the specified issue
|
|
Pierre-Yves Chibon |
562d75 |
'''
|
|
Pierre-Yves Chibon |
251d96 |
subquery = session.query(
|
|
Pierre-Yves Chibon |
251d96 |
model.GlobalId,
|
|
Pierre-Yves Chibon |
251d96 |
sqlalchemy.over(
|
|
Pierre-Yves Chibon |
251d96 |
sqlalchemy.func.row_number(),
|
|
Pierre-Yves Chibon |
251d96 |
partition_by=model.GlobalId.project_id,
|
|
Pierre-Yves Chibon |
251d96 |
order_by=model.GlobalId.id
|
|
Pierre-Yves Chibon |
251d96 |
).label('global_id')
|
|
Pierre-Yves Chibon |
251d96 |
).subquery()
|
|
Pierre-Yves Chibon |
251d96 |
|
|
Pierre-Yves Chibon |
562d75 |
query = session.query(
|
|
Pierre-Yves Chibon |
562d75 |
model.Issue
|
|
Pierre-Yves Chibon |
562d75 |
).filter(
|
|
Pierre-Yves Chibon |
251d96 |
subquery.c.project_id == model.Issue.project_id
|
|
Pierre-Yves Chibon |
251d96 |
).filter(
|
|
Pierre-Yves Chibon |
a93753 |
subquery.c.issue_id == model.Issue.id
|
|
Pierre-Yves Chibon |
a93753 |
).filter(
|
|
Pierre-Yves Chibon |
251d96 |
subquery.c.global_id == issueid
|
|
Pierre-Yves Chibon |
3a2a1c |
).order_by(
|
|
Pierre-Yves Chibon |
3a2a1c |
model.Issue.id
|
|
Pierre-Yves Chibon |
562d75 |
)
|
|
Pierre-Yves Chibon |
562d75 |
|
|
Pierre-Yves Chibon |
562d75 |
return query.first()
|
|
Pierre-Yves Chibon |
35112d |
|
|
Pierre-Yves Chibon |
35112d |
|
|
Pierre-Yves Chibon |
b0265c |
def get_pull_requests(
|
|
Pierre-Yves Chibon |
b0265c |
session, project_id=None, project_id_from=None, status=None):
|
|
Pierre-Yves Chibon |
b0265c |
''' Retrieve the specified issue
|
|
Pierre-Yves Chibon |
b0265c |
'''
|
|
Pierre-Yves Chibon |
33e9fc |
|
|
Pierre-Yves Chibon |
33e9fc |
subquery = session.query(
|
|
Pierre-Yves Chibon |
33e9fc |
model.GlobalId,
|
|
Pierre-Yves Chibon |
33e9fc |
sqlalchemy.over(
|
|
Pierre-Yves Chibon |
33e9fc |
sqlalchemy.func.row_number(),
|
|
Pierre-Yves Chibon |
33e9fc |
partition_by=model.GlobalId.project_id,
|
|
Pierre-Yves Chibon |
33e9fc |
order_by=model.GlobalId.id
|
|
Pierre-Yves Chibon |
33e9fc |
).label('global_id')
|
|
Pierre-Yves Chibon |
33e9fc |
).subquery()
|
|
Pierre-Yves Chibon |
33e9fc |
|
|
Pierre-Yves Chibon |
b0265c |
query = session.query(
|
|
Pierre-Yves Chibon |
33e9fc |
model.PullRequest,
|
|
Pierre-Yves Chibon |
33e9fc |
subquery.c.global_id
|
|
Pierre-Yves Chibon |
33e9fc |
).filter(
|
|
Pierre-Yves Chibon |
33e9fc |
subquery.c.request_id == model.PullRequest.id
|
|
Pierre-Yves Chibon |
33e9fc |
).filter(
|
|
Pierre-Yves Chibon |
33e9fc |
subquery.c.project_id == model.PullRequest.project_id
|
|
Pierre-Yves Chibon |
3a2a1c |
).order_by(
|
|
Pierre-Yves Chibon |
3a2a1c |
model.PullRequest.id
|
|
Pierre-Yves Chibon |
b0265c |
)
|
|
Pierre-Yves Chibon |
b0265c |
|
|
Pierre-Yves Chibon |
b0265c |
if project_id:
|
|
Pierre-Yves Chibon |
b0265c |
query = query.filter(
|
|
Pierre-Yves Chibon |
b0265c |
model.PullRequest.project_id == project_id
|
|
Pierre-Yves Chibon |
b0265c |
)
|
|
Pierre-Yves Chibon |
b0265c |
|
|
Pierre-Yves Chibon |
b0265c |
if project_id_from:
|
|
Pierre-Yves Chibon |
b0265c |
query = query.filter(
|
|
Pierre-Yves Chibon |
b0265c |
model.PullRequest.project_id_from == project_id_from
|
|
Pierre-Yves Chibon |
b0265c |
)
|
|
Pierre-Yves Chibon |
b0265c |
|
|
Pierre-Yves Chibon |
b0265c |
if status is not None:
|
|
Pierre-Yves Chibon |
b0265c |
query = query.filter(
|
|
Pierre-Yves Chibon |
b0265c |
model.PullRequest.status == status
|
|
Pierre-Yves Chibon |
b0265c |
)
|
|
Pierre-Yves Chibon |
b0265c |
|
|
Pierre-Yves Chibon |
b0265c |
return query.all()
|
|
Pierre-Yves Chibon |
b0265c |
|
|
Pierre-Yves Chibon |
b0265c |
|
|
Pierre-Yves Chibon |
35112d |
def get_pull_request(
|
|
Pierre-Yves Chibon |
35112d |
session, requestid, project_id=None, project_id_from=None):
|
|
Pierre-Yves Chibon |
35112d |
''' Retrieve the specified issue
|
|
Pierre-Yves Chibon |
35112d |
'''
|
|
Pierre-Yves Chibon |
3f844b |
|
|
Pierre-Yves Chibon |
3f844b |
subquery = session.query(
|
|
Pierre-Yves Chibon |
3f844b |
model.GlobalId,
|
|
Pierre-Yves Chibon |
3f844b |
sqlalchemy.over(
|
|
Pierre-Yves Chibon |
3f844b |
sqlalchemy.func.row_number(),
|
|
Pierre-Yves Chibon |
3f844b |
partition_by=model.GlobalId.project_id,
|
|
Pierre-Yves Chibon |
3f844b |
order_by=model.GlobalId.id
|
|
Pierre-Yves Chibon |
3f844b |
).label('global_id')
|
|
Pierre-Yves Chibon |
3f844b |
).subquery()
|
|
Pierre-Yves Chibon |
3f844b |
|
|
Pierre-Yves Chibon |
35112d |
query = session.query(
|
|
Pierre-Yves Chibon |
35112d |
model.PullRequest
|
|
Pierre-Yves Chibon |
35112d |
).filter(
|
|
Pierre-Yves Chibon |
3f844b |
subquery.c.project_id == model.PullRequest.project_id
|
|
Pierre-Yves Chibon |
3f844b |
).filter(
|
|
Pierre-Yves Chibon |
9a1f18 |
subquery.c.request_id == model.PullRequest.id
|
|
Pierre-Yves Chibon |
9a1f18 |
).filter(
|
|
Pierre-Yves Chibon |
3f844b |
subquery.c.global_id == requestid
|
|
Pierre-Yves Chibon |
9a1f18 |
).order_by(
|
|
Pierre-Yves Chibon |
9a1f18 |
model.PullRequest.id
|
|
Pierre-Yves Chibon |
35112d |
)
|
|
Pierre-Yves Chibon |
35112d |
|
|
Pierre-Yves Chibon |
35112d |
if project_id:
|
|
Pierre-Yves Chibon |
35112d |
query = query.filter(
|
|
Pierre-Yves Chibon |
35112d |
model.PullRequest.project_id == project_id
|
|
Pierre-Yves Chibon |
35112d |
)
|
|
Pierre-Yves Chibon |
35112d |
|
|
Pierre-Yves Chibon |
35112d |
if project_id_from:
|
|
Pierre-Yves Chibon |
35112d |
query = query.filter(
|
|
Pierre-Yves Chibon |
35112d |
model.PullRequest.project_id_from == project_id_from
|
|
Pierre-Yves Chibon |
35112d |
)
|
|
Pierre-Yves Chibon |
35112d |
|
|
Pierre-Yves Chibon |
35112d |
return query.first()
|
|
Pierre-Yves Chibon |
42a02c |
|
|
Pierre-Yves Chibon |
42a02c |
|
|
Pierre-Yves Chibon |
42a02c |
def close_pull_request(session, request):
|
|
Pierre-Yves Chibon |
42a02c |
''' Close the provided pull-request.
|
|
Pierre-Yves Chibon |
42a02c |
'''
|
|
Pierre-Yves Chibon |
42a02c |
request.status = False
|
|
Pierre-Yves Chibon |
42a02c |
session.add(request)
|
|
Pierre-Yves Chibon |
42a02c |
session.flush()
|
|
Pierre-Yves Chibon |
4d1cbe |
|
|
Pierre-Yves Chibon |
4d1cbe |
|
|
Pierre-Yves Chibon |
4d1cbe |
def get_issue_statuses(session):
|
|
Pierre-Yves Chibon |
4d1cbe |
''' Return the complete list of status an issue can have.
|
|
Pierre-Yves Chibon |
4d1cbe |
'''
|
|
Pierre-Yves Chibon |
4d1cbe |
output = []
|
|
Pierre-Yves Chibon |
4d1cbe |
statuses = session.query(model.StatusIssue).all()
|
|
Pierre-Yves Chibon |
4d1cbe |
for status in statuses:
|
|
Pierre-Yves Chibon |
4d1cbe |
output.append(status.status)
|
|
Pierre-Yves Chibon |
4d1cbe |
return output
|
|
Pierre-Yves Chibon |
7c47d2 |
|
|
Pierre-Yves Chibon |
7c47d2 |
|
|
Pierre-Yves Chibon |
7c47d2 |
def generate_gitolite_acls(session, configfile):
|
|
Pierre-Yves Chibon |
7c47d2 |
''' Generate the configuration file for gitolite for all projects
|
|
Pierre-Yves Chibon |
7c47d2 |
on the forge.
|
|
Pierre-Yves Chibon |
7c47d2 |
'''
|
|
Pierre-Yves Chibon |
7c47d2 |
config = []
|
|
Pierre-Yves Chibon |
7c47d2 |
for project in session.query(model.Project).all():
|
|
Pierre-Yves Chibon |
7f72e8 |
if project.parent_id:
|
|
Pierre-Yves Chibon |
7f72e8 |
config.append('repo forks/%s' % project.fullname)
|
|
Pierre-Yves Chibon |
7f72e8 |
else:
|
|
Pierre-Yves Chibon |
7f72e8 |
config.append('repo %s' % project.fullname)
|
|
Pierre-Yves Chibon |
dfe989 |
config.append(' RW+ = %s' % project.user.user)
|
|
Pierre-Yves Chibon |
7c47d2 |
for user in project.users:
|
|
Pierre-Yves Chibon |
7c47d2 |
if user != project.user:
|
|
Pierre-Yves Chibon |
3562ab |
config.append(' RW+ = %s' % user.user.user)
|
|
Pierre-Yves Chibon |
7c47d2 |
config.append('')
|
|
Pierre-Yves Chibon |
7c47d2 |
|
|
Pierre-Yves Chibon |
3cec45 |
config.append('repo docs/%s' % project.fullname)
|
|
Pierre-Yves Chibon |
3cec45 |
config.append(' RW+ = %s' % project.user.user)
|
|
Pierre-Yves Chibon |
3cec45 |
for user in project.users:
|
|
Pierre-Yves Chibon |
3cec45 |
if user != project.user:
|
|
Pierre-Yves Chibon |
3562ab |
config.append(' RW+ = %s' % user.user.user)
|
|
Pierre-Yves Chibon |
3cec45 |
config.append('')
|
|
Pierre-Yves Chibon |
3cec45 |
|
|
Pierre-Yves Chibon |
1a37c6 |
config.append('repo tickets/%s' % project.fullname)
|
|
Pierre-Yves Chibon |
1a37c6 |
config.append(' RW+ = %s' % project.user.user)
|
|
Pierre-Yves Chibon |
1a37c6 |
for user in project.users:
|
|
Pierre-Yves Chibon |
1a37c6 |
if user != project.user:
|
|
Pierre-Yves Chibon |
3562ab |
config.append(' RW+ = %s' % user.user.user)
|
|
Pierre-Yves Chibon |
1a37c6 |
config.append('')
|
|
Pierre-Yves Chibon |
1a37c6 |
|
|
Pierre-Yves Chibon |
edd115 |
with open(configfile, 'w') as stream:
|
|
Pierre-Yves Chibon |
9df3ed |
for row in config:
|
|
Pierre-Yves Chibon |
30ec31 |
stream.write(row + '\n')
|
|
Pierre-Yves Chibon |
c2aa0d |
|
|
Pierre-Yves Chibon |
c2aa0d |
|
|
Pierre-Yves Chibon |
c2aa0d |
def set_up_user(session, username, fullname, user_email):
|
|
Pierre-Yves Chibon |
c2aa0d |
''' Set up a new user into the database or update its information. '''
|
|
Pierre-Yves Chibon |
03c11f |
user = get_user(session, username)
|
|
Pierre-Yves Chibon |
c2aa0d |
if not user:
|
|
Pierre-Yves Chibon |
c2aa0d |
user = model.User(
|
|
Pierre-Yves Chibon |
c2aa0d |
user=username,
|
|
Pierre-Yves Chibon |
c2aa0d |
fullname=fullname)
|
|
Pierre-Yves Chibon |
c2aa0d |
session.add(user)
|
|
Pierre-Yves Chibon |
c2aa0d |
session.flush()
|
|
Pierre-Yves Chibon |
c2aa0d |
|
|
Pierre-Yves Chibon |
c2aa0d |
if user.fullname != fullname:
|
|
Pierre-Yves Chibon |
c2aa0d |
user.fullname = fullname
|
|
Pierre-Yves Chibon |
c2aa0d |
session.add(user)
|
|
Pierre-Yves Chibon |
c2aa0d |
session.flush()
|
|
Pierre-Yves Chibon |
c2aa0d |
|
|
Pierre-Yves Chibon |
8b2894 |
emails = [email.email for email in user.emails]
|
|
Pierre-Yves Chibon |
8b2894 |
if user_email not in emails:
|
|
Pierre-Yves Chibon |
c2aa0d |
useremail = model.UserEmail(
|
|
Pierre-Yves Chibon |
c2aa0d |
user_id=user.id,
|
|
Pierre-Yves Chibon |
c2aa0d |
email=user_email)
|
|
Pierre-Yves Chibon |
c2aa0d |
session.add(useremail)
|
|
Pierre-Yves Chibon |
c2aa0d |
session.flush()
|
|
Pierre-Yves Chibon |
8f25f2 |
|
|
Pierre-Yves Chibon |
8f25f2 |
|
|
Pierre-Yves Chibon |
8f25f2 |
def update_user_ssh(session, user, ssh_key):
|
|
Pierre-Yves Chibon |
8f25f2 |
''' Set up a new user into the database or update its information. '''
|
|
Pierre-Yves Chibon |
8f25f2 |
if isinstance(user, basestring):
|
|
Pierre-Yves Chibon |
8f25f2 |
user = get_user(session, user)
|
|
Pierre-Yves Chibon |
8f25f2 |
|
|
Pierre-Yves Chibon |
8f25f2 |
message = 'Nothing to update'
|
|
Pierre-Yves Chibon |
8f25f2 |
|
|
Pierre-Yves Chibon |
8f25f2 |
if ssh_key != user.public_ssh_key:
|
|
Pierre-Yves Chibon |
8f25f2 |
user.public_ssh_key = ssh_key
|
|
Pierre-Yves Chibon |
8f25f2 |
session.add(user)
|
|
Pierre-Yves Chibon |
8f25f2 |
session.flush()
|
|
Pierre-Yves Chibon |
8f25f2 |
message = 'Public ssh key updated'
|
|
Pierre-Yves Chibon |
8f25f2 |
|
|
Pierre-Yves Chibon |
8f25f2 |
return message
|
|
Pierre-Yves Chibon |
f7d963 |
|
|
Pierre-Yves Chibon |
f7d963 |
|
|
Pierre-Yves Chibon |
f7d963 |
def issue_to_json(issue):
|
|
Pierre-Yves Chibon |
f7d963 |
""" Convert all the data related to an issue (a ticket) as json object.
|
|
Pierre-Yves Chibon |
f7d963 |
|
|
Pierre-Yves Chibon |
f7d963 |
"""
|
|
Pierre-Yves Chibon |
f7d963 |
output = {
|
|
Pierre-Yves Chibon |
f7d963 |
'title': issue.title,
|
|
Pierre-Yves Chibon |
f7d963 |
'content': issue.content,
|
|
Pierre-Yves Chibon |
f7d963 |
'status': issue.status,
|
|
Pierre-Yves Chibon |
f7d963 |
'date_created': issue.date_created.strftime('%s'),
|
|
Pierre-Yves Chibon |
f7d963 |
'user': {
|
|
Pierre-Yves Chibon |
f7d963 |
'name': issue.user.user,
|
|
Pierre-Yves Chibon |
f7d963 |
'emails': [email.email for email in issue.user.emails],
|
|
Pierre-Yves Chibon |
f7d963 |
}
|
|
Pierre-Yves Chibon |
f7d963 |
}
|
|
Pierre-Yves Chibon |
f7d963 |
|
|
Pierre-Yves Chibon |
f7d963 |
comments = []
|
|
Pierre-Yves Chibon |
f7d963 |
for comment in issue.comments:
|
|
Pierre-Yves Chibon |
f7d963 |
cmt = {
|
|
Pierre-Yves Chibon |
f7d963 |
'id': comment.id,
|
|
Pierre-Yves Chibon |
f7d963 |
'comment': comment.comment,
|
|
Pierre-Yves Chibon |
f7d963 |
'parent': comment.parent_id,
|
|
Pierre-Yves Chibon |
f7d963 |
'date_created': comment.date_created.strftime('%s'),
|
|
Pierre-Yves Chibon |
f7d963 |
'user': {
|
|
Pierre-Yves Chibon |
f7d963 |
'name': comment.user.user,
|
|
Pierre-Yves Chibon |
f7d963 |
'emails': [email.email for email in comment.user.emails],
|
|
Pierre-Yves Chibon |
f7d963 |
}
|
|
Pierre-Yves Chibon |
f7d963 |
}
|
|
Pierre-Yves Chibon |
f7d963 |
comments.append(cmt)
|
|
Pierre-Yves Chibon |
f7d963 |
|
|
Pierre-Yves Chibon |
f7d963 |
output['comments'] = comments
|
|
Pierre-Yves Chibon |
f7d963 |
|
|
Pierre-Yves Chibon |
f7d963 |
return json.dumps(output)
|
|
Pierre-Yves Chibon |
d133cd |
|
|
Pierre-Yves Chibon |
d133cd |
|
|
Pierre-Yves Chibon |
d133cd |
def update_git_ticket(issue, repo, ticketfolder):
|
|
Pierre-Yves Chibon |
d133cd |
""" Update the given issue in its git.
|
|
Pierre-Yves Chibon |
d133cd |
|
|
Pierre-Yves Chibon |
d133cd |
This method forks the provided repo, add/edit the issue whose file name
|
|
Pierre-Yves Chibon |
d133cd |
is defined by the uid field of the issue and if there are additions/
|
|
Pierre-Yves Chibon |
d133cd |
changes commit them and push them back to the original repo.
|
|
Pierre-Yves Chibon |
d133cd |
|
|
Pierre-Yves Chibon |
d133cd |
"""
|
|
Pierre-Yves Chibon |
d133cd |
|
|
Pierre-Yves Chibon |
d133cd |
# Get the fork
|
|
Pierre-Yves Chibon |
d133cd |
repopath = os.path.join(ticketfolder, repo.path)
|
|
Pierre-Yves Chibon |
d133cd |
ticket_repo = pygit2.Repository(repopath)
|
|
Pierre-Yves Chibon |
d133cd |
|
|
Pierre-Yves Chibon |
d133cd |
# Clone the repo into a temp folder
|
|
Pierre-Yves Chibon |
d133cd |
newpath = tempfile.mkdtemp()
|
|
Pierre-Yves Chibon |
d133cd |
new_repo = pygit2.clone_repository(repopath, newpath)
|
|
Pierre-Yves Chibon |
d133cd |
|
|
Pierre-Yves Chibon |
d133cd |
file_path = os.path.join(newpath, issue.uid)
|
|
Pierre-Yves Chibon |
d133cd |
|
|
Pierre-Yves Chibon |
d133cd |
# Get the current index
|
|
Pierre-Yves Chibon |
d133cd |
index = new_repo.index
|
|
Pierre-Yves Chibon |
d133cd |
|
|
Pierre-Yves Chibon |
d133cd |
# Are we adding files
|
|
Pierre-Yves Chibon |
d133cd |
added = False
|
|
Pierre-Yves Chibon |
d133cd |
if not os.path.exists(file_path):
|
|
Pierre-Yves Chibon |
d133cd |
added = True
|
|
Pierre-Yves Chibon |
d133cd |
|
|
Pierre-Yves Chibon |
d133cd |
# Write down what changed
|
|
Pierre-Yves Chibon |
d133cd |
with open(file_path, 'w') as stream:
|
|
Pierre-Yves Chibon |
d133cd |
stream.write(issue_to_json(issue))
|
|
Pierre-Yves Chibon |
d133cd |
|
|
Pierre-Yves Chibon |
d133cd |
# Retrieve the list of files that changed
|
|
Pierre-Yves Chibon |
d133cd |
diff = new_repo.diff()
|
|
Pierre-Yves Chibon |
d133cd |
files = [patch.new_file_path for patch in diff]
|
|
Pierre-Yves Chibon |
d133cd |
|
|
Pierre-Yves Chibon |
d133cd |
# Add the changes to the index
|
|
Pierre-Yves Chibon |
d133cd |
if added:
|
|
Pierre-Yves Chibon |
d133cd |
index.add(issue.uid)
|
|
Pierre-Yves Chibon |
d133cd |
for filename in files:
|
|
Pierre-Yves Chibon |
d133cd |
index.add(filename)
|
|
Pierre-Yves Chibon |
d133cd |
|
|
Pierre-Yves Chibon |
d133cd |
# If not change, return
|
|
Pierre-Yves Chibon |
63324c |
if not files and not added:
|
|
Pierre-Yves Chibon |
d133cd |
shutil.rmtree(newpath)
|
|
Pierre-Yves Chibon |
d133cd |
return
|
|
Pierre-Yves Chibon |
d133cd |
|
|
Pierre-Yves Chibon |
d133cd |
# See if there is a parent to this commit
|
|
Pierre-Yves Chibon |
d133cd |
parent = None
|
|
Pierre-Yves Chibon |
d133cd |
try:
|
|
Pierre-Yves Chibon |
d133cd |
parent = new_repo.head.get_object().oid
|
|
Pierre-Yves Chibon |
d133cd |
except pygit2.GitError:
|
|
Pierre-Yves Chibon |
d133cd |
pass
|
|
Pierre-Yves Chibon |
d133cd |
|
|
Pierre-Yves Chibon |
d133cd |
parents = []
|
|
Pierre-Yves Chibon |
d133cd |
if parent:
|
|
Pierre-Yves Chibon |
d133cd |
parents.append(parent)
|
|
Pierre-Yves Chibon |
d133cd |
|
|
Pierre-Yves Chibon |
d133cd |
# Author/commiter will always be this one
|
|
Pierre-Yves Chibon |
d133cd |
author = pygit2.Signature(name='progit', email='progit')
|
|
Pierre-Yves Chibon |
d133cd |
|
|
Pierre-Yves Chibon |
d133cd |
# Actually commit
|
|
Pierre-Yves Chibon |
d133cd |
sha = new_repo.create_commit(
|
|
Pierre-Yves Chibon |
d133cd |
'refs/heads/master',
|
|
Pierre-Yves Chibon |
d133cd |
author,
|
|
Pierre-Yves Chibon |
d133cd |
author,
|
|
Pierre-Yves Chibon |
d133cd |
'Updated ticket %s: %s' % (issue.uid, issue.title),
|
|
Pierre-Yves Chibon |
d133cd |
new_repo.index.write_tree(),
|
|
Pierre-Yves Chibon |
d133cd |
parents)
|
|
Pierre-Yves Chibon |
d133cd |
index.write()
|
|
Pierre-Yves Chibon |
d133cd |
|
|
Pierre-Yves Chibon |
d133cd |
# Push to origin
|
|
Pierre-Yves Chibon |
d133cd |
ori_remote = new_repo.remotes[0]
|
|
Pierre-Yves Chibon |
d133cd |
master_ref = new_repo.lookup_reference('HEAD').resolve()
|
|
Pierre-Yves Chibon |
d133cd |
refname = '%s:%s' % (master_ref.name, master_ref.name)
|
|
Pierre-Yves Chibon |
d133cd |
|
|
Pierre-Yves Chibon |
d133cd |
ori_remote.push(refname)
|
|
Pierre-Yves Chibon |
d133cd |
|
|
Pierre-Yves Chibon |
d133cd |
# Remove the clone
|
|
Pierre-Yves Chibon |
d133cd |
shutil.rmtree(newpath)
|