Skip to content

Synthesize

Synthesize is a tool for managing long-lived development workflows that involve multiple tools executing concurrently, each of which might have bespoke conditions around when and how it needs to be run or re-run.

In Synthesize, a flow is a graph (potentially disjoint) of nodes, each of which runs a target whenever one of that node's triggers activates. Synthesize has a wide variety of triggers:

  • Target B should run after target A runs.
  • Target W should run every time file F changes.
  • Target R should be restarted if it ever exits.
  • Target O should run once when the flow starts.

These can all coexist as part of same flow, and can even be combined for a single target, allowing for complex nodes like "restart target W if it exits or if file F changes".

Features

  • Target and trigger definitions can be factored out and shared across multiple nodes and flows.
  • Targets are just shell commands, so you can use any tools you'd like. Synthesize works with your existing tools, it doesn't replace them.
  • Targets can be parameterized with arguments (each target is actually a Jinja template) and environment variables. Arguments and environment variables can also be provided at the flow and target levels (most specific wins).
  • Nodes can have multiple triggers, allowing you to express complex triggering conditions.
  • All command output is combined in a single output stream, with each node's output prefixed with a timestamp and its name.
  • The current time and the status of each node is displayed at the bottom of your terminal.
  • You can generate Mermaid diagrams of your flows for debugging and documentation.

Examples

As an example, here is Synthesize's own synth.yaml configuration file:

```yaml flows: default: nodes: tests: target: tests triggers: - code-changes types: target: types triggers: - code-changes docs: target: docs triggers: - delay: 1 - watch: ["docs/hooks/"]

targets: tests: commands: | pytest -vv --cov

types: commands: | mypy

docs: commands: | mkdocs serve --strict

triggers: code-changes: watch: - src/ - tests/ - docs/examples/ - docs/hooks/ - pyproject.toml - .coveragerc

```

flowchart TD
  tests(tests)
  w_bb19edcd7b45bfcfbfcab4096798a339f9610617[("src/
tests/
docs/examples/
docs/hooks/
pyproject.toml
.coveragerc")]
  w_bb19edcd7b45bfcfbfcab4096798a339f9610617 -->|👁| tests
  types(types)
  w_bb19edcd7b45bfcfbfcab4096798a339f9610617 -->|👁| types
  docs(docs)
  docs -->|∞ 1s| docs
  w_f8192994ea74c4d2311ffd6eb936c7c30e96617f[("docs/hooks/")]
  w_f8192994ea74c4d2311ffd6eb936c7c30e96617f -->|👁| docs

Installation

Synthesize is available on PyPI.

We recommend installing Synthesize via pipx:

bash pipx install synthesize

Then run synth --help to get started.

Synthesize does not work on Windows

We recommend using the Windows Subsystem for Linux (WSL) to run Synthesize on Windows.

Inspirations