diff options
author | Steve Fung <stevefung@google.com> | 2016-04-18 13:52:46 -0700 |
---|---|---|
committer | Steve Fung <stevefung@google.com> | 2016-04-18 21:57:29 +0000 |
commit | 63c64a0e299baae63414decde185264944a96e46 (patch) | |
tree | f485db623cd638b731bccd2089ef3cf91dfc1317 | |
parent | 14e7aa88a6e7a9bda189ce4aa8a5eff482e30d8e (diff) | |
download | bdk-63c64a0e299baae63414decde185264944a96e46.tar.gz |
Convert commands/ to 4 space indent
Convert most files in the commands/ folder to a 4 space indent
to comply with PEP8 style rules. This CL skips
commands/v2/build/image.py, to avoid merge conflicts with
http://r.android.com/216174. That file will be fixed up in
a later CL.
Bug: 28007659
Test: `python test_runner.py` passes.
Test: pylint passes.
Change-Id: I1344907a8b346e054b6b5b3c8201d9563142543f
28 files changed, 951 insertions, 926 deletions
diff --git a/cli/lib/commands/bsp/__init__.py b/cli/lib/commands/bsp/__init__.py index aa2c705..fd8124a 100644 --- a/cli/lib/commands/bsp/__init__.py +++ b/cli/lib/commands/bsp/__init__.py @@ -25,13 +25,13 @@ DEFAULT_OS = util.DEPRECATED_GetDefaultOSPath() class BSPGroup(clicommand.Group): - """Manage Brillo BSPs.""" + """Manage Brillo BSPs.""" - @staticmethod - def GroupArgs(parser): - """See super class.""" - parser.add_argument('-m', '--manifest', - default=manifest.DEFAULT_MANIFEST_FILE, - help='Path to custom manifest of BSPs ' - '(default {})'.format( - manifest.DEFAULT_MANIFEST_FILE)) + @staticmethod + def GroupArgs(parser): + """See super class.""" + parser.add_argument('-m', '--manifest', + default=manifest.DEFAULT_MANIFEST_FILE, + help='Path to custom manifest of BSPs ' + '(default {})'.format( + manifest.DEFAULT_MANIFEST_FILE)) diff --git a/cli/lib/commands/bsp/download.py b/cli/lib/commands/bsp/download.py index 770f5b3..7c5524f 100644 --- a/cli/lib/commands/bsp/download.py +++ b/cli/lib/commands/bsp/download.py @@ -27,93 +27,96 @@ from core import util class Update(clicommand.Command): - """Update an existing BSP, or download a new BSP. - - The software that you are downloading is the property of the software owner - and is distributed by the software owner. Google is providing the download - service as a convenience. - """ - - @staticmethod - def Args(parser): - parser.add_argument('device', help='Device to download BSP for.') - parser.add_argument('-a', '--accept_licenses', action='store_true', - help=argparse.SUPPRESS) - parser.add_argument('-e', '--extract_only', nargs='*', - help='List of tarballs to use directly instead of ' - 'downloading from the remote host ' - 'listed in the manifest.') - parser.add_argument('-l', '--link', action='store_true', - help=argparse.SUPPRESS) - - def Run(self, args): - bsp_manifest = manifest.Manifest.from_json(args.manifest) - - device_ = bsp_manifest.devices.get(args.device) - if not device_: - print 'Unrecognized device name:', args.device - return 1 - - extract_only = {} - if args.extract_only: - extract_only = self.IdentifyTarballs(args.extract_only, device_) - if len(extract_only) != len(args.extract_only): - print ('Could not identify all provided tarballs ' - '(successfully identified {0}).').format(extract_only.keys()) - return 1 - - os_version = util.GetOSVersion() - link_os = os_version if args.link else '' - - try: - device_.install(extract_only, args.accept_licenses, link_os, verbose=True) - except device.PackageLinkError as e: - # If the only error was linking, we may still have downloaded fine. - print e - - # Print and return the results. - (device_status, status_string) = device_.status(os_version, - verbose=True) - print status_string - if device_status <= status.LINKED: - # LINKED or INSTALLED - print 'Successfully installed all packages for {}.'.format(device_.name) - return 0 - elif device_status == status.UNRECOGNIZED: - print 'The following paths exist but do not link to BSP packages:' - for path in device_.unrecognized_paths(os_version): - print ' * ' + path - print ('If this is not intentional, consider ' - 'removing them and installing again.') - return 0 - else: - print 'Failed to install some packages for {}.'.format(device_.name) - return 1 - - def IdentifyTarballs(self, tarballs, device_): - """Matches a list of tarballs to their corresponding packages. - - Args: - tarballs: a list of tarball files. - device_: the device to match to packages in. - - Returns: - A dictionary mapping { package_name : tarball }. + """Update an existing BSP, or download a new BSP. + + The software that you are downloading is the property of the software owner + and is distributed by the software owner. Google is providing the download + service as a convenience. """ - mapping = {} - for tarball in tarballs: - package_name = device_.match_tarball(tarball) - if package_name: - mapping[package_name] = tarball - return mapping + @staticmethod + def Args(parser): + parser.add_argument('device', help='Device to download BSP for.') + parser.add_argument('-a', '--accept_licenses', action='store_true', + help=argparse.SUPPRESS) + parser.add_argument('-e', '--extract_only', nargs='*', + help='List of tarballs to use directly instead of ' + 'downloading from the remote host ' + 'listed in the manifest.') + parser.add_argument('-l', '--link', action='store_true', + help=argparse.SUPPRESS) + + def Run(self, args): + bsp_manifest = manifest.Manifest.from_json(args.manifest) + + device_ = bsp_manifest.devices.get(args.device) + if not device_: + print 'Unrecognized device name:', args.device + return 1 + + extract_only = {} + if args.extract_only: + extract_only = self.IdentifyTarballs(args.extract_only, device_) + if len(extract_only) != len(args.extract_only): + print ('Could not identify all provided tarballs ' + '(successfully identified {0}).').format( + extract_only.keys()) + return 1 + + os_version = util.GetOSVersion() + link_os = os_version if args.link else '' + + try: + device_.install(extract_only, args.accept_licenses, link_os, + verbose=True) + except device.PackageLinkError as e: + # If the only error was linking, we may still have downloaded fine. + print e + + # Print and return the results. + (device_status, status_string) = device_.status(os_version, + verbose=True) + print status_string + if device_status <= status.LINKED: + # LINKED or INSTALLED + print 'Successfully installed all packages for {}.'.format( + device_.name) + return 0 + elif device_status == status.UNRECOGNIZED: + print 'The following paths exist but do not link to BSP packages:' + for path in device_.unrecognized_paths(os_version): + print ' * ' + path + print ('If this is not intentional, consider ' + 'removing them and installing again.') + return 0 + else: + print 'Failed to install some packages for {}.'.format(device_.name) + return 1 + + def IdentifyTarballs(self, tarballs, device_): + """Matches a list of tarballs to their corresponding packages. + + Args: + tarballs: a list of tarball files. + device_: the device to match to packages in. + + Returns: + A dictionary mapping { package_name : tarball }. + """ + mapping = {} + for tarball in tarballs: + package_name = device_.match_tarball(tarball) + if package_name: + mapping[package_name] = tarball + + return mapping class Download(Update): - """Alias, see "bdk bsp update".""" - pass + """Alias, see "bdk bsp update".""" + pass class Install(Update): - """Alias, see "bdk bsp update".""" - pass + """Alias, see "bdk bsp update".""" + pass diff --git a/cli/lib/commands/bsp/list.py b/cli/lib/commands/bsp/list.py index 1cb8a70..8d75896 100644 --- a/cli/lib/commands/bsp/list.py +++ b/cli/lib/commands/bsp/list.py @@ -22,45 +22,46 @@ from core import util class List(clicommand.Command): - """List available BSPs, and their current installation status.""" + """List available BSPs, and their current installation status.""" - @staticmethod - def Args(parser): - parser.add_argument('-v', '--verbose', action='store_true', - help='Print detailed information of device subpackages') + @staticmethod + def Args(parser): + parser.add_argument('-v', '--verbose', action='store_true', + help='Print detailed information of device ' + 'subpackages.') - def Generate(self, manifest_file, verbose): - """Generates a list of devices and statuses. + def Generate(self, manifest_file, verbose): + """Generates a list of devices and statuses. - Args: - manifest_file: Path to the manifest json file. - verbose: If True, print out longer information. + Args: + manifest_file: Path to the manifest json file. + verbose: If True, print out longer information. - Returns: - A (sorted) list of (short name, status string) tuples - """ - bsp_manifest = manifest.Manifest.from_json(manifest_file) + Returns: + A (sorted) list of (short name, status string) tuples + """ + bsp_manifest = manifest.Manifest.from_json(manifest_file) - devices = [] - os_version = util.GetOSVersion() + devices = [] + os_version = util.GetOSVersion() - for short_name in sorted(bsp_manifest.devices): - device = bsp_manifest.devices[short_name] - (_, status_string) = device.status(os_version, verbose) - devices.append((short_name, status_string)) + for short_name in sorted(bsp_manifest.devices): + device = bsp_manifest.devices[short_name] + (_, status_string) = device.status(os_version, verbose) + devices.append((short_name, status_string)) - return devices + return devices - def Print(self, devices): - """Prints a list of devices and statuses. + def Print(self, devices): + """Prints a list of devices and statuses. - Args: - devices: a list of (short name, status string) tuples - """ - for device_details in devices: - print '%s - %s' % device_details + Args: + devices: a list of (short name, status string) tuples + """ + for device_details in devices: + print '%s - %s' % device_details - def Run(self, args): - devices = self.Generate(args.manifest, args.verbose) - self.Print(devices) - return 0 + def Run(self, args): + devices = self.Generate(args.manifest, args.verbose) + self.Print(devices) + return 0 diff --git a/cli/lib/commands/bsp/refresh.py b/cli/lib/commands/bsp/refresh.py index 3c824bb..137bd66 100644 --- a/cli/lib/commands/bsp/refresh.py +++ b/cli/lib/commands/bsp/refresh.py @@ -24,71 +24,73 @@ from core import util class Refresh(clicommand.Command): - """Refresh an existing BSP. - - Removes and re-downloads all packages for a specified device. Note that this - does not update a BSP, and is intended to reset in the event that a BSP has - become somehow messed up. For updating, run: - bdk bsp update - - The software that you are downloading is the property of the software owner - and is distributed by the software owner. Google is providing the download - service as a convenience. - """ - - @staticmethod - def Args(parser): - parser.add_argument('device', help='Device to download BSP for.') - parser.add_argument('-a', '--accept_licenses', action='store_true', - help=argparse.SUPPRESS) - parser.add_argument('-e', '--extract_only', nargs='*', - help='List of tarballs to use directly instead of ' - 'downloading from the remote host ' - 'listed in the manifest.') - parser.add_argument('-l', '--link', action='store_true', - help=argparse.SUPPRESS) - - def Run(self, args): - bsp_manifest = manifest.Manifest.from_json(args.manifest) - - device = bsp_manifest.devices.get(args.device) - if not device: - print 'Unrecognized device name:', args.device - return 1 - - extract_only = {} - if args.extract_only: - extract_only = self.IdentifyTarballs(args.extract_only, device) - if len(extract_only) != len(args.extract_only): - print ('Could not identify all provided tarballs ' - '(successfully identified {}).').format(extract_only.keys()) - return 1 - - os_version = util.GetOSVersion() - link_os = os_version if args.link else '' - - print 'Cleaning up...' - device.uninstall() - print 'Re-installing...' - device.install(extract_only, args.accept_licenses, link_os, verbose=True) - print 'Successfully refreshed {}.'.format(device.name) - return 0 - - def IdentifyTarballs(self, tarballs, device): - """Matches a list of tarballs to their corresponding packages. - - Args: - tarballs: a list of tarball files. - device: the device to match to packages in. - - Returns: - A dictionary mapping { package_name : tarball }. - """ + """Refresh an existing BSP. + + Removes and re-downloads all packages for a specified device. Note that this + does not update a BSP, and is intended to reset in the event that a BSP has + become somehow messed up. For updating, run: + bdk bsp update - mapping = {} - for tarball in tarballs: - package_name = device.match_tarball(tarball) - if package_name: - mapping[package_name] = tarball + The software that you are downloading is the property of the software owner + and is distributed by the software owner. Google is providing the download + service as a convenience. + """ - return mapping + @staticmethod + def Args(parser): + parser.add_argument('device', help='Device to download BSP for.') + parser.add_argument('-a', '--accept_licenses', action='store_true', + help=argparse.SUPPRESS) + parser.add_argument('-e', '--extract_only', nargs='*', + help='List of tarballs to use directly instead of ' + 'downloading from the remote host ' + 'listed in the manifest.') + parser.add_argument('-l', '--link', action='store_true', + help=argparse.SUPPRESS) + + def Run(self, args): + bsp_manifest = manifest.Manifest.from_json(args.manifest) + + device = bsp_manifest.devices.get(args.device) + if not device: + print 'Unrecognized device name:', args.device + return 1 + + extract_only = {} + if args.extract_only: + extract_only = self.IdentifyTarballs(args.extract_only, device) + if len(extract_only) != len(args.extract_only): + print ('Could not identify all provided tarballs ' + '(successfully identified {}).').format( + extract_only.keys()) + return 1 + + os_version = util.GetOSVersion() + link_os = os_version if args.link else '' + + print 'Cleaning up...' + device.uninstall() + print 'Re-installing...' + device.install(extract_only, args.accept_licenses, link_os, + verbose=True) + print 'Successfully refreshed {}.'.format(device.name) + return 0 + + def IdentifyTarballs(self, tarballs, device): + """Matches a list of tarballs to their corresponding packages. + + Args: + tarballs: a list of tarball files. + device: the device to match to packages in. + + Returns: + A dictionary mapping { package_name : tarball }. + """ + + mapping = {} + for tarball in tarballs: + package_name = device.match_tarball(tarball) + if package_name: + mapping[package_name] = tarball + + return mapping diff --git a/cli/lib/commands/bsp/status.py b/cli/lib/commands/bsp/status.py index 959df8c..e55aac1 100644 --- a/cli/lib/commands/bsp/status.py +++ b/cli/lib/commands/bsp/status.py @@ -23,19 +23,19 @@ from core import util class Status(clicommand.Command): - """Get detailed information on the current status of a device BSP.""" + """Get detailed information on the current status of a device BSP.""" - @staticmethod - def Args(parser): - parser.add_argument('device', help='Device to check the BSP status of.') + @staticmethod + def Args(parser): + parser.add_argument('device', help='Device to check the BSP status of.') - def Run(self, args): - bsp_manifest = manifest.Manifest.from_json(args.manifest) + def Run(self, args): + bsp_manifest = manifest.Manifest.from_json(args.manifest) - device = bsp_manifest.devices.get(args.device) - if not device: - print 'Unrecognized device name:', args.device - return 1 + device = bsp_manifest.devices.get(args.device) + if not device: + print 'Unrecognized device name:', args.device + return 1 - print device.status(util.GetOSVersion(), verbose=True)[1] - return 0 + print device.status(util.GetOSVersion(), verbose=True)[1] + return 0 diff --git a/cli/lib/commands/config/__init__.py b/cli/lib/commands/config/__init__.py index 3ac9539..eed06b9 100644 --- a/cli/lib/commands/config/__init__.py +++ b/cli/lib/commands/config/__init__.py @@ -19,4 +19,4 @@ from cli import clicommand class ConfigGroup(clicommand.Group): - """Manage BDK-wide configuration.""" + """Manage BDK-wide configuration.""" diff --git a/cli/lib/commands/config/check.py b/cli/lib/commands/config/check.py index 13732bc..9ccdbdf 100644 --- a/cli/lib/commands/config/check.py +++ b/cli/lib/commands/config/check.py @@ -20,27 +20,26 @@ from cli import clicommand from core import user_config -from core import util class Check(clicommand.Command): - """Check user configuration values.""" - - @staticmethod - def Args(parser): - parser.add_argument('action', choices=user_config.EXPOSED, - nargs='?', default=None, - help='The variable to check the value of.') - - def Run(self, args): - if not args.action: - for var in user_config.EXPOSED: - print '{}:'.format(var) - self._CheckStatus(var, indent=2) - else: - self._CheckStatus(args.action) - return 0 - - def _CheckStatus(self, var, indent=0): - val = getattr(user_config.USER_CONFIG, var) - print ' ' * indent + '{}'.format(val) + """Check user configuration values.""" + + @staticmethod + def Args(parser): + parser.add_argument('action', choices=user_config.EXPOSED, + nargs='?', default=None, + help='The variable to check the value of.') + + def Run(self, args): + if not args.action: + for var in user_config.EXPOSED: + print '{}:'.format(var) + self._CheckStatus(var, indent=2) + else: + self._CheckStatus(args.action) + return 0 + + def _CheckStatus(self, var, indent=0): + val = getattr(user_config.USER_CONFIG, var) + print ' ' * indent + '{}'.format(val) diff --git a/cli/lib/commands/config/set.py b/cli/lib/commands/config/set.py index 389d565..0c5a814 100644 --- a/cli/lib/commands/config/set.py +++ b/cli/lib/commands/config/set.py @@ -22,22 +22,21 @@ import os from cli import clicommand from core import user_config -from core import util class Set(clicommand.Command): - """Set configuration values.""" - - @staticmethod - def Args(parser): - parser.add_argument('option', choices=user_config.EXPOSED, - help='The variable to set.') - parser.add_argument('value', help='The value to set the option to.') - - def Run(self, args): - value = args.value - if value and args.option in user_config.PATHS: - # Make paths absolute if being set to something non-empty. - value = os.path.abspath(value) - setattr(user_config.USER_CONFIG, args.option, value) - return 0 + """Set configuration values.""" + + @staticmethod + def Args(parser): + parser.add_argument('option', choices=user_config.EXPOSED, + help='The variable to set.') + parser.add_argument('value', help='The value to set the option to.') + + def Run(self, args): + value = args.value + if value and args.option in user_config.PATHS: + # Make paths absolute if being set to something non-empty. + value = os.path.abspath(value) + setattr(user_config.USER_CONFIG, args.option, value) + return 0 diff --git a/cli/lib/commands/product/__init__.py b/cli/lib/commands/product/__init__.py index 6811dfe..d8abda6 100644 --- a/cli/lib/commands/product/__init__.py +++ b/cli/lib/commands/product/__init__.py @@ -19,4 +19,4 @@ from cli import clicommand class ProductGroup(clicommand.Group): - """Manage Brillo products.""" + """Manage Brillo products.""" diff --git a/cli/lib/commands/product/build.py b/cli/lib/commands/product/build.py index 5fe6766..aad3c3b 100644 --- a/cli/lib/commands/product/build.py +++ b/cli/lib/commands/product/build.py @@ -22,87 +22,91 @@ import os from bsp import manifest from cli import clicommand from commands.product import constants +from core import config from core import tool from core import util class Build(clicommand.Command): - """Build a product project from the current directory.""" - - @staticmethod - def Args(parser): - parser.add_argument('-s', '--submodule', action='store_true', - help='Build the submodule in the current directory') - parser.add_argument('-p', '--product_path', default=util.GetProductDir(), - required=False, help='Path to the root of the product') - parser.add_argument('-b', '--buildtype', default=None, required=False, - choices=['eng', 'userdebug', 'user'], - help='Override the configured type of build to perform') - parser.add_argument('make_args', nargs=argparse.REMAINDER, - help='Arguments to pass through to make') - - def Run(self, args): - sdk_path = util.GetBDKPath() - - if args.product_path is None: - print constants.MSG_NO_PRODUCT_PATH - return 1 - - store = config.ProductFileStore(args.product_path) - - # Get the device so the BSP can be linked. - manifest_ = manifest.Manifest.from_json() - if not manifest_.is_bsp_available(store.device): - print ('BSP for "{0}" is not downloaded. ' - 'Please run `bdk bsp download {0}`.'.format( - store.device)) - return 1 - device = manifest_.devices[store.device] - - # Pull the buildtype from the config if it is not overridden. - if args.buildtype is None: - args.buildtype = store.bdk.buildtype - - no_java = 'BRILLO_NO_JAVA=0' - if len(store.bdk.java) and store.bdk.java != '1': - no_java = 'BRILLO_NO_JAVA=1' - - # This should only happen if the ProductFileStore is incomplete. - if not args.buildtype: - args.buildtype = 'userdebug' - - # Don't pass along the first '--' since it was meant for argparse. - if args.make_args.count('--'): - args.make_args.remove('--') - - envcmd = 'make' - - make = tool.BrunchToolWrapper(store, args.product_path, 'make') - wrap_makefile = os.path.join(sdk_path, 'build/wrap-product.mk') - buildtype = 'BUILDTYPE=%s' % args.buildtype - full_make_args = [] - if args.submodule == True: - print "Building submodule only . . ." - here = 'HERE=%s' % os.getcwd() - full_make_args = ['-f', wrap_makefile, - no_java, here, buildtype, - 'ENVCMD=mm'] + args.make_args - envcmd = 'mm' - else: - # Change to the product path and build the whole product. - make.set_cwd(args.product_path) - full_make_args = ['-f', wrap_makefile, - no_java, buildtype] + args.make_args - - # Determine the envcmd for reporting purposes. - for arg in args.make_args: - split_arg = arg.split('=') - if split_arg[0] == 'ENVCMD' and len(split_arg) > 1: - envcmd = split_arg[1] - self.SetMetricsLabel(envcmd) - # TODO(arihc)(b/25952600): Some way to also prevent or at least filter - # metrics for build --help - - with device.linked(util.GetOSVersion()): - make.run(full_make_args) - - return 0 + """Build a product project from the current directory.""" + + @staticmethod + def Args(parser): + parser.add_argument('-s', '--submodule', action='store_true', + help='Build the submodule in the current ' + 'directory.') + parser.add_argument('-p', '--product_path', + default=util.GetProductDir(), + required=False, + help='Path to the root of the product.') + parser.add_argument('-b', '--buildtype', default=None, required=False, + choices=['eng', 'userdebug', 'user'], + help='Override the configured type of build to ' + 'perform.') + parser.add_argument('make_args', nargs=argparse.REMAINDER, + help='Arguments to pass through to make.') + + def Run(self, args): + sdk_path = util.GetBDKPath() + + if args.product_path is None: + print constants.MSG_NO_PRODUCT_PATH + return 1 + + store = config.ProductFileStore(args.product_path) + + # Get the device so the BSP can be linked. + manifest_ = manifest.Manifest.from_json() + if not manifest_.is_bsp_available(store.device): + print ('BSP for "{0}" is not downloaded. ' + 'Please run `bdk bsp download {0}`.'.format(store.device)) + return 1 + device = manifest_.devices[store.device] + + # Pull the buildtype from the config if it is not overridden. + if args.buildtype is None: + args.buildtype = store.bdk.buildtype + + no_java = 'BRILLO_NO_JAVA=0' + if len(store.bdk.java) and store.bdk.java != '1': + no_java = 'BRILLO_NO_JAVA=1' + + # This should only happen if the ProductFileStore is incomplete. + if not args.buildtype: + args.buildtype = 'userdebug' + + # Don't pass along the first '--' since it was meant for argparse. + if args.make_args.count('--'): + args.make_args.remove('--') + + envcmd = 'make' + + make = tool.BrunchToolWrapper(store, args.product_path, 'make') + wrap_makefile = os.path.join(sdk_path, 'build/wrap-product.mk') + buildtype = 'BUILDTYPE=%s' % args.buildtype + full_make_args = [] + if args.submodule == True: + print "Building submodule only . . ." + here = 'HERE=%s' % os.getcwd() + full_make_args = ['-f', wrap_makefile, + no_java, here, buildtype, + 'ENVCMD=mm'] + args.make_args + envcmd = 'mm' + else: + # Change to the product path and build the whole product. + make.set_cwd(args.product_path) + full_make_args = ['-f', wrap_makefile, + no_java, buildtype] + args.make_args + + # Determine the envcmd for reporting purposes. + for arg in args.make_args: + split_arg = arg.split('=') + if split_arg[0] == 'ENVCMD' and len(split_arg) > 1: + envcmd = split_arg[1] + self.SetMetricsLabel(envcmd) + # TODO(arihc)(b/25952600): Some way to also prevent or at least filter + # metrics for build --help + + with device.linked(util.GetOSVersion()): + make.run(full_make_args) + + return 0 diff --git a/cli/lib/commands/product/create.py b/cli/lib/commands/product/create.py index 1533793..c830477 100644 --- a/cli/lib/commands/product/create.py +++ b/cli/lib/commands/product/create.py @@ -24,28 +24,28 @@ from core import util class Create(clicommand.Command): - """Create a product project in the current directory.""" - - @staticmethod - def Args(parser): - parser.add_argument('name', help='Product name') - # TODO(wad, arihc)(b/25670466) populate BSP choices here if possible. - parser.add_argument('device', help='Device name (BSP)') - parser.add_argument('-v', '--vendor', default='novendor', - help='Product vendor name') - - def Run(self, args): - print 'Creating product "%s" . . .' % args.name - - os_path = util.DEPRECATED_GetDefaultOSPath() - proj_path = os.path.abspath(args.name) - if proj_path.startswith(os_path + os.path.sep): - print 'Error: Products must be created outside of the OS tree.' - return 1 - - p = product.ProductCreator(args.name, args.vendor, args.device) - if p.exists(): - print 'Product "%s" already exists' % args.name - return 1 - p.create() - return 0 + """Create a product project in the current directory.""" + + @staticmethod + def Args(parser): + parser.add_argument('name', help='Product name') + # TODO(wad, arihc)(b/25670466) populate BSP choices here if possible. + parser.add_argument('device', help='Device name (BSP)') + parser.add_argument('-v', '--vendor', default='novendor', + help='Product vendor name') + + def Run(self, args): + print 'Creating product "%s" . . .' % args.name + + os_path = util.DEPRECATED_GetDefaultOSPath() + proj_path = os.path.abspath(args.name) + if proj_path.startswith(os_path + os.path.sep): + print 'Error: Products must be created outside of the OS tree.' + return 1 + + p = product.ProductCreator(args.name, args.vendor, args.device) + if p.exists(): + print 'Product "%s" already exists' % args.name + return 1 + p.create() + return 0 diff --git a/cli/lib/commands/product/envsetup.py b/cli/lib/commands/product/envsetup.py index 8804909..f930b0a 100644 --- a/cli/lib/commands/product/envsetup.py +++ b/cli/lib/commands/product/envsetup.py @@ -25,31 +25,32 @@ from core import product from core import util class Envsetup(clicommand.Command): - """Generate the environment for the product in the CWD.""" + """Generate the environment for the product in the CWD.""" - @staticmethod - def Args(parser): - # TODO(wad)(b/25951098): Set the current version here. - parser.add_argument('-p', '--product_path', default=util.GetProductDir(), - help='Path to the product') - parser.add_argument('--generate', required=False, default=False, - action='store_true', - help='If true, outputs the envsetup.sh file') - # TODO(wad)(b/25951597): Add 'shell' argument to select a non-sh format. + @staticmethod + def Args(parser): + # TODO(wad)(b/25951098): Set the current version here. + parser.add_argument('-p', '--product_path', + default=util.GetProductDir(), + help='Path to the product') + parser.add_argument('--generate', required=False, default=False, + action='store_true', + help='If true, outputs the envsetup.sh file') + # TODO(wad)(b/25951597): Add 'shell' argument to select a non-sh format. - def Run(self, args): - if args.product_path is None: - print constants.MSG_NO_PRODUCT_PATH - return 1 + def Run(self, args): + if args.product_path is None: + print constants.MSG_NO_PRODUCT_PATH + return 1 - # As product_path will end up in the shell environment, we can't - # rely on a relative path being safe for reinvocation. - product_path = os.path.abspath(args.product_path) - store = config.ProductFileStore(product_path) - env = product.Environment(store, product_path) - if args.generate is False: - print env.environment() - else: - print 'Generating envsetup.sh . . .' - env.envsetup() - return 0 + # As product_path will end up in the shell environment, we can't + # rely on a relative path being safe for reinvocation. + product_path = os.path.abspath(args.product_path) + store = config.ProductFileStore(product_path) + env = product.Environment(store, product_path) + if args.generate is False: + print env.environment() + else: + print 'Generating envsetup.sh . . .' + env.envsetup() + return 0 diff --git a/cli/lib/commands/product/gdb.py b/cli/lib/commands/product/gdb.py index 31bbb81..877749b 100644 --- a/cli/lib/commands/product/gdb.py +++ b/cli/lib/commands/product/gdb.py @@ -28,85 +28,88 @@ from core import tool from core import util class Gdb(clicommand.Command): - """Run gdbclient.py for a given product.""" - - @staticmethod - def Args(parser): - parser.add_argument('-p', '--product_path', default=util.GetProductDir(), - help='Path to the root of the product') - parser.add_argument('args', nargs=argparse.REMAINDER, - help='Arguments to pass through to gdbclient.py') - - def LinkToSymbols(self, out_dir, device): - """Creates a symlink to the symbols directory. - - Args: - out_dir: path to the product out/ directory. - device: device name. - """ - built_symbols_path = os.path.join( - out_dir, 'out-' + device, 'target', 'product', device, 'symbols') - gdb_symbols_dir = os.path.join( - out_dir, '.bdk', 'out', 'target', 'product', device) - gdb_symbols_path = os.path.join(gdb_symbols_dir, 'symbols') - - if os.path.exists(gdb_symbols_path): - # Blow away whatever might be blocking the symlink we need. This is in - # the .bdk dir so the user shouldn't be keeping anything important here. - try: - os.remove(gdb_symbols_path) - except OSError: - # OSError means |gdb_symbols_path| is being blocked by a directory. - shutil.rmtree(gdb_symbols_path, ignore_errors=True) - elif not os.path.exists(gdb_symbols_dir): - os.makedirs(gdb_symbols_dir) - os.symlink(built_symbols_path, gdb_symbols_path) - - def Run(self, args): - if args.product_path is None: - print constants.MSG_NO_PRODUCT_PATH - return 1 - - # We have to add '--' in product_templates to prevent argparse from trying - # to slurp up arguments meant for gdbclient.py, but we need to remove it - # now or else gdbclient.py will also treat it as a signal to clump the - # remaining args. - if args.args and args.args[0] == '--': - args.args.pop(0) - - store = config.ProductFileStore(args.product_path) - - adb = tool.BrunchHostToolWrapper(store, args.product_path, 'adb') - if not adb.exists(): - print 'The product must be built once prior to using gdbclient.py.' - return 1 - - device = store.device - out_dir = os.path.join(args.product_path, 'out') - - try: - self.LinkToSymbols(out_dir, device) - except IOError as e: - print 'Failed to create symlink to built symbols: ' + str(e) - return 1 - - os_path = util.DEPRECATED_GetDefaultOSPath() - makefile_path = util.GetBDKPath('build', 'wrap-gdb.mk') - - make = tool.BrunchToolWrapper(store, args.product_path, 'make') - # Ignore SIGINT, otherwise both this process and the gdb subprocess will - # receive the signal, causing this script to exit instead of just pausing - # gdb as the user intended. - sigint_handler = signal.signal(signal.SIGINT, signal.SIG_IGN) - try: - make.run(['make', '-f', makefile_path, 'gdbclient', - 'BDK_PATH=' + os_path, - 'PRODUCT_BDK=' + os.path.join(out_dir, '.bdk'), - 'PRODUCT_NAME=' + store.name, - 'BUILDTYPE=' + store.bdk.buildtype, - 'ADB_PATH=' + adb.path(), - 'GDBCLIENT_ARGS=' + util.AsShellArgs(args.args)]) - finally: - signal.signal(signal.SIGINT, sigint_handler) - - return 0 + """Run gdbclient.py for a given product.""" + + @staticmethod + def Args(parser): + parser.add_argument('-p', '--product_path', + default=util.GetProductDir(), + help='Path to the root of the product') + parser.add_argument('args', nargs=argparse.REMAINDER, + help='Arguments to pass through to gdbclient.py') + + def LinkToSymbols(self, out_dir, device): + """Creates a symlink to the symbols directory. + + Args: + out_dir: path to the product out/ directory. + device: device name. + """ + built_symbols_path = os.path.join( + out_dir, 'out-' + device, 'target', 'product', device, 'symbols') + gdb_symbols_dir = os.path.join( + out_dir, '.bdk', 'out', 'target', 'product', device) + gdb_symbols_path = os.path.join(gdb_symbols_dir, 'symbols') + + if os.path.exists(gdb_symbols_path): + # Blow away whatever might be blocking the symlink we need. This is + # in the .bdk dir so the user shouldn't be keeping anything + # important here. + try: + os.remove(gdb_symbols_path) + except OSError: + # OSError means |gdb_symbols_path| is being blocked by a + # directory. + shutil.rmtree(gdb_symbols_path, ignore_errors=True) + elif not os.path.exists(gdb_symbols_dir): + os.makedirs(gdb_symbols_dir) + os.symlink(built_symbols_path, gdb_symbols_path) + + def Run(self, args): + if args.product_path is None: + print constants.MSG_NO_PRODUCT_PATH + return 1 + + # We have to add '--' in product_templates to prevent argparse from + # trying to slurp up arguments meant for gdbclient.py, but we need to + # remove it now or else gdbclient.py will also treat it as a signal to + # clump the remaining args. + if args.args and args.args[0] == '--': + args.args.pop(0) + + store = config.ProductFileStore(args.product_path) + + adb = tool.BrunchHostToolWrapper(store, args.product_path, 'adb') + if not adb.exists(): + print 'The product must be built once prior to using gdbclient.py.' + return 1 + + device = store.device + out_dir = os.path.join(args.product_path, 'out') + + try: + self.LinkToSymbols(out_dir, device) + except IOError as e: + print 'Failed to create symlink to built symbols: ' + str(e) + return 1 + + os_path = util.DEPRECATED_GetDefaultOSPath() + makefile_path = util.GetBDKPath('build', 'wrap-gdb.mk') + + make = tool.BrunchToolWrapper(store, args.product_path, 'make') + # Ignore SIGINT, otherwise both this process and the gdb subprocess will + # receive the signal, causing this script to exit instead of just + # pausing gdb as the user intended. + sigint_handler = signal.signal(signal.SIGINT, signal.SIG_IGN) + try: + make.run(['make', '-f', makefile_path, 'gdbclient', + 'BDK_PATH=' + os_path, + 'PRODUCT_BDK=' + os.path.join(out_dir, '.bdk'), + 'PRODUCT_NAME=' + store.name, + 'BUILDTYPE=' + store.bdk.buildtype, + 'ADB_PATH=' + adb.path(), + 'GDBCLIENT_ARGS=' + util.AsShellArgs(args.args)]) + finally: + signal.signal(signal.SIGINT, sigint_handler) + + return 0 diff --git a/cli/lib/commands/product/provision.py b/cli/lib/commands/product/provision.py index c30cc7d..50bc965 100644 --- a/cli/lib/commands/product/provision.py +++ b/cli/lib/commands/product/provision.py @@ -26,46 +26,47 @@ from core import tool from core import util class Provision(clicommand.Command): - """Run provision-device for a given product.""" + """Run provision-device for a given product.""" - @staticmethod - def Args(parser): - parser.add_argument('-p', '--product_path', default=util.GetProductDir(), - help='Path to the root of the product') - # Workaround for https://bugs.python.org/issue17050 - # Need to specifically handle -s argument - parser.add_argument('-s', metavar='<specific device>', default=None, - help='Provision a specific device') - parser.add_argument('args', nargs=argparse.REMAINDER, - help='Arguments to pass through to the tool') + @staticmethod + def Args(parser): + parser.add_argument('-p', '--product_path', + default=util.GetProductDir(), + help='Path to the root of the product') + # Workaround for https://bugs.python.org/issue17050 + # Need to specifically handle -s argument + parser.add_argument('-s', metavar='<specific device>', default=None, + help='Provision a specific device') + parser.add_argument('args', nargs=argparse.REMAINDER, + help='Arguments to pass through to the tool') - def Run(self, args): - if args.product_path is None: - print constants.MSG_NO_PRODUCT_PATH - return 1 + def Run(self, args): + if args.product_path is None: + print constants.MSG_NO_PRODUCT_PATH + return 1 - store = config.ProductFileStore(args.product_path) + store = config.ProductFileStore(args.product_path) - t = tool.BrunchTargetToolWrapper(store, args.product_path, - 'provision-device') - if not t.exists(): - print 'The product must be built once prior to using provision.' - return 1 + t = tool.BrunchTargetToolWrapper(store, args.product_path, + 'provision-device') + if not t.exists(): + print 'The product must be built once prior to using provision.' + return 1 - # We have to export the host tools because provision-device - # expects them in its path. - ht = tool.BrunchHostToolWrapper(store, args.product_path, 'dummy') - # Grab the tool path from the dummy tool. - path_str = '%s%s' % (os.path.dirname(ht.path()), os.pathsep) - if t.environment.has_key('PATH'): - # The BrunchToolWrapper merges in the calling environment, so - # we should always just be prefixing. - t.environment['PATH'] = path_str + t.environment['PATH'] - else: - print ('No PATH found in the environment! ' - 'Please set a PATH and call again.') - return 1 - if args.s is not None: - args.args += ['-s', args.s] - t.run(args.args) - return 0 + # We have to export the host tools because provision-device + # expects them in its path. + ht = tool.BrunchHostToolWrapper(store, args.product_path, 'dummy') + # Grab the tool path from the dummy tool. + path_str = '%s%s' % (os.path.dirname(ht.path()), os.pathsep) + if t.environment.has_key('PATH'): + # The BrunchToolWrapper merges in the calling environment, so + # we should always just be prefixing. + t.environment['PATH'] = path_str + t.environment['PATH'] + else: + print ('No PATH found in the environment! ' + 'Please set a PATH and call again.') + return 1 + if args.s is not None: + args.args += ['-s', args.s] + t.run(args.args) + return 0 diff --git a/cli/lib/commands/product/tool.py b/cli/lib/commands/product/tool.py index 0853ea1..58c12ff 100644 --- a/cli/lib/commands/product/tool.py +++ b/cli/lib/commands/product/tool.py @@ -28,38 +28,42 @@ from core import util class Tool(clicommand.Command): - """Run a host tool for a given product.""" - _TOOL_ENV_CMD = 'env' + """Run a host tool for a given product.""" + _TOOL_ENV_CMD = 'env' - @staticmethod - def Args(parser): - parser.add_argument('tool', choices=['adb', 'fastboot', Tool._TOOL_ENV_CMD], - help='Product host tool to execute') - parser.add_argument('-p', '--product_path', default=util.GetProductDir(), - help='Path to the root of the product') - parser.add_argument('args', nargs=argparse.REMAINDER, - help='Arguments to pass through to the tool') + @staticmethod + def Args(parser): + parser.add_argument('tool', + choices=['adb', 'fastboot', Tool._TOOL_ENV_CMD], + help='Product host tool to execute') + parser.add_argument('-p', '--product_path', + default=util.GetProductDir(), + help='Path to the root of the product') + parser.add_argument('args', nargs=argparse.REMAINDER, + help='Arguments to pass through to the tool') - def Run(self, args): - if args.product_path is None: - print constants.MSG_NO_PRODUCT_PATH - return 1 + def Run(self, args): + if args.product_path is None: + print constants.MSG_NO_PRODUCT_PATH + return 1 - store = config.ProductFileStore(args.product_path) - t = tool.BrunchHostToolWrapper(store, args.product_path, args.tool) + store = config.ProductFileStore(args.product_path) + t = tool.BrunchHostToolWrapper(store, args.product_path, args.tool) - # Allow the fake toolenv command to pass through for introspection. - if args.tool == self._TOOL_ENV_CMD: - print "Product path: %s" % args.product_path - print "Tool path: %s" % t.path() - print "Tool environment:" - pprint.pprint(t.environment) - print "Allowed passthrough environment: %s" % store.bdk.allowed_environ - return 0 + # Allow the fake toolenv command to pass through for introspection. + if args.tool == self._TOOL_ENV_CMD: + print 'Product path: {}'.format(args.product_path) + print 'Tool path: {}'.format(t.path()) + print 'Tool environment:' + pprint.pprint(t.environment) + print 'Allowed passthrough environment: {}'.format( + store.bdk.allowed_environ) + return 0 - if not t.exists(): - print 'The product must be built once prior to using %s.' % args.tool - return 1 + if not t.exists(): + print 'The product must be built once prior to using {}.'.format( + args.tool) + return 1 - t.run(args.args) - return 0 + t.run(args.args) + return 0 diff --git a/cli/lib/commands/root/__init__.py b/cli/lib/commands/root/__init__.py index 892a4b3..4ffccc1 100644 --- a/cli/lib/commands/root/__init__.py +++ b/cli/lib/commands/root/__init__.py @@ -19,4 +19,4 @@ from cli import clicommand class BdkRoot(clicommand.Group): - """Manage Brillo product development flow.""" + """Manage Brillo product development flow.""" diff --git a/cli/lib/commands/root/help.py b/cli/lib/commands/root/help.py index b730faa..dee9a2b 100644 --- a/cli/lib/commands/root/help.py +++ b/cli/lib/commands/root/help.py @@ -19,12 +19,12 @@ from cli import clicommand class Help(clicommand.Command): - """Information on how to use the BDK.""" + """Information on how to use the BDK.""" - @staticmethod - def Args(parser): - pass + @staticmethod + def Args(parser): + pass - def Run(self, args): - print "For help at any level of brunch, use the '-h' argument." - return 0 + def Run(self, args): + print "For help at any level of brunch, use the '-h' argument." + return 0 diff --git a/cli/lib/commands/root/version.py b/cli/lib/commands/root/version.py index 66596fc..76518e2 100644 --- a/cli/lib/commands/root/version.py +++ b/cli/lib/commands/root/version.py @@ -20,8 +20,8 @@ from cli import clicommand from core import util class Version(clicommand.Command): - """Print version info.""" + """Print version info.""" - def Run(self, args): - print util.GetBDKVersion() - return 0 + def Run(self, args): + print util.GetBDKVersion() + return 0 diff --git a/cli/lib/commands/v2/build/__init__.py b/cli/lib/commands/v2/build/__init__.py index 7acc079..825b005 100644 --- a/cli/lib/commands/v2/build/__init__.py +++ b/cli/lib/commands/v2/build/__init__.py @@ -20,4 +20,4 @@ from cli import clicommand from core import util class BuildGroup(clicommand.Group): - """Brillo build commands.""" + """Brillo build commands.""" diff --git a/cli/lib/commands/v2/build/platform.py b/cli/lib/commands/v2/build/platform.py index be8d5f4..9f79352 100644 --- a/cli/lib/commands/v2/build/platform.py +++ b/cli/lib/commands/v2/build/platform.py @@ -24,46 +24,46 @@ from selinux import policy class Platform(clicommand.Command): - """Build a Brillo platform.""" + """Build a Brillo platform.""" - remainder_arg = ('args', 'Arguments to pass through to make.') + remainder_arg = ('args', 'Arguments to pass through to make.') - @staticmethod - def Args(parser): - Platform.AddProductArgs(parser) + @staticmethod + def Args(parser): + Platform.AddProductArgs(parser) - def Run(self, args): - """Runs the platform build. + def Run(self, args): + """Runs the platform build. - Returns: - 0 if successful, an exit code otherwise. - """ - try: - _, target = self.GetSpecAndTarget(args) - except clicommand.Error as error: - print str(error) - return 1 + Returns: + 0 if successful, an exit code otherwise. + """ + try: + _, target = self.GetSpecAndTarget(args) + except clicommand.Error as error: + print str(error) + return 1 - platform_dir = target.platform_build_cache() - try: - # Build the platform cache. - ret = build.BuildPlatform(target, platform_dir, args.args) + platform_dir = target.platform_build_cache() + try: + # Build the platform cache. + ret = build.BuildPlatform(target, platform_dir, args.args) - # Obtain and cache SELinux information. - # GetBoardComboSepolicyDirs() will either raise an exception or return a - # valid value, so no need to update |ret|. - sepolicy_dirs = policy.GetBoardComboSepolicyDirs(target) - policy.SaveSepolicyDirsCache(platform_dir, sepolicy_dirs) + # Obtain and cache SELinux information. + # GetBoardComboSepolicyDirs() will either raise an exception or + # return a valid value, so no need to update |ret|. + sepolicy_dirs = policy.GetBoardComboSepolicyDirs(target) + policy.SaveSepolicyDirsCache(platform_dir, sepolicy_dirs) - except build.BuildUtilityError as e: - print 'Failed to build platform: {}'.format(e) - return 1 - except policy.SELinuxCommandError as e: - print 'Failed to build platform: SELinux policy error: {}'.format(e) - return 1 + except build.BuildUtilityError as e: + print 'Failed to build platform: {}'.format(e) + return 1 + except policy.SELinuxCommandError as e: + print 'Failed to build platform: SELinux policy error: {}'.format(e) + return 1 - if ret: - print 'Failed to build platform: unknown error code {}'.format(ret) - else: - print 'Successfully built platform in {}'.format(platform_dir) - return ret + if ret: + print 'Failed to build platform: unknown error code {}'.format(ret) + else: + print 'Successfully built platform in {}'.format(platform_dir) + return ret diff --git a/cli/lib/commands/v2/environment/__init__.py b/cli/lib/commands/v2/environment/__init__.py index 5e20e32..bc4b3b5 100644 --- a/cli/lib/commands/v2/environment/__init__.py +++ b/cli/lib/commands/v2/environment/__init__.py @@ -19,4 +19,4 @@ from cli import clicommand class EnvironmentGroup(clicommand.Group): - """Manage Brillo developer environments.""" + """Manage Brillo developer environments.""" diff --git a/cli/lib/commands/v2/environment/setup.py b/cli/lib/commands/v2/environment/setup.py index 6f8fa2d..af88bed 100644 --- a/cli/lib/commands/v2/environment/setup.py +++ b/cli/lib/commands/v2/environment/setup.py @@ -53,118 +53,125 @@ clean: class Setup(clicommand.Command): - """Set up a sysroot in the given directory.""" - - @staticmethod - def Args(parser): - Setup.AddProductArgs(parser) - parser.add_argument('--pkgconfig_csv', - help='The path to a csv file describing packages for ' - 'the sysroot (default {}).'.format( - util.GetBDKPath('pkgconfig', 'packages.csv')), - default=util.GetBDKPath('pkgconfig', 'packages.csv')) - parser.add_argument('--sysroot_dir', - help='The directory to generate the sysroot in. ' - '(default {}/sysroot).'.format( - util.PLATFORM_CACHE_FORMAT)) - parser.add_argument('--toolchain_dir', - help='The directory to generate the toolchain in. ' - '(default {}/toolchain).'.format( - util.PLATFORM_CACHE_FORMAT)) - - def Run(self, args): - """Sets up a sysroot and toolchain.""" - try: - _, target = self.GetSpecAndTarget(args) - except clicommand.Error as error: - print(error) - return 1 - device_ = target.get_device() - - # TODO(b/27385334): maybe toolchain/sysroot setup should really be different - # commands, with a helper command that invokes both. Alternatively, - # they could work together better such as by adding the necessary flags - # to use the sysroot into the tools. - - # Check args. - platform_build_cache = target.platform_build_cache() - product_out = util.GetAndroidProductOut(platform_build_cache, target.board) - if not os.path.isdir(product_out): - print('Could not find platform build output "{}". ' - 'You must run\n' - ' bdk build platform\n' - 'before you set up your build environment.'.format(product_out)) - return 1 - if device_.arch not in sysroot_util.SysrootUtil.DEFAULT_ARCH_INCLUDES: - print('Unknown architecture: {}'.format(device_.arch)) - return 1 - if not os.path.isfile(args.pkgconfig_csv): - print('No such file: {}'.format(args.pkgconfig_csv)) - return 1 - try: - host_arch = util.GetHostArch() - except util.HostUnsupportedArchError as e: - print('Could not set up environment: {}'.format(e)) - return 1 - - # Basic values. - shared_libs = os.path.join(product_out, 'obj', 'lib') - static_libs = os.path.join(product_out, 'obj', 'STATIC_LIBRARIES') - - # TODO(b/27458309): determine an actual location for this. - board_packages = util.GetOSPath(target.os_version, - 'device', device_.vendor, target.board, - 'developer', 'packages.csv') - sysroot_path = args.sysroot_dir or target.platform_cache('sysroot') - toolchain_path = args.toolchain_dir or target.platform_cache('toolchain') - - ret = 0 - # Generate the sysroot. - if os.path.exists(sysroot_path): - print ('Not generating sysroot: ' - 'something already exists at {}.'.format(sysroot_path)) - else: - sysroot_success = False - brillo_sysroot = sysroot.Sysroot(sysroot_path) - setup_util = sysroot_util.SysrootUtil(brillo_sysroot, target.os_version) - # Setup from a base, add libs. - try: - setup_util.SetupBaseSysroot(device_.arch, shared_libs, static_libs) - setup_util.AddSharedLibsFromCSV(shared_libs, args.pkgconfig_csv) - # Add board libs, if any - with device_.linked(target.os_version): - if os.path.isfile(board_packages): - setup_util.AddSharedLibsFromCSV(shared_libs, board_packages, - suffix=target.board) - sysroot_success = True - except (IOError, ValueError, device.Error) as e: - print('Failed to generate sysroot: {}'.format(e)) - finally: - if not sysroot_success: - ret = 1 - brillo_sysroot.Destroy() - - # Generate toolchain. - if os.path.exists(toolchain_path): - print('Not generating toolchain: ' - 'something already exists at {}.'.format(toolchain_path)) - else: - toolchain_success = False - try: - os.makedirs(toolchain_path) - toolchain_util.GenerateToolchain(target.os_version, host_arch, - device_.arch, toolchain_path) - toolchain_success = True - except toolchain_util.Error as e: - print('Failed to generate toolchain: {}'.format(e)) - finally: - if not toolchain_success: - ret = 1 - shutil.rmtree(toolchain_path) - - if not ret: - print('Finished building environment.') - print('Sample Makefile:\n\n' + SAMPLE_MAKEFILE_TEMPLATE.format( - sysroot=sysroot_path, toolchain=toolchain_path)) - - return ret + """Set up a sysroot in the given directory.""" + + @staticmethod + def Args(parser): + Setup.AddProductArgs(parser) + parser.add_argument('--pkgconfig_csv', + help='The path to a csv file describing packages ' + 'for the sysroot (default {}).'.format( + util.GetBDKPath('pkgconfig', 'packages.csv')), + default=util.GetBDKPath('pkgconfig', + 'packages.csv')) + parser.add_argument('--sysroot_dir', + help='The directory to generate the sysroot in. ' + '(default {}/sysroot).'.format( + util.PLATFORM_CACHE_FORMAT)) + parser.add_argument('--toolchain_dir', + help='The directory to generate the toolchain in. ' + '(default {}/toolchain).'.format( + util.PLATFORM_CACHE_FORMAT)) + + def Run(self, args): + """Sets up a sysroot and toolchain.""" + try: + _, target = self.GetSpecAndTarget(args) + except clicommand.Error as error: + print(error) + return 1 + device_ = target.get_device() + + # TODO(b/27385334): maybe toolchain/sysroot setup should really be + # different commands, with a helper command that invokes both. + # Alternatively, they could work together better such as by adding + # the necessary flags to use the sysroot into the tools. + + # Check args. + platform_build_cache = target.platform_build_cache() + product_out = util.GetAndroidProductOut(platform_build_cache, + target.board) + if not os.path.isdir(product_out): + print('Could not find platform build output "{}". ' + 'You must run\n' + ' bdk build platform\n' + 'before you set up your build environment.'.format( + product_out)) + return 1 + if device_.arch not in sysroot_util.SysrootUtil.DEFAULT_ARCH_INCLUDES: + print('Unknown architecture: {}'.format(device_.arch)) + return 1 + if not os.path.isfile(args.pkgconfig_csv): + print('No such file: {}'.format(args.pkgconfig_csv)) + return 1 + try: + host_arch = util.GetHostArch() + except util.HostUnsupportedArchError as e: + print('Could not set up environment: {}'.format(e)) + return 1 + + # Basic values. + shared_libs = os.path.join(product_out, 'obj', 'lib') + static_libs = os.path.join(product_out, 'obj', 'STATIC_LIBRARIES') + + # TODO(b/27458309): determine an actual location for this. + board_packages = util.GetOSPath(target.os_version, + 'device', device_.vendor, target.board, + 'developer', 'packages.csv') + sysroot_path = args.sysroot_dir or target.platform_cache('sysroot') + toolchain_path = (args.toolchain_dir or + target.platform_cache('toolchain')) + + ret = 0 + # Generate the sysroot. + if os.path.exists(sysroot_path): + print ('Not generating sysroot: ' + 'something already exists at {}.'.format(sysroot_path)) + else: + sysroot_success = False + brillo_sysroot = sysroot.Sysroot(sysroot_path) + setup_util = sysroot_util.SysrootUtil(brillo_sysroot, + target.os_version) + # Setup from a base, add libs. + try: + setup_util.SetupBaseSysroot(device_.arch, shared_libs, + static_libs) + setup_util.AddSharedLibsFromCSV(shared_libs, args.pkgconfig_csv) + # Add board libs, if any + with device_.linked(target.os_version): + if os.path.isfile(board_packages): + setup_util.AddSharedLibsFromCSV(shared_libs, + board_packages, + suffix=target.board) + sysroot_success = True + except (IOError, ValueError, device.Error) as e: + print('Failed to generate sysroot: {}'.format(e)) + finally: + if not sysroot_success: + ret = 1 + brillo_sysroot.Destroy() + + # Generate toolchain. + if os.path.exists(toolchain_path): + print('Not generating toolchain: ' + 'something already exists at {}.'.format(toolchain_path)) + else: + toolchain_success = False + try: + os.makedirs(toolchain_path) + toolchain_util.GenerateToolchain(target.os_version, host_arch, + device_.arch, toolchain_path) + toolchain_success = True + except toolchain_util.Error as e: + print('Failed to generate toolchain: {}'.format(e)) + finally: + if not toolchain_success: + ret = 1 + shutil.rmtree(toolchain_path) + + if not ret: + print('Finished building environment.') + print('Sample Makefile:\n\n' + SAMPLE_MAKEFILE_TEMPLATE.format( + sysroot=sysroot_path, toolchain=toolchain_path)) + + return ret diff --git a/cli/lib/commands/v2/root/__init__.py b/cli/lib/commands/v2/root/__init__.py index 87c24b1..39abe5f 100644 --- a/cli/lib/commands/v2/root/__init__.py +++ b/cli/lib/commands/v2/root/__init__.py @@ -19,4 +19,4 @@ from cli import clicommand class BdkRoot(clicommand.Group): - """Manage Brillo product development flow.""" + """Manage Brillo product development flow.""" diff --git a/cli/lib/commands/v2/root/adb.py b/cli/lib/commands/v2/root/adb.py index 813bcf5..857ac5c 100644 --- a/cli/lib/commands/v2/root/adb.py +++ b/cli/lib/commands/v2/root/adb.py @@ -24,36 +24,36 @@ from core import tool class Adb(clicommand.Command): - """Calls the adb executable.""" - - remainder_arg = ('args', 'Arguments to pass through to adb.') - - @staticmethod - def Args(parser): - Adb.AddProductArgs(parser) - - def Run(self, args): - """Runs adb. - - Args: - args: parsed argparse namespace. - - Returns: - 0 if successful, an exit code otherwise. - """ - try: - # All we need is the adb binary which is checked below. - _, target = self.GetSpecAndTarget(args, os=False, board=False) - except clicommand.Error as error: - print(str(error)) - return 1 - - adb_tool = tool.HostToolWrapper('adb', target.platform_build_cache(), - target.board) - if not adb_tool.exists(): - print('Could not find adb executable at {}. Use `bdk build platform`' - ' to build it.'.format(adb_tool.path())) - return 1 - - adb_tool.run(args.args) - return 0 + """Calls the adb executable.""" + + remainder_arg = ('args', 'Arguments to pass through to adb.') + + @staticmethod + def Args(parser): + Adb.AddProductArgs(parser) + + def Run(self, args): + """Runs adb. + + Args: + args: parsed argparse namespace. + + Returns: + 0 if successful, an exit code otherwise. + """ + try: + # All we need is the adb binary which is checked below. + _, target = self.GetSpecAndTarget(args, os=False, board=False) + except clicommand.Error as error: + print(str(error)) + return 1 + + adb_tool = tool.HostToolWrapper('adb', target.platform_build_cache(), + target.board) + if not adb_tool.exists(): + print('Could not find adb executable at {}. Use `bdk build ' + 'platform` to build it.'.format(adb_tool.path())) + return 1 + + adb_tool.run(args.args) + return 0 diff --git a/cli/lib/commands/v2/root/fastboot.py b/cli/lib/commands/v2/root/fastboot.py index 7b9d561..056a4f6 100644 --- a/cli/lib/commands/v2/root/fastboot.py +++ b/cli/lib/commands/v2/root/fastboot.py @@ -24,37 +24,37 @@ from core import tool class Fastboot(clicommand.Command): - """Calls the fastboot executable.""" - - remainder_arg = ('args', 'Arguments to pass through to fastboot.') - - @staticmethod - def Args(parser): - Fastboot.AddProductArgs(parser) - - def Run(self, args): - """Runs fastboot. - - Args: - args: parsed argparse namespace. - - Returns: - 0 if successful, an exit code otherwise. - """ - try: - # All we need is the fastboot binary which is checked below. - _, target = self.GetSpecAndTarget(args, os=False, board=False) - except clicommand.Error as error: - print(str(error)) - return 1 - - fastboot_tool = tool.HostToolWrapper('fastboot', - target.platform_build_cache(), - target.board) - if not fastboot_tool.exists(): - print('Could not find fastboot executable at {}. Use `bdk build platform`' - ' to build it.'.format(fastboot_tool.path())) - return 1 - - fastboot_tool.run(args.args) - return 0 + """Calls the fastboot executable.""" + + remainder_arg = ('args', 'Arguments to pass through to fastboot.') + + @staticmethod + def Args(parser): + Fastboot.AddProductArgs(parser) + + def Run(self, args): + """Runs fastboot. + + Args: + args: parsed argparse namespace. + + Returns: + 0 if successful, an exit code otherwise. + """ + try: + # All we need is the fastboot binary which is checked below. + _, target = self.GetSpecAndTarget(args, os=False, board=False) + except clicommand.Error as error: + print(str(error)) + return 1 + + fastboot_tool = tool.HostToolWrapper('fastboot', + target.platform_build_cache(), + target.board) + if not fastboot_tool.exists(): + print('Could not find fastboot executable at {}. Use `bdk build ' + 'platform` to build it.'.format(fastboot_tool.path())) + return 1 + + fastboot_tool.run(args.args) + return 0 diff --git a/cli/lib/commands/v2/root/flash.py b/cli/lib/commands/v2/root/flash.py index f4f775a..16317a8 100644 --- a/cli/lib/commands/v2/root/flash.py +++ b/cli/lib/commands/v2/root/flash.py @@ -23,48 +23,48 @@ from core import tool class Flash(clicommand.Command): - """Flashes the most recent build onto a device. + """Flashes the most recent build onto a device. - If only one device is attached, it will be targeted by default. If - more than one device is attached, a specific target can be passed - with -s or by setting the ANDROID_SERIAL environment variable. - """ + If only one device is attached, it will be targeted by default. If + more than one device is attached, a specific target can be passed + with -s or by setting the ANDROID_SERIAL environment variable. + """ - @staticmethod - def Args(parser): - Flash.AddProductArgs(parser) - parser.add_argument('-s', metavar='<specific device>', default=None, - help='Target a specific device.') - parser.add_argument('--no_reboot', dest='reboot', action='store_false', - help='Do not reboot after flashing.') + @staticmethod + def Args(parser): + Flash.AddProductArgs(parser) + parser.add_argument('-s', metavar='<specific device>', default=None, + help='Target a specific device.') + parser.add_argument('--no_reboot', dest='reboot', action='store_false', + help='Do not reboot after flashing.') - def Run(self, args): - """Runs the flash procedure. + def Run(self, args): + """Runs the flash procedure. - Args: - args: parsed argparse namespace. + Args: + args: parsed argparse namespace. - Returns: - 0 if successful, an exit code otherwise. - """ - try: - spec, target = self.GetSpecAndTarget(args) - except clicommand.Error as error: - print str(error) - return 1 + Returns: + 0 if successful, an exit code otherwise. + """ + try: + spec, target = self.GetSpecAndTarget(args) + except clicommand.Error as error: + print str(error) + return 1 - platform_build_out = target.platform_build_cache() - system_image_dir = spec.config.output_dir + platform_build_out = target.platform_build_cache() + system_image_dir = spec.config.output_dir - # TODO(http://b/27503751): make sure the device exists and potentially put - # it in fastboot mode if it's not. + # TODO(http://b/27503751): make sure the device exists and potentially + # put it in fastboot mode if it's not. - provision_args = ['-s', args.s] if args.s else [] - provision.provision_device(target, platform_build_out, - system_image_dir, provision_args) + provision_args = ['-s', args.s] if args.s else [] + provision.provision_device(target, platform_build_out, + system_image_dir, provision_args) - if args.reboot: - fastboot_tool = tool.HostToolWrapper('fastboot', platform_build_out) - fastboot_tool.run(provision_args + ['reboot']) + if args.reboot: + fastboot_tool = tool.HostToolWrapper('fastboot', platform_build_out) + fastboot_tool.run(provision_args + ['reboot']) - return 0 + return 0 diff --git a/cli/lib/commands/v2/root/init.py b/cli/lib/commands/v2/root/init.py index 2b6fb7a..90ec2c0 100644 --- a/cli/lib/commands/v2/root/init.py +++ b/cli/lib/commands/v2/root/init.py @@ -52,11 +52,11 @@ IMAGE_SPEC_TEMPLATE = """\ </packs> <targets> - <!-- Two targets are defined below that use the sample pack above to determine - what files must be placed in the image. The only difference between the - two, other than their names, is that one uses a "user" build of the OS - (no/minimal debugging) and the other uses a "userdebug" build which - includes debugging information. --> + <!-- Two targets are defined below that use the sample pack above to + determine what files must be placed in the image. The only difference + between the two, other than their names, is that one uses a "user" + build of the OS (no/minimal debugging) and the other uses a "userdebug" + build which includes debugging information. --> <target name="{project}-release" pack="{project}.main" os="brillo" os-version="{os_version}" board="{board}" board-version="{board_version}" @@ -70,58 +70,59 @@ IMAGE_SPEC_TEMPLATE = """\ """ class Init(clicommand.Command): - """Create an image spec in the current directory.""" - - @staticmethod - def Args(parser): - parser.add_argument('--board', required=True, - help='The board model.') - parser.add_argument('--board_version', - default='0.0.0', - help='The BSP version to use.') - parser.add_argument('--os_version', - default=util.GetOSVersion(), - help='The OS version.') - parser.add_argument('--project', - default=os.path.basename(os.getcwd()), - help='The project name. Default current dir name.') - - def Run(self, args): - filename = os.path.join(os.getcwd(), util.PROJECT_SPEC_FILENAME) - - # Spoof up a target to take advantage of Command.ValidateTarget. - spoof_target = target.Target(args.project, 'brillo', args.os_version, - args.board, args.board_version) - spoof_target.origin.source_file = 'attempted project spec' - - try: - self.ValidateTarget(spoof_target) - except clicommand.NotDownloadedError as e: - print('Warning: {}'.format(e)) - except clicommand.ValidationError as e: - print(e) - print('Project spec not written. Exiting.') - return 1 - - sample = IMAGE_SPEC_TEMPLATE.format( - board=args.board, board_version=args.board_version, - os_version=args.os_version, project=args.project) - - if os.path.isfile(filename): - choice = util.GetUserInput('The file {} already exists. Do you wish to ' - 'overwrite it?\n' - '(y/N) '.format(filename)).strip().upper() - if not choice or choice != 'Y': - print('Project spec not written. Exiting.') - return 1 - - try: - with open(filename, 'w') as f: - print(sample, file=f) - print('Starter project spec written to: {}.'.format(filename)) - except IOError as e: - print('Unable to write to file {}.'.format(filename)) - print('Error: {}'.format(e)) - return 1 - - return 0 + """Create an image spec in the current directory.""" + + @staticmethod + def Args(parser): + parser.add_argument('--board', required=True, + help='The board model.') + parser.add_argument('--board_version', + default='0.0.0', + help='The BSP version to use.') + parser.add_argument('--os_version', + default=util.GetOSVersion(), + help='The OS version.') + parser.add_argument('--project', + default=os.path.basename(os.getcwd()), + help='The project name. Default current dir name.') + + def Run(self, args): + filename = os.path.join(os.getcwd(), util.PROJECT_SPEC_FILENAME) + + # Spoof up a target to take advantage of Command.ValidateTarget. + spoof_target = target.Target(args.project, 'brillo', args.os_version, + args.board, args.board_version) + spoof_target.origin.source_file = 'attempted project spec' + + try: + self.ValidateTarget(spoof_target) + except clicommand.NotDownloadedError as e: + print('Warning: {}'.format(e)) + except clicommand.ValidationError as e: + print(e) + print('Project spec not written. Exiting.') + return 1 + + sample = IMAGE_SPEC_TEMPLATE.format( + board=args.board, board_version=args.board_version, + os_version=args.os_version, project=args.project) + + if os.path.isfile(filename): + choice = util.GetUserInput('The file {} already exists. Do you ' + 'wish to overwrite it?\n' + '(y/N) '.format( + filename)).strip().upper() + if not choice or choice != 'Y': + print('Project spec not written. Exiting.') + return 1 + + try: + with open(filename, 'w') as f: + print(sample, file=f) + print('Starter project spec written to: {}.'.format(filename)) + except IOError as e: + print('Unable to write to file {}.'.format(filename)) + print('Error: {}'.format(e)) + return 1 + + return 0 diff --git a/cli/lib/commands/v2/root/sync.py b/cli/lib/commands/v2/root/sync.py index e4ea5ef..5ebbe10 100644 --- a/cli/lib/commands/v2/root/sync.py +++ b/cli/lib/commands/v2/root/sync.py @@ -32,88 +32,88 @@ _SYNC_DIR = 'system' class Sync(clicommand.Command): - """Syncs files to the attached device. + """Syncs files to the attached device. - This provides a fast workflow to iterate on changes, but can only - download to system/. Any other files must be updated using a full - `bdk flash`. + This provides a fast workflow to iterate on changes, but can only + download to system/. Any other files must be updated using a full + `bdk flash`. - Sync only pushes new files and updates existing files; files on - the device that no longer exist locally will not be deleted. + Sync only pushes new files and updates existing files; files on + the device that no longer exist locally will not be deleted. - This will root and remount the device in order to enable writing to - the file system. Does not reboot the device or restart any processes - after syncing. + This will root and remount the device in order to enable writing to + the file system. Does not reboot the device or restart any processes + after syncing. - If only one device is attached, it will be targeted by default. If - more than one device is attached, a specific target can be passed - with -s or by setting the ANDROID_SERIAL environment variable. - """ - - @staticmethod - def Args(parser): - Sync.AddProductArgs(parser) - parser.add_argument('-s', metavar='<specific device>', default=None, - help='Target a specific device.') - parser.add_argument('-l', '--list_only', action='store_true', - help='List only; do not make any changes.') - - def Run(self, args): - """Runs the sync procedure. - - Args: - args: parsed argparse namespace. - - Returns: - 0 if successful, an exit code otherwise. + If only one device is attached, it will be targeted by default. If + more than one device is attached, a specific target can be passed + with -s or by setting the ANDROID_SERIAL environment variable. """ - try: - # Don't need board as long as we have the build output, which is checked - # in image_build.BuildImage(). - spec, target = self.GetSpecAndTarget(args, board=False) - except clicommand.Error as error: - print(str(error)) - return 1 - - image_build.AddTargetOsPacks(spec, target) - - target_dir = os.path.join(spec.config.cache_dir, - '{}.cache'.format(target.name)) - mountpoint = os.path.join(os.path.sep, _SYNC_DIR) - try: - image_build.CreateTargetCache(spec, target, target_dir, - mountpoint=mountpoint, update=True) - except dependency.Error as e: - print('Dependencies unmet for target {}: {}'.format(target.name, e)) - return 1 - - # TODO(dpursell): we might want to start encapsulating adb behind - # a Python class instead of calling it directly (http://b/27854198). - platform_dir = target.platform_build_cache() - adb_tool = tool.HostToolWrapper('adb', platform_dir, target.board) - if not adb_tool.exists(): - print('Could not find adb executable at {}'.format(adb_tool.path()) + - ' Use `bdk build platform` to build it.') - return 1 - - device_args = ['-s', args.s] if args.s else [] - - # The device must be rooted and remounted before we can sync to it. We - # could try to check for these conditions first and skip the commands if - # we're in the right state already, but these are very fast if a device - # is already rooted and remounted so it's probably not worth it. - if not args.list_only: - for command in ('root', 'remount'): - adb_tool.run(device_args + [command]) - - # Point adb to the user artifact sysroot for syncing. This means changes - # to the platform won't be pushed by `bdk sync`, which is good because - # platform changes should probably require a full image flash. - adb_tool.environment['ANDROID_PRODUCT_OUT'] = target_dir - - # adb does it's own parsing rather than using a library, so we have to be - # pretty careful to specify args the way it expects. Usage must be: - # adb [-s serial] sync [-l] dir - sync_args = (['-l'] if args.list_only else []) + [_SYNC_DIR] - adb_tool.run(device_args + ['sync'] + sync_args) - return 0 + + @staticmethod + def Args(parser): + Sync.AddProductArgs(parser) + parser.add_argument('-s', metavar='<specific device>', default=None, + help='Target a specific device.') + parser.add_argument('-l', '--list_only', action='store_true', + help='List only; do not make any changes.') + + def Run(self, args): + """Runs the sync procedure. + + Args: + args: parsed argparse namespace. + + Returns: + 0 if successful, an exit code otherwise. + """ + try: + # Don't need board as long as we have the build output, which is + # checked in image_build.BuildImage(). + spec, target = self.GetSpecAndTarget(args, board=False) + except clicommand.Error as error: + print(str(error)) + return 1 + + image_build.AddTargetOsPacks(spec, target) + + target_dir = os.path.join(spec.config.cache_dir, + '{}.cache'.format(target.name)) + mountpoint = os.path.join(os.path.sep, _SYNC_DIR) + try: + image_build.CreateTargetCache(spec, target, target_dir, + mountpoint=mountpoint, update=True) + except dependency.Error as e: + print('Dependencies unmet for target {}: {}'.format(target.name, e)) + return 1 + + # TODO(dpursell): we might want to start encapsulating adb behind + # a Python class instead of calling it directly (http://b/27854198). + platform_dir = target.platform_build_cache() + adb_tool = tool.HostToolWrapper('adb', platform_dir, target.board) + if not adb_tool.exists(): + print('Could not find adb executable at {}. Use ' + '`bdk build platform` to build it.'.format(adb_tool.path())) + return 1 + + device_args = ['-s', args.s] if args.s else [] + + # The device must be rooted and remounted before we can sync to it. We + # could try to check for these conditions first and skip the commands if + # we're in the right state already, but these are very fast if a device + # is already rooted and remounted so it's probably not worth it. + if not args.list_only: + for command in ('root', 'remount'): + adb_tool.run(device_args + [command]) + + # Point adb to the user artifact sysroot for syncing. This means changes + # to the platform won't be pushed by `bdk sync`, which is good because + # platform changes should probably require a full image flash. + adb_tool.environment['ANDROID_PRODUCT_OUT'] = target_dir + + # adb does it's own parsing rather than using a library, so we have to + # be pretty careful to specify args the way it expects. Usage must be: + # adb [-s serial] sync [-l] dir + sync_args = (['-l'] if args.list_only else []) + [_SYNC_DIR] + adb_tool.run(device_args + ['sync'] + sync_args) + return 0 |