summaryrefslogtreecommitdiffstats
path: root/tools/cr
diff options
context:
space:
mode:
authoriancottrell@chromium.org <iancottrell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-21 16:50:09 +0000
committeriancottrell@chromium.org <iancottrell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-21 16:50:09 +0000
commitd925280a75c8394c2fa7d121b5e4e1e0d9d86714 (patch)
tree149d355ae220f4c773b89fee22587b6c2f79e9e0 /tools/cr
parent5182b3844a191c28d02e5ac16120fd1239fe3799 (diff)
downloadchromium_src-d925280a75c8394c2fa7d121b5e4e1e0d9d86714.zip
chromium_src-d925280a75c8394c2fa7d121b5e4e1e0d9d86714.tar.gz
chromium_src-d925280a75c8394c2fa7d121b5e4e1e0d9d86714.tar.bz2
[cr tool] Make context implicit
This removes context from many function signatures, and instead adds cr.context to access the current context. This will allow a few places that are currently ugly to be cleaned up, make it possible to access the context from inside some properties, and make it easy to hijack for testing purposes. BUG=336240 Review URL: https://codereview.chromium.org/142933004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@258609 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/cr')
-rw-r--r--tools/cr/cr/actions/action.py4
-rw-r--r--tools/cr/cr/actions/adb.py12
-rw-r--r--tools/cr/cr/actions/builder.py24
-rw-r--r--tools/cr/cr/actions/debugger.py18
-rw-r--r--tools/cr/cr/actions/gdb.py4
-rw-r--r--tools/cr/cr/actions/gyp.py7
-rw-r--r--tools/cr/cr/actions/installer.py14
-rw-r--r--tools/cr/cr/actions/linux.py14
-rw-r--r--tools/cr/cr/actions/ninja.py16
-rw-r--r--tools/cr/cr/actions/runner.py24
-rw-r--r--tools/cr/cr/autocomplete.py6
-rw-r--r--tools/cr/cr/base/android.py22
-rw-r--r--tools/cr/cr/base/client.py56
-rw-r--r--tools/cr/cr/base/context.py (renamed from tools/cr/cr/context.py)48
-rw-r--r--tools/cr/cr/base/host.py48
-rw-r--r--tools/cr/cr/base/platform.py16
-rw-r--r--tools/cr/cr/commands/build.py12
-rw-r--r--tools/cr/cr/commands/command.py22
-rw-r--r--tools/cr/cr/commands/debug.py20
-rw-r--r--tools/cr/cr/commands/info.py18
-rw-r--r--tools/cr/cr/commands/init.py46
-rw-r--r--tools/cr/cr/commands/install.py10
-rw-r--r--tools/cr/cr/commands/prepare.py11
-rw-r--r--tools/cr/cr/commands/run.py18
-rw-r--r--tools/cr/cr/commands/select.py18
-rw-r--r--tools/cr/cr/commands/shell.py10
-rw-r--r--tools/cr/cr/commands/sync.py9
-rw-r--r--tools/cr/cr/config.py12
-rw-r--r--tools/cr/cr/fixups/arch.py2
-rw-r--r--tools/cr/cr/loader.py1
-rw-r--r--tools/cr/cr/plugin.py32
-rw-r--r--tools/cr/cr/targets/target.py34
-rw-r--r--tools/cr/main.py111
33 files changed, 348 insertions, 371 deletions
diff --git a/tools/cr/cr/actions/action.py b/tools/cr/cr/actions/action.py
index b812aae..e2f966a 100644
--- a/tools/cr/cr/actions/action.py
+++ b/tools/cr/cr/actions/action.py
@@ -29,7 +29,7 @@ class Action(cr.Plugin):
)
@cr.Plugin.activemethod
- def Skipping(self, context):
+ def Skipping(self):
"""A method that is used to detect void or skip implementations.
Most actions have a skip version that you can select to indicate that you
@@ -39,8 +39,6 @@ class Action(cr.Plugin):
performing actions that were only there to produce the inputs of an action
that is being skipped).
- Args:
- context: the cr context to test within.
Returns:
True if this implementation is a skip action.
"""
diff --git a/tools/cr/cr/actions/adb.py b/tools/cr/cr/actions/adb.py
index e55d503..54eebe95 100644
--- a/tools/cr/cr/actions/adb.py
+++ b/tools/cr/cr/actions/adb.py
@@ -106,14 +106,14 @@ class AdbRunner(cr.Runner):
def enabled(self):
return cr.AndroidPlatform.GetInstance().is_active
- def Kill(self, context, targets, arguments):
+ def Kill(self, targets, arguments):
for target in targets:
Adb.Kill(target, arguments)
- def Run(self, context, target, arguments):
+ def Run(self, target, arguments):
Adb.Run(target, arguments)
- def Test(self, context, target, arguments):
+ def Test(self, target, arguments):
cr.Host.Execute(
target,
'{CR_TEST_RUNNER}', '{CR_TEST_TYPE}',
@@ -130,14 +130,14 @@ class AdbInstaller(cr.Installer):
def enabled(self):
return cr.AndroidPlatform.GetInstance().is_active
- def Uninstall(self, context, targets, arguments):
+ def Uninstall(self, targets, arguments):
for target in targets:
Adb.Uninstall(target, arguments)
- def Install(self, context, targets, arguments):
+ def Install(self, targets, arguments):
for target in targets:
Adb.Install(target, arguments)
- def Reinstall(self, context, targets, arguments):
+ def Reinstall(self, targets, arguments):
for target in targets:
Adb.Reinstall(target, arguments)
diff --git a/tools/cr/cr/actions/builder.py b/tools/cr/cr/actions/builder.py
index 286d2ec..b3ff2bf 100644
--- a/tools/cr/cr/actions/builder.py
+++ b/tools/cr/cr/actions/builder.py
@@ -26,26 +26,26 @@ class Builder(cr.Action, cr.Plugin.Type):
SELECTOR_HELP = 'Sets the builder to use to update dependencies.'
@cr.Plugin.activemethod
- def Build(self, context, targets, arguments):
+ def Build(self, targets, arguments):
raise NotImplementedError('Must be overridden.')
@cr.Plugin.activemethod
- def Clean(self, context, targets, arguments):
+ def Clean(self, targets, arguments):
"""Clean temporary files built by a target."""
raise NotImplementedError('Must be overridden.')
@cr.Plugin.activemethod
- def Rebuild(self, context, targets, arguments):
+ def Rebuild(self, targets, arguments):
"""Make a target build even if it is up to date.
Default implementation is to do a Clean and Build sequence.
Do not call the base version if you implement a more efficient one.
"""
- self.Clean(context, targets, [])
- self.Build(context, targets, arguments)
+ self.Clean(targets, [])
+ self.Build(targets, arguments)
@cr.Plugin.activemethod
- def GetTargets(self, context):
+ def GetTargets(self):
"""Gets the full set of targets supported by this builder.
Used in automatic target name transformations, and also in offering the
@@ -54,14 +54,14 @@ class Builder(cr.Action, cr.Plugin.Type):
return []
@cr.Plugin.activemethod
- def IsTarget(self, context, target_name):
+ def IsTarget(self, target_name):
"""Check if a target name is on the builder knows about."""
- return target_name in self.GetTargets(context)
+ return target_name in self.GetTargets()
@cr.Plugin.activemethod
- def GuessTargets(self, context, target_name):
+ def GuessTargets(self, target_name):
"""Returns a list of closest matching targets for a named target."""
- return difflib.get_close_matches(target_name, self.GetTargets(context))
+ return difflib.get_close_matches(target_name, self.GetTargets(), 10, 0.4)
class SkipBuilder(Builder):
@@ -71,9 +71,9 @@ class SkipBuilder(Builder):
def priority(self):
return super(SkipBuilder, self).priority - 1
- def Build(self, context, targets, arguments):
+ def Build(self, targets, arguments):
pass
- def Clean(self, context, targets, arguments):
+ def Clean(self, targets, arguments):
pass
diff --git a/tools/cr/cr/actions/debugger.py b/tools/cr/cr/actions/debugger.py
index a634ab2..1db3d81 100644
--- a/tools/cr/cr/actions/debugger.py
+++ b/tools/cr/cr/actions/debugger.py
@@ -22,30 +22,30 @@ class Debugger(cr.Action, cr.Plugin.Type):
cr.Runner.AddSelectorArg(command, parser)
@classmethod
- def ShouldInvoke(cls, context):
+ def ShouldInvoke(cls):
"""Checks if the debugger is attaching or launching."""
- return not cr.Runner.Skipping(context)
+ return not cr.Runner.Skipping()
@cr.Plugin.activemethod
- def Restart(self, context, targets, arguments):
+ def Restart(self, targets, arguments):
"""Ask the debugger to restart.
Defaults to a Kill Invoke sequence.
"""
- self.Kill(context, targets, [])
- self.Invoke(context, targets, arguments)
+ self.Kill(targets, [])
+ self.Invoke(targets, arguments)
@cr.Plugin.activemethod
- def Kill(self, context, targets, arguments):
+ def Kill(self, targets, arguments):
"""Kill the running debugger."""
- cr.Runner.Kill(context, targets, arguments)
+ cr.Runner.Kill(targets, arguments)
@cr.Plugin.activemethod
- def Invoke(self, context, targets, arguments):
+ def Invoke(self, targets, arguments):
"""Invoke the program within a debugger."""
raise NotImplementedError('Must be overridden.')
@cr.Plugin.activemethod
- def Attach(self, context, targets, arguments):
+ def Attach(self, targets, arguments):
"""Attach a debugger to a running program."""
raise NotImplementedError('Must be overridden.')
diff --git a/tools/cr/cr/actions/gdb.py b/tools/cr/cr/actions/gdb.py
index 64386db..841c2c1 100644
--- a/tools/cr/cr/actions/gdb.py
+++ b/tools/cr/cr/actions/gdb.py
@@ -17,7 +17,7 @@ class GdbDebugger(cr.Debugger):
return (cr.LinuxPlatform.GetInstance().is_active and
self.DETECTED.Find('CR_GDB'))
- def Invoke(self, context, targets, arguments):
+ def Invoke(self, targets, arguments):
for target in targets:
cr.Host.Execute(
target,
@@ -27,7 +27,7 @@ class GdbDebugger(cr.Debugger):
*arguments
)
- def Attach(self, context, targets, arguments):
+ def Attach(self, targets, arguments):
raise NotImplementedError('Attach not currently supported for gdb.')
@classmethod
diff --git a/tools/cr/cr/actions/gyp.py b/tools/cr/cr/actions/gyp.py
index b3492bb..fc191e3 100644
--- a/tools/cr/cr/actions/gyp.py
+++ b/tools/cr/cr/actions/gyp.py
@@ -15,11 +15,10 @@ class GypPrepareOut(cr.PrepareOut):
GYP_GENERATOR_FLAGS='output_dir={CR_OUT_BASE} config={CR_BUILDTYPE}',
)
- def Prepare(self, context):
- if context.verbose >= 1:
- print context.Substitute('Invoking gyp with {GYP_GENERATOR_FLAGS}')
+ def Prepare(self):
+ if cr.context.verbose >= 1:
+ print cr.context.Substitute('Invoking gyp with {GYP_GENERATOR_FLAGS}')
cr.Host.Execute(
- context,
'{CR_SRC}/build/gyp_chromium',
'--depth={CR_SRC}',
'--check'
diff --git a/tools/cr/cr/actions/installer.py b/tools/cr/cr/actions/installer.py
index 0dd432d..064b4d0 100644
--- a/tools/cr/cr/actions/installer.py
+++ b/tools/cr/cr/actions/installer.py
@@ -20,25 +20,25 @@ class Installer(cr.Action, cr.Plugin.Type):
SELECTOR_HELP = 'Sets the installer to use.'
@cr.Plugin.activemethod
- def Uninstall(self, context, targets, arguments):
+ def Uninstall(self, targets, arguments):
"""Removes a target from it's installed location."""
raise NotImplementedError('Must be overridden.')
@cr.Plugin.activemethod
- def Install(self, context, targets, arguments):
+ def Install(self, targets, arguments):
"""Installs a target somewhere so that it is ready to run."""
raise NotImplementedError('Must be overridden.')
@cr.Plugin.activemethod
- def Reinstall(self, context, targets, arguments):
+ def Reinstall(self, targets, arguments):
"""Force a target to install even if already installed.
Default implementation is to do an Uninstall Install sequence.
Do not call the base version if you implement a more efficient one.
"""
- self.Uninstall(context, targets, [])
- self.Install(context, targets, arguments)
+ self.Uninstall(targets, [])
+ self.Install(targets, arguments)
class SkipInstaller(Installer):
@@ -48,8 +48,8 @@ class SkipInstaller(Installer):
def priority(self):
return super(SkipInstaller, self).priority - 1
- def Uninstall(self, context, targets, arguments):
+ def Uninstall(self, targets, arguments):
pass
- def Install(self, context, targets, arguments):
+ def Install(self, targets, arguments):
pass
diff --git a/tools/cr/cr/actions/linux.py b/tools/cr/cr/actions/linux.py
index adcdb31..b56c797 100644
--- a/tools/cr/cr/actions/linux.py
+++ b/tools/cr/cr/actions/linux.py
@@ -17,15 +17,15 @@ class LinuxRunner(cr.Runner):
def enabled(self):
return cr.LinuxPlatform.GetInstance().is_active
- def Kill(self, context, targets, arguments):
+ def Kill(self, targets, arguments):
# TODO(iancottrell): Think about how to implement this, or even if we should
print '**WARNING** Kill not yet implemented on linux'
- def Run(self, context, target, arguments):
+ def Run(self, target, arguments):
cr.Host.Execute(target, '{CR_BINARY}', '{CR_RUN_ARGUMENTS}', *arguments)
- def Test(self, context, target, arguments):
- self.Run(context, target, arguments)
+ def Test(self, target, arguments):
+ self.Run(target, arguments)
class LinuxInstaller(cr.Installer):
@@ -39,12 +39,12 @@ class LinuxInstaller(cr.Installer):
def enabled(self):
return cr.LinuxPlatform.GetInstance().is_active
- def Uninstall(self, context, targets, arguments):
+ def Uninstall(self, targets, arguments):
pass
- def Install(self, context, targets, arguments):
+ def Install(self, targets, arguments):
pass
- def Reinstall(self, context, targets, arguments):
+ def Reinstall(self, targets, arguments):
pass
diff --git a/tools/cr/cr/actions/ninja.py b/tools/cr/cr/actions/ninja.py
index afd2d1f..dd324f3 100644
--- a/tools/cr/cr/actions/ninja.py
+++ b/tools/cr/cr/actions/ninja.py
@@ -34,15 +34,14 @@ class NinjaBuilder(cr.Builder):
super(NinjaBuilder, self).__init__()
self._targets = []
- def Build(self, context, targets, arguments):
+ def Build(self, targets, arguments):
# Make sure Goma is started if Ninja is set to use it.
# This may be redundant, but it currently improves reliability.
try:
- with open(context.Get('NINJA_BUILD_FILE'), 'r') as f:
- if f.readline().rstrip('\n') == context.Get('NINJA_GOMA_LINE'):
+ with open(cr.context.Get('NINJA_BUILD_FILE'), 'r') as f:
+ if f.readline().rstrip('\n') == cr.context.Get('NINJA_GOMA_LINE'):
# Goma is active, so make sure it's started.
cr.Host.ExecuteSilently(
- context,
'{NINJA_GOMA_CTL}',
'ensure_start'
)
@@ -52,7 +51,6 @@ class NinjaBuilder(cr.Builder):
build_arguments = [target.build_target for target in targets]
build_arguments.extend(arguments)
cr.Host.Execute(
- context,
'{NINJA_BINARY}',
'-C{CR_BUILD_DIR}',
'-j{NINJA_JOBS}',
@@ -60,26 +58,24 @@ class NinjaBuilder(cr.Builder):
*build_arguments
)
- def Clean(self, context, targets, arguments):
+ def Clean(self, targets, arguments):
build_arguments = [target.build_target for target in targets]
build_arguments.extend(arguments)
cr.Host.Execute(
- context,
'{NINJA_BINARY}',
'-C{CR_BUILD_DIR}',
'-tclean',
*build_arguments
)
- def GetTargets(self, context):
+ def GetTargets(self):
"""Overridden from Builder.GetTargets."""
if not self._targets:
try:
- context.Get('CR_BUILD_DIR', raise_errors=True)
+ cr.context.Get('CR_BUILD_DIR', raise_errors=True)
except KeyError:
return self._targets
output = cr.Host.Capture(
- context,
'{NINJA_BINARY}',
'-C{CR_BUILD_DIR}',
'-ttargets',
diff --git a/tools/cr/cr/actions/runner.py b/tools/cr/cr/actions/runner.py
index 72590fc..0886174 100644
--- a/tools/cr/cr/actions/runner.py
+++ b/tools/cr/cr/actions/runner.py
@@ -32,41 +32,41 @@ class Runner(cr.Action, cr.Plugin.Type):
)
@cr.Plugin.activemethod
- def Kill(self, context, targets, arguments):
+ def Kill(self, targets, arguments):
"""Stops all running processes that match a target."""
raise NotImplementedError('Must be overridden.')
@cr.Plugin.activemethod
- def Run(self, context, target, arguments):
+ def Run(self, target, arguments):
"""Run a new copy of a runnable target."""
raise NotImplementedError('Must be overridden.')
@cr.Plugin.activemethod
- def Test(self, context, target, arguments):
+ def Test(self, target, arguments):
"""Run a test target."""
raise NotImplementedError('Must be overridden.')
@cr.Plugin.activemethod
- def Invoke(self, context, targets, arguments):
+ def Invoke(self, targets, arguments):
"""Invoke a target.
This dispatches to either Test or Run depending on the target type.
"""
for target in targets:
if target.is_test:
- self.Test(context, target, arguments)
+ self.Test(target, arguments)
else:
- self.Run(context, target, arguments)
+ self.Run(target, arguments)
@cr.Plugin.activemethod
- def Restart(self, context, targets, arguments):
+ def Restart(self, targets, arguments):
"""Force a target to restart if it is already running.
Default implementation is to do a Kill Invoke sequence.
Do not call the base version if you implement a more efficient one.
"""
- self.Kill(context, targets, [])
- self.Invoke(context, targets, arguments)
+ self.Kill(targets, [])
+ self.Invoke(targets, arguments)
class SkipRunner(Runner):
@@ -76,12 +76,12 @@ class SkipRunner(Runner):
def priority(self):
return super(SkipRunner, self).priority - 1
- def Kill(self, context, targets, arguments):
+ def Kill(self, targets, arguments):
pass
- def Run(self, context, target, arguments):
+ def Run(self, target, arguments):
pass
- def Test(self, context, target, arguments):
+ def Test(self, target, arguments):
pass
diff --git a/tools/cr/cr/autocomplete.py b/tools/cr/cr/autocomplete.py
index ab9ce2f..f03b821 100644
--- a/tools/cr/cr/autocomplete.py
+++ b/tools/cr/cr/autocomplete.py
@@ -11,17 +11,13 @@ current command line.
import cr
-def Complete(context):
+def Complete():
"""Attempts to build a completion list for the current command line.
COMP_WORD contains the word that is being completed, and COMP_CWORD has
the index of that word on the command line.
-
- Args:
- context: The cr context object, of type cr.context.Context.
"""
- _ = context
# TODO(iancottrell): support auto complete of more than just the command
# try to parse the command line using parser
print ' '.join(command.name for command in cr.Command.Plugins())
diff --git a/tools/cr/cr/base/android.py b/tools/cr/cr/base/android.py
index 027a697..582d21c 100644
--- a/tools/cr/cr/base/android.py
+++ b/tools/cr/cr/base/android.py
@@ -51,19 +51,19 @@ class AndroidPlatform(cr.Platform):
def priority(self):
return super(AndroidPlatform, self).priority + 1
- def Prepare(self, context):
+ def Prepare(self):
"""Override Prepare from cr.Platform."""
- super(AndroidPlatform, self).Prepare(context)
+ super(AndroidPlatform, self).Prepare()
try:
# capture the result of env setup if we have not already done so
if not self._env_ready:
# See what the env would be without env setup
- before = context.exported
+ before = cr.context.exported
before['GYP_DEFINES'] = before.get(
'GYP_DEFINES', '') + ' target_arch={CR_ENVSETUP_ARCH}'
# Run env setup and capture/parse its output
envsetup = 'source {CR_ENVSETUP}'
- output = cr.Host.CaptureShell(context, envsetup + ' > /dev/null && env')
+ output = cr.Host.CaptureShell(envsetup + ' > /dev/null && env')
env_setup = cr.Config('envsetup', literal=True, export=True)
for line in output.split('\n'):
(key, op, value) = line.partition('=')
@@ -77,7 +77,7 @@ class AndroidPlatform(cr.Platform):
# Make a version of GYP_DEFINES that is the combination of base
# setting and envsetup, needs to override the overrides
# Note: Forcing it into the top level scope - sledge-hammer
- context[key] = value.strip() + ' ' + before.get(key, '')
+ cr.context[key] = value.strip() + ' ' + before.get(key, '')
items = env_setup.exported.items()
if not items:
# Because of the way envsetup is run, the exit code does not make it
@@ -109,13 +109,13 @@ class AndroidInitHook(cr.InitHook):
def enabled(self):
return cr.AndroidPlatform.GetInstance().is_active
- def Run(self, context, old_version, config):
+ def Run(self, old_version, config):
_ = old_version, config # unused
# Check we are an android capable client
- target_os = context.gclient.get('target_os', [])
+ target_os = cr.context.gclient.get('target_os', [])
if 'android' in target_os:
return
- url = context.gclient.get('solutions', [{}])[0].get('url')
+ url = cr.context.gclient.get('solutions', [{}])[0].get('url')
if (url.startswith('https://chrome-internal.googlesource.com/') and
url.endswith('/internal/apps.git')):
return
@@ -126,10 +126,10 @@ class AndroidInitHook(cr.InitHook):
print 'Abandoning the creation of and android output directory.'
exit(1)
target_os.append('android')
- context.gclient['target_os'] = target_os
- context.WriteGClient()
+ cr.context.gclient['target_os'] = target_os
+ cr.base.client.WriteGClient()
print 'Client updated.'
print 'You may need to sync before an output directory can be made.'
if cr.Host.YesNo('Would you like to sync this client now?'):
- cr.SyncCommand.Sync(context, ["--nohooks"])
+ cr.SyncCommand.Sync(["--nohooks"])
diff --git a/tools/cr/cr/base/client.py b/tools/cr/cr/base/client.py
index 0b679ce..9ab52f9 100644
--- a/tools/cr/cr/base/client.py
+++ b/tools/cr/cr/base/client.py
@@ -50,7 +50,7 @@ DEFAULT = cr.Config.From(
)
-def DetectClient(context):
+def DetectClient():
# Attempt to detect the current client from the cwd
# See if we can detect the source tree root
client_path = os.getcwd()
@@ -66,11 +66,11 @@ def DetectClient(context):
# we have the src path, base is one level up
client_path = dirname
if client_path is not None:
- context.derived['CR_CLIENT_PATH'] = client_path
- # now get the value from context, it may be different
- client_path = context.Get('CR_CLIENT_PATH')
+ cr.context.derived['CR_CLIENT_PATH'] = client_path
+ # now get the value from it may be different
+ client_path = cr.context.Get('CR_CLIENT_PATH')
if client_path is not None:
- context.derived['CR_CLIENT_NAME'] = os.path.basename(client_path)
+ cr.context.derived['CR_CLIENT_NAME'] = os.path.basename(client_path)
def _GetConfigFilename(path):
@@ -96,24 +96,22 @@ def AddArguments(parser):
)
-def GetOutArgument(context):
- return getattr(context.args, '_out', None)
+def GetOutArgument():
+ return getattr(cr.context.args, '_out', None)
-def ApplyOutArgument(context):
+def ApplyOutArgument():
# TODO(iancottrell): be flexible, allow out to do approximate match...
- out = GetOutArgument(context)
+ out = GetOutArgument()
if out:
- context.derived.Set(CR_OUT_FULL=out)
+ cr.context.derived.Set(CR_OUT_FULL=out)
-def ReadGClient(context):
+def ReadGClient():
"""Loads the .gclient configuration for the current client.
This will load from CR_CLIENT_PATH.
- Args:
- context: The active context to load configuration for.
Returns:
The dict of values set in the .gclient file.
@@ -121,7 +119,7 @@ def ReadGClient(context):
# Now attempt to load and parse the .gclient file
result = {}
try:
- gclient_file = context.Substitute(
+ gclient_file = cr.context.Substitute(
os.path.join('{CR_CLIENT_PATH}', GCLIENT_FILENAME))
with open(gclient_file, 'r') as spec_file:
# matching the behaviour of gclient, so pylint: disable=exec-used
@@ -132,46 +130,41 @@ def ReadGClient(context):
return result
-def WriteGClient(context):
+def WriteGClient():
"""Writes the .gclient configuration for the current client.
This will write to CR_CLIENT_PATH.
- Args:
- context: The active context to write the configuration for.
-
"""
- gclient_file = context.Substitute(
+ gclient_file = cr.context.Substitute(
os.path.join('{CR_CLIENT_PATH}', GCLIENT_FILENAME))
spec = '\n'.join('%s = %s' % (key, pprint.pformat(value))
- for key,value in context.gclient.items())
- if context.dry_run:
+ for key,value in cr.context.gclient.items())
+ if cr.context.dry_run:
print 'Write the following spec to', gclient_file
print spec
else:
with open(gclient_file, 'w') as spec_file:
spec_file.write(spec)
-def LoadConfig(context):
+def LoadConfig():
"""Loads the client configuration for the given context.
This will load configuration if present from CR_CLIENT_PATH and then
CR_BUILD_DIR.
- Args:
- context: The active context to load configuratin for.
Returns:
True if configuration was fully loaded.
"""
# Load the root config, will help set default build dir
- client_path = context.Find('CR_CLIENT_PATH')
+ client_path = cr.context.Find('CR_CLIENT_PATH')
if not client_path:
return False
cr.auto.client.__path__.append(os.path.join(client_path, CLIENT_CONFIG_PATH))
cr.loader.Scan()
# Now load build dir config
- build_dir = context.Find('CR_BUILD_DIR')
+ build_dir = cr.context.Find('CR_BUILD_DIR')
if not build_dir:
return False
cr.auto.build.__path__.append(os.path.join(build_dir, CLIENT_CONFIG_PATH))
@@ -179,19 +172,18 @@ def LoadConfig(context):
return hasattr(cr.auto.build, 'config')
-def WriteConfig(context, path, data):
+def WriteConfig(path, data):
"""Writes a configuration out to a file.
This writes all the key value pairs in data out to a config file below path.
Args:
- context: The context to run under.
path: The base path to write the config plugin into.
data: The key value pairs to write.
"""
filename = _GetConfigFilename(path)
config_dir = os.path.dirname(filename)
- if context.dry_run:
+ if cr.context.dry_run:
print 'makedirs', config_dir
print 'Write config to', filename
_WriteConfig(sys.stdout, data)
@@ -205,10 +197,10 @@ def WriteConfig(context, path, data):
_WriteConfig(writer, data)
-def PrintInfo(context):
- print 'Selected output directory is', context.Find('CR_BUILD_DIR')
+def PrintInfo():
+ print 'Selected output directory is', cr.context.Find('CR_BUILD_DIR')
try:
for name in cr.auto.build.config.OVERRIDES.exported.keys():
- print ' ', name, '=', context.Get(name)
+ print ' ', name, '=', cr.context.Get(name)
except AttributeError:
pass
diff --git a/tools/cr/cr/context.py b/tools/cr/cr/base/context.py
index 176961e..b700519 100644
--- a/tools/cr/cr/context.py
+++ b/tools/cr/cr/base/context.py
@@ -1,4 +1,4 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
+# Copyright 2014 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.
@@ -12,7 +12,6 @@ import argparse
import os
import cr
-
class _DumpVisitor(cr.visitor.ExportVisitor):
"""A visitor that prints all variables in a config hierarchy."""
@@ -57,9 +56,9 @@ class _ShowHelp(argparse.Action):
"""
def __call__(self, parser, namespace, values, option_string=None):
- if parser.context.speculative:
+ if cr.context.speculative:
return
- command = cr.Command.GetActivePlugin(parser.context)
+ command = cr.Command.GetActivePlugin()
if command:
command.parser.print_help()
else:
@@ -76,12 +75,12 @@ class _ArgumentParser(argparse.ArgumentParser):
"""
def error(self, message):
- if self.context.speculative:
+ if cr.context.speculative:
return
super(_ArgumentParser, self).error(message)
def parse_args(self):
- if self.context.speculative:
+ if cr.context.speculative:
result = self.parse_known_args()
if result:
return result[0]
@@ -95,16 +94,19 @@ class _ArgumentParser(argparse.ArgumentParser):
return result
-class Context(cr.config.Config, cr.loader.AutoExport):
+# The context stack
+_stack = []
+
+
+class _Context(cr.config.Config):
"""The base context holder for the cr system.
- This is passed to almost all methods in the cr system, and holds the common
- context they all shared. Mostly this is stored in the Config structure of
- variables.
+ This holds the common context shared throughout cr.
+ Mostly this is stored in the Config structure of variables.
"""
def __init__(self, description='', epilog=''):
- super(Context, self).__init__('Context')
+ super(_Context, self).__init__('Context')
self._args = None
self._arguments = cr.config.Config('ARGS')
self._derived = cr.config.Config('DERIVED')
@@ -118,17 +120,25 @@ class Context(cr.config.Config, cr.loader.AutoExport):
# Build the command line argument parser
self._parser = _ArgumentParser(add_help=False, description=description,
epilog=epilog)
- self._parser.context = self
self._subparsers = self.parser.add_subparsers()
# Add the global arguments
self.AddCommonArguments(self._parser)
self._gclient = {}
- # Try to detect the current client information
- cr.base.client.DetectClient(self)
+
+ def __enter__(self):
+ """ To support using 'with cr.base.context.Create():'"""
+ _stack.append(self)
+ cr.context = self
+ return self
+
+ def __exit__(self, *_):
+ _stack.pop()
+ if _stack:
+ cr.context = _stack[-1]
+ return False
def AddSubParser(self, source):
parser = source.AddArguments(self._subparsers)
- parser.context = self
@classmethod
def AddCommonArguments(cls, parser):
@@ -202,13 +212,9 @@ class Context(cr.config.Config, cr.loader.AutoExport):
@property
def gclient(self):
if not self._gclient:
- self._gclient = cr.base.client.ReadGClient(self)
+ self._gclient = cr.base.client.ReadGClient()
return self._gclient
- def WriteGClient(self):
- if self._gclient:
- cr.base.client.WriteGClient(self)
-
def ParseArgs(self, speculative=False):
cr.plugin.DynamicChoices.only_active = not speculative
self._speculative = speculative
@@ -221,3 +227,5 @@ class Context(cr.config.Config, cr.loader.AutoExport):
def DumpValues(self, with_source):
_DumpVisitor(with_source).VisitNode(self)
+def Create(description='', epilog=''):
+ return _Context(description=description, epilog=epilog)
diff --git a/tools/cr/cr/base/host.py b/tools/cr/cr/base/host.py
index b8fb296..30ce785 100644
--- a/tools/cr/cr/base/host.py
+++ b/tools/cr/cr/base/host.py
@@ -36,22 +36,21 @@ class Host(cr.Plugin, cr.Plugin.Type):
return False
@classmethod
- def Select(cls, context):
+ def Select(cls):
for host in cls.Plugins():
if host.Matches():
return host
- def _Execute(self, context, command,
+ def _Execute(self, command,
shell=False, capture=False, silent=False,
ignore_dry_run=False, return_status=False,
ignore_interrupt_signal=False):
"""This is the only method that launches external programs.
It is a thin wrapper around subprocess.Popen that handles cr specific
- issues. The command is expanded in the context, so that context variables
+ issues. The command is expanded in the active context so that variables
are substituted.
Args:
- context: the cr context to run under.
command: the command to run.
shell: whether to run the command using the shell.
capture: controls wether the output of the command is captured.
@@ -67,19 +66,19 @@ class Host(cr.Plugin, cr.Plugin.Type):
the status if return_status is true, or the output if capture is true,
otherwise nothing.
"""
- with context.Trace():
- command = [context.Substitute(arg) for arg in command if arg]
- trail = context.trail
+ with cr.context.Trace():
+ command = [cr.context.Substitute(arg) for arg in command if arg]
+ trail = cr.context.trail
if not command:
print 'Empty command passed to execute'
exit(1)
- if context.verbose:
+ if cr.context.verbose:
print ' '.join(command)
- if context.verbose >= _TRAIL_VERBOSITY:
+ if cr.context.verbose >= _TRAIL_VERBOSITY:
print 'Command expanded the following variables:'
for key, value in trail:
print ' ', key, '=', value
- if ignore_dry_run or not context.dry_run:
+ if ignore_dry_run or not cr.context.dry_run:
out = None
if capture:
out = subprocess.PIPE
@@ -88,12 +87,12 @@ class Host(cr.Plugin, cr.Plugin.Type):
try:
p = subprocess.Popen(
command, shell=shell,
- env={k: str(v) for k, v in context.exported.items()},
+ env={k: str(v) for k, v in cr.context.exported.items()},
stdout=out)
except OSError:
print 'Failed to exec', command
# Don't log the trail if we already have
- if context.verbose < _TRAIL_VERBOSITY:
+ if cr.context.verbose < _TRAIL_VERBOSITY:
print 'Variables used to build the command were:'
for key, value in trail:
print ' ', key, '=', value
@@ -116,31 +115,30 @@ class Host(cr.Plugin, cr.Plugin.Type):
return ''
@cr.Plugin.activemethod
- def Shell(self, context, *command):
+ def Shell(self, *command):
command = ' '.join([pipes.quote(arg) for arg in command])
- return self._Execute(context, [command], shell=True,
- ignore_interrupt_signal=True)
+ return self._Execute([command], shell=True, ignore_interrupt_signal=True)
@cr.Plugin.activemethod
- def Execute(self, context, *command):
- return self._Execute(context, command, shell=False)
+ def Execute(self, *command):
+ return self._Execute(command, shell=False)
@cr.Plugin.activemethod
- def ExecuteSilently(self, context, *command):
- return self._Execute(context, command, shell=False, silent=True)
+ def ExecuteSilently(self, *command):
+ return self._Execute(command, shell=False, silent=True)
@cr.Plugin.activemethod
- def CaptureShell(self, context, *command):
- return self._Execute(context, command,
+ def CaptureShell(self, *command):
+ return self._Execute(command,
shell=True, capture=True, ignore_dry_run=True)
@cr.Plugin.activemethod
- def Capture(self, context, *command):
- return self._Execute(context, command, capture=True, ignore_dry_run=True)
+ def Capture(self, *command):
+ return self._Execute(command, capture=True, ignore_dry_run=True)
@cr.Plugin.activemethod
- def ExecuteStatus(self, context, *command):
- return self._Execute(context, command,
+ def ExecuteStatus(self, *command):
+ return self._Execute(command,
ignore_dry_run=True, return_status=True)
@cr.Plugin.activemethod
diff --git a/tools/cr/cr/base/platform.py b/tools/cr/cr/base/platform.py
index db6f66d..0220d9f 100644
--- a/tools/cr/cr/base/platform.py
+++ b/tools/cr/cr/base/platform.py
@@ -39,13 +39,13 @@ class Platform(cr.Plugin, cr.Plugin.Type):
def __init__(self):
super(Platform, self).__init__()
- def Activate(self, context):
- super(Platform, self).Activate(context)
- if _PathFixup not in context.fixup_hooks:
- context.fixup_hooks.append(_PathFixup)
+ def Activate(self):
+ super(Platform, self).Activate()
+ if _PathFixup not in cr.context.fixup_hooks:
+ cr.context.fixup_hooks.append(_PathFixup)
@cr.Plugin.activemethod
- def Prepare(self, context):
+ def Prepare(self):
pass
@property
@@ -53,12 +53,12 @@ class Platform(cr.Plugin, cr.Plugin.Type):
return []
-def _PathFixup(context, key, value):
+def _PathFixup(base, key, value):
"""A context fixup that does platform specific modifications to the PATH."""
if key == 'PATH':
paths = []
- for entry in Platform.GetActivePlugin(context).paths:
- entry = context.Substitute(entry)
+ for entry in Platform.GetActivePlugin().paths:
+ entry = base.Substitute(entry)
if entry not in paths:
paths.append(entry)
for entry in value.split(os.path.pathsep):
diff --git a/tools/cr/cr/commands/build.py b/tools/cr/cr/commands/build.py
index 2d2c27f..1d33130 100644
--- a/tools/cr/cr/commands/build.py
+++ b/tools/cr/cr/commands/build.py
@@ -28,9 +28,9 @@ class BuildCommand(cr.Command):
self.ConsumeArgs(parser, 'the builder')
return parser
- def Run(self, context):
+ def Run(self):
return cr.Builder.Build(
- context, cr.Target.GetTargets(context), context.remains)
+ cr.Target.GetTargets(), cr.context.remains)
class CleanCommand(cr.Command):
@@ -52,9 +52,9 @@ class CleanCommand(cr.Command):
self.ConsumeArgs(parser, 'the builder')
return parser
- def Run(self, context):
+ def Run(self):
return cr.Builder.Clean(
- context, cr.Target.GetTargets(context), context.remains)
+ cr.Target.GetTargets(), cr.context.remains)
class RebuildCommand(cr.Command):
@@ -76,6 +76,6 @@ class RebuildCommand(cr.Command):
self.ConsumeArgs(parser, 'the builder')
return parser
- def Run(self, context):
+ def Run(self):
return cr.Builder.Rebuild(
- context, cr.Target.GetTargets(context), context.remains)
+ cr.Target.GetTargets(), cr.context.remains)
diff --git a/tools/cr/cr/commands/command.py b/tools/cr/cr/commands/command.py
index d2e65a2..d42a688 100644
--- a/tools/cr/cr/commands/command.py
+++ b/tools/cr/cr/commands/command.py
@@ -18,18 +18,16 @@ class Command(cr.Plugin, cr.Plugin.Type):
"""
@classmethod
- def Select(cls, context):
+ def Select(cls):
"""Called to select which command is active.
This picks a command based on the first non - argument on the command
line.
- Args:
- context: The context to select the command for.
Returns:
the selected command, or None if not specified on the command line.
"""
- if context.args:
- return getattr(context.args, '_command', None)
+ if cr.context.args:
+ return getattr(cr.context.args, '_command', None)
return None
def __init__(self):
@@ -59,7 +57,7 @@ class Command(cr.Plugin, cr.Plugin.Type):
epilog=self.epilog,
)
self.parser.set_defaults(_command=self)
- cr.Context.AddCommonArguments(self.parser)
+ cr.context.AddCommonArguments(self.parser)
cr.base.client.AddArguments(self.parser)
return self.parser
@@ -78,27 +76,21 @@ class Command(cr.Plugin, cr.Plugin.Type):
help='The additional arguments to {0}.'.format(reason)
)
- def EarlyArgProcessing(self, context):
+ def EarlyArgProcessing(self):
"""Called to make decisions based on speculative argument parsing.
When this method is called, enough of the command line parsing has been
done that the command is selected. This allows the command to make any
modifications needed before the final argument parsing is done.
-
- Args:
- context: The context that is parsing the arguments.
"""
- cr.base.client.ApplyOutArgument(context)
+ cr.base.client.ApplyOutArgument()
@cr.Plugin.activemethod
- def Run(self, context):
+ def Run(self):
"""The main method of the command.
This is the only thing that a command has to implement, and it should not
call this base version.
- Args:
- context: The context to run the command in.
"""
- _ = context
raise NotImplementedError('Must be overridden.')
diff --git a/tools/cr/cr/commands/debug.py b/tools/cr/cr/commands/debug.py
index 48fb513b..f113691 100644
--- a/tools/cr/cr/commands/debug.py
+++ b/tools/cr/cr/commands/debug.py
@@ -27,14 +27,14 @@ class DebugCommand(cr.Command):
self.ConsumeArgs(parser, 'the binary')
return parser
- def Run(self, context):
- targets = cr.Target.GetTargets(context)
- if not cr.Debugger.ShouldInvoke(context):
- cr.Debugger.Attach(context, targets, context.remains)
- elif cr.Installer.Skipping(context):
- cr.Debugger.Restart(context, targets, context.remains)
+ def Run(self):
+ targets = cr.Target.GetTargets()
+ if not cr.Debugger.ShouldInvoke():
+ cr.Debugger.Attach(targets, cr.context.remains)
+ elif cr.Installer.Skipping():
+ cr.Debugger.Restart(targets, cr.context.remains)
else:
- cr.Builder.Build(context, targets, [])
- cr.Debugger.Kill(context, targets, [])
- cr.Installer.Reinstall(context, targets, [])
- cr.Debugger.Invoke(context, targets, context.remains)
+ cr.Builder.Build(targets, [])
+ cr.Debugger.Kill(targets, [])
+ cr.Installer.Reinstall(targets, [])
+ cr.Debugger.Invoke(targets, cr.context.remains)
diff --git a/tools/cr/cr/commands/info.py b/tools/cr/cr/commands/info.py
index 88af0f5..fcd7307 100644
--- a/tools/cr/cr/commands/info.py
+++ b/tools/cr/cr/commands/info.py
@@ -24,20 +24,20 @@ class InfoCommand(cr.Command):
self.ConsumeArgs(parser, 'the environment')
return parser
- def EarlyArgProcessing(self, context):
- if getattr(context.args, '_short', False):
+ def EarlyArgProcessing(self):
+ if getattr(cr.context.args, '_short', False):
self.requires_build_dir = False
- def Run(self, context):
- if context.remains:
- for var in context.remains:
- if getattr(context.args, '_short', False):
- val = context.Find(var)
+ def Run(self):
+ if cr.context.remains:
+ for var in cr.context.remains:
+ if getattr(cr.context.args, '_short', False):
+ val = cr.context.Find(var)
if val is None:
val = ''
print val
else:
- print var, '=', context.Find(var)
+ print var, '=', cr.context.Find(var)
else:
- cr.base.client.PrintInfo(context)
+ cr.base.client.PrintInfo()
diff --git a/tools/cr/cr/commands/init.py b/tools/cr/cr/commands/init.py
index adcb4a1..5991825 100644
--- a/tools/cr/cr/commands/init.py
+++ b/tools/cr/cr/commands/init.py
@@ -50,13 +50,13 @@ class InitCommand(cr.Command):
)
return parser
- def EarlyArgProcessing(self, context):
- base_settings = getattr(context.args, '_settings', None)
+ def EarlyArgProcessing(self):
+ base_settings = getattr(cr.context.args, '_settings', None)
if base_settings:
self._settings.extend(base_settings)
# Do not call super early processing, we do not want to apply
# the output arg...
- out = cr.base.client.GetOutArgument(context)
+ out = cr.base.client.GetOutArgument()
if out:
# Output directory is fully specified
# We need to deduce other settings from it's name
@@ -68,11 +68,12 @@ class InitCommand(cr.Command):
print 'Specified build type', buildtype, 'is not valid'
print 'Must be one of', ','.join(p.name for p in cr.BuildType.Plugins())
exit(1)
- if context.args.CR_BUILDTYPE and context.args.CR_BUILDTYPE != buildtype:
+ if (cr.context.args.CR_BUILDTYPE and
+ cr.context.args.CR_BUILDTYPE != buildtype):
print 'If --type and --out are both specified, they must match'
- print 'Got', context.args.CR_BUILDTYPE, 'and', buildtype
+ print 'Got', cr.context.args.CR_BUILDTYPE, 'and', buildtype
exit(1)
- platform = context.args.CR_PLATFORM
+ platform = cr.context.args.CR_PLATFORM
if not platform:
# Try to guess platform based on output name
platforms = [p.name for p in cr.Platform.AllPlugins()]
@@ -84,23 +85,23 @@ class InitCommand(cr.Command):
print 'Matched all of', ','.join(matches)
exit(1)
platform = matches[0]
- context.derived.Set(
+ cr.context.derived.Set(
CR_OUT_FULL=out,
CR_OUT_BASE=base,
CR_PLATFORM=platform,
CR_BUILDTYPE=buildtype,
)
- if not 'CR_OUT_BASE' in context:
- context.derived['CR_OUT_BASE'] = 'out_{CR_PLATFORM}'
- if not 'CR_OUT_FULL' in context:
- context.derived['CR_OUT_FULL'] = os.path.join(
+ if not 'CR_OUT_BASE' in cr.context:
+ cr.context.derived['CR_OUT_BASE'] = 'out_{CR_PLATFORM}'
+ if not 'CR_OUT_FULL' in cr.context:
+ cr.context.derived['CR_OUT_FULL'] = os.path.join(
'{CR_OUT_BASE}', '{CR_BUILDTYPE}')
- def Run(self, context):
+ def Run(self):
"""Overridden from cr.Command."""
- src_path = context.Get('CR_SRC')
+ src_path = cr.context.Get('CR_SRC')
if not os.path.isdir(src_path):
- print context.Substitute('Path {CR_SRC} is not a valid client')
+ print cr.context.Substitute('Path {CR_SRC} is not a valid client')
exit(1)
# Ensure we have an output directory override ready to fill in
@@ -109,7 +110,7 @@ class InitCommand(cr.Command):
build_package = cr.auto.build
# Collect the old version (and float convert)
- old_version = context.Find('CR_VERSION')
+ old_version = cr.context.Find('CR_VERSION')
try:
old_version = float(old_version)
except (ValueError, TypeError):
@@ -132,7 +133,7 @@ class InitCommand(cr.Command):
build_package.config.OVERRIDES.Set(CR_VERSION=cr.base.client.VERSION)
# Add all the variables that we always want to have
for name in OUT_CONFIG_VARS:
- value = context.Find(name)
+ value = cr.context.Find(name)
build_package.config.OVERRIDES[name] = value
# Apply the settings from the command line
for setting in self._settings:
@@ -146,16 +147,16 @@ class InitCommand(cr.Command):
# Run all the output directory init hooks
for hook in InitHook.Plugins():
- hook.Run(context, old_version, build_package.config)
+ hook.Run(old_version, build_package.config)
# Redo activations, they might have changed
- cr.plugin.Activate(context)
+ cr.plugin.Activate()
# Write out the new configuration, and select it as the default
- cr.base.client.WriteConfig(context, context.Get('CR_BUILD_DIR'),
+ cr.base.client.WriteConfig(cr.context.Get('CR_BUILD_DIR'),
build_package.config.OVERRIDES.exported)
# Prepare the platform in here, using the updated config
- cr.Platform.Prepare(context)
- cr.SelectCommand.Select(context)
+ cr.Platform.Prepare()
+ cr.SelectCommand.Select()
class InitHook(cr.Plugin, cr.Plugin.Type):
@@ -165,12 +166,11 @@ class InitHook(cr.Plugin, cr.Plugin.Type):
cr.fixups package.
"""
- def Run(self, context, old_version, config):
+ def Run(self, old_version, config):
"""Run the initialization hook.
This is invoked once per init invocation.
Args:
- context: The context of the init command.
old_version: The old version,
0.0 if the old version was bad or missing,
None if building a new output direcory.
diff --git a/tools/cr/cr/commands/install.py b/tools/cr/cr/commands/install.py
index 51a02b3..20e1dff 100644
--- a/tools/cr/cr/commands/install.py
+++ b/tools/cr/cr/commands/install.py
@@ -29,8 +29,8 @@ class InstallCommand(cr.Command):
self.ConsumeArgs(parser, 'the installer')
return parser
- def Run(self, context):
- targets = cr.Target.GetTargets(context)
- if not cr.Installer.Skipping(context):
- cr.Builder.Build(context, targets, [])
- cr.Installer.Reinstall(context, targets, context.remains)
+ def Run(self):
+ targets = cr.Target.GetTargets()
+ if not cr.Installer.Skipping():
+ cr.Builder.Build(targets, [])
+ cr.Installer.Reinstall(targets, cr.context.remains)
diff --git a/tools/cr/cr/commands/prepare.py b/tools/cr/cr/commands/prepare.py
index 57abcce..a9418d9 100644
--- a/tools/cr/cr/commands/prepare.py
+++ b/tools/cr/cr/commands/prepare.py
@@ -26,13 +26,13 @@ class PrepareCommand(cr.Command):
running gyp.
""")
- def Run(self, context):
- self.Prepare(context)
+ def Run(self):
+ self.Prepare()
@classmethod
- def Prepare(cls, context):
+ def Prepare(cls):
for preparation in PrepareOut.Plugins():
- preparation.Prepare(context)
+ preparation.Prepare()
class PrepareOut(cr.Plugin, cr.Plugin.Type):
@@ -41,8 +41,7 @@ class PrepareOut(cr.Plugin, cr.Plugin.Type):
See PrepareCommand for details.
"""
- def Prepare(self, context):
+ def Prepare(self):
"""All PrepareOut plugins must override this method to do their work."""
- _ = context
raise NotImplementedError('Must be overridden.')
diff --git a/tools/cr/cr/commands/run.py b/tools/cr/cr/commands/run.py
index 9b57d94..cbfc421 100644
--- a/tools/cr/cr/commands/run.py
+++ b/tools/cr/cr/commands/run.py
@@ -29,22 +29,22 @@ class RunCommand(cr.Command):
self.ConsumeArgs(parser, 'the binary')
return parser
- def Run(self, context):
- targets = cr.Target.GetTargets(context)
+ def Run(self):
+ targets = cr.Target.GetTargets()
test_targets = [target for target in targets if target.is_test]
run_targets = [target for target in targets if not target.is_test]
- if cr.Installer.Skipping(context):
+ if cr.Installer.Skipping():
# No installer, only build test targets
build_targets = test_targets
else:
build_targets = targets
if build_targets:
- cr.Builder.Build(context, build_targets, [])
+ cr.Builder.Build(build_targets, [])
# See if we can use restart when not installing
- if cr.Installer.Skipping(context):
- cr.Runner.Restart(context, targets, context.remains)
+ if cr.Installer.Skipping():
+ cr.Runner.Restart(targets, cr.context.remains)
else:
- cr.Runner.Kill(context, run_targets, [])
- cr.Installer.Reinstall(context, run_targets, [])
- cr.Runner.Invoke(context, targets, context.remains)
+ cr.Runner.Kill(run_targets, [])
+ cr.Installer.Reinstall(run_targets, [])
+ cr.Runner.Invoke(targets, cr.context.remains)
diff --git a/tools/cr/cr/commands/select.py b/tools/cr/cr/commands/select.py
index 58cebdd..eadd109 100644
--- a/tools/cr/cr/commands/select.py
+++ b/tools/cr/cr/commands/select.py
@@ -40,22 +40,20 @@ class SelectCommand(cr.Command):
help='Don\'t prepare the output directory.'
)
- def Run(self, context):
- self.Select(context)
+ def Run(self):
+ self.Select()
@classmethod
- def Select(cls, context):
+ def Select(cls):
"""Performs the select.
This is also called by the init command to auto select the new output
directory.
- Args:
- context: The cr Context to select in.
"""
cr.base.client.WriteConfig(
- context, context.Get('CR_CLIENT_PATH'), dict(
- CR_OUT_FULL=context.Get('CR_OUT_FULL')))
- cr.base.client.PrintInfo(context)
+ cr.context.Get('CR_CLIENT_PATH'), dict(
+ CR_OUT_FULL=cr.context.Get('CR_OUT_FULL')))
+ cr.base.client.PrintInfo()
# Now we run the post select actions
- if not getattr(context.args, '_no_prepare', None):
- cr.PrepareCommand.Prepare(context)
+ if not getattr(cr.context.args, '_no_prepare', None):
+ cr.PrepareCommand.Prepare()
diff --git a/tools/cr/cr/commands/shell.py b/tools/cr/cr/commands/shell.py
index 452ebb7..2cd338d 100644
--- a/tools/cr/cr/commands/shell.py
+++ b/tools/cr/cr/commands/shell.py
@@ -35,9 +35,9 @@ class ShellCommand(cr.Command):
self.ConsumeArgs(parser, 'the shell')
return parser
- def Run(self, context):
- if context.remains:
- cr.Host.Shell(context, *context.remains)
+ def Run(self):
+ if cr.context.remains:
+ cr.Host.Shell(*cr.context.remains)
return
# If we get here, we are trying to launch an interactive shell
shell = os.environ.get('SHELL', None)
@@ -48,6 +48,6 @@ class ShellCommand(cr.Command):
with tempfile.NamedTemporaryFile() as rcfile:
rcfile.write('source ~/.bashrc\nPS1="'+ps1+'"')
rcfile.flush()
- cr.Host.Execute(context, shell, '--rcfile', rcfile.name)
+ cr.Host.Execute(shell, '--rcfile', rcfile.name)
else:
- cr.Host.Execute(context, shell)
+ cr.Host.Execute(shell)
diff --git a/tools/cr/cr/commands/sync.py b/tools/cr/cr/commands/sync.py
index c18187f..c7e6e70 100644
--- a/tools/cr/cr/commands/sync.py
+++ b/tools/cr/cr/commands/sync.py
@@ -36,17 +36,16 @@ class SyncCommand(cr.Command):
# TODO(iancottrell): clean no-hooks support would be nice.
return parser
- def Run(self, context):
- self.Sync(context, context.remains)
+ def Run(self):
+ self.Sync(cr.context.remains)
@staticmethod
- def Sync(context, args):
+ def Sync(args):
# TODO(iancottrell): we should probably run the python directly,
# rather than the shell wrapper
# TODO(iancottrell): try to help out when the local state is not a good
# one to do a sync in
- cr.Host.Execute(context, '{GCLIENT_BINARY}', 'sync', *args)
-
+ cr.Host.Execute('{GCLIENT_BINARY}', 'sync', *args)
@classmethod
def ClassInit(cls):
diff --git a/tools/cr/cr/config.py b/tools/cr/cr/config.py
index a19b837..5b4ca8e 100644
--- a/tools/cr/cr/config.py
+++ b/tools/cr/cr/config.py
@@ -97,13 +97,13 @@ class Config(cr.visitor.Node):
Returns:
A dynamic value.
"""
- def Resolve(context):
- test = context.Get(condition)
+ def Resolve(base):
+ test = base.Get(condition)
if test:
value = true_value
else:
value = false_value
- return context.Substitute(value)
+ return base.Substitute(value)
return Resolve
@classmethod
@@ -116,11 +116,11 @@ class Config(cr.visitor.Node):
Returns:
value if it resolves, alternate otherwise.
"""
- def Resolve(context):
+ def Resolve(base):
try:
- return context.Substitute(value)
+ return base.Substitute(value)
except KeyError:
- return context.Substitute(alternate)
+ return base.Substitute(alternate)
return Resolve
def __init__(self, name='--', literal=False, export=None, enabled=True):
diff --git a/tools/cr/cr/fixups/arch.py b/tools/cr/cr/fixups/arch.py
index e6ac81c..a756272 100644
--- a/tools/cr/cr/fixups/arch.py
+++ b/tools/cr/cr/fixups/arch.py
@@ -17,7 +17,7 @@ class _ArchInitHookHelper(cr.InitHook):
def _ArchConvert(self, old_arch):
return old_arch
- def Run(self, context, old_version, config):
+ def Run(self, old_version, config):
if old_version is None or not self._VersionTest(old_version):
return
old_arch = config.OVERRIDES.Find(cr.Arch.SELECTOR)
diff --git a/tools/cr/cr/loader.py b/tools/cr/cr/loader.py
index 51dc940..9a5aaca 100644
--- a/tools/cr/cr/loader.py
+++ b/tools/cr/cr/loader.py
@@ -109,6 +109,7 @@ def Scan():
# Try this one again, if progress was made on a possible dependency
remains.append(name)
if remains:
+ print "Cannot load all of", remains
# There are modules that won't import in any order.
# Print all the errors as we can't determine root cause.
for name in remains:
diff --git a/tools/cr/cr/plugin.py b/tools/cr/cr/plugin.py
index 824d2c5d..1dbf9f5 100644
--- a/tools/cr/cr/plugin.py
+++ b/tools/cr/cr/plugin.py
@@ -104,8 +104,8 @@ class Plugin(cr.loader.AutoExport):
self.method = method
def __get__(self, instance, owner):
- def unbound(context, *args, **kwargs):
- active = owner.GetActivePlugin(context)
+ def unbound(*args, **kwargs):
+ active = owner.GetActivePlugin()
if not active:
print 'No active', owner.__name__
exit(1)
@@ -113,10 +113,10 @@ class Plugin(cr.loader.AutoExport):
if not method:
print owner.__name__, 'does not support', self.method.__name__
exit(1)
- return method(context, *args, **kwargs)
+ return method(*args, **kwargs)
- def bound(context, *args, **kwargs):
- return self.method(instance, context, *args, **kwargs)
+ def bound(*args, **kwargs):
+ return self.method(instance, *args, **kwargs)
if instance is None:
return unbound
@@ -167,7 +167,7 @@ class Plugin(cr.loader.AutoExport):
def is_active(self):
return self._is_active
- def Activate(self, unused_context):
+ def Activate(self):
assert not self._is_active
self._is_active = True
for config_root in CONFIG_TYPES:
@@ -265,17 +265,15 @@ class Plugin(cr.loader.AutoExport):
return [plugin for plugin in cls.UnorderedPlugins() if plugin.is_active]
@classmethod
- def GetActivePlugin(cls, context):
+ def GetActivePlugin(cls):
"""Gets the active plugin of type cls.
This method will select a plugin to be the active one, and will activate
the plugin if needed.
- Args:
- context: The context to select the active plugin for.
Returns:
the plugin that is currently active.
"""
- plugin, _ = _GetActivePlugin(cls, context)
+ plugin, _ = _GetActivePlugin(cls)
return plugin
@classproperty
@@ -288,14 +286,14 @@ class Plugin(cr.loader.AutoExport):
return result
@classmethod
- def Select(cls, context):
+ def Select(cls):
"""Called to determine which plugin should be the active one."""
plugin = cls.default
selector = getattr(cls, 'SELECTOR', None)
if selector:
if plugin is not None:
_selectors[selector] = plugin.name
- name = context.Find(selector)
+ name = cr.context.Find(selector)
if name is not None:
plugin = cls.FindPlugin(name)
return plugin
@@ -313,26 +311,26 @@ def ChainModuleConfigs(module):
cr.loader.scan_hooks.append(ChainModuleConfigs)
-def _GetActivePlugin(cls, context):
+def _GetActivePlugin(cls):
activated = False
actives = cls.GetAllActive()
- plugin = cls.Select(context)
+ plugin = cls.Select()
for active in actives:
if active != plugin:
active.Deactivate()
if plugin and not plugin.is_active:
activated = True
- plugin.Activate(context)
+ plugin.Activate()
return plugin, activated
-def Activate(context):
+def Activate():
"""Activates a plugin for all known plugin types."""
types = Plugin.Type.__subclasses__()
modified = True
while modified:
modified = False
for child in types:
- _, activated = _GetActivePlugin(child, context)
+ _, activated = _GetActivePlugin(child)
if activated:
modified = True
diff --git a/tools/cr/cr/targets/target.py b/tools/cr/cr/targets/target.py
index 0780ae9..295d59d 100644
--- a/tools/cr/cr/targets/target.py
+++ b/tools/cr/cr/targets/target.py
@@ -31,9 +31,8 @@ class Target(cr.Config, cr.AutoExport):
# TODO(iancottrell): support the other test types
TEST_TYPES = [NOT_A_TEST, NORMAL_TEST]
- def __init__(self, context, target_name):
+ def __init__(self, target_name):
super(Target, self).__init__(target_name)
- self.context = context
test_type = None
if self.TEST_PATTERN.search(target_name):
test_type = self.NORMAL_TEST
@@ -45,7 +44,7 @@ class Target(cr.Config, cr.AutoExport):
CR_RUN_ARGUMENTS='',
CR_TEST_TYPE=test_type,
)
- self.AddChildren(config, context)
+ self.AddChildren(config, cr.context)
if hasattr(self, 'CONFIG'):
self.AddChild(self.CONFIG)
if not self.valid:
@@ -59,15 +58,15 @@ class Target(cr.Config, cr.AutoExport):
@property
def verbose(self):
- return self.context.verbose
+ return cr.context.verbose
@property
def dry_run(self):
- return self.context.dry_run
+ return cr.context.dry_run
@property
def valid(self):
- return cr.Builder.IsTarget(self.context, self.build_target)
+ return cr.Builder.IsTarget(self.build_target)
@property
def is_test(self):
@@ -94,14 +93,13 @@ class Target(cr.Config, cr.AutoExport):
yield t
@classmethod
- def CreateTarget(cls, context, target_name):
+ def CreateTarget(cls, target_name):
"""Attempts to build a target by name.
This searches the set of installed targets in priority order to see if any
of them are willing to handle the supplied name.
If a target cannot be found, the program will be aborted.
Args:
- context: The context to run in.
target_name: The name of the target we are searching for.
Returns:
The target that matched.
@@ -112,12 +110,12 @@ class Target(cr.Config, cr.AutoExport):
reverse=True
)
for handler in target_clses:
- target = handler.Build(context, target_name)
+ target = handler.Build(target_name)
if target:
if not target.valid:
print 'Invalid target {0} as {1}'.format(
target_name, target.build_target)
- guesses = cr.Builder.GuessTargets(context, target_name)
+ guesses = cr.Builder.GuessTargets(target_name)
if guesses:
print 'Did you mean {0}?'.format(
', '.join(guesses[:-1]) + ' or ' + guesses[-1]
@@ -128,19 +126,19 @@ class Target(cr.Config, cr.AutoExport):
exit(1)
@classmethod
- def GetTargets(cls, context):
- target_names = getattr(context.args, '_targets', None)
+ def GetTargets(cls):
+ target_names = getattr(cr.context.args, '_targets', None)
if not target_names:
- target_names = [context.Get('CR_DEFAULT_TARGET')]
+ target_names = [cr.context.Get('CR_DEFAULT_TARGET')]
elif hasattr(target_names, 'swapcase'):
# deal with the single target case
target_names = [target_names]
- return [cls.CreateTarget(context, target_name)
+ return [cls.CreateTarget(target_name)
for target_name in target_names]
@classmethod
- def Build(cls, context, target_name):
- return cls(context, target_name)
+ def Build(cls, target_name):
+ return cls(target_name)
class NamedTarget(Target):
@@ -153,10 +151,10 @@ class NamedTarget(Target):
PRIORITY = Target.PRIORITY + 1
@classmethod
- def Build(cls, context, target_name):
+ def Build(cls, target_name):
try:
if target_name == cls.NAME:
- return cls(context, target_name)
+ return cls(target_name)
except AttributeError:
pass
return None
diff --git a/tools/cr/main.py b/tools/cr/main.py
index dced8cd..3dd63bd 100644
--- a/tools/cr/main.py
+++ b/tools/cr/main.py
@@ -13,6 +13,7 @@ import cr
import cr.auto.user
import cr.autocomplete
import cr.loader
+import cr.base.context
_CONTACT = 'iancottrell@chromium.org'
@@ -32,63 +33,67 @@ def Main():
cr.loader.Scan()
# Build the command context
- context = cr.Context(
+ with cr.base.context.Create(
description='The chrome dev build tool.',
epilog='Contact ' + _CONTACT + ' if you have issues with this tool.',
- )
- # Install the sub-commands
- for command in cr.Command.Plugins():
- context.AddSubParser(command)
+ ) as context:
- # test for the special autocomplete command
- if context.autocompleting:
- # After plugins are loaded so pylint: disable=g-import-not-at-top
- cr.autocomplete.Complete(context)
- return
- # Speculative argument processing to add config specific args
- context.ParseArgs(True)
- cr.plugin.Activate(context)
- # At this point we should know what command we are going to use
- command = cr.Command.GetActivePlugin(context)
- # Do some early processing, in case it changes the build dir
- if command:
- command.EarlyArgProcessing(context)
- # Update the activated set again, in case the early processing changed it
- cr.plugin.Activate(context)
- # Load the build specific configuration
- found_build_dir = cr.base.client.LoadConfig(context)
- # Final processing or arguments
- context.ParseArgs()
- cr.plugin.Activate(context)
- # If we did not get a command before, it might have been fixed.
- if command is None:
- command = cr.Command.GetActivePlugin(context)
- # If the verbosity level is 3 or greater, then print the environment here
- if context.verbose >= 3:
- context.DumpValues(context.verbose > 3)
- if command is None:
- print context.Substitute('No command specified.')
- exit(1)
- if command.requires_build_dir:
- if not found_build_dir:
- if not context.Find('CR_OUT_FULL'):
- print context.Substitute(
- 'No build directory specified. Please use cr init to make one.')
- else:
- print context.Substitute(
- 'Build {CR_BUILD_DIR} not a valid build directory')
- exit(1)
- if context.Find('CR_VERSION') != cr.base.client.VERSION:
- print context.Substitute(
- 'Build {CR_BUILD_DIR} is for the wrong version of cr')
- print 'Please run cr init to reset it'
+ # Try to detect the current client information
+ cr.base.client.DetectClient()
+
+ # Install the sub-commands
+ for command in cr.Command.Plugins():
+ cr.context.AddSubParser(command)
+
+ # test for the special autocomplete command
+ if cr.context.autocompleting:
+ # After plugins are loaded so pylint: disable=g-import-not-at-top
+ cr.autocomplete.Complete()
+ return
+ # Speculative argument processing to add config specific args
+ cr.context.ParseArgs(True)
+ cr.plugin.Activate()
+ # At this point we should know what command we are going to use
+ command = cr.Command.GetActivePlugin()
+ # Do some early processing, in case it changes the build dir
+ if command:
+ command.EarlyArgProcessing()
+ # Update the activated set again, in case the early processing changed it
+ cr.plugin.Activate()
+ # Load the build specific configuration
+ found_build_dir = cr.base.client.LoadConfig()
+ # Final processing or arguments
+ cr.context.ParseArgs()
+ cr.plugin.Activate()
+ # If we did not get a command before, it might have been fixed.
+ if command is None:
+ command = cr.Command.GetActivePlugin()
+ # If the verbosity level is 3 or greater, then print the environment here
+ if cr.context.verbose >= 3:
+ cr.context.DumpValues(cr.context.verbose > 3)
+ if command is None:
+ print cr.context.Substitute('No command specified.')
exit(1)
- cr.Platform.Prepare(context)
- if context.verbose >= 1:
- print context.Substitute(
- 'Running cr ' + command.name + ' for {CR_BUILD_DIR}')
- # Invoke the given command
- command.Run(context)
+ if command.requires_build_dir:
+ if not found_build_dir:
+ if not cr.context.Find('CR_OUT_FULL'):
+ print cr.context.Substitute(
+ 'No build directory specified. Please use cr init to make one.')
+ else:
+ print cr.context.Substitute(
+ 'Build {CR_BUILD_DIR} not a valid build directory')
+ exit(1)
+ if cr.context.Find('CR_VERSION') != cr.base.client.VERSION:
+ print cr.context.Substitute(
+ 'Build {CR_BUILD_DIR} is for the wrong version of cr')
+ print 'Please run cr init to reset it'
+ exit(1)
+ cr.Platform.Prepare()
+ if cr.context.verbose >= 1:
+ print cr.context.Substitute(
+ 'Running cr ' + command.name + ' for {CR_BUILD_DIR}')
+ # Invoke the given command
+ command.Run()
if __name__ == '__main__':
sys.exit(Main())