You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			165 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Python
		
	
			
		
		
	
	
			165 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Python
		
	
#!/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): Use cipd/glyco instead of git/gclient.
 | 
						|
 | 
						|
import argparse
 | 
						|
import sys
 | 
						|
import os
 | 
						|
import subprocess
 | 
						|
import re
 | 
						|
 | 
						|
 | 
						|
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.PIPE)
 | 
						|
  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.PIPE, 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.PIPE)
 | 
						|
  subprocess.check_call(
 | 
						|
      [sys.executable, GCLIENT, 'sync', '--revision', 'origin/%s' % (branch,)],
 | 
						|
      cwd=TARGET_DIR,
 | 
						|
      stdout=subprocess.PIPE)
 | 
						|
  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 >>sys.stderr, 'Unknown tool "%s"' % tool_name
 | 
						|
    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())
 |