Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: ensure_dependencies.py

Issue 5934936779390976: 1377 - Blacklist dependencies from SCM tracking (Closed)
Patch Set: 1377 - Blacklist dependencies from Mercurial and Git tracking Created Sept. 28, 2014, 12:23 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # coding: utf-8 2 # coding: utf-8
3 3
4 # This file is part of the Adblock Plus build tools, 4 # This file is part of the Adblock Plus build tools,
5 # Copyright (C) 2006-2014 Eyeo GmbH 5 # Copyright (C) 2006-2014 Eyeo GmbH
6 # 6 #
7 # Adblock Plus is free software: you can redistribute it and/or modify 7 # Adblock Plus is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License version 3 as 8 # it under the terms of the GNU General Public License version 3 as
9 # published by the Free Software Foundation. 9 # published by the Free Software Foundation.
10 # 10 #
11 # Adblock Plus is distributed in the hope that it will be useful, 11 # Adblock Plus is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details. 14 # GNU General Public License for more details.
15 # 15 #
16 # You should have received a copy of the GNU General Public License 16 # You should have received a copy of the GNU General Public License
17 # along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 17 # along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
18 18
19 import sys 19 import sys
20 import os 20 import os
21 import posixpath 21 import posixpath
22 import re 22 import re
23 import io 23 import io
24 import errno 24 import errno
25 import logging 25 import logging
26 import subprocess 26 import subprocess
27 import urlparse 27 import urlparse
28
28 from collections import OrderedDict 29 from collections import OrderedDict
30 from ConfigParser import RawConfigParser
29 31
30 USAGE = """ 32 USAGE = """
31 A dependencies file should look like this: 33 A dependencies file should look like this:
32 34
33 # VCS-specific root URLs for the repositories 35 # VCS-specific root URLs for the repositories
34 _root = hg:https://hg.adblockplus.org/ git:https://github.com/adblockplus/ 36 _root = hg:https://hg.adblockplus.org/ git:https://github.com/adblockplus/
35 # File to update this script from (optional) 37 # File to update this script from (optional)
36 _self = buildtools/ensure_dependencies.py 38 _self = buildtools/ensure_dependencies.py
37 # Check out elemhidehelper repository into extensions/elemhidehelper directory 39 # Check out elemhidehelper repository into extensions/elemhidehelper directory
38 # at tag "1.2". 40 # at tag "1.2".
39 extensions/elemhidehelper = elemhidehelper 1.2 41 extensions/elemhidehelper = elemhidehelper 1.2
40 # Check out buildtools repository into buildtools directory at VCS-specific 42 # Check out buildtools repository into buildtools directory at VCS-specific
41 # revision IDs. 43 # revision IDs.
42 buildtools = buildtools hg:016d16f7137b git:f3f8692f82e5 44 buildtools = buildtools hg:016d16f7137b git:f3f8692f82e5
43 """ 45 """
44 46
45 class Mercurial(): 47 class SCM(object):
48 def _ignore(self, target, file_name):
Wladimir Palant 2014/10/07 22:30:14 That should simply be a helper function _ensure_li
aalvz 2014/10/08 13:49:18 Done.
Wladimir Palant 2014/10/08 21:40:30 And the same file format? That's merely a coincide
49 with open(file_name, 'a+') as f:
50 file_content = [l.strip() for l in f.readlines()]
51 if not target in file_content:
52 if len(file_content):
53 f.seek(-1, os.SEEK_CUR)
54 last_character = f.read(1)
55 if not last_character in "\r\n":
Wladimir Palant 2014/10/07 22:30:14 No need to overcomplicate this: file_content.appe
aalvz 2014/10/08 13:49:18 I think the solution you are suggesting and the cu
mathias 2014/10/08 17:37:55 While the first point is not really true (though i
56 f.write(os.linesep)
57 f.write(target)
58 f.write(os.linesep)
59
60 class Mercurial(SCM):
46 def istype(self, repodir): 61 def istype(self, repodir):
47 return os.path.exists(os.path.join(repodir, ".hg")) 62 return os.path.exists(os.path.join(repodir, ".hg"))
48 63
49 def clone(self, source, target): 64 def clone(self, source, target):
50 if not source.endswith("/"): 65 if not source.endswith("/"):
51 source += "/" 66 source += "/"
52 subprocess.check_call(["hg", "clone", "--quiet", "--noupdate", source, targe t]) 67 subprocess.check_call(["hg", "clone", "--quiet", "--noupdate", source, targe t])
53 68
54 def get_revision_id(self, repo, rev=None): 69 def get_revision_id(self, repo, rev=None):
55 command = ["hg", "id", "--repository", repo, "--id"] 70 command = ["hg", "id", "--repository", repo, "--id"]
56 if rev: 71 if rev:
57 command.extend(["--rev", rev]) 72 command.extend(["--rev", rev])
58 73
59 # Ignore stderr output and return code here: if revision lookup failed we 74 # Ignore stderr output and return code here: if revision lookup failed we
60 # should simply return an empty string. 75 # should simply return an empty string.
61 result = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess .PIPE).communicate()[0] 76 result = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess .PIPE).communicate()[0]
62 return result.strip() 77 return result.strip()
63 78
64 def pull(self, repo): 79 def pull(self, repo):
65 subprocess.check_call(["hg", "pull", "--repository", repo, "--quiet"]) 80 subprocess.check_call(["hg", "pull", "--repository", repo, "--quiet"])
66 81
67 def update(self, repo, rev): 82 def update(self, repo, rev):
68 subprocess.check_call(["hg", "update", "--repository", repo, "--quiet", "--c heck", "--rev", rev]) 83 subprocess.check_call(["hg", "update", "--repository", repo, "--quiet", "--c heck", "--rev", rev])
69 84
70 class Git(): 85 def ignore(self, target, repo):
86
87 if not self.istype(target):
88
89 config_path = os.path.join(repo, ".hg", "hgrc")
90 ignore_path = os.path.join(".", ".hg", "dependencies")
91
92 config = RawConfigParser()
93 config.read(config_path)
94
95 if not config.has_section("ui"):
96 config.add_section("ui")
97
98 if not config.has_option("ui", "ignore.dependencies"):
99 config.set("ui", "ignore.dependencies", ignore_path)
100 with open(config_path, "w") as stream:
101 config.write(stream)
102 else:
103 ignore_path = config.get("ui", "ignore.dependencies")
Wladimir Palant 2014/10/07 22:30:14 Please set that option regardless of whether it is
mathias 2014/10/08 16:32:11 Agreed, this is necessary due to the issue above,
104
105 module = os.path.relpath(target, repo)
106 self._ignore(module, ignore_path)
107
108 class Git(SCM):
71 def istype(self, repodir): 109 def istype(self, repodir):
72 return os.path.exists(os.path.join(repodir, ".git")) 110 return os.path.exists(os.path.join(repodir, ".git"))
73 111
74 def clone(self, source, target): 112 def clone(self, source, target):
75 source = source.rstrip("/") 113 source = source.rstrip("/")
76 if not source.endswith(".git"): 114 if not source.endswith(".git"):
77 source += ".git" 115 source += ".git"
78 subprocess.check_call(["git", "clone", "--quiet", source, target]) 116 subprocess.check_call(["git", "clone", "--quiet", source, target])
79 117
80 def get_revision_id(self, repo, rev="HEAD"): 118 def get_revision_id(self, repo, rev="HEAD"):
81 command = ["git", "rev-parse", "--revs-only", rev] 119 command = ["git", "rev-parse", "--revs-only", rev]
82 return subprocess.check_output(command, cwd=repo).strip() 120 return subprocess.check_output(command, cwd=repo).strip()
83 121
84 def pull(self, repo): 122 def pull(self, repo):
85 subprocess.check_call(["git", "fetch", "--quiet", "--all", "--tags"], cwd=re po) 123 subprocess.check_call(["git", "fetch", "--quiet", "--all", "--tags"], cwd=re po)
86 124
87 def update(self, repo, rev): 125 def update(self, repo, rev):
88 subprocess.check_call(["git", "checkout", "--quiet", rev], cwd=repo) 126 subprocess.check_call(["git", "checkout", "--quiet", rev], cwd=repo)
89 127
128 def ignore(self, target, repo):
129 module = os.path.relpath(target, repo)
130 exclude_file = os.path.join(repo, ".git", "info", "exclude")
131 self._ignore(module, exclude_file)
132
90 repo_types = { 133 repo_types = {
91 "hg": Mercurial(), 134 "hg": Mercurial(),
92 "git": Git(), 135 "git": Git(),
93 } 136 }
94 137
95 def parse_spec(path, line): 138 def parse_spec(path, line):
96 if "=" not in line: 139 if "=" not in line:
97 logging.warning("Invalid line in file %s: %s" % (path, line)) 140 logging.warning("Invalid line in file %s: %s" % (path, line))
98 return None, None 141 return None, None
99 142
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 197
155 def get_repo_type(repo): 198 def get_repo_type(repo):
156 for name, repotype in repo_types.iteritems(): 199 for name, repotype in repo_types.iteritems():
157 if repotype.istype(repo): 200 if repotype.istype(repo):
158 return name 201 return name
159 return None 202 return None
160 203
161 def ensure_repo(parentrepo, target, roots, sourcename): 204 def ensure_repo(parentrepo, target, roots, sourcename):
162 if os.path.exists(target): 205 if os.path.exists(target):
163 return 206 return
164
165 parenttype = get_repo_type(parentrepo) 207 parenttype = get_repo_type(parentrepo)
166 type = None 208 type = None
167 for key in roots: 209 for key in roots:
168 if key == parenttype or (key in repo_types and type is None): 210 if key == parenttype or (key in repo_types and type is None):
169 type = key 211 type = key
170 if type is None: 212 if type is None:
171 raise Exception("No valid source found to create %s" % target) 213 raise Exception("No valid source found to create %s" % target)
172 214
173 url = urlparse.urljoin(roots[type], sourcename) 215 url = urlparse.urljoin(roots[type], sourcename)
174 logging.info("Cloning repository %s into %s" % (url, target)) 216 logging.info("Cloning repository %s into %s" % (url, target))
175 repo_types[type].clone(url, target) 217 repo_types[type].clone(url, target)
176 218
219 for repo in repo_types.itervalues():
220 if repo.istype(parentrepo):
221 repo.ignore(target, parentrepo)
222
177 def update_repo(target, revisions): 223 def update_repo(target, revisions):
178 type = get_repo_type(target) 224 type = get_repo_type(target)
179 if type is None: 225 if type is None:
180 logging.warning("Type of repository %s unknown, skipping update" % target) 226 logging.warning("Type of repository %s unknown, skipping update" % target)
181 return 227 return
182 228
183 if type in revisions: 229 if type in revisions:
184 revision = revisions[type] 230 revision = revisions[type]
185 elif "*" in revisions: 231 elif "*" in revisions:
186 revision = revisions["*"] 232 revision = revisions["*"]
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 else: 292 else:
247 logging.warning("Cannot restart %s automatically, please rerun" % target ) 293 logging.warning("Cannot restart %s automatically, please rerun" % target )
248 294
249 if __name__ == "__main__": 295 if __name__ == "__main__":
250 logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO) 296 logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
251 repos = sys.argv[1:] 297 repos = sys.argv[1:]
252 if not len(repos): 298 if not len(repos):
253 repos = [os.getcwd()] 299 repos = [os.getcwd()]
254 for repo in repos: 300 for repo in repos:
255 resolve_deps(repo) 301 resolve_deps(repo)
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld