Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(229)

Side by Side Diff: infra/tools/new_tool/new_tool.py

Issue 1172053003: Created infra/tools/new_tool (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « infra/tools/new_tool/__main__.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Copyright 2015 The Chromium Authors. All rights reserved.
Ryan Tseng 2015/06/09 23:03:05 I think i'd prefer a filename.template file with a
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 import argparse
6 import datetime
7 import os
8 import sys
9 import textwrap
10
11 # infra subdirectory containing tools.
12 TOOL_DIR = os.path.dirname(os.path.dirname(__file__))
13
14
15 COPYRIGHT_NOTICE = """\
16 # Copyright %s The Chromium Authors. All rights reserved.
17 # Use of this source code is governed by a BSD-style license that can be
18 # found in the LICENSE file.
19 """ % datetime.datetime.now().strftime('%Y')
20
21
22 def add_argparse_options(parser):
23 parser.add_argument(
24 'name', metavar='name', type=str, nargs=1,
25 help='The name of the new tool.')
26
27 parser.add_argument('--base-dir', default=TOOL_DIR,
28 help='Directory where to create the tool. Default: '
29 '%(default)s')
30
31
32 def generate_init_file(dirpath):
33 """Generate a __init__.py file in the specified directory."""
34
35 init_file_path = os.path.join(dirpath, '__init__.py')
36 if os.path.isfile(init_file_path):
37 print 'Skipping existing file %s' % init_file_path
38 return
39
40 with open(init_file_path, 'w') as f:
41 f.write(COPYRIGHT_NOTICE)
42
43
44 def generate_main_file(dirpath, toolname):
45 """Generate a __main__.py file in the specified directory."""
46 main_file_path = os.path.join(dirpath, '__main__.py')
47 if os.path.isfile(main_file_path):
48 print 'Skipping existing file %s' % main_file_path
49 return
50
51 MAIN_CONTENT = textwrap.dedent("""
52 \"\"\"<General description of {Toolname} here.>
53
54 [TBD] Example invocation:
55 ./run.py infra.tools.{toolname} <arguments>
56 \"\"\"
57
58 # This file is untested, keep as little code as possible in there.
59
60 import argparse
61 import logging
62 import sys
63
64 from infra.tools.{toolname} import {toolname}
65 import infra_libs.logs
66
67
68 # https://storage.googleapis.com/chromium-infra-docs/infra/html/logging.html
69 LOGGER = logging.getLogger(__name__)
70
71
72 def main(argv):
73 parser = argparse.ArgumentParser(
74 prog="{toolname}",
75 description=sys.modules['__main__'].__doc__)
76 {toolname}.add_argparse_options(parser)
77 infra_libs.logs.add_argparse_options(parser)
78 _args = parser.parse_args(argv)
79
80 infra_libs.logs.process_argparse_options(parser)
81
82 # Do more processing here
83 LOGGER.info('{Toolname} starting.')
84
85
86 if __name__ == '__main__':
87 sys.exit(main(sys.argv[1:]))
88 """).format(toolname=toolname, Toolname=toolname.capitalize())
89
90 with open(main_file_path, 'w') as f:
91 f.write(COPYRIGHT_NOTICE)
92 f.write(MAIN_CONTENT)
93
94
95 def generate_tool_file(dirpath, toolname):
96 """Generate a <toolname>.py file in the specified directory"""
97
98 file_path = os.path.join(dirpath, '%s.py' % toolname)
99 if os.path.isfile(file_path):
100 print 'Skipping existing file %s' % file_path
101 return
102
103 MODULE_CONTENT = textwrap.dedent("""
104 \"\"\"Testable functions for {Toolname}.\"\"\"
105
106 import logging
107
108
109 # https://storage.googleapis.com/chromium-infra-docs/infra/html/logging.html
110 LOGGER = logging.getLogger(__name__)
111
112
113 def add_argparse_options(parser):
114 \"\"\"Define command-line arguments.\"\"\"
115 parser.add_argument('--my-argument', '-m', help='')
116 """).format(Toolname=toolname.capitalize())
117
118 with open(file_path, 'w') as f:
119 f.write(COPYRIGHT_NOTICE)
120 f.write(MODULE_CONTENT)
121
122
123 def generate_test_file(dirpath, toolname, tested_file):
124 """Generate a test file in the proper place.
125
126 Example:
127 generate_test_file('foo', 'bar') creates foo/test/bar_test.py
128 """
129 file_path = os.path.join(dirpath, 'test', '%s_test.py' % tested_file)
130 if os.path.isfile(file_path):
131 print 'Skipping existing file %s' % file_path
132 return
133
134 test_dir = os.path.join(dirpath, 'test')
135 if not os.path.exists(test_dir):
136 os.mkdir(os.path.join(test_dir))
137
138 MODULE_CONTENT = textwrap.dedent("""
139 \"\"\"Tests for ../{tested_file}.py\"\"\"
140
141 import argparse
142 import unittest
143
144 from infra.tools.{toolname} import {tested_file}
145
146 class MyTest(unittest.TestCase):
147 def test_arguments(self):
148 parser = argparse.ArgumentParser()
149 {tested_file}.add_argparse_options(parser)
150 args = parser.parse_args(['--my-argument', 'value'])
151 self.assertEqual(args.my_argument, 'value')
152
153 ## expect_tests style: the test method returns a value (expectation)
154 ## that is stored when run in 'train' mode, and compared to in 'test' mode.
155 ## If the stored and returned values do not match, the test fails.
156 ##
157 ## def test_my_first_test_with_expectation(self):
158 ## # Use hash() here to make sure the test fails in any case.
159 ## return hash(MyTest)
Sergey Berezin 2015/06/10 00:32:37 nit: this looks confusing to me. Why would I want
160 """).format(toolname=toolname, tested_file=tested_file)
161
162 with open(file_path, 'w') as f:
163 f.write(COPYRIGHT_NOTICE)
164 f.write(MODULE_CONTENT)
165
166
167 def generate_tool_files(name, base_dir):
168 """Generate a stub tool from template files.
169
170 Args:
171 name (str): name of the tool. This is also the name of the directory
172 generated.
173 base_dir (str): path to the directory where to create the files.
174
175 Return:
176 tool_path (str or None): directory created or None is nothing has been done.
177 """
178
179 if not os.path.isdir(base_dir):
180 print 'Destination directory does not exist'
181 return 1
182
183 tool_dir = os.path.join(base_dir, name)
184 if os.path.exists(tool_dir):
185 print 'Tool seems to already exists: %s\nAborting.' % tool_dir
186 return 1
187
188 print 'Generating %s...' % tool_dir
189 os.mkdir(tool_dir)
190 generate_init_file(tool_dir)
191 generate_main_file(tool_dir, name)
192 generate_tool_file(tool_dir, name)
193 generate_test_file(tool_dir, name, name)
194 generate_init_file(os.path.join(tool_dir, 'test'))
195 print 'Done.'
OLDNEW
« no previous file with comments | « infra/tools/new_tool/__main__.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698