kogral/scripts/kogral-backup.nu
Jesús Pérez 9ea04852a8
Some checks failed
Rust CI / Security Audit (push) Has been cancelled
Rust CI / Check + Test + Lint (nightly) (push) Has been cancelled
Rust CI / Check + Test + Lint (stable) (push) Has been cancelled
Nickel Type Check / Nickel Type Checking (push) Has been cancelled
chore: add schemas and just recipes
2026-01-23 16:12:50 +00:00

165 lines
5.5 KiB
Plaintext

#!/usr/bin/env nu
# Backup KOGRAL graphs to archive
#
# Usage: nu kogral-backup.nu [--output <path>] [--format <tar|zip>] [--compress]
def main [
--output: string = "kogral-backup" # Output filename (without extension)
--format: string = "tar" # Archive format: tar or zip
--compress # Compress the archive
--kogral-dir: string = ".kogral" # KOGRAL directory
--include-metadata # Include .git and other metadata
] {
print $"(ansi green_bold)KOGRAL Backup(ansi reset)"
print $"KOGRAL Directory: ($kogral-dir)"
print $"Format: ($format)"
print $"Compress: ($compress)"
# Check if .kogral directory exists
if not ($kogral-dir | path exists) {
print $"(ansi red)Error: KOGRAL directory not found: ($kogral-dir)(ansi reset)"
exit 1
}
# Generate timestamp
let timestamp = date now | format date "%Y%m%d_%H%M%S"
let backup_name = $"($output)_($timestamp)"
# Determine file extension
let extension = if $compress {
if $format == "tar" { ".tar.gz" } else { ".zip" }
} else {
if $format == "tar" { ".tar" } else { ".zip" }
}
let backup_file = $"($backup_name)($extension)"
print $"\n(ansi cyan_bold)Preparing backup...(ansi reset)"
print $"Output file: ($backup_file)"
# Count files
let stats = get_kogral_stats $kogral_dir
print $"\n(ansi cyan_bold)Files to backup:(ansi reset)"
print $" Notes: ($stats.notes)"
print $" Decisions: ($stats.decisions)"
print $" Guidelines: ($stats.guidelines)"
print $" Patterns: ($stats.patterns)"
print $" Journal: ($stats.journal)"
print $" Config: ($stats.config)"
print $" Total: ($stats.total)"
# Create backup
print $"\n(ansi cyan_bold)Creating backup...(ansi reset)"
match $format {
"tar" => {
create_tar_backup $kogral_dir $backup_file $compress $include_metadata
},
"zip" => {
create_zip_backup $kogral_dir $backup_file $include_metadata
},
_ => {
print $"(ansi red)Error: Invalid format. Use: tar or zip(ansi reset)"
exit 1
}
}
# Verify backup
if ($backup_file | path exists) {
let size = ls $backup_file | get size | first
print $"\n(ansi green_bold)✓ Backup created successfully(ansi reset)"
print $"File: ($backup_file)"
print $"Size: ($size)"
} else {
print $"\n(ansi red)✗ Backup creation failed(ansi reset)"
exit 1
}
# Generate manifest
print $"\n(ansi cyan_bold)Generating manifest...(ansi reset)"
let manifest = generate_manifest $kogral_dir $backup_file $stats $timestamp
let manifest_file = $"($backup_name).manifest.json"
$manifest | to json | save $manifest_file
print $"Manifest saved: ($manifest_file)"
print $"\n(ansi green_bold)✓ Backup completed(ansi reset)"
}
def get_kogral_stats [kogral_dir: string] -> record {
let notes = (glob $"($kogral_dir)/notes/**/*.md" | length)
let decisions = (glob $"($kogral_dir)/decisions/**/*.md" | length)
let guidelines = (glob $"($kogral_dir)/guidelines/**/*.md" | length)
let patterns = (glob $"($kogral_dir)/patterns/**/*.md" | length)
let journal = (glob $"($kogral_dir)/journal/**/*.md" | length)
let config = if ($"($kogral_dir)/config.toml" | path exists) { 1 } else { 0 }
{
notes: $notes,
decisions: $decisions,
guidelines: $guidelines,
patterns: $patterns,
journal: $journal,
config: $config,
total: ($notes + $decisions + $guidelines + $patterns + $journal + $config)
}
}
def create_tar_backup [kogral_dir: string, output: string, compress: bool, include_metadata: bool] {
let compress_flag = if $compress { "z" } else { "" }
let exclude_flags = if not $include_metadata {
["--exclude=.git", "--exclude=.DS_Store"]
} else {
[]
}
print $" Creating tar archive..."
# Use tar command
let tar_cmd = if $compress {
$"tar -c($compress_flag)f ($output) ($exclude_flags | str join ' ') ($kogral_dir)"
} else {
$"tar -cf ($output) ($exclude_flags | str join ' ') ($kogral_dir)"
}
try {
bash -c $tar_cmd
print $" (ansi green)✓ Tar archive created(ansi reset)"
} catch {
print $" (ansi red)✗ Tar archive creation failed(ansi reset)"
}
}
def create_zip_backup [kogral_dir: string, output: string, include_metadata: bool] {
print $" Creating zip archive..."
let exclude_pattern = if not $include_metadata { "*.git* */.DS_Store" } else { "" }
try {
bash -c $"zip -r ($output) ($kogral_dir) -x ($exclude_pattern)"
print $" (ansi green)✓ Zip archive created(ansi reset)"
} catch {
print $" (ansi red)✗ Zip archive creation failed(ansi reset)"
}
}
def generate_manifest [kogral_dir: string, backup_file: string, stats: record, timestamp: string] -> record {
let config_path = $"($kogral_dir)/config.toml"
let config = if ($config_path | path exists) {
open $config_path | from toml
} else {
{ graph: { name: "unknown", version: "unknown" } }
}
{
backup_timestamp: $timestamp,
backup_file: $backup_file,
kogral_directory: $kogral_dir,
graph_name: $config.graph.name,
graph_version: $config.graph.version,
statistics: $stats,
created_by: "kogral-backup.nu",
version: "1.0.0"
}
}