 Issue 29868595:
  Issue 6909 - Make ensure_dependencies.py call "npm install" for non-repositories  (Closed)
    
  
    Issue 29868595:
  Issue 6909 - Make ensure_dependencies.py call "npm install" for non-repositories  (Closed) 
  | Left: | ||
| Right: | 
| 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 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 239 raise Exception('Dependency path %s cannot be absolute' % subpath) | 239 raise Exception('Dependency path %s cannot be absolute' % subpath) | 
| 240 if normpath == posixpath.pardir or normpath.startswith(posixpath.pardir + po sixpath.sep): | 240 if normpath == posixpath.pardir or normpath.startswith(posixpath.pardir + po sixpath.sep): | 
| 241 raise Exception('Dependency path %s has to be inside the repository' % s ubpath) | 241 raise Exception('Dependency path %s has to be inside the repository' % s ubpath) | 
| 242 return os.path.join(path, *normpath.split(posixpath.sep)) | 242 return os.path.join(path, *normpath.split(posixpath.sep)) | 
| 243 | 243 | 
| 244 | 244 | 
| 245 def get_repo_type(repo): | 245 def get_repo_type(repo): | 
| 246 for name, repotype in repo_types.iteritems(): | 246 for name, repotype in repo_types.iteritems(): | 
| 247 if repotype.istype(repo): | 247 if repotype.istype(repo): | 
| 248 return name | 248 return name | 
| 249 return 'hg' | 249 return None | 
| 250 | 250 | 
| 251 | 251 | 
| 252 def resolve_npm_dependencies(target, vcs): | 252 def resolve_npm_dependencies(target, vcs): | 
| 253 """Install Node.js production-only dependencies if necessary and desired. | 253 """Install Node.js production-only dependencies if necessary and desired. | 
| 254 | 254 | 
| 255 When the target dependency has additional Node.js dependencies declared | 255 When the target dependency has additional Node.js dependencies declared | 
| 256 run "npm install --only=production --loglevel=warn" to resolve the declared | 256 run "npm install --only=production --loglevel=warn" to resolve the declared | 
| 257 dependencies. | 257 dependencies. | 
| 258 | 258 | 
| 259 Additionally, make sure that any VCS will ignore the installed files. | 259 Additionally, make sure that any VCS will ignore the installed files. | 
| (...skipping 24 matching lines...) Expand all Loading... | |
| 284 # Node.js only provides a npm.cmd, which is executable but won't | 284 # Node.js only provides a npm.cmd, which is executable but won't | 
| 285 # be recognized as such by CreateProcess(). | 285 # be recognized as such by CreateProcess(). | 
| 286 npm_exec = 'npm.cmd' | 286 npm_exec = 'npm.cmd' | 
| 287 else: | 287 else: | 
| 288 npm_exec = 'npm' | 288 npm_exec = 'npm' | 
| 289 | 289 | 
| 290 cmd = [npm_exec, 'install', '--only=production', '--loglevel=warn', | 290 cmd = [npm_exec, 'install', '--only=production', '--loglevel=warn', | 
| 291 '--no-package-lock', '--no-optional'] | 291 '--no-package-lock', '--no-optional'] | 
| 292 subprocess.check_output(cmd, cwd=target) | 292 subprocess.check_output(cmd, cwd=target) | 
| 293 | 293 | 
| 294 repo_types[vcs].ignore(os.path.join(target, NPM_LOCKFILE), target) | 294 if vcs: | 
| 295 repo_types[vcs].ignore(os.path.join(target, 'node_modules'), target) | 295 repo_types[vcs].ignore(os.path.join(target, NPM_LOCKFILE), target) | 
| 296 repo_types[vcs].ignore(os.path.join(target, 'node_modules'), target) | |
| 296 | 297 | 
| 297 os.remove(lockfile_path) | 298 os.remove(lockfile_path) | 
| 298 except OSError as e: | 299 except OSError as e: | 
| 299 import errno | 300 import errno | 
| 300 if e.errno == errno.ENOENT: | 301 if e.errno == errno.ENOENT: | 
| 301 logging.error('Failed to install Node.js dependencies for %s,' | 302 logging.error('Failed to install Node.js dependencies for %s,' | 
| 302 ' please ensure Node.js is installed.', target) | 303 ' please ensure Node.js is installed.', target) | 
| 303 else: | 304 else: | 
| 304 raise | 305 raise | 
| 305 | 306 | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 344 resolved_revision = repo_types[type].get_revision_id(target, revisio n) | 345 resolved_revision = repo_types[type].get_revision_id(target, revisio n) | 
| 345 if not resolved_revision: | 346 if not resolved_revision: | 
| 346 raise Exception('Failed to resolve revision %s' % revision) | 347 raise Exception('Failed to resolve revision %s' % revision) | 
| 347 | 348 | 
| 348 logging.info('Updating repository %s to revision %s' % (target, resolved _revision)) | 349 logging.info('Updating repository %s to revision %s' % (target, resolved _revision)) | 
| 349 repo_types[type].update(target, resolved_revision, revision) | 350 repo_types[type].update(target, resolved_revision, revision) | 
| 350 return True | 351 return True | 
| 351 return False | 352 return False | 
| 352 | 353 | 
| 353 | 354 | 
| 354 def resolve_deps(repodir, level=0, self_update=True, overrideroots=None, skipdep endencies=set()): | 355 def resolve_deps(repodir, repotype, level=0, self_update=True, overrideroots=Non e, skipdependencies=set()): | 
| 
tlucas
2018/08/29 21:19:14
Nit: please break after 79, when touching this any
 
Sebastian Noack
2018/08/30 00:42:33
Done.
 | |
| 355 config = read_deps(repodir) | 356 config = read_deps(repodir) | 
| 356 if config is None: | 357 if config is None: | 
| 357 if level == 0: | 358 if level == 0: | 
| 358 logging.warning('No dependencies file in directory %s, nothing to do ...\n%s' % (repodir, USAGE)) | 359 logging.warning('No dependencies file in directory %s, nothing to do ...\n%s' % (repodir, USAGE)) | 
| 359 return | 360 return | 
| 360 if level >= 10: | 361 if level >= 10: | 
| 361 logging.warning('Too much subrepository nesting, ignoring %s' % repo) | 362 logging.warning('Too much subrepository nesting, ignoring %s' % repo) | 
| 362 return | 363 return | 
| 363 | 364 | 
| 364 if overrideroots is not None: | 365 if overrideroots is not None: | 
| 365 config['_root'] = overrideroots | 366 config['_root'] = overrideroots | 
| 366 | 367 | 
| 367 for dir, sources in sorted(config.iteritems()): | 368 for dir, sources in sorted(config.iteritems()): | 
| 368 if (dir.startswith('_') or | 369 if (dir.startswith('_') or | 
| 369 skipdependencies.intersection([s[0] for s in sources if s[0]])): | 370 skipdependencies.intersection([s[0] for s in sources if s[0]])): | 
| 370 continue | 371 continue | 
| 371 | 372 | 
| 372 target = safe_join(repodir, dir) | 373 target = safe_join(repodir, dir) | 
| 373 parenttype = get_repo_type(repodir) | 374 parenttype = repotype or 'hg' | 
| 374 _root = config.get('_root', {}) | 375 _root = config.get('_root', {}) | 
| 375 | 376 | 
| 376 for key in sources.keys() + _root.keys(): | 377 for key in sources.keys() + _root.keys(): | 
| 377 if key == parenttype or key is None and vcs != '*': | 378 if key == parenttype or key is None and vcs != '*': | 
| 378 vcs = key | 379 vcs = key | 
| 379 source, rev = merge_seqs(sources.get('*'), sources.get(vcs)) | 380 source, rev = merge_seqs(sources.get('*'), sources.get(vcs)) | 
| 380 | 381 | 
| 381 if not (vcs and source and rev): | 382 if not (vcs and source and rev): | 
| 382 logging.warning('No valid source / revision found to create %s' % ta rget) | 383 logging.warning('No valid source / revision found to create %s' % ta rget) | 
| 383 continue | 384 continue | 
| 384 | 385 | 
| 385 repo_cloned = ensure_repo(repodir, parenttype, target, vcs, | 386 repo_cloned = ensure_repo(repodir, parenttype, target, vcs, | 
| 386 _root.get(vcs, ''), source) | 387 _root.get(vcs, ''), source) | 
| 387 repo_updated = update_repo(target, vcs, rev) | 388 if repo_types[vcs].istype(target): | 
| 389 repo_updated = update_repo(target, vcs, rev) | |
| 390 npm_outdated = repo_cloned or repo_updated | |
| 391 else: | |
| 392 vcs = None | |
| 393 npm_outdated = not os.path.exists(os.path.join(target, 'node_modules ')) | |
| 
tlucas
2018/08/29 21:19:14
Nit: Please break after 79 characters.
 
Sebastian Noack
2018/08/30 00:42:33
Done.
 | |
| 394 | |
| 388 recent_npm_failed = os.path.exists(os.path.join(target, NPM_LOCKFILE)) | 395 recent_npm_failed = os.path.exists(os.path.join(target, NPM_LOCKFILE)) | 
| 389 if repo_cloned or repo_updated or recent_npm_failed: | 396 if npm_outdated or recent_npm_failed: | 
| 390 resolve_npm_dependencies(target, vcs) | 397 resolve_npm_dependencies(target, vcs) | 
| 391 resolve_deps(target, level + 1, self_update=False, | 398 | 
| 399 resolve_deps(target, vcs, level + 1, self_update=False, | |
| 392 overrideroots=overrideroots, skipdependencies=skipdependenc ies) | 400 overrideroots=overrideroots, skipdependencies=skipdependenc ies) | 
| 393 | 401 | 
| 394 if self_update and '_self' in config and '*' in config['_self']: | 402 if self_update and '_self' in config and '*' in config['_self']: | 
| 395 source = safe_join(repodir, config['_self']['*']) | 403 source = safe_join(repodir, config['_self']['*']) | 
| 396 try: | 404 try: | 
| 397 with io.open(source, 'rb') as handle: | 405 with io.open(source, 'rb') as handle: | 
| 398 sourcedata = handle.read() | 406 sourcedata = handle.read() | 
| 399 except IOError as e: | 407 except IOError as e: | 
| 400 if e.errno != errno.ENOENT: | 408 if e.errno != errno.ENOENT: | 
| 401 raise | 409 raise | 
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 437 parser.add_argument('-q', '--quiet', action='store_true', help='Suppress inf ormational output') | 445 parser.add_argument('-q', '--quiet', action='store_true', help='Suppress inf ormational output') | 
| 438 args = parser.parse_args() | 446 args = parser.parse_args() | 
| 439 | 447 | 
| 440 if args.quiet: | 448 if args.quiet: | 
| 441 logging.disable(logging.INFO) | 449 logging.disable(logging.INFO) | 
| 442 | 450 | 
| 443 repos = args.repos | 451 repos = args.repos | 
| 444 if not len(repos): | 452 if not len(repos): | 
| 445 repos = [os.path.dirname(__file__)] | 453 repos = [os.path.dirname(__file__)] | 
| 446 for repo in repos: | 454 for repo in repos: | 
| 447 resolve_deps(repo) | 455 resolve_deps(repo, get_repo_type(repo)) | 
| OLD | NEW |