Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
25 changed files
with
665 additions
and
162 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
# @cli | ||
|
||
The `@cli` module provides a simple interface to | ||
easily build CLI applications. | ||
|
||
## API | ||
|
||
```py | ||
cli = require('@cli') | ||
``` | ||
|
||
### @cli.cmd(name, description, default_flags) | ||
|
||
A decorator that registers a command to be executed via CLI: | ||
|
||
```py | ||
@cli.cmd("date", "prints the current date", {format: ''}) | ||
f date(args, flags) { | ||
format = flags.format | ||
return `date ${format}` | ||
} | ||
``` | ||
|
||
The `name` of the command matches the command entered | ||
by the user on the CLI (eg. `$ ./cli my_command`), while | ||
the description is used when printing a help message, | ||
available through `$ ./cli help`. | ||
|
||
The user can pass however many arguments and flags they want, | ||
and they will be passed on to the function defined as command. | ||
For example, when the user issues the command `$ ./cli a b c --flag 25`, | ||
args will be `["a", "b", "c", "--flag", "25"]` and flags will | ||
be `{"flag": "25"}`. Default flags are there so that, if a flag | ||
is not passed, it will be populated with a default value. | ||
|
||
### @cli.run() | ||
|
||
Runs the CLI application: | ||
|
||
```py | ||
cli.run() | ||
``` | ||
|
||
The application will, by default, have an `help` command | ||
that lists all available commands and is called if no command | ||
is provided. | ||
|
||
## Example CLI app | ||
|
||
Here is an example app with 3 commands: | ||
|
||
* the default `help` | ||
* `date`, to print the current date in a specific format | ||
* `ip`, to fetch our IP address | ||
|
||
```py | ||
#!/usr/bin/env abs | ||
cli = require('@cli') | ||
|
||
@cli.cmd("ip", "finds our IP address", {}) | ||
f ip_address(arguments, flags) { | ||
return `curl icanhazip.com` | ||
} | ||
|
||
@cli.cmd("date", "Is it Friday already?", {"format": ""}) | ||
f date(arguments, flags) { | ||
format = flags.format | ||
return `date ${format}` | ||
} | ||
|
||
cli.run() | ||
``` | ||
|
||
You can save this script as `./cli` and make it executable | ||
with `chmod +x ./cli`. Then you will be able to use the CLI | ||
app: | ||
|
||
``` | ||
$ ./cli | ||
Available commands: | ||
* date - Is it Friday already? | ||
* help - print this help message | ||
* ip - finds our IP address | ||
$ ./cli help | ||
Available commands: | ||
* date - Is it Friday already? | ||
* help - print this help message | ||
* ip - finds our IP address | ||
$ ./cli ip | ||
87.201.252.69 | ||
$ ./cli date | ||
Sat Apr 4 18:06:35 +04 2020 | ||
$ ./cli date --format +%s | ||
1586009212 | ||
``` | ||
|
||
## Next | ||
|
||
That's about it for this section! | ||
|
||
You can now head over to read a little bit about [how to install 3rd party libraries](/misc/3pl). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
# Standard library | ||
|
||
ABS comes bundled not only with an array of builtin types and functions, | ||
but also with a few modules to ease your development process: we refer | ||
to this modules as the "standard library", "standard modules" or `stdlib`. | ||
|
||
## Requiring a standard library module | ||
|
||
Standard library modules are required the same way you'd require | ||
any other external module, by using the `require(...)` function; | ||
the only difference is that standard modules use the `@` character | ||
as prefix, for example: | ||
|
||
```py | ||
mod = require('@module') # Loads "module" from the standard library | ||
mod = require('./module') # Loads "module" from the current directory | ||
mod = require('module') # Loads "module" that was installed through the ABS package manager | ||
``` | ||
|
||
## Technical details | ||
|
||
The ABS standard library is developed in ABS itself and available | ||
for everyone to see (and poke with) at [github.com/abs-lang/abs/tree/master/stdlib](https://github.com/abs-lang/abs/tree/master/stdlib). | ||
|
||
The `@cli` library, for example, is a simple ABS script of less | ||
than 100 lines of code: | ||
|
||
```bash | ||
# CLI app | ||
cli = {} | ||
|
||
# Commands registered within this CLI app | ||
cli.commands = {} | ||
|
||
# Function used to register a command | ||
cli.cmd = f(name, description, flags) { | ||
return f(fn) { | ||
cli.commands[name] = {}; | ||
cli.commands[name].cmd = f() { | ||
# Create flags with default values | ||
for k, _ in flags { | ||
v = flag(k) | ||
|
||
if v { | ||
flags[k] = v | ||
} | ||
} | ||
|
||
# Call the original cmd | ||
result = fn.call([args()[3:], flags]) | ||
|
||
# If there's a result we print it out | ||
if result { | ||
echo(result) | ||
} | ||
} | ||
|
||
cli.commands[name].description = description | ||
} | ||
} | ||
|
||
# Run the CLI app | ||
cli.run = f() { | ||
# ABS sees "abs script.abs xyz" | ||
# so the command is the 3rd argument | ||
cmd = arg(2) | ||
|
||
# Not passing a command? Let's print the help | ||
if !cmd { | ||
return cli.commands['help'].cmd() | ||
} | ||
|
||
if !cli.commands[cmd] { | ||
exit(99, "command '${cmd}' not found") | ||
} | ||
|
||
return cli.commands[cmd].cmd() | ||
} | ||
|
||
# Add a default help command that can be | ||
# overridden by the caller | ||
@cli.cmd("help", "print this help message", {}) | ||
f help() { | ||
echo("Available commands:\n") | ||
|
||
for cmd in cli.commands.keys().sort() { | ||
s = " * ${cmd}" | ||
|
||
if cli.commands[cmd].description { | ||
s += " - " + cli.commands[cmd].description | ||
} | ||
|
||
echo(s) | ||
} | ||
} | ||
|
||
return cli | ||
``` | ||
## Next | ||
That's about it for this section! | ||
You can now explore ABS' first standard library module, the [@runtime](/stdlib/runtime). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# @runtime | ||
|
||
The `@runtime` module provides information about the ABS | ||
runtime that is currently executing the script. | ||
|
||
## API | ||
|
||
```py | ||
runtime = require('@runtime') | ||
``` | ||
|
||
### @runtime.version | ||
|
||
Returns the version of the ABS interpreter: | ||
|
||
```py | ||
runtime.version # "x.y.z" eg. 1.0.0 | ||
``` | ||
|
||
### @runtime.name | ||
|
||
Returns the name of the runtime: | ||
|
||
```py | ||
runtime.name # "abs" | ||
``` | ||
|
||
## Next | ||
|
||
That's about it for this section! | ||
|
||
You can now explore how to easily build command-line applications through the [@cli](/stdlib/cli) module. |
Oops, something went wrong.