1+ import * as fs from 'fs/promises' ;
2+ import * as path from 'path' ;
3+ import os from 'os' ;
4+ import { execSync } from 'child_process' ;
5+
6+ describe ( 'apply-disable-backup.toml' , ( ) => {
7+ let tmpDir : string ;
8+ let rulerDir : string ;
9+
10+ beforeEach ( async ( ) => {
11+ tmpDir = await fs . mkdtemp ( path . join ( os . tmpdir ( ) , 'ruler-backup-' ) ) ;
12+ rulerDir = path . join ( tmpDir , '.ruler' ) ;
13+ await fs . mkdir ( rulerDir , { recursive : true } ) ;
14+
15+ // Create a simple instruction file
16+ await fs . writeFile (
17+ path . join ( rulerDir , 'instructions.md' ) ,
18+ '# Test Instructions\n\nThis is a test.' ,
19+ ) ;
20+ } ) ;
21+
22+ afterEach ( async ( ) => {
23+ await fs . rm ( tmpDir , { recursive : true , force : true } ) ;
24+ } ) ;
25+
26+ it ( 'does not create backup files when disable_backup=true in TOML' , async ( ) => {
27+ const toml = `disable_backup = true
28+ default_agents = ["Claude"]
29+ ` ;
30+ await fs . writeFile ( path . join ( rulerDir , 'ruler.toml' ) , toml ) ;
31+
32+ execSync ( 'npm run build' , { stdio : 'inherit' } ) ;
33+ execSync ( `node dist/cli/index.js apply --project-root ${ tmpDir } ` , {
34+ stdio : 'inherit' ,
35+ } ) ;
36+
37+ // Check that no backup files were created
38+ const claudeFile = path . join ( tmpDir , 'CLAUDE.md' ) ;
39+ const backupFile = path . join ( tmpDir , 'CLAUDE.md.bak' ) ;
40+
41+ expect ( await fs . access ( claudeFile ) . then ( ( ) => true ) . catch ( ( ) => false ) ) . toBe ( true ) ;
42+ expect ( await fs . access ( backupFile ) . then ( ( ) => true ) . catch ( ( ) => false ) ) . toBe ( false ) ;
43+ } ) ;
44+
45+ it ( 'creates backup files when disable_backup=false in TOML' , async ( ) => {
46+ const toml = `disable_backup = false
47+ default_agents = ["Claude"]
48+ ` ;
49+ await fs . writeFile ( path . join ( rulerDir , 'ruler.toml' ) , toml ) ;
50+
51+ // Create a pre-existing file to back up
52+ const claudeFile = path . join ( tmpDir , 'CLAUDE.md' ) ;
53+ await fs . writeFile ( claudeFile , '# Existing content\n' ) ;
54+
55+ execSync ( 'npm run build' , { stdio : 'inherit' } ) ;
56+ execSync ( `node dist/cli/index.js apply --project-root ${ tmpDir } ` , {
57+ stdio : 'inherit' ,
58+ } ) ;
59+
60+ // Check that backup file was created
61+ const backupFile = path . join ( tmpDir , 'CLAUDE.md.bak' ) ;
62+
63+ expect ( await fs . access ( claudeFile ) . then ( ( ) => true ) . catch ( ( ) => false ) ) . toBe ( true ) ;
64+ expect ( await fs . access ( backupFile ) . then ( ( ) => true ) . catch ( ( ) => false ) ) . toBe ( true ) ;
65+
66+ const backupContent = await fs . readFile ( backupFile , 'utf8' ) ;
67+ expect ( backupContent ) . toBe ( '# Existing content\n' ) ;
68+ } ) ;
69+
70+ it ( 'CLI --disable-backup overrides TOML disable_backup=false' , async ( ) => {
71+ const toml = `disable_backup = false
72+ default_agents = ["Claude"]
73+ ` ;
74+ await fs . writeFile ( path . join ( rulerDir , 'ruler.toml' ) , toml ) ;
75+
76+ // Create a pre-existing file to back up
77+ const claudeFile = path . join ( tmpDir , 'CLAUDE.md' ) ;
78+ await fs . writeFile ( claudeFile , '# Existing content\n' ) ;
79+
80+ execSync ( 'npm run build' , { stdio : 'inherit' } ) ;
81+ execSync ( `node dist/cli/index.js apply --disable-backup --project-root ${ tmpDir } ` , {
82+ stdio : 'inherit' ,
83+ } ) ;
84+
85+ // Check that no backup file was created despite TOML setting
86+ const backupFile = path . join ( tmpDir , 'CLAUDE.md.bak' ) ;
87+
88+ expect ( await fs . access ( claudeFile ) . then ( ( ) => true ) . catch ( ( ) => false ) ) . toBe ( true ) ;
89+ expect ( await fs . access ( backupFile ) . then ( ( ) => true ) . catch ( ( ) => false ) ) . toBe ( false ) ;
90+ } ) ;
91+ } ) ;
0 commit comments