Pipe CLI
Why should I use it?
Pipe goal's is help users automate everyday tasks and standardize codes. Pipe allow you create and
document CLI commands and code templates using markdown
and yaml
. With Pipe you can create
scripts that:
- Generate code
- Refactor code
- Run commands
and much more.
Motivations
You probably know a CLI command, but it takes care of everything you need?
Sometimes we need a very specific command or, that well know command with some changes, but sometimes these changes are not possible to config and there are no command that meet expectations available.
Pipe CLI allows you write CLI commands with flexible configurations using scripts yaml
and
pre-fabs commands.
Features
Installation
dart pub global activate pipe_cli
Usage
Getting Stated
- Create a pipe.md file, write your CLI command using yaml
- Run your CLI command
pipe <your_created_cli>
Create CLI (Command Line Interface)
To create a new CLI command simple add your script inside file pipe.md.
**`example.yaml`**
```yaml
say_hello:
name: 'hello' # Name of command, used to call it on terminal
abbr: 'h' # Abbrev of command, used as an alias of Name
description: 'Say hello'
execute:
- print: 'Hello World' # A pre-fab command called "print" that show 'Hello World' in terminal
```
to use just simple runs
pipe say hello
Create subcommands
To create a subcommand write first your command and add a list named sub-commands
with the name of
cli that will work as subcommand, subcommands name must have command name and name separated by a
dot.
**`example.yaml`**
```yaml
say:
name: 'say' # Name of command, used to call it on terminal
abbr: 's' # Abbrev of command, used as an alias of Name
description: 'Say something'
sub_commands:
- say.hello
say.hello:
name: 'hello'
abbr: 'h'
description: 'Say hello
execute:
- print: 'Hello World' # A pre-fab command called "print" that show 'Hello World' in terminal
```
to use just simple runs
pipe say hello
Add options to CLI
To create a subcommand write first your command and add a list named sub-commands
with the name of
cli that will work as subcommand, subcommands name must have command name and name separated by a
dot.
**`example.yaml`**
```yaml
say:
name: 'say' # Name of command, used to call it on terminal
abbr: 's' # Abbrev of command, used as an alias of Name
description: 'Say something'
sub_commands:
- say.hello
say.hello:
name: 'hello'
abbr: 'h'
description: 'Say hello
args:
world:
help: "appends a word 'World' to phrase" # help text showed when use --help flag
abbr: w # an alias to this flag (usage -w)
negatable: true # create option --no-world that set world as false
defaults: true # set defaults as true
execute:
if_flag:
flag: world
then:
- print: 'Hello World' # A pre-fab command called "print" that show 'Hello World' in terminal
else:
- print: 'Hello' # A pre-fab command called "print" that show 'Hello' in terminal
```
to use just simple runs
pipe say hello --world
or
pipe say hello -w
Pipe.md
Create a markdown file named pipe.md
then write your first command.
**`name_of_script`**
```yaml
gen_usecase:
name: usecase
abbr: u
description: 'Creates an usecase in a custom template'
```
The command receive a pattern, extracts of this pattern two arguments `feature` and `name`, then
creates a usecase named `**name**_usecase.dart` in
`lib/**feature**/domain/usecases/` path from templates `interface_usecase` and `usecase`.
```yaml
execute:
- install:
- get_it
- capture:
text: '{{rest}}'
regex: '(?<feature>[A-z]*)@(?<name>[A-z]*)'
- file_name: '{{name}}_usecase'
- file_path: 'lib/features/{{feature}}/domain/usecase/{{file_name}}.dart'
- build_usecase: '{{interface_usecase}}{{\n}}{{usecase}}'
- generate:
template: '{{build_usecase}}'
path: '{{file_path}}'
```
# Templates
Creates a new line
**`\n`**
```dart
```
Template of an interface for Usecases
**`interface_usecase`**
```dart
abstract class I{{file_name|pascalCase}} {
Future<void> call();
}
```
Template of an implementation of Usecase using interface
**`usecase`**
```dart
class {{file_name|pascalCase}} extends I{{file_name|pascalCase}} {
@override
Future<void> call() async {
throw UnimplementedError();
}
}
```
Detailing
-
Name of your script
You must declare the name of yaml script at least once, on first declaration.
**`name_of_script`**
-
Script declaration named
gen_usecase
, where created a CLI command namedusecase
with abbrevu
and descriptionCreates an usecase in a custom template
.Must be at next line after name.
**`name_of_script`** ```yaml usecase: name: usecase abbr: u description: 'Creates an usecase in a custom template' ```
-
Documentation of your script.
Declaration of flags and options [Work In Progress].
-
Execution steps declaration Note that there are Objects and Values, the objects are interpreted as a Command and the Values as a Variable.
```yaml execute: - install: - get_it - capture: text: '{{rest}}' regex: '(?<feature>[A-z]*)@(?<name>[A-z]*)' - file_name: '{{name}}_usecase' - file_path: 'lib/features/{{feature}}/domain/usecase/{{file_name}}.dart' - build_usecase: '{{interface_usecase}}{{\n}}{{usecase}}' - generate: template: '{{build_usecase}}' path: '{{file_path}}' ```
-
Creates a dart template
**`interface_usecase`** ```dart abstract class I{{file_name|pascalCase}} { Future<void> call(); } ```
Commands
capture: Create variables with names
equals named capturing groups (
regex) of gived regex
with values matches in text
.
```yaml
...
capture:
text: 'a CamelCase word'
regex: '(?<word_with_camelCase>^[a-z]|[A-Z0-9])[a-z]*'
```
generate: Create a file path
with content template
.
```yaml
...
generate:
template: '{{build_usecase}}'
path: '{{file_path}}'
```
print: Print the given value.
```yaml
...
print: 'Hello World'
```
run: Run a command at terminal.
```yaml
...
run:
executable: 'dart'
args:
- pub
- add
- dio
show_outputs: true # defaults true - show outputs of given command (dart)
provide_feedback: true # defaults true - provide a feedback of success or error at end the command
```
Variables
Declare variables using an yaml object with value String
num
bool
, the variable name must not
match an object name.
You can interpolate values using double mustache expression
Hello {{name}}
.
```yaml
...
name: 'André'
hello_world: 'Hello {{André}}'
print: hello_world
```
Templates
Dart code are saved as templates and can be used as parameter using eval sintax {{template_name}}
passing the name of template that is the content before dart block between template name pattern
**`name_of_template`**
```yaml
generate_class:
name: generate_class
abbr: g
description: Creates a Class.
execute:
- class_name: 'some_class'
- generate:
template: '{{use_case.dart}}'
path: 'lib/classes/{{class_name}}.dart'
```
**`class_template`**
```dart
class {{class_name|pascalCase}}{}
```