toys 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,101 @@
1
+ # Copyright 2018 Daniel Azuma
2
+ #
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ # * Neither the name of the copyright holder, nor the names of any other
14
+ # contributors to this software, may be used to endorse or promote products
15
+ # derived from this software without specific prior written permission.
16
+ #
17
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ # POSSIBILITY OF SUCH DAMAGE.
28
+ ;
29
+
30
+ module Toys
31
+ module Utils
32
+ ##
33
+ # A helper module that provides methods to do module lookups. This is
34
+ # used to obtain named helpers, middleware, and templates from the
35
+ # respective modules.
36
+ #
37
+ # You generally do not need to use these module methods directly. Instead
38
+ # use the convenience methods {Toys::Helpers.lookup},
39
+ # {Toys::Middleware.lookup}, or {Toys::Templates.lookup}.
40
+ #
41
+ module ModuleLookup
42
+ class << self
43
+ ##
44
+ # Convert the given string to a path element. Specifically, converts
45
+ # to `lower_snake_case`.
46
+ #
47
+ # @param [String,Symbol] str String to convert.
48
+ # @return [String] Converted string
49
+ #
50
+ def to_path_name(str)
51
+ str.to_s.gsub(/([a-zA-Z])([A-Z])/) { |_m| "#{$1}_#{$2.downcase}" }.downcase
52
+ end
53
+
54
+ ##
55
+ # Convert the given string to a module name. Specifically, converts
56
+ # to `UpperCamelCase`.
57
+ #
58
+ # @param [String,Symbol] str String to convert.
59
+ # @return [String] Converted string
60
+ #
61
+ def to_module_name(str)
62
+ str.to_s.gsub(/(^|_)([a-zA-Z0-9])/) { |_m| $2.upcase }
63
+ end
64
+
65
+ ##
66
+ # Obtain a named module from the given collection. Raises an exception
67
+ # on failure.
68
+ #
69
+ # @param [String,Symbol] collection The collection to search. Typical
70
+ # values are `:helpers`, `:middleware`, and `:templates`.
71
+ # @param [String,Symbol] name The name of the module to return.
72
+ #
73
+ # @return [Module] The specified module
74
+ # @raise [LoadError] No Ruby file containing the given module could
75
+ # be found.
76
+ # @raise [NameError] The given module was not defined.
77
+ #
78
+ def lookup!(collection, name)
79
+ require "toys/#{to_path_name(collection)}/#{to_path_name(name)}"
80
+ ::Toys.const_get(to_module_name(collection)).const_get(to_module_name(name))
81
+ end
82
+
83
+ ##
84
+ # Obtain a named module from the given collection. Returns `nil` on
85
+ # failure.
86
+ #
87
+ # @param [String,Symbol] collection The collection to search. Typical
88
+ # values are `:helpers`, `:middleware`, and `:templates`.
89
+ # @param [String,Symbol] name The name of the module to return.
90
+ #
91
+ # @return [Module,nil] The specified module, or `nil` if not found.
92
+ #
93
+ def lookup(collection, name)
94
+ lookup!(collection, name)
95
+ rescue ::NameError, ::LoadError
96
+ nil
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,119 @@
1
+ # Copyright 2018 Daniel Azuma
2
+ #
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ # * Neither the name of the copyright holder, nor the names of any other
14
+ # contributors to this software, may be used to endorse or promote products
15
+ # derived from this software without specific prior written permission.
16
+ #
17
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ # POSSIBILITY OF SUCH DAMAGE.
28
+ ;
29
+
30
+ module Toys
31
+ module Utils
32
+ ##
33
+ # Helper that generates usage text
34
+ #
35
+ class Usage
36
+ def self.from_context(context)
37
+ new(context[Context::TOOL], context[Context::BINARY_NAME], context[Context::LOADER])
38
+ end
39
+
40
+ def initialize(tool, binary_name, loader)
41
+ @tool = tool
42
+ @binary_name = binary_name
43
+ @loader = loader
44
+ end
45
+
46
+ def string(recursive: false)
47
+ optparse = ::OptionParser.new
48
+ optparse.banner = @tool.includes_executor? ? tool_banner : group_banner
49
+ unless @tool.effective_long_desc.empty?
50
+ optparse.separator("")
51
+ optparse.separator(@tool.effective_long_desc)
52
+ end
53
+ add_switches(optparse)
54
+ if @tool.includes_executor?
55
+ add_positional_arguments(optparse)
56
+ elsif !@tool.alias?
57
+ add_command_list(optparse, recursive)
58
+ end
59
+ optparse.to_s
60
+ end
61
+
62
+ private
63
+
64
+ def tool_banner
65
+ banner = ["Usage:", @binary_name] + @tool.full_name
66
+ banner << "[<options...>]" unless @tool.switches.empty?
67
+ @tool.required_args.each do |arg_info|
68
+ banner << "<#{arg_info.canonical_name}>"
69
+ end
70
+ @tool.optional_args.each do |arg_info|
71
+ banner << "[<#{arg_info.canonical_name}>]"
72
+ end
73
+ if @tool.remaining_args
74
+ banner << "[<#{@tool.remaining_args.canonical_name}...>]"
75
+ end
76
+ banner.join(" ")
77
+ end
78
+
79
+ def group_banner
80
+ (["Usage:", @binary_name] + @tool.full_name + ["<command>", "[<options...>]"]).join(" ")
81
+ end
82
+
83
+ def add_switches(optparse)
84
+ return if @tool.switches.empty?
85
+ optparse.separator("")
86
+ optparse.separator("Options:")
87
+ @tool.switches.each do |switch|
88
+ optparse.on(*switch.optparse_info)
89
+ end
90
+ end
91
+
92
+ def add_positional_arguments(optparse)
93
+ args_to_display = @tool.required_args + @tool.optional_args
94
+ args_to_display << @tool.remaining_args if @tool.remaining_args
95
+ return if args_to_display.empty?
96
+ optparse.separator("")
97
+ optparse.separator("Positional arguments:")
98
+ args_to_display.each do |arg_info|
99
+ optparse.separator(" #{arg_info.canonical_name.ljust(31)} #{arg_info.doc.first}")
100
+ (arg_info.doc[1..-1] || []).each do |d|
101
+ optparse.separator(" #{d}")
102
+ end
103
+ end
104
+ end
105
+
106
+ def add_command_list(optparse, recursive)
107
+ name_len = @tool.full_name.length
108
+ subtools = @loader.list_subtools(@tool.full_name, recursive)
109
+ return if subtools.empty?
110
+ optparse.separator("")
111
+ optparse.separator("Commands:")
112
+ subtools.each do |subtool|
113
+ tool_name = subtool.full_name.slice(name_len..-1).join(" ").ljust(31)
114
+ optparse.separator(" #{tool_name} #{subtool.effective_desc}")
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
@@ -32,5 +32,5 @@ module Toys
32
32
  # Current version of Toys
33
33
  # @return [String]
34
34
  #
35
- VERSION = "0.2.2".freeze
35
+ VERSION = "0.3.0".freeze
36
36
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: toys
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Azuma
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-13 00:00:00.000000000 Z
11
+ date: 2018-05-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '5.10'
19
+ version: '5.11'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '5.10'
26
+ version: '5.11'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: minitest-focus
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.53.0
61
+ version: 0.55.0
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 0.53.0
68
+ version: 0.55.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: yard
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -88,25 +88,37 @@ executables:
88
88
  extensions: []
89
89
  extra_rdoc_files: []
90
90
  files:
91
+ - CHANGELOG.md
91
92
  - LICENSE.md
92
93
  - README.md
93
94
  - bin/toys
94
95
  - lib/toys.rb
95
96
  - lib/toys/builder.rb
97
+ - lib/toys/builtins/do.rb
96
98
  - lib/toys/builtins/system.rb
97
99
  - lib/toys/cli.rb
98
100
  - lib/toys/context.rb
99
101
  - lib/toys/errors.rb
102
+ - lib/toys/helpers.rb
100
103
  - lib/toys/helpers/exec.rb
101
104
  - lib/toys/helpers/file_utils.rb
102
- - lib/toys/lookup.rb
105
+ - lib/toys/loader.rb
106
+ - lib/toys/middleware.rb
107
+ - lib/toys/middleware/base.rb
108
+ - lib/toys/middleware/group_default.rb
109
+ - lib/toys/middleware/set_verbosity.rb
110
+ - lib/toys/middleware/show_tool_help.rb
111
+ - lib/toys/middleware/show_usage_errors.rb
103
112
  - lib/toys/template.rb
113
+ - lib/toys/templates.rb
104
114
  - lib/toys/templates/clean.rb
105
115
  - lib/toys/templates/gem_build.rb
106
116
  - lib/toys/templates/minitest.rb
107
117
  - lib/toys/templates/rubocop.rb
108
118
  - lib/toys/templates/yardoc.rb
109
119
  - lib/toys/tool.rb
120
+ - lib/toys/utils/module_lookup.rb
121
+ - lib/toys/utils/usage.rb
110
122
  - lib/toys/version.rb
111
123
  homepage: https://github.com/dazuma/toys
112
124
  licenses:
@@ -128,7 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
128
140
  version: '0'
129
141
  requirements: []
130
142
  rubyforge_project:
131
- rubygems_version: 2.6.14
143
+ rubygems_version: 2.7.6
132
144
  signing_key:
133
145
  specification_version: 4
134
146
  summary: Command line tool framework