Skip to content

Commit

Permalink
Start setting up multiple versions of docs for v2
Browse files Browse the repository at this point in the history
  • Loading branch information
Whiteknight committed Sep 29, 2022
1 parent f5f8901 commit 01b7a98
Show file tree
Hide file tree
Showing 23 changed files with 848 additions and 35 deletions.
37 changes: 2 additions & 35 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,4 @@
# StoneFruit

**StoneFruit** is a commandlet host and execution engine. It allows you to rapidly develop new command-line utility routines without having to create a new application for each one. StoneFruit is designed from the ground-up to be configurable, pluggable and flexible, and to easily integrate with your existing code. It deeply integrates with your DI container, if you have one, to make all your application services available at every point of the execution pipeline.

## Quick Example: Git

Git is a powerful development tool but typing "`git`" by itself at the prompt doesn't do much. To access the varied functionality of git, you must specify a **verb** like "`git clone`", "`git add`" or "`git remote add`". Each different verb causes the application to do different tasks, often with completely separate sets of input arguments and program output. StoneFruit is like this: It allows you to create a program with many verbs, each of which can do something different and useful.

## Basic Terminology

A **Verb** is the name of an action which the user types at the commandline, which may have arguments and output effects. Verbs in StoneFruit are case-insensitive and may be one or several words.

A **Handler** is a class which is invoked by StoneFruit when a verb is input. A single Handler class may correspond to one or more verbs.

A **Command** is a combination of a Verb and all input arguments.

**Headless** is a mode where the StoneFruit application executes one or more commands without user input.

**Interactive** is a mode where the StoneFruit application displays an interactive prompt where commands can be input one after the other.

## Quick Start

To get started, we need to create an `EngineBuilder`, configure it, and build an `Engine`. This is done in slightly different ways depending on whether you're using a DI container or not, and which one.

* [Lamar Quick Start](start_lamar.md)
* [StructureMap Quick Start](start_structuremap.md)
* [Microsoft DI Quick Start](start_microsoft.md)
* [No DI Quick Start](start_basic.md)

## Pages

* [Handlers](handlers.md)
* [Arguments](arguments.md)
* [DI Containers](containers.md)
* [Execution](execution.md)
* [Scripting](scripting.md)
* [Simple Example](example1.md)
* [V1.0.0](v1/index.md)
* [V2.0.0](v2/index.md)
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
37 changes: 37 additions & 0 deletions docs/v1/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# StoneFruit

**StoneFruit** is a commandlet host and execution engine. It allows you to rapidly develop new command-line utility routines without having to create a new application for each one. StoneFruit is designed from the ground-up to be configurable, pluggable and flexible, and to easily integrate with your existing code. It deeply integrates with your DI container, if you have one, to make all your application services available at every point of the execution pipeline.

## Quick Example: Git

Git is a powerful development tool but typing "`git`" by itself at the prompt doesn't do much. To access the varied functionality of git, you must specify a **verb** like "`git clone`", "`git add`" or "`git remote add`". Each different verb causes the application to do different tasks, often with completely separate sets of input arguments and program output. StoneFruit is like this: It allows you to create a program with many verbs, each of which can do something different and useful.

## Basic Terminology

A **Verb** is the name of an action which the user types at the commandline, which may have arguments and output effects. Verbs in StoneFruit are case-insensitive words.

A **Handler** is a class which is invoked by StoneFruit when a verb is input. A single Handler class may correspond to one or more verbs.

A **Command** is a combination of a Verb and all input arguments.

**Headless** is a mode where the StoneFruit application executes one or more commands without user input.

**Interactive** is a mode where the StoneFruit application displays an interactive prompt where commands can be input one after the other.

## Quick Start

To get started, we need to create an `EngineBuilder`, configure it, and build an `Engine`. This is done in slightly different ways depending on whether you're using a DI container or not, and which one.

* [Lamar Quick Start](start_lamar.md)
* [StructureMap Quick Start](start_structuremap.md)
* [Microsoft DI Quick Start](start_microsoft.md)
* [No DI Quick Start](start_basic.md)

## Pages

* [Handlers](handlers.md)
* [Arguments](arguments.md)
* [DI Containers](containers.md)
* [Execution](execution.md)
* [Scripting](scripting.md)
* [Simple Example](example1.md)
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
94 changes: 94 additions & 0 deletions docs/v2/arguments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Arguments and Syntax

A **Command** is a combination of a **verb** and zero or more **arguments**. There are three types of arguments:

1. **Positional** arguments are unnamed values in the argument list and are accessed by index. There can be many positional arguments, each one with a unique index (starting from 0). Positional arguments at the beginning of the argument list (before any flag or named arguments) may be used as a verb to dispatch control flow to a handler. Arguments which are used as Verbs are removed from the list of arguments.
1. **Flag** arguments are defined by their name and can appear in any order. A flag does not have a value, but is instead defined by whether or not it exists. Only one flag of a given name can be passed for a single command. Passing the same flag more than once will be ignored.
1. **Named** arguments have a name and a value and can appear in any order. You can have multiple named arguments with the same name. Ordering of named arguments will not be preserved.

The `echo` built-in takes arguments of all three types:

```
echo -nonewline color=Red 'ERROR MESSAGE'
```

`-nonewline` is a flag which tells the echo handler not to write a newline at the end, which can be useful in some scripting scenarios. The `color=Red` is a named argument called "color" with a value of "Red". Finally, the string `ERROR MESSAGE` is a positional argument which does not have a name.

## Argument Syntax

StoneFruit supports multiple different argument formats, which can be set in the `IEngineBuilder`. The default syntax is the "Simplified" version. In all syntaxes, positional arguments are the same: Either a bare word with no whitespace or a quoted value (single- or double-quoted, with backslash escapes).

### Simplified

Simplified syntax is the default, is the simplest, and has no parsing ambiguities:

* `-flag` is the flag "flag"
* `name=value` is the named argument with name "name" and value "value"
* `value` is the positional argument with the value "value"

Simplified argument grammar is the default, but you can specify it explicitly in your EngineBuilder:

```csharp
services.SetupEngine(b => b
.SetupArguments(a => a.UseSimplifiedArgumentParser())
);
```

### Posix Style

"POSIX"-style is a little bit different from program to program, and has become quite complex. StoneFruit attempts to cover most of the common patterns from modern apps, though there are some ambiguities in the syntax:

* `-a` is the Flag "a"
* `-abc` are the three flags "a", "b", "c".
* `--abc` is the flag "abc".
* `--name=value` is a named argument "name" with value "value".
* `--name value` is an ambiguous case which might be the flag "name" followed by the positional "value", or it might be a named argument "name=value"
* `-a value` is also an ambiguous case, which might be the flag "a" followed by the positional "value", or it might be a named argument "a=value"

Ambiguities are resolved at handler execution time, if the handler asks for the named argument it will be treated like a named argument, otherwise if you ask for the flag or the positional, it will be treated as the combination of flag and positional.

```csharp
services.SetupEngine(b => b
.SetupArguments(a => a.UsePosixStyleArgumentParser())
);
```

### Powershell Style

Powershell style also contains some ambiguities but it is simpler than POSIX-style:

* `-name` is the flag "name"
* `-name value` is ambiguous. It is either the flag "name" followed by the positional "value" or it's the named "name=value"

Again, ambiguities are resolved at runtime depending on how you access the arguments.

```csharp
services.SetupEngine(b => b
.SetupArguments(a => a.UsePowershellStyleArgumentParser())
);
```

### Windows CMD Style

* `/flag` is a flag
* `/named:value` is a named argument

```csharp
engineBuilder
.SetupArguments(a => a.UseWindowsCmdArgumentParser())
;
```

### Custom Parsers

You can implement your own `IParser<char, IParsedArgument>` grammar for your own syntax if you want. See the documentation for [ParserObjects](https://github.com/Whiteknight/ParserObjects) for more details about how to create your own parser.

```csharp
engineBuilder
.SetupArguments(a => a.UseArgumentParser(myParser))
;
```

## Retrieving Argument Values

TBD
19 changes: 19 additions & 0 deletions docs/v2/containers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Dependency-Injection Containers

StoneFruit is developed with DI containers in mind. If you have a DI container you prefer to use, you can scan for instances of `IHandler` and `IAsyncHandler`. Or, you can use one of the existing bindings for popular containers. For DI containers, the Stonefruit engine is configured as a series of registrations in your container, and then the engine instance is created by your container.

## StructureMap

See the [StructureMap Quick Start](start_structuremap.md) for information on configuring StructureMap to run StoneFruit.

## Lamar

See the [Lamar Quick Start](start_lamar.md) for information on configuring Lamar to run StoneFruit.

## Microsoft DependencyInjection

See the [Microsoft DI Quick Start](start_microsoft.md) for information on configuring the microsoft DI container to run StoneFruit.

## Other Containers and Custom Implementations

Bindings for other popular containers are in development and will be offered as separate nuget packages when they are available. If your container implements the `Microsoft.Extensions.DependencyInjection.Abstractions` contracts, you might be able to integrate it easily using some of the existing code.
Loading

0 comments on commit 01b7a98

Please sign in to comment.