|
Pierre-Yves Chibon |
33b534 |
# -*- coding: utf-8 -*-
|
|
Pierre-Yves Chibon |
a27356 |
|
|
Pierre-Yves Chibon |
a27356 |
"""
|
|
Pierre-Yves Chibon |
a27356 |
(c) 2015 - Copyright Red Hat Inc
|
|
Pierre-Yves Chibon |
a27356 |
|
|
Pierre-Yves Chibon |
a27356 |
Authors:
|
|
Pierre-Yves Chibon |
a27356 |
Pierre-Yves Chibon <pingou@pingoured.fr></pingou@pingoured.fr>
|
|
Pierre-Yves Chibon |
a27356 |
|
|
Pierre-Yves Chibon |
a27356 |
"""
|
|
Pierre-Yves Chibon |
a27356 |
|
|
Pierre-Yves Chibon |
a27356 |
|
|
Pierre-Yves Chibon |
a27356 |
import datetime
|
|
Pierre-Yves Chibon |
852918 |
import hashlib
|
|
Pierre-Yves Chibon |
a27356 |
import json
|
|
Pierre-Yves Chibon |
a27356 |
import os
|
|
Pierre-Yves Chibon |
a27356 |
import random
|
|
Pierre-Yves Chibon |
a27356 |
import shutil
|
|
Pierre-Yves Chibon |
a27356 |
import string
|
|
Pierre-Yves Chibon |
a27356 |
import tempfile
|
|
Pierre-Yves Chibon |
852918 |
import time
|
|
Pierre-Yves Chibon |
a27356 |
import uuid
|
|
Pierre-Yves Chibon |
a27356 |
|
|
Pierre-Yves Chibon |
a27356 |
import pygit2
|
|
Pierre-Yves Chibon |
2c34e0 |
import werkzeug
|
|
Pierre-Yves Chibon |
a27356 |
|
|
Pierre-Yves Chibon |
852918 |
import progit
|
|
Pierre-Yves Chibon |
a27356 |
import progit.exceptions
|
|
Pierre-Yves Chibon |
c7f9fa |
import progit.lib
|
|
Pierre-Yves Chibon |
f2c72b |
import progit.lib.notify
|
|
Pierre-Yves Chibon |
a27356 |
from progit.lib import model
|
|
Pierre-Yves Chibon |
a27356 |
|
|
Pierre-Yves Chibon |
a27356 |
|
|
Pierre-Yves Chibon |
a27356 |
def commit_to_patch(repo_obj, commits):
|
|
Pierre-Yves Chibon |
a27356 |
''' For a given commit (PyGit2 commit object) of a specified git repo,
|
|
Pierre-Yves Chibon |
a27356 |
returns a string representation of the changes the commit did in a
|
|
Pierre-Yves Chibon |
a27356 |
format that allows it to be used as patch.
|
|
Pierre-Yves Chibon |
a27356 |
'''
|
|
Pierre-Yves Chibon |
a27356 |
if not isinstance(commits, list):
|
|
Pierre-Yves Chibon |
a27356 |
commits = [commits]
|
|
Pierre-Yves Chibon |
a27356 |
|
|
Pierre-Yves Chibon |
a27356 |
patch = ""
|
|
Pierre-Yves Chibon |
a27356 |
for cnt, commit in enumerate(commits):
|
|
Pierre-Yves Chibon |
a27356 |
if commit.parents:
|
|
Pierre-Yves Chibon |
a27356 |
diff = commit.tree.diff_to_tree()
|
|
Pierre-Yves Chibon |
a27356 |
|
|
Pierre-Yves Chibon |
a27356 |
parent = repo_obj.revparse_single('%s^' % commit.oid.hex)
|
|
Pierre-Yves Chibon |
a27356 |
diff = repo_obj.diff(parent, commit)
|
|
Pierre-Yves Chibon |
a27356 |
else:
|
|
Pierre-Yves Chibon |
a27356 |
# First commit in the repo
|
|
Pierre-Yves Chibon |
a27356 |
diff = commit.tree.diff_to_tree(swap=True)
|
|
Pierre-Yves Chibon |
a27356 |
|
|
Pierre-Yves Chibon |
a27356 |
subject = message = ''
|
|
Pierre-Yves Chibon |
a27356 |
if '\n' in commit.message:
|
|
Pierre-Yves Chibon |
a27356 |
subject, message = commit.message.split('\n', 1)
|
|
Pierre-Yves Chibon |
a27356 |
else:
|
|
Pierre-Yves Chibon |
a27356 |
subject = commit.message
|
|
Pierre-Yves Chibon |
a27356 |
|
|
Pierre-Yves Chibon |
a27356 |
if len(commits) > 1:
|
|
Pierre-Yves Chibon |
a27356 |
subject = '[PATCH %s/%s] %s' % (cnt + 1, len(commits), subject)
|
|
Pierre-Yves Chibon |
a27356 |
|
|
Pierre-Yves Chibon |
a27356 |
patch += """From %(commit)s Mon Sep 17 00:00:00 2001
|
|
Pierre-Yves Chibon |
a27356 |
From: %(author_name)s <%(author_email)s>
|
|
Pierre-Yves Chibon |
a27356 |
Date: %(date)s
|
|
Pierre-Yves Chibon |
a27356 |
Subject: %(subject)s
|
|
Pierre-Yves Chibon |
a27356 |
|
|
Pierre-Yves Chibon |
a27356 |
%(msg)s
|
|
Pierre-Yves Chibon |
a27356 |
---
|
|
Pierre-Yves Chibon |
a27356 |
|
|
Pierre-Yves Chibon |
a27356 |
%(patch)s
|
|
Pierre-Yves Chibon |
a27356 |
""" % (
|
|
Pierre-Yves Chibon |
a27356 |
{
|
|
Pierre-Yves Chibon |
a27356 |
'commit': commit.oid.hex,
|
|
Pierre-Yves Chibon |
a27356 |
'author_name': commit.author.name,
|
|
Pierre-Yves Chibon |
a27356 |
'author_email': commit.author.email,
|
|
Pierre-Yves Chibon |
a27356 |
'date': datetime.datetime.utcfromtimestamp(
|
|
Pierre-Yves Chibon |
a27356 |
commit.commit_time).strftime('%b %d %Y %H:%M:%S +0000'),
|
|
Pierre-Yves Chibon |
a27356 |
'subject': subject,
|
|
Pierre-Yves Chibon |
a27356 |
'msg': message,
|
|
Pierre-Yves Chibon |
a27356 |
'patch': diff.patch,
|
|
Pierre-Yves Chibon |
a27356 |
}
|
|
Pierre-Yves Chibon |
a27356 |
)
|
|
Pierre-Yves Chibon |
a27356 |
return patch
|
|
Pierre-Yves Chibon |
459834 |
|
|
Pierre-Yves Chibon |
459834 |
|
|
Pierre-Yves Chibon |
40699d |
def write_gitolite_acls(session, configfile):
|
|
Pierre-Yves Chibon |
459834 |
''' Generate the configuration file for gitolite for all projects
|
|
Pierre-Yves Chibon |
459834 |
on the forge.
|
|
Pierre-Yves Chibon |
459834 |
'''
|
|
Pierre-Yves Chibon |
459834 |
config = []
|
|
Pierre-Yves Chibon |
459834 |
for project in session.query(model.Project).all():
|
|
Pierre-Yves Chibon |
459834 |
if project.parent_id:
|
|
Pierre-Yves Chibon |
459834 |
config.append('repo forks/%s' % project.fullname)
|
|
Pierre-Yves Chibon |
459834 |
else:
|
|
Pierre-Yves Chibon |
459834 |
config.append('repo %s' % project.fullname)
|
|
Pierre-Yves Chibon |
459834 |
config.append(' R = @all')
|
|
Pierre-Yves Chibon |
459834 |
config.append(' RW+ = %s' % project.user.user)
|
|
Pierre-Yves Chibon |
459834 |
for user in project.users:
|
|
Pierre-Yves Chibon |
459834 |
if user != project.user:
|
|
Pierre-Yves Chibon |
2286f4 |
config.append(' RW+ = %s' % user.user)
|
|
Pierre-Yves Chibon |
459834 |
config.append('')
|
|
Pierre-Yves Chibon |
459834 |
|
|
Pierre-Yves Chibon |
459834 |
config.append('repo docs/%s' % project.fullname)
|
|
Pierre-Yves Chibon |
459834 |
config.append(' R = @all')
|
|
Pierre-Yves Chibon |
459834 |
config.append(' RW+ = %s' % project.user.user)
|
|
Pierre-Yves Chibon |
459834 |
for user in project.users:
|
|
Pierre-Yves Chibon |
459834 |
if user != project.user:
|
|
Pierre-Yves Chibon |
2286f4 |
config.append(' RW+ = %s' % user.user)
|
|
Pierre-Yves Chibon |
459834 |
config.append('')
|
|
Pierre-Yves Chibon |
459834 |
|
|
Pierre-Yves Chibon |
459834 |
config.append('repo tickets/%s' % project.fullname)
|
|
Pierre-Yves Chibon |
459834 |
config.append(' R = @all')
|
|
Pierre-Yves Chibon |
459834 |
config.append(' RW+ = %s' % project.user.user)
|
|
Pierre-Yves Chibon |
459834 |
for user in project.users:
|
|
Pierre-Yves Chibon |
459834 |
if user != project.user:
|
|
Pierre-Yves Chibon |
2286f4 |
config.append(' RW+ = %s' % user.user)
|
|
Pierre-Yves Chibon |
459834 |
config.append('')
|
|
Pierre-Yves Chibon |
459834 |
|
|
Pierre-Yves Chibon |
459834 |
with open(configfile, 'w') as stream:
|
|
Pierre-Yves Chibon |
459834 |
for row in config:
|
|
Pierre-Yves Chibon |
459834 |
stream.write(row + '\n')
|
|
Pierre-Yves Chibon |
c8b13b |
|
|
Pierre-Yves Chibon |
c8b13b |
|
|
Pierre-Yves Chibon |
2b0341 |
def update_git(obj, repo, repofolder, objtype='ticket'):
|
|
Pierre-Yves Chibon |
c8b13b |
""" Update the given issue in its git.
|
|
Pierre-Yves Chibon |
c8b13b |
|
|
Pierre-Yves Chibon |
c8b13b |
This method forks the provided repo, add/edit the issue whose file name
|
|
Pierre-Yves Chibon |
c8b13b |
is defined by the uid field of the issue and if there are additions/
|
|
Pierre-Yves Chibon |
c8b13b |
changes commit them and push them back to the original repo.
|
|
Pierre-Yves Chibon |
c8b13b |
|
|
Pierre-Yves Chibon |
c8b13b |
"""
|
|
Pierre-Yves Chibon |
c8b13b |
|
|
Pierre-Yves Chibon |
2b0341 |
if not repofolder:
|
|
Pierre-Yves Chibon |
e3b595 |
return
|
|
Pierre-Yves Chibon |
e3b595 |
|
|
Pierre-Yves Chibon |
c8b13b |
# Get the fork
|
|
Pierre-Yves Chibon |
2b0341 |
repopath = os.path.join(repofolder, repo.path)
|
|
Pierre-Yves Chibon |
c8b13b |
ticket_repo = pygit2.Repository(repopath)
|
|
Pierre-Yves Chibon |
c8b13b |
|
|
Pierre-Yves Chibon |
c8b13b |
# Clone the repo into a temp folder
|
|
Pierre-Yves Chibon |
c8b13b |
newpath = tempfile.mkdtemp()
|
|
Pierre-Yves Chibon |
c8b13b |
new_repo = pygit2.clone_repository(repopath, newpath)
|
|
Pierre-Yves Chibon |
c8b13b |
|
|
Pierre-Yves Chibon |
2b0341 |
file_path = os.path.join(newpath, obj.uid)
|
|
Pierre-Yves Chibon |
c8b13b |
|
|
Pierre-Yves Chibon |
c8b13b |
# Get the current index
|
|
Pierre-Yves Chibon |
c8b13b |
index = new_repo.index
|
|
Pierre-Yves Chibon |
c8b13b |
|
|
Pierre-Yves Chibon |
c8b13b |
# Are we adding files
|
|
Pierre-Yves Chibon |
c8b13b |
added = False
|
|
Pierre-Yves Chibon |
c8b13b |
if not os.path.exists(file_path):
|
|
Pierre-Yves Chibon |
c8b13b |
added = True
|
|
Pierre-Yves Chibon |
c8b13b |
|
|
Pierre-Yves Chibon |
c8b13b |
# Write down what changed
|
|
Pierre-Yves Chibon |
c8b13b |
with open(file_path, 'w') as stream:
|
|
Pierre-Yves Chibon |
2b0341 |
stream.write(obj.to_json())
|
|
Pierre-Yves Chibon |
c8b13b |
|
|
Pierre-Yves Chibon |
c8b13b |
# Retrieve the list of files that changed
|
|
Pierre-Yves Chibon |
c8b13b |
diff = new_repo.diff()
|
|
Pierre-Yves Chibon |
c8b13b |
files = [patch.new_file_path for patch in diff]
|
|
Pierre-Yves Chibon |
c8b13b |
|
|
Pierre-Yves Chibon |
c8b13b |
# Add the changes to the index
|
|
Pierre-Yves Chibon |
c8b13b |
if added:
|
|
Pierre-Yves Chibon |
2b0341 |
index.add(obj.uid)
|
|
Pierre-Yves Chibon |
c8b13b |
for filename in files:
|
|
Pierre-Yves Chibon |
c8b13b |
index.add(filename)
|
|
Pierre-Yves Chibon |
c8b13b |
|
|
Pierre-Yves Chibon |
c8b13b |
# If not change, return
|
|
Pierre-Yves Chibon |
c8b13b |
if not files and not added:
|
|
Pierre-Yves Chibon |
c8b13b |
shutil.rmtree(newpath)
|
|
Pierre-Yves Chibon |
c8b13b |
return
|
|
Pierre-Yves Chibon |
c8b13b |
|
|
Pierre-Yves Chibon |
c8b13b |
# See if there is a parent to this commit
|
|
Pierre-Yves Chibon |
c8b13b |
parent = None
|
|
Pierre-Yves Chibon |
c8b13b |
try:
|
|
Pierre-Yves Chibon |
c8b13b |
parent = new_repo.head.get_object().oid
|
|
Pierre-Yves Chibon |
c8b13b |
except pygit2.GitError:
|
|
Pierre-Yves Chibon |
c8b13b |
pass
|
|
Pierre-Yves Chibon |
c8b13b |
|
|
Pierre-Yves Chibon |
c8b13b |
parents = []
|
|
Pierre-Yves Chibon |
c8b13b |
if parent:
|
|
Pierre-Yves Chibon |
c8b13b |
parents.append(parent)
|
|
Pierre-Yves Chibon |
c8b13b |
|
|
Pierre-Yves Chibon |
c8b13b |
# Author/commiter will always be this one
|
|
Pierre-Yves Chibon |
c8b13b |
author = pygit2.Signature(name='progit', email='progit')
|
|
Pierre-Yves Chibon |
c8b13b |
|
|
Pierre-Yves Chibon |
c8b13b |
# Actually commit
|
|
Pierre-Yves Chibon |
c8b13b |
sha = new_repo.create_commit(
|
|
Pierre-Yves Chibon |
c8b13b |
'refs/heads/master',
|
|
Pierre-Yves Chibon |
c8b13b |
author,
|
|
Pierre-Yves Chibon |
c8b13b |
author,
|
|
Pierre-Yves Chibon |
2b0341 |
'Updated %s %s: %s' % (objtype, obj.uid, obj.title),
|
|
Pierre-Yves Chibon |
c8b13b |
new_repo.index.write_tree(),
|
|
Pierre-Yves Chibon |
c8b13b |
parents)
|
|
Pierre-Yves Chibon |
c8b13b |
index.write()
|
|
Pierre-Yves Chibon |
c8b13b |
|
|
Pierre-Yves Chibon |
c8b13b |
# Push to origin
|
|
Pierre-Yves Chibon |
c8b13b |
ori_remote = new_repo.remotes[0]
|
|
Pierre-Yves Chibon |
c8b13b |
master_ref = new_repo.lookup_reference('HEAD').resolve()
|
|
Pierre-Yves Chibon |
c8b13b |
refname = '%s:%s' % (master_ref.name, master_ref.name)
|
|
Pierre-Yves Chibon |
c8b13b |
|
|
Pierre-Yves Chibon |
c8b13b |
ori_remote.push(refname)
|
|
Pierre-Yves Chibon |
c8b13b |
|
|
Pierre-Yves Chibon |
c8b13b |
# Remove the clone
|
|
Pierre-Yves Chibon |
c8b13b |
shutil.rmtree(newpath)
|
|
Pierre-Yves Chibon |
c7f9fa |
|
|
Pierre-Yves Chibon |
c7f9fa |
|
|
Pierre-Yves Chibon |
c7f9fa |
def get_user_from_json(session, jsondata):
|
|
Pierre-Yves Chibon |
c7f9fa |
""" From the given json blob, retrieve the user info and search for it
|
|
Pierre-Yves Chibon |
c7f9fa |
in the db and create the user if it does not already exist.
|
|
Pierre-Yves Chibon |
c7f9fa |
"""
|
|
Pierre-Yves Chibon |
c7f9fa |
user = None
|
|
Pierre-Yves Chibon |
c7f9fa |
|
|
Pierre-Yves Chibon |
c7f9fa |
username = jsondata.get('user', {}).get('name')
|
|
Pierre-Yves Chibon |
c7f9fa |
fullname = jsondata.get('user', {}).get('fullname')
|
|
Pierre-Yves Chibon |
c7f9fa |
useremails = jsondata.get('user', {}).get('emails')
|
|
Pierre-Yves Chibon |
c7f9fa |
user = progit.lib.search_user(session, username=username)
|
|
Pierre-Yves Chibon |
c7f9fa |
if not user:
|
|
Pierre-Yves Chibon |
c7f9fa |
for email in useremails:
|
|
Pierre-Yves Chibon |
c7f9fa |
user = progit.lib.search_user(session, email=email)
|
|
Pierre-Yves Chibon |
c7f9fa |
if user:
|
|
Pierre-Yves Chibon |
c7f9fa |
break
|
|
Pierre-Yves Chibon |
c7f9fa |
|
|
Pierre-Yves Chibon |
c7f9fa |
if not user:
|
|
Pierre-Yves Chibon |
c7f9fa |
user = progit.lib.set_up_user(
|
|
Pierre-Yves Chibon |
c7f9fa |
session=session,
|
|
Pierre-Yves Chibon |
c7f9fa |
username=username,
|
|
Pierre-Yves Chibon |
c7f9fa |
fullname=fullname or username,
|
|
Pierre-Yves Chibon |
c7f9fa |
user_email=useremails[0],
|
|
Pierre-Yves Chibon |
c7f9fa |
)
|
|
Pierre-Yves Chibon |
c7f9fa |
session.commit()
|
|
Pierre-Yves Chibon |
c7f9fa |
|
|
Pierre-Yves Chibon |
c7f9fa |
return user
|
|
Pierre-Yves Chibon |
c7f9fa |
|
|
Pierre-Yves Chibon |
c7f9fa |
|
|
Pierre-Yves Chibon |
c7f9fa |
def update_ticket_from_git(
|
|
Pierre-Yves Chibon |
c7f9fa |
session, reponame, username, issue_uid, json_data):
|
|
Pierre-Yves Chibon |
c7f9fa |
""" Update the specified issue (identified by its unique identifier)
|
|
Pierre-Yves Chibon |
c7f9fa |
with the data present in the json blob provided.
|
|
Pierre-Yves Chibon |
c7f9fa |
|
|
Pierre-Yves Chibon |
c7f9fa |
:arg session: the session to connect to the database with.
|
|
Pierre-Yves Chibon |
c7f9fa |
:arg repo: the name of the project to update
|
|
Pierre-Yves Chibon |
c7f9fa |
:arg issue_uid: the unique identifier of the issue to update
|
|
Pierre-Yves Chibon |
c7f9fa |
:arg json_data: the json representation of the issue taken from the git
|
|
Pierre-Yves Chibon |
c7f9fa |
and used to update the data in the database.
|
|
Pierre-Yves Chibon |
c7f9fa |
|
|
Pierre-Yves Chibon |
c7f9fa |
"""
|
|
Pierre-Yves Chibon |
c7f9fa |
print json.dumps(json_data, sort_keys=True,
|
|
Pierre-Yves Chibon |
c7f9fa |
indent=4, separators=(',', ': '))
|
|
Pierre-Yves Chibon |
c7f9fa |
|
|
Pierre-Yves Chibon |
c7f9fa |
repo = progit.lib.get_project(session, reponame, user=username)
|
|
Pierre-Yves Chibon |
c7f9fa |
if not repo:
|
|
Pierre-Yves Chibon |
c7f9fa |
raise progit.exceptions.ProgitException(
|
|
Pierre-Yves Chibon |
c7f9fa |
'Unknown repo %s of username: %s' % (reponame, username))
|
|
Pierre-Yves Chibon |
c7f9fa |
|
|
Pierre-Yves Chibon |
c7f9fa |
user = get_user_from_json(session, json_data)
|
|
Pierre-Yves Chibon |
c7f9fa |
|
|
Pierre-Yves Chibon |
c7f9fa |
issue = progit.lib.get_issue_by_uid(session, issue_uid=issue_uid)
|
|
Pierre-Yves Chibon |
c7f9fa |
if not issue:
|
|
Pierre-Yves Chibon |
c7f9fa |
# Create new issue
|
|
Pierre-Yves Chibon |
c7f9fa |
progit.lib.new_issue(
|
|
Pierre-Yves Chibon |
c7f9fa |
session,
|
|
Pierre-Yves Chibon |
c7f9fa |
repo=repo,
|
|
Pierre-Yves Chibon |
c7f9fa |
title=json_data.get('title'),
|
|
Pierre-Yves Chibon |
c7f9fa |
content=json_data.get('content'),
|
|
Pierre-Yves Chibon |
c7f9fa |
user=user.username,
|
|
Pierre-Yves Chibon |
c7f9fa |
ticketfolder=None,
|
|
Pierre-Yves Chibon |
c7f9fa |
issue_id=json_data.get('id'),
|
|
Pierre-Yves Chibon |
c7f9fa |
issue_uid=issue_uid,
|
|
Pierre-Yves Chibon |
c7f9fa |
private=json_data.get('private'),
|
|
Pierre-Yves Chibon |
c7f9fa |
status=json_data.get('status'),
|
|
Pierre-Yves Chibon |
c7f9fa |
notify=False,
|
|
Pierre-Yves Chibon |
c7f9fa |
)
|
|
Pierre-Yves Chibon |
c7f9fa |
|
|
Pierre-Yves Chibon |
c7f9fa |
else:
|
|
Pierre-Yves Chibon |
c7f9fa |
# Edit existing issue
|
|
Pierre-Yves Chibon |
c7f9fa |
progit.lib.edit_issue(
|
|
Pierre-Yves Chibon |
c7f9fa |
session,
|
|
Pierre-Yves Chibon |
c7f9fa |
issue=issue,
|
|
Pierre-Yves Chibon |
c7f9fa |
ticketfolder=None,
|
|
Pierre-Yves Chibon |
c7f9fa |
title=json_data.get('title'),
|
|
Pierre-Yves Chibon |
c7f9fa |
content=json_data.get('content'),
|
|
Pierre-Yves Chibon |
c7f9fa |
status=json_data.get('status'),
|
|
Pierre-Yves Chibon |
c7f9fa |
private=json_data.get('private'),
|
|
Pierre-Yves Chibon |
c7f9fa |
)
|
|
Pierre-Yves Chibon |
c7f9fa |
session.commit()
|
|
Pierre-Yves Chibon |
c7f9fa |
|
|
Pierre-Yves Chibon |
c7f9fa |
issue = progit.lib.get_issue_by_uid(session, issue_uid=issue_uid)
|
|
Pierre-Yves Chibon |
c7f9fa |
|
|
Pierre-Yves Chibon |
afa3e7 |
# Update tags
|
|
Pierre-Yves Chibon |
afa3e7 |
tags = json_data.get('tags', [])
|
|
Pierre-Yves Chibon |
afa3e7 |
progit.lib.update_tags_issue(
|
|
Pierre-Yves Chibon |
c99f14 |
session, issue, tags, username=user.user, ticketfolder=None)
|
|
Pierre-Yves Chibon |
afa3e7 |
|
|
Pierre-Yves Chibon |
afa3e7 |
# Update depends
|
|
Pierre-Yves Chibon |
afa3e7 |
depends = json_data.get('depends', [])
|
|
Pierre-Yves Chibon |
c99f14 |
progit.lib.update_dependency_issue(
|
|
Pierre-Yves Chibon |
c99f14 |
session, issue.project, issue, depends,
|
|
Pierre-Yves Chibon |
c99f14 |
username=user.user, ticketfolder=None)
|
|
Pierre-Yves Chibon |
afa3e7 |
|
|
Pierre-Yves Chibon |
afa3e7 |
# Update blocks
|
|
Pierre-Yves Chibon |
afa3e7 |
blocks = json_data.get('blocks', [])
|
|
Pierre-Yves Chibon |
c99f14 |
progit.lib.update_blocked_issue(
|
|
Pierre-Yves Chibon |
c99f14 |
session, issue.project, issue, blocks,
|
|
Pierre-Yves Chibon |
c99f14 |
username=user.user, ticketfolder=None)
|
|
Pierre-Yves Chibon |
afa3e7 |
|
|
Pierre-Yves Chibon |
c7f9fa |
for comment in json_data['comments']:
|
|
Pierre-Yves Chibon |
c7f9fa |
user = get_user_from_json(session, comment)
|
|
Pierre-Yves Chibon |
c7f9fa |
commentobj = progit.lib.get_issue_comment(
|
|
Pierre-Yves Chibon |
c7f9fa |
session, issue_uid, comment['id'])
|
|
Pierre-Yves Chibon |
c7f9fa |
if not commentobj:
|
|
Pierre-Yves Chibon |
c7f9fa |
progit.lib.add_issue_comment(
|
|
Pierre-Yves Chibon |
c7f9fa |
session,
|
|
Pierre-Yves Chibon |
c7f9fa |
issue=issue,
|
|
Pierre-Yves Chibon |
c7f9fa |
comment=comment['comment'],
|
|
Pierre-Yves Chibon |
c7f9fa |
user=user.username,
|
|
Pierre-Yves Chibon |
c7f9fa |
ticketfolder=None,
|
|
Pierre-Yves Chibon |
c7f9fa |
notify=False,
|
|
Pierre-Yves Chibon |
c7f9fa |
)
|
|
Pierre-Yves Chibon |
c7f9fa |
session.commit()
|
|
Pierre-Yves Chibon |
852918 |
|
|
Pierre-Yves Chibon |
852918 |
|
|
Pierre-Yves Chibon |
852918 |
def add_file_to_git(repo, issue, ticketfolder, user, filename, filestream):
|
|
Pierre-Yves Chibon |
852918 |
''' Add a given file to the specified ticket git repository.
|
|
Pierre-Yves Chibon |
852918 |
|
|
Pierre-Yves Chibon |
852918 |
:arg repo: the Project object from the database
|
|
Pierre-Yves Chibon |
852918 |
:arg ticketfolder: the folder on the filesystem where the git repo for
|
|
Pierre-Yves Chibon |
852918 |
tickets are stored
|
|
Pierre-Yves Chibon |
852918 |
:arg user: the user object with its username and email
|
|
Pierre-Yves Chibon |
852918 |
:arg filename: the name of the file to save
|
|
Pierre-Yves Chibon |
852918 |
:arg filestream: the actual content of the file
|
|
Pierre-Yves Chibon |
852918 |
|
|
Pierre-Yves Chibon |
852918 |
'''
|
|
Pierre-Yves Chibon |
852918 |
|
|
Pierre-Yves Chibon |
852918 |
if not ticketfolder:
|
|
Pierre-Yves Chibon |
852918 |
return
|
|
Pierre-Yves Chibon |
852918 |
|
|
Pierre-Yves Chibon |
852918 |
# Prefix the filename with a timestamp:
|
|
Pierre-Yves Chibon |
852918 |
filename = '%s-%s' % (
|
|
Pierre-Yves Chibon |
852918 |
hashlib.sha256(filestream.read()).hexdigest(),
|
|
Pierre-Yves Chibon |
2c34e0 |
werkzeug.secure_filename(filename)
|
|
Pierre-Yves Chibon |
852918 |
)
|
|
Pierre-Yves Chibon |
852918 |
|
|
Pierre-Yves Chibon |
852918 |
# Get the fork
|
|
Pierre-Yves Chibon |
852918 |
repopath = os.path.join(ticketfolder, repo.path)
|
|
Pierre-Yves Chibon |
852918 |
ticket_repo = pygit2.Repository(repopath)
|
|
Pierre-Yves Chibon |
852918 |
|
|
Pierre-Yves Chibon |
852918 |
# Clone the repo into a temp folder
|
|
Pierre-Yves Chibon |
852918 |
newpath = tempfile.mkdtemp()
|
|
Pierre-Yves Chibon |
852918 |
new_repo = pygit2.clone_repository(repopath, newpath)
|
|
Pierre-Yves Chibon |
852918 |
|
|
Pierre-Yves Chibon |
852918 |
folder_path = os.path.join(newpath, 'files')
|
|
Pierre-Yves Chibon |
852918 |
file_path = os.path.join(folder_path, filename)
|
|
Pierre-Yves Chibon |
852918 |
|
|
Pierre-Yves Chibon |
852918 |
# Get the current index
|
|
Pierre-Yves Chibon |
852918 |
index = new_repo.index
|
|
Pierre-Yves Chibon |
852918 |
|
|
Pierre-Yves Chibon |
852918 |
# Are we adding files
|
|
Pierre-Yves Chibon |
852918 |
added = False
|
|
Pierre-Yves Chibon |
852918 |
if not os.path.exists(file_path):
|
|
Pierre-Yves Chibon |
852918 |
added = True
|
|
Pierre-Yves Chibon |
852918 |
else:
|
|
Pierre-Yves Chibon |
852918 |
# File exists, remove the clone and return
|
|
Pierre-Yves Chibon |
852918 |
shutil.rmtree(newpath)
|
|
Pierre-Yves Chibon |
852918 |
return os.path.join('files', filename)
|
|
Pierre-Yves Chibon |
852918 |
|
|
Pierre-Yves Chibon |
852918 |
if not os.path.exists(folder_path):
|
|
Pierre-Yves Chibon |
852918 |
os.mkdir(folder_path)
|
|
Pierre-Yves Chibon |
852918 |
|
|
Pierre-Yves Chibon |
852918 |
# Write down what changed
|
|
Pierre-Yves Chibon |
852918 |
filestream.seek(0)
|
|
Pierre-Yves Chibon |
852918 |
with open(file_path, 'w') as stream:
|
|
Pierre-Yves Chibon |
852918 |
stream.write(filestream.read())
|
|
Pierre-Yves Chibon |
852918 |
|
|
Pierre-Yves Chibon |
852918 |
# Retrieve the list of files that changed
|
|
Pierre-Yves Chibon |
852918 |
diff = new_repo.diff()
|
|
Pierre-Yves Chibon |
852918 |
files = [patch.new_file_path for patch in diff]
|
|
Pierre-Yves Chibon |
852918 |
|
|
Pierre-Yves Chibon |
852918 |
# Add the changes to the index
|
|
Pierre-Yves Chibon |
852918 |
if added:
|
|
Pierre-Yves Chibon |
852918 |
index.add(os.path.join('files', filename))
|
|
Pierre-Yves Chibon |
852918 |
for filename in files:
|
|
Pierre-Yves Chibon |
852918 |
index.add(filename)
|
|
Pierre-Yves Chibon |
852918 |
|
|
Pierre-Yves Chibon |
852918 |
# If not change, return
|
|
Pierre-Yves Chibon |
852918 |
if not files and not added:
|
|
Pierre-Yves Chibon |
852918 |
shutil.rmtree(newpath)
|
|
Pierre-Yves Chibon |
852918 |
return
|
|
Pierre-Yves Chibon |
852918 |
|
|
Pierre-Yves Chibon |
852918 |
# See if there is a parent to this commit
|
|
Pierre-Yves Chibon |
852918 |
parent = None
|
|
Pierre-Yves Chibon |
852918 |
try:
|
|
Pierre-Yves Chibon |
852918 |
parent = new_repo.head.get_object().oid
|
|
Pierre-Yves Chibon |
852918 |
except pygit2.GitError:
|
|
Pierre-Yves Chibon |
852918 |
pass
|
|
Pierre-Yves Chibon |
852918 |
|
|
Pierre-Yves Chibon |
852918 |
parents = []
|
|
Pierre-Yves Chibon |
852918 |
if parent:
|
|
Pierre-Yves Chibon |
852918 |
parents.append(parent)
|
|
Pierre-Yves Chibon |
852918 |
|
|
Pierre-Yves Chibon |
852918 |
# Author/commiter will always be this one
|
|
Pierre-Yves Chibon |
852918 |
author = pygit2.Signature(
|
|
Pierre-Yves Chibon |
852918 |
name=user.username,
|
|
Pierre-Yves Chibon |
852918 |
email=user.email
|
|
Pierre-Yves Chibon |
852918 |
)
|
|
Pierre-Yves Chibon |
852918 |
|
|
Pierre-Yves Chibon |
852918 |
# Actually commit
|
|
Pierre-Yves Chibon |
852918 |
sha = new_repo.create_commit(
|
|
Pierre-Yves Chibon |
852918 |
'refs/heads/master',
|
|
Pierre-Yves Chibon |
852918 |
author,
|
|
Pierre-Yves Chibon |
852918 |
author,
|
|
Pierre-Yves Chibon |
852918 |
'Add file %s to ticket %s: %s' % (filename, issue.uid, issue.title),
|
|
Pierre-Yves Chibon |
852918 |
new_repo.index.write_tree(),
|
|
Pierre-Yves Chibon |
852918 |
parents)
|
|
Pierre-Yves Chibon |
852918 |
index.write()
|
|
Pierre-Yves Chibon |
852918 |
|
|
Pierre-Yves Chibon |
852918 |
# Push to origin
|
|
Pierre-Yves Chibon |
852918 |
ori_remote = new_repo.remotes[0]
|
|
Pierre-Yves Chibon |
852918 |
master_ref = new_repo.lookup_reference('HEAD').resolve()
|
|
Pierre-Yves Chibon |
852918 |
refname = '%s:%s' % (master_ref.name, master_ref.name)
|
|
Pierre-Yves Chibon |
852918 |
|
|
Pierre-Yves Chibon |
852918 |
ori_remote.push(refname)
|
|
Pierre-Yves Chibon |
852918 |
|
|
Pierre-Yves Chibon |
852918 |
# Remove the clone
|
|
Pierre-Yves Chibon |
852918 |
shutil.rmtree(newpath)
|
|
Pierre-Yves Chibon |
852918 |
|
|
Pierre-Yves Chibon |
852918 |
return os.path.join('files', filename)
|