blob: f08ddddc5b057e9d86cbcc6617a32cdbdd558238 [file] [log] [blame]
[email protected]bdc47282015-07-17 22:05:191#!/usr/bin/env python
2# Copyright (c) 2015 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6
7"""Wrapper for updating and calling infra.git tools.
8
9This tool does a two things:
10* Maintains a infra.git checkout pinned at "deployed" in the home dir
11* Acts as an alias to infra.tools.*
hinoka9a0de0b2016-07-14 20:00:0012* Acts as an alias to infra.git/cipd/<executable>
[email protected]bdc47282015-07-17 22:05:1913"""
14
15# TODO(hinoka): Use cipd/glyco instead of git/gclient.
16
[email protected]8829c522015-10-24 03:25:0517import argparse
[email protected]bdc47282015-07-17 22:05:1918import sys
19import os
20import subprocess
21import re
22
23
24SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
25GCLIENT = os.path.join(SCRIPT_DIR, 'gclient.py')
[email protected]c3499712015-11-25 01:04:0126TARGET_DIR = os.path.expanduser(os.path.join('~', '.chrome-infra'))
[email protected]bdc47282015-07-17 22:05:1927INFRA_DIR = os.path.join(TARGET_DIR, 'infra')
28
29
30def get_git_rev(target, branch):
31 return subprocess.check_output(
32 ['git', 'log', '--format=%B', '-n1', branch], cwd=target)
33
34
[email protected]8829c522015-10-24 03:25:0535def need_to_update(branch):
[email protected]bdc47282015-07-17 22:05:1936 """Checks to see if we need to update the ~/.chrome-infra/infra checkout."""
37 try:
38 cmd = [sys.executable, GCLIENT, 'revinfo']
39 subprocess.check_call(
40 cmd, cwd=os.path.join(TARGET_DIR), stdout=subprocess.PIPE)
41 except subprocess.CalledProcessError:
42 return True # Gclient failed, definitely need to update.
43 except OSError:
44 return True # Gclient failed, definitely need to update.
45
[email protected]3add4b62015-11-17 20:27:5646 if not os.path.isdir(INFRA_DIR):
47 return True
48
[email protected]bdc47282015-07-17 22:05:1949 local_rev = get_git_rev(INFRA_DIR, 'HEAD')
50
51 subprocess.check_call(
52 ['git', 'fetch', 'origin'], cwd=INFRA_DIR,
53 stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
[email protected]8829c522015-10-24 03:25:0554 origin_rev = get_git_rev(INFRA_DIR, 'origin/%s' % (branch,))
[email protected]bdc47282015-07-17 22:05:1955 return origin_rev != local_rev
56
57
[email protected]8829c522015-10-24 03:25:0558def ensure_infra(branch):
[email protected]bdc47282015-07-17 22:05:1959 """Ensures that infra.git is present in ~/.chrome-infra."""
tandrii56396af2016-06-17 16:50:4660 sys.stderr.write(
61 'Fetching infra@%s into %s, may take a couple of minutes...' % (
62 branch, TARGET_DIR))
63 sys.stderr.flush()
[email protected]bdc47282015-07-17 22:05:1964 if not os.path.isdir(TARGET_DIR):
65 os.mkdir(TARGET_DIR)
66 if not os.path.exists(os.path.join(TARGET_DIR, '.gclient')):
67 subprocess.check_call(
68 [sys.executable, os.path.join(SCRIPT_DIR, 'fetch.py'), 'infra'],
69 cwd=TARGET_DIR,
70 stdout=subprocess.PIPE)
71 subprocess.check_call(
[email protected]8829c522015-10-24 03:25:0572 [sys.executable, GCLIENT, 'sync', '--revision', 'origin/%s' % (branch,)],
[email protected]bdc47282015-07-17 22:05:1973 cwd=TARGET_DIR,
74 stdout=subprocess.PIPE)
tandrii56396af2016-06-17 16:50:4675 sys.stderr.write(' done.\n')
76 sys.stderr.flush()
[email protected]bdc47282015-07-17 22:05:1977
78
hinoka9a0de0b2016-07-14 20:00:0079def is_exe(filename):
80 """Given a full filepath, return true if the file is an executable."""
81 if sys.platform.startswith('win'):
82 return filename.endswith('.exe')
83 else:
84 return os.path.isfile(filename) and os.access(filename, os.X_OK)
85
86
[email protected]bdc47282015-07-17 22:05:1987def get_available_tools():
hinoka9a0de0b2016-07-14 20:00:0088 """Returns a tuple of (list of infra tools, list of cipd tools)"""
89 infra_tools = []
90 cipd_tools = []
[email protected]bdc47282015-07-17 22:05:1991 starting = os.path.join(TARGET_DIR, 'infra', 'infra', 'tools')
92 for root, _, files in os.walk(starting):
93 if '__main__.py' in files:
hinoka9a0de0b2016-07-14 20:00:0094 infra_tools.append(root[len(starting)+1:].replace(os.path.sep, '.'))
95 cipd = os.path.join(TARGET_DIR, 'infra', 'cipd')
96 for fn in os.listdir(cipd):
97 if is_exe(os.path.join(cipd, fn)):
98 cipd_tools.append(fn)
99 return (sorted(infra_tools), sorted(cipd_tools))
[email protected]bdc47282015-07-17 22:05:19100
101
dsansome72decfe2016-08-02 03:55:46102def usage():
hinoka9a0de0b2016-07-14 20:00:00103 infra_tools, cipd_tools = get_available_tools()
[email protected]bdc47282015-07-17 22:05:19104 print """usage: cit.py <name of tool> [args for tool]
105
hinoka9a0de0b2016-07-14 20:00:00106 Wrapper for maintaining and calling tools in:
107 "infra.git/run.py infra.tools.*"
108 "infra.git/cipd/*"
[email protected]bdc47282015-07-17 22:05:19109
hinoka9a0de0b2016-07-14 20:00:00110 Available infra tools are:"""
111 for tool in infra_tools:
[email protected]bdc47282015-07-17 22:05:19112 print ' * %s' % tool
113
hinoka9a0de0b2016-07-14 20:00:00114 print """
115 Available cipd tools are:"""
116 for tool in cipd_tools:
117 print ' * %s' % tool
118
119
dsansome72decfe2016-08-02 03:55:46120def run(args):
121 if not args:
122 return usage()
123
124 tool_name = args[0]
125 # Check to see if it is a infra tool first.
126 infra_dir = os.path.join(
127 TARGET_DIR, 'infra', 'infra', 'tools', *tool_name.split('.'))
128 cipd_file = os.path.join(TARGET_DIR, 'infra', 'cipd', tool_name)
129 if sys.platform.startswith('win'):
130 cipd_file += '.exe'
131 if (os.path.isdir(infra_dir)
132 and os.path.isfile(os.path.join(infra_dir, '__main__.py'))):
133 cmd = [
134 sys.executable, os.path.join(TARGET_DIR, 'infra', 'run.py'),
135 'infra.tools.%s' % tool_name]
136 elif os.path.isfile(cipd_file) and is_exe(cipd_file):
137 cmd = [cipd_file]
138 else:
139 print >>sys.stderr, 'Unknown tool "%s"' % tool_name
140 return usage()
141
142 # Add the remaining arguments.
143 cmd.extend(args[1:])
144 return subprocess.call(cmd)
145
[email protected]bdc47282015-07-17 22:05:19146
147def main():
[email protected]8829c522015-10-24 03:25:05148 parser = argparse.ArgumentParser("Chrome Infrastructure CLI.")
149 parser.add_argument('-b', '--infra-branch', default='deployed',
150 help="The name of the 'infra' branch to use (default is %(default)s).")
151 parser.add_argument('args', nargs=argparse.REMAINDER)
152
153 args, extras = parser.parse_known_args()
154 if args.args and args.args[0] == '--':
155 args.args.pop(0)
156 if extras:
157 args.args = extras + args.args
158
159 if need_to_update(args.infra_branch):
160 ensure_infra(args.infra_branch)
161 return run(args.args)
[email protected]bdc47282015-07-17 22:05:19162
163if __name__ == '__main__':
164 sys.exit(main())