danny logo

Pub danny License: MIT Powered by Mason

A Command-Line Interface to develop wilde file-based command-line apps.

Danny Wilde:

  1. Protagonist in a great tv series from the 70s.

Quick Start

# 🎯 Activate from https://pub.dev
dart pub global activate danny_cli

# 🚀 Create a project
danny create greet

# 📦 Build the project
danny build

# 🔨 Activate the project locally
danny activate

# Use the new CLI
greet -h

Table of Contents

Overview

Installation

# 🎯 Activate from https://pub.dev
dart pub global activate danny_cli

Usage

A Command-Line Interface to develop wilde command-line apps.

Usage: danny <command>

Global options:
-h, --help       Print this usage information.
-v, --version    Print the current version.
    --verbose    Enable verbose logging.

Available commands:
  activate   Activate a build locally.
  build      Create a build.
  create     Create a wilde project.
  list       List the commands of a project.
  new        Create a new command.

Run "danny help <command>" for more information about a command.

Motivation 🧠

Frequently, during Dart/Flutter project development, specific project-related tooling requirements arise. In good cases this results in the creation of shell scripts placed in a tool directory, in less optimally cases, the task is only retained in developers' minds. This package aims to simplify the process of writing tooling CLI(s) for Dart/Flutter projects using the Dart language.

Prerequisites 📝

Each danny project relies on the args package, so it's essential for developers to possess a fundamental understanding of how it functions.

Project Structure

A basic danny project structure looks like this:

commands/
  <command-1>.dart
  <command-2>.dart
  <branch-command-1>/
    <nested-command-1>.dart
    <nested-command-2>.dart
pubspec.yaml
runner.dart

The pubspec.yaml exposes the executable of the CLI.

Inside the commands directory Commands are defined in a file-based way.

The runner.dart configures the CommandRunner hosting the commands.

CommandRunner

The runner.dart allows developers to configure the CommandRunner of the CLI.

import 'package:args/args.dart';

// Required
typedef Type = void;

// Required
const description = 'The cool CLI.';

// Optional
const usageLineLength = 100;

// Optional
const suggestionDistanceLimit = 4;

// Optional
Future<Type?> run(
  Iterable<String> args,
  Future<Type?> Function(Iterable<String> args) run,
) async {
  // ...
}

// Optional
Future<Type?> runCommand(
  ArgResults topLevelResults,
  Future<Type?> Function(ArgResults topLevelResults) runCommand,
) async {
  // ...
}

The code above shows the contents of a runner.dart. It must expose a Type and a description at the top-level.

Type: The type of the CommandRunner and all Commands.

description: The description of the CLI.

usageLineLength: The usage line length of the CLI. (optional)

suggestionDistanceLimit: The suggestion distance limit of the CLI. (optional)

run: The run-method of the CLI. (Notice how it uses Type defined in runner.dart, and gets the run-method from super class passed to it) (optional)

runCommand: The runCommand-method of the CLI. (Notice how it uses Type defined in runner.dart, and gets the runCommand-method from super class passed to it) (optional)

Command

A <name>.dart (command file) allows developers to implement a Command of the CLI.

import 'dart:async';

import 'package:args/args.dart';

import '../runner.dart';

// Required
const description = 'My cool command.';

// Optional
const category = 'Foo';

// Optional
const invocation = 'cool [args]';

// Optional
const usageFooter = 'oooxxxooo';

// Optional
final argParser = ArgParser()
      ..addFlag(
        'foo',
        help: 'The foo flag.',
      )
      ..addOption(
        'bar',
        help: 'The bar option.',
      );

// Required
FutureOr<Type> run(ArgResults globalResults, ArgResults argResults) {
  final foo = argResults['foo'] as bool? ?? false;
  final bar = argResults['bar'] as String? ?? 'Baz';

  // ...
}

The code above shows the contents of a command file. The description, and run-method must be available at the top-level of the file while, category, invocation, usageFooter and argParser are optional.

description: The description of the command.

run: The run-method of the command. (Notice how it uses Type defined in runner.dart, and gets ArgResults holding the parsed command-line arguments passed to it)

category: The category of the command. (optional)

invocation: The invocation of the command. (optional)

usageFooter: The usageFooter of the command. (optional)

argParser: The argParser of the command. Allows developers to define options and flags of the command. (optional)

Create Project

The create command allows developers to create a new project.

Create a wilde project.

Usage: danny create <project-name>
-h, --help           Print this usage information.
-o, --output-dir     The directory where to generate the new project.
                     (defaults to ".")
    --description    The description passed to the CommandRunner.

Run "danny help" to see global options.

Add Commands

The add command allows developers to add new commands to a project. If the new command includes parameters or flags, it is necessary to provide the arg-parser flag.

Create a new command.

Usage: danny new "foo bar baz"
-h, --help           Print this usage information.
    --arg-parser     Whether the command has a custom ArgParser.
    --description    The description of the command.

Run "danny help" to see global options.

List Commands

The list command shows all available commands of a project.

List the commands of a project.

Usage: danny list
-h, --help    Print this usage information.

Run "danny help" to see global options.

Build Project

The build command produces a runner.danny.dart at the project root containing the ready to use CommandRunner and Commands based on runner.dart and the commands defined inside commands directory.

Create a build.

Usage: danny build
-h, --help    Print this usage information.

Run "danny help" to see global options.

Activate Project Locally

The activate command makes the executable of the project available locally, using dart pub global activate under the hood.

Activate a build locally.

Usage: danny activate
-h, --help    Print this usage information.

Run "danny help" to see global options.

Libraries

danny_cli
Danny Command Line Interface.