OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 | 2 |
3 # This Source Code Form is subject to the terms of the Mozilla Public | 3 # This Source Code Form is subject to the terms of the Mozilla Public |
4 # License, v. 2.0. If a copy of the MPL was not distributed with this | 4 # License, v. 2.0. If a copy of the MPL was not distributed with this |
5 # file, You can obtain one at http://mozilla.org/MPL/2.0/. | 5 # file, You can obtain one at http://mozilla.org/MPL/2.0/. |
6 | 6 |
7 import sys | 7 import sys |
8 import os | 8 import os |
9 import posixpath | 9 import posixpath |
10 import re | 10 import re |
(...skipping 26 matching lines...) Expand all Loading... |
37 adblockplus = adblockplus hg:893426c6a6ab git:git@github.com:user/adblockplus.
git@b2ffd52b | 37 adblockplus = adblockplus hg:893426c6a6ab git:git@github.com:user/adblockplus.
git@b2ffd52b |
38 # Clone the adblockpluschrome repository into the adblockpluschrome directory, | 38 # Clone the adblockpluschrome repository into the adblockpluschrome directory, |
39 # from a specific Git repository, specifying the revision ID. | 39 # from a specific Git repository, specifying the revision ID. |
40 adblockpluschrome = git:git@github.com:user/adblockpluschrome.git@1fad3a7 | 40 adblockpluschrome = git:git@github.com:user/adblockpluschrome.git@1fad3a7 |
41 ''' | 41 ''' |
42 | 42 |
43 SKIP_DEPENDENCY_UPDATES = os.environ.get( | 43 SKIP_DEPENDENCY_UPDATES = os.environ.get( |
44 'SKIP_DEPENDENCY_UPDATES', '' | 44 'SKIP_DEPENDENCY_UPDATES', '' |
45 ).lower() not in ('', '0', 'false') | 45 ).lower() not in ('', '0', 'false') |
46 | 46 |
| 47 NPM_LOCKFILE = '.npm_install_lock' |
| 48 |
47 | 49 |
48 class Mercurial(): | 50 class Mercurial(): |
49 def istype(self, repodir): | 51 def istype(self, repodir): |
50 return os.path.exists(os.path.join(repodir, '.hg')) | 52 return os.path.exists(os.path.join(repodir, '.hg')) |
51 | 53 |
52 def clone(self, source, target): | 54 def clone(self, source, target): |
53 if not source.endswith('/'): | 55 if not source.endswith('/'): |
54 source += '/' | 56 source += '/' |
55 subprocess.check_call(['hg', 'clone', '--quiet', '--noupdate', source, t
arget]) | 57 subprocess.check_call(['hg', 'clone', '--quiet', '--noupdate', source, t
arget]) |
56 | 58 |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 | 266 |
265 # In case a package.json does not exist at all or if there are no | 267 # In case a package.json does not exist at all or if there are no |
266 # production dependencies declared, we don't need to run npm and can | 268 # production dependencies declared, we don't need to run npm and can |
267 # bail out early. | 269 # bail out early. |
268 if not package_data.get('dependencies', False): | 270 if not package_data.get('dependencies', False): |
269 return | 271 return |
270 except IOError: | 272 except IOError: |
271 return | 273 return |
272 | 274 |
273 try: | 275 try: |
274 cmd = ['npm', 'install', '--only=production', '--loglevel=warn'] | 276 # Create an empty file, which gets deleted after successfully |
| 277 # installing Node.js dependencies. |
| 278 lockfile_path = os.path.join(target, NPM_LOCKFILE) |
| 279 open(lockfile_path, 'a').close() |
| 280 |
| 281 if os.name == 'nt': |
| 282 # Windows' CreateProcess() (called by subprocess.Popen()) only |
| 283 # resolves executables ending in .exe. The windows installation of |
| 284 # Node.js only provides a npm.cmd, which is executable but won't |
| 285 # be recognized as such by CreateProcess(). |
| 286 npm_exec = 'npm.cmd' |
| 287 else: |
| 288 npm_exec = 'npm' |
| 289 |
| 290 cmd = [npm_exec, 'install', '--only=production', '--loglevel=warn', |
| 291 '--no-package-lock', '--no-optional'] |
275 subprocess.check_output(cmd, cwd=target) | 292 subprocess.check_output(cmd, cwd=target) |
276 | 293 |
| 294 repo_types[vcs].ignore(os.path.join(target, NPM_LOCKFILE), target) |
277 repo_types[vcs].ignore(os.path.join(target, 'node_modules'), target) | 295 repo_types[vcs].ignore(os.path.join(target, 'node_modules'), target) |
| 296 |
| 297 os.remove(lockfile_path) |
278 except OSError as e: | 298 except OSError as e: |
279 import errno | 299 import errno |
280 if e.errno == errno.ENOENT: | 300 if e.errno == errno.ENOENT: |
281 logging.error('Failed to install Node.js dependencies for %s,' | 301 logging.error('Failed to install Node.js dependencies for %s,' |
282 ' please ensure Node.js is installed.', target) | 302 ' please ensure Node.js is installed.', target) |
283 else: | 303 else: |
284 raise | 304 raise |
285 | 305 |
286 | 306 |
287 def ensure_repo(parentrepo, parenttype, target, type, root, sourcename): | 307 def ensure_repo(parentrepo, parenttype, target, type, root, sourcename): |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 vcs = key | 378 vcs = key |
359 source, rev = merge_seqs(sources.get('*'), sources.get(vcs)) | 379 source, rev = merge_seqs(sources.get('*'), sources.get(vcs)) |
360 | 380 |
361 if not (vcs and source and rev): | 381 if not (vcs and source and rev): |
362 logging.warning('No valid source / revision found to create %s' % ta
rget) | 382 logging.warning('No valid source / revision found to create %s' % ta
rget) |
363 continue | 383 continue |
364 | 384 |
365 repo_cloned = ensure_repo(repodir, parenttype, target, vcs, | 385 repo_cloned = ensure_repo(repodir, parenttype, target, vcs, |
366 _root.get(vcs, ''), source) | 386 _root.get(vcs, ''), source) |
367 repo_updated = update_repo(target, vcs, rev) | 387 repo_updated = update_repo(target, vcs, rev) |
368 if repo_cloned or repo_updated: | 388 recent_npm_failed = os.path.exists(os.path.join(target, NPM_LOCKFILE)) |
| 389 if repo_cloned or repo_updated or recent_npm_failed: |
369 resolve_npm_dependencies(target, vcs) | 390 resolve_npm_dependencies(target, vcs) |
370 resolve_deps(target, level + 1, self_update=False, | 391 resolve_deps(target, level + 1, self_update=False, |
371 overrideroots=overrideroots, skipdependencies=skipdependenc
ies) | 392 overrideroots=overrideroots, skipdependencies=skipdependenc
ies) |
372 | 393 |
373 if self_update and '_self' in config and '*' in config['_self']: | 394 if self_update and '_self' in config and '*' in config['_self']: |
374 source = safe_join(repodir, config['_self']['*']) | 395 source = safe_join(repodir, config['_self']['*']) |
375 try: | 396 try: |
376 with io.open(source, 'rb') as handle: | 397 with io.open(source, 'rb') as handle: |
377 sourcedata = handle.read() | 398 sourcedata = handle.read() |
378 except IOError as e: | 399 except IOError as e: |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 args = parser.parse_args() | 438 args = parser.parse_args() |
418 | 439 |
419 if args.quiet: | 440 if args.quiet: |
420 logging.disable(logging.INFO) | 441 logging.disable(logging.INFO) |
421 | 442 |
422 repos = args.repos | 443 repos = args.repos |
423 if not len(repos): | 444 if not len(repos): |
424 repos = [os.path.dirname(__file__)] | 445 repos = [os.path.dirname(__file__)] |
425 for repo in repos: | 446 for repo in repos: |
426 resolve_deps(repo) | 447 resolve_deps(repo) |
OLD | NEW |