ontoref/install/gen-projects.nu

127 lines
5.4 KiB
Plaintext
Raw Permalink Normal View History

#!/usr/bin/env nu
# install/gen-projects.nu — validate and regenerate ~/.config/ontoref/projects.ncl.
#
# Manages LOCAL projects only. Remote projects live in remote-projects.ncl.
#
# Reads projects.ncl as text, extracts import paths, verifies each .ontoref/project.ncl
# exists on disk, removes missing ones (with warning), and rewrites projects.ncl with
# only valid imports. Must run before `nickel export config.ncl`.
#
# Usage:
# nu install/gen-projects.nu # validate + regenerate
# nu install/gen-projects.nu --add /path/to/project # register new local project
# nu install/gen-projects.nu --remove /path/to/project # unregister local project
# nu install/gen-projects.nu --dry-run # print result without writing
def main [
--add: string, # path to local project root to register
--remove: string, # path to local project root to unregister
--dry-run, # print result without writing
--config-dir: string = "",
] {
let cfg_dir = if ($config_dir | is-empty) {
$"($env.HOME)/.config/ontoref"
} else {
$config_dir
}
let projects_file = $"($cfg_dir)/projects.ncl"
if not ($projects_file | path exists) {
"[]" | save -f $projects_file
}
# ── Extract existing import paths as plain text (never call nickel here) ────
# open --raw: .ncl is unknown to Nushell; without --raw it may parse `[]` as
# an empty list instead of a string, which would silently lose all existing entries.
let content = open --raw $projects_file
let existing_paths = (
$content
| lines
| each { |l| $l | str trim }
| where { |l| ($l | str contains "import \"") }
| each { |l|
$l | parse --regex 'import\s+"(?P<path>[^"]+)"' | get path | first
}
| flatten
)
# ── Handle --remove ──────────────────────────────────────────────────────────
let after_remove = if ($remove | is-not-empty) {
let abs = ($remove | path expand)
let ncl_path = $"($abs)/.ontoref/project.ncl"
let filtered = ($existing_paths | where { |p| $p != $ncl_path })
if ($filtered | length) == ($existing_paths | length) {
print --stderr $" (ansi yellow)not registered(ansi reset): ($ncl_path)"
} else {
print --stderr $" (ansi green)removed(ansi reset): ($ncl_path)"
}
$filtered
} else {
$existing_paths
}
# ── Handle --add ─────────────────────────────────────────────────────────────
let after_add = if ($add | is-not-empty) {
let abs = ($add | path expand)
let ncl_path = $"($abs)/.ontoref/project.ncl"
if not ($ncl_path | path exists) {
error make { msg: $"project.ncl not found: ($ncl_path)\nCopy templates/project.ncl to ($add)/.ontoref/project.ncl and fill in the fields." }
}
if ($after_remove | any { |p| $p == $ncl_path }) {
print --stderr $" (ansi yellow)already registered(ansi reset): ($ncl_path)"
$after_remove
} else {
$after_remove | append $ncl_path
}
} else {
$after_remove
}
# ── Validate: check local paths still exist ──────────────────────────────────
let valid_paths = (
$after_add | each { |p|
if not ($p | path exists) {
let project_root = ($p | str replace --regex '(/\.ontoref/project\.ncl)$' '')
if not ($project_root | path exists) {
print --stderr $" (ansi yellow)WARN(ansi reset) removing missing project (root deleted): ($project_root)"
} else {
print --stderr $" (ansi yellow)WARN(ansi reset) removing invalid project (project.ncl missing): ($p)"
}
null
} else {
$p
}
}
| compact
)
let removed = ($after_add | length) - ($valid_paths | length)
if $removed > 0 {
print --stderr $" (ansi yellow)($removed) project(s) removed — path(s) no longer exist(ansi reset)"
}
# ── Generate projects.ncl ─────────────────────────────────────────────────────
let import_lines = (
$valid_paths
| each { |p| $" [import \"($p)\"]," }
| str join "\n"
)
let output = if ($valid_paths | is-empty) {
"# AUTO-GENERATED by ontoref project-add / ontoref-daemon-boot. Do not edit by hand.\n# Add a local project: ontoref project-add /path/to/project\n\n[]\n"
} else {
"# AUTO-GENERATED by ontoref project-add / ontoref-daemon-boot. Do not edit by hand.\n# Add a local project: ontoref project-add /path/to/project\n\nstd.array.flatten [\n" + $import_lines + "\n]\n"
}
if $dry_run {
print --stderr "── projects.ncl (dry-run) ──────────────────────────────"
print $output
print --stderr "────────────────────────────────────────────────────────"
} else {
$output | save -f $projects_file
let n = ($valid_paths | length)
let label = if $n == 1 { "project" } else { "projects" }
print --stderr $" (ansi green)OK(ansi reset) ($n) local ($label) written to ($projects_file)"
}
}