unscripted 0.6.2

  • README.md
  • Installing
  • Versions
  • 1

unscripted pub package Build Status Coverage Status

Define command-line interfaces using ordinary dart methods and classes.


pub global activate den
den install unscripted


The following greet.dart script outputs a configurable greeting:

#!/usr/bin/env dart

import 'package:unscripted/unscripted.dart';

main(arguments) => new Script(greet).execute(arguments);

// All metadata annotations are optional.
@Command(help: 'Print a configurable greeting', plugins: const [const Completion()])
@ArgExample('--salutation Hi --enthusiasm 3 Bob', help: 'enthusiastic')
    @Rest(help: 'Name(s) to greet.')
    List<String> who, {
      @Option(help: 'How many !\'s to append.')
      int enthusiasm : 0,
      @Flag(abbr: 'l', help: 'Put names on separate lines.')
      bool lineMode : false,
      @Option(name: 'greeting', help: 'Alternate word to greet with e.g. "Hi".')
      String salutation : 'Hello'
    }) {

  print(salutation +
        who.map((w) => (lineMode ? '\n  ' : ' ') + w).join(',') +
        '!' * enthusiasm);

We can call this script as follows:

$ greet.dart Bob
Hello Bob
$ greet.dart --enthusiasm 3 -l --greeting Hi Alice Bob

##Automatic --help

A --help/-h flag is automatically defined:

$ greet.dart --help


  Print a configurable greeting.


  greet.dart [options] [<who>...]

    <who>    Name(s) to greet.


      --completion         Tab completion for this command.

            [install]      Install completion script to .bashrc/.zshrc.
            [print]        Print completion script to stdout.
            [uninstall]    Uninstall completion script from .bashrc/.zshrc.

  -h, --help               Print this usage information.


      --enthusiasm         How many !'s to append.
                           (defaults to "0")

  -l, --line-mode          Put names on separate lines.
      --greeting           Alternate word to greet with e.g. "Hi".
                           (defaults to "Hello")


  greet.dart --greeting Hi --enthusiasm 3 Bob # enthusiastic


Sub-commands are represented as SubCommand-annotated instance methods of classes, as seen in the following server.dart:

#!/usr/bin/env dart

import 'dart:io';

import 'package:unscripted/unscripted.dart';
import 'package:path/path.dart' as path;

main(arguments) => new Script(Server).execute(arguments);

class Server {

  final String configPath;

      help: 'Manages a server',
      plugins: const [const Completion()])
  Server({this.configPath: 'config.xml'});

  @SubCommand(help: 'Start the server')
  start({bool clean: false}) {
Starting the server.
Config path: $configPath''');

  @SubCommand(help: 'Stop the server')
  stop() {
    print('Stopping the server.');


We can call this script as follows:

$ server.dart start --config-path my-config.xml --clean
Starting the server.
Config path: my-config.xml

Help is also available for sub-commands:

$ server.dart help

Available commands:


Use "server.dart help [command]" for more information about a command.

$ server.dart help stop


  Stop the server


  server.dart stop [options]


  -h, --help    Print this usage information.


Any value-taking argument (option, positional, rest) can have a "parser" responsible for validating and transforming the string passed on the command line. You can give an argument a parser simply by giving it a type (such as int or DateTime) which has a static parse method, or by specifying the parser named argument of the argument's metadata (Option, Positional, or Rest).


Plugins allow you to mixin reusable chunks of cli-specific functionality (options/flags/commands) on top of your base interface.

To add a plugin to your script, just add an instance of the associated plugin class to the plugins named argument of your @Command annotation. The following plugins are available:

###Tab Completion

Add bash/zsh tab completion to your script:

@Command(/*...*/ plugins: const [const Completion()])

If your script already has sub-commands, this will add a completion sub-command (similar to npm completion), otherwise it adds a --completion option. These can then be used as follows:

# Try the tab-completion without permanently installing.
. <(greet.dart --completion print)
. <(server.dart completion print)

# Install the completion script to .bashrc/.zshrc depending on current shell.
# No-op if already installed.
greet.dart --completion install
server.dart completion install

# Uninstall a previously installed completion script.
# No-op if not installed.
greet.dart --completion uninstall
server.dart completion uninstall

Once installed, the user will be able to tab-complete all aspects of your cli, for example:

Option/Flag names: Say your script is a dart method with a longOptionName named parameter. This becomes --long-option-name in your cli, and once completion is installed, the user can type --l[TAB] and it will be completed to --long-option-name. It will also expand short options to their long equivalents, e.g. -vh[TAB] becomes --verbose --help.

Commands: If your script is a dart class having a @SubCommand() longCommandName method, that becomes a long-command-name sub-command in your cli, and the user can type l[TAB] and it will be completed to long-command-name.

Option/Positional/Rest values: The allowed named parameter of Option, Positional, and Rest specifies the allowed values, and thus completions, for those parameters. For example if you have @Option(allowed: const ['red', 'yellow', 'green']) textColor, and the user types --text-color g[TAB] this will become --text-color green. allowed can also be a callback of one of the following forms:

Iterable<String> complete(String text);
Iterable<String> complete();
Future<Iterable<String>> complete(String text);
Future<Iterable<String>> complete();

where if an arg (e.g. text here) is specified, it represents the last partial word typed by the user when completion is requested, which can be used to filter the results to match that prefix. If the arg is omitted, the filtering is done automatically for you. For example if the option/positional/rest represents a file name, you could emulate the builtin shell file name completion by returning a list of filenames in the current directory.

Tab completion is supported in cygwin, with one minor bug (#64).

###Other Plugins

There are several other plugins planned, and also the ability to write your own is planned, see #62.


den uses a large subset of the features above. Run pub global activate den to install, and then den -h to get a feel for the UX provided by unscripted.


  • Add name parameter to Option and Flag ( #102 )
  • Add option groups ( #40 )


  • Allow dynamic help content


  • Deprecated declare in favor of new Script.

Breaking changes:

  • Script.execute now calls the method asynchronously so that it can return a Future for the return value.


Breaking changes:

  • Flags without a null default value now default to null instead of false when neither the flag nor it's negation occur on the command-line (#86)



  • Improve color-support detection (#73)



  • Reference scripts as foo instead of foo.dart (expect foo.bat in cygwin) (#80)
  • Add allowTrailingOptions to Command and SubCommand (#70)



  • Fixed omission of {Rest,Positional}.allowed (#79)



  • Colorful help output (#68)
  • Add help output for positional arguments (#42)
  • Add metaVar configuration (#43)
  • Only fail completion in windows on actual usage not definition (#75)
  • Support hidden commands (#69)
  • Allow omitting arg to allowed callback (#67)
  • Allow latest args version (#74)


  • Fix some checked mode errors
  • Fix running scripts via pub run



  • Tab Completion! (#7)
  • Initial plugin support (see #62)
  • Improved examples to demo parsers and other metadata

Breaking changes:

  • Removed CallStyle



  • dart:mirror closurization operator removed (#50)



  • Demo: complete *nix cat implementation (#28)
  • Derive parsers from type annotations (#31)
  • Derive rest parameter from List type annotation (#36)
  • Derive allowMultiple from List type annotation (#34)
  • Add ellipsis to rest parameter help formatting (#22)
  • Include script name in error messages (#32)
  • Input and output parsers which transparently handle both file paths and '-' for stdin/stdout (#23)

Breaking changes:

  • Renamed sketch to declare (#37)
  • Rest.min changed to Rest.required (#26)
  • Flag.negatable now defaults to false (#25)



  • Support argument parsers (#5)
  • Support hierarchical sub-commands (#15)

Breaking changes:

  • @Command metadata must now be placed on the unnamed constructor instead of the class.
  • allowedHelp in Option is now merged into allowed.

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:

  unscripted: ^0.6.2

2. Install it

You can install packages from the command line:

with pub:

$ pub get

Alternatively, your editor might support pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:

import 'package:unscripted/unscripted.dart';
Version Uploaded Documentation Archive
0.6.2 Jun 17, 2015 Go to the documentation of unscripted 0.6.2 Download unscripted 0.6.2 archive
0.6.1+1 Apr 29, 2015 Go to the documentation of unscripted 0.6.1+1 Download unscripted 0.6.1+1 archive
0.6.1 Apr 24, 2015 Go to the documentation of unscripted 0.6.1 Download unscripted 0.6.1 archive
0.6.0 Mar 20, 2015 Go to the documentation of unscripted 0.6.0 Download unscripted 0.6.0 archive
0.5.2+1 Dec 22, 2014 Go to the documentation of unscripted 0.5.2+1 Download unscripted 0.5.2+1 archive
0.5.2 Dec 22, 2014 Go to the documentation of unscripted 0.5.2 Download unscripted 0.5.2 archive
0.5.1 Dec 10, 2014 Go to the documentation of unscripted 0.5.1 Download unscripted 0.5.1 archive
0.5.0 Dec 10, 2014 Go to the documentation of unscripted 0.5.0 Download unscripted 0.5.0 archive
0.4.7 Oct 21, 2014 Go to the documentation of unscripted 0.4.7 Download unscripted 0.4.7 archive
0.4.6 Oct 17, 2014 Go to the documentation of unscripted 0.4.6 Download unscripted 0.4.6 archive

All 29 versions...

Describes how popular the package is relative to other packages. [more]
Code health derived from static analysis. [more]
Reflects how tidy and up-to-date the package is. [more]
Weighted score of the above. [more]
Learn more about scoring.

The package version is not analyzed, because it does not support Dart 2. Until this is resolved, the package will receive a health and maintenance score of 0.

Analysis issues and suggestions

Fix dependencies in pubspec.yaml.

Running pub upgrade failed with the following output:

ERR: The current Dart SDK version is 2.1.0.
 Because unscripted depends on mockable_filesystem >=0.0.3 which requires SDK version <2.0.0, version solving failed.

Health suggestions

Format lib/src/annotations.dart.

Run dartfmt to format lib/src/annotations.dart.

Format lib/src/call_style.dart.

Run dartfmt to format lib/src/call_style.dart.

Format lib/src/group_annotations.dart.

Run dartfmt to format lib/src/group_annotations.dart.

Fix additional 20 files with analysis or formatting issues.

Additional issues in the following files:

  • lib/src/invocation_maker.dart (Run dartfmt to format lib/src/invocation_maker.dart.)
  • lib/src/io.dart (Run dartfmt to format lib/src/io.dart.)
  • lib/src/plugin.dart (Run dartfmt to format lib/src/plugin.dart.)
  • lib/src/plugins/completion/command_line.dart (Run dartfmt to format lib/src/plugins/completion/command_line.dart.)
  • lib/src/plugins/completion/completion.dart (Run dartfmt to format lib/src/plugins/completion/completion.dart.)
  • lib/src/plugins/completion/completion_script.dart (Run dartfmt to format lib/src/plugins/completion/completion_script.dart.)
  • lib/src/plugins/completion/marker.dart (Run dartfmt to format lib/src/plugins/completion/marker.dart.)
  • lib/src/plugins/completion/usage_completion.dart (Run dartfmt to format lib/src/plugins/completion/usage_completion.dart.)
  • lib/src/plugins/completion/util.dart (Run dartfmt to format lib/src/plugins/completion/util.dart.)
  • lib/src/plugins/help/help.dart (Run dartfmt to format lib/src/plugins/help/help.dart.)
  • lib/src/plugins/help/option_help.dart (Run dartfmt to format lib/src/plugins/help/option_help.dart.)
  • lib/src/plugins/help/pens.dart (Run dartfmt to format lib/src/plugins/help/pens.dart.)
  • lib/src/plugins/help/usage_formatter.dart (Run dartfmt to format lib/src/plugins/help/usage_formatter.dart.)
  • lib/src/plugins/help/util.dart (Run dartfmt to format lib/src/plugins/help/util.dart.)
  • lib/src/script.dart (Run dartfmt to format lib/src/script.dart.)
  • lib/src/script_impl.dart (Run dartfmt to format lib/src/script_impl.dart.)
  • lib/src/string_codecs.dart (Run dartfmt to format lib/src/string_codecs.dart.)
  • lib/src/usage.dart (Run dartfmt to format lib/src/usage.dart.)
  • lib/src/util.dart (Run dartfmt to format lib/src/util.dart.)
  • lib/unscripted.dart (Run dartfmt to format lib/unscripted.dart.)

Maintenance issues and suggestions

Add SDK constraint in pubspec.yaml. (-50 points)

For information about setting SDK constraint, please see https://www.dartlang.org/tools/pub/pubspec#sdk-constraints.

Fix platform conflicts. (-20 points)

Error(s) prevent platform classification:

Fix dependencies in pubspec.yaml.

Running dartdoc failed. (-10 points)

Make sure dartdoc runs without any issues.

Package is too old. (-100 points)

The package was released more than two years ago.

The description is too short. (-20 points)

Add more detail about the package, what it does and what is its target use case. Try to write at least 60 characters.

Maintain an example.

None of the files in your example/ directory matches a known example patterns. Common file name patterns include: main.dart, example.dart or you could also use unscripted.dart. Packages with multiple examples should use example/readme.md.