flmake

Managing FLASH simulations can be a tedious task for both new and experienced users. The flmake command line utility eases the simulation/development cycle by providing a modular tool that implements many common elements of a user’s workflow. Thus, flmake replaces the following workflow tasks:

  • setup/configuration
  • building
  • execution
  • logging
  • analysis & post-processing
  • and many others!

Another important aim of the flmake infrastructure is to have every FLASH run be completely reproducible on a wide variety of systems. This document is not intended as a flmake user’s guide. Rather these docs provide the API that flmake itself uses. This sub-package is called flmake:

import flash.flmake

writing additional flmake commands

Exposing new commands to flmake and expanding the FLASH workflow options is a simple task which is explained in detail here. The flmake utility uses a dynamic registration pattern to find commands. Three tasks must be completed add a command to flmake:

  • register the main command function,
  • register the help/usage string or function,
  • and write command-specific bash completion (optional).

As a fictional example, suppose that FLASH requires delicious, slightly burnt bread. A toast command seems imminent...


main function

Every flmake command must have a main function which can have any name, but is by convention main(). This function must have a very specific signature:

flash.flmake.toast.main(opts, rc, msg)
Parameters :

opts : list

The command line arguments, as a list of strings, that come after the flmake command. For flmake mv dir1 dir2 opts would be ['dir1', 'dir2'].

rc : dict

The run control dictionary or an empty dict if the flashrc.py does not exist.

msg : str or None

The message given by the user on the command line or None if no message was supplied.

Therefore, a toast command’s main function - which accepts a toastiness level - may be implemented in a toast.py module:

from flash.flmake import logger

def main(opts, rc, msg):
    """Makes delicious toast for you."""
    toastiness = int(opts[0]) if 0 < len(opts) else 5

    print "Engage the bread warming!"

    if msg is None:
        msg = "Toasting to level {}".format(toastiness)
    logger.info(msg, "toast")

Moreover, the docstring of this function is used by flmake help as the command’s summary description.

This function must then be registered with the main flamke command itself. This is done by adding an entry to the commands dictionary in the flash.flmake.main module. The keys in the dictionary are the names of the commands at the command line. The values are 2-tuples of module relative import paths and the name of the main function in this module:

commands = {
    'setup': ('setup', 'main'),
    'build': ('build', 'main'),
    'run': ('run', 'main'),
    'ls-runs': ('lsruns', 'main'),
    # ...
    'toast': ('toast', 'main'),
    }

Enterprising developers may alter the commands dictionary from the flashrc.py run control file as flmake itself is running!


help/usage

Similar to the commands main function, the flmake help command requires a usage string which may be dynamically registered. The usage object may be a string or a function which takes no arguments and returns a string. The latter function pattern is useful if the usage string may change based on the state of the system. Both static and dynamic examples are presented below:

import os

# static
USAGE = ("In flmake, command toasts you!\n\n"
         "usage: flmake toast [<toastiness>]")

# dynamic
def usage():
    slices = len(os.listdir('.'))
    msg = "You can make {} pieces of toast!".format(slices)

This string or function object must then be added to the messages dictionary in the flash.flmake.help_cmd module. The keys are the same as the keys in the flmake main commands dictionary. The values are the usage objects themselves. For example:

from . import build
from . import run
from . import restart
from . import clean
from . import metadata
from . import merge
# ...
from . import toast

messages = {
    'build': build.usage,
    'run': run.usage,
    'restart': restart.usage,
    'merge': merge.USAGE,
    'clean': clean.USAGE,
    'metadata': metadata.USAGE,
    # ...
    'toast': toast.USAGE,
    }

bash completion

An optional, but useful, component of flmake is its support for bash completion. This is the tool whereby pressing tab on the command line the potential valid options are automatically filled in. Currently, whenever the Python API is installed the flmake bash completion file is regenerated.

Therefore to add new command-specific options to flmake’s bash completion the ${FLASH_SRC_DIR}/tools/setup.py file must be edited. This module contains a template that may be adjusted as needed.

Please refer to this tutorial for the new command’s completion needs (part 1, part 2).

Table Of Contents

Previous topic

Configuration Language

Next topic

build

This Page