Giter Club home page Giter Club logo

zio-cli's Introduction

ZIO Logo

Project Stage CI Release Snapshot Issues
Project stage CI Release Artifacts Snapshot Artifacts Average time to resolve an issue
Scaladoc Scaladex Discord Twitter Gitpod
Scaladoc Badge-Scaladex-page Badge-Discord Badge-Twitter Gitpod ready-to-code

Welcome to ZIO

ZIO is a zero-dependency Scala library for asynchronous and concurrent programming.

Powered by highly-scalable, non-blocking fibers that never waste or leak resources, ZIO lets you build scalable, resilient, and reactive applications that meet the needs of your business.

  • High-performance. Build scalable applications with minimal runtime overhead.
  • Type-safe. Use the full power of the Scala compiler to catch bugs at compile time.
  • Concurrent. Easily build concurrent apps without deadlocks, race conditions, or complexity.
  • Asynchronous. Write sequential code that looks the same whether it's asynchronous or synchronous.
  • Resource-safe. Build apps that never leak resources (including threads!), even when they fail.
  • Testable. Inject test services into your app for fast, deterministic, and type-safe testing.
  • Resilient. Build apps that never lose errors, and which respond to failure locally and flexibly.
  • Functional. Rapidly compose solutions to complex problems from simple building blocks.

To learn more about ZIO, see the following references:


Adopters

Following is a partial list of companies happily using ZIO in production to craft concurrent applications.

Want to see your company here? Submit a PR!

Sponsors

Ziverge

Ziverge is a leading contributor to ZIO.

Scalac

Scalac sponsors ZIO Hackathons and contributes work to multiple projects in ZIO ecosystem.

Septimal Mind

Septimal Mind sponsors work on ZIO Tracing and continuous maintenance.

YourKit

YourKit generously provides use of their monitoring and profiling tools to maximize the performance of ZIO applications.



Code of Conduct

See the Code of Conduct


Support

Come chat with us on Badge-Discord.


Legal

Copyright 2017 - 2024 John A. De Goes and the ZIO Contributors. All rights reserved.

zio-cli's People

Contributors

abcpro1 avatar adamgfraser avatar ashprakasan avatar chris-albert avatar damianreeves avatar defrag avatar dependabot[bot] avatar domartynov avatar edvmorango avatar francistoth avatar github-actions[bot] avatar guizmaii avatar jdegoes avatar jgoday avatar jirijakes avatar jorge-vasquez-2301 avatar katlasik avatar khajavi avatar kitlangton avatar kurgansoft avatar landlockedsurfer avatar nathanknox avatar pablf avatar quelgar avatar tobiaspfeifer avatar tusharmath avatar vdeclerk avatar vigoo avatar vladimir-popov avatar wi101 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

zio-cli's Issues

Add Flags constructors (Single) for various data types

  • integer (BigInt)
  • decimal (BigDecimal)
  • path (java.io.file.Path). For this one, we should accept (optionally) some options like: should it exist or not exist (or doesn't matter?)? should it be a file or a directory (or doesn't matter?)?
  • all java.time structures (instant, datetime, etc.)

Support boolean option grouping

Grouping is a feature whereby boolean, single-letter flags may be clustered together.

For example, instead of writing:

wc -l -c -w

You could write:

wc -lcw

Supporting this is tricky, because it requires two things:

  1. All of the clustered options need to be of type boolean.
  2. The clustered option cannot match any other option.

This seems to require "global knowledge" but right now the validation / parsing only has "local" knowledge; that is, every Options may only have access to part of the command-line arguments and may not know about the decisions about other Options and Args.

Support displaying help pages for subcommands

Displaying help should work for subcommands, and such help pages should make it clear that the help they are displaying is not the top-level help, but rather, help for the specific subcommand.

e.g.:

git merge --help

Upgrade to ZIO 2.0

ZIO 2.0 is at Milestone 4, with an RC expected in the next few weeks.
https://github.com/zio/zio/releases/tag/v2.0.0-M4

The API is nearly stable at this point, so any early migration work against this version should pay off towards the official 2.0 release.

The progress is being tracked here:
zio/zio#5470

The Stream Encoding work in progress is the only area where the API might still change before the RC.

We are actively working on a ScalaFix rule that will cover the bulk of the simple API changes:
https://github.com/zio/zio/blob/series/2.x/scalafix/rules/src/main/scala/fix/Zio2Upgrade.scala
We highly recommend starting with that, and then working through any remaining compilation errors :)

To assist with the rest of the migration, we have created this guide:
https://zio.dev/howto/migrate/zio-2.x-migration-guide/

@kitlangton Has already done a substantial amount of the work required.

Smoothly integrate built-in commands into user's own `Command` structure

The user of ZIO CLI must define a CLIApp, which is the command-line application itself. One of the fields is Command, which represents the top-level command of the CLI application.

Currently, this command is kept separate from the "built-in" options that CLIApp supports, including --help, and in the future, --version. This means that when a user prints out help documentation, the --help option is not included in the help documentation.

In order to avoid this problem, we need to push the help option and other options into the user's own command structure. Probably, this can be done by adding a new method to Command, such as:

sealed trait Command[A] {
  ...
  def addOption[B](opt: Options[B]): Command[Either[B, A]]
  ...
}

Then with this new method, the --help option that CLIApp provides "for free" can be cleanly integrated into the existing user's Command, so that when --help is run, that option appears with other documented help options.

Add a tiny figlet font parser

Once a parser is written, this can be used to render the name of the CLI application in a nice way, e.g.:

 ______ _____  _____      _______        _____
  ____/   |   |     | ___ |       |        |  
 /_____ __|__ |_____|     |_____  |_____ __|__                                              

Example here and some discussion on format here.

Implement `HelpDoc.toHTML`

Currently, HelpDoc.toPlaintext is implemented. However, some details are not preserved well in plaintext format, but can be captured more precisely using HTML. Therefore, we should implement a renderer to HTML on HelpDoc, which tries to create a beautiful and useful representation of the help documentation for a CLI application.

Document and verify / add tests for all `PrimType` classes

The PrimType values are the primitive types in ZIO CLI, and represent things like strings or numbers or paths. They have, principally, a validate method which attempts to validate the value of a primitive type.

Tests and Scala doc should be added for all PrimType classes.

Add a figlet font renderer

This can be used to render the name of the CLI application in a nice way, e.g.:

 ______ _____  _____      _______        _____
  ____/   |   |     | ___ |       |        |  
 /_____ __|__ |_____|     |_____  |_____ __|__                                              

Example here and some discussion on format here.

This will be used in conjunction with #1.

Implement Magnolia derivation for user-defined ADTs

A user-defined ADT, consisting of sealed traits, case classes, and strings/collections, could, in theory, be used to derive a Command that produces a data structure of that type.

For example:

case class WordCount(c: Boolean, l: Boolean, w: Boolean)

val wordCount: Command[WordCount] = DeriveCommand.genCommand

This can be done using Magnolia, and following a pattern similar to ZIO JSON.

We should also add annotations to provide custom details which cannot be inferred from the structure of the ADT alone.

Add ZIO Test integration

Using custom assertions and / or other combinators, it should be easy to test ZIO CLI applications, feeding them test "standard input" and validating standard error / standard output, as well as process exit codes.

Create all-in-one "installer" for a ZIO CLI application

The installer or package should do the following:

  • Download the GraalVM native image or Docker image
  • Add the CLI application to the path
  • Add completions for bash and zshell

Inspiration could be taken from Fury which seems to do a nice job with this.

Create Spec for `HelpDoc.scala`

Introduce a test spec for HelpDoc.scala. Look to test tricky combination and things like:

what happens when you have a header, then you have an enumeration (bulletpoint list), and inside the bulletpoint list, you have another bulletpoint list. Does toPlaintext do the right thing?

How to import zio-cli in a project

I am using ZIO in my current project and I would like to include CLI functionality. Unfortunately, this github repo has a broken documentation link and the README.md file has no info on how to import this library into a project.

Please provide information how to import this into my project, it would be greatly appreciated. Note: I am using gradle.

Refactor List[HelpDoc] to HelpDoc

There are places in the code that use List[HelpDoc]. However, two help docs can be combined into one using +. So this is not necessary. In fact, we can change all code that currently uses the type List[HelpDoc] into an ordinary HelpDoc.

Create simple examples of ZIO CLI

This ticket is to create a new module in the repository, called examples. This module will define CLIApp (command-line applications) for a variety of simple existing or fictional command-line applications.

Examples could include:

  • wc
  • cat
  • tail

These examples should demonstrate a range of features of ZIO CLI, including booleans, options, flags, arguments, custom documentation, and more.

Flatten Units in `++`, `.subcommands`, and `Command.apply` methods

This will be similar to ZIO's Zippable, which helps deal with awkward nesting of tuples when zipping polymorphic effects. In our case, don't want to be forced to .map(_._2), when the left or right hand side of a composed Command/Options/Args is a Unit. These Units are usually the cruft of combining Options or Args values that do not generate a value. For example:

Command("something", Options.none, Args.int) will generate a Command[(Unit, Int)]. Though, with this new capability, it should return Command[Int].

I'd recommend taking a look at the implementation of Zippable as well as the Zymposium on Path Dependent Types.

Add automatic --wizard command that generates menus and prompts

The structure of Command permits an interactive mode that generates menus and prompts, e.g.:

Please enter the command you would like to execute:

1. commit — Commits the changes
2. version — Prints out the version
...


Please enter the boolean flags you would like to use:

[ ] (f) Force — Forces the deletion
[ ] (r) Remove — Removes the files

Please enter any combination of r, f: 

This ticket is to prototype such a wizard mode, which will walk the user through providing arguments and options using interactive menu prompts.

Improve Command.apply to not require Options.none/Args.none

If we can make Options.none and Args.none extend Option[Nothing]/Args[Nothing], then we'll be able to provide default values for these in the Command.apply method. Currently, you need to write Args.none or Options.none, which isn't as nice as it could be.

Add ZIO Config integration

There are two potential points of integration:

  • It should be possible to generate a ZIO Config descriptor from a CLI specification. This would allow code that uses ZIO Config to plug a nice CLI on top.
  • It should be possible to load ZIO Config data as a set of "defaults", that can be overwritten using CLI information. For example, like .gitconfig and .jvmopts and many other command-line utilities that support reading common options from a standardized location.

/cc @afsalthaj

Refactor PrimType#validate to accept ParserOptions

Currently, ParserOptions are not threaded down into PrimType#validate, which means the primitive types cannot take advantage of any parser-specific settings. This could be useful, especially in the future. So we should refactor the validate method to take the parser options.

Display subcommands in HelpDoc synopsis

When using subcommands, the generated synopsis for non-leaf subcommands does not include the partial subcommand "path."

For example, given a sub command structure

foo
└── a
    └── one
        ├── blue
        └── red

such that foo a one blue is a leaf command, the Synopsis section in --help documentation doesn't include relevant subcommand names.

Example:
Any level of non-leaf subcommand foo a --help, foo a one --help, produces

SYNOPSIS

    foo   <command> [<args>]

The expected output for foo a --help would be

SYNOPSIS

    foo a <command> [<args>]

and for foo a one --help

SYNOPSIS

    foo a one <command> [<args>]

and for foo a one blue --help

SYNOPSIS

    foo a one blue [<args>]

Note that the expected synopsis for a leaf command does not include the string <command> (whereas it is included in the current code), but that can be considered a separate issue.

Bonus nitpick

There's an extra space in here :)

SYNOPSIS

    foo   <command> [<args>]
       ^^^

Implement document generator for CLI

There is a type HelpDoc in the code now, and various methods that generate help doc, implemented with ??? for now.

All these methods need to be implemented.

Support default commands for CLI applications

Several commands can be supported by default, including:

  • --help which displays help on standard output. This variation should work with commands and subcommands, and display specific / tailored help if appropriate.
  • --version which displays version information on standard output

It should be possible for users to "opt out" of these default commands or override them in some fashion.

Spec is failing in master

Overview

There is a failing spec in master:

[info] - PrimTypeTests
[info]   - Boolean Suite
[info]     - validate false combinations returns proper Boolean representation

Changes Requested

Fix the failing spec

Auto-generation bash script to perform completions for a given CLI

Bash is a common shell for Linux / BSD operating systems. Bash has a feature whereby you can have the shell auto-complete options for a command-line argument, which can simplify usage of command-line applications.

See here for a tutorial and here for more extensive documentation.

Given a CLI, we should be able to nicely generate a bash script that when sourced, will add all appropriate completions using the complete process.

See CLIApp#completions.

Variadic Args.file with exists=true fails with wrong error message if file does not exist

(Args.file("files", true) *).validate("doesNotExist.file" :: Nil, ParserOptions.default)

fails with

List(Paragraph(Error(Text(Unexpected arguments for command wc: List(doesNotExist.file)))))

expected

List(Paragraph(Error(Text(doesNotExist.file is not a recognized path.))))

Can be reproduced by running the WcApp Example with unrecognized file.

My investigation so far:

validate in Variadic turns a validation failure into a success without consuming the argument. The unconsumed argument leads to "Unexpected arguments..."

Implement error-correction using Levenshtein distance

If a command or flag is not recognized verbatim, then using Levenstein distance calculation, the closest command(s) / flag(s) can be identified, and the suggestion made to the user.

e.g.:

> myapp load -forc -source foo.txt

- The flag "-forc" is not recognized. Did you mean "-force"?

In order to implement this feature, a simple Levenstein distance function can be implemented. Atop this, a separate method can be added to Command, perhaps, autoCorrections, which returns a List[HelpDoc] containing any possible auto-corrections.

Then, inside CLIApp, if it is not possible to parse the command-line arguments, then auto-corrections can be generated.

Solidify Argument support

Args should support:

  • optional, required, and variadic
  • providing a name for an argument (this will be important when generating help and docs)
  • providing a description

Display subcommand short desc in synopsis

When using nested subcommands, subcommand description text is not displayed next to each subcommand in the synopsis SUBCOMMANDS section. This would be helpful for usage understanding, and a cursory reading of the source for zio-cli seems to suggest that it was originally intended behavior.

Given a subcommand hierarchy like this

foo
└── a
    └── one
        ├── blue
        └── red

the command foo a one --help produces

SYNOPSIS

    foo   <command> [<args>]

SUBCOMMANDS

      - red

      - blue

The expected output would have some brief summary of subcommands red and blue to the right of their enumeration.

Support negation name for Options

For boolean options, we should support an optional negation name, such that, for example:

-v

turns the option ON, where as:

-V

turns the option OFF.

Support property arguments

Property arguments are options (which may be repeated) whose values are actually key/value pairs.

Example syntax:

-Dkey=value
-D key1=value key2=value

To support these, we probably need a new Options.Map which parses options of the specified name (-D in these examples) into a map, where the key and value types could be PrimType.

Introduce --help support for all subcommands (recursively)

Currently, --help is only available for the top-level command. This is inconvenient, because we have full documentation for all subcommands. Yet, at the same time, we cannot display all documentation on a single page. We should wait until the user requests help for a subcommand to print the help.

Thus, our subcommand help can work a bit like git:

git fetch --help

Now, in order to make this work, we need to take care of a few details:

  1. First, the way subcommand help is printed out will be somewhat different from the way the top-level command is printed out. We should look to git and other complicated CLI tools for inspiration.
  2. Second, we need to ensure we can print out help even if a parent command does not have all of its required options and arguments. If we were to do a simple process of augmenting the child commands with --help, then we would only succeed in parsing them if the parents succeeded too. But for help, we really want to ignore required arguments/options for parents, and give the user help anyway. We need to make sure this is possible.
  3. Third, we need to ensure the way it is rendered looks good for commands with subcommands, both the top-level help, as well as the subcommand help, and that it scales for subcommands of subcommands of subcommands (etc.).

Display possible subcommands for non-leaf nested subcommands

When using nested subcommands, the generated help doc does not list subcommands for any non-leaf subcommand whose distance from a leaf is > 1.

For example, given a sub command structure

foo
└── a
    └── one
        ├── blue
        └── red

The this command correctly enumerates subcommands in the SUBCOMMANDS section in the help doc

foo a one --help

But these commands do not

foo --help
foo a --help

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.