Added new macro features. resolve_value + default: key. Added raises to prevent CliGen features from being used outside of a already parsed state, and worked on specs. Will be working on specs later on as well to finish covering regex & redo timeparse & relative_operations

This commit is contained in:
2026-09-07 16:40:02 -05:00
parent 3fa77f5707
commit 8fab6912fc
89 changed files with 3615 additions and 515 deletions
+209 -35
View File
@@ -117,6 +117,11 @@
</li>
<li class=" " data-id="CliGenerator/CliGen/Common" data-name="cligen::common">
<a href="../CliGen/Common.html">Common</a>
</li>
<li class=" " data-id="CliGenerator/CliGen/ConfigurationError" data-name="cligen::configurationerror">
<a href="../CliGen/ConfigurationError.html">ConfigurationError</a>
@@ -182,6 +187,11 @@
</li>
<li class=" " data-id="CliGenerator/CliGen/InternalVar" data-name="cligen::internalvar">
<a href="../CliGen/InternalVar.html">InternalVar</a>
</li>
<li class=" " data-id="CliGenerator/CliGen/InvalidFlagValueError" data-name="cligen::invalidflagvalueerror">
<a href="../CliGen/InvalidFlagValueError.html">InvalidFlagValueError</a>
@@ -252,11 +262,6 @@
</li>
<li class=" " data-id="CliGenerator/CliGen/Selection" data-name="cligen::selection">
<a href="../CliGen/Selection.html">Selection</a>
</li>
<li class=" " data-id="CliGenerator/CliGen/SubCommand" data-name="cligen::subcommand">
<a href="../CliGen/SubCommand.html">SubCommand</a>
@@ -373,12 +378,22 @@
<br/>
cligen/command/def_init.cr
cligen/command/define_command_initializer.cr
<br/>
cligen/command/define_command_initializer.cr
cligen/command/define_singleton_init.cr
<br/>
cligen/command/generate_gather_handler.cr
<br/>
cligen/command/generate_register_command.cr
<br/>
@@ -388,7 +403,7 @@
<br/>
cligen/command/selection.cr
cligen/command/resolve_value.cr
<br/>
@@ -397,6 +412,11 @@
<br/>
cligen/command/validate_command_tree.cr
<br/>
@@ -418,12 +438,7 @@
<ul class="list-summary">
<li class="entry-summary">
<a href="#argument%28variable%2Cdescription%2Clong%3Dnil%2Cshort%3Dnil%2Cvalidation%3Dnil%2Con_match%3Dnil%2Cdef_setter%3Dfalse%2Cdef_getter%3Dfalse%2Coptions%3Dnil%2Cdelimiter%3D%22%2C%22%2Cformat%3Dnil%2Callow_no_verification%3Dfalse%2Cenv_var%3Dnil%29-macro" class="signature"><strong>argument</strong>(variable, description, long = <span class="n">nil</span>, short = <span class="n">nil</span>, validation = <span class="n">nil</span>, on_match = <span class="n">nil</span>, def_setter = <span class="n">false</span>, def_getter = <span class="n">false</span>, options = <span class="n">nil</span>, delimiter = <span class="s">&quot;,&quot;</span>, format = <span class="n">nil</span>, allow_no_verification = <span class="n">false</span>, env_var = <span class="n">nil</span>)</a>
</li>
<li class="entry-summary">
<a href="#def_init-macro" class="signature"><strong>def_init</strong></a>
<a href="#argument%28variable%2Cdescription%2Clong%3Dnil%2Cshort%3Dnil%2Cvalidation%3Dnil%2Con_match%3Dnil%2Cdef_setter%3Dfalse%2Cdef_getter%3Dfalse%2Coptions%3Dnil%2Cdelimiter%3D%22%2C%22%2Cformat%3Dnil%2Callow_no_verification%3Dfalse%2Cenv_var%3D%22%22%29-macro" class="signature"><strong>argument</strong>(variable, description, long = <span class="n">nil</span>, short = <span class="n">nil</span>, validation = <span class="n">nil</span>, on_match = <span class="n">nil</span>, def_setter = <span class="n">false</span>, def_getter = <span class="n">false</span>, options = <span class="n">nil</span>, delimiter = <span class="s">&quot;,&quot;</span>, format = <span class="n">nil</span>, allow_no_verification = <span class="n">false</span>, env_var = <span class="s">&quot;&quot;</span>)</a>
</li>
@@ -432,13 +447,32 @@
</li>
<li class="entry-summary">
<a href="#define_singleton_init-macro" class="signature"><strong>define_singleton_init</strong></a>
<div class="summary"><p>This macro simply provides a easy singleton initializer for your command to allow for you do (if this class isn't the target of a command) to still be able to gather a Command object without having to have it as the target.</p></div>
</li>
<li class="entry-summary">
<a href="#generate_gather_handler-macro" class="signature"><strong>generate_gather_handler</strong></a>
</li>
<li class="entry-summary">
<a href="#generate_register_command-macro" class="signature"><strong>generate_register_command</strong></a>
</li>
<li class="entry-summary">
<a href="#help_template%28filepath%29-macro" class="signature"><strong>help_template</strong>(filepath)</a>
</li>
<li class="entry-summary">
<a href="#selection%28variable%2Cdescription%2Coptions%2Cshort%3Dnil%2Clong%3Dnil%2Cvalidation%3Dnil%2Con_match%3Dnil%29-macro" class="signature"><strong>selection</strong>(variable, description, options, short = <span class="n">nil</span>, long = <span class="n">nil</span>, validation = <span class="n">nil</span>, on_match = <span class="n">nil</span>)</a>
<a href="#resolve_value%28variable%2C%2A%2Cdefault%3Dnil%29-macro" class="signature"><strong>resolve_value</strong>(variable, *, default = <span class="n">nil</span>)</a>
<div class="summary"><p>This macro is just meant to provide the user an ability to resolve instance var/varibles from parent commands.</p></div>
</li>
@@ -447,10 +481,34 @@
</li>
<li class="entry-summary">
<a href="#validate_command_tree-macro" class="signature"><strong>validate_command_tree</strong></a>
<div class="summary"><p>This macro serves as a compile-time checker of the command-tree to validate that there is no recursive references of the command-list that would possibly cause a recursive stack-overflow during App.generate when App begins registering all user defined commands.</p></div>
</li>
</ul>
<h2>
<a id="instance-method-summary" class="anchor" href="#instance-method-summary">
<svg class="octicon-link" aria-hidden="true">
<use href="#octicon-link"/>
</svg>
</a>
Instance Method Summary
</h2>
<ul class="list-summary">
<li class="entry-summary">
<a href="#handler%3F%3ABool-instance-method" class="signature"><strong>#handler?</strong> : Bool</a>
</li>
</ul>
<div class="methods-inherited">
@@ -497,26 +555,12 @@
Macro Detail
</h2>
<div class="entry-detail" id="argument(variable,description,long=nil,short=nil,validation=nil,on_match=nil,def_setter=false,def_getter=false,options=nil,delimiter=&quot;,&quot;,format=nil,allow_no_verification=false,env_var=nil)-macro">
<div class="entry-detail" id="argument(variable,description,long=nil,short=nil,validation=nil,on_match=nil,def_setter=false,def_getter=false,options=nil,delimiter=&quot;,&quot;,format=nil,allow_no_verification=false,env_var=&quot;&quot;)-macro">
<div class="signature">
macro <strong>argument</strong>(variable, description, long = <span class="n">nil</span>, short = <span class="n">nil</span>, validation = <span class="n">nil</span>, on_match = <span class="n">nil</span>, def_setter = <span class="n">false</span>, def_getter = <span class="n">false</span>, options = <span class="n">nil</span>, delimiter = <span class="s">&quot;,&quot;</span>, format = <span class="n">nil</span>, allow_no_verification = <span class="n">false</span>, env_var = <span class="n">nil</span>)
macro <strong>argument</strong>(variable, description, long = <span class="n">nil</span>, short = <span class="n">nil</span>, validation = <span class="n">nil</span>, on_match = <span class="n">nil</span>, def_setter = <span class="n">false</span>, def_getter = <span class="n">false</span>, options = <span class="n">nil</span>, delimiter = <span class="s">&quot;,&quot;</span>, format = <span class="n">nil</span>, allow_no_verification = <span class="n">false</span>, env_var = <span class="s">&quot;&quot;</span>)
<a class="method-permalink" href="#argument%28variable%2Cdescription%2Clong%3Dnil%2Cshort%3Dnil%2Cvalidation%3Dnil%2Con_match%3Dnil%2Cdef_setter%3Dfalse%2Cdef_getter%3Dfalse%2Coptions%3Dnil%2Cdelimiter%3D%22%2C%22%2Cformat%3Dnil%2Callow_no_verification%3Dfalse%2Cenv_var%3Dnil%29-macro">#</a>
</div>
<br/>
<div>
</div>
</div>
<div class="entry-detail" id="def_init-macro">
<div class="signature">
macro <strong>def_init</strong>
<a class="method-permalink" href="#def_init-macro">#</a>
<a class="method-permalink" href="#argument%28variable%2Cdescription%2Clong%3Dnil%2Cshort%3Dnil%2Cvalidation%3Dnil%2Con_match%3Dnil%2Cdef_setter%3Dfalse%2Cdef_getter%3Dfalse%2Coptions%3Dnil%2Cdelimiter%3D%22%2C%22%2Cformat%3Dnil%2Callow_no_verification%3Dfalse%2Cenv_var%3D%22%22%29-macro">#</a>
</div>
<br/>
@@ -539,6 +583,60 @@
</div>
</div>
<div class="entry-detail" id="define_singleton_init-macro">
<div class="signature">
macro <strong>define_singleton_init</strong>
<a class="method-permalink" href="#define_singleton_init-macro">#</a>
</div>
<div class="doc">
<p>This macro simply provides a easy singleton initializer for your command
to allow for you do (if this class isn't the target of a command) to still
be able to gather a Command object without having to have it as the target.</p>
<p>This will setup the default (no args) initializer to gather the handler from
CliGen::App and then resolve all of the ivar (CliGen managed) to the parsed
values from the associated Flag(T) object that (if the process itself is
being started by CliGen the provided flags will store the value to be
set here)</p>
</div>
<br/>
<div>
</div>
</div>
<div class="entry-detail" id="generate_gather_handler-macro">
<div class="signature">
macro <strong>generate_gather_handler</strong>
<a class="method-permalink" href="#generate_gather_handler-macro">#</a>
</div>
<br/>
<div>
</div>
</div>
<div class="entry-detail" id="generate_register_command-macro">
<div class="signature">
macro <strong>generate_register_command</strong>
<a class="method-permalink" href="#generate_register_command-macro">#</a>
</div>
<br/>
<div>
</div>
</div>
<div class="entry-detail" id="help_template(filepath)-macro">
<div class="signature">
@@ -553,14 +651,29 @@
</div>
</div>
<div class="entry-detail" id="selection(variable,description,options,short=nil,long=nil,validation=nil,on_match=nil)-macro">
<div class="entry-detail" id="resolve_value(variable,*,default=nil)-macro">
<div class="signature">
macro <strong>selection</strong>(variable, description, options, short = <span class="n">nil</span>, long = <span class="n">nil</span>, validation = <span class="n">nil</span>, on_match = <span class="n">nil</span>)
macro <strong>resolve_value</strong>(variable, *, default = <span class="n">nil</span>)
<a class="method-permalink" href="#selection%28variable%2Cdescription%2Coptions%2Cshort%3Dnil%2Clong%3Dnil%2Cvalidation%3Dnil%2Con_match%3Dnil%29-macro">#</a>
<a class="method-permalink" href="#resolve_value%28variable%2C%2A%2Cdefault%3Dnil%29-macro">#</a>
</div>
<div class="doc">
<p>This macro is just meant to provide the user an ability to resolve instance
var/varibles from parent commands. Simply to allow subcommands to be able
to retrieve values from their parents</p>
<p>As an aside, this (as written) can only be used for variables that have
a default defined (ex: @var : Int32 = 3)</p>
<p>For variables that (in your parent class) isn't set with a default value,
you will need to provide the (default: <val>) kwarg to set your own
runtime default if the value itself cannot be ensured by the compiler.</p>
<p>This is a requirement as this macro MUST always return a value without
rasing, and the only way to do that is force the user to provide a
default of their choosing.</p>
</div>
<br/>
<div>
@@ -581,9 +694,70 @@
</div>
</div>
<div class="entry-detail" id="validate_command_tree-macro">
<div class="signature">
macro <strong>validate_command_tree</strong>
<a class="method-permalink" href="#validate_command_tree-macro">#</a>
</div>
<div class="doc">
<p>This macro serves as a compile-time checker of the command-tree to
validate that there is no recursive references of the command-list
that would possibly cause a recursive stack-overflow during App.generate
when App begins registering all user defined commands.</p>
<p>However, while this does exist, due to the way that the App.generate method
handles gathering root commands it makes this edge-case impossible to hit
aside from manually running the
Command#register_command([] of CliGen::Command) method.</p>
<p>However, with this in place this issue cannot be hit at runtime as this will
prevent compilation if a recursive/circular command tree exists.</p>
<p>Additionally, this exists to prevent the user from defining a command tree
that extends past the compile-time configured max via the
CliGen::MAX_COMMAND_DEPTH constant.</p>
<p>The reason this is a thing is because crystal macros don't allow for
unbounded while's/until's in macros, meaning it always has to be
deterministic. SO to deal with this and still allow for subcommand
defining you need either go with the default (32 command depth) or
define your own larger max (understand this will affect compile-time
due to this directly affecting loops in the Command macros).</p>
</div>
<br/>
<div>
</div>
</div>
<h2>
<a id="instance-method-detail" class="anchor" href="#instance-method-detail">
<svg class="octicon-link" aria-hidden="true">
<use href="#octicon-link"/>
</svg>
</a>
Instance Method Detail
</h2>
<div class="entry-detail" id="handler?:Bool-instance-method">
<div class="signature">
def <strong>handler?</strong> : Bool
<a class="method-permalink" href="#handler%3F%3ABool-instance-method">#</a>
</div>
<br/>
<div>
</div>
</div>
</div>