A minimal, deterministic, LLM-friendly, line-based file manipulation DSL
Project description
🔩 DataForge
A minimal, deterministic, LLM-friendly, line-based file manipulation DSL.
Install
pip install dfgscript
Afterwards three entry points are available:
dataforge script.dfg # canonical command
build script.dfg # alias matching the spec
py -m dataforge script.dfg # module invocation
Quick example
create-file "notes.txt"
1+Hello world
2+This is a test file
3+It has some content
4+End of file
end-file
dataforge notes.dfg # write the file
dataforge notes.dfg --dry-run # preview without writing
Multi-file support (v0.3)
A single .dfg script can create and edit multiple files at once. Each block
is explicitly closed with end-file:
create-file "notes.txt"
1+Hello
end-file
create-file "Hi.txt"
1+Hi
end-file
Rules:
- Every block must be closed with
end-filebefore opening a new one - A single block without
end-fileis still valid (v0.2 backwards compatibility) - If a block fails fatally, execution stops and later blocks are not run
DSL reference
File-level commands
create-file "path" # create new — error if file exists
replace-file "path" # unconditional overwrite
change-file "path" # patch an existing file (creates if absent)
remove-file "path" # delete a file — error if it does not exist
end-file # close the current block (required for multi-file scripts)
Line-level operations
N+<text> # write/replace line N (expands file with "" if N > length)
N-"<text>" # delete line N only if content matches exactly (warns otherwise)
N><text> # insert <text> after line N (shifts tail down)
$+<text> # append as new final line
Comments & blank lines
# This is a comment — ignored by the parser
Blank lines in a .dfg are also ignored. To write an actual blank line into
a target file use N+ with no text: 3+
Edit example
change-file "notes.txt"
# Delete line 2 only if it still matches exactly
2-"This is a test file"
2+This is an edited file
# Delete line 3 only if it matches
3-"It has some content"
# Insert a new line after line 1
1>Inserted line here
# Append to end
$+--- EOF ---
end-file
Result:
Hello worldInserted line hereThis is an edited fileEnd of file--- EOF ---
CLI flags
| Flag | Description |
|---|---|
--dry-run / --preview |
Show resulting file(s); do not write anything |
--backup-dir PATH |
Save a timestamped .bak copy before each write |
--log PATH |
Append log output to a file |
--verbose / -v |
Debug-level logging of every operation |
--version |
Print version and exit |
Python API
from dataforge import parse, run
# Multi-file — parse() returns a list of DfgScript blocks
scripts = parse(open("edit.dfg").read())
results = run(scripts, dry_run=True) # → { "path": ["line", ...], ... }
# Single-file convenience
from dataforge import parse_one
script = parse_one(open("single.dfg").read())
results = run(script, backup_dir=".backups")
Security
- Path traversal (
..) is blocked by default - No shell code is ever executed
- Atomic rename semantics — original only replaced on full success
- Transactional apply — writes go to a temp file first, then rename over the original
Project structure
dataforge_pkg/
├── pyproject.toml ← pip install .
├── README.md
├── README.celes
├── tests.py
└── dataforge/
├── __init__.py ← public Python API
├── __main__.py ← py -m dataforge
├── parser.py ← .dfg → DfgScript AST
├── interpreter.py ← executes the AST
└── cli.py ← argparse CLI
Changelog
v0.3.1
- Added
remove-file "path"— deletes a file; errors if it does not exist - Respects
--backup-dirand--dry-runlike all other commands - Line-level operations inside a
remove-fileblock are a parse error
v0.3.0
- Multi-file support — a single
.dfgcan now target multiple files - New
end-fileterminator closes each block explicitly parse()now returnslist[DfgScript]instead of a singleDfgScriptparse_one()added as a convenience wrapper for single-block scriptsrun()now accepts either a singleDfgScriptor alist[DfgScript]run()now returnsdict[path, list[str]]- Full backwards compatibility with v0.2 single-block
.dfgfiles
v0.2.0
- Initial release
License
Server-Lab Open-Control License (SOCL) — Copyright © 2025 Sourasish Das.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dfgscript-0.3.1.tar.gz.
File metadata
- Download URL: dfgscript-0.3.1.tar.gz
- Upload date:
- Size: 12.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
48399d6a1528820b07f84927e96b8d7985ba95c645c12e40d3cc25cfb1a34bf3
|
|
| MD5 |
b97c73f947d86e770e9de53b7c533d9c
|
|
| BLAKE2b-256 |
3cbafa7ac7395705ba99454c5ca74b7cd6dcf22b40eed9dbae0f8debeef370fe
|
File details
Details for the file dfgscript-0.3.1-py3-none-any.whl.
File metadata
- Download URL: dfgscript-0.3.1-py3-none-any.whl
- Upload date:
- Size: 11.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
47b40869d69f3b23dd0a7681e40cc13b9ca043fd30cc376b924805f4f3d15623
|
|
| MD5 |
0cfecd06a1d29597417383c4efed234f
|
|
| BLAKE2b-256 |
4bcd88fb21d859e2c706037dcf6585740cadb60f3f464fbba5d8b70add397bb8
|