123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- #!/usr/bin/env python
- # Copyright (c) 2015 The Chromium Authors. All rights reserved.
- # Use of this source code is governed by a BSD-style license that can be
- # found in the LICENSE file.
- """Wrapper for updating and calling infra.git tools.
- This tool does a two things:
- * Maintains a infra.git checkout pinned at "deployed" in the home dir
- * Acts as an alias to infra.tools.*
- * Acts as an alias to infra.git/cipd/<executable>
- """
- # TODO(hinoka,iannucci): Pre-pack infra tools in cipd package with vpython spec.
- from __future__ import print_function
- import argparse
- import sys
- import os
- import re
- import subprocess2 as subprocess
- SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
- GCLIENT = os.path.join(SCRIPT_DIR, 'gclient.py')
- TARGET_DIR = os.path.expanduser(os.path.join('~', '.chrome-infra'))
- INFRA_DIR = os.path.join(TARGET_DIR, 'infra')
- def get_git_rev(target, branch):
- return subprocess.check_output(
- ['git', 'log', '--format=%B', '-n1', branch], cwd=target)
- def need_to_update(branch):
- """Checks to see if we need to update the ~/.chrome-infra/infra checkout."""
- try:
- cmd = [sys.executable, GCLIENT, 'revinfo']
- subprocess.check_call(
- cmd, cwd=os.path.join(TARGET_DIR), stdout=subprocess.DEVNULL)
- except subprocess.CalledProcessError:
- return True # Gclient failed, definitely need to update.
- except OSError:
- return True # Gclient failed, definitely need to update.
- if not os.path.isdir(INFRA_DIR):
- return True
- local_rev = get_git_rev(INFRA_DIR, 'HEAD')
- subprocess.check_call(
- ['git', 'fetch', 'origin'], cwd=INFRA_DIR,
- stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
- origin_rev = get_git_rev(INFRA_DIR, 'origin/%s' % (branch,))
- return origin_rev != local_rev
- def ensure_infra(branch):
- """Ensures that infra.git is present in ~/.chrome-infra."""
- sys.stderr.write(
- 'Fetching infra@%s into %s, may take a couple of minutes...' % (
- branch, TARGET_DIR))
- sys.stderr.flush()
- if not os.path.isdir(TARGET_DIR):
- os.mkdir(TARGET_DIR)
- if not os.path.exists(os.path.join(TARGET_DIR, '.gclient')):
- subprocess.check_call(
- [sys.executable, os.path.join(SCRIPT_DIR, 'fetch.py'), 'infra'],
- cwd=TARGET_DIR,
- stdout=subprocess.DEVNULL)
- subprocess.check_call(
- [sys.executable, GCLIENT, 'sync', '--revision', 'origin/%s' % (branch,)],
- cwd=TARGET_DIR,
- stdout=subprocess.DEVNULL)
- sys.stderr.write(' done.\n')
- sys.stderr.flush()
- def is_exe(filename):
- """Given a full filepath, return true if the file is an executable."""
- if sys.platform.startswith('win'):
- return filename.endswith('.exe')
- else:
- return os.path.isfile(filename) and os.access(filename, os.X_OK)
- def get_available_tools():
- """Returns a tuple of (list of infra tools, list of cipd tools)"""
- infra_tools = []
- cipd_tools = []
- starting = os.path.join(TARGET_DIR, 'infra', 'infra', 'tools')
- for root, _, files in os.walk(starting):
- if '__main__.py' in files:
- infra_tools.append(root[len(starting)+1:].replace(os.path.sep, '.'))
- cipd = os.path.join(TARGET_DIR, 'infra', 'cipd')
- for fn in os.listdir(cipd):
- if is_exe(os.path.join(cipd, fn)):
- cipd_tools.append(fn)
- return (sorted(infra_tools), sorted(cipd_tools))
- def usage():
- infra_tools, cipd_tools = get_available_tools()
- print("""usage: cit.py <name of tool> [args for tool]
- Wrapper for maintaining and calling tools in:
- "infra.git/run.py infra.tools.*"
- "infra.git/cipd/*"
- Available infra tools are:""")
- for tool in infra_tools:
- print(' * %s' % tool)
- print("""
- Available cipd tools are:""")
- for tool in cipd_tools:
- print(' * %s' % tool)
- def run(args):
- if not args:
- return usage()
- tool_name = args[0]
- # Check to see if it is a infra tool first.
- infra_dir = os.path.join(
- TARGET_DIR, 'infra', 'infra', 'tools', *tool_name.split('.'))
- cipd_file = os.path.join(TARGET_DIR, 'infra', 'cipd', tool_name)
- if sys.platform.startswith('win'):
- cipd_file += '.exe'
- if (os.path.isdir(infra_dir)
- and os.path.isfile(os.path.join(infra_dir, '__main__.py'))):
- cmd = [
- sys.executable, os.path.join(TARGET_DIR, 'infra', 'run.py'),
- 'infra.tools.%s' % tool_name]
- elif os.path.isfile(cipd_file) and is_exe(cipd_file):
- cmd = [cipd_file]
- else:
- print('Unknown tool "%s"' % tool_name, file=sys.stderr)
- return usage()
- # Add the remaining arguments.
- cmd.extend(args[1:])
- return subprocess.call(cmd)
- def main():
- parser = argparse.ArgumentParser("Chrome Infrastructure CLI.")
- parser.add_argument('-b', '--infra-branch', default='cit',
- help="The name of the 'infra' branch to use (default is %(default)s).")
- parser.add_argument('args', nargs=argparse.REMAINDER)
- args, extras = parser.parse_known_args()
- if args.args and args.args[0] == '--':
- args.args.pop(0)
- if extras:
- args.args = extras + args.args
- if need_to_update(args.infra_branch):
- ensure_infra(args.infra_branch)
- return run(args.args)
- if __name__ == '__main__':
- sys.exit(main())
|