Browse Source
New punk::args::moduledoc::punkexe 0.1.0: (script)::punkexe dispatch definition (package modes, subcommand enumeration, default reclassification) + (script)::punkexe::tclsh full contract (stock arg-form parity incl the deliberate no -e boundary (G-077), lib: refusal, piperepl ::tclsh state array + env gates, intended divergences recorded per item decisions 2/6/8) + summary definitions for script/shell/punk/shellspy. G-032-compatible: the launcher help/parse wiring renders from these ids later. punk::args 0.12.7: update_definitions handles tag-prefixed id namespaces first-class - namespace_docpackages consulted with the tagged key (usage/ real_id on registered-but-unloaded (script)::* ids no longer no-such-id), generic tag strip for the real-namespace probes, unqualified-ns warning no longer fires for tag ids. args/ns/repl suites 352 pass 0 fail. punk::repl 0.5.3: code-interp setup catch-requires the punkexe moduledoc beside tclcore (both sites) so the docs are queryable in any punk shell. ARCHITECTURE.md: tclsh subcommand bullet in the boot/launch chain (architecture_lint clean). punkproject 0.20.1 + CHANGELOG. Verified: fresh-interp usage-first render (real_id path); rebuilt punk902z kit self-carries 0.1.0 (5298-char tclsh render); piped punk session renders (script)::punkexe with no manual require. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.commaster
14 changed files with 784 additions and 12 deletions
@ -1,4 +1,4 @@
|
||||
[project] |
||||
name = "punkshell" |
||||
version = "0.20.0" |
||||
version = "0.20.1" |
||||
license = "BSD-2-Clause" |
||||
|
||||
@ -0,0 +1,343 @@
|
||||
# -*- tcl -*- |
||||
# Maintenance Instruction: leave the 999999.xxx.x as is and use punkshell 'dev make' or bin/punkmake to update from <pkg>-buildversion.txt |
||||
# module template: punkshell/src/decktemplates/vendor/punk/modules/template_module-0.0.3.tm |
||||
# |
||||
# Please consider using a BSD or MIT style license for greatest compatibility with the Tcl ecosystem. |
||||
# Code using preferred Tcl licenses can be eligible for inclusion in Tcllib, Tklib and the punk package repository. |
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
# (C) 2026 |
||||
# |
||||
# @@ Meta Begin |
||||
# Application punk::args::moduledoc::punkexe 999999.0a1.0 |
||||
# Meta platform tcl |
||||
# Meta license BSD |
||||
# @@ Meta End |
||||
|
||||
|
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
# doctools header |
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
#*** !doctools |
||||
#[manpage_begin punkshell_module_punk::args::moduledoc::punkexe 0 999999.0a1.0] |
||||
#[copyright "2026"] |
||||
#[titledesc {punk executable launch documentation}] [comment {-- Name section and table of contents description --}] |
||||
#[moddesc {-}] [comment {-- Description at end of page heading --}] |
||||
#[require punk::args::moduledoc::punkexe] |
||||
#[keywords module launch subcommand tclsh] |
||||
#[description] |
||||
#[para] punk::args definitions documenting the punk executable launch dispatch |
||||
#[para] (the subcommand family implemented in the kit boot script src/vfs/_config/punk_main.tcl) |
||||
|
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
|
||||
#*** !doctools |
||||
#[section Overview] |
||||
#[para] These definitions are the documentation home for the launch subcommand |
||||
#[para] family of the punk executables: tclsh, script, shell, punk, shellspy |
||||
#[para] (G-118 item 10). They are authored to be consumable by the future |
||||
#[para] launcher help/parse wiring (goal G-032) - rendering, option parsing and |
||||
#[para] degradation wiring stay with that goal. Id convention follows the |
||||
#[para] make.tcl precedent for script-level surfaces: (script)::punkexe and |
||||
#[para] (script)::punkexe::<subcommand>, with explicit @form -synopsis overrides |
||||
#[para] since a constructed id is not an invocable command name. |
||||
|
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
## Requirements |
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
|
||||
#*** !doctools |
||||
#[subsection dependencies] |
||||
#[para] packages used by punk::args::moduledoc::punkexe |
||||
#[list_begin itemized] |
||||
|
||||
package require Tcl 8.6- |
||||
#*** !doctools |
||||
#[item] [package {Tcl 8.6}] |
||||
|
||||
#*** !doctools |
||||
#[list_end] |
||||
|
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
|
||||
#*** !doctools |
||||
#[section API] |
||||
|
||||
|
||||
tcl::namespace::eval punk::args::moduledoc::punkexe { |
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
# Base namespace |
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
#*** !doctools |
||||
#[subsection {Namespace punk::args::moduledoc::punkexe}] |
||||
#[para] punk::args definitions for the punk executable launch dispatch |
||||
#[list_begin definitions] |
||||
|
||||
variable PUNKARGS |
||||
|
||||
namespace eval argdoc { |
||||
#Top-level launch dispatch (kit boot script punk_main.tcl, mirrored in |
||||
#project_main.tcl for generated projects). Display-first definitions: |
||||
#the dispatch itself does not parse via punk::args yet (goal G-032). |
||||
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- |
||||
lappend PUNKARGS [list { |
||||
@id -id (script)::punkexe |
||||
@cmd -name punkexe\ |
||||
-summary\ |
||||
"punk executable launch: package modes and subcommand dispatch."\ |
||||
-help\ |
||||
"Launch surface of the punk shell executables ('<punkexe>' below |
||||
stands for any punk kit executable, e.g punk905, or a generated |
||||
project's kit). |
||||
|
||||
An optional FIRST argument selects package modes: one or more of |
||||
the tokens dev, os, src, internal joined with '-' when combined |
||||
(e.g 'dev', 'src', 'dev-src'). Modes decide which module sources |
||||
the shell trusts and their precedence; 'internal' (kit-bundled |
||||
modules) is always appended when absent. Details: bin/AGENTS.md |
||||
'launch package modes' in the punkshell source tree. |
||||
|
||||
The next argument selects a subcommand from the choices below. |
||||
When the first non-mode argument is not a known subcommand: |
||||
with no arguments at all the interactive punk shell is launched |
||||
('shell'); any other first argument is treated as a script |
||||
invocation (handled as for the 'script' subcommand)." |
||||
@form -synopsis "<punkexe> ?packagemode? ?subcommand? ?arg ...?" |
||||
@leaders -min 0 -max 1 |
||||
subcommand -type string -optional 1 -choicerestricted 0 -choices {tclsh script shell punk shellspy} -choicelabels { |
||||
tclsh |
||||
" Run as a (near) stock tclsh - no punk modules loaded." |
||||
script |
||||
" Run a script non-interactively in the punk script environment; honest exit codes." |
||||
shell |
||||
" Interactive punk shell (repl); can run a script first and stay interactive." |
||||
punk |
||||
" punk shell launch; piped-stdin friendly (echo cmds | <punkexe> punk)." |
||||
shellspy |
||||
" Experimental shellspy command-line processor." |
||||
} -help\ |
||||
"Subcommand to run. Each subcommand's own contract is documented |
||||
under its definition id (script)::punkexe::<subcommand>." |
||||
@values -min 0 -max -1 |
||||
arg -type any -optional 1 -multiple 1 -help\ |
||||
"Arguments for the selected subcommand." |
||||
}] |
||||
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- |
||||
|
||||
#tclsh subcommand: full contract (G-118). The documented-as-intended |
||||
#divergences below record G-118 item decisions: item 2 (tcl_interactive |
||||
#early link), item 6 (piped whole-buffer eval + honest exit codes), |
||||
#item 8 (istty read-only by convention). The 'no -e one-liner' note is |
||||
#the G-077 boundary: stock parity INSIDE this subcommand is deliberate; |
||||
#one-liner affordances belong to the top-level/'script' surfaces (G-077). |
||||
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- |
||||
lappend PUNKARGS [list { |
||||
@id -id (script)::punkexe::tclsh |
||||
@cmd -name "punkexe tclsh"\ |
||||
-summary\ |
||||
"Run the punk executable as a (near) stock tclsh - no punk modules."\ |
||||
-help\ |
||||
"Run the executable as a plain tclsh: no punk modules are loaded |
||||
and behaviour matches stock 'tclsh' as closely as the kit boot |
||||
allows. The subcommand is an EXTENSION of standard tclsh |
||||
behaviour, not an exact emulator - the divergences are listed |
||||
below and are intended. |
||||
|
||||
Stock argument-form parity (tclMain.c): the only recognised |
||||
leading option is '-encoding name scriptfile', and only when |
||||
scriptfile does not itself begin with '-'. Any other leading '-' |
||||
argument means NO script file: all arguments stay in ::argv and |
||||
input comes from stdin. In particular there is no -e/-c |
||||
one-liner flag - '<punkexe> tclsh -e (script)' puts '-e' and the |
||||
script text into ::argv and reads stdin, exactly like stock |
||||
tclsh. That parity is deliberate; one-liner affordances belong |
||||
to the punk-level launch surfaces, not this subcommand. |
||||
|
||||
A scriptfile of the form 'lib:name' is refused with a pointer to |
||||
the 'script' subcommand: scriptlib resolution is a punk |
||||
facility and the tclsh subcommand keeps plain-tclsh semantics. |
||||
A missing scriptfile is a clean error (exit 1); errors raised by |
||||
an existing script keep their full trace. |
||||
|
||||
Piperepl runtimes: kits on a 'punk' family runtime carry the |
||||
TCLSH_PIPEREPL patch (disable with env TCLSH_PIPEREPL=0; a kit |
||||
on an unpatched runtime notes the missing patch on stderr for |
||||
the forms that would use it). With the gate open the runtime |
||||
publishes launch state in the ::tclsh array before any script |
||||
runs: |
||||
istty launch-time fact: was stdin a tty? Never updated |
||||
afterwards (still 0 after a console reopen). |
||||
Read-only by convention - no readonly trace is |
||||
installed; a script write corrupts the |
||||
Tcl-visible value without affecting behaviour. |
||||
Its existence is also the patch-presence probe. |
||||
dorepl linked control: a script (or piped input) sets |
||||
this to 1 to enter the interactive repl after |
||||
the script/stdin completes - on piped launches |
||||
stdin is reopened from the console (CONIN$ on |
||||
windows, /dev/tty elsewhere). |
||||
evalinput linked control: piped input a script-arg run |
||||
did not consume is BUFFERED, not evaluated, |
||||
unless the script sets evalinput to 1. |
||||
inputbuffer set at console reopen: holds the unconsumed |
||||
piped input. |
||||
reopened 0 at gate-open startup; republished as 1 after |
||||
a successful console reopen. |
||||
Env TCLSH_PIPEREPL_DEBUG=1 enables patch diagnostics on stderr |
||||
(e.g the console-reopen notice, silent by default). |
||||
|
||||
Intended divergences from stock tclsh: |
||||
- tcl_interactive: with the piperepl gate open it is linked |
||||
to the tty flag BEFORE the startup script runs; a |
||||
script-arg launch from a console therefore reads 1 where |
||||
stock reads 0 (piped launches read 0 either way). The |
||||
early link is load-bearing: a piped script that sets |
||||
dorepl writes ::tcl_interactive to opt into prompts/echo |
||||
in the reopened repl. |
||||
- piped no-arg evaluation WITHOUT the machinery (unpatched |
||||
runtime, or TCLSH_PIPEREPL=0): stdin is read to eof and |
||||
evaluated as one script - output appears at eof on slow |
||||
pipes, a mid-script error aborts the remainder, and the |
||||
exit code is honest (nonzero on error) where stock tclsh |
||||
streams per command, continues after errors and exits 0. |
||||
(With the machinery present, evaluation is the stock |
||||
per-command repl loop.) On machinery-less runtimes the |
||||
interactive form (console stdin, no script) fails fast |
||||
with a usage error instead of blocking in a console read." |
||||
|
||||
@form -form {scriptfile} -synopsis "<punkexe> tclsh ?-encoding name? scriptfile ?arg ...?" |
||||
@leaders -min 0 -max 0 |
||||
@opts |
||||
-encoding -type string -optional 1 -typesynopsis name -help\ |
||||
"Encoding used to read scriptfile (as for 'source -encoding'). |
||||
Recognised only immediately after 'tclsh' and only when the |
||||
following argument does not begin with '-'; an incomplete |
||||
-encoding form falls through to the no-script form (stock |
||||
behaviour)." |
||||
@values -min 1 -max -1 |
||||
scriptfile -type string -optional 0 -help\ |
||||
"Script file to source and exit. ::argv0 and 'info script' are |
||||
the (normalized) script path; remaining args are ::argv. The |
||||
script may set ::tclsh(dorepl) 1 (piperepl runtimes) to enter |
||||
the interactive repl after it completes." |
||||
arg -type any -optional 1 -multiple 1 -help\ |
||||
"Arguments passed to the script in ::argv." |
||||
|
||||
@form -form {stdin} -synopsis "<punkexe> tclsh ?arg ...?" |
||||
@values -min 0 -max -1 |
||||
arg -type any -optional 1 -multiple 1 -help\ |
||||
"With no script file all arguments (including any leading '-' |
||||
arguments) stay in ::argv; ::argv0 is the executable path. |
||||
Input comes from stdin: the interactive repl on a console |
||||
(piperepl runtimes), evaluation of piped input otherwise." |
||||
}] |
||||
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- |
||||
|
||||
#Sibling subcommands: summary-level contracts. Deep punk::args parse |
||||
#definitions for these surfaces are G-032's lane ('script' is its |
||||
#natural first parsed subcommand). |
||||
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- |
||||
lappend PUNKARGS [list { |
||||
@id -id (script)::punkexe::script |
||||
@cmd -name "punkexe script"\ |
||||
-summary\ |
||||
"Run a script non-interactively in the punk script environment."\ |
||||
-help\ |
||||
"Run a Tcl script and exit with an honest exit code |
||||
(app-punkscript): script errors exit nonzero and the launch |
||||
plumbing emits nothing of its own on stdout/stderr, so |
||||
exec-style callers see only the script's output. The default |
||||
punk module/alias environment is loaded (unlike 'tclsh'). |
||||
|
||||
The script comes from the file argument, from piped stdin when |
||||
no argument is given (terminal stdin without a script argument |
||||
is a usage error - no interactive fallback), or via scriptlib |
||||
resolution when the argument has the form 'lib:name' (resolved |
||||
from the scriptlib locations associated with the executable, |
||||
including extensionless and shebang'd scripts)." |
||||
@form -synopsis "<punkexe> script ?scriptfile|lib:name? ?arg ...?" |
||||
@values -min 0 -max -1 |
||||
scriptfile -type string -optional 1 -help\ |
||||
"Script file path, or lib:name for scriptlib resolution. |
||||
Omitted: the script is read from piped stdin." |
||||
arg -type any -optional 1 -multiple 1 -help\ |
||||
"Arguments passed to the script in ::argv." |
||||
}] |
||||
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- |
||||
lappend PUNKARGS [list { |
||||
@id -id (script)::punkexe::shell |
||||
@cmd -name "punkexe shell"\ |
||||
-summary\ |
||||
"Interactive punk shell (repl)."\ |
||||
-help\ |
||||
"Launch the interactive punk shell (app-punkshell). With |
||||
arguments, a script can be run first with the interactive |
||||
shell maintained afterwards. This is also the default when the |
||||
executable is launched with no arguments at all." |
||||
@form -synopsis "<punkexe> shell ?arg ...?" |
||||
@values -min 0 -max -1 |
||||
arg -type any -optional 1 -multiple 1 -help\ |
||||
"Arguments passed through to the shell launch." |
||||
}] |
||||
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- |
||||
lappend PUNKARGS [list { |
||||
@id -id (script)::punkexe::punk |
||||
@cmd -name "punkexe punk"\ |
||||
-summary\ |
||||
"punk shell launch; piped-stdin friendly."\ |
||||
-help\ |
||||
"Launch the punk shell. With arguments the app-punkshell launch |
||||
path is used (as for 'shell'); without arguments the |
||||
interactive shell is launched directly. Commands piped into |
||||
stdin are supported (e.g: echo 'puts hello' | <punkexe> punk) |
||||
and stderr is kept clean of launch chatter so exec-style |
||||
callers do not misreport failure." |
||||
@form -synopsis "<punkexe> punk ?arg ...?" |
||||
@values -min 0 -max -1 |
||||
arg -type any -optional 1 -multiple 1 -help\ |
||||
"Arguments passed through to the shell launch." |
||||
}] |
||||
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- |
||||
lappend PUNKARGS [list { |
||||
@id -id (script)::punkexe::shellspy |
||||
@cmd -name "punkexe shellspy"\ |
||||
-summary\ |
||||
"Experimental shellspy command-line processor."\ |
||||
-help\ |
||||
"Pass all arguments to the experimental shellspy command-line |
||||
processor (app-shellspy). Note: 'shellspy' is only this launch |
||||
subcommand - it is not the project name (the project is |
||||
punkshell)." |
||||
@form -synopsis "<punkexe> shellspy ?arg ...?" |
||||
@values -min 0 -max -1 |
||||
arg -type any -optional 1 -multiple 1 -help\ |
||||
"Arguments for the shellspy processor." |
||||
}] |
||||
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- |
||||
} |
||||
|
||||
#*** !doctools |
||||
#[list_end] [comment {--- end definitions namespace punk::args::moduledoc::punkexe ---}] |
||||
} |
||||
|
||||
# ----------------------------------------------------------------------------- |
||||
# register namespace(s) to have PUNKARGS,PUNKARGS_aliases variables checked |
||||
# ----------------------------------------------------------------------------- |
||||
# variable PUNKARGS |
||||
# variable PUNKARGS_aliases |
||||
namespace eval ::punk::args::register { |
||||
#use fully qualified so 8.6 doesn't find existing var in global namespace |
||||
lappend ::punk::args::register::NAMESPACES ::punk::args::moduledoc::punkexe ::punk::args::moduledoc::punkexe::argdoc |
||||
} |
||||
# ----------------------------------------------------------------------------- |
||||
|
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
## Ready |
||||
package provide punk::args::moduledoc::punkexe [tcl::namespace::eval punk::args::moduledoc::punkexe { |
||||
variable pkg punk::args::moduledoc::punkexe |
||||
variable version |
||||
set version 999999.0a1.0 |
||||
}] |
||||
return |
||||
|
||||
#*** !doctools |
||||
#[manpage_end] |
||||
@ -0,0 +1,3 @@
|
||||
0.1.0 |
||||
#First line must be a semantic version number |
||||
#all other lines are ignored. |
||||
@ -0,0 +1,343 @@
|
||||
# -*- tcl -*- |
||||
# Maintenance Instruction: leave the 999999.xxx.x as is and use punkshell 'dev make' or bin/punkmake to update from <pkg>-buildversion.txt |
||||
# module template: punkshell/src/decktemplates/vendor/punk/modules/template_module-0.0.3.tm |
||||
# |
||||
# Please consider using a BSD or MIT style license for greatest compatibility with the Tcl ecosystem. |
||||
# Code using preferred Tcl licenses can be eligible for inclusion in Tcllib, Tklib and the punk package repository. |
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
# (C) 2026 |
||||
# |
||||
# @@ Meta Begin |
||||
# Application punk::args::moduledoc::punkexe 0.1.0 |
||||
# Meta platform tcl |
||||
# Meta license BSD |
||||
# @@ Meta End |
||||
|
||||
|
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
# doctools header |
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
#*** !doctools |
||||
#[manpage_begin punkshell_module_punk::args::moduledoc::punkexe 0 0.1.0] |
||||
#[copyright "2026"] |
||||
#[titledesc {punk executable launch documentation}] [comment {-- Name section and table of contents description --}] |
||||
#[moddesc {-}] [comment {-- Description at end of page heading --}] |
||||
#[require punk::args::moduledoc::punkexe] |
||||
#[keywords module launch subcommand tclsh] |
||||
#[description] |
||||
#[para] punk::args definitions documenting the punk executable launch dispatch |
||||
#[para] (the subcommand family implemented in the kit boot script src/vfs/_config/punk_main.tcl) |
||||
|
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
|
||||
#*** !doctools |
||||
#[section Overview] |
||||
#[para] These definitions are the documentation home for the launch subcommand |
||||
#[para] family of the punk executables: tclsh, script, shell, punk, shellspy |
||||
#[para] (G-118 item 10). They are authored to be consumable by the future |
||||
#[para] launcher help/parse wiring (goal G-032) - rendering, option parsing and |
||||
#[para] degradation wiring stay with that goal. Id convention follows the |
||||
#[para] make.tcl precedent for script-level surfaces: (script)::punkexe and |
||||
#[para] (script)::punkexe::<subcommand>, with explicit @form -synopsis overrides |
||||
#[para] since a constructed id is not an invocable command name. |
||||
|
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
## Requirements |
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
|
||||
#*** !doctools |
||||
#[subsection dependencies] |
||||
#[para] packages used by punk::args::moduledoc::punkexe |
||||
#[list_begin itemized] |
||||
|
||||
package require Tcl 8.6- |
||||
#*** !doctools |
||||
#[item] [package {Tcl 8.6}] |
||||
|
||||
#*** !doctools |
||||
#[list_end] |
||||
|
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
|
||||
#*** !doctools |
||||
#[section API] |
||||
|
||||
|
||||
tcl::namespace::eval punk::args::moduledoc::punkexe { |
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
# Base namespace |
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
#*** !doctools |
||||
#[subsection {Namespace punk::args::moduledoc::punkexe}] |
||||
#[para] punk::args definitions for the punk executable launch dispatch |
||||
#[list_begin definitions] |
||||
|
||||
variable PUNKARGS |
||||
|
||||
namespace eval argdoc { |
||||
#Top-level launch dispatch (kit boot script punk_main.tcl, mirrored in |
||||
#project_main.tcl for generated projects). Display-first definitions: |
||||
#the dispatch itself does not parse via punk::args yet (goal G-032). |
||||
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- |
||||
lappend PUNKARGS [list { |
||||
@id -id (script)::punkexe |
||||
@cmd -name punkexe\ |
||||
-summary\ |
||||
"punk executable launch: package modes and subcommand dispatch."\ |
||||
-help\ |
||||
"Launch surface of the punk shell executables ('<punkexe>' below |
||||
stands for any punk kit executable, e.g punk905, or a generated |
||||
project's kit). |
||||
|
||||
An optional FIRST argument selects package modes: one or more of |
||||
the tokens dev, os, src, internal joined with '-' when combined |
||||
(e.g 'dev', 'src', 'dev-src'). Modes decide which module sources |
||||
the shell trusts and their precedence; 'internal' (kit-bundled |
||||
modules) is always appended when absent. Details: bin/AGENTS.md |
||||
'launch package modes' in the punkshell source tree. |
||||
|
||||
The next argument selects a subcommand from the choices below. |
||||
When the first non-mode argument is not a known subcommand: |
||||
with no arguments at all the interactive punk shell is launched |
||||
('shell'); any other first argument is treated as a script |
||||
invocation (handled as for the 'script' subcommand)." |
||||
@form -synopsis "<punkexe> ?packagemode? ?subcommand? ?arg ...?" |
||||
@leaders -min 0 -max 1 |
||||
subcommand -type string -optional 1 -choicerestricted 0 -choices {tclsh script shell punk shellspy} -choicelabels { |
||||
tclsh |
||||
" Run as a (near) stock tclsh - no punk modules loaded." |
||||
script |
||||
" Run a script non-interactively in the punk script environment; honest exit codes." |
||||
shell |
||||
" Interactive punk shell (repl); can run a script first and stay interactive." |
||||
punk |
||||
" punk shell launch; piped-stdin friendly (echo cmds | <punkexe> punk)." |
||||
shellspy |
||||
" Experimental shellspy command-line processor." |
||||
} -help\ |
||||
"Subcommand to run. Each subcommand's own contract is documented |
||||
under its definition id (script)::punkexe::<subcommand>." |
||||
@values -min 0 -max -1 |
||||
arg -type any -optional 1 -multiple 1 -help\ |
||||
"Arguments for the selected subcommand." |
||||
}] |
||||
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- |
||||
|
||||
#tclsh subcommand: full contract (G-118). The documented-as-intended |
||||
#divergences below record G-118 item decisions: item 2 (tcl_interactive |
||||
#early link), item 6 (piped whole-buffer eval + honest exit codes), |
||||
#item 8 (istty read-only by convention). The 'no -e one-liner' note is |
||||
#the G-077 boundary: stock parity INSIDE this subcommand is deliberate; |
||||
#one-liner affordances belong to the top-level/'script' surfaces (G-077). |
||||
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- |
||||
lappend PUNKARGS [list { |
||||
@id -id (script)::punkexe::tclsh |
||||
@cmd -name "punkexe tclsh"\ |
||||
-summary\ |
||||
"Run the punk executable as a (near) stock tclsh - no punk modules."\ |
||||
-help\ |
||||
"Run the executable as a plain tclsh: no punk modules are loaded |
||||
and behaviour matches stock 'tclsh' as closely as the kit boot |
||||
allows. The subcommand is an EXTENSION of standard tclsh |
||||
behaviour, not an exact emulator - the divergences are listed |
||||
below and are intended. |
||||
|
||||
Stock argument-form parity (tclMain.c): the only recognised |
||||
leading option is '-encoding name scriptfile', and only when |
||||
scriptfile does not itself begin with '-'. Any other leading '-' |
||||
argument means NO script file: all arguments stay in ::argv and |
||||
input comes from stdin. In particular there is no -e/-c |
||||
one-liner flag - '<punkexe> tclsh -e (script)' puts '-e' and the |
||||
script text into ::argv and reads stdin, exactly like stock |
||||
tclsh. That parity is deliberate; one-liner affordances belong |
||||
to the punk-level launch surfaces, not this subcommand. |
||||
|
||||
A scriptfile of the form 'lib:name' is refused with a pointer to |
||||
the 'script' subcommand: scriptlib resolution is a punk |
||||
facility and the tclsh subcommand keeps plain-tclsh semantics. |
||||
A missing scriptfile is a clean error (exit 1); errors raised by |
||||
an existing script keep their full trace. |
||||
|
||||
Piperepl runtimes: kits on a 'punk' family runtime carry the |
||||
TCLSH_PIPEREPL patch (disable with env TCLSH_PIPEREPL=0; a kit |
||||
on an unpatched runtime notes the missing patch on stderr for |
||||
the forms that would use it). With the gate open the runtime |
||||
publishes launch state in the ::tclsh array before any script |
||||
runs: |
||||
istty launch-time fact: was stdin a tty? Never updated |
||||
afterwards (still 0 after a console reopen). |
||||
Read-only by convention - no readonly trace is |
||||
installed; a script write corrupts the |
||||
Tcl-visible value without affecting behaviour. |
||||
Its existence is also the patch-presence probe. |
||||
dorepl linked control: a script (or piped input) sets |
||||
this to 1 to enter the interactive repl after |
||||
the script/stdin completes - on piped launches |
||||
stdin is reopened from the console (CONIN$ on |
||||
windows, /dev/tty elsewhere). |
||||
evalinput linked control: piped input a script-arg run |
||||
did not consume is BUFFERED, not evaluated, |
||||
unless the script sets evalinput to 1. |
||||
inputbuffer set at console reopen: holds the unconsumed |
||||
piped input. |
||||
reopened 0 at gate-open startup; republished as 1 after |
||||
a successful console reopen. |
||||
Env TCLSH_PIPEREPL_DEBUG=1 enables patch diagnostics on stderr |
||||
(e.g the console-reopen notice, silent by default). |
||||
|
||||
Intended divergences from stock tclsh: |
||||
- tcl_interactive: with the piperepl gate open it is linked |
||||
to the tty flag BEFORE the startup script runs; a |
||||
script-arg launch from a console therefore reads 1 where |
||||
stock reads 0 (piped launches read 0 either way). The |
||||
early link is load-bearing: a piped script that sets |
||||
dorepl writes ::tcl_interactive to opt into prompts/echo |
||||
in the reopened repl. |
||||
- piped no-arg evaluation WITHOUT the machinery (unpatched |
||||
runtime, or TCLSH_PIPEREPL=0): stdin is read to eof and |
||||
evaluated as one script - output appears at eof on slow |
||||
pipes, a mid-script error aborts the remainder, and the |
||||
exit code is honest (nonzero on error) where stock tclsh |
||||
streams per command, continues after errors and exits 0. |
||||
(With the machinery present, evaluation is the stock |
||||
per-command repl loop.) On machinery-less runtimes the |
||||
interactive form (console stdin, no script) fails fast |
||||
with a usage error instead of blocking in a console read." |
||||
|
||||
@form -form {scriptfile} -synopsis "<punkexe> tclsh ?-encoding name? scriptfile ?arg ...?" |
||||
@leaders -min 0 -max 0 |
||||
@opts |
||||
-encoding -type string -optional 1 -typesynopsis name -help\ |
||||
"Encoding used to read scriptfile (as for 'source -encoding'). |
||||
Recognised only immediately after 'tclsh' and only when the |
||||
following argument does not begin with '-'; an incomplete |
||||
-encoding form falls through to the no-script form (stock |
||||
behaviour)." |
||||
@values -min 1 -max -1 |
||||
scriptfile -type string -optional 0 -help\ |
||||
"Script file to source and exit. ::argv0 and 'info script' are |
||||
the (normalized) script path; remaining args are ::argv. The |
||||
script may set ::tclsh(dorepl) 1 (piperepl runtimes) to enter |
||||
the interactive repl after it completes." |
||||
arg -type any -optional 1 -multiple 1 -help\ |
||||
"Arguments passed to the script in ::argv." |
||||
|
||||
@form -form {stdin} -synopsis "<punkexe> tclsh ?arg ...?" |
||||
@values -min 0 -max -1 |
||||
arg -type any -optional 1 -multiple 1 -help\ |
||||
"With no script file all arguments (including any leading '-' |
||||
arguments) stay in ::argv; ::argv0 is the executable path. |
||||
Input comes from stdin: the interactive repl on a console |
||||
(piperepl runtimes), evaluation of piped input otherwise." |
||||
}] |
||||
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- |
||||
|
||||
#Sibling subcommands: summary-level contracts. Deep punk::args parse |
||||
#definitions for these surfaces are G-032's lane ('script' is its |
||||
#natural first parsed subcommand). |
||||
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- |
||||
lappend PUNKARGS [list { |
||||
@id -id (script)::punkexe::script |
||||
@cmd -name "punkexe script"\ |
||||
-summary\ |
||||
"Run a script non-interactively in the punk script environment."\ |
||||
-help\ |
||||
"Run a Tcl script and exit with an honest exit code |
||||
(app-punkscript): script errors exit nonzero and the launch |
||||
plumbing emits nothing of its own on stdout/stderr, so |
||||
exec-style callers see only the script's output. The default |
||||
punk module/alias environment is loaded (unlike 'tclsh'). |
||||
|
||||
The script comes from the file argument, from piped stdin when |
||||
no argument is given (terminal stdin without a script argument |
||||
is a usage error - no interactive fallback), or via scriptlib |
||||
resolution when the argument has the form 'lib:name' (resolved |
||||
from the scriptlib locations associated with the executable, |
||||
including extensionless and shebang'd scripts)." |
||||
@form -synopsis "<punkexe> script ?scriptfile|lib:name? ?arg ...?" |
||||
@values -min 0 -max -1 |
||||
scriptfile -type string -optional 1 -help\ |
||||
"Script file path, or lib:name for scriptlib resolution. |
||||
Omitted: the script is read from piped stdin." |
||||
arg -type any -optional 1 -multiple 1 -help\ |
||||
"Arguments passed to the script in ::argv." |
||||
}] |
||||
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- |
||||
lappend PUNKARGS [list { |
||||
@id -id (script)::punkexe::shell |
||||
@cmd -name "punkexe shell"\ |
||||
-summary\ |
||||
"Interactive punk shell (repl)."\ |
||||
-help\ |
||||
"Launch the interactive punk shell (app-punkshell). With |
||||
arguments, a script can be run first with the interactive |
||||
shell maintained afterwards. This is also the default when the |
||||
executable is launched with no arguments at all." |
||||
@form -synopsis "<punkexe> shell ?arg ...?" |
||||
@values -min 0 -max -1 |
||||
arg -type any -optional 1 -multiple 1 -help\ |
||||
"Arguments passed through to the shell launch." |
||||
}] |
||||
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- |
||||
lappend PUNKARGS [list { |
||||
@id -id (script)::punkexe::punk |
||||
@cmd -name "punkexe punk"\ |
||||
-summary\ |
||||
"punk shell launch; piped-stdin friendly."\ |
||||
-help\ |
||||
"Launch the punk shell. With arguments the app-punkshell launch |
||||
path is used (as for 'shell'); without arguments the |
||||
interactive shell is launched directly. Commands piped into |
||||
stdin are supported (e.g: echo 'puts hello' | <punkexe> punk) |
||||
and stderr is kept clean of launch chatter so exec-style |
||||
callers do not misreport failure." |
||||
@form -synopsis "<punkexe> punk ?arg ...?" |
||||
@values -min 0 -max -1 |
||||
arg -type any -optional 1 -multiple 1 -help\ |
||||
"Arguments passed through to the shell launch." |
||||
}] |
||||
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- |
||||
lappend PUNKARGS [list { |
||||
@id -id (script)::punkexe::shellspy |
||||
@cmd -name "punkexe shellspy"\ |
||||
-summary\ |
||||
"Experimental shellspy command-line processor."\ |
||||
-help\ |
||||
"Pass all arguments to the experimental shellspy command-line |
||||
processor (app-shellspy). Note: 'shellspy' is only this launch |
||||
subcommand - it is not the project name (the project is |
||||
punkshell)." |
||||
@form -synopsis "<punkexe> shellspy ?arg ...?" |
||||
@values -min 0 -max -1 |
||||
arg -type any -optional 1 -multiple 1 -help\ |
||||
"Arguments for the shellspy processor." |
||||
}] |
||||
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- |
||||
} |
||||
|
||||
#*** !doctools |
||||
#[list_end] [comment {--- end definitions namespace punk::args::moduledoc::punkexe ---}] |
||||
} |
||||
|
||||
# ----------------------------------------------------------------------------- |
||||
# register namespace(s) to have PUNKARGS,PUNKARGS_aliases variables checked |
||||
# ----------------------------------------------------------------------------- |
||||
# variable PUNKARGS |
||||
# variable PUNKARGS_aliases |
||||
namespace eval ::punk::args::register { |
||||
#use fully qualified so 8.6 doesn't find existing var in global namespace |
||||
lappend ::punk::args::register::NAMESPACES ::punk::args::moduledoc::punkexe ::punk::args::moduledoc::punkexe::argdoc |
||||
} |
||||
# ----------------------------------------------------------------------------- |
||||
|
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
## Ready |
||||
package provide punk::args::moduledoc::punkexe [tcl::namespace::eval punk::args::moduledoc::punkexe { |
||||
variable pkg punk::args::moduledoc::punkexe |
||||
variable version |
||||
set version 0.1.0 |
||||
}] |
||||
return |
||||
|
||||
#*** !doctools |
||||
#[manpage_end] |
||||
Binary file not shown.
Loading…
Reference in new issue