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
136
137
138
139
140
141
142
143
144
145
146
|
import os
import subprocess
from devbot import command
from devbot import utils
from devbot import config
_root_path = None
def _chdir(func):
def wrapped(*args, **kwargs):
orig_cwd = os.getcwd()
os.chdir(args[0].local)
result = func(*args, **kwargs)
os.chdir(orig_cwd)
return result
return wrapped
class Module:
def __init__(self, path=None, name=None, remote=None,
branch="master", tag=None, retry=10):
if path is None or name is None or remote is None:
raise RuntimeError("path, name and remote are required")
self.remote = remote
self.local = os.path.join(path, name)
self.tag = tag
self._path = path
self._name = name
self._branch = branch
self._retry = 10
def _clone(self):
os.chdir(self._path)
command.run(["git", "clone", "--progress", self.remote, self._name],
retry=self._retry)
os.chdir(self.local)
if self.tag:
command.run(["git", "checkout", self.tag])
else:
command.run(["git", "checkout", self._branch])
def update(self):
if not os.path.exists(os.path.join(self.local, ".git")):
self._clone()
return
os.chdir(self.local)
command.run(["git", "fetch"], retry=self._retry)
if self.tag:
command.run(["git", "checkout", self.tag])
else:
command.run(["git", "merge", "--ff-only",
"origin/%s" % self._branch])
@_chdir
def checkout(self, revision=None):
if revision is None:
revision = self.tag
if revision is None:
revision = self._branch
command.run(["git", "checkout", revision])
@_chdir
def describe(self):
return subprocess.check_output(["git", "describe"]).strip()
@_chdir
def is_valid(self):
result = subprocess.call(["git", "rev-parse", "HEAD"],
stdout=utils.devnull,
stderr=utils.devnull)
return result == 0
@_chdir
def get_commit_id(self):
return subprocess.check_output(["git", "rev-parse", "HEAD"]).strip()
@_chdir
def get_annotation(self, tag):
# FIXME this is fragile, there must be a better way
show = subprocess.check_output(["git", "show", tag])
annotation = []
for line in show.split("\n"):
ignore = False
for start in ["tag ", "Tagger: ", "Date: "]:
if line.startswith(start):
ignore = True
if line.startswith("commit "):
break
if not ignore:
annotation.append(line)
return "\n".join(annotation)
def clean(self):
try:
os.chdir(self.local)
except OSError:
return False
command.run(["git", "clean", "-fdx"])
return True
def set_root_path(path):
global _root_path
_root_path = path
def get_module(module):
return Module(path=config.get_source_dir(),
name=module.name,
remote=module.repo,
branch=module.branch,
tag=module.tag,
retry=10)
def get_root_module():
remote = "git://git.sugarlabs.org/sugar-build/sugar-build.git"
module = Module(name=os.path.basename(_root_path),
remote=remote,
path=os.path.dirname(_root_path))
if not module.is_valid():
return None
return module
|