Quickstart¶
Here’s an example script, quickstart.py.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This file is formatted slightly differently for readability in ReadTheDocs.
"""python-scriptharness quickstart example.
This file can be found in the examples/ directory of the source at
https://github.com/scriptharness/python-scriptharness
"""
from __future__ import absolute_import, division, print_function, \
unicode_literals
import scriptharness
import scriptharness.commands
"""First, define functions for all actions. Each action MUST have a function
defined. The function should be named the same as the action. (If the
action has a `-` in it, replace it with an `_`; e.g. an action named
`upload-to-s3` would call the `upload_to_s3()` function. Each action function
will take a single argument, `context`.
Each action function should be idempotent, and able to run standalone.
In this example, `package` may require that the steps in `build` ran at
some point before `package` is run, but we can't assume that happened in
the same script run. It could have happened yesterday, or three weeks ago,
and `package` should still be able to run. If you need to save state
between actions, consider saving state to disk.
"""
def clobber(context):
"""Clobber the source"""
context.logger.info("log message from clobber")
def pull(context):
"""Pull source"""
context.logger.info("log message from pull")
def build(context):
"""Build source"""
context.logger.info("log message from build")
if context.config.get("new_argument"):
context.logger.info("new_argument is set to %s",
context_config['new_argument'])
def package(context):
"""Package source"""
context.logger.info("log message from package")
scriptharness.commands.run(
['python', '-c',
"from __future__ import print_function; print('hello world!')"]
)
def upload(context):
"""Upload packages"""
context.logger.info("log message from upload")
def notify(context):
"""Notify watchers"""
context.logger.info("log message from notify")
if __name__ == '__main__':
"""Enable logging to screen + artifacts/log.txt. Not required, but
without it the script will run silently.
"""
scriptharness.prepare_simple_logging("artifacts/log.txt")
"""Define actions. All six actions are available to run, but if the
script is run without any action commandline options, only the
enabled actions will run.
If default_actions is specified, it MUST be a subset of all_actions
(the first list), and any actions in default_actions will be enabled
by default (the others will be disabled). If default_actions isn't
specified, all the actions are enabled.
Each action MUST have a function defined (see above).
"""
actions = scriptharness.get_actions_from_list(
["clobber", "pull", "build", "package", "upload", "notify"],
default_actions=["pull", "build", "package"]
)
"""Create a commandline argument parser, with default scriptharness
argument options pre-populated.
"""
template = scriptharness.get_config_template(all_actions=actions)
"""Add new commandline argument(s)
https://docs.python.org/dev/library/argparse.html#argparse.ArgumentParser.add_argument
"""
template.add_argument("--new-argument", action='store',
help="help message for --new-argument")
"""Create the Script object. If ``get_script()`` is called a second time,
it will return the same-named script object. (`name` in get_script()
defaults to "root". We'll explore running multiple Script objects within
the same script in the not-distant future.)
When this Script object is created, it will parse all commandline
arguments sent to the script. So it doesn't matter that this script
(quickstart.py) didn't have the --new-argument option until one line
above; the Script object will parse it and store the new_argument
value in its config.
"""
script = scriptharness.get_script(actions=actions, template=template)
"""This will run the script.
Essentially, it will go through the list of actions, and if the action
is enabled, it will run the associated function.
"""
script.run()
output¶
If you run this without any arguments, you might get output like this:
$ ./quickstart.py
00:00:00 INFO - Starting at 2015-06-21 00:00 PDT.
00:00:00 INFO - Enabled actions:
00:00:00 INFO - pull, build, package
00:00:00 INFO - {'new_argument': None,
00:00:00 INFO - 'scriptharness_artifact_dir': '/src/python-scriptharness/docs/artifacts',
00:00:00 INFO - 'scriptharness_base_dir': '/src/python-scriptharness/docs',
00:00:00 INFO - 'scriptharness_work_dir': '/src/python-scriptharness/docs/build'}
00:00:00 INFO - Creating directory /src/python-scriptharness/docs/artifacts
00:00:00 INFO - Already exists.
00:00:00 INFO - ### Skipping action clobber
00:00:00 INFO - ### Running action pull
00:00:00 INFO - log message from pull
00:00:00 INFO - ### Action pull: finished successfully
00:00:00 INFO - ### Running action build
00:00:00 INFO - log message from build
00:00:00 INFO - ### Action build: finished successfully
00:00:00 INFO - ### Running action package
00:00:00 INFO - log message from package
00:00:00 INFO - Running command: ['python', '-c', "from __future__ import print_function; print('hello world!')"]
00:00:00 INFO - Copy/paste: python -c "from __future__ import print_function; print('hello world!')"
00:00:00 INFO - hello world!
00:00:00 INFO - ### Action package: finished successfully
00:00:00 INFO - ### Skipping action upload
00:00:00 INFO - ### Skipping action notify
00:00:00 INFO - Done.
First, it announced it’s starting the script. Next, it outputs the running
config, also saving it to the file artifacts/localconfig.json
. Then it
logs each action as it runs enabled actions and skips disabled actions.
Finally, it announces ‘Done.’.
The same output is written to the file artifacts/log.txt
.
--actions
¶
You can change which actions are run via the --actions
option:
$ ./quickstart.py --actions package upload notify
00:00:05 INFO - Starting at 2015-06-21 00:00 PDT.
00:00:05 INFO - Enabled actions:
00:00:05 INFO - package, upload, notify
00:00:05 INFO - {'new_argument': None,
00:00:05 INFO - 'scriptharness_artifact_dir': '/src/python-scriptharness/docs/artifacts',
00:00:05 INFO - 'scriptharness_base_dir': '/src/python-scriptharness/docs',
00:00:05 INFO - 'scriptharness_work_dir': '/src/python-scriptharness/docs/build'}
00:00:05 INFO - Creating directory /src/python-scriptharness/docs/artifacts
00:00:05 INFO - Already exists.
00:00:05 INFO - ### Skipping action clobber
00:00:05 INFO - ### Skipping action pull
00:00:05 INFO - ### Skipping action build
00:00:05 INFO - ### Running action package
00:00:05 INFO - log message from package
00:00:05 INFO - Running command: ['python', '-c', "from __future__ import print_function; print('hello world!')"]
00:00:05 INFO - Copy/paste: python -c "from __future__ import print_function; print('hello world!')"
00:00:05 INFO - hello world!
00:00:05 INFO - ### Action package: finished successfully
00:00:05 INFO - ### Running action upload
00:00:05 INFO - log message from upload
00:00:05 INFO - ### Action upload: finished successfully
00:00:05 INFO - ### Running action notify
00:00:05 INFO - log message from notify
00:00:05 INFO - ### Action notify: finished successfully
00:00:05 INFO - Done.
For more, see Enabling and Disabling Actions.
--list-actions
¶
If you want to list which actions are available, and which are enabled by
default, use the --list-actions
option:
$ ./quickstart.py --list-actions
clobber ['all']
* pull ['all']
* build ['all']
* package ['all']
upload ['all']
notify ['all']
--dump-config
¶
You can change the new_argument
value in the config via the
--new-argument
option that the script added. Also, if you just want to
see what the config is without running anything, you can use the
--dump-config
option:
$ ./quickstart.py --new-argument foo --dump-config
00:00:14 INFO - Dumping config:
00:00:14 INFO - {'new_argument': 'foo',
00:00:14 INFO - 'scriptharness_artifact_dir': '/src/python-scriptharness/docs/artifacts',
00:00:14 INFO - 'scriptharness_base_dir': '/src/python-scriptharness/docs',
00:00:14 INFO - 'scriptharness_work_dir': '/src/python-scriptharness/docs/build'}
00:00:14 INFO - Creating directory /src/python-scriptharness/docs/artifacts
00:00:14 INFO - Already exists.
--help
¶
You can always use the --help
option:
$ ./quickstart.py --help
usage: quickstart.py [-h] [--opt-config-file CONFIG_FILE]
[--config-file CONFIG_FILE] [--dump-config]
[--actions ACTION [ACTION ...]]
[--skip-actions ACTION [ACTION ...]]
[--add-actions ACTION [ACTION ...]] [--list-actions]
[--action-group {none,all}] [--new-argument NEW_ARGUMENT]
optional arguments:
-h, --help show this help message and exit
--opt-config-file CONFIG_FILE, --opt-cfg CONFIG_FILE
Specify optional config files/urls
--config-file CONFIG_FILE, --cfg CONFIG_FILE, -c CONFIG_FILE
Specify required config files/urls
--dump-config Log the built configuration and exit.
--actions ACTION [ACTION ...]
Specify the actions to run.
--skip-actions ACTION [ACTION ...]
Specify the actions to skip.
--add-actions ACTION [ACTION ...]
Specify the actions to add to the default set.
--list-actions List all actions (default prepended with '*') and
exit.
--action-group {none,all}
Specify the action group to use.
--new-argument NEW_ARGUMENT
help message for --new-argument