RTS & Python ToolsΒΆ

Craftr allows you to create Python (command-line) Tools inside the Craftfile that Ninja can call through the Craftr RTS (runtime server). These tools are all executed in the same Craftr process, thus being very efficient since the Craftfile does not need to be re-evaluated with each invocation.

You will see something like craftr-rts-invoke project.my_tool_target in the build.ninja file. When you run Craftr, it will create a socket server and set the environment variable CRAFTR_RTS to the host:port combination. craftr-rts-invoke uses this address too communicate with the original Craftr process and execute the desired function.

Limitations:

  • You can not pipe into the craftr-rts-invoke script
  • This feature can not be used if you do a build-only (eg. craftr -b) since that will skip the execution step, unless you specify the --rts option which will keep the runtime server alive

Example:

This is from the craftr.ext.rules module:

class render_template(PythonTool):
  ''' This is a simple Python tool that can render a template file
  to a new file given a set of key/value pairs. Variables in the template
  are references by `${KEY}$`. There is currently not escape mechanism
  implemented. '''

  def __init__(self, template, output, **context):
    super().__init__([template], [output])
    self.template = template
    self.output = output
    self.context = context

  def __call__(self, args):
    with open(self.template) as src:
      content = src.read()
    for key, value in self.context.items():
      key = '${' + key + '}$'
      content = content.replace(key, value)
    with open(self.output, 'w') as dst:
      dst.write(content)

You can then use it like

my_target = render_template(
  template = path.local('the-template-file.txt'),
  output = 'the-rendered-template.txt',
  SOME_VARIABLE = 'Here was SOME_VARIABLE before!',
)