Class: OKF::CLI::Command

Inherits:
Object
  • Object
show all
Defined in:
lib/okf/cli/command.rb

Overview

What every command inherits: the injected streams, and the shared surface a verb leans on — ref resolution, the flags several of them offer, the JSON emitters, the list-view printers.

A command answers four questions about itself (.id, .group, .help_rows, .hidden?) and one about a run (#call, returning an exit status). That is the whole contract, and it is the same one a plugin implements — there is no second, lesser interface for an addon, because a seam only the base gem can use is not a seam.

Privacy is the boundary, the one idea worth taking from Thor without taking Thor: #call is the entire public surface, so a helper added below can never become a verb by accident.

Constant Summary collapse

DUCK_TYPE =

What .register checks before admitting a command. Checked at registration rather than at dispatch, so a malformed addon fails where it is installed instead of the first time a user types its verb.

%i[id group help_rows hidden? new].freeze
FILTER_KEYS =

Every key a filter flag can set. One list, read by both the narrowing itself and the "is anything narrowing?" guard, so adding a filter cannot leave one of them behind.

%i[type area dir tag status trust].freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(out:, err:, runner: nil, input: nil) ⇒ Command

runner: is the server's injected boot seam and input: the terminal a full-screen command needs. Both live here rather than on the two commands that want them, so construction is uniform: a plugin is built exactly the way a built-in is, and the CLI needs to know nothing about which is which.



62
63
64
65
66
67
68
69
# File 'lib/okf/cli/command.rb', line 62

def initialize(out:, err:, runner: nil, input: nil)
  @out = out
  @err = err
  @runner = runner
  @input = input
  @pretty = false
  @ref_slugs = {}
end

Class Method Details

.groupObject

Where the verb sits in the map okf help prints. CLI::GROUPS fixes the order; anything else — which is what a plugin gets by default — falls to the end, under its own heading.



40
41
42
# File 'lib/okf/cli/command.rb', line 40

def group
  :extension
end

.help_rowsObject

[ [ left-column, description ], … ] — one row per line of the map. A list rather than a pair because registry is an umbrella: five subcommands under one verb, each of which has to be findable alone.



47
48
49
# File 'lib/okf/cli/command.rb', line 47

def help_rows
  []
end

.hidden?Boolean

A command that works but is not advertised.

Returns:

  • (Boolean)


52
53
54
# File 'lib/okf/cli/command.rb', line 52

def hidden?
  false
end

.idObject

The verb this answers to, as a Symbol. The registry is keyed on it.

Raises:

  • (NotImplementedError)


33
34
35
# File 'lib/okf/cli/command.rb', line 33

def id
  raise NotImplementedError, "#{self}.id must name the verb it answers to"
end

Instance Method Details

#call(argv) ⇒ Object

The run. Returns the exit status; it never calls exit, and never writes anywhere but the injected streams.

Raises:

  • (NotImplementedError)


73
74
75
# File 'lib/okf/cli/command.rb', line 73

def call(argv)
  raise NotImplementedError, "#{self.class} must implement #call(argv) and return an exit status"
end