Skip to main content

modash

modash merges Bash script projects into one file.

It resolves source dependencies without executing shell code during normal compile. When a path can only be known by running the script, modash can trace one explicit run and compile from the reviewed result.

Install

python -m pip install modash

For source-tree development:

git clone https://github.com/nmehran/modash.git
cd modash
python -m pip install -e .

No external runtime dependencies are required.

Quick Start

Readable review output:

modash scripts/main.sh merged-context.sh

Runnable output for the supported Bash subset:

modash scripts/main.sh merged.sh --mode executable

If executable mode cannot prove a source site is safe to lower, it fails before writing or overwriting the output file.

Output Modes

Context Mode

Context mode is the default. It writes dependency-first sections for the files modash can resolve, preserves original source lines, and annotates resolved relationships:

# modash: source ./dep.sh -> dep.sh
source ./dep.sh

Use context mode for review, debugging, and collecting complete shell-project context for another tool. It is not a runtime parity mode.

Executable Mode

Executable mode inlines sourced files at their source sites so supported parent shell state remains Bash-equivalent: variables, functions, set state, current directory, source arguments, repeated sources, and function-scoped sources.

The supported static subset includes exact paths, exact variables, safe path commands and file producers, arrays, finite loops, modeled read loops, branch-aware if and case source sites, child-shell source contexts, and bounded source-bearing function calls.

See Supported Source Resolution for the current support matrix and fail-closed boundaries.

Runtime-Dependent Sources

Most source dependencies can be resolved without running the script. When a project chooses a source path at runtime, use runtime discovery explicitly. It runs the target once, records the source files that were actually loaded, writes review artifacts, and then compiles from that reviewed graph. compile-observed rewrites the observed source operations into trusted replay groups and bundles the observed files. The original script still decides whether each source site runs; modash replaces only the source operation that the trusted graph observed.

Use this for patterns like hook dispatchers, plugin loaders, or helper functions where a normal executable compile correctly fails closed because the source path depends on runtime state.

Recommended flow:

modash trace scripts/main.sh --output observation.json -- --flag
modash graph scripts/main.sh --from-observation observation.json --output runtime-graph.json
modash compile-observed scripts/main.sh merged.sh --from-graph runtime-graph.json

The graph and its text report are the review points. They show which source sites ran, which files were loaded, and whether the files still match the trace. One trace represents one execution path; it is not proof that every branch was covered.

If you want to keep a declarative compiler input as a separate file for static executable compile, write an explicit supplement and pass it to executable compile. This remains useful for review and compatibility, while compile-observed is the preferred runtime path:

modash supplement scripts/main.sh --from-graph runtime-graph.json --output source-supplement.json
modash scripts/main.sh merged.sh --mode executable --source-supplement source-supplement.json

For automation, observe-compile performs the explicit trace, writes the graph and report, and compiles from that newly observed graph:

modash observe-compile scripts/main.sh merged.sh --reviewed-graph-out runtime-graph.json -- --flag

Normal compile never traces. Runtime artifacts are data, not shell code. The runtime compiler consumes a trusted graph and fails closed if any observed edge cannot be mapped precisely, if an unobserved source site runs later, or if a trusted edge is left unused. See Runtime Source Discovery and Runtime Graph Compiler for the detailed artifact formats, trust checks, and safety model.

Commands

modash <entrypoint> <output> [--mode context|executable] [--source-supplement FILE]
modash trace <entrypoint> [--cwd DIR] [--env KEY=VALUE] [--output FILE] [--timeout SECONDS] [--] [args...]
modash graph <entrypoint> --from-observation observation.json --output runtime-graph.json [--report graph-review.txt]
modash supplement <entrypoint> (--from-observation observation.json [--report report.json] | --from-graph runtime-graph.json) --output source-supplement.json
modash compile-observed <entrypoint> <output> --from-graph runtime-graph.json
modash observe-compile <entrypoint> <output> --reviewed-graph-out runtime-graph.json [--observation-out observation.json] [--report graph-review.txt] [--cwd DIR] [--env KEY=VALUE] [--timeout SECONDS] [--] [args...]

Useful options:

  • --mode executable: write runnable output for the supported subset.
  • --source-supplement FILE: provide exact values for runtime-dynamic source sites.
  • trace --cwd DIR: run the target script from a specific directory.
  • trace --env KEY=VALUE: add an environment overlay for the traced run. Source-relevant inherited environment values are replay-checked when observed; use --env for values you want to make explicit in review artifacts.
  • trace --timeout SECONDS: bound target execution. Default: 30.
  • graph --from-observation FILE: build a trusted source graph from a trace observation.
  • graph --report FILE: choose the human-readable graph review report path.
  • compile-observed --from-graph FILE: compile executable output with the trusted runtime graph compiler.
  • observe-compile --reviewed-graph-out FILE: explicitly run tracing, write review artifacts, and compile executable output from the newly observed graph.
  • supplement --report FILE: choose where to write the review report.

Development

Run the local verification suite:

python -m unittest discover -s . -p 'test_*.py'
python -m py_compile $(find methods -name '*.py' -print) $(find test -name '*.py' -print) modash.py
git diff --check

Optional packaging checks:

python -m build --sdist --wheel --outdir dist
python -m twine check dist/*
MODASH_PACKAGING_SMOKE=1 python -m unittest test.test_packaging_smoke -v

Design notes live in docs.

License

This project is licensed under the Apache 2.0 License. See LICENSE.

Metadata

Release files for modash 0.7.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for modash 0.7.0
File Size Uploaded
modash-0.7.0.tar.gz 192.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for modash 0.7.0
File Interpreter ABI Platform
modash-0.7.0-py3-none-any.whl Python 3 none any Details

Total release size: 418.3 kB

Release files / modash-0.7.0.tar.gz

Download URL modash-0.7.0.tar.gz
Size 192.6 kB
Tags Source
SHA-256 checksum
How to use checksums
bacc37ada69d9c8afea89e11d817b7d401ba5473bdd602b4140c7c4e6119f7b4
BLAKE2b-256 checksum
How to use checksums
d746138ec32ad645cec70e7fb7f55f0d7b374a2abade37eb3adfb405c923d893
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 8, 2026.

Transparency log

Release files / modash-0.7.0-py3-none-any.whl

Download URL modash-0.7.0-py3-none-any.whl
Size 225.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cd9883850e3c5ad70fc0d0d88cb3cb2d6667f446026951ee76374a3faa471e56
BLAKE2b-256 checksum
How to use checksums
bfea503ab948e12badbc70e4f447737956420d2a8d2b45dc4816c569be9cc6a9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 8, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.7.0 This release

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.5

2 release files

0.4.1

2 release files

0.4.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page