diff options
author | sbc <sbc@chromium.org> | 2015-01-14 07:30:12 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-01-14 15:31:14 +0000 |
commit | 22adb217d481d9a2115daab9caecd9d93aff8370 (patch) | |
tree | d7e7b03feb2416728727c7cd49591fa79bc6a135 /native_client_sdk | |
parent | d4646647dea3fa62f5682af240009b9dbf29b4b9 (diff) | |
download | chromium_src-22adb217d481d9a2115daab9caecd9d93aff8370.zip chromium_src-22adb217d481d9a2115daab9caecd9d93aff8370.tar.gz chromium_src-22adb217d481d9a2115daab9caecd9d93aff8370.tar.bz2 |
[NaCl SDK] Convert python scripts from optparse to argparse.
None of these changes should change the behaviour of the
scripts with the exception of rst_index.py which now takes
both output and input as positional parameters since they
are both required.
TEST=./test_all.py
Review URL: https://codereview.chromium.org/720233003
Cr-Commit-Position: refs/heads/master@{#311477}
Diffstat (limited to 'native_client_sdk')
48 files changed, 707 insertions, 671 deletions
diff --git a/native_client_sdk/src/build_tools/build_app.py b/native_client_sdk/src/build_tools/build_app.py index 61dd1d9..0c406c0 100755 --- a/native_client_sdk/src/build_tools/build_app.py +++ b/native_client_sdk/src/build_tools/build_app.py @@ -3,8 +3,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import argparse import json -import optparse import os import re import sys @@ -77,8 +77,8 @@ def GetStrip(pepperdir, platform, arch, toolchain): def main(args): - parser = optparse.OptionParser() - parser.add_option('-c', '--channel', + parser = argparse.ArgumentParser() + parser.add_argument('-c', '--channel', help='Channel to display in the name of the package.') # To setup bash completion for this command first install optcomplete @@ -90,7 +90,7 @@ def main(args): except ImportError: pass - options, args = parser.parse_args(args) + options = parser.parse_args(args) if options.channel: if options.channel not in ('Dev', 'Beta'): diff --git a/native_client_sdk/src/build_tools/build_projects.py b/native_client_sdk/src/build_tools/build_projects.py index 0c196ef..b25d7b7 100755 --- a/native_client_sdk/src/build_tools/build_projects.py +++ b/native_client_sdk/src/build_tools/build_projects.py @@ -3,8 +3,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import argparse import multiprocessing -import optparse import os import posixpath import sys @@ -243,28 +243,30 @@ def BuildProjects(pepperdir, project_tree, deps=True, BuildProjectsBranch(pepperdir, branch, deps, clean, config) -def main(argv): - parser = optparse.OptionParser() - parser.add_option('-c', '--clobber', +def main(args): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('-c', '--clobber', help='Clobber project directories before copying new files', action='store_true', default=False) - parser.add_option('-b', '--build', + parser.add_argument('-b', '--build', help='Build the projects. Otherwise the projects are only copied.', action='store_true') - parser.add_option('--config', + parser.add_argument('--config', help='Choose configuration to build (Debug or Release). Builds both ' 'by default') - parser.add_option('--bionic', + parser.add_argument('--bionic', help='Enable bionic projects', action='store_true') - parser.add_option('-x', '--experimental', + parser.add_argument('-x', '--experimental', help='Build experimental projects', action='store_true') - parser.add_option('-t', '--toolchain', + parser.add_argument('-t', '--toolchain', help='Build using toolchain. Can be passed more than once.', action='append', default=[]) - parser.add_option('-d', '--dest', + parser.add_argument('-d', '--dest', help='Select which build destinations (project types) are valid.', action='append') - parser.add_option('-v', '--verbose', action='store_true') + parser.add_argument('projects', nargs='*', + help='Select which projects to build.') + parser.add_argument('-v', '--verbose', action='store_true') # To setup bash completion for this command first install optcomplete # and then add this line to your .bashrc: @@ -275,7 +277,7 @@ def main(argv): except ImportError: pass - options, args = parser.parse_args(argv) + options = parser.parse_args(args) global verbose if options.verbose: @@ -316,9 +318,9 @@ def main(argv): if options.dest: filters['DEST'] = options.dest Trace('Filter by type: ' + str(options.dest)) - if args: - filters['NAME'] = args - Trace('Filter by name: ' + str(args)) + if options.projects: + filters['NAME'] = options.projects + Trace('Filter by name: ' + str(options.projects)) try: project_tree = parse_dsc.LoadProjectTree(SDK_SRC_DIR, include=filters) diff --git a/native_client_sdk/src/build_tools/build_sdk.py b/native_client_sdk/src/build_tools/build_sdk.py index 3002e14..cd34081 100755 --- a/native_client_sdk/src/build_tools/build_sdk.py +++ b/native_client_sdk/src/build_tools/build_sdk.py @@ -18,9 +18,9 @@ and whether it should upload an SDK to file storage (GSTORE) # pylint: disable=W0621 # std python includes +import argparse import datetime import glob -import optparse import os import re import sys @@ -903,32 +903,32 @@ def BuildStepBuildAppEngine(pepperdir, chrome_revision): def main(args): - parser = optparse.OptionParser(description=__doc__) - parser.add_option('--nacl-tree-path', + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--nacl-tree-path', help='Path to native client tree for bionic build.', dest='nacl_tree_path') - parser.add_option('--qemu', help='Add qemu for ARM.', + parser.add_argument('--qemu', help='Add qemu for ARM.', action='store_true') - parser.add_option('--bionic', help='Add bionic build.', + parser.add_argument('--bionic', help='Add bionic build.', action='store_true') - parser.add_option('--tar', help='Force the tar step.', + parser.add_argument('--tar', help='Force the tar step.', action='store_true') - parser.add_option('--archive', help='Force the archive step.', + parser.add_argument('--archive', help='Force the archive step.', action='store_true') - parser.add_option('--release', help='PPAPI release version.', + parser.add_argument('--release', help='PPAPI release version.', dest='release', default=None) - parser.add_option('--build-ports', + parser.add_argument('--build-ports', help='Build naclport bundle.', action='store_true') - parser.add_option('--build-app-engine', + parser.add_argument('--build-app-engine', help='Build AppEngine demos.', action='store_true') - parser.add_option('--experimental', + parser.add_argument('--experimental', help='build experimental examples and libraries', action='store_true', dest='build_experimental') - parser.add_option('--skip-toolchain', help='Skip toolchain untar', + parser.add_argument('--skip-toolchain', help='Skip toolchain untar', action='store_true') - parser.add_option('--mac-sdk', + parser.add_argument('--mac-sdk', help='Set the mac-sdk (e.g. 10.6) to use when building with ninja.') - parser.add_option('--no-arm-trusted', action='store_true', + parser.add_argument('--no-arm-trusted', action='store_true', help='Disable building of ARM trusted components (sel_ldr, etc).') # To setup bash completion for this command first install optcomplete @@ -941,9 +941,7 @@ def main(args): pass global options - options, args = parser.parse_args(args) - if args: - parser.error("Unexpected arguments: %s" % str(args)) + options = parser.parse_args(args) if options.nacl_tree_path: options.bionic = True diff --git a/native_client_sdk/src/build_tools/build_updater.py b/native_client_sdk/src/build_tools/build_updater.py index fc79fbb..66e0c9f 100755 --- a/native_client_sdk/src/build_tools/build_updater.py +++ b/native_client_sdk/src/build_tools/build_updater.py @@ -9,10 +9,10 @@ This script packages the files necessary to generate the SDK updater -- the tool users run to download new bundles, update existing bundles, etc. """ +import argparse import buildbot_common import build_version import glob -import optparse import os import sys @@ -174,13 +174,13 @@ def BuildUpdater(out_dir, revision_number=None): def main(args): - parser = optparse.OptionParser() - parser.add_option('-o', '--out', help='output directory', + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('-o', '--out', help='output directory', dest='out_dir', default=os.path.join(SRC_DIR, 'out')) - parser.add_option('-r', '--revision', help='revision number of this updater', - dest='revision', default=None) - parser.add_option('-v', '--verbose', help='verbose output') - options, args = parser.parse_args(args) + parser.add_argument('-r', '--revision', dest='revision', default=None, + help='revision number of this updater') + parser.add_argument('-v', '--verbose', help='verbose output') + options = parser.parse_args(args) buildbot_common.verbose = options.verbose diff --git a/native_client_sdk/src/build_tools/buildbot_run.py b/native_client_sdk/src/build_tools/buildbot_run.py index 61b740a..5971a58 100755 --- a/native_client_sdk/src/build_tools/buildbot_run.py +++ b/native_client_sdk/src/build_tools/buildbot_run.py @@ -12,9 +12,9 @@ while being able to separately control excactly what the bots run. """ +import argparse import buildbot_common import os -import optparse import subprocess import sys @@ -101,14 +101,14 @@ def main(args): # orphaned .pyc files generated by a previous run. os.environ['PYTHONDONTWRITEBYTECODE'] = '1' - parser = optparse.OptionParser(description=__doc__) - parser.add_option('--build-only', action='store_true', + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--build-only', action='store_true', help='Only build the SDK, don\'t build or run tests.') - parser.add_option('--build-properties', + parser.add_argument('--build-properties', help='JSON properties passed by buildbot. Currently ignored.') - parser.add_option('--factory-properties', + parser.add_argument('--factory-properties', help='JSON properties passed by buildbot. Currently ignored.') - options, args = parser.parse_args(args) + options = parser.parse_args(args) # Skip the testing phase if we are running on a build-only bots. if not options.build_only: diff --git a/native_client_sdk/src/build_tools/dsc2gyp.py b/native_client_sdk/src/build_tools/dsc2gyp.py index f0ecfa3..7032e94 100755 --- a/native_client_sdk/src/build_tools/dsc2gyp.py +++ b/native_client_sdk/src/build_tools/dsc2gyp.py @@ -2,10 +2,11 @@ # Copyright (c) 2012 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. + +import argparse import StringIO import sys import os -import optparse SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) sys.path.append(os.path.join(os.path.dirname(SCRIPT_DIR), 'tools')) @@ -359,19 +360,17 @@ def ProcessDSC(filename, outfile=None): def main(args): - parser = optparse.OptionParser() - parser.add_option('-o', help='Set output filename.', dest='output') - options, args = parser.parse_args(args) - if not args: - Error('No .dsc file specified.') + parser = argparse.ArgumentParser() + parser.add_argument('-o', help='Set output filename.', dest='output') + parser.add_argument('dsc', help='dsc to convert') + options = parser.parse_args(args) if options.output: outdir = os.path.dirname(options.output) if not os.path.exists(outdir): os.makedirs(outdir) - assert len(args) == 1 - ProcessDSC(args[0], options.output) + ProcessDSC(options.dsc, options.output) return 0 diff --git a/native_client_sdk/src/build_tools/dsc_info.py b/native_client_sdk/src/build_tools/dsc_info.py index ac08fae..947f52b 100755 --- a/native_client_sdk/src/build_tools/dsc_info.py +++ b/native_client_sdk/src/build_tools/dsc_info.py @@ -5,7 +5,7 @@ """Extracts information from a library.dsc file.""" -import optparse +import argparse import os import sys @@ -32,25 +32,23 @@ def GetSources(lib_dir, tree, target_name): return result -def DoMain(argv): - "Entry point for gyp's pymod_do_main command." - parser = optparse.OptionParser(usage='%prog: [OPTIONS] TARGET') +def DoMain(args): + """Entry point for gyp's pymod_do_main command.""" + parser = argparse.ArgumentParser(description=__doc__) # Give a clearer error message when this is used as a module. parser.prog = 'dsc_info' - parser.add_option('-s', '--sources', + parser.add_argument('-s', '--sources', help='Print a list of source files for the target', action='store_true', default=False) - parser.add_option('-l', '--libdir', + parser.add_argument('-l', '--libdir', help='Directory where the library.dsc file is located', metavar='DIR') - options, args = parser.parse_args(argv) - if len(args) != 1: - parser.error('Expecting exactly one argument.') - target = args[0] + parser.add_argument('target') + options = parser.parse_args(args) libdir = options.libdir or '' tree = parse_dsc.LoadProject(os.path.join(libdir, 'library.dsc')) if options.sources: - return '\n'.join(GetSources(libdir, tree, target)) + return '\n'.join(GetSources(libdir, tree, options.target)) parser.error('No action specified') diff --git a/native_client_sdk/src/build_tools/easy_template.py b/native_client_sdk/src/build_tools/easy_template.py index 999bdb1..d6b9045 100755 --- a/native_client_sdk/src/build_tools/easy_template.py +++ b/native_client_sdk/src/build_tools/easy_template.py @@ -3,9 +3,9 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import argparse import copy import cStringIO -import optparse import os import re import sys @@ -98,12 +98,11 @@ def RunTemplateString(src, template_dict, statement_re=None, expr_re=None): def main(args): - parser = optparse.OptionParser() - _, args = parser.parse_args(args) - if not args: - return + parser = argparse.ArgumentParser() + parser.add_argument('template') + options = parser.parse_args(args) - with open(args[0]) as f: + with open(options.template) as f: print TemplateToPython( f.read(), re.compile(STATEMENT_RE), re.compile(EXPR_RE)) diff --git a/native_client_sdk/src/build_tools/generate_notice.py b/native_client_sdk/src/build_tools/generate_notice.py index c7d81d2..ab873f7 100755 --- a/native_client_sdk/src/build_tools/generate_notice.py +++ b/native_client_sdk/src/build_tools/generate_notice.py @@ -6,7 +6,7 @@ """Build the NOTICE file distributed with the NaCl SDK from a set of given license files.""" -import optparse +import argparse import os import sys @@ -68,13 +68,14 @@ def Generate(output_filename, root, files): def main(args): - parser = optparse.OptionParser() - parser.add_option('-v', '--verbose', help='Verbose output.', + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('-v', '--verbose', help='Verbose output.', action='store_true') - parser.add_option('-o', '--output', help='Output file') - parser.add_option('--root', help='Root for all paths') + parser.add_argument('-o', '--output', help='Output file') + parser.add_argument('--root', help='Root for all paths') + parser.add_argument('files', nargs='*') - options, args = parser.parse_args(args) + options = parser.parse_args(args) Trace.verbose = options.verbose if not options.output: @@ -82,7 +83,7 @@ def main(args): if not options.root: parser.error('No root directory given. See --root.') - Generate(options.output, options.root, args) + Generate(options.output, options.root, options.files) Trace('Done.') return 0 diff --git a/native_client_sdk/src/build_tools/nacl-mono-archive.py b/native_client_sdk/src/build_tools/nacl-mono-archive.py index 35403b0..a9dd468 100755 --- a/native_client_sdk/src/build_tools/nacl-mono-archive.py +++ b/native_client_sdk/src/build_tools/nacl-mono-archive.py @@ -3,7 +3,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import optparse +import argparse import os import sys import tarfile @@ -12,28 +12,28 @@ import buildbot_common def main(args): - parser = optparse.OptionParser() - parser.add_option('--install-dir', + parser = argparse.ArgumentParser() + parser.add_argument('--install-dir', help='Install Directory', dest='install_dir', default='naclmono') - parser.add_option('--tar-path', + parser.add_argument('--tar-path', help='Tarfile path', dest='tar_path', default='naclmono_%pepperrev%.bz2') - parser.add_option('--upload-path', + parser.add_argument('--upload-path', help='Upload path (nativeclient-mirror/nacl/nacl_sdk/XXX)', dest='upload_path', default=None) - parser.add_option('--pepper-revision', + parser.add_argument('--pepper-revision', help='Pepper revision', dest='pepper_revision', default=None) - parser.add_option('--skip-upload', + parser.add_argument('--skip-upload', help='Skips upload step', action="store_true", dest='skip_upload') - (options, args) = parser.parse_args(args) + options = parser.parse_args(args) if not options.upload_path: buildbot_common.ErrorExit('--upload-path is required') diff --git a/native_client_sdk/src/build_tools/nacl-mono-builder.py b/native_client_sdk/src/build_tools/nacl-mono-builder.py index 0bb119d..1790f18 100755 --- a/native_client_sdk/src/build_tools/nacl-mono-builder.py +++ b/native_client_sdk/src/build_tools/nacl-mono-builder.py @@ -3,7 +3,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import optparse +import argparse import os import sys import tarfile @@ -17,25 +17,25 @@ MONO_DIR = os.path.join(MONO_BUILD_DIR, 'nacl-mono') def main(args): - parser = optparse.OptionParser() - parser.add_option('--arch', + parser = argparse.ArgumentParser() + parser.add_argument('--arch', help='Target architecture', dest='arch', default='x86-32') - parser.add_option('--sdk-revision', + parser.add_argument('--sdk-revision', help='SDK Revision' ' (default=buildbot revision)', dest='sdk_revision', default=None) - parser.add_option('--sdk-url', + parser.add_argument('--sdk-url', help='SDK Download URL', dest='sdk_url', default=None) - parser.add_option('--install-dir', + parser.add_argument('--install-dir', help='Install Directory', dest='install_dir', default='naclmono') - (options, args) = parser.parse_args(args) + options = parser.parse_args(args) assert sys.platform.find('linux') != -1 diff --git a/native_client_sdk/src/build_tools/parse_dsc.py b/native_client_sdk/src/build_tools/parse_dsc.py index 409eb40..5047469 100755 --- a/native_client_sdk/src/build_tools/parse_dsc.py +++ b/native_client_sdk/src/build_tools/parse_dsc.py @@ -3,9 +3,9 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import argparse import collections import fnmatch -import optparse import os import sys @@ -244,24 +244,18 @@ def PrintProjectTree(tree): print '\t' + val['NAME'] -def main(argv): - parser = optparse.OptionParser(usage='%prog [options] <dir>') - parser.add_option('-e', '--experimental', +def main(args): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('-e', '--experimental', help='build experimental examples and libraries', action='store_true') - parser.add_option('-t', '--toolchain', + parser.add_argument('-t', '--toolchain', help='Build using toolchain. Can be passed more than once.', action='append') + parser.add_argument('project_root', default='.') - options, args = parser.parse_args(argv) + options = parser.parse_args(args) filters = {} - load_from_dir = '.' - if len(args) > 1: - parser.error('Expected 0 or 1 args, got %d.' % len(args)) - - if args: - load_from_dir = args[0] - if options.toolchain: filters['TOOLS'] = options.toolchain @@ -269,7 +263,7 @@ def main(argv): filters['EXPERIMENTAL'] = False try: - tree = LoadProjectTree(load_from_dir, include=filters) + tree = LoadProjectTree(options.project_root, include=filters) except ValidationError as e: sys.stderr.write(str(e) + '\n') return 1 diff --git a/native_client_sdk/src/build_tools/test_projects.py b/native_client_sdk/src/build_tools/test_projects.py index a46ea0f..40a688c 100755 --- a/native_client_sdk/src/build_tools/test_projects.py +++ b/native_client_sdk/src/build_tools/test_projects.py @@ -3,7 +3,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import optparse +import argparse import os import subprocess import sys @@ -27,7 +27,7 @@ browser_path = find_chrome.FindChrome(SRC_DIR, ['Debug', 'Release']) # Fall back to using CHROME_PATH (same as in common.mk) if not browser_path: - browser_path = os.environ['CHROME_PATH'] + browser_path = os.environ.get('CHROME_PATH') pepper_ver = str(int(build_version.ChromeMajorVersion())) @@ -313,25 +313,26 @@ def GetProjectTree(include): def main(args): - parser = optparse.OptionParser() - parser.add_option('-c', '--config', + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('-c', '--config', help='Choose configuration to run (Debug or Release). Runs both ' 'by default', action='append') - parser.add_option('-x', '--experimental', + parser.add_argument('-x', '--experimental', help='Run experimental projects', action='store_true') - parser.add_option('-t', '--toolchain', + parser.add_argument('-t', '--toolchain', help='Run using toolchain. Can be passed more than once.', action='append', default=[]) - parser.add_option('-d', '--dest', + parser.add_argument('-d', '--dest', help='Select which destinations (project types) are valid.', action='append') - parser.add_option('-b', '--build', + parser.add_argument('-b', '--build', help='Build each project before testing.', action='store_true') - parser.add_option('--retry-times', + parser.add_argument('--retry-times', help='Number of types to retry on failure (Default: %default)', - type='int', default=1) + type=int, default=1) + parser.add_argument('projects', nargs='*') - options, args = parser.parse_args(args) + options = parser.parse_args(args) if not options.toolchain: options.toolchain = ['newlib', 'glibc', 'pnacl', 'host'] @@ -352,9 +353,9 @@ def main(args): if options.dest: include['DEST'] = options.dest print 'Filter by type: ' + str(options.dest) - if args: - include['NAME'] = args - print 'Filter by name: ' + str(args) + if options.projects: + include['NAME'] = options.projects + print 'Filter by name: ' + str(options.projects) if not options.config: options.config = ALL_CONFIGS diff --git a/native_client_sdk/src/build_tools/test_sdk.py b/native_client_sdk/src/build_tools/test_sdk.py index 0c00a09..7f1fe051 100755 --- a/native_client_sdk/src/build_tools/test_sdk.py +++ b/native_client_sdk/src/build_tools/test_sdk.py @@ -8,7 +8,7 @@ This script is normally run immediately after build_sdk.py. """ -import optparse +import argparse import os import subprocess import sys @@ -159,15 +159,15 @@ def StepRunBrowserTests(toolchains, experimental): def main(args): - usage = '%prog [<options>] [<phase...>]' - parser = optparse.OptionParser(description=__doc__, usage=usage) - parser.add_option('--experimental', help='build experimental tests', - action='store_true') - parser.add_option('--sanitizer', - help='Run sanitizer (asan/tsan/valgrind) tests', - action='store_true') - parser.add_option('--verbose', '-v', help='Verbose output', - action='store_true') + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--experimental', help='build experimental tests', + action='store_true') + parser.add_argument('--sanitizer', + help='Run sanitizer (asan/tsan/valgrind) tests', + action='store_true') + parser.add_argument('--verbose', '-v', help='Verbose output', + action='store_true') + parser.add_argument('phases', nargs="*") if 'NACL_SDK_ROOT' in os.environ: # We don't want the currently configured NACL_SDK_ROOT to have any effect @@ -183,7 +183,7 @@ def main(args): except ImportError: pass - options, args = parser.parse_args(args) + options = parser.parse_args(args) pepper_ver = str(int(build_version.ChromeMajorVersion())) pepperdir = os.path.join(OUT_DIR, 'pepper_' + pepper_ver) @@ -210,9 +210,9 @@ def main(args): ('sel_ldr_tests_valgrind', StepRunSelLdrTests, pepperdir, 'valgrind') ] - if args: + if options.phases: phase_names = [p[0] for p in phases] - for arg in args: + for arg in options.phases: if arg not in phase_names: msg = 'Invalid argument: %s\n' % arg msg += 'Possible arguments:\n' @@ -222,7 +222,7 @@ def main(args): for phase in phases: phase_name = phase[0] - if args and phase_name not in args: + if options.phases and phase_name not in options.phases: continue phase_func = phase[1] phase_args = phase[2:] diff --git a/native_client_sdk/src/build_tools/tests/build_artifacts_test.py b/native_client_sdk/src/build_tools/tests/build_artifacts_test.py index 2666fab..9c4f756 100755 --- a/native_client_sdk/src/build_tools/tests/build_artifacts_test.py +++ b/native_client_sdk/src/build_tools/tests/build_artifacts_test.py @@ -13,7 +13,7 @@ import unittest SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) BUILD_TOOLS_DIR = os.path.dirname(SCRIPT_DIR) CHROME_SRC = os.path.dirname(os.path.dirname(os.path.dirname(BUILD_TOOLS_DIR))) -MOCK_DIR = os.path.join(CHROME_SRC, "third_party", "pymock") +MOCK_DIR = os.path.join(CHROME_SRC, 'third_party', 'pymock') # For the mock library sys.path.append(MOCK_DIR) diff --git a/native_client_sdk/src/build_tools/tests/build_version_test.py b/native_client_sdk/src/build_tools/tests/build_version_test.py index f8f60a2..904d966 100755 --- a/native_client_sdk/src/build_tools/tests/build_version_test.py +++ b/native_client_sdk/src/build_tools/tests/build_version_test.py @@ -11,7 +11,7 @@ import unittest SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) BUILD_TOOLS_DIR = os.path.dirname(SCRIPT_DIR) CHROME_SRC = os.path.dirname(os.path.dirname(os.path.dirname(BUILD_TOOLS_DIR))) -MOCK_DIR = os.path.join(CHROME_SRC, "third_party", "pymock") +MOCK_DIR = os.path.join(CHROME_SRC, 'third_party', 'pymock') # For the mock library sys.path.append(MOCK_DIR) diff --git a/native_client_sdk/src/build_tools/tests/easy_template_test.py b/native_client_sdk/src/build_tools/tests/easy_template_test.py index 5601704..f26de77 100755 --- a/native_client_sdk/src/build_tools/tests/easy_template_test.py +++ b/native_client_sdk/src/build_tools/tests/easy_template_test.py @@ -10,10 +10,18 @@ import sys import unittest SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) +TOOLS_DIR = os.path.dirname(SCRIPT_DIR) +CHROME_SRC = os.path.dirname(os.path.dirname(os.path.dirname(TOOLS_DIR))) +MOCK_DIR = os.path.join(CHROME_SRC, 'third_party', 'pymock') BUILD_TOOLS_DIR = os.path.dirname(SCRIPT_DIR) sys.path.append(BUILD_TOOLS_DIR) +sys.path.append(MOCK_DIR) + import easy_template +import mock + +SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) class EasyTemplateTestCase(unittest.TestCase): def _RunTest(self, template, expected, template_dict): @@ -116,6 +124,12 @@ struct Foo { self._RunTest('inside {{8 % 3}}', 'inside 2', {}) self._RunTest('Everywhere % {{8 % 3}} %', 'Everywhere % 2 %', {}) + @mock.patch('easy_template.TemplateToPython') + @mock.patch('sys.stdout', mock.Mock()) + def testMainArgParsing(self, mock_template_to_python): + easy_template.main([__file__]) + mock_template_to_python.assert_called() + if __name__ == '__main__': unittest.main() diff --git a/native_client_sdk/src/build_tools/tests/test_projects_test.py b/native_client_sdk/src/build_tools/tests/test_projects_test.py new file mode 100755 index 0000000..ca615a8 --- /dev/null +++ b/native_client_sdk/src/build_tools/tests/test_projects_test.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python +# Copyright (c) 2013 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. + +import os +import sys +import unittest + +SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) +BUILD_TOOLS_DIR = os.path.dirname(SCRIPT_DIR) +CHROME_SRC = os.path.dirname(os.path.dirname(os.path.dirname(BUILD_TOOLS_DIR))) +MOCK_DIR = os.path.join(CHROME_SRC, 'third_party', 'pymock') + +sys.path.append(BUILD_TOOLS_DIR) +sys.path.append(MOCK_DIR) + +import mock +import test_projects + +class TestMain(unittest.TestCase): + """Tests for main() entry point of the script.""" + + def testInvalidArgs(self): + with mock.patch('sys.stderr'): + with self.assertRaises(SystemExit): + test_projects.main(['--foo']) + + +if __name__ == '__main__': + unittest.main() diff --git a/native_client_sdk/src/build_tools/tests/verify_ppapi_test.py b/native_client_sdk/src/build_tools/tests/verify_ppapi_test.py index e63d10a..efdd0a6 100755 --- a/native_client_sdk/src/build_tools/tests/verify_ppapi_test.py +++ b/native_client_sdk/src/build_tools/tests/verify_ppapi_test.py @@ -10,7 +10,7 @@ import unittest SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) BUILD_TOOLS_DIR = os.path.dirname(SCRIPT_DIR) CHROME_SRC = os.path.dirname(os.path.dirname(os.path.dirname(BUILD_TOOLS_DIR))) -MOCK_DIR = os.path.join(CHROME_SRC, "third_party", "pymock") +MOCK_DIR = os.path.join(CHROME_SRC, 'third_party', 'pymock') # For the mock library sys.path.append(MOCK_DIR) diff --git a/native_client_sdk/src/build_tools/update_nacl_manifest.py b/native_client_sdk/src/build_tools/update_nacl_manifest.py index c93198b..d60f098 100755 --- a/native_client_sdk/src/build_tools/update_nacl_manifest.py +++ b/native_client_sdk/src/build_tools/update_nacl_manifest.py @@ -10,6 +10,7 @@ in manifest. # pylint is convinced the email module is missing attributes # pylint: disable=E1101 +import argparse import buildbot_common import csv import cStringIO @@ -18,7 +19,6 @@ import email import logging import logging.handlers import manifest_util -import optparse import os import posixpath import re @@ -879,24 +879,25 @@ class CapturedFile(object): def main(args): - parser = optparse.OptionParser() - parser.add_option('--gsutil', help='path to gsutil.') - parser.add_option('-d', '--debug', help='run in debug mode.', + parser = argparse.ArgumentParser() + parser.add_argument('--gsutil', help='path to gsutil.') + parser.add_argument('-d', '--debug', help='run in debug mode.', action='store_true') - parser.add_option('--mailfrom', help='email address of sender.') - parser.add_option('--mailto', help='send error mails to...', action='append') - parser.add_option('-n', '--dryrun', help="don't upload the manifest.", + parser.add_argument('--mailfrom', help='email address of sender.') + parser.add_argument('--mailto', help='send error mails to...', + action='append') + parser.add_argument('-n', '--dryrun', help="don't upload the manifest.", action='store_true') - parser.add_option('-v', '--verbose', help='print more diagnotic messages. ' + parser.add_argument('-v', '--verbose', help='print more diagnotic messages. ' 'Use more than once for more info.', action='count') - parser.add_option('--log-file', metavar='FILE', help='log to FILE') - parser.add_option('--upload-log', help='Upload log alongside the manifest.', - action='store_true') - parser.add_option('--bundle-version', + parser.add_argument('--log-file', metavar='FILE', help='log to FILE') + parser.add_argument('--upload-log', help='Upload log alongside the manifest.', + action='store_true') + parser.add_argument('--bundle-version', help='Manually set a bundle version. This can be passed more than once. ' 'format: --bundle-version pepper_24=24.0.1312.25', action='append') - options, args = parser.parse_args(args) + options = parser.parse_args(args) if (options.mailfrom is None) != (not options.mailto): options.mailfrom = None diff --git a/native_client_sdk/src/build_tools/update_sdktools.py b/native_client_sdk/src/build_tools/update_sdktools.py index 561093f..e9e72d1 100755 --- a/native_client_sdk/src/build_tools/update_sdktools.py +++ b/native_client_sdk/src/build_tools/update_sdktools.py @@ -16,10 +16,10 @@ update_nacl_manifest.py is customarily run by a cron job, and does not check in any changes. Instead it modifies the manifest file in cloud storage.""" +import argparse import collections import difflib import json -import optparse import re import sys import urllib2 @@ -107,12 +107,10 @@ def UpdateManifestFileToRevision(filename, revision): def main(args): - parser = optparse.OptionParser(description=__doc__) - parser.add_option('-r', '--revision', + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('-r', '--revision', help='set revision manually, rather than using the latest version') - options, args = parser.parse_args(args) - if len(args) != 0: - parser.error('Unexpected args: %s' % ', '.join(args)) + options = parser.parse_args(args) # TODO(binji): http://crbug.com/169047. Rename RealDelegate to something else. delegate = RealDelegate() diff --git a/native_client_sdk/src/build_tools/verify_filelist.py b/native_client_sdk/src/build_tools/verify_filelist.py index 33a9a4f..b49d188 100755 --- a/native_client_sdk/src/build_tools/verify_filelist.py +++ b/native_client_sdk/src/build_tools/verify_filelist.py @@ -3,7 +3,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import optparse +import argparse import os import re import sys @@ -182,28 +182,24 @@ def SortFile(rule_path): def main(args): - parser = optparse.OptionParser(usage='%prog <rule file> <directory>') - parser.add_option('-p', '--platform', + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('-p', '--platform', help='Test with this platform, instead of the system\'s platform') - parser.add_option('-s', '--sort', action='store_true', + parser.add_argument('-s', '--sort', action='store_true', help='Sort the file list in place, rather than verifying the contents.') - options, args = parser.parse_args(args) - - if not args: - args = [os.path.join(SCRIPT_DIR, 'sdk_files.list')] + parser.add_argument('rule_file', nargs='?', + default=os.path.join(SCRIPT_DIR, 'sdk_files.list')) + parser.add_argument('directory_path', nargs='?') + options = parser.parse_args(args) if options.sort: - if not args: - parser.error('Expected rule file.') - SortFile(args[0]) + SortFile(options.rule_file) return 0 - if len(args) < 2: + if not options.directory_path: version = build_version.ChromeMajorVersion() - args.append(os.path.join(OUT_DIR, 'pepper_%s' % version)) + options.directory_path = os.path.join(OUT_DIR, 'pepper_%s' % version) - rule_path = args[0] - directory_path = args[1] if options.platform: if options.platform not in VALID_PLATFORMS: parser.error('Unknown platform: %s' % options.platform) @@ -212,12 +208,12 @@ def main(args): platform = getos.GetPlatform() try: - return Verify(rule_path, directory_path, platform) + return Verify(options.rule_file, options.directory_path, platform) except ParseException, e: - print >> sys.stderr, 'Error parsing rules:\n', e + sys.stderr.write('Error parsing rules:\n%s\n' % e) return 1 except VerifyException, e: - print >> sys.stderr, 'Error verifying file list:\n', e + sys.stderr.write('Error verifying file list:\n%s\n' % e) return 1 return 0 diff --git a/native_client_sdk/src/build_tools/verify_ppapi.py b/native_client_sdk/src/build_tools/verify_ppapi.py index 54cb8c0..f1c36c3 100755 --- a/native_client_sdk/src/build_tools/verify_ppapi.py +++ b/native_client_sdk/src/build_tools/verify_ppapi.py @@ -11,7 +11,7 @@ For example, if a user adds "ppapi/c/foo.h", we check that the interface has been added to "native_client_sdk/src/libraries/ppapi/library.dsc". """ -import optparse +import argparse import os import sys @@ -167,15 +167,12 @@ def VerifyOrPrintError(dsc_filename, dsc_sources_and_headers, changed_filenames, def main(args): - usage = '%prog <file>...' - description = __doc__ - parser = optparse.OptionParser(usage=usage, description=description) - args = parser.parse_args(args)[1] - if not args: - parser.error('Expected a PPAPI header or source file.') + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('sources', nargs='+') + options = parser.parse_args(args) retval = 0 - lib_files = PartitionFiles(args) + lib_files = PartitionFiles(options.sources) directory_list = GetDirectoryList(PPAPI_DIR, relative_to=SRC_DIR) for lib_name, filenames in lib_files.iteritems(): if not filenames: diff --git a/native_client_sdk/src/doc/doxygen/doxy_cleanup.py b/native_client_sdk/src/doc/doxygen/doxy_cleanup.py index d90f214..05c02c2 100755 --- a/native_client_sdk/src/doc/doxygen/doxy_cleanup.py +++ b/native_client_sdk/src/doc/doxygen/doxy_cleanup.py @@ -7,12 +7,13 @@ that they are suitable for publication on a Google documentation site. ''' +import argparse import glob -import optparse import os import re import shutil import sys + try: from BeautifulSoup import BeautifulSoup, Tag except (ImportError, NotImplementedError): @@ -147,24 +148,23 @@ class HTMLFixer(object): return html -def main(argv): +def main(args): """Main entry for the doxy_cleanup utility doxy_cleanup cleans up the html files generated by doxygen. """ - parser = optparse.OptionParser(usage='Usage: %prog [options] directory') - parser.add_option('-v', '--verbose', help='verbose output.', - action='store_true') - options, files = parser.parse_args(argv) + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('-v', '--verbose', help='verbose output.', + action='store_true') + parser.add_argument('directory') - if len(files) != 1: - parser.error('Expected one directory') + options = parser.parse_args(args) if options.verbose: Trace.verbose = True - root_dir = files[0] + root_dir = options.directory html_dir = os.path.join(root_dir, 'html') # Doxygen puts all files in an 'html' directory. diff --git a/native_client_sdk/src/doc/doxygen/generate_docs.py b/native_client_sdk/src/doc/doxygen/generate_docs.py index 0e6c545..13316ef 100755 --- a/native_client_sdk/src/doc/doxygen/generate_docs.py +++ b/native_client_sdk/src/doc/doxygen/generate_docs.py @@ -3,9 +3,12 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +"""Script to regenerate API docs using doxygen. +""" + +import argparse import collections import json -import optparse import os import shutil import subprocess @@ -227,7 +230,7 @@ def RunRstIndex(kind, channel, pepper_version, out_dirname, out_rst_filename): '--channel', channel, '--version', pepper_version, out_dirname, - '-o', out_rst_filename] + out_rst_filename] Trace('Running rst_index:\n %s' % ' '.join(cmd)) subprocess.check_call(cmd) @@ -288,20 +291,18 @@ def GenerateDocs(root_dirname, channel, pepper_version, branch): def main(argv): - parser = optparse.OptionParser(usage='Usage: %prog [options] <out_directory>') - parser.add_option('-v', '--verbose', - help='Verbose output', action='store_true') - options, dirs = parser.parse_args(argv) + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('-v', '--verbose', + help='Verbose output', action='store_true') + parser.add_argument('out_directory') + options = parser.parse_args(argv) if options.verbose: Trace.verbose = True - if len(dirs) != 1: - parser.error('Expected an output directory') - channel_info = GetChannelInfo() for channel, info in channel_info.iteritems(): - GenerateDocs(dirs[0], channel, info.version, info.branch) + GenerateDocs(options.out_directory, channel, info.version, info.branch) return 0 diff --git a/native_client_sdk/src/doc/doxygen/rst_index.py b/native_client_sdk/src/doc/doxygen/rst_index.py index 9706f97..35e4f02 100755 --- a/native_client_sdk/src/doc/doxygen/rst_index.py +++ b/native_client_sdk/src/doc/doxygen/rst_index.py @@ -3,9 +3,12 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +"""Script to generate rst index file doxygen generated html files. +""" + +import argparse import cStringIO import fnmatch -import optparse import os import re import sys @@ -227,24 +230,18 @@ def GenerateCppIndex(root_dir, channel, version, out_filename): def main(argv): - usage = 'Usage: %prog [options] <--root|--c|--cpp> directory' - parser = optparse.OptionParser(usage=usage) - parser.add_option('--channel', help='pepper channel (stable, beta, dev)') - parser.add_option('--version', help='pepper version (e.g. 32, 33, 34, etc.)') - parser.add_option('--root', help='Generate root API index', - action='store_true', default=False) - parser.add_option('--c', help='Generate C API index', action='store_true', - default=False) - parser.add_option('--cpp', help='Generate C++ API index', action='store_true', - default=False) - parser.add_option('-o', '--output', help='output file.') - options, files = parser.parse_args(argv) - - if len(files) != 1: - parser.error('Expected one directory') - - if not options.output: - parser.error('Need output file') + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--channel', help='pepper channel (stable, beta, dev)') + parser.add_argument('--version', help='pepper version (e.g. 32, 33, etc.)') + parser.add_argument('--root', help='Generate root API index', + action='store_true', default=False) + parser.add_argument('--c', help='Generate C API index', action='store_true', + default=False) + parser.add_argument('--cpp', help='Generate C++ API index', + action='store_true', default=False) + parser.add_argument('directory', help='input directory') + parser.add_argument('output_file', help='output file') + options = parser.parse_args(argv) if options.channel not in VALID_CHANNELS: parser.error('Expected channel to be one of %s' % ', '.join(VALID_CHANNELS)) @@ -252,14 +249,16 @@ def main(argv): if sum((options.c, options.cpp, options.root)) != 1: parser.error('Exactly one of --c/--cpp/--root flags is required.') - root_dir = files[0] if options.c: - GenerateCIndex(root_dir, options.channel, options.version, options.output) + GenerateCIndex(options.directory, options.channel, options.version, + options.output_file) elif options.cpp: - GenerateCppIndex(root_dir, options.channel, options.version, options.output) + GenerateCppIndex(options.directory, options.channel, options.version, + options.output_file) elif options.root: - GenerateRootIndex(options.channel, options.version, options.output) + GenerateRootIndex(options.channel, options.version, + options.output_file) else: assert(False) return 0 diff --git a/native_client_sdk/src/test_all.py b/native_client_sdk/src/test_all.py index a929f43..5062c40 100755 --- a/native_client_sdk/src/test_all.py +++ b/native_client_sdk/src/test_all.py @@ -55,6 +55,7 @@ TEST_MODULES = [ 'quote_test', 'sdktools_config_test', 'sel_ldr_test', + 'test_projects_test', 'update_nacl_manifest_test', 'verify_filelist_test', 'verify_ppapi_test', diff --git a/native_client_sdk/src/tools/create_html.py b/native_client_sdk/src/tools/create_html.py index 64f6d89..8647b46 100755 --- a/native_client_sdk/src/tools/create_html.py +++ b/native_client_sdk/src/tools/create_html.py @@ -15,7 +15,7 @@ the nmf files. If it is given an nmf it will only create the html file. """ -import optparse +import argparse import os import sys import subprocess @@ -160,18 +160,18 @@ def CreateHTML(filenames, options): def main(argv): - usage = 'Usage: %prog [options] <.nexe/.pexe or .nmf>' - epilog = 'Example: create_html.py -o index.html my_nexe.nexe' - parser = optparse.OptionParser(usage, description=__doc__, epilog=epilog) - parser.add_option('-v', '--verbose', action='store_true', - help='Verbose output') - parser.add_option('-d', '--debug-libs', action='store_true', - help='When calling create_nmf request debug libaries') - parser.add_option('-o', '--output', dest='output', - help='Name of html file to write (default is ' - 'input name with .html extension)', - metavar='FILE') - + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('-v', '--verbose', action='store_true', + help='Verbose output') + parser.add_argument('-d', '--debug-libs', action='store_true', + help='When calling create_nmf request debug libaries') + parser.add_argument('-o', '--output', dest='output', + help='Name of html file to write (default is ' + 'input name with .html extension)', + metavar='FILE') + parser.add_argument('exe', metavar='EXE_OR_NMF', nargs='+', + help='Executable (.nexe/.pexe) or nmf file to generate ' + 'html for.') # To enable bash completion for this command first install optcomplete # and then add this line to your .bashrc: # complete -F _optcomplete create_html.py @@ -181,15 +181,12 @@ def main(argv): except ImportError: pass - options, args = parser.parse_args(argv) - - if not args: - parser.error('no input file specified') + options = parser.parse_args(argv) if options.verbose: Log.enabled = True - CreateHTML(args, options) + CreateHTML(options.exe, options) return 0 diff --git a/native_client_sdk/src/tools/create_nmf.py b/native_client_sdk/src/tools/create_nmf.py index bf87979..de72408 100755 --- a/native_client_sdk/src/tools/create_nmf.py +++ b/native_client_sdk/src/tools/create_nmf.py @@ -9,9 +9,9 @@ As well as creating the nmf file this tool can also find and stage any shared libraries dependencies that the executables might have. """ +import argparse import errno import json -import optparse import os import posixpath import shutil @@ -158,7 +158,7 @@ class ArchFile(object): self.path = path self.url = url self.arch = arch - if not arch: + if arch is None: self.arch = ParseElfHeader(path)[0] def __repr__(self): @@ -402,7 +402,7 @@ class NmfUtils(object): def GetManifest(self): """Returns a JSON-formatted dict containing the NaCl dependencies""" - if not self.manifest: + if self.manifest is None: if self.pnacl: self._GeneratePNaClManifest() else: @@ -541,60 +541,60 @@ def GetDefaultLibPath(config): return libpath -def main(argv): - parser = optparse.OptionParser( - usage='Usage: %prog [options] nexe [extra_libs...]', description=__doc__) - parser.add_option('-o', '--output', dest='output', - help='Write manifest file to FILE (default is stdout)', - metavar='FILE') - parser.add_option('-D', '--objdump', dest='objdump', - help='Override the default "objdump" tool used to find ' - 'shared object dependencies', - metavar='TOOL') - parser.add_option('--no-default-libpath', action='store_true', - help="Don't include the SDK default library paths") - parser.add_option('--debug-libs', action='store_true', - help='Use debug library paths when constructing default ' - 'library path.') - parser.add_option('-L', '--library-path', dest='lib_path', - action='append', default=[], - help='Add DIRECTORY to library search path', - metavar='DIRECTORY') - parser.add_option('-P', '--path-prefix', dest='path_prefix', default='', - help='Deprecated. An alias for --lib-prefix.', - metavar='DIRECTORY') - parser.add_option('-p', '--lib-prefix', dest='lib_prefix', default='', - help='A path to prepend to shared libraries in the .nmf', - metavar='DIRECTORY') - parser.add_option('-N', '--nexe-prefix', dest='nexe_prefix', default='', - help='A path to prepend to nexes in the .nmf', - metavar='DIRECTORY') - parser.add_option('-s', '--stage-dependencies', dest='stage_dependencies', - help='Destination directory for staging libraries', - metavar='DIRECTORY') - parser.add_option('--no-arch-prefix', action='store_true', - help='Don\'t put shared libraries in the lib32/lib64 ' - 'directories. Instead, they will be put in the same ' - 'directory as the .nexe that matches its architecture.') - parser.add_option('-t', '--toolchain', help='Legacy option, do not use') - parser.add_option('-n', '--name', dest='name', - help='Rename FOO as BAR', - action='append', default=[], metavar='FOO,BAR') - parser.add_option('-x', '--extra-files', - help=('Add extra key:file tuple to the "files"' + - ' section of the .nmf'), - action='append', default=[], metavar='FILE') - parser.add_option('-O', '--pnacl-optlevel', - help='Set the optimization level to N in PNaCl manifests', - metavar='N') - parser.add_option('--pnacl-debug-optlevel', - help='Set the optimization level to N for debugging ' - 'sections in PNaCl manifests', - metavar='N') - parser.add_option('-v', '--verbose', - help='Verbose output', action='store_true') - parser.add_option('-d', '--debug-mode', - help='Debug mode', action='store_true') +def main(args): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('-o', '--output', dest='output', + help='Write manifest file to FILE (default is stdout)', + metavar='FILE') + parser.add_argument('-D', '--objdump', dest='objdump', + help='Override the default "objdump" tool used to find ' + 'shared object dependencies', + metavar='TOOL') + parser.add_argument('--no-default-libpath', action='store_true', + help="Don't include the SDK default library paths") + parser.add_argument('--debug-libs', action='store_true', + help='Use debug library paths when constructing default ' + 'library path.') + parser.add_argument('-L', '--library-path', dest='lib_path', + action='append', default=[], + help='Add DIRECTORY to library search path', + metavar='DIRECTORY') + parser.add_argument('-P', '--path-prefix', dest='path_prefix', default='', + help='Deprecated. An alias for --lib-prefix.', + metavar='DIRECTORY') + parser.add_argument('-p', '--lib-prefix', dest='lib_prefix', default='', + help='A path to prepend to shared libraries in the .nmf', + metavar='DIRECTORY') + parser.add_argument('-N', '--nexe-prefix', dest='nexe_prefix', default='', + help='A path to prepend to nexes in the .nmf', + metavar='DIRECTORY') + parser.add_argument('-s', '--stage-dependencies', dest='stage_dependencies', + help='Destination directory for staging libraries', + metavar='DIRECTORY') + parser.add_argument('--no-arch-prefix', action='store_true', + help='Don\'t put shared libraries in the lib32/lib64 ' + 'directories. Instead, they will be put in the same ' + 'directory as the .nexe that matches its architecture.') + parser.add_argument('-t', '--toolchain', help='Legacy option, do not use') + parser.add_argument('-n', '--name', dest='name', + help='Rename FOO as BAR', + action='append', default=[], metavar='FOO,BAR') + parser.add_argument('-x', '--extra-files', + help=('Add extra key:file tuple to the "files"' + + ' section of the .nmf'), + action='append', default=[], metavar='FILE') + parser.add_argument('-O', '--pnacl-optlevel', + help='Set the optimization level to N in PNaCl manifests', + metavar='N') + parser.add_argument('--pnacl-debug-optlevel', + help='Set the optimization level to N for debugging ' + 'sections in PNaCl manifests', + metavar='N') + parser.add_argument('-v', '--verbose', + help='Verbose output', action='store_true') + parser.add_argument('-d', '--debug-mode', + help='Debug mode', action='store_true') + parser.add_argument('executables', metavar='EXECUTABLE', nargs='+') # To enable bash completion for this command first install optcomplete # and then add this line to your .bashrc: @@ -605,7 +605,7 @@ def main(argv): except ImportError: pass - options, args = parser.parse_args(argv) + options = parser.parse_args(args) if options.verbose: Trace.verbose = True if options.debug_mode: @@ -614,9 +614,6 @@ def main(argv): if options.toolchain is not None: sys.stderr.write('warning: option -t/--toolchain is deprecated.\n') - if len(args) < 1: - parser.error('No nexe files specified. See --help for more info') - canonicalized = ParseExtraFiles(options.extra_files, sys.stderr) if canonicalized is None: parser.error('Bad --extra-files (-x) argument syntax') @@ -661,7 +658,7 @@ def main(argv): nmf_root = os.path.dirname(options.output) nmf = NmfUtils(objdump=options.objdump, - main_files=args, + main_files=options.executables, lib_path=options.lib_path, extra_files=canonicalized, lib_prefix=options.lib_prefix, diff --git a/native_client_sdk/src/tools/decode_dump.py b/native_client_sdk/src/tools/decode_dump.py index b16a8e2..60bf702 100755 --- a/native_client_sdk/src/tools/decode_dump.py +++ b/native_client_sdk/src/tools/decode_dump.py @@ -8,8 +8,8 @@ Currently this produces a simple stack trace. """ +import argparse import json -import optparse import os import posixpath import subprocess @@ -176,30 +176,27 @@ class CoreDecoder(object): def main(args): - parser = optparse.OptionParser( - usage='USAGE: %prog [options] <core.json>') - parser.add_option('-m', '--main-nexe', dest='main_nexe', - help='nexe to resolve NaClMain references from') - parser.add_option('-n', '--nmf', dest='nmf_filename', default='-', - help='nmf to resolve references from') - parser.add_option('-a', '--addr2line', dest='addr2line', - help='path to appropriate addr2line') - parser.add_option('-L', '--library-path', dest='library_paths', - action='append', default=[], - help='path to search for shared libraries') - parser.add_option('-p', '--platform', dest='platform', - help='platform in a style match nmf files') - options, args = parser.parse_args(args) - if len(args) != 1: - parser.print_help() - sys.exit(1) + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('-m', '--main-nexe', + help='nexe to resolve NaClMain references from') + parser.add_argument('-n', '--nmf', default='-', + help='nmf to resolve references from') + parser.add_argument('-a', '--addr2line', + help='path to appropriate addr2line') + parser.add_argument('-L', '--library-path', dest='library_paths', + action='append', default=[], + help='path to search for shared libraries') + parser.add_argument('-p', '--platform', + help='platform in a style match nmf files') + parser.add_argument('core_json') + options = parser.parse_args(args) decoder = CoreDecoder( main_nexe=options.main_nexe, - nmf_filename=options.nmf_filename, - addr2line=options.add2line, + nmf_filename=options.nmf, + addr2line=options.addr2line, library_paths=options.library_paths, platform=options.platform) - info = decoder.LoadAndDecode(args[0]) + info = decoder.LoadAndDecode(options.core_json) trace = decoder.StackTrace(info) decoder.PrintTrace(trace, sys.stdout) return 0 diff --git a/native_client_sdk/src/tools/fix_deps.py b/native_client_sdk/src/tools/fix_deps.py index 31e7627..f5a9cc8 100755 --- a/native_client_sdk/src/tools/fix_deps.py +++ b/native_client_sdk/src/tools/fix_deps.py @@ -12,8 +12,8 @@ the build to be broken. See http://mad-scientist.net/make/autodep.html for more details of the problem. """ +import argparse import os -import optparse import sys TAG_LINE = '# Updated by fix_deps.py\n' @@ -82,24 +82,20 @@ def FixupDepFile(filename, output_filename=None): def main(argv): - usage = "usage: %prog [options] <dep_file>" - parser = optparse.OptionParser(usage=usage, description=__doc__) - parser.add_option('-o', '--output', help='Output filename (defaults to ' + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('-o', '--output', help='Output filename (defaults to ' 'input name with .deps extension') - parser.add_option('-c', '--clean', action='store_true', + parser.add_argument('-c', '--clean', action='store_true', help='Remove input file after writing output') - options, args = parser.parse_args(argv) - if not args: - raise parser.error('No input file specified') - if len(args) > 1: - raise parser.error('Only one argument supported') - input_filename = args[0] + parser.add_argument('dep_file') + options = parser.parse_args(argv) output_filename = options.output if not output_filename: - output_filename = os.path.splitext(input_filename)[0] + '.deps' - FixupDepFile(input_filename, output_filename) - if options.clean and input_filename != output_filename: - os.remove(input_filename) + output_filename = os.path.splitext(options.dep_file)[0] + '.deps' + FixupDepFile(options.dep_file, output_filename) + if options.clean and options.dep_file != output_filename: + os.remove(options.dep_file) + return 0 diff --git a/native_client_sdk/src/tools/fix_manifest.py b/native_client_sdk/src/tools/fix_manifest.py index 4d4d194..28729b9 100755 --- a/native_client_sdk/src/tools/fix_manifest.py +++ b/native_client_sdk/src/tools/fix_manifest.py @@ -34,9 +34,9 @@ Becomes ... """ +import argparse import collections import json -import optparse import os import sys @@ -57,28 +57,23 @@ def Trace(msg): Trace.verbose = False -def main(argv): - parser = optparse.OptionParser( - usage='Usage: %prog [options] manifest.json', description=__doc__) - parser.add_option('-p', '--prefix', - help='Prefix to set for all sub_package_paths in the ' - 'manifest. If none is specified, the prefix will be ' - 'removed; i.e. the start of the path will be ' - '"_platform_specific/..."') - parser.add_option('-v', '--verbose', - help='Verbose output', action='store_true') +def main(args): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('-p', '--prefix', + help='Prefix to set for all sub_package_paths in the ' + 'manifest. If none is specified, the prefix will be ' + 'removed; i.e. the start of the path will be ' + '"_platform_specific/..."') + parser.add_argument('-v', '--verbose', + help='Verbose output', action='store_true') + parser.add_argument('manifest_json') - options, args = parser.parse_args(argv) + options = parser.parse_args(args) if options.verbose: Trace.verbose = True - if not args: - parser.error('Expected manifest file.') - - manifest = args[0] - - Trace('Reading %s' % manifest) - with open(manifest) as f: + Trace('Reading %s' % options.manifest_json) + with open(options.manifest_json) as f: # Keep the dictionary order. This is only supported on Python 2.7+ if sys.version_info >= (2, 7, 0): data = json.load(f, object_pairs_hook=collections.OrderedDict) @@ -86,7 +81,7 @@ def main(argv): data = json.load(f) if 'platforms' not in data: - raise Error('%s does not have "platforms" key.' % manifest) + raise Error('%s does not have "platforms" key.' % options.manifest_json) platforms = data['platforms'] if type(platforms) is not list: @@ -114,7 +109,7 @@ def main(argv): Trace(' %s: "%s" -> "%s"' % (nacl_arch, sub_package_path, new_path)) - with open(manifest, 'w') as f: + with open(options.manifest_json, 'w') as f: json.dump(data, f, indent=2) return 0 diff --git a/native_client_sdk/src/tools/genhttpfs.py b/native_client_sdk/src/tools/genhttpfs.py index 4e9aa92..8cd7e50 100755 --- a/native_client_sdk/src/tools/genhttpfs.py +++ b/native_client_sdk/src/tools/genhttpfs.py @@ -11,8 +11,8 @@ For each file, the mode bits, size and path relative to the CWD are written to the output file which is stdout by default. """ +import argparse import glob -import optparse import os import sys import urllib @@ -21,19 +21,19 @@ class Error(Exception): pass -def main(argv): - parser = optparse.OptionParser(description=__doc__, - usage='Usage: %prog [options] <filename>...') - parser.add_option('-C', '--srcdir', - help='Change directory.', dest='srcdir', default=None) - parser.add_option('-o', '--output', - help='Output file name.', dest='output', default=None) - parser.add_option('-v', '--verbose', - help='Verbose output.', dest='verbose', - action='store_true') - parser.add_option('-r', '--recursive', - help='Recursive search.', action='store_true') - options, args = parser.parse_args(argv) +def main(args): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('-C', '--srcdir', + help='Change directory.', dest='srcdir', default=None) + parser.add_argument('-o', '--output', + help='Output file name.', dest='output', default=None) + parser.add_argument('-v', '--verbose', + help='Verbose output.', dest='verbose', + action='store_true') + parser.add_argument('-r', '--recursive', + help='Recursive search.', action='store_true') + parser.add_argument('paths', nargs='+') + options = parser.parse_args(args) if options.output: outfile = open(options.output, 'w') @@ -43,12 +43,9 @@ def main(argv): if options.srcdir: os.chdir(options.srcdir) - if not args: - parser.error("One or more pathnames must be specified. See --help.") - # Generate a set of unique file names bases on the input globs fileset = set() - for fileglob in args: + for fileglob in options.paths: filelist = glob.glob(fileglob) if not filelist: raise Error('Could not find match for "%s".\n' % fileglob) diff --git a/native_client_sdk/src/tools/getos.py b/native_client_sdk/src/tools/getos.py index 91f0ea6..c5fe5c2 100755 --- a/native_client_sdk/src/tools/getos.py +++ b/native_client_sdk/src/tools/getos.py @@ -10,7 +10,7 @@ the location of Chrome. This is used, for example, to determine the correct Toolchain to invoke. """ -import optparse +import argparse import os import re import subprocess @@ -216,36 +216,32 @@ def CheckVersion(required_version): def main(args): - parser = optparse.OptionParser() - parser.add_option('--arch', action='store_true', + parser = argparse.ArgumentParser() + parser.add_argument('--arch', action='store_true', help='Print architecture of current machine (x86_32, x86_64 or arm).') - parser.add_option('--chrome', action='store_true', + parser.add_argument('--chrome', action='store_true', help='Print the path chrome (by first looking in $CHROME_PATH and ' 'then $PATH).') - parser.add_option('--nacl-arch', action='store_true', + parser.add_argument('--nacl-arch', action='store_true', help='Print architecture used by NaCl on the current machine.') - parser.add_option('--sdk-version', action='store_true', + parser.add_argument('--sdk-version', action='store_true', help='Print major version of the NaCl SDK.') - parser.add_option('--sdk-revision', action='store_true', + parser.add_argument('--sdk-revision', action='store_true', help='Print revision number of the NaCl SDK.') - parser.add_option('--sdk-commit-position', action='store_true', + parser.add_argument('--sdk-commit-position', action='store_true', help='Print commit position of the NaCl SDK.') - parser.add_option('--check-version', + parser.add_argument('--check-version', metavar='MAJOR.POSITION', help='Check that the SDK version is at least as great as the ' 'version passed in. MAJOR is the major version number and POSITION ' 'is the Cr-Commit-Position number.') - options, _ = parser.parse_args(args) - - platform = GetPlatform() - if len(args) > 1: parser.error('Only one option can be specified at a time.') - if not args: - print platform - return 0 + options = parser.parse_args(args) + + platform = GetPlatform() if options.arch: out = GetSystemArch(platform) @@ -263,6 +259,8 @@ def main(args): required_version = ParseVersion(options.check_version) CheckVersion(required_version) out = None + else: + out = platform if out: print out diff --git a/native_client_sdk/src/tools/httpd.py b/native_client_sdk/src/tools/httpd.py index ea8d0fb..059f28b 100755 --- a/native_client_sdk/src/tools/httpd.py +++ b/native_client_sdk/src/tools/httpd.py @@ -3,10 +3,10 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import argparse import BaseHTTPServer import logging import multiprocessing -import optparse import os import SimpleHTTPServer # pylint: disable=W0611 import socket @@ -185,13 +185,13 @@ def _HTTPServerProcess(conn, dirname, port, server_kwargs): def main(args): - parser = optparse.OptionParser() - parser.add_option('-C', '--serve-dir', + parser = argparse.ArgumentParser() + parser.add_argument('-C', '--serve-dir', help='Serve files out of this directory.', default=os.path.abspath('.')) - parser.add_option('-p', '--port', + parser.add_argument('-p', '--port', help='Run server on this port.', default=5103) - parser.add_option('--no-dir-check', '--no_dir_check', + parser.add_argument('--no-dir-check', '--no_dir_check', help='No check to ensure serving from safe directory.', dest='do_safe_check', action='store_false', default=True) @@ -204,7 +204,7 @@ def main(args): except ImportError: pass - options, args = parser.parse_args(args) + options = parser.parse_args(args) if options.do_safe_check: SanityCheckDirectory(options.serve_dir) diff --git a/native_client_sdk/src/tools/lib/tests/quote_test.py b/native_client_sdk/src/tools/lib/tests/quote_test.py index fe0e6c3..a14f186 100755 --- a/native_client_sdk/src/tools/lib/tests/quote_test.py +++ b/native_client_sdk/src/tools/lib/tests/quote_test.py @@ -3,7 +3,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import optparse +import argparse import os import sys import unittest @@ -92,53 +92,51 @@ class TestQuote(unittest.TestCase): # Invoke this file directly for simple manual testing. For running # the unittests, use the -t flag. Any flags to be passed to the -# unittest module should be passed as after the optparse processing, +# unittest module should be passed as after the argparse processing, # e.g., "quote_test.py -t -- -v" to pass the -v flag to the unittest # module. -def main(argv): +def main(args): global verbose - parser = optparse.OptionParser( - usage='Usage: %prog [options] word...') - parser.add_option('-s', '--special-chars', dest='special_chars', default=':', - help='Special characters to quote (default is ":")') - parser.add_option('-q', '--quote', dest='quote', default='\\', - help='Quote or escape character (default is "\")') - parser.add_option('-t', '--run-tests', dest='tests', action='store_true', - help='Run built-in tests\n') - parser.add_option('-u', '--unquote-input', dest='unquote_input', - action='store_true', help='Unquote command line argument') - parser.add_option('-v', '--verbose', dest='verbose', action='store_true', - help='Verbose test output') - options, args = parser.parse_args(argv) + parser = argparse.ArgumentParser() + parser.add_argument('-s', '--special-chars', + dest='special_chars', default=':', + help='Special characters to quote (default is ":")') + parser.add_argument('-q', '--quote', dest='quote', default='\\', + help='Quote or escape character (default is "\")') + parser.add_argument('-u', '--unquote-input', dest='unquote_input', + action='store_true', help='Unquote command line argument') + parser.add_argument('-v', '--verbose', dest='verbose', action='store_true', + help='Verbose test output') + parser.add_argument('words', nargs='*') + options = parser.parse_args(args) if options.verbose: verbose = True - num_errors = 0 - if options.tests: - sys.argv = [sys.argv[0]] + args + if not options.words: unittest.main() - else: - for word in args: - # NB: there are inputs x for which quote(unquote(x) != x, but - # there should be no input x for which unquote(quote(x)) != x. - if options.unquote_input: - qq = quote.unquote(word, options.special_chars, options.quote) - sys.stdout.write('unquote(%s) = %s\n' - % (word, ''.join(qq))) - # There is no expected output for unquote -- this is just for - # manual testing, so it is okay that we do not (and cannot) - # update num_errors here. - else: - q = quote.quote(word, options.special_chars, options.quote) - qq = quote.unquote(q, options.special_chars, options.quote) - sys.stdout.write('quote(%s) = %s, unquote(%s) = %s\n' - % (word, q, q, ''.join(qq))) - if word != ''.join(qq): - num_errors += 1 - if num_errors > 0: - sys.stderr.write('[ FAILED ] %d test failures\n' % num_errors) + + num_errors = 0 + for word in options.words: + # NB: there are inputs x for which quote(unquote(x) != x, but + # there should be no input x for which unquote(quote(x)) != x. + if options.unquote_input: + qq = quote.unquote(word, options.special_chars, options.quote) + sys.stdout.write('unquote(%s) = %s\n' + % (word, ''.join(qq))) + # There is no expected output for unquote -- this is just for + # manual testing, so it is okay that we do not (and cannot) + # update num_errors here. + else: + q = quote.quote(word, options.special_chars, options.quote) + qq = quote.unquote(q, options.special_chars, options.quote) + sys.stdout.write('quote(%s) = %s, unquote(%s) = %s\n' + % (word, q, q, ''.join(qq))) + if word != ''.join(qq): + num_errors += 1 + if num_errors > 0: + sys.stderr.write('[ FAILED ] %d test failures\n' % num_errors) return num_errors if __name__ == '__main__': diff --git a/native_client_sdk/src/tools/nacl_config.py b/native_client_sdk/src/tools/nacl_config.py index d98b2bc..e8a7129 100755 --- a/native_client_sdk/src/tools/nacl_config.py +++ b/native_client_sdk/src/tools/nacl_config.py @@ -8,7 +8,7 @@ It is similar in behavior to pkg-config or sdl-config. """ -import optparse +import argparse import os import posixpath import sys @@ -222,27 +222,25 @@ def GetLDFlags(): def main(args): - usage = 'Usage: %prog [options] <command>' - parser = optparse.OptionParser(usage=usage, description=__doc__) - parser.add_option('-t', '--toolchain', help='toolchain name. This can also ' - 'be specified with the NACL_TOOLCHAIN environment ' - 'variable.') - parser.add_option('-a', '--arch', help='architecture name. This can also be ' - 'specified with the NACL_ARCH environment variable.') - - group = optparse.OptionGroup(parser, 'Commands') - group.add_option('--tool', help='get tool path') - group.add_option('--cflags', - help='output all preprocessor and compiler flags', - action='store_true') - group.add_option('--libs', '--ldflags', help='output all linker flags', - action='store_true') - group.add_option('--include-dirs', - help='output include dirs, separated by spaces', - action='store_true') - parser.add_option_group(group) - - options, _ = parser.parse_args(args) + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('-t', '--toolchain', help='toolchain name. This can also ' + 'be specified with the NACL_TOOLCHAIN environment ' + 'variable.') + parser.add_argument('-a', '--arch', help='architecture name. This can also ' + 'be specified with the NACL_ARCH environment variable.') + + group = parser.add_argument_group('Commands') + group.add_argument('--tool', help='get tool path') + group.add_argument('--cflags', + help='output all preprocessor and compiler flags', + action='store_true') + group.add_argument('--libs', '--ldflags', help='output all linker flags', + action='store_true') + group.add_argument('--include-dirs', + help='output include dirs, separated by spaces', + action='store_true') + + options = parser.parse_args(args) # Get toolchain/arch from environment, if not specified on commandline options.toolchain = options.toolchain or os.getenv('NACL_TOOLCHAIN') diff --git a/native_client_sdk/src/tools/ncval.py b/native_client_sdk/src/tools/ncval.py index aebfe34..8490399 100755 --- a/native_client_sdk/src/tools/ncval.py +++ b/native_client_sdk/src/tools/ncval.py @@ -3,10 +3,10 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Wrapper script for running ncval. +"""Wrapper script for running the Native Client validator (ncval). """ -import optparse +import argparse import os import subprocess import sys @@ -28,12 +28,11 @@ def Log(msg): sys.stderr.write(str(msg) + '\n') Log.verbose = False -def main(argv): - usage = 'Usage: %prog [options] <.nexe | .so>' - epilog = 'Example: ncval.py my_nexe.nexe' - parser = optparse.OptionParser(usage, description=__doc__, epilog=epilog) - parser.add_option('-v', '--verbose', action='store_true', - help='Verbose output') +def main(args): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('-v', '--verbose', action='store_true', + help='Verbose output') + parser.add_argument('nexe', metavar="EXE", help='Executable to validate') # To enable bash completion for this command first install optcomplete # and then add this line to your .bashrc: @@ -44,11 +43,9 @@ def main(argv): except ImportError: pass - options, args = parser.parse_args(argv) - if not args: - parser.error('No executable file specified') + options = parser.parse_args(args) + nexe = options.nexe - nexe = args[0] if options.verbose: Log.verbose = True diff --git a/native_client_sdk/src/tools/oshelpers.py b/native_client_sdk/src/tools/oshelpers.py index aa67cff..ff9bd09 100755 --- a/native_client_sdk/src/tools/oshelpers.py +++ b/native_client_sdk/src/tools/oshelpers.py @@ -3,9 +3,13 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +"""Utility script for emulating common unix commands.""" + +from __future__ import print_function + import fnmatch import glob -import optparse +import argparse import os import posixpath import shutil @@ -23,7 +27,8 @@ def IncludeFiles(filters, files): """Filter files based on inclusion lists Return a list of files which match and of the Unix shell-style wildcards - provided, or return all the files if no filter is provided.""" + provided, or return all the files if no filter is provided. + """ if not filters: return files match = set() @@ -36,7 +41,8 @@ def ExcludeFiles(filters, files): """Filter files based on exclusions lists Return a list of files which do not match any of the Unix shell-style - wildcards provided, or return all the files if no filter is provided.""" + wildcards provided, or return all the files if no filter is provided. + """ if not filters: return files match = set() @@ -52,7 +58,8 @@ def CopyPath(options, src, dst): Copy a fully specified src to a fully specified dst. If src and dst are both files, the dst file is removed first to prevent error. If and include or exclude list are provided, the destination is first matched against that - filter.""" + filter. + """ if options.includes: if not IncludeFiles(options.includes, [src]): return @@ -62,7 +69,7 @@ def CopyPath(options, src, dst): return if options.verbose: - print 'cp %s %s' % (src, dst) + print('cp %s %s' % (src, dst)) # If the source is a single file, copy it individually if os.path.isfile(src): @@ -82,7 +89,7 @@ def CopyPath(options, src, dst): # Otherwise it's a directory, ignore it unless allowed if os.path.isdir(src): if not options.recursive: - print "cp: omitting directory '%s'" % src + print("cp: omitting directory '%s'" % src) return # We can not copy over a file with a directory. @@ -107,31 +114,31 @@ def Copy(args): Copies multiple sources to a single destination using the normal cp semantics. In addition, it support inclusion and exclusion filters which - allows the copy to skip certain types of files.""" - parser = optparse.OptionParser(usage='usage: cp [Options] sources... dest') - parser.add_option( + allows the copy to skip certain types of files. + """ + parser = argparse.ArgumentParser(usage='cp [Options] sources... dest', + description=Copy.__doc__) + parser.add_argument( '-R', '-r', '--recursive', dest='recursive', action='store_true', default=False, help='copy directories recursively.') - parser.add_option( + parser.add_argument( '-v', '--verbose', dest='verbose', action='store_true', default=False, help='verbose output.') - parser.add_option( + parser.add_argument( '--include', dest='includes', action='append', default=[], help='include files matching this expression.') - parser.add_option( + parser.add_argument( '--exclude', dest='excludes', action='append', default=[], help='exclude files matching this expression.') - options, files = parser.parse_args(args) - if len(files) < 2: - parser.error('ERROR: expecting SOURCE(s) and DEST.') + parser.add_argument('srcs', nargs='+', help='files to copy') + parser.add_argument('dest', help='destination') - srcs = files[:-1] - dst = files[-1] + options = parser.parse_args(args) src_list = [] - for src in srcs: + for src in options.srcs: files = glob.glob(src) if not files: raise OSError('cp: no such file or directory: ' + src) @@ -141,31 +148,31 @@ def Copy(args): for src in src_list: # If the destination is a directory, then append the basename of the src # to the destination. - if os.path.isdir(dst): - CopyPath(options, src, os.path.join(dst, os.path.basename(src))) + if os.path.isdir(options.dest): + CopyPath(options, src, os.path.join(options.dest, os.path.basename(src))) else: - CopyPath(options, src, dst) + CopyPath(options, src, options.dest) def Mkdir(args): - """A Unix style mkdir""" - parser = optparse.OptionParser(usage='usage: mkdir [Options] DIRECTORY...') - parser.add_option( + """A Unix style mkdir.""" + parser = argparse.ArgumentParser(usage='mkdir [Options] DIRECTORY...', + description=Mkdir.__doc__) + parser.add_argument( '-p', '--parents', dest='parents', action='store_true', default=False, help='ignore existing parents, create parents as needed.') - parser.add_option( + parser.add_argument( '-v', '--verbose', dest='verbose', action='store_true', default=False, help='verbose output.') + parser.add_argument('dirs', nargs='+', help='directory(s) to create') - options, dsts = parser.parse_args(args) - if len(dsts) < 1: - parser.error('ERROR: expecting DIRECTORY...') + options = parser.parse_args(args) - for dst in dsts: + for dst in options.dirs: if options.verbose: - print 'mkdir ' + dst + print('mkdir %s' % dst) try: os.makedirs(dst) except OSError: @@ -179,12 +186,13 @@ def Mkdir(args): def MovePath(options, src, dst): - """MovePath from src to dst + """MovePath from src to dst. Moves the src to the dst much like the Unix style mv command, except it only handles one source at a time. Because of possible temporary failures do to locks (such as anti-virus software on Windows), the function will retry - up to five times.""" + up to five times. + """ # if the destination is not an existing directory, then overwrite it if os.path.isdir(dst): dst = os.path.join(dst, os.path.basename(src)) @@ -200,36 +208,38 @@ def MovePath(options, src, dst): for _ in range(5): try: os.rename(src, dst) - return + break except OSError as error: - print 'Failed on %s with %s, retrying' % (src, error) + print('Failed on %s with %s, retrying' % (src, error)) time.sleep(5) - print 'Gave up.' - raise OSError('mv: ' + error) + else: + print('Gave up.') + raise OSError('mv: ' + error) def Move(args): - parser = optparse.OptionParser(usage='usage: mv [Options] sources... dest') - parser.add_option( + """A Unix style mv.""" + + parser = argparse.ArgumentParser(usage='mv [Options] sources... dest', + description=Move.__doc__) + parser.add_argument( '-v', '--verbose', dest='verbose', action='store_true', default=False, help='verbose output.') - parser.add_option( + parser.add_argument( '-f', '--force', dest='force', action='store_true', default=False, help='force, do not error it files already exist.') - options, files = parser.parse_args(args) - if len(files) < 2: - parser.error('ERROR: expecting SOURCE... and DEST.') + parser.add_argument('srcs', nargs='+') + parser.add_argument('dest') - srcs = files[:-1] - dst = files[-1] + options = parser.parse_args(args) if options.verbose: - print 'mv %s %s' % (' '.join(srcs), dst) + print('mv %s %s' % (' '.join(options.srcs), options.dest)) - for src in srcs: - MovePath(options, src, dst) + for src in options.srcs: + MovePath(options, src, options.dest) return 0 @@ -238,26 +248,27 @@ def Remove(args): Removes the list of paths. Because of possible temporary failures do to locks (such as anti-virus software on Windows), the function will retry up to five - times.""" - parser = optparse.OptionParser(usage='usage: rm [Options] PATHS...') - parser.add_option( + times. + """ + parser = argparse.ArgumentParser(usage='rm [Options] PATHS...', + description=Remove.__doc__) + parser.add_argument( '-R', '-r', '--recursive', dest='recursive', action='store_true', default=False, help='remove directories recursively.') - parser.add_option( + parser.add_argument( '-v', '--verbose', dest='verbose', action='store_true', default=False, help='verbose output.') - parser.add_option( + parser.add_argument( '-f', '--force', dest='force', action='store_true', default=False, help='force, do not error it files does not exist.') - options, files = parser.parse_args(args) - if len(files) < 1: - parser.error('ERROR: expecting FILE...') + parser.add_argument('files', nargs='+') + options = parser.parse_args(args) try: - for pattern in files: + for pattern in options.files: dst_files = glob.glob(pattern) if not dst_files: # Ignore non existing files when using force @@ -267,10 +278,10 @@ def Remove(args): for dst in dst_files: if options.verbose: - print 'rm ' + dst + print('rm ' + dst) if os.path.isfile(dst) or os.path.islink(dst): - for i in range(5): + for _ in range(5): try: # Check every time, since it may have been deleted after the # previous failed attempt. @@ -278,27 +289,28 @@ def Remove(args): os.remove(dst) break except OSError as error: - if i == 5: - print 'Gave up.' - raise OSError('rm: ' + str(error)) - print 'Failed remove with %s, retrying' % error + print('Failed remove with %s, retrying' % error) time.sleep(5) + else: + print('Gave up.') + raise OSError('rm: ' + str(error)) if options.recursive: - for i in range(5): + for _ in range(5): try: if os.path.isdir(dst): shutil.rmtree(dst) break except OSError as error: - if i == 5: - print 'Gave up.' - raise OSError('rm: ' + str(error)) - print 'Failed rmtree with %s, retrying' % error + print('Failed rmtree with %s, retrying' % error) time.sleep(5) + else: + print('Gave up.') + raise OSError('rm: ' + str(error)) except OSError as error: - print error + print(error) + return 0 @@ -342,29 +354,27 @@ def OSMakeZipPath(os_path): def Zip(args): """A Unix style zip. - Compresses the listed files.""" - parser = optparse.OptionParser(usage='usage: zip [Options] zipfile list') - parser.add_option( + Compresses the listed files. + """ + parser = argparse.ArgumentParser(description=Zip.__doc__) + parser.add_argument( '-r', dest='recursive', action='store_true', default=False, help='recurse into directories') - parser.add_option( + parser.add_argument( '-q', dest='quiet', action='store_true', default=False, help='quiet operation') - options, files = parser.parse_args(args) - if len(files) < 2: - parser.error('ERROR: expecting ZIPFILE and LIST.') - - dest_zip = files[0] - src_args = files[1:] + parser.add_argument('zipfile') + parser.add_argument('filenames', nargs='+') + options = parser.parse_args(args) src_files = [] - for src_arg in src_args: - globbed_src_args = glob.glob(src_arg) + for filename in options.filenames: + globbed_src_args = glob.glob(filename) if not globbed_src_args: if not options.quiet: - print 'zip warning: name not matched: %s' % (src_arg,) + print('zip warning: name not matched: %s' % filename) for src_file in globbed_src_args: src_file = os.path.normpath(src_file) @@ -376,7 +386,6 @@ def Zip(args): for filename in files: src_files.append(os.path.join(root, filename)) - zip_stream = None # zip_data represents a list of the data to be written or appended to the # zip_stream. It is a list of tuples: # (OS file path, zip path/zip file info, and file data) @@ -389,39 +398,37 @@ def Zip(args): zip_path_to_os_path_dict = dict((new_files_to_add[i], src_files[i]) for i in range(len(src_files))) write_mode = 'a' - try: - zip_stream = zipfile.ZipFile(dest_zip, 'r') - files_to_update = set(new_files_to_add).intersection( - set(zip_stream.namelist())) - if files_to_update: - # As far as I can tell, there is no way to update a zip entry using - # zipfile; the best you can do is rewrite the archive. - # Iterate through the zipfile to maintain file order. - write_mode = 'w' - for zip_path in zip_stream.namelist(): - if zip_path in files_to_update: - os_path = zip_path_to_os_path_dict[zip_path] - zip_data.append((os_path, zip_path, None)) - new_files_to_add.remove(zip_path) - else: - file_bytes = zip_stream.read(zip_path) - file_info = zip_stream.getinfo(zip_path) - zip_data.append((None, file_info, file_bytes)) - except IOError: - pass - finally: - if zip_stream: - zip_stream.close() + if os.path.exists(options.zipfile): + with zipfile.ZipFile(options.zipfile, 'r') as zip_stream: + try: + files_to_update = set(new_files_to_add).intersection( + set(zip_stream.namelist())) + if files_to_update: + # As far as I can tell, there is no way to update a zip entry using + # zipfile; the best you can do is rewrite the archive. + # Iterate through the zipfile to maintain file order. + write_mode = 'w' + for zip_path in zip_stream.namelist(): + if zip_path in files_to_update: + os_path = zip_path_to_os_path_dict[zip_path] + zip_data.append((os_path, zip_path, None)) + new_files_to_add.remove(zip_path) + else: + file_bytes = zip_stream.read(zip_path) + file_info = zip_stream.getinfo(zip_path) + zip_data.append((None, file_info, file_bytes)) + except IOError: + pass for zip_path in new_files_to_add: zip_data.append((zip_path_to_os_path_dict[zip_path], zip_path, None)) if not zip_data: - print 'zip error: Nothing to do! (%s)' % (dest_zip,) + print('zip error: Nothing to do! (%s)' % options.zipfile) return 1 - try: - zip_stream = zipfile.ZipFile(dest_zip, write_mode, zipfile.ZIP_DEFLATED) + with zipfile.ZipFile(options.zipfile, write_mode, + zipfile.ZIP_DEFLATED) as zip_stream: for os_path, file_info_or_zip_path, file_bytes in zip_data: if isinstance(file_info_or_zip_path, zipfile.ZipInfo): zip_path = file_info_or_zip_path.filename @@ -458,12 +465,10 @@ def Zip(args): zip_info = zip_stream.getinfo(zip_path) if (zip_info.compress_type == zipfile.ZIP_STORED or zip_info.file_size == 0): - print ' %s: %s (stored 0%%)' % (operation, zip_path) + print(' %s: %s (stored 0%%)' % (operation, zip_path)) elif zip_info.compress_type == zipfile.ZIP_DEFLATED: - print ' %s: %s (deflated %d%%)' % (operation, zip_path, - 100 - zip_info.compress_size * 100 / zip_info.file_size) - finally: - zip_stream.close() + print(' %s: %s (deflated %d%%)' % (operation, zip_path, + 100 - zip_info.compress_size * 100 / zip_info.file_size)) return 0 @@ -494,16 +499,15 @@ def Which(args): Note: If you pass an argument with a path to which, it will just test if it is executable, not if it is in the path. """ - parser = optparse.OptionParser(usage='usage: which args...') - _, files = parser.parse_args(args) - if not files: - return 0 + parser = argparse.ArgumentParser(description=Which.__doc__) + parser.add_argument('files', nargs='+') + options = parser.parse_args(args) retval = 0 - for filename in files: + for filename in options.files: fullname = FindExeInPath(filename) if fullname: - print fullname + print(fullname) else: retval = 1 @@ -522,19 +526,19 @@ FuncMap = { def main(args): if not args: - print 'No command specified' - print 'Available commands: %s' % ' '.join(FuncMap) + print('No command specified') + print('Available commands: %s' % ' '.join(FuncMap)) return 1 func_name = args[0] func = FuncMap.get(func_name) if not func: - print 'Do not recognize command: %s' % func_name - print 'Available commands: %s' % ' '.join(FuncMap) + print('Do not recognize command: %s' % func_name) + print('Available commands: %s' % ' '.join(FuncMap)) return 1 try: return func(args[1:]) except KeyboardInterrupt: - print '%s: interrupted' % func_name + print('%s: interrupted' % func_name) return 1 if __name__ == '__main__': diff --git a/native_client_sdk/src/tools/run.py b/native_client_sdk/src/tools/run.py index 441cc1f..b0131c5 100755 --- a/native_client_sdk/src/tools/run.py +++ b/native_client_sdk/src/tools/run.py @@ -3,13 +3,17 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Launch a local server on an ephemeral port, then launch a executable that -points to that server. +"""Launch a local http server, then launch a executable directed at the server. + +This command creates a local server (on port 5103 by default) then runs: + <executable> <args..> http://localhost:<port>/<page>. + +Where <page> can be set by -P, or uses index.html by default. """ +import argparse import copy import getos -import optparse import os import subprocess import sys @@ -22,30 +26,24 @@ if sys.version_info < (2, 7, 0): def main(args): - usage = """usage: %prog [options] -- executable args... - - This command creates a local server on an ephemeral port, then runs: - <executable> <args..> http://localhost:<port>/<page>. - - Where <page> can be set by -P, or uses index.html by default.""" - parser = optparse.OptionParser(usage) - parser.add_option('-C', '--serve-dir', + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('-C', '--serve-dir', help='Serve files out of this directory.', dest='serve_dir', default=os.path.abspath('.')) - parser.add_option('-P', '--path', help='Path to load from local server.', + parser.add_argument('-P', '--path', help='Path to load from local server.', dest='path', default='index.html') - parser.add_option('-D', + parser.add_argument('-D', help='Add debug command-line when launching the chrome debug.', dest='debug', action='append', default=[]) - parser.add_option('-E', + parser.add_argument('-E', help='Add environment variables when launching the executable.', dest='environ', action='append', default=[]) - parser.add_option('-p', '--port', + parser.add_argument('-p', '--port', help='Port to run server on. Default is 5103, ephemeral is 0.', - type='int', default=5103) - options, args = parser.parse_args(args) - if not args: - parser.error('No executable given.') + type=int, default=5103) + parser.add_argument('executable', help='command to run') + parser.add_argument('args', nargs='*', help='arguments for executable') + options = parser.parse_args(args) # 0 means use an ephemeral port. server = httpd.LocalHTTPServer(options.serve_dir, options.port) @@ -56,7 +54,7 @@ def main(args): key, value = map(str.strip, e.split('=')) env[key] = value - cmd = args + [server.GetURL(options.path)] + cmd = [options.executable] + options.args + [server.GetURL(options.path)] print 'Running: %s...' % (' '.join(cmd),) process = subprocess.Popen(cmd, env=env) diff --git a/native_client_sdk/src/tools/sel_ldr.py b/native_client_sdk/src/tools/sel_ldr.py index 79d763b..8cc49eb 100755 --- a/native_client_sdk/src/tools/sel_ldr.py +++ b/native_client_sdk/src/tools/sel_ldr.py @@ -6,7 +6,7 @@ """Wrapper script for launching application within the sel_ldr. """ -import optparse +import argparse import os import subprocess import sys @@ -49,16 +49,17 @@ def FindQemu(): def main(argv): - usage = 'Usage: %prog [options] <.nexe>' epilog = 'Example: sel_ldr.py my_nexe.nexe' - parser = optparse.OptionParser(usage, description=__doc__, epilog=epilog) - parser.add_option('-v', '--verbose', action='store_true', - help='Verbose output') - parser.add_option('-d', '--debug', action='store_true', - help='Enable debug stub') - parser.add_option('--debug-libs', action='store_true', - help='For dynamic executables, reference debug ' - 'libraries rather then release') + parser = argparse.ArgumentParser(description=__doc__, epilog=epilog) + parser.add_argument('-v', '--verbose', action='store_true', + help='Verbose output') + parser.add_argument('-d', '--debug', action='store_true', + help='Enable debug stub') + parser.add_argument('--debug-libs', action='store_true', + help='For dynamic executables, reference debug ' + 'libraries rather then release') + parser.add_argument('executable', help='executable (.nexe) to run') + parser.add_argument('args', nargs='*', help='argument to pass to exectuable') # To enable bash completion for this command first install optcomplete # and then add this line to your .bashrc: @@ -69,21 +70,18 @@ def main(argv): except ImportError: pass - options, args = parser.parse_args(argv) - if not args: - parser.error('No executable file specified') + options = parser.parse_args(argv) - nexe = args[0] if options.verbose: Log.verbose = True osname = getos.GetPlatform() - if not os.path.exists(nexe): - raise Error('executable not found: %s' % nexe) - if not os.path.isfile(nexe): - raise Error('not a file: %s' % nexe) + if not os.path.exists(options.executable): + raise Error('executable not found: %s' % options.executable) + if not os.path.isfile(options.executable): + raise Error('not a file: %s' % options.executable) - arch, dynamic = create_nmf.ParseElfHeader(nexe) + arch, dynamic = create_nmf.ParseElfHeader(options.executable) if arch == 'arm' and osname != 'linux': raise Error('Cannot run ARM executables under sel_ldr on ' + osname) @@ -150,13 +148,12 @@ def main(argv): cmd.append(libpath) - if args: - # Append arguments for the executable itself. - cmd += args + # Append arguments for the executable itself. + cmd.append(options.executable) + cmd += options.args Log(cmd) - rtn = subprocess.call(cmd) - return rtn + return subprocess.call(cmd) if __name__ == '__main__': diff --git a/native_client_sdk/src/tools/tests/chrome_mock.py b/native_client_sdk/src/tools/tests/chrome_mock.py index 227a606..966e231 100755 --- a/native_client_sdk/src/tools/tests/chrome_mock.py +++ b/native_client_sdk/src/tools/tests/chrome_mock.py @@ -3,37 +3,39 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import optparse +"""Mock chrome process used by test code for http server.""" + +import argparse import sys import time import urllib2 def PrintAndFlush(s): - print s + sys.stdout.write(s + '\n') sys.stdout.flush() def main(args): - parser = optparse.OptionParser(usage='%prog [options] <URL to load>') - parser.add_option('--post', help='POST to URL.', dest='post', - action='store_true') - parser.add_option('--get', help='GET to URL.', dest='get', - action='store_true') - parser.add_option('--sleep', - help='Number of seconds to sleep after reading URL', - dest='sleep', default=0) - parser.add_option('--expect-to-be-killed', help='If set, the script will warn' - ' if it isn\'t killed before it finishes sleeping.', - dest='expect_to_be_killed', action='store_true') - options, args = parser.parse_args(args) - if len(args) != 1: - parser.error('Expected URL to load.') + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--post', help='POST to URL.', dest='post', + action='store_true') + parser.add_argument('--get', help='GET to URL.', dest='get', + action='store_true') + parser.add_argument('--sleep', + help='Number of seconds to sleep after reading URL', + dest='sleep', default=0) + parser.add_argument('--expect-to-be-killed', help='If set, the script will' + ' warn if it isn\'t killed before it finishes sleeping.', + dest='expect_to_be_killed', action='store_true') + parser.add_argument('url') + + options = parser.parse_args(args) PrintAndFlush('Starting %s.' % sys.argv[0]) if options.post: - urllib2.urlopen(args[0], data='').read() + urllib2.urlopen(options.url, data='').read() elif options.get: - urllib2.urlopen(args[0]).read() + urllib2.urlopen(options.url).read() else: # Do nothing but wait to be killed. pass diff --git a/native_client_sdk/src/tools/tests/create_html_test.py b/native_client_sdk/src/tools/tests/create_html_test.py index a02b720..dd37338 100755 --- a/native_client_sdk/src/tools/tests/create_html_test.py +++ b/native_client_sdk/src/tools/tests/create_html_test.py @@ -11,7 +11,7 @@ import tempfile SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) PARENT_DIR = os.path.dirname(SCRIPT_DIR) CHROME_SRC = os.path.dirname(os.path.dirname(os.path.dirname(PARENT_DIR))) -MOCK_DIR = os.path.join(CHROME_SRC, "third_party", "pymock") +MOCK_DIR = os.path.join(CHROME_SRC, 'third_party', 'pymock') sys.path.append(PARENT_DIR) sys.path.append(MOCK_DIR) diff --git a/native_client_sdk/src/tools/tests/fix_deps_test.py b/native_client_sdk/src/tools/tests/fix_deps_test.py index d02f8ac..6024e56 100755 --- a/native_client_sdk/src/tools/tests/fix_deps_test.py +++ b/native_client_sdk/src/tools/tests/fix_deps_test.py @@ -11,7 +11,7 @@ SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) PARENT_DIR = os.path.dirname(SCRIPT_DIR) DATA_DIR = os.path.join(SCRIPT_DIR, 'data') CHROME_SRC = os.path.dirname(os.path.dirname(os.path.dirname(PARENT_DIR))) -MOCK_DIR = os.path.join(CHROME_SRC, "third_party", "pymock") +MOCK_DIR = os.path.join(CHROME_SRC, 'third_party', 'pymock') # For the mock library sys.path.append(MOCK_DIR) diff --git a/native_client_sdk/src/tools/tests/getos_test.py b/native_client_sdk/src/tools/tests/getos_test.py index f47fffb..710ec52 100755 --- a/native_client_sdk/src/tools/tests/getos_test.py +++ b/native_client_sdk/src/tools/tests/getos_test.py @@ -12,7 +12,7 @@ import unittest SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) TOOLS_DIR = os.path.dirname(SCRIPT_DIR) CHROME_SRC = os.path.dirname(os.path.dirname(os.path.dirname(TOOLS_DIR))) -MOCK_DIR = os.path.join(CHROME_SRC, "third_party", "pymock") +MOCK_DIR = os.path.join(CHROME_SRC, 'third_party', 'pymock') # For the mock library sys.path.append(MOCK_DIR) @@ -103,6 +103,24 @@ class TestGetos(TestCaseExtended): arch = getos.GetNaClArch(platform) self.assertIn(arch, ('x86_64', 'x86_32', 'arm')) + def testMainInvalidArgs(self): + with self.assertRaises(SystemExit): + with mock.patch('sys.stderr'): + getos.main('--foo') + + @mock.patch('sys.stdout', mock.Mock()) + @mock.patch('getos.GetPlatform') + def testMainNoArgs(self, mock_get_platform): + mock_get_platform.return_value = 'platform' + getos.main([]) + + @mock.patch('sys.stdout', mock.Mock()) + @mock.patch('getos.GetSystemArch') + def testMainArgsParsing(self, mock_system_arch): + mock_system_arch.return_value = 'dummy' + getos.main(['--arch']) + mock_system_arch.assert_called() + class TestGetosWithTempdir(TestCaseExtended): def setUp(self): diff --git a/native_client_sdk/src/tools/tests/httpd_test.py b/native_client_sdk/src/tools/tests/httpd_test.py index ff4ef5a..abc1cc3 100755 --- a/native_client_sdk/src/tools/tests/httpd_test.py +++ b/native_client_sdk/src/tools/tests/httpd_test.py @@ -14,13 +14,13 @@ import urllib2 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) TOOLS_DIR = os.path.dirname(SCRIPT_DIR) CHROME_SRC = os.path.dirname(os.path.dirname(os.path.dirname(TOOLS_DIR))) -MOCK_DIR = os.path.join(CHROME_SRC, "third_party", "pymock") +MOCK_DIR = os.path.join(CHROME_SRC, 'third_party', 'pymock') sys.path.append(TOOLS_DIR) sys.path.append(MOCK_DIR) import httpd -from mock import patch +from mock import patch, Mock class HTTPDTest(unittest.TestCase): @@ -38,6 +38,16 @@ class HTTPDTest(unittest.TestCase): self.assertFalse(self.server.process.is_alive()) +class MainTest(unittest.TestCase): + @patch('httpd.LocalHTTPServer') + @patch('sys.stdout', Mock()) + def testArgs(self, mock_server_ctor): + mock_server = Mock() + mock_server_ctor.return_value = mock_server + httpd.main(['-p', '123', '-C', 'dummy']) + mock_server_ctor.assert_called_once_with('dummy', 123) + + class RunTest(unittest.TestCase): def setUp(self): self.process = None diff --git a/native_client_sdk/src/tools/tests/nacl_config_test.py b/native_client_sdk/src/tools/tests/nacl_config_test.py index 31957c5..b0cbe26 100755 --- a/native_client_sdk/src/tools/tests/nacl_config_test.py +++ b/native_client_sdk/src/tools/tests/nacl_config_test.py @@ -10,7 +10,7 @@ import unittest SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) TOOLS_DIR = os.path.dirname(SCRIPT_DIR) CHROME_SRC = os.path.dirname(os.path.dirname(os.path.dirname(TOOLS_DIR))) -MOCK_DIR = os.path.join(CHROME_SRC, "third_party", "pymock") +MOCK_DIR = os.path.join(CHROME_SRC, 'third_party', 'pymock') # For the mock library sys.path.append(MOCK_DIR) @@ -40,6 +40,13 @@ class TestNaclConfig(unittest.TestCase): self.patches.append(patch) return patch.start() + @mock.patch('nacl_config.GetCFlags') + def testMainArgParsing(self, mock_get_cflags): + mock_get_cflags.return_value = 'flags' + with mock.patch('sys.stdout'): + nacl_config.main(['--cflags']) + mock_get_cflags.assert_called() + def testCFlags(self): cases = { 'newlib': '-I/sdk_root/include -I/sdk_root/include/newlib', diff --git a/native_client_sdk/src/tools/tests/sel_ldr_test.py b/native_client_sdk/src/tools/tests/sel_ldr_test.py index 6ad6961..0334730 100755 --- a/native_client_sdk/src/tools/tests/sel_ldr_test.py +++ b/native_client_sdk/src/tools/tests/sel_ldr_test.py @@ -11,7 +11,7 @@ SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) PARENT_DIR = os.path.dirname(SCRIPT_DIR) DATA_DIR = os.path.join(SCRIPT_DIR, 'data') CHROME_SRC = os.path.dirname(os.path.dirname(os.path.dirname(PARENT_DIR))) -MOCK_DIR = os.path.join(CHROME_SRC, "third_party", "pymock") +MOCK_DIR = os.path.join(CHROME_SRC, 'third_party', 'pymock') # For the mock library sys.path.append(MOCK_DIR) |