Better support for multiple commands
This changes the 'commands' YAML portion to be an array. E.g.: commands: - ls - ps - echo 'Have you tried turning it off and on again?' Docker doesn't really support issuing multiple commands to a container on the command line very well. You have to either munge it with something like: sh -c 'ls && ps' or place all of the commands to execute into a master script, then execute that script. This change proposes the second option and creates a master script if the number of commands is more than one. The master script file will be created in a .dox subdirectory of the current directory, and named master_script.sh. Right now, it is created as a Bourne shell script. We could easily add support later for different shells. If the -c option is used, then the command specified is the only command that will run. If -c is NOT used, but extra arguments are supplied, these extra arguments will be used to replace the {posargs} placeholders in tox.ini files. The extra args are not currently used elsewhere. This change REMOVES the ability to add extra_args to the end of the command when {posargs} is NOT present. That does not make sense in a multi-command situation. Change-Id: I78dbc0613f5db22cea0ed714f5f30ef0207fac24
This commit is contained in:
parent
a21659d31e
commit
0339a34458
|
@ -89,8 +89,10 @@ def run_dox(args):
|
|||
# Get Command
|
||||
if args.command:
|
||||
command = dox.config.cmdline.CommandLine(args.extra_args)
|
||||
logger.debug("Command source is the command line")
|
||||
else:
|
||||
command = dox.commands.Commands(args.extra_args)
|
||||
logger.debug("Command source is %s" % command.source.source_name())
|
||||
|
||||
# Run
|
||||
try:
|
||||
|
@ -98,6 +100,5 @@ def run_dox(args):
|
|||
command=command)
|
||||
map(run, images)
|
||||
except Exception:
|
||||
logger.error(
|
||||
"Operation failed, aborting dox.", exc_info=args.debug)
|
||||
logger.error("Operation failed, aborting dox.", exc_info=args.debug)
|
||||
return 1
|
||||
|
|
|
@ -19,12 +19,12 @@ __all__ = [
|
|||
]
|
||||
|
||||
import logging
|
||||
import os
|
||||
|
||||
import dox.config.dox_yaml
|
||||
import dox.config.tox_ini
|
||||
import dox.config.travis_yaml
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
@ -37,7 +37,6 @@ def get_commands():
|
|||
|
||||
for source in (dox_yaml, tox_ini, travis_yaml):
|
||||
if source.exists():
|
||||
logger.debug("Command source is: %s" % source.source_name())
|
||||
return source
|
||||
raise Exception("dox cannot figure out what command to run")
|
||||
|
||||
|
@ -49,12 +48,42 @@ class Commands(object):
|
|||
self.args = []
|
||||
self.extra_args = extra_args
|
||||
|
||||
def _test_command_as_script(self, commands, shell='/bin/sh'):
|
||||
"""Combine test commands into a master script file.
|
||||
|
||||
The script, using the given shell, will be created in the .dox
|
||||
subdirectory of the current directory.
|
||||
|
||||
:param commands: A list of commands to execute.
|
||||
:param shell: Path to the OS shell to run the commands.
|
||||
"""
|
||||
dox_dir = '.dox'
|
||||
master_script = os.path.join(dox_dir, 'master_script.sh')
|
||||
|
||||
if not os.path.exists(dox_dir):
|
||||
os.mkdir(dox_dir, 0o755)
|
||||
|
||||
with open(master_script, "w") as f:
|
||||
f.write("#!" + shell + "\n")
|
||||
f.write("\n".join(commands))
|
||||
f.write("\n")
|
||||
|
||||
os.chmod(master_script, 0o700)
|
||||
return master_script
|
||||
|
||||
def test_command(self):
|
||||
"""Return the command to execute in the container.
|
||||
|
||||
If there is more than one command, we combine them into a master
|
||||
script to execute. Otherwise, we just issue the command normally
|
||||
on the docker command line.
|
||||
"""
|
||||
commands = self.source.get_commands(self.extra_args)
|
||||
if hasattr(commands, 'append'):
|
||||
ret = "\n".join(commands)
|
||||
else:
|
||||
ret = commands + ' ' + ' '.join(self.args)
|
||||
|
||||
if len(commands) > 1:
|
||||
return self._test_command_as_script(commands)
|
||||
|
||||
ret = commands[0] + ' ' + ' '.join(self.args)
|
||||
return ret.strip()
|
||||
|
||||
def prep_commands(self):
|
||||
|
|
|
@ -54,7 +54,7 @@ class DoxYaml(base.ConfigBase):
|
|||
return self._open_dox_yaml().get('images', [])
|
||||
|
||||
def get_commands(self, extra_args):
|
||||
return " ".join([self._open_dox_yaml().get('commands')] + extra_args)
|
||||
return self._open_dox_yaml().get('commands', [])
|
||||
|
||||
def get_prep_commands(self):
|
||||
return self._open_dox_yaml().get('prep', [])
|
||||
|
|
|
@ -56,15 +56,22 @@ class ToxIni(base.ConfigBase):
|
|||
return ini.get('docker', 'images', '').split(',')
|
||||
|
||||
def get_commands(self, extra_args, section='testenv'):
|
||||
"""Get commands to run from the config file.
|
||||
|
||||
If any of the commands contain the string '{posargs}', then this
|
||||
is replaced with the extra_args value.
|
||||
"""
|
||||
ini = self._open_tox_ini()
|
||||
commands = ini.get(section, 'commands')
|
||||
commands = ini.get(section, 'commands').split("\n")
|
||||
extra_args = " ".join(extra_args)
|
||||
if '{posargs}' in commands:
|
||||
commands = commands.replace('{posargs}', extra_args)
|
||||
else:
|
||||
commands += " "
|
||||
commands += extra_args
|
||||
return commands
|
||||
|
||||
scrubbed = []
|
||||
for cmd in commands:
|
||||
if '{posargs}' in cmd:
|
||||
scrubbed.append(cmd.replace('{posargs}', extra_args))
|
||||
else:
|
||||
scrubbed.append(cmd)
|
||||
return scrubbed
|
||||
|
||||
def get_prep_commands(self):
|
||||
ini = self._open_tox_ini()
|
||||
|
|
|
@ -39,20 +39,20 @@ class TestCommands(base.TestCase):
|
|||
scenarios = [
|
||||
('dox_yaml', dict(
|
||||
dox_yaml=True, tox_ini=False, travis_yaml=False,
|
||||
dox_value="testr run", tox_value=None, travis_value=None,
|
||||
dox_value=["testr run"], tox_value=None, travis_value=None,
|
||||
commands="testr run")),
|
||||
('dox_yaml_ignore_others', dict(
|
||||
dox_yaml=True, tox_ini=True, travis_yaml=True,
|
||||
dox_value="testr run", tox_value="setup.py test",
|
||||
travis_value="gem test",
|
||||
dox_value=["testr run"], tox_value=["setup.py test"],
|
||||
travis_value=["gem test"],
|
||||
commands="testr run")),
|
||||
('tox_ini', dict(
|
||||
dox_yaml=False, tox_ini=True, travis_yaml=False,
|
||||
dox_value=None, tox_value="setup.py test", travis_value=None,
|
||||
dox_value=None, tox_value=["setup.py test"], travis_value=None,
|
||||
commands="setup.py test")),
|
||||
('travis_yaml', dict(
|
||||
dox_yaml=False, tox_ini=False, travis_yaml=True,
|
||||
dox_value="testr run", tox_value=None, travis_value="ruby",
|
||||
dox_value=["testr run"], tox_value=None, travis_value=["ruby"],
|
||||
commands="ruby")),
|
||||
]
|
||||
|
||||
|
|
|
@ -51,10 +51,7 @@ class TestToxIni(base.TestCase):
|
|||
self.toxini.get_images())
|
||||
|
||||
def test_get_commands(self):
|
||||
self.assertEqual('foobar -c',
|
||||
self.toxini.get_commands(['-c']))
|
||||
|
||||
self.assertEqual('foobar -c blah',
|
||||
self.assertEqual(['foobar -c blah'],
|
||||
self.toxini.get_commands(
|
||||
['-c'], section='testenv2'))
|
||||
|
||||
|
|
Loading…
Reference in New Issue