hanami-cli 0.0.0 → 0.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -1,5 +1,6 @@
1
1
  module Hanami
2
- module Cli
3
- VERSION = "0.0.0"
2
+ class CLI
3
+ # @since 0.1.0
4
+ VERSION = "0.1.0.beta1".freeze
4
5
  end
5
6
  end
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.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-04-04 00:00:00.000000000 Z
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: '0'
128
+ version: 1.3.1
75
129
  requirements: []
76
130
  rubyforge_project:
77
131
  rubygems_version: 2.6.11