Add safety features for file writing and enhance split command with options

This commit is contained in:
Kyler Olsen 2025-11-02 01:21:29 -06:00
parent dd73f3d71c
commit 75b750b662
3 changed files with 58 additions and 12 deletions

View File

@ -6,7 +6,7 @@ Next:
# Stack Language Specification
**Version**: 0.8
**Version**: 0.8.1
**Status**: Draft Specification
**Changes**:
- 0.5 (AI)
@ -75,5 +75,7 @@ Next:
6. **Tutorial content** - Added beginner tutorials to Appendix G
7. **Trait reference** - Consolidated all trait definitions in Appendix B
8. **Grammar simplification** - Referenced Implementable trait instead of repeating
- 0.8.1 (Human)
1. Added links
---

View File

@ -3,6 +3,7 @@ import re
import sys
import json
from pathlib import Path
import shutil
filenames = [
"docs/changes.md",
@ -72,7 +73,37 @@ def combine_markdown(file_inputs, output_combined, output_meta_json):
print(f"Combined file saved as: {output_combined}")
print(f"Metadata JSON saved as: {output_meta_json}")
def split_with_front_matter(input_combined, output_dir, metadata_file):
def write_with_safety(path, content, force=False, backup=False):
"""Write a file safely with force/backup options and diff-aware prompt."""
if path.exists():
current = path.read_text(encoding='utf-8')
if current == content:
print(f"No changes for: {path}")
return
if backup and not force:
backup_path = path.with_suffix(path.suffix + ".bak")
shutil.copy2(path, backup_path)
print(f"Backup created: {backup_path}")
elif not force:
while True:
choice = input(f"{path} has changed. [y] overwrite, [b] backup+overwrite, [n] skip? ").strip().lower()
if choice in ("y", "yes"):
break
elif choice in ("b", "backup"):
backup_path = path.with_suffix(path.suffix + ".bak")
shutil.copy2(path, backup_path)
print(f"Backup created: {backup_path}")
break
elif choice in ("n", "no", ""):
print(f"Skipped: {path}")
return
else:
print("Please choose [y], [b], or [n].")
path.write_text(content, encoding='utf-8')
print(f"Wrote: {path}")
def split_with_front_matter(input_combined, output_dir, metadata_file, force=False, backup=False):
"""Split a combined markdown file back into original files, restoring front matter."""
content = Path(input_combined).read_text(encoding='utf-8')
@ -81,13 +112,15 @@ def split_with_front_matter(input_combined, output_dir, metadata_file):
sys.exit(1)
meta_info = json.loads(Path(metadata_file).read_text(encoding='utf-8'))
os.makedirs(output_dir, exist_ok=True)
# Find all sections between <!-- START filename.md --> and <!-- END filename.md -->
pattern = r'<!-- START (.*?) -->\n(.*?)\n<!-- END \1 -->'
matches = re.findall(pattern, content, flags=re.DOTALL)
total_written = 0
total_skipped = 0
total_backups = 0
for filename, body in matches:
body = body.strip()
output_path = Path(output_dir, filename)
@ -99,26 +132,35 @@ def split_with_front_matter(input_combined, output_dir, metadata_file):
else:
restored = body + "\n"
output_path.write_text(restored, encoding='utf-8')
print(f"Restored: {output_path}")
before = output_path.exists()
write_with_safety(output_path, restored, force=force, backup=backup)
print("Split complete.")
if backup and before:
total_backups += 1
if output_path.exists():
total_written += 1
else:
total_skipped += 1
print(f"Split complete. {total_written} files written, {total_skipped} skipped, {total_backups} backups made.")
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage:")
print(" Combine files: python manage_docs.py combine")
print(" Split files: python manage_docs.py split")
print(" Combine: python manage_docs.py combine")
print(" Split: python manage_docs.py split [--force|--backup]")
sys.exit(1)
command = sys.argv[1].lower()
force = "--force" in sys.argv
backup = "--backup" in sys.argv
if command == "combine":
combine_markdown(filenames, "stack_lang_spec.md", "metadata.json")
elif command == "split":
split_with_front_matter("stack_lang_spec.md", "docs", "metadata.json")
split_with_front_matter("stack_lang_spec.md", "docs", "metadata.json",
force=force, backup=backup)
else:
print("Unknown command. Use 'combine' or 'split'.")

View File

@ -1,7 +1,7 @@
<!-- START changes.md -->
# Stack Language Specification
**Version**: 0.8
**Version**: 0.8.1
**Status**: Draft Specification
**Changes**:
- 0.5 (AI)
@ -70,6 +70,8 @@
6. **Tutorial content** - Added beginner tutorials to Appendix G
7. **Trait reference** - Consolidated all trait definitions in Appendix B
8. **Grammar simplification** - Referenced Implementable trait instead of repeating
- 0.8.1 (Human)
1. Added links
---
<!-- END changes.md -->