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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « infra/tools/new_tool/__main__.py ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: infra/tools/new_tool/new_tool.py
diff --git a/infra/tools/new_tool/new_tool.py b/infra/tools/new_tool/new_tool.py
new file mode 100644
index 0000000000000000000000000000000000000000..1b29fca5366ca07afecfd7dc21f7890d086d155f
--- /dev/null
+++ b/infra/tools/new_tool/new_tool.py
@@ -0,0 +1,195 @@
+# 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
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import argparse
+import datetime
+import os
+import sys
+import textwrap
+
+# infra subdirectory containing tools.
+TOOL_DIR = os.path.dirname(os.path.dirname(__file__))
+
+
+COPYRIGHT_NOTICE = """\
+# Copyright %s 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.
+""" % datetime.datetime.now().strftime('%Y')
+
+
+def add_argparse_options(parser):
+ parser.add_argument(
+ 'name', metavar='name', type=str, nargs=1,
+ help='The name of the new tool.')
+
+ parser.add_argument('--base-dir', default=TOOL_DIR,
+ help='Directory where to create the tool. Default: '
+ '%(default)s')
+
+
+def generate_init_file(dirpath):
+ """Generate a __init__.py file in the specified directory."""
+
+ init_file_path = os.path.join(dirpath, '__init__.py')
+ if os.path.isfile(init_file_path):
+ print 'Skipping existing file %s' % init_file_path
+ return
+
+ with open(init_file_path, 'w') as f:
+ f.write(COPYRIGHT_NOTICE)
+
+
+def generate_main_file(dirpath, toolname):
+ """Generate a __main__.py file in the specified directory."""
+ main_file_path = os.path.join(dirpath, '__main__.py')
+ if os.path.isfile(main_file_path):
+ print 'Skipping existing file %s' % main_file_path
+ return
+
+ MAIN_CONTENT = textwrap.dedent("""
+ \"\"\"<General description of {Toolname} here.>
+
+ [TBD] Example invocation:
+ ./run.py infra.tools.{toolname} <arguments>
+ \"\"\"
+
+ # This file is untested, keep as little code as possible in there.
+
+ import argparse
+ import logging
+ import sys
+
+ from infra.tools.{toolname} import {toolname}
+ import infra_libs.logs
+
+
+ # https://storage.googleapis.com/chromium-infra-docs/infra/html/logging.html
+ LOGGER = logging.getLogger(__name__)
+
+
+ def main(argv):
+ parser = argparse.ArgumentParser(
+ prog="{toolname}",
+ description=sys.modules['__main__'].__doc__)
+ {toolname}.add_argparse_options(parser)
+ infra_libs.logs.add_argparse_options(parser)
+ _args = parser.parse_args(argv)
+
+ infra_libs.logs.process_argparse_options(parser)
+
+ # Do more processing here
+ LOGGER.info('{Toolname} starting.')
+
+
+ if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
+ """).format(toolname=toolname, Toolname=toolname.capitalize())
+
+ with open(main_file_path, 'w') as f:
+ f.write(COPYRIGHT_NOTICE)
+ f.write(MAIN_CONTENT)
+
+
+def generate_tool_file(dirpath, toolname):
+ """Generate a <toolname>.py file in the specified directory"""
+
+ file_path = os.path.join(dirpath, '%s.py' % toolname)
+ if os.path.isfile(file_path):
+ print 'Skipping existing file %s' % file_path
+ return
+
+ MODULE_CONTENT = textwrap.dedent("""
+ \"\"\"Testable functions for {Toolname}.\"\"\"
+
+ import logging
+
+
+ # https://storage.googleapis.com/chromium-infra-docs/infra/html/logging.html
+ LOGGER = logging.getLogger(__name__)
+
+
+ def add_argparse_options(parser):
+ \"\"\"Define command-line arguments.\"\"\"
+ parser.add_argument('--my-argument', '-m', help='')
+ """).format(Toolname=toolname.capitalize())
+
+ with open(file_path, 'w') as f:
+ f.write(COPYRIGHT_NOTICE)
+ f.write(MODULE_CONTENT)
+
+
+def generate_test_file(dirpath, toolname, tested_file):
+ """Generate a test file in the proper place.
+
+ Example:
+ generate_test_file('foo', 'bar') creates foo/test/bar_test.py
+ """
+ file_path = os.path.join(dirpath, 'test', '%s_test.py' % tested_file)
+ if os.path.isfile(file_path):
+ print 'Skipping existing file %s' % file_path
+ return
+
+ test_dir = os.path.join(dirpath, 'test')
+ if not os.path.exists(test_dir):
+ os.mkdir(os.path.join(test_dir))
+
+ MODULE_CONTENT = textwrap.dedent("""
+ \"\"\"Tests for ../{tested_file}.py\"\"\"
+
+ import argparse
+ import unittest
+
+ from infra.tools.{toolname} import {tested_file}
+
+ class MyTest(unittest.TestCase):
+ def test_arguments(self):
+ parser = argparse.ArgumentParser()
+ {tested_file}.add_argparse_options(parser)
+ args = parser.parse_args(['--my-argument', 'value'])
+ self.assertEqual(args.my_argument, 'value')
+
+ ## expect_tests style: the test method returns a value (expectation)
+ ## that is stored when run in 'train' mode, and compared to in 'test' mode.
+ ## If the stored and returned values do not match, the test fails.
+ ##
+ ## def test_my_first_test_with_expectation(self):
+ ## # Use hash() here to make sure the test fails in any case.
+ ## return hash(MyTest)
Sergey Berezin 2015/06/10 00:32:37 nit: this looks confusing to me. Why would I want
+ """).format(toolname=toolname, tested_file=tested_file)
+
+ with open(file_path, 'w') as f:
+ f.write(COPYRIGHT_NOTICE)
+ f.write(MODULE_CONTENT)
+
+
+def generate_tool_files(name, base_dir):
+ """Generate a stub tool from template files.
+
+ Args:
+ name (str): name of the tool. This is also the name of the directory
+ generated.
+ base_dir (str): path to the directory where to create the files.
+
+ Return:
+ tool_path (str or None): directory created or None is nothing has been done.
+ """
+
+ if not os.path.isdir(base_dir):
+ print 'Destination directory does not exist'
+ return 1
+
+ tool_dir = os.path.join(base_dir, name)
+ if os.path.exists(tool_dir):
+ print 'Tool seems to already exists: %s\nAborting.' % tool_dir
+ return 1
+
+ print 'Generating %s...' % tool_dir
+ os.mkdir(tool_dir)
+ generate_init_file(tool_dir)
+ generate_main_file(tool_dir, name)
+ generate_tool_file(tool_dir, name)
+ generate_test_file(tool_dir, name, name)
+ generate_init_file(os.path.join(tool_dir, 'test'))
+ print 'Done.'
« 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