Skip to content

Commit

Permalink
More documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
erdnaxeli committed Apr 11, 2021
1 parent 9b0c8d0 commit 039431c
Show file tree
Hide file tree
Showing 9 changed files with 217 additions and 4 deletions.
37 changes: 37 additions & 0 deletions docs/alternatives.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Alternatives, inspirations and comparisons

**Clip** is not the only library to parse CLI parameters.
Here are some alternatives and inspirations.

## <a href="https://typer.tiangolo.com" class="external-link" target="_blank">Typer</a>

> Typer is a library for building CLI applications that users will love using and developers will love creating.
Typer is actually a Python library and an awesome project!
It inspired a lot **Clip**, whether for the idea of using type restrictions, the general behavior of the lib (what to consider an option or an argument, the help message), or even this documentation.

## <a href="https://crystal-lang.org/api/1.0.0/OptionParser.html" class="external-link" target="_blank">OptionParser</a>

> `OptionParser` is a class for command-line options processing.
It works by using a specific DSL to react to options or arguments during the parsing.

## <a href="https://github.com/jwaldrip/admiral.cr" class="external-link" target="_blank">Admiral.cr</a>

> A robust DSL for writing command line interfaces
Admiral provides an easy way to define command using a user defined type and a DSL.

## <a href="https://github.com/mrrooijen/commander" class="external-link" target="_blank">Commander</a>

> Command-line interface builder for the Crystal programming language.
Commander provides a DSL to declare and use options, arguments, and commands.

## <a href="https://github.com/j8r/clicr" class="external-link" target="_blank">Clicr</a>

> A simple declarative command line interface builder.
Unlike to others presented libraries (and **Clip**), Clicr is declarative: you call the library with a NamedTuple describing exactly what options, arguments and command you want.

--8<-- "includes/abbreviations.md"
69 changes: 69 additions & 0 deletions docs/contributing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Contributing

Feel free to contribute to **Clip**.

If you spot a bug, you can [open a pull request](https://github.com/erdnaxeli/clip/pulls) to fix it.
If you want to contribute but are not sure about how to do it, just [open an issue](https://github.com/erdnaxeli/clip/issues) to talk discuss about it.

Here are some tips to develop on **Clip**, assuming you have already cloned the repository.

## Install the dependencies

Don't forget to install the dependencies.
There is only one so far, and it is a dev one, but it will be useful.

```console
$ shards install
Resolving dependencies
Fetching https://github.com/crystal-ameba/ameba.git
Installing ameba (0.14.2)
Postinstall of ameba: make bin && make run_file
```

## Develop your fix or feature

Always remember to commit your modification on a separated branch.

The majority of the **Clip** features are done by macros.
Macros look like Crystal code, but they actually use a different language that is interpreted at compilation time by the compiler.
The code is not easy to read, don't hesitate to ask for help!

You may want to read the [reference about macros](https://crystal-lang.org/reference/syntax_and_semantics/macros/index.html) and the [macro module documentation](https://crystal-lang.org/api/1.0.0/Crystal/Macros.html).

## Write and run the tests

Whether you fixed a bug or developed a new feature, you need to write a test to test the new behavior.

Then run the tests:

```console
$ crystal spec
........................................................................................................................................

Finished in 5.95 milliseconds
136 examples, 0 failures, 0 errors, 0 pending
```

## Run static code analysis

Ameba provides some hints about the code, to prevent wrong code constructions.

Run it with:

```
$ ./bin/ameba
Inspecting 16 files
................
Finished in 279.16 milliseconds
17 inspected, 0 failure
```

!!! Warning
There is currently an [open issue](https://github.com/crystal-ameba/ameba/issues/224) on Ameba about `Lint/ShadowingOuterLocalVar`, you can skip this failure.

## Open a pull request

Your code is now done, congrats!
Your can open a pull request, I will try to at it quickly :)
6 changes: 6 additions & 0 deletions docs/css/custom.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
a.external-link::after {
/* \00A0 is a non-breaking space
to make the mark be on the same line as the link
*/
content: "\00A0[↪]";
}
47 changes: 47 additions & 0 deletions docs/features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Features

## Static typing

**Clip** use a user defined type, a struct or a class, to infer what options and arguments should be parsed.

The object returned by the **Clip** parsing method is just an instance of this type, hence you benefit from the compilation time type validation.

## No DSL to learn

There is no new DSL to learn to build applications with **Clip**.

You want to add a string option? Just add an attribute and restrict its type to `String`.

You want to add a default value? Just add a default value to the attribute.

You already know how to do it.

## Standard behaviors

**Clip** allows you to build beautiful applications that respect standard behaviors.
Anything you expect from a CLI application should work with **Clip** too: short and long options, flags, arguments, default values, multiple values, standard help messages, and many more.

## Not a CLI application framework

**Clip** is about parsing CLI-like user input, but is not a framework to build CLI applications.

It means that **Clip** does not run your application code for you, does not print anything for you, and can read the user input from any array of strings, not only `ARGV`.

Not running your code application for you means that you are free to architecture you code as you like.
Your command's code can take the parsed options and arguments as a parameter, and anything else too, because _you_ run by yourself, **Clip** does not.

Not printing anything for you means that you can send errors and help messages to any medium, being a `STDOUT`, a socket, or anything else.

Reading the input from any array of strings means that you can use **Clip** to build applications that are not _CLI applications_.
You can receive the user input from an HTTP call, an IRC message, a REPL, or whatever you want.

## Efficient

**Clip** uses your type definition to write a parser and build the hel message.
The parser and the help messages are built at compilation time, which enabled **Clip** to have a minimal overhead at runtime.

## Tested

The **Clip** repository contains 136 tests covering all its features, and all the documentation examples can be run "as is".

--8<-- "includes/abbreviations.md"
8 changes: 8 additions & 0 deletions docs/help.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Get help

This project use [github Discussions](https://github.com/erdnaxeli/clip/discussions) for community discussions.
Don't hesitate to start a discussion if you need help!

If you think you have found a bug, or you would like some new feature to be implemented, just [open an issue](https://github.com/erdnaxeli/clip/issues) :)

If you like **Clip**, don't forget to "star" the repository on Github, it will help other users to known that it is useful.
6 changes: 3 additions & 3 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
---

Clip is a library for building CLI or CLI-like [Crystal](https://crystal-lang.org) applications.
By CLI-like applications I mean every app that interacts with the user in a CLI style, like irc bots.
By CLI-like applications I mean every application that interacts with the user in a CLI style, like IRC bots.

The major features of Clip are:

* **Easy to write**: All you need to write is a type. No new DSL, you get completion in your editor, and you have type safety.
* **Easy to use**: Make beautiful CLI with standard behaviors, error messages and an automatic help.
* **Easy to write**: All you need to write is a type. No new DSL to learn, and compilation time type validation.
* **Easy to use**: Make beautiful applications with standard behaviors and automatic error and help messages.
* **You are in control**: No code automatically executed for you, no messages printed to stdout. You do what you want, when you want.

## Requirements
Expand Down
34 changes: 34 additions & 0 deletions docs/release-notes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Release notes

## 0.x

### 0.2.4

* Fix arguments parsing order to respect the idx instruction
* Support `--help` with nested command
* Support for `name: nil` with `#help`
* Fix array arguments in usage line
* Fix #help generated by .add_commands to support `nil` and the command's doc
* Add a `#parse(String)` method

### 0.2.3

* fix the error message when an argument's value is invalid

### 0.2.2

* fix errors' message
* the generated subclass `Help` now inherits from `Clip::Mapper::Help`
* fix a bug when calling a command with subcommands without specifying any command
* fix the help usage for commands (note that the subclass `Help` is not a singleton anymore)

### 0.2.1

* all errors inherit from `Clip::Error`
* all errors have a correct message
* document the `--help` flag in the help message
* add a command `help` when there is commands

### 0.1.0

first public version
6 changes: 5 additions & 1 deletion docs/user guide/non_cli_app.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ module Mycommand
print "> "
if input = gets
begin
command = Command.parse(Process.parse_arguments(input))
command = Command.parse(input)
rescue ex : Clip::Error
puts ex
next
Expand Down Expand Up @@ -153,6 +153,10 @@ end
Mycommand.run
```

!!! Tip
We could parse the `input` string using [`Process.parse_arguments`](https://crystal-lang.org/api/1.0.0/Process.html#parse_arguments(line:String):Array(String)-class-method), but the `#parse` method provides a shortcut and accepts a string.
Internally it uses the exact same method from the `Process` class.

Now we have options and arguments support, beautiful help messages, and error handling!

```console
Expand Down
8 changes: 8 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ markdown_extensions:

nav:
- Clip: index.md
- Features: features.md
- User guide:
- Setup: user guide/setup.md
- First steps: user guide/first_steps.md
Expand All @@ -41,3 +42,10 @@ nav:
- Multiple values: user guide/arrays.md
- Errors: user guide/errors.md
- Non CLI applications: user guide/non_cli_app.md
- Alternatives, inspirations and comparisons: alternatives.md
- Get help: help.md
- Contributing: contributing.md
- Release notes: release-notes.md

extra_css:
- css/custom.css

0 comments on commit 039431c

Please sign in to comment.