Metadata-Version: 2.4
Name: bytecraft
Version: 0.2.0
Summary: A lightweight DSL for scaffolding files and folders
Author: Sourasish Das
License: SOCL-1.0
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Classifier: Topic :: Software Development :: Build Tools
Classifier: Topic :: Utilities
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: author
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: license
Dynamic: license-file
Dynamic: requires-python
Dynamic: summary

# 🧱 Bytecraft

> A human-readable DSL for scaffolding files and folders.

```
pip install bytecraft
```

---

Bytecraft lets you describe a project structure in plain, readable instructions and execute it with a single command — no Bash, no Python boilerplate, no mental overhead.

```
# bootstrap.bc

set project "my-app"
set version "1.0.0"

set-working-folder "{{project}}"

make-folder "src"
make-folder "src/utils"
make-folder "assets"

make-file "README.md" with "# {{project}}"
make-file "src/main.py" with "print('Hello, World!')"
make-file "src/utils/helper.py"
```

```bash
py -m bytecraft bootstrap.bc
```

```
[Bytecraft] Working folder set: my-app
[Bytecraft] Created folder: my-app/src
[Bytecraft] Created folder: my-app/src/utils
[Bytecraft] Created folder: my-app/assets
[Bytecraft] Created file: my-app/README.md
[Bytecraft] Created file: my-app/src/main.py
[Bytecraft] Created file: my-app/src/utils/helper.py
```

---

## Installation

Requires Python 3.10+

```bash
pip install bytecraft
```

---

## Commands

### `set-working-folder`

Sets the base directory for all subsequent relative paths. Created automatically if it doesn't exist.

```
set-working-folder "my-project"
```

---

### `make-folder`

Creates a directory and any missing parent directories. Does nothing if the folder already exists.

```
make-folder "src/utils"
```

---

### `make-file`

Creates a file. Parent directories are created automatically. Overwrites if the file already exists.

```
# Empty file
make-file "src/__init__.py"

# Inline content
make-file "VERSION" with "1.0.0"

# Multi-line content block
make-file "README.md" with ---
# My Project

Some description here.
---
```

---

### `copy-file`

Copies a file or folder to a new location. Parent directories are created automatically. If copying a folder that already exists at the destination, it is replaced.

```
# Copy a file
copy-file "src/app.py" to "backup/app.py"

# Copy an entire folder
copy-file "src" to "src_backup"
```

---

### `move-file`

Moves a file or folder to a new location. Parent directories are created automatically.

```
move-file "build/output.js" to "dist/app.js"
move-file "temp" to "archive/temp"
```

---

### `make-zip`

Creates a zip archive from a file or folder. Folder structure is preserved inside the zip.

```
# Zip a folder
make-zip "releases/v1.0.zip" from "dist"

# Zip a single file
make-zip "releases/app.zip" from "dist/app.py"
```

---

### `set`

Defines a variable. Variables are referenced anywhere using `{{name}}` syntax — in paths, content, and template calls.

```
set project "my-app"
set version "1.0.0"

make-file "VERSION" with "{{version}}"
make-file "src/main.py" with "# {{project}} v{{version}}"
```

Variables interpolate inside multi-line blocks too:

```
set author "Sourasish Das"

make-file "README.md" with ---
# {{project}}

Maintained by {{author}}.
---
```

---

### `define-template` / `use-template`

Templates let you define reusable scaffolding blocks and stamp them out with different values.

```
define-template "module"
  make-folder "src/{{name}}"
  make-file "src/{{name}}/__init__.py"
  make-file "src/{{name}}/main.py" with "# {{name}} module"
end-template

use-template "module" name "auth"
use-template "module" name "api"
use-template "module" name "db"
```

Variables passed to `use-template` are local to that call — they don't leak back into the outer script. Global variables defined with `set` are still accessible inside the template body.

---

### `include`

Runs another `.bc` file inline, with fully shared state. Variables, templates, the working folder, and strict mode all carry across in both directions.

```
include "base.bc"
include "templates/python.bc"
```

Paths are resolved relative to the calling script's directory, not the working folder.

---

### `strict on` / `strict off`

Enables or disables strict mode. In strict mode, warnings become fatal errors — undefined variables, unknown commands, and missing source files all halt execution immediately.

```
strict on

set version "1.0.0"
make-file "VERSION" with "{{version}}"   # fine
make-file "bad.txt" with "{{typo}}"      # ERROR: halts execution

strict off
```

Strict mode can be toggled on and off within the same script.

---

### Comments

Lines starting with `#` are ignored.

```
# This is a comment
```

---

## Forgiving Syntax

Bytecraft is intentionally forgiving. Quotes are optional — if they're missing, Bytecraft will recover and interpret your intent:

```
make-file hello.txt with Hello World
```

is treated the same as:

```
make-file "hello.txt" with "Hello World"
```

Unknown commands print a warning and are skipped rather than crashing the whole script. Enable `strict on` if you want the opposite behaviour.

---

## Full Example

```
# Full project scaffold + release build

strict on

set project "dashboard"
set author "Sourasish Das"
set version "1.0.0"

set-working-folder "{{project}}"

# Pull in shared folder templates
include "common/folders.bc"

# Stamp out feature modules
define-template "module"
  make-folder "src/{{name}}"
  make-file "src/{{name}}/__init__.py"
  make-file "src/{{name}}/main.py" with "# {{name}} — part of {{project}}"
end-template

use-template "module" name "auth"
use-template "module" name "api"
use-template "module" name "db"

# Static files
make-file "VERSION" with "{{version}}"

make-file "README.md" with ---
# {{project}}

Version: {{version}}
Author: {{author}}
---

make-file "tests/test_main.py" with ---
import unittest

class TestMain(unittest.TestCase):
    def test_placeholder(self):
        self.assertTrue(True)
---

# Package for release
copy-file "src" to "dist/src"
make-zip "releases/{{project}}-{{version}}.zip" from "dist"
```

---

## Limitations (v0.2.0)

- No loops or conditionals
- No append mode
- No import of variables from external files (e.g. `.env`)

These are planned for future versions.

---

## Roadmap

- [x] Variables and interpolation
- [x] Multi-line file content blocks
- [x] `copy-file` and `move-file`
- [x] `make-zip`
- [x] Templates (`define-template` / `use-template`)
- [x] `include`
- [x] Strict mode
- [ ] `append-file` command
- [ ] Loops and conditionals
- [ ] `.env` / external variable files

---

## License

[Server-Lab Open-Control License (SOCL) 1.0](./LICENSE)  
Copyright (c) 2025 Sourasish Das
