aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWill Drewry <drewry@google.com>2015-10-23 15:43:39 +0000
committerWill Drewry <drewry@google.com>2015-10-23 09:12:54 -0700
commit296de802e44672a5cb864d016ac70ebe334a0cd3 (patch)
tree7ef14da2d5ad4c312e74a22b74badbce429b1408
parentda940b12d8879f31c9b7de516818cd310accaa91 (diff)
downloadbdk-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.py8
-rw-r--r--brunch/lib/commands/product/reconfig.py1
-rw-r--r--brunch/lib/core/config.py2
-rw-r--r--brunch/lib/core/product.py20
-rw-r--r--brunch/lib/core/product_templates.py46
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
""")