Skip to content

Commit ef8dce0

Browse files
authored
Merge pull request #2 from Emin-ACIKGOZ/refactor-transaction-logic
# Changes: - Native Transactions: Implemented a LIFO manager with automated backups for atomic "all-or-nothing" rollbacks. - Security Hardening: Enforced project boundaries by canonicalizing task paths with filepath.Abs to block traversal. - Modular VCS: Refactored Git into an optional template to support Git-free scaffolding. - Test Isolation: Hardened the integration suite via environment variables to prevent host Git config leakage. - Registry Parity: Unified language and template registries with deterministic sorting.
2 parents b4e59a6 + 33d5831 commit ef8dce0

36 files changed

+2136
-695
lines changed

README.md

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
Designed for flexibility. If a language pack is missing, simply **add it**. If a template doesn’t fit, you can **modify or replace it**. The handler interface simplifies extension.
1616

1717
- **Built-in Atomic Safety**
18-
All modifications are wrapped in a **Git savepoint**. If any task fails, changes are automatically rolled back, restoring the repository to its exact previous state.
18+
All modifications are managed by a **LIFO-based Transaction Manager**. If any task fails, the engine executes a journaled rollback. This deletes created artifacts and restores file backups in reverse order, ensuring the filesystem returns to its original state.
1919

2020
- **Prioritized Execution**
2121
Tasks run in a defined order using **Priority Bands** (e.g., directory creation → language setup → universal config) to ensure dependencies are met.
@@ -24,13 +24,36 @@
2424

2525
## 🚀 Installation
2626

27-
#### (WIP)
27+
`scbake` is currently in **alpha development**. There is no fixed method for installation or distribution beyond compiling from source at this stage.
28+
29+
### Build from Source
30+
31+
To compile the binary yourself, ensure you have **Go 1.21+** installed:
32+
33+
#### 1. Clone the repository:
34+
```bash
35+
git clone https://github.com/Emin-ACIKGOZ/scbake.git
36+
```
37+
38+
39+
#### 2. Build the project:
40+
```bash
41+
go build -o scbake main.go
42+
```
43+
44+
45+
#### 3. Move the binary to your path (optional):
46+
```bash
47+
mv scbake /usr/local/bin/
48+
```
2849

2950
## 📋 Commands & Usage
3051

3152
### `new`: Create a New Project
3253

33-
Creates a directory, initializes Git, sets up `scbake.toml`, and applies language packs and templates.
54+
Creates a new directory, bootstraps the `scbake.toml` manifest, and applies language packs and templates.
55+
56+
**Note:** Git initialization can be added via the `--with git` template.
3457

3558
```bash
3659
scbake new <project-name> [--lang <lang>] [--with <template...>]
@@ -50,7 +73,7 @@ scbake new my-backend --lang go --with makefile,ci_github
5073

5174
### `apply`: Apply Templates to an Existing Project
5275

53-
Applies new language packs or tooling templates to an existing path (requires a clean Git tree).
76+
Applies new language packs or tooling templates to an existing path. Because `scbake` uses its own transaction logic, it does **not** require a clean Git tree to operate safely.
5477

5578
```bash
5679
scbake apply [--lang <lang>] [--with <template...>] [<path>]
@@ -89,14 +112,14 @@ scbake list [langs|templates|projects]
89112

90113
| Template | Priority Band | Features |
91114
| :-------------- | :---------------------- | :--------------------------------------------- |
92-
| `editorconfig` | Universal Config (1000) | Standard file formatting |
93-
| `ci_github` | CI (1100) | Conditional CI setup for all projects |
94-
| `go_linter` | Linter (1200) | Configures `golangci-lint` |
115+
| `editorconfig` | Universal Config (1000) | Standard file formatting across the project |
116+
| `ci_github` | CI (1100) | Conditional CI setup based on detected languages |
117+
| `go_linter` | Linter (1200) | Standard `golangci-lint` configuration |
95118
| `maven_linter` | Linter (1200) | Sets up Maven Checkstyle |
96-
| `svelte_linter` | Linter (1200) | Configures ESLint 9 with Svelte rules |
119+
| `svelte_linter` | Linter (1200) | ESLint 9 integration for Svelte projects |
97120
| `makefile` | Build System (1400) | Universal build/lint scripts for all projects |
98-
| `devcontainer` | Dev Env (1500) | Auto-detects languages and installs toolchains |
99-
121+
| `devcontainer` | Dev Env (1500) | Containerized DX with auto-detected toolchains |
122+
| `git` | Version Control (2000) | Initializes repo, stages all files, and creates initial commit |
100123

101124
## 💻 Extending `scbake`
102125

@@ -117,8 +140,8 @@ scbake list [langs|templates|projects]
117140
| `PrioCI` | 1100–1199 | CI workflows |
118141
| `PrioLinter` | 1200–1399 | Linter setup |
119142
| `PrioBuildSystem` | 1400–1499 | Build systems |
120-
| `PrioDevEnv` | 1500+ | Dev environment setup |
121-
143+
| `PrioDevEnv` | 1500-1999 | Dev environment setup |
144+
| `PrioVersionControl` | 2000-2100 | VCS initialization (Git) |
122145

123146
### Global Flags
124147

cmd/apply.go

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ package cmd
66

77
import (
88
"fmt"
9-
"os"
109
"path/filepath"
1110
"scbake/internal/core"
1211

@@ -21,10 +20,8 @@ var (
2120
var applyCmd = &cobra.Command{
2221
Use: "apply [--lang <lang>] [--with <template...>] [<path>]",
2322
Short: "Apply a language pack or tooling template to a project",
24-
Long: `Applies language packs or tooling templates to a specified path.
25-
This command is atomic and requires a clean Git working tree.`,
26-
Args: cobra.MaximumNArgs(1),
27-
Run: func(_ *cobra.Command, args []string) {
23+
Args: cobra.MaximumNArgs(1),
24+
RunE: func(_ *cobra.Command, args []string) error {
2825
// Store the original argument for the manifest, which must be relative.
2926
manifestPathArg := "."
3027
targetPath := "."
@@ -36,8 +33,7 @@ This command is atomic and requires a clean Git working tree.`,
3633
// Convert to absolute path for robust execution (npm, go build).
3734
absPath, err := filepath.Abs(targetPath)
3835
if err != nil {
39-
fmt.Fprintf(os.Stderr, "Error resolving path %s: %v\n", targetPath, err)
40-
os.Exit(1)
36+
return fmt.Errorf("Error resolving path: %w", err)
4137
}
4238

4339
rc := core.RunContext{
@@ -50,15 +46,15 @@ This command is atomic and requires a clean Git working tree.`,
5046
}
5147

5248
if err := core.RunApply(rc); err != nil {
53-
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
54-
os.Exit(1)
49+
return err
5550
}
5651
fmt.Println("✅ Success! 'apply' command finished.")
52+
return nil
5753
},
5854
}
5955

6056
func init() {
6157
rootCmd.AddCommand(applyCmd)
62-
applyCmd.PersistentFlags().StringVar(&langFlag, "lang", "", "Language project pack to apply (e.g., 'go')")
63-
applyCmd.PersistentFlags().StringSliceVar(&withFlag, "with", []string{}, "Tooling template to apply (e.g., 'makefile')")
58+
applyCmd.PersistentFlags().StringVar(&langFlag, "lang", "", "Language pack")
59+
applyCmd.PersistentFlags().StringSliceVar(&withFlag, "with", []string{}, "Tooling templates")
6460
}

0 commit comments

Comments
 (0)