refactor(cli)!: split the contributor tool out of the ludic CLI
`ludic help` ended with a section titled "contributing to the toolchain itself", listing bootstrap, reseed, docs-gen and release tasks. None of that is available to someone who installed the language — those tasks need the repository — so the shipped tool was advertising work its user cannot do, in a namespace they have to read past to find `new` and `run`. The tasks move to a second program, dev.ludic -> bin/ludic-dev, built from a checkout and excluded from every release artifact. `ludic` keeps the project and package commands and nothing else; `ludic dev …` now explains where the tasks went instead of failing as an unknown command. What this shook out: the two programs share prelude/build/project/pkg, so the helpers each had accreted in whichever file first needed them — cc(), ensure_ludicc, the string functions, title_case, cmd_version — moved to where both can see them. The argument-shift indirection added for the `dev` namespace is gone with the namespace, so commands read argv directly again. `ludic-dev test` asserts the split rather than trusting it: the staged install must build a project, and `ludic dev build` there must fail while naming ludic-dev. install.sh keeps building older tags, whose bootstrap goes through main.ludic. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
f369fbd227
commit
e175619543
46 changed files with 630 additions and 558 deletions
|
|
@ -131,11 +131,11 @@ function template_readme(name: pointer) -> pointer {
|
|||
|
||||
# ludic new <name> — scaffold a project that builds and runs as it stands.
|
||||
function cmd_new() -> int {
|
||||
if arg_total() < 3 {
|
||||
if arg_count() < 3 {
|
||||
err("usage: ludic new <name>\n")
|
||||
return 1
|
||||
}
|
||||
let name = arg_n(2)
|
||||
let name = arg(2)
|
||||
if file_exists(name) {
|
||||
err(`ludic new: {name} already exists\n`)
|
||||
return 1
|
||||
|
|
@ -173,12 +173,12 @@ function parse_build_args(start: int) -> pointer {
|
|||
g_out = ""
|
||||
g_save = false
|
||||
var ai = start
|
||||
while ai < arg_total() {
|
||||
let a = arg_n(ai)
|
||||
while ai < arg_count() {
|
||||
let a = arg(ai)
|
||||
if a == "--headless" { g_mode = 2 }
|
||||
else if a == "--windowed" { g_mode = 1 }
|
||||
else if a == "--save-temps" { g_save = true }
|
||||
else if a == "-o" { ai += 1; if ai < arg_total() { g_out = arg_n(ai) } }
|
||||
else if a == "-o" { ai += 1; if ai < arg_count() { g_out = arg(ai) } }
|
||||
else if a[0] != '-' { src = a }
|
||||
ai += 1
|
||||
}
|
||||
|
|
@ -245,7 +245,7 @@ function test_files() -> []pointer {
|
|||
function cmd_test() -> int {
|
||||
var files = new []pointer
|
||||
var ai = 2
|
||||
while ai < arg_total() { if arg_n(ai)[0] != '-' { push(files, arg_n(ai)) }; ai += 1 }
|
||||
while ai < arg_count() { if arg(ai)[0] != '-' { push(files, arg(ai)) }; ai += 1 }
|
||||
if len(files) == 0 { files = test_files() }
|
||||
if len(files) == 0 {
|
||||
err("ludic test: no tests found (expected tests/*.ludic or src/**/*_test.ludic)\n")
|
||||
|
|
@ -298,7 +298,7 @@ function strip_ext(p: pointer) -> pointer {
|
|||
function cmd_fmt() -> int {
|
||||
var args = ""
|
||||
var ai = 2
|
||||
while ai < arg_total() { args = `{args} {arg_n(ai)}`; ai += 1 }
|
||||
while ai < arg_count() { args = `{args} {arg(ai)}`; ai += 1 }
|
||||
if args == "" {
|
||||
let found = capture_line("find src tests -name '*.ludic' 2>/dev/null | sort")
|
||||
if found == "" {
|
||||
|
|
@ -315,7 +315,7 @@ function cmd_fmt() -> int {
|
|||
function cmd_lsp() -> int {
|
||||
var args = ""
|
||||
var ai = 2
|
||||
while ai < arg_total() { args = `{args} {arg_n(ai)}`; ai += 1 }
|
||||
while ai < arg_count() { args = `{args} {arg(ai)}`; ai += 1 }
|
||||
return sh(`exec {tool("ludic-lsp")}{args}`)
|
||||
}
|
||||
|
||||
|
|
@ -377,6 +377,25 @@ function cmd_doctor() -> int {
|
|||
return 1
|
||||
}
|
||||
|
||||
# ludic version — report the version of the toolchain this CLI belongs to.
|
||||
#
|
||||
# It asks the compiler (proving that path works), addressed through ludic_home()
|
||||
# rather than as a relative bin/ludicc: `ludic version` is run from a user's
|
||||
# project, not from the toolchain's own directory, and looking beside the current
|
||||
# directory found nothing there and reported "(version unknown)" for a perfectly
|
||||
# good install.
|
||||
function cmd_version() -> int {
|
||||
let cc = ludicc()
|
||||
if is_exec(cc) {
|
||||
run(`{cc} --version`)
|
||||
return 0
|
||||
}
|
||||
let v = read_file(`{ludic_home()}VERSION`)
|
||||
if v != null { print(`ludic {s_trim(v)}`); return 0 }
|
||||
print("ludic (version unknown)")
|
||||
return 0
|
||||
}
|
||||
|
||||
# ---- ludic upgrade ----------------------------------------------------------
|
||||
|
||||
function install_url() -> pointer { return getenv_or("LUDIC_INSTALL_URL", "https://workshopsoft.pages.workshopsoft.io/ludic/install.sh") }
|
||||
|
|
@ -386,7 +405,7 @@ function install_url() -> pointer { return getenv_or("LUDIC_INSTALL_URL", "https
|
|||
# drift from a fresh install.
|
||||
function cmd_upgrade() -> int {
|
||||
var ver = ""
|
||||
if arg_total() >= 3 { ver = arg_n(2) }
|
||||
if arg_count() >= 3 { ver = arg(2) }
|
||||
if not shq("command -v curl >/dev/null 2>&1") {
|
||||
err("ludic upgrade: needs curl\n")
|
||||
return 1
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue