haxetink / tink_cli Goto Github PK
View Code? Open in Web Editor NEWWrite command line tools in Haxe
License: MIT License
Write command line tools in Haxe
License: MIT License
Just like --
in other cli
Hi,
I'm not sure if it's related to #3, but I wanted to know if there is a plan to extend the Prompt capabilities?
I'm not an Haxe macro expert so it's hard for me to try to match your style of code, but I've built a little sample to show you what I have in mind:
var author = CLI.ask("Author Name");
var mail = CLI.ask("What is your email adress", emailCallback);
var select = CLI.select(elements); // horizontal
var select = CLI.select(elements,true); // vertical
I'm cleaning the code a bit and I will create a public repo for it if you feel like guiding me on properly adding it to tink_cli!
@:required
public var assets:Array<String>;
Currently fails with tink.Stringly should be Array<String>
The examples specified in the doc, the readme and in the repo are incorrect. When trying to compile it warns you that you're not allowed to use Array<String> and that you have to refer to the docs about using a custom abstract instead. This didn't really make sense to me but after some troubleshooting and looking at the unit tests I figured out why. You have to initialize the variables as null.
Don't echo user input.
I am getting this error about 30 times with tink_cli 0.5.0.
~/haxe/haxe_libraries/tink_cli/0.5.0/haxelib/src/tink/cli/Macro.hx|169 col 21 error| On static platforms, null can't be used as basic type Bool
I have seen a mention in haxelib info tink_cli that 0.5.0 introduces a breaking change: 2019-11-06 06:47:50 0.5.0 : [breaking] Vars without expression is treated as required flags
but I can not figure out what it is.
I should probably investigate further but my app has subcommands (e.g. myapp command subcommand args) so a lot of classes are using tink_cli, better ask advice before.
Edit: reverted to tink_cli 0.4.1 for now, it compiles alright.
/home/matt/.local/share/haxe/lib/tink_cli/0,5,0/src/tink/cli/Macro.hx:20: characters 29-61 : Uncaught exception Type not found 'tink.Stringly'
/usr/share/haxe/std/haxe/macro/Context.hx:277: characters 10-35 : Called from here
/home/matt/.local/share/haxe/lib/tink_cli/0,5,0/src/tink/cli/Macro.hx:20: characters 29-61 : Called from here
/usr/share/haxe/std/haxe/macro/Context.hx:51: characters 10-36 : Called from here
/home/matt/.local/share/haxe/lib/tink_cli/0,5,0/src/tink/cli/Macro.hx:96: characters 15-104 : Called from here
/home/matt/.local/share/haxe/lib/tink_cli/0,5,0/src/tink/cli/Macro.hx:25: characters 57-73 : Called from here
/usr/share/haxe/std/haxe/macro/Context.hx:51: characters 10-36 : Called from here
/home/matt/.local/share/haxe/lib/tink_cli/0,5,0/src/tink/cli/Macro.hx:96: characters 15-104 : Called from here
/home/matt/.local/share/haxe/lib/tink_cli/0,5,0/src/tink/cli/Macro.hx:25: characters 57-73 : Called from here
I'm just trying to start a project, not doing anything fancy yet.
compile.hxml
--library tink_http
--library tink_cli
--library tink_stringly
--library yaml
tink_cli/src/tink/cli/Macro.hx
Line 493 in c9124f9
C:/Haxe/Haxe425/haxe/lib/tink_cli/0,5,1/src/tink/cli/Macro.hx:493: characters 34-41 : Uncaught exception Null Access
C:/Haxe/Haxe425/haxe/lib/tink_cli/0,5,1/src/tink/cli/Macro.hx:403: characters 62-73 : Called from here
C:/Haxe/Haxe425/haxe/lib/tink_core/2,1,1/src/tink/core/Promise.hx:86: characters 24-28 : Called from here
C:/Haxe/Haxe425/haxe/lib/tink_core/2,1,1/src/tink/core/Future.hx:109: characters 47-54 : Called from here
C:/Haxe/Haxe425/haxe/lib/tink_core/2,1,1/src/tink/core/Future.hx:537: characters 12-35 : Called from here
C:/Haxe/Haxe425/haxe/lib/tink_core/2,1,1/src/tink/core/Future.hx:511: characters 7-12 : Called from here
C:/Haxe/Haxe425/haxe/lib/tink_core/2,1,1/src/tink/core/Future.hx:533: characters 9-32 : Called from here
Part of the problem may be my Haxe version, it's 4.3 which changes macro parsing I think.
Hi,
Thanks for this library, exactly what I was about to write :).
I have a few issues I'm not sure if it's user error or code issues yet.
Here my simple case:
class Go {
public static function main() {
Cli.process(Sys.args(), new GoCli()).handle(Cli.exit);
}
}
class GoCli {
@:flag('verbose')
public static var debug:Bool;
@:flag('-r')
public static var targetSize:String;
@:flag('help')
public static var help:Bool;
@:defaultCommand
public function run(rest:Rest<String>) {
if (help){
trace(Cli.getDoc(run));
return;
}
trace('Resize to: $targetSize');
trace('Verbose: $debug');
}
}
Very simple case to illustrate my issues. I had to completely remove the getDoc as it fails with the following errors:
C:\HaxeToolkit\haxe\lib\tink_cli/git/src/tink/cli/Macro.hx:235: characters 14-19 : Uncaught exception assert
C:\HaxeToolkit\haxe\lib\tink_cli/git/src/tink/cli/Macro.hx:33: characters 15-31 : Called from here
C:\HaxeToolkit\haxe\lib\tink_cli/git/src/tink/Cli.hx:24: characters 13-60 : Called from here
src/tools/Cmft.hx:176: characters 23-38 : Called from here
C:\HaxeToolkit\haxe\lib\tink_cli/git/src/tink/cli/Macro.hx:425: characters 29-32 : Called from here
C:\HaxeToolkit\haxe\lib\tink_cli/git/src/tink/cli/Macro.hx:506: characters 4-31 : Called from here
C:\HaxeToolkit\haxe\lib\tink_cli/git/src/tink/cli/Macro.hx:411: characters 11-43 : Called from here
C:\HaxeToolkit\haxe\lib\tink_cli/git/src/tink/cli/Macro.hx:110: characters 16-42 : Called from here
C:\HaxeToolkit\haxe\lib\tink_cli/git/src/tink/cli/Macro.hx:23: characters 57-73 : Called from here
For function argument 'message'
And my other issue is Int not being catch:
Command | Output |
---|---|
cmd -v or cmd --verbose | Resize to: null Verbose: true |
cmd -r 2048 | Resize to: null Verbose: false |
Hi Kevin,
I'm not sure that you are interested in this, or even if it's the right approach, but as I did not think tink_cli
was able to do that, here is a small writeup on Subcommands with tink_cli
:
MainCommand
to wire them allThe idea is pretty simple, your main command is just used to run your subcommands as commands... An example will be clearer.
Let's take this basic example:
class Main {
static function main() {
Cli.process(Sys.args(), new MainCommand()).handle(Main.exit);
}
}
class MainCommand
{
/** Be more verbose */
public var verbose:Bool=false;
public function new() {}
@:defaultCommand
public function main_command(rest:Rest<String>){
// print the help
Sys.println(Cli.getDoc(this));
}
}
tink_cli sets the public var verbose
as a flag (-v or --verbose) and running the command simply prints the help.
Now just like we did we run the main command we can run subcommands, let's add an info
subcommand:
class MainCommand
{
/** Be more verbose */
public var verbose:Bool=false;
public function new() {}
@:defaultCommand
public function main_command(rest:Rest<String>){
// print the help
Sys.println(Cli.getDoc(this));
}
/** Get the news */
@:command public function info(rest:Rest<String>){
Sys.println("INFO");
}
}
This will work as expected but the issue is the more complicated your app gets the more separation you want..
The trick to separate commands and flags it to remove the first item from the Sys.args() before handling it:
class MainCommand
{
/** Be more verbose */
public var verbose:Bool=false;
public function new() {}
/** Returns Sys.args without the first arg. */
private function subargs():Array<String> {
var fargs = Sys.args();
fargs.remove(fargs[0]);
return fargs;
}
@:defaultCommand
public function main_command(rest:Rest<String>){
// print the help
Sys.println(Cli.getDoc(this));
}
/** Get the news */
@:command public function info(rest:Rest<String>){
Cli.process(subargs(), new InfoCommand()).handle(Cli.exit);
}
}
class InfoCommand
{
/** Filters fake news */
@:flag("fake")
public var verbose:fakeNewsFilter=false;
@:defaultCommand
public function main_command(rest:Rest<String>){
// print the help
Sys.println(Cli.getDoc(this));
}
We now have two separate sets of flags for subcommands
Hello,
I came across an issue while doing some tests using Tink_Cli.
See following code:
import tink.cli.*;
import tink.Cli;
class Main {
/**
* REQUIRED - Specify a first flag
*/
@:required
public var flag:String;
/**
* Specify a second flag
*/
public var anotherflag:String;
static function main() {
Cli.process(Sys.args(), new Main()).handle(Cli.exit);
}
public function new() {}
@:defaultCommand @:skipFlags
public function default_command() {
Sys.println(Cli.getDoc(this));
}
/**
* Show Test #1
*/
@:command
public function test1(rest:Rest<String>) {
trace(flag);
}
/**
* Show Test #2
*/
@:command @:skipFlags
public function test2() {
trace("Test #2");
}
/**
* Write a file
*/
@:command @:skipFlags
public function write() {
trace("\n[INFO] Writing to file...");
}
}
This execute properly, but if you remove the digit from the function test1 or test2 or if you rename them without a digit in the name, then the execution in Python without args (should retrieve the help command as it is the default command) result in the following error:
Traceback (most recent call last): File "Main.py", line 2245, in <module> Main.main() File "Main.py", line 131, in main tink_cli_Router0(Main(),tink_cli_prompt_RetryPrompt(5)).process(Sys.args()).handle(tink_Cli.exit) File "Main.py", line 1280, in process _hx_local_0 = len(_g) TypeError: object of type 'NoneType' has no len()
Same is true if you keep the name unchanged while forcing it through metadata:
@:command("test")
public function test1(rest:Rest<String>) {
trace(flag);
}
But calling the program while specifying the flag "test" does work. Thus:
python main.py test
Work as intended.
Best regards;
So this allows commands to select what flags they need.
README reads "Every public var in the class will be treated as a cli flag". I was wondering if there was a meta to disable it from a tink_cli standpoint.
Right now I would put the variable private, and use a @:privateAccess
. Feels a little dirty though.
Hi Kevin,
I've been using tink_cli quite a lot and I'm amazed at the possibilities!
How can I catch exceptions for unknown flags?
For now, it simply outputs:
Unexpected Error, Unrecognized alias "-a"
Instead of manual caching
Context.getType('tink.Stringly').unifiesWith
fails when building cli.
tink_cli/0,5,1/src/tink/cli/Macro.hx:374: characters 39-50 : haxe.macro.Type has no field unifiesWith
Not sure if a bug, or whether I don't understand best practices, but I get the following error if not specifying "tink_io:0.5.0" in my hxml:
/usr/share/haxelib/tink_cli/0,3,1/src/tink/cli/prompt/SimplePrompt.hx:5: characters 7-21 : Type not found : tink.io.Duplex
If replacing -l tink_io
with -l tink_io:0.5.0
it compiles.
I am just installing libs with sudo haxelib install tink_xxx
and using sudo haxelib update
to update them.
Is there a documentation that deals about best practices to use tink libs? I use them more and more (as the tink libs are awesome, despite the learning curve).
I also had the same problem where I had to use tink_core:1.17.1 instead of the latest to be able to use the latest tink_streams.
I'm worried about situations where things would compile but code would be broken if forcing versions too much...
If it is a single dash + single char.
Don't disable alias too.
Produce a warning too.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.