hanami-cli 0.0.0 → 0.1.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rspec +2 -0
- data/.travis.yml +19 -0
- data/CHANGELOG.md +14 -0
- data/Gemfile +9 -2
- data/README.md +412 -6
- data/Rakefile +19 -2
- data/hanami-cli.gemspec +6 -1
- data/lib/hanami/cli.rb +120 -4
- data/lib/hanami/cli/banner.rb +121 -0
- data/lib/hanami/cli/command.rb +365 -0
- data/lib/hanami/cli/command_registry.rb +184 -0
- data/lib/hanami/cli/option.rb +125 -0
- data/lib/hanami/cli/parser.rb +123 -0
- data/lib/hanami/cli/program_name.rb +19 -0
- data/lib/hanami/cli/registry.rb +122 -0
- data/lib/hanami/cli/usage.rb +88 -0
- data/lib/hanami/cli/version.rb +3 -2
- metadata +59 -5
@@ -0,0 +1,122 @@
|
|
1
|
+
require "hanami/cli/command_registry"
|
2
|
+
|
3
|
+
module Hanami
|
4
|
+
class CLI
|
5
|
+
# Registry mixin
|
6
|
+
#
|
7
|
+
# @since 0.1.0
|
8
|
+
module Registry
|
9
|
+
# @since 0.1.0
|
10
|
+
# @api private
|
11
|
+
def self.extended(base)
|
12
|
+
base.class_eval do
|
13
|
+
@commands = CommandRegistry.new
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Register a command
|
18
|
+
#
|
19
|
+
# @param name [String] the command name
|
20
|
+
# @param command [NilClass,Hanami::CLI::Command] the optional command
|
21
|
+
# @param aliases [Array<String>] an optional list of aliases
|
22
|
+
# @param options [Hash] a set of options
|
23
|
+
#
|
24
|
+
# @since 0.1.0
|
25
|
+
#
|
26
|
+
# @example Register a command
|
27
|
+
# require "hanami/cli"
|
28
|
+
#
|
29
|
+
# module Foo
|
30
|
+
# module Commands
|
31
|
+
# extend Hanami::CLI::Registry
|
32
|
+
#
|
33
|
+
# class Hello < Hanami::CLI::Command
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# register "hi", Hello
|
37
|
+
# end
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# @example Register a command with aliases
|
41
|
+
# require "hanami/cli"
|
42
|
+
#
|
43
|
+
# module Foo
|
44
|
+
# module Commands
|
45
|
+
# extend Hanami::CLI::Registry
|
46
|
+
#
|
47
|
+
# class Hello < Hanami::CLI::Command
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# register "hello", Hello, aliases: ["hi", "ciao"]
|
51
|
+
# end
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# @example Register a group of commands
|
55
|
+
# require "hanami/cli"
|
56
|
+
#
|
57
|
+
# module Foo
|
58
|
+
# module Commands
|
59
|
+
# extend Hanami::CLI::Registry
|
60
|
+
#
|
61
|
+
# module Generate
|
62
|
+
# class App < Hanami::CLI::Command
|
63
|
+
# end
|
64
|
+
#
|
65
|
+
# class Action < Hanami::CLI::Command
|
66
|
+
# end
|
67
|
+
# end
|
68
|
+
#
|
69
|
+
# register "generate", aliases: ["g"] do |prefix|
|
70
|
+
# prefix.register "app", Generate::App
|
71
|
+
# prefix.register "action", Generate::Action
|
72
|
+
# end
|
73
|
+
# end
|
74
|
+
# end
|
75
|
+
def register(name, command = nil, aliases: [], **options)
|
76
|
+
if block_given?
|
77
|
+
yield Prefix.new(@commands, name, aliases)
|
78
|
+
else
|
79
|
+
@commands.set(name, command, aliases, **options)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# @since 0.1.0
|
84
|
+
# @api private
|
85
|
+
def get(arguments)
|
86
|
+
@commands.get(arguments)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Command name prefix
|
90
|
+
#
|
91
|
+
# @since 0.1.0
|
92
|
+
class Prefix
|
93
|
+
# @since 0.1.0
|
94
|
+
# @api private
|
95
|
+
def initialize(registry, prefix, aliases)
|
96
|
+
@registry = registry
|
97
|
+
@prefix = prefix
|
98
|
+
|
99
|
+
registry.set(prefix, nil, aliases)
|
100
|
+
end
|
101
|
+
|
102
|
+
# @since 0.1.0
|
103
|
+
#
|
104
|
+
# @see Hanami::CLI::Registry#register
|
105
|
+
def register(name, command, aliases: [], **options)
|
106
|
+
command_name = "#{prefix} #{name}"
|
107
|
+
registry.set(command_name, command, aliases, **options)
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
# @since 0.1.0
|
113
|
+
# @api private
|
114
|
+
attr_reader :registry
|
115
|
+
|
116
|
+
# @since 0.1.0
|
117
|
+
# @api private
|
118
|
+
attr_reader :prefix
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require "hanami/cli/program_name"
|
2
|
+
|
3
|
+
module Hanami
|
4
|
+
class CLI
|
5
|
+
# Command(s) usage
|
6
|
+
#
|
7
|
+
# @since 0.1.0
|
8
|
+
# @api private
|
9
|
+
module Usage
|
10
|
+
# @since 0.1.0
|
11
|
+
# @api private
|
12
|
+
SUBCOMMAND_BANNER = " [SUBCOMMAND]".freeze
|
13
|
+
|
14
|
+
# @since 0.1.0
|
15
|
+
# @api private
|
16
|
+
def self.call(result, out)
|
17
|
+
out.puts "Commands:"
|
18
|
+
max_length, commands = commands_and_arguments(result)
|
19
|
+
|
20
|
+
commands.each do |banner, node|
|
21
|
+
usage = description(node.command) if node.leaf?
|
22
|
+
out.puts "#{justify(banner, max_length, usage)}#{usage}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# @since 0.1.0
|
27
|
+
# @api private
|
28
|
+
def self.commands_and_arguments(result) # rubocop:disable Metrics/MethodLength
|
29
|
+
max_length = 0
|
30
|
+
ret = commands(result).each_with_object({}) do |(name, node), memo|
|
31
|
+
args = if node.leaf?
|
32
|
+
arguments(node.command)
|
33
|
+
else
|
34
|
+
SUBCOMMAND_BANNER
|
35
|
+
end
|
36
|
+
|
37
|
+
partial = " #{command_name(result, name)}#{args}"
|
38
|
+
max_length = partial.bytesize if max_length < partial.bytesize
|
39
|
+
memo[partial] = node
|
40
|
+
end
|
41
|
+
|
42
|
+
[max_length, ret]
|
43
|
+
end
|
44
|
+
|
45
|
+
# @since 0.1.0
|
46
|
+
# @api private
|
47
|
+
def self.arguments(command) # rubocop:disable Metrics/AbcSize
|
48
|
+
return unless CLI.command?(command)
|
49
|
+
|
50
|
+
required_arguments = command.required_arguments
|
51
|
+
optional_arguments = command.optional_arguments
|
52
|
+
|
53
|
+
required = required_arguments.map { |arg| arg.name.upcase }.join(' ') if required_arguments.any?
|
54
|
+
optional = optional_arguments.map { |arg| "[#{arg.name.upcase}]" }.join(' ') if optional_arguments.any?
|
55
|
+
result = [required, optional].compact
|
56
|
+
|
57
|
+
" #{result.join(' ')}" unless result.empty?
|
58
|
+
end
|
59
|
+
|
60
|
+
# @since 0.1.0
|
61
|
+
# @api private
|
62
|
+
def self.description(command)
|
63
|
+
return unless CLI.command?(command)
|
64
|
+
|
65
|
+
" # #{command.description}" unless command.description.nil?
|
66
|
+
end
|
67
|
+
|
68
|
+
# @since 0.1.0
|
69
|
+
# @api private
|
70
|
+
def self.justify(string, padding, usage)
|
71
|
+
return string.chomp(" ") if usage.nil?
|
72
|
+
string.ljust(padding + padding / 2)
|
73
|
+
end
|
74
|
+
|
75
|
+
# @since 0.1.0
|
76
|
+
# @api private
|
77
|
+
def self.commands(result)
|
78
|
+
result.children.sort_by { |name, _| name }
|
79
|
+
end
|
80
|
+
|
81
|
+
# @since 0.1.0
|
82
|
+
# @api private
|
83
|
+
def self.command_name(result, name)
|
84
|
+
ProgramName.call([result.names, name])
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
data/lib/hanami/cli/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hanami-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.1.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luca Guidi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-08-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: hanami-utils
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.1.0.beta1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.1.0.beta1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: concurrent-ruby
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.0'
|
13
41
|
- !ruby/object:Gem::Dependency
|
14
42
|
name: bundler
|
15
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,6 +66,20 @@ dependencies:
|
|
38
66
|
- - "~>"
|
39
67
|
- !ruby/object:Gem::Version
|
40
68
|
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.5'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.5'
|
41
83
|
description: Hanami framework to build command line interfaces with Ruby
|
42
84
|
email:
|
43
85
|
- me@lucaguidi.com
|
@@ -46,6 +88,9 @@ extensions: []
|
|
46
88
|
extra_rdoc_files: []
|
47
89
|
files:
|
48
90
|
- ".gitignore"
|
91
|
+
- ".rspec"
|
92
|
+
- ".travis.yml"
|
93
|
+
- CHANGELOG.md
|
49
94
|
- Gemfile
|
50
95
|
- README.md
|
51
96
|
- Rakefile
|
@@ -53,9 +98,18 @@ files:
|
|
53
98
|
- bin/setup
|
54
99
|
- hanami-cli.gemspec
|
55
100
|
- lib/hanami/cli.rb
|
101
|
+
- lib/hanami/cli/banner.rb
|
102
|
+
- lib/hanami/cli/command.rb
|
103
|
+
- lib/hanami/cli/command_registry.rb
|
104
|
+
- lib/hanami/cli/option.rb
|
105
|
+
- lib/hanami/cli/parser.rb
|
106
|
+
- lib/hanami/cli/program_name.rb
|
107
|
+
- lib/hanami/cli/registry.rb
|
108
|
+
- lib/hanami/cli/usage.rb
|
56
109
|
- lib/hanami/cli/version.rb
|
57
110
|
homepage: http://hanamirb.org
|
58
|
-
licenses:
|
111
|
+
licenses:
|
112
|
+
- MIT
|
59
113
|
metadata:
|
60
114
|
allowed_push_host: https://rubygems.org
|
61
115
|
post_install_message:
|
@@ -69,9 +123,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
69
123
|
version: '0'
|
70
124
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
125
|
requirements:
|
72
|
-
- - "
|
126
|
+
- - ">"
|
73
127
|
- !ruby/object:Gem::Version
|
74
|
-
version:
|
128
|
+
version: 1.3.1
|
75
129
|
requirements: []
|
76
130
|
rubyforge_project:
|
77
131
|
rubygems_version: 2.6.11
|