-
-
Notifications
You must be signed in to change notification settings - Fork 459
/
Copy pathoca_projects.py
135 lines (113 loc) · 3.5 KB
/
oca_projects.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# -*- coding: utf-8 -*-
# License AGPLv3 (https://www.gnu.org/licenses/agpl-3.0-standalone.html)
"""
Data about OCA Projects, with a few helper functions.
OCA_REPOSITORY_NAMES: list of OCA repository names
"""
from __future__ import print_function
import os
import shutil
import subprocess
import tempfile
from contextlib import contextmanager
import appdirs
from .config import NOT_ADDONS, is_main_branch
from .github_login import login
ALL = ["OCA_REPOSITORY_NAMES", "url"]
def get_repositories():
gh = login()
all_repos = [
repo.name
for repo in gh.repositories_by("OCA")
if repo.name not in NOT_ADDONS and not repo.archived
]
return all_repos
def get_repositories_and_branches(repos=(), branches=(), branch_filter=is_main_branch):
gh = login()
for repo in gh.repositories_by("OCA"):
if repos and repo.name not in repos:
continue
if repo.name in NOT_ADDONS:
continue
for branch in repo.branches():
if branches and branch.name not in branches:
continue
if branch_filter and not branch_filter(branch.name):
continue
yield repo.name, branch.name
try:
OCA_REPOSITORY_NAMES = get_repositories()
except Exception as exc:
print(exc)
OCA_REPOSITORY_NAMES = []
OCA_REPOSITORY_NAMES.sort()
_OCA_REPOSITORY_NAMES = set(OCA_REPOSITORY_NAMES)
_URL_MAPPINGS = {
"git": "[email protected]:%s/%s.git",
"ssh": "ssh://[email protected]/%s/%s.git",
"https": "https://github.com/%s/%s.git",
}
def url(project_name, protocol="git", org_name="OCA"):
"""get the URL for an OCA project repository"""
return _URL_MAPPINGS[protocol] % (org_name, project_name)
class BranchNotFoundError(RuntimeError):
pass
@contextmanager
def temporary_clone(project_name, branch=None, protocol="git", org_name="OCA"):
"""context manager that clones a git branch and cd to it, with cache"""
# init cache directory
cache_dir = appdirs.user_cache_dir("oca-mqt")
repo_cache_dir = os.path.join(
cache_dir, "github.com", org_name.lower(), project_name.lower()
)
if not os.path.isdir(repo_cache_dir):
os.makedirs(repo_cache_dir)
subprocess.check_call(["git", "init", "--bare"], cwd=repo_cache_dir)
repo_url = url(project_name, protocol, org_name)
# fetch all branches into cache
fetch_cmd = [
"git",
"fetch",
"--quiet",
"--force",
repo_url,
"refs/heads/*:refs/heads/*",
]
subprocess.check_call(fetch_cmd, cwd=repo_cache_dir)
if branch:
# check if branch exist
branches = subprocess.check_output(
["git", "branch"], universal_newlines=True, cwd=repo_cache_dir
)
branches = [b.strip() for b in branches.split()]
if branch not in branches:
raise BranchNotFoundError()
# clone to temp dir, with --reference to cache
tempdir = tempfile.mkdtemp()
try:
clone_cmd = [
"git",
"clone",
"--quiet",
"--reference",
repo_cache_dir,
]
if branch:
clone_cmd += [
"--branch",
branch,
]
clone_cmd += [
"--",
repo_url,
tempdir,
]
subprocess.check_call(clone_cmd)
cwd = os.getcwd()
os.chdir(tempdir)
try:
yield
finally:
os.chdir(cwd)
finally:
shutil.rmtree(tempdir)