L'enfer, c'est les .bats
Jean-Paul Start is verbose about plugin loading, batch loading and parsing, task execution, ...
Be sure to set your logging level to INFO if needed
python -m jeanpaulstart -f path/to/a/batch.ymlimport jeanpaulstart
jeanpaulstart.run_from_filepath('path/to/a/batch.yml')Tasks can be run step by step, so progress can be forwarded to the user
Here, ui stands for any class that represents a window or dialog
import jeanpaulstart
executor = jeanpaulstart.executor_from_filepath('path/to/a/batch.yml')
while not executor.has_stopped:
ui.set_status_message(executor.next_task.name)
status, messages = executor.step()
if status != jeanpaulstart.OK:
ui.set_status_message(' '.join([messages[-1], status]))
ui.set_progress(executor.progress)
if executor.success:
ui.set_status_message('Execution OK !')
ui.set_progress(0.0)Batch are redacted in YAML or JSON, in a way similar to Ansible playbooks
A batch describes
- a name
- an icon path
- tags
- an environment (through variables, can be omitted)
- tasks to perform
---
name: Jean Bauchefort
icon_path: $ENVIRONMENT/_config/jeanpaulstart/icons/jean-bauchefort.png
tags:
- production
environment:
PYTHONPATH:
- C:\cube\python\Lib\site-packages
- R:\deploy\cube
tasks:
- name: Running application
raw:
command: python -m jeanbauchefortui
...For a complete example please read example-batch.yml
A YAML file represents how usernames (based on os.getpass.getuser()) are associated with batch tags
Example
---
production:
- jp.sartre
- p.deproges
graphist_base:
- y.montand
- j.hallyday
rigging:
- s.weaver
- j.rochefort
...Batches with 'production' tag will show for jp.sartre
- Special character
$allows to reference a group withing another group
everyone:
- $production
- $graphist_base
- $rigging
- m.polnareff
...Each task is identified by a command name
Tasks are written as plugins, in the package jeanpaulstart.tasks, they must conform to what the plugin loader expects
Copies a file
If destination exists and force: no, nothing will happen
- name: Name of task
copy:
src: /path/to/source.ext
dest: /path/to/destination.ext
force: [yes|no]Creates a file
Use state: directory if you want to create a directory
Use state: absent if you want to remove a file, or a directory and its subdirectories
- name: Name of task
file:
path: /path/to/file
state: [directory|absent]Runs another batch file
Current environment is passed to executed batch, modifications made by that batch to the environment are not kept
- name: Name
include_tasks:
file: path/to/batch/file.ymlModifies a config file (.ini)
- name: Task Name
ini_file:
src: /path/to/ini/file.ini
state: [present|absent]
section: sectionName
option: optionName
value: valueValueRuns pip install / pip3 install
Please make sure that pip / pip3 is in your $PATH
Parameter state is not mandatory, defaults to present
- name: Task Name
pip:
name: PySide
state: [present|forcereinstall]- name: Task Name
pip3:
name: PySide
state: [present|forcereinstall]- name: Task Name
pip:
name: git+http://some/url.gitRun a command in the terminal
Parameter async spawns a new process (Popen())
Parameter open_terminal opns a new terminal window
async defaults to True
open_terminal defaults to False
If the exit code of the command is 0, jeanpaulstart.OK is return, else the exit code is returned
If async: yes, jeanpaulstart.OK is immediately returned
- name: Launch djv_view
raw:
command: "\"C:\\Program Files\\djv-1.1.0-Windows-64\\bin\\djv_view.exe\""
async:[yes|no]
open_terminal:[yes|no]Copy a file and applies Jinja2 templating, based on environment variables
Parameter force: yes will overwrite destination if it already exists
- name: Task Name
template:
src: /path/to/source.ext.j2
dest: /path/to/dest.ext
force: [yes|no]Opens the given url in the default browser
- name: Task Name
url: http://some.url/Registers the current datetime, formatted, to an environment variable
- name: Register Timestamp
datetime:
variable: LOG_TIMESTAMP
format: "%y%m%d-%H%M%S"Enable or disable the windows error reporting dialog when the application crashs
- name: Task Name
win_err_reporting_dialog:
state: [present|absent]All tasks have 4 flags that can be set besides the command and its arguements.
register_statusdefaults toFalseornocatch_exceptiondefaults toFalseornoexit_if_not_okdefaults toTrueoryeswhendefaults to"True"
register_status memorises the status returned by the task, and stores this
status in the environment variable $JPS_REGISTERED_STATUS, immediately available for the next task
The executor returns the last registered status
All tasks must return OK, maybe something else if something went wrong.
Most tasks should not raise any exception (exception should be dealt with when writing the task plugin), but it can happen (e.g when a socket is busy, a file missing, ...)
Those two flags are used to control batch execution, when task execution doesn't return OK,
or when an Exception is raised.
If catch_exception is set to True or yes, exit_if_not_ok is forced to False or no
Here is a table of what happens on different cases
| Task return | catch_exception=Trueexit_if_not_ok=False |
catch_exception=Falseexit_if_not_ok=True |
|---|---|---|
OK |
execution continues | execution continues |
not OK but no Exception is raised |
execution continues | batch is exited status is returned |
| Exception raised | exception is catched TASK_ERROR_IGNORED is returned execution continues |
exception is raised |
The when clause allows to specify a python expression that will be evaluated
If that expression doesn't evaluates to True, task is skipped
Environment variables can be used. For example
tasks:
- name: Render Image Sequence
raw:
command: $BLENDER_BIN --enable-autoexec ...
async: False
open_terminal: True
register_status: True
- name: Make mov
raw:
command: python -m preview ....
when: $JPS_REGISTERED_STATUS == 'OK'
register_status: TrueThe "Make mov" task will be run only if the task "Render Image Sequence" returns OK
If the when clause evaluates to False and register_status is on, no status will be
registered