Skip to content

Commit

Permalink
extract more examples from the readme
Browse files Browse the repository at this point in the history
  • Loading branch information
svenfuchs committed Aug 10, 2019
1 parent 24212f9 commit fbeedf1
Show file tree
Hide file tree
Showing 18 changed files with 535 additions and 228 deletions.
196 changes: 127 additions & 69 deletions README.md
Expand Up @@ -12,7 +12,7 @@ after `gem --help`).

Further documentation is available on [rubydoc.info](https://www.rubydoc.info/github/svenfuchs/cl)

Most examples in this README are included from [examples/readme](https://github.com/svenfuchs/cl/tree/master/examples/readme).
Examples in this README are included from [examples/readme](https://github.com/svenfuchs/cl/tree/master/examples/readme).
More examples can be found in [examples](https://github.com/svenfuchs/cl/tree/master/examples).
All examples are guaranteed to be up to date by the way of being [verified](https://github.com/svenfuchs/cl/blob/master/.travis.yml#L14)
on CI.
Expand Down Expand Up @@ -51,7 +51,6 @@ on CI.
## Basic Usage

```ruby
# lib/cli/owners/add.rb
module Owners
class Add < Cl::Cmd
summary 'Add one or more owners to an existing owner group'
Expand All @@ -63,48 +62,58 @@ module Owners
[...]
str

args :owners
args :owner

opt '-t', '--to TO', 'An existing owner group'

def run
# add owners as listed in `owners` to the group given in
# `to`, as well as `opts[:to]`.
# implement adding the owner as given in `owner` (as well as `args`)
# to the group given in `to` (as well as `opts[:to]`).
p owner: owner, to: to, to?: to?, args: args, opts: opts
end
end
end

# bin/owners
Cl.new('owners').run(ARGV)
```

Running this, e.g. using `bin/owners add one,two --to group` will instantiate the
class `Owners::Add`, and call the method `run` on it.

Help output:

```txt
Usage: owners add [owners] [options]
Summary:
Add one or more owners to an existing owner group
# Running this, e.g. using `bin/owners add one,two --to group` will instantiate the
# class `Owners::Add`, and call the method `run` on it.

Description:
Use this command to add one or more owners to an existing
owner group.
# e.g. bin/owners
#
# args normally would be ARGV
args = %w(add one --to group)

These will be visible in [...]
Cl.new('owners').run(args)

Arguments:
# Output:
#
# {:owner=>"one", :to=>"group", :to?=>true, :args=>["one"], :opts=>{:to=>"group"}}

owners type: string
Cl.new('owners').run(%w(add --help))

Options:
# Output:
#
# Usage: owners add [owner] [options]
#
# Summary:
#
# Add one or more owners to an existing owner group
#
# Description:
#
# Use this command to add one or more owners to an existing
# owner group.
#
# [...]
#
# Arguments:
#
# owner type: string
#
# Options:
#
# -t --to TO An existing owner group (type: string)
# --help Get help on this command

-t --to TO An existing owner group (type: string, required: true)
--help Get help on this command (type: flag)
```

### Command Registry
Expand All @@ -125,8 +134,9 @@ module Cmd
end
end

Cl::Cmd[:one] # => Cmd::One
Cl::Cmd[:two] # => Cmd::Two
p Cl::Cmd[:one] # => Cmd::One
p Cl::Cmd[:two] # => Cmd::Two

```

Commands auto register themselves with the underscored name of the last part of
Expand Down Expand Up @@ -159,60 +169,76 @@ would recognize and run the following commands:

```
$ bin/run one something else
# instantiates One, passing the args array `["something", "else"]`, and calls `run`
# instantiates One, passing the args array `["something", "else"]`, and calls the instance method `run`
$ bin/run two something else
# instantiates One, passing an empty args arry `[]`, and calls `run`
$ bin/run two
# instantiates Two, passing an empty args arry `[]`, and calls the instance method `run`
```

The default runner also supports nested namespaces, and checks for command classes
with keys separated by colons. For instance:

```ruby
module Git
class Pull < Cl::Cmd
register :'git:pull'
end
end

module Git
class Push < Cl::Cmd
register :'git:push'
def run
p cmd: registry_key, args: args
end
end
end
```

With these classes registered (and assuming the executable that calls `Cl` is
`bin/git`) the default runner would recognize and run the following commands:
# With this class registered (and assuming the executable that calls `Cl` is
# `bin/run`) the default runner would recognize and run it:
#
# ```
# $ bin/run git:pull master # instantiates Git::Pull, and passes ["master"] as args
# $ bin/run git pull master # does the same
# ```

```
$ bin/git pull:master # instantiates Git::Pull, and passes ["master"] as args
$ bin/git pull master # does the same
Cl.new('run').run(%w(git:pull master))
# Output:
#
# {:cmd=>:"git:pull", :args=>["master"]}

Cl.new('run').run(%w(git pull master))
# Output:
#
# {:cmd=>:"git:pull", :args=>["master"]}

$ bin/git push:master # instantiates Git::Push, and passes ["master"] as args
$ bin/git push master # does the same
```

Runners are registered on the module `Cl::Runner`. It is possible to register custom
runners, and use them by passing the option `runner` to `Cl.new`:

```
# in bin/run
Cli.new('run', runner: :custom).run(ARGV)
# anywhere in your library
class Runner
Cl::Runner.register :custom, self
def initialize(ctx, args)
# ...
end
```ruby
module Git
class Pull < Cl::Cmd
register :'git:pull'

def run
const = identify_cmd_class_from_args
const.new(ctx, args).run
def run
p cmd: registry_key, args: args
end
end
end

# With this class registered (and assuming the executable that calls `Cl` is
# `bin/run`) the default runner would recognize and run it:
#
# ```
# $ bin/run git:pull master # instantiates Git::Pull, and passes ["master"] as args
# $ bin/run git pull master # does the same
# ```

Cl.new('run').run(%w(git:pull master))
# Output:
#
# {:cmd=>:"git:pull", :args=>["master"]}

Cl.new('run').run(%w(git pull master))
# Output:
#
# {:cmd=>:"git:pull", :args=>["master"]}

```

See `Cl::Runner::Default` for more details.
Expand All @@ -238,7 +264,7 @@ Commands are classes that are derived from the base class `Cl::Cmd`.

The description, summary, and examples are used in the help output.

```
```ruby
module Owners
class Add < Cl::Cmd
summary 'Add one or more owners to an existing owner group'
Expand All @@ -259,6 +285,36 @@ module Owners
str
end
end

Cl.new('owners').run(%w(add --help))

# Output:
#
# Usage: owners add [options]
#
# Summary:
#
# Add one or more owners to an existing owner group
#
# Description:
#
# Use this command to add one or more owners to an existing
# owner group.
#
# Options:
#
# --help Get help on this command
#
# Examples:
#
# Adding a single user to the group admins:
#
# owners add user --to admins
#
# Adding a several users at once:
#
# owners add one two three --to admins

```

#### Abstract
Expand Down Expand Up @@ -832,12 +888,14 @@ end

Cl.new('owners').run(%w(add --help))

# Usage: owners add [options]
# Output:
#
# Options:
# Usage: owners add [options]
#
# --to GROUP type: string, note: needs to be a group
# --help Get help on this command
# Options:
#
# --to GROUP type: string, note: needs to be a group
# --help Get help on this command

```

Expand Down
7 changes: 4 additions & 3 deletions bin/examples
Expand Up @@ -28,19 +28,20 @@ class Example < Struct.new(:src)
end

def run(code)
@actual = capture { eval(code) }.strip
@actual = capture { eval(code) }.strip.sub('Example::', '') # ugh.
code
rescue Exception => e
puts e.message, e.backtrace unless e.message == 'exit'
@actual = @stdout.string.strip # Cl::Ui prints error messages to stdout? gotta fix that.
code
end

def out(expected)
def out(expected, opts = { short: false })
@num += 1
@expected = expected.rstrip
errors << error unless actual.strip == expected.strip
comment ['Output:', indent(actual)].join("\n\n")
out = "# => #{actual}" if opts[:short]
out || comment(['Output:', indent(actual)].join("\n\n"))
end

def indent(str)
Expand Down
70 changes: 70 additions & 0 deletions examples/_src/readme/basic.erb.rb
@@ -0,0 +1,70 @@
<%= run sq(<<-'rb')
require 'cl'
# e.g. lib/owners/add.rb
module Owners
class Add < Cl::Cmd
summary 'Add one or more owners to an existing owner group'
description <<~str
Use this command to add one or more owners to an existing
owner group.
[...]
str
args :owner
opt '-t', '--to TO', 'An existing owner group'
def run
# implement adding the owner as given in `owner` (as well as `args`)
# to the group given in `to` (as well as `opts[:to]`).
p owner: owner, to: to, to?: to?, args: args, opts: opts
end
end
end
rb
-%>
# Running this, e.g. using `bin/owners add one,two --to group` will instantiate the
# class `Owners::Add`, and call the method `run` on it.
<%= run sq(<<-'rb')
# e.g. bin/owners
#
# args normally would be ARGV
args = %w(add one --to group)
Cl.new('owners').run(args)
rb
-%>

<%= out '{:owner=>"one", :to=>"group", :to?=>true, :args=>["one"], :opts=>{:to=>"group"}}' %>
<%= run "Cl.new('owners').run(%w(add --help))" %>

<%= out sq(<<-'str')
Usage: owners add [owner] [options]
Summary:
Add one or more owners to an existing owner group
Description:
Use this command to add one or more owners to an existing
owner group.
[...]
Arguments:
owner type: string
Options:
-t --to TO An existing owner group (type: string)
--help Get help on this command
str
%>

0 comments on commit fbeedf1

Please sign in to comment.