34
34
buildtools = buildtools hg:016d16f7137b git:f3f8692f82e5
37
SKIP_DEPENDENCY_UPDATES = os.environ.get(
38
"SKIP_DEPENDENCY_UPDATES", ""
39
).lower() not in ("", "0", "false")
38
42
def istype(self, repodir):
39
43
return os.path.exists(os.path.join(repodir, ".hg"))
79
83
module = os.path.relpath(target, repo)
80
84
_ensure_line_exists(ignore_path, module)
86
def postprocess_url(self, url):
83
90
def istype(self, repodir):
84
91
return os.path.exists(os.path.join(repodir, ".git"))
94
101
return subprocess.check_output(command, cwd=repo).strip()
96
103
def pull(self, repo):
104
# Fetch tracked branches, new tags and the list of available remote branches
97
105
subprocess.check_call(["git", "fetch", "--quiet", "--all", "--tags"], cwd=repo)
106
# Next we need to ensure all remote branches are tracked
107
newly_tracked = False
108
remotes = subprocess.check_output(["git", "branch", "--remotes"], cwd=repo)
109
for match in re.finditer(r"^\s*(origin/(\S+))$", remotes, re.M):
110
remote, local = match.groups()
111
with open(os.devnull, "wb") as devnull:
112
if subprocess.call(["git", "branch", "--track", local, remote],
113
cwd=repo, stdout=devnull, stderr=devnull) == 0:
115
# Finally fetch any newly tracked remote branches
117
subprocess.check_call(["git", "fetch", "--quiet", "origin"], cwd=repo)
99
119
def update(self, repo, rev):
100
120
subprocess.check_call(["git", "checkout", "--quiet", rev], cwd=repo)
104
124
exclude_file = os.path.join(repo, ".git", "info", "exclude")
105
125
_ensure_line_exists(exclude_file, module)
127
def postprocess_url(self, url):
128
# Handle alternative syntax of SSH URLS
129
if "@" in url and ":" in url and not urlparse.urlsplit(url).scheme:
130
return "ssh://" + url.replace(":", "/", 1)
107
133
repo_types = OrderedDict((
108
134
("hg", Mercurial()),
159
185
def safe_join(path, subpath):
160
186
# This has been inspired by Flask's safe_join() function
161
forbidden = set([os.sep, os.altsep]) - set([posixpath.sep, None])
187
forbidden = {os.sep, os.altsep} - {posixpath.sep, None}
162
188
if any(sep in subpath for sep in forbidden):
163
189
raise Exception("Illegal directory separator in dependency path %s" % subpath)
179
205
if os.path.exists(target):
208
if SKIP_DEPENDENCY_UPDATES:
209
logging.warning("SKIP_DEPENDENCY_UPDATES environment variable set, "
210
"%s not cloned", target)
182
213
parenttype = get_repo_type(parentrepo)
184
215
for key in roots:
188
219
raise Exception("No valid source found to create %s" % target)
190
if os.path.exists(roots[type]):
191
url = os.path.join(roots[type], sourcename)
221
postprocess_url = repo_types[type].postprocess_url
222
root = postprocess_url(roots[type])
223
sourcename = postprocess_url(sourcename)
225
if os.path.exists(root):
226
url = os.path.join(root, sourcename)
193
url = urlparse.urljoin(roots[type], sourcename)
228
url = urlparse.urljoin(root, sourcename)
195
230
logging.info("Cloning repository %s into %s" % (url, target))
196
231
repo_types[type].clone(url, target)
216
251
resolved_revision = repo_types[type].get_revision_id(target, revision)
217
if not resolved_revision:
218
logging.info("Revision %s is unknown, downloading remote changes" % revision)
219
repo_types[type].pull(target)
220
resolved_revision = repo_types[type].get_revision_id(target, revision)
221
if not resolved_revision:
222
raise Exception("Failed to resolve revision %s" % revision)
224
252
current_revision = repo_types[type].get_revision_id(target)
225
254
if resolved_revision != current_revision:
255
if SKIP_DEPENDENCY_UPDATES:
256
logging.warning("SKIP_DEPENDENCY_UPDATES environment variable set, "
257
"%s not checked out to %s", target, revision)
260
if not resolved_revision:
261
logging.info("Revision %s is unknown, downloading remote changes" % revision)
262
repo_types[type].pull(target)
263
resolved_revision = repo_types[type].get_revision_id(target, revision)
264
if not resolved_revision:
265
raise Exception("Failed to resolve revision %s" % revision)
226
267
logging.info("Updating repository %s to revision %s" % (target, resolved_revision))
227
268
repo_types[type].update(target, resolved_revision)