diff options
author | Will Drewry <drewry@google.com> | 2015-10-23 15:43:39 +0000 |
---|---|---|
committer | Will Drewry <drewry@google.com> | 2015-10-23 09:12:54 -0700 |
commit | 296de802e44672a5cb864d016ac70ebe334a0cd3 (patch) | |
tree | 7ef14da2d5ad4c312e74a22b74badbce429b1408 | |
parent | da940b12d8879f31c9b7de516818cd310accaa91 (diff) | |
download | bdk-296de802e44672a5cb864d016ac70ebe334a0cd3.tar.gz |
brunch: portable product directories"
Re-attempting to land support for portable
paths:
https://googleplex-android-review.git.corp.google.com/#/c/798182/
Two minor changes were needed during product
creation to pass along the correct path.
BUG=25148498
TEST=I will not land this until I have a test patch to go in parallel.
Change-Id: Ib66cd2155cb931e6f01f9da692b30154647362dd
-rw-r--r-- | brunch/lib/commands/product/envsetup.py | 8 | ||||
-rw-r--r-- | brunch/lib/commands/product/reconfig.py | 1 | ||||
-rw-r--r-- | brunch/lib/core/config.py | 2 | ||||
-rw-r--r-- | brunch/lib/core/product.py | 20 | ||||
-rw-r--r-- | brunch/lib/core/product_templates.py | 46 |
5 files changed, 60 insertions, 17 deletions
diff --git a/brunch/lib/commands/product/envsetup.py b/brunch/lib/commands/product/envsetup.py index 27bcbcf..18dfd82 100644 --- a/brunch/lib/commands/product/envsetup.py +++ b/brunch/lib/commands/product/envsetup.py @@ -37,13 +37,15 @@ class Envsetup(clicommand.Command): # TODO(wad): Add 'shell' argument to select a non-sh format. def Run(self, args): - # TODO(wad) Check version difference. - store = config.ProductStore(args.product_path) + # 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.ProductStore(product_path) if not store.complete(): # TODO(wad) what's the best way to recover for a user here? print "Product data store is incomplete. Product must be recreated." return 1 - env = product.Environment(store) + env = product.Environment(store, product_path) if args.generate is False: print env.environment() else: diff --git a/brunch/lib/commands/product/reconfig.py b/brunch/lib/commands/product/reconfig.py index c0bc135..eb340c3 100644 --- a/brunch/lib/commands/product/reconfig.py +++ b/brunch/lib/commands/product/reconfig.py @@ -58,7 +58,6 @@ class Reconfig(clicommand.Command): if not store.buildtype: store.buildtype = 'eng' if not store.type: store.type = 'empty' - store.path = args.product_path store.bdk_version = util.GetBDKVersion() # Repopulate the envsetup.sh file. diff --git a/brunch/lib/core/config.py b/brunch/lib/core/config.py index 050924f..e565ede 100644 --- a/brunch/lib/core/config.py +++ b/brunch/lib/core/config.py @@ -121,7 +121,7 @@ class UserStore(Store): class ProductStore(Store): REQUIRED_PROPS = [ 'name', 'device', 'manufacturer', \ - 'buildtype', 'path', 'bdk_version', 'type' ] + 'buildtype', 'bdk_version', 'type' ] OPTIONAL_PROPS = [ 'java' ] PREFIX = 'product_' diff --git a/brunch/lib/core/product.py b/brunch/lib/core/product.py index 0c9b94c..9dafdeb 100644 --- a/brunch/lib/core/product.py +++ b/brunch/lib/core/product.py @@ -57,7 +57,7 @@ class ProductCreator(object): self._create_func() # Populate the envsetup.sh file. - env = Environment(self._config) + env = Environment(self._config, self._name) env.envsetup() if self._type != 'empty': print 'The %s example can be found under \'%s\'' % (self._type, self._name) @@ -70,7 +70,6 @@ class ProductCreator(object): self._config.device = self._device self._config.type = self._type self._config.buildtype = 'eng' - self._config.path = os.path.abspath(self._name) self._config.bdk_version = util.GetBDKVersion() def _create_common(self): @@ -120,10 +119,14 @@ class ProductCreator(object): class Environment(object): """This class is used to generate a shell environment meant to streamline the use of the BDK while keeping it familiar to Android device developers. + + Note: None of the templates other than ENVSETUP should contain single + quotes ('). If they do, it will break during sourcing of envsetup.sh. """ - def __init__(self, config): + def __init__(self, config, product_dir=util.GetProductDir()): self._config = config + self._product_dir = product_dir def banner(self): """Return the banner to be printed after envsetup.sh is sourced""" @@ -145,15 +148,17 @@ class Environment(object): return product_templates.ENV_EXPORTS.substitute( self._config.dict(), bdk_path=bdk_path, + product_path=self._product_dir, brunch_path=os.path.join(bdk_path, 'tools', 'bdk', 'brunch'), - target_out=os.path.join(self._config.path, 'out', + target_out=os.path.join(self._product_dir, 'out', 'out-%s' % (self._config.device), 'target', 'product', self._config.device) ) def aliases(self): """Wrap brunch commands with shell functions""" - return product_templates.ENV_ALIASES.substitute(self._config.dict()) + return product_templates.ENV_ALIASES.substitute( + self._config.dict(), product_path=self._product_dir) def environment(self): """Returns a complete shell environment for product development""" @@ -163,6 +168,7 @@ class Environment(object): """Generates a file which will run brunch product envsetup""" bdk_path = util.GetBDKPath() bdk_version = util.GetBDKVersion() - with open(os.path.join(self._config.path, 'envsetup.sh'), 'w') as f: + with open(os.path.join(self._product_dir, 'envsetup.sh'), 'w') as f: f.write(product_templates.ENVSETUP.substitute( - self._config.dict(), bdk_path=bdk_path)) + self._config.dict(), bdk_path=bdk_path, + product_path=self._product_dir)) diff --git a/brunch/lib/core/product_templates.py b/brunch/lib/core/product_templates.py index ea64286..d81045a 100644 --- a/brunch/lib/core/product_templates.py +++ b/brunch/lib/core/product_templates.py @@ -124,13 +124,49 @@ provision() { """) +# Inside this template, brunch is re-called to export an updated +# environment. To do so, the output is packed into an fd and then +# source'd by the shell. The approach is messier than using <() +# in order to avoid a specific bashism and keep this part dash clean. +# That is yet to be a requirement across all the scripts, though. ENVSETUP = string.Template("""\ _envsetup_load() { - local t=`mktemp ${product_path}/.envsetup.sh.XXXXX` - ${bdk_path}/tools/bdk/brunch/brunch product envsetup \\ - --product_path="${product_path}" > "$$t" - source $$t - rm $$t + # Allow the environment to override the BDK path. + local bdk="$${BDK_PATH:-${bdk_path}}" + if ! test -x "$${bdk}/tools/bdk/brunch/brunch"; then + echo "The BDK cannot be found." 1>&2 + echo "Please supply its path in the BDK_PATH environment variable or " 1>&2 + echo "run 'brunch product reconfig'" 1>&2 + return 1 + fi + + # Make sure we're in the root of a product. + # If the user explicitly exported a PRODUCT_PATH, then fail if it is wrong. + if test -n "$${PRODUCT_PATH}" && \ + ! test -e "$${PRODUCT_PATH}/.brunch_product.db"; then + echo "Cannot find a product at PRODUCT_PATH: $${PRODUCT_PATH}" 1>&2 + return 1 + fi + # Otherwise, use the default or check the cwd. + local product_path="$${PRODUCT_PATH:-${product_path}}" + if ! test -e "$${product_path}/.brunch_product.db"; then + echo "Checking current directory for a valid product . . ." 1>&2 + product_path=$$PWD + if ! test -e "$${product_path}/.brunch_product.db"; then + echo "Please source envsetup.sh from the product directory " 1>&2 + echo "or set a valid PRODUCT_PATH in the environment." 1>&2 + return 1 + fi + fi + + # Find a free file descriptor and use it rather than a tempfile. + fd=$$((`ls /dev/fd/ | sort -n | tail -1` + 1)) + eval 'exec '$$fd'<<EOFEOF + $$($${bdk}/tools/bdk/brunch/brunch product envsetup \\ + --product_path="$${product_path}") +EOFEOF' + . /dev/fd/$$fd + eval "exec $$fd<&-" } _envsetup_load """) |