Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/tanmaykm/figcligen.jl

Generate Julia code for cli programs using a variant of Fig specifications.
https://github.com/tanmaykm/figcligen.jl

commandline fig julia

Last synced: 13 days ago
JSON representation

Generate Julia code for cli programs using a variant of Fig specifications.

Awesome Lists containing this project

README

        

# FigCLIGen.jl

[![Build Status](https://github.com/tanmaykm/FigCLIGen.jl/workflows/CI/badge.svg)](https://github.com/tanmaykm/FigCLIGen.jl/actions?query=workflow%3ACI+branch%3Amain)
[![codecov.io](http://codecov.io/github/tanmaykm/FigCLIGen.jl/coverage.svg?branch=main)](http://codecov.io/github/tanmaykm/FigCLIGen.jl?branch=main)

Generate Julia code that provide functions to run CLI programs.

The specification to generate this code is similar to what [Fig](https://fig.io/) uses, but in JSON format. So for popular CLIs, a starting point can be the spec found in the [Fig autocomplete repo](https://github.com/withfig/autocomplete). Remember to convert from `js` to `json` format.

## Code generation

```julia
generate(
specfile::AbstractString,
outputfile::AbstractString;
kwargs...
)
```

Generate a Julia module for a CLI based on a specification file.
Refer to [Generated Code Structure](#generated-code-structure) for more details of the code generated.

Arguments:
- `specfile`: path to the specification file
- `outputfile`: path to the output file

Keyword arguments:
- `custom_include`: a string to include at the top of the generated module
- `ignore_base_command`: if `true`, do not generate the base command.
The base command must be made available by the caller,
either by including it in `custom_include` or by
defining it in the module before calling `generate`.

## Generated Code Structure

Code is generated into a module named `CLI`. The module name is fixed, the intent being for it to be wrapped within another module or package.

The primary command line options are generated as methods within the module, with names same as the option name. The optional parameters are keyword arguments. And the methods accept other arguments to be passed to the command.

An example that generates a CLI for `grep` is included:
- `grep` [specs](test/specs/grep.json)
- `grep` [generated code](examples/grep.jl)
- `grep` [example use of generated code](test/greptest.jl)

A more complex spec is that of Open Policy Agent:
- `opa` [specs](test/specs/opa.json)
- `opa` [generated code](examples/opa.jl)

Example:

```julia
function grep(
ctx::CommandLine,
_args...;
help::Union{Nothing,Bool} = false,
extended_regexp::Union{Nothing,Bool} = false,
...,
file::Union{Nothing,AbstractString} = nothing,
)
```

Each method accepts an instance of `CommandLine` as the first argument that holds the execution context. It has the following members:
- `exec`: a no argument function that provides the base command to execute in a julia `do` block.
- `cmdopts`: keyword arguments that should be used to further customize the `Cmd` creation
- `pipelineopts`: keyword arguments that should be used to further customize the `pipeline` creation

`CommandLine` is generated by default, and is termed as the "base command". It can be overridden during code generation by passing the optional `ignore_base_command` and `custom_include` keyword arguments. See ["Code generation"](#code-generation).

## Using the Generated Code

Create a `CommandLine` and invoke methods. Example:

```julia
julia> include("grep.jl");

julia> ctx = CLI.CommandLine();

julia> CLI.grep(ctx, "CLI", "grep.jl"; ignore_case=true, count=true);
4

julia> CLI.grep(ctx, "the", "grep.jl"; ignore_case=true, count=true);
40
```