diff --git a/cit b/cit new file mode 100755 index 000000000..410341ff9 --- /dev/null +++ b/cit @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# 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. + +base_dir=$(dirname "$0") + +PYTHONDONTWRITEBYTECODE=1 exec python "$base_dir/cit.py" "$@" diff --git a/cit.bat b/cit.bat new file mode 100755 index 000000000..a1da0ddc3 --- /dev/null +++ b/cit.bat @@ -0,0 +1,11 @@ +@echo off +:: 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. +setlocal + +:: This is required with cygwin only. +PATH=%~dp0;%PATH% + +:: Defer control. +%~dp0python "%~dp0\cit.py" %* diff --git a/cit.py b/cit.py new file mode 100755 index 000000000..8e1ae55d6 --- /dev/null +++ b/cit.py @@ -0,0 +1,104 @@ +#!/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.* +""" + +# TODO(hinoka): Use cipd/glyco instead of git/gclient. + +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('~/.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(): + """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. + + 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/deployed') + return origin_rev != local_rev + + +def ensure_infra(): + """Ensures that infra.git is present in ~/.chrome-infra.""" + print 'Fetching infra into %s, may take a couple of minutes...' % TARGET_DIR + 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', 'deployed'], + cwd=TARGET_DIR, + stdout=subprocess.PIPE) + + +def get_available_tools(): + tools = [] + starting = os.path.join(TARGET_DIR, 'infra', 'infra', 'tools') + for root, _, files in os.walk(starting): + if '__main__.py' in files: + tools.append(root[len(starting)+1:].replace(os.path.sep, '.')) + return tools + + +def run(args): + if args: + tool_name = args[0] + cmd = [ + sys.executable, os.path.join(TARGET_DIR, 'infra', 'run.py'), + 'infra.tools.%s' % tool_name] + cmd.extend(args[1:]) + return subprocess.call(cmd) + + tools = get_available_tools() + print """usage: cit.py [args for tool] + + Wrapper for maintaining and calling tools in "infra.git/run.py infra.tools.*" + + Available tools are: + """ + for tool in tools: + print ' * %s' % tool + + +def main(): + if need_to_update(): + ensure_infra() + return run(sys.argv[1:]) + +if __name__ == '__main__': + sys.exit(main())