toys 0.7.0 → 0.8.0

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.
@@ -1,38 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright 2018 Daniel Azuma
3
+ # Copyright 2019 Daniel Azuma
4
4
  #
5
- # All rights reserved.
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
6
11
  #
7
- # Redistribution and use in source and binary forms, with or without
8
- # modification, are permitted provided that the following conditions are met:
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
9
14
  #
10
- # * Redistributions of source code must retain the above copyright notice,
11
- # this list of conditions and the following disclaimer.
12
- # * Redistributions in binary form must reproduce the above copyright notice,
13
- # this list of conditions and the following disclaimer in the documentation
14
- # and/or other materials provided with the distribution.
15
- # * Neither the name of the copyright holder, nor the names of any other
16
- # contributors to this software, may be used to endorse or promote products
17
- # derived from this software without specific prior written permission.
18
- #
19
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
- # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
- # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
- # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
- # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
- # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
- # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
- # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
- # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
- # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
- # POSSIBILITY OF SUCH DAMAGE.
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
+ # IN THE SOFTWARE.
30
22
  ;
31
23
 
32
24
  ##
33
25
  # Toys is a configurable command line tool. Write commands in config files
34
- # using a simple DSL, and Toys will provide the command line binary and take
35
- # care of all the details such as argument parsing, online help, and error
26
+ # using a simple DSL, and Toys will provide the command line executable and
27
+ # take care of all the details such as argument parsing, online help, and error
36
28
  # reporting. Toys is designed for software developers, IT professionals, and
37
29
  # other power users who want to write and organize scripts to automate their
38
30
  # workflows. It can also be used as a Rake replacement, providing a more
@@ -40,10 +32,12 @@
40
32
  #
41
33
  module Toys
42
34
  ##
43
- # Path to the Toys binary
44
- # @return [String]
35
+ # Path to the Toys executable.
36
+ #
37
+ # @return [String] Absolute path to the executable
38
+ # @return [nil] if the Toys executable is not running.
45
39
  #
46
- BINARY_PATH = ::ENV["TOYS_BIN_PATH"] || "toys"
40
+ EXECUTABLE_PATH = ::ENV["TOYS_BIN_PATH"]
47
41
 
48
42
  ##
49
43
  # Namespace for standard template classes.
@@ -53,11 +47,15 @@ end
53
47
 
54
48
  require "toys/version"
55
49
 
56
- if ::ENV["TOYS_CORE_LIB_PATH"]
57
- $LOAD_PATH.unshift(::ENV["TOYS_CORE_LIB_PATH"])
58
- else
59
- gem "toys-core", "= #{::Toys::VERSION}"
50
+ # Add toys-core to the load path. The Toys debug scripts will set this
51
+ # environment variable explicitly, but in production, we get it from rubygems.
52
+ # We prepend to $LOAD_PATH directly rather than calling Kernel.gem, so that we
53
+ # don't get clobbered in case someone sets up bundler later.
54
+ ::ENV["TOYS_CORE_LIB_PATH"] ||= begin
55
+ dep = Gem::Dependency.new("toys-core", "= #{::Toys::VERSION}")
56
+ dep.to_spec.full_require_paths.first
60
57
  end
61
- require "toys-core"
58
+ $LOAD_PATH.unshift(::ENV["TOYS_CORE_LIB_PATH"])
62
59
 
60
+ require "toys-core"
63
61
  require "toys/standard_cli"
@@ -1,104 +1,90 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright 2018 Daniel Azuma
3
+ # Copyright 2019 Daniel Azuma
4
4
  #
5
- # All rights reserved.
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
6
11
  #
7
- # Redistribution and use in source and binary forms, with or without
8
- # modification, are permitted provided that the following conditions are met:
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
9
14
  #
10
- # * Redistributions of source code must retain the above copyright notice,
11
- # this list of conditions and the following disclaimer.
12
- # * Redistributions in binary form must reproduce the above copyright notice,
13
- # this list of conditions and the following disclaimer in the documentation
14
- # and/or other materials provided with the distribution.
15
- # * Neither the name of the copyright holder, nor the names of any other
16
- # contributors to this software, may be used to endorse or promote products
17
- # derived from this software without specific prior written permission.
18
- #
19
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
- # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
- # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
- # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
- # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
- # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
- # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
- # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
- # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
- # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
- # POSSIBILITY OF SUCH DAMAGE.
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
+ # IN THE SOFTWARE.
30
22
  ;
31
23
 
32
24
  require "logger"
33
25
 
34
26
  module Toys
35
27
  ##
36
- # Helpers that configure the toys-core CLI with the behavior for the
37
- # standard Toys binary.
28
+ # Subclass of `Toys::CLI` configured for the behavior of the standard Toys
29
+ # executable.
38
30
  #
39
- module StandardCLI
31
+ class StandardCLI < CLI
40
32
  ##
41
- # Path to standard built-in tools
42
- # @return [String]
43
- #
44
- BUILTINS_PATH = ::File.join(::File.dirname(::File.dirname(__dir__)), "builtins").freeze
45
-
46
- ##
47
- # Standard toys configuration directory name
33
+ # Standard toys configuration directory name.
48
34
  # @return [String]
49
35
  #
50
36
  CONFIG_DIR_NAME = ".toys"
51
37
 
52
38
  ##
53
- # Standard toys configuration file name
39
+ # Standard toys configuration file name.
54
40
  # @return [String]
55
41
  #
56
42
  CONFIG_FILE_NAME = ".toys.rb"
57
43
 
58
44
  ##
59
- # Standard index file name in a toys configuration
45
+ # Standard index file name in a toys configuration.
60
46
  # @return [String]
61
47
  #
62
48
  INDEX_FILE_NAME = ".toys.rb"
63
49
 
64
50
  ##
65
- # Standard preload directory name in a toys configuration
51
+ # Standard preload directory name in a toys configuration.
66
52
  # @return [String]
67
53
  #
68
- PRELOAD_DIRECTORY_NAME = ".preload"
54
+ PRELOAD_DIR_NAME = ".preload"
69
55
 
70
56
  ##
71
- # Standard preload file name in a toys configuration
57
+ # Standard preload file name in a toys configuration.
72
58
  # @return [String]
73
59
  #
74
60
  PRELOAD_FILE_NAME = ".preload.rb"
75
61
 
76
62
  ##
77
- # Standard data directory name in a toys configuration
63
+ # Standard data directory name in a toys configuration.
78
64
  # @return [String]
79
65
  #
80
- DATA_DIRECTORY_NAME = ".data"
66
+ DATA_DIR_NAME = ".data"
81
67
 
82
68
  ##
83
- # Name of standard toys binary
69
+ # Name of the standard toys executable.
84
70
  # @return [String]
85
71
  #
86
- BINARY_NAME = "toys"
72
+ EXECUTABLE_NAME = "toys"
87
73
 
88
74
  ##
89
- # Delimiter characters recognized
75
+ # Delimiter characters recognized.
90
76
  # @return [String]
91
77
  #
92
78
  EXTRA_DELIMITERS = ":."
93
79
 
94
80
  ##
95
- # Short description for the standard root tool
81
+ # Short description for the standard root tool.
96
82
  # @return [String]
97
83
  #
98
84
  DEFAULT_ROOT_DESC = "Your personal command line tool"
99
85
 
100
86
  ##
101
- # Help text for the standard root tool
87
+ # Help text for the standard root tool.
102
88
  # @return [String]
103
89
  #
104
90
  DEFAULT_ROOT_LONG_DESC =
@@ -109,13 +95,13 @@ module Toys
109
95
  " For detailed information, see https://www.rubydoc.info/gems/toys"
110
96
 
111
97
  ##
112
- # Short description for the verion flag
98
+ # Short description for the version flag.
113
99
  # @return [String]
114
100
  #
115
101
  DEFAULT_VERSION_FLAG_DESC = "Show the version of Toys."
116
102
 
117
103
  ##
118
- # Name of the toys path environment variable
104
+ # Name of the toys path environment variable.
119
105
  # @return [String]
120
106
  #
121
107
  TOYS_PATH_ENV = "TOYS_PATH"
@@ -124,51 +110,52 @@ module Toys
124
110
  # Create a standard CLI, configured with the appropriate paths and
125
111
  # middleware.
126
112
  #
127
- # @param [String,nil] cur_dir Starting search directory for configs.
113
+ # @param cur_dir [String,nil] Starting search directory for configs.
128
114
  # Defaults to the current working directory.
129
- # @return [Toys::CLI]
130
115
  #
131
- def self.create(cur_dir: nil)
132
- cli = CLI.new(
133
- binary_name: BINARY_NAME,
116
+ def initialize(cur_dir: nil)
117
+ super(
118
+ executable_name: EXECUTABLE_NAME,
134
119
  config_dir_name: CONFIG_DIR_NAME,
135
120
  config_file_name: CONFIG_FILE_NAME,
136
121
  index_file_name: INDEX_FILE_NAME,
137
122
  preload_file_name: PRELOAD_FILE_NAME,
138
- preload_directory_name: PRELOAD_DIRECTORY_NAME,
139
- data_directory_name: DATA_DIRECTORY_NAME,
123
+ preload_dir_name: PRELOAD_DIR_NAME,
124
+ data_dir_name: DATA_DIR_NAME,
140
125
  extra_delimiters: EXTRA_DELIMITERS,
141
126
  middleware_stack: default_middleware_stack,
142
127
  template_lookup: default_template_lookup
143
128
  )
144
- add_standard_paths(cli, cur_dir: cur_dir)
145
- cli
129
+ add_standard_paths(cur_dir: cur_dir)
146
130
  end
147
131
 
132
+ private
133
+
148
134
  ##
149
135
  # Add paths for a toys standard CLI. Paths added, in order from high to
150
136
  # low priority, are:
151
137
  #
152
- # * Search the current directory and all ancestors for config files and
153
- # directories.
154
- # * Read the `TOYS_PATH` environment variable and search for config files
155
- # and directories in the given paths. If this variable is empty, use
156
- # `$HOME:/etc` by default.
157
- # * The builtins for the standard toys binary.
138
+ # * Search the current directory and all ancestors for config files and
139
+ # directories.
140
+ # * Read the `TOYS_PATH` environment variable and search for config files
141
+ # and directories in the given paths. If this variable is empty, use
142
+ # `$HOME:/etc` by default.
143
+ # * The builtins for the standard toys executable.
158
144
  #
159
- # @param [Toys::CLI] cli Add paths to this CLI
160
- # @param [String,nil] cur_dir Starting search directory for configs.
145
+ # @param cur_dir [String,nil] Starting search directory for configs.
161
146
  # Defaults to the current working directory.
162
- # @param [Array<String>,nil] global_dirs Optional list of global
147
+ # @param global_dirs [Array<String>,nil] Optional list of global
163
148
  # directories, or `nil` to use the defaults.
149
+ # @return [self]
164
150
  #
165
- def self.add_standard_paths(cli, cur_dir: nil, global_dirs: nil)
151
+ def add_standard_paths(cur_dir: nil, global_dirs: nil)
166
152
  cur_dir ||= ::Dir.pwd
167
153
  global_dirs ||= default_global_dirs
168
- cli.add_search_path_hierarchy(start: cur_dir, terminate: global_dirs)
169
- global_dirs.each { |path| cli.add_search_path(path) }
170
- cli.add_config_path(BUILTINS_PATH)
171
- cli
154
+ add_search_path_hierarchy(start: cur_dir, terminate: global_dirs)
155
+ global_dirs.each { |path| add_search_path(path) }
156
+ builtins_path = ::File.join(::File.dirname(::File.dirname(__dir__)), "builtins")
157
+ add_config_path(builtins_path)
158
+ self
172
159
  end
173
160
 
174
161
  # rubocop:disable Metrics/MethodLength
@@ -178,12 +165,12 @@ module Toys
178
165
  #
179
166
  # @return [Array]
180
167
  #
181
- def self.default_middleware_stack
168
+ def default_middleware_stack
182
169
  [
183
170
  [
184
171
  :set_default_descriptions,
185
172
  default_root_desc: DEFAULT_ROOT_DESC,
186
- default_root_long_desc: DEFAULT_ROOT_LONG_DESC
173
+ default_root_long_desc: DEFAULT_ROOT_LONG_DESC,
187
174
  ],
188
175
  [
189
176
  :show_help,
@@ -196,28 +183,20 @@ module Toys
196
183
  default_recursive: true,
197
184
  allow_root_args: true,
198
185
  show_source_path: true,
199
- use_less: true
186
+ use_less: true,
187
+ fallback_execution: true,
200
188
  ],
201
189
  [
202
190
  :show_root_version,
203
191
  version_string: ::Toys::VERSION,
204
- version_flag_desc: DEFAULT_VERSION_FLAG_DESC
192
+ version_flag_desc: DEFAULT_VERSION_FLAG_DESC,
205
193
  ],
206
194
  [
207
- :handle_usage_errors
195
+ :handle_usage_errors,
208
196
  ],
209
197
  [
210
- :show_help,
211
- fallback_execution: true,
212
- recursive_flags: true,
213
- search_flags: true,
214
- default_recursive: true,
215
- show_source_path: true,
216
- use_less: true
198
+ :add_verbosity_flags,
217
199
  ],
218
- [
219
- :add_verbosity_flags
220
- ]
221
200
  ]
222
201
  end
223
202
 
@@ -228,7 +207,7 @@ module Toys
228
207
  #
229
208
  # @return [Array<String>]
230
209
  #
231
- def self.default_global_dirs
210
+ def default_global_dirs
232
211
  paths = ::ENV[TOYS_PATH_ENV].to_s.split(::File::PATH_SEPARATOR)
233
212
  paths = [::Dir.home, "/etc"] if paths.empty?
234
213
  paths
@@ -241,10 +220,10 @@ module Toys
241
220
  ##
242
221
  # Returns a ModuleLookup for the default templates.
243
222
  #
244
- # @return [Toys::Utils::ModuleLookup]
223
+ # @return [Toys::ModuleLookup]
245
224
  #
246
- def self.default_template_lookup
247
- Utils::ModuleLookup.new.add_path("toys/templates")
225
+ def default_template_lookup
226
+ ModuleLookup.new.add_path("toys/templates")
248
227
  end
249
228
  end
250
229
  end
@@ -1,32 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright 2018 Daniel Azuma
3
+ # Copyright 2019 Daniel Azuma
4
4
  #
5
- # All rights reserved.
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
6
11
  #
7
- # Redistribution and use in source and binary forms, with or without
8
- # modification, are permitted provided that the following conditions are met:
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
9
14
  #
10
- # * Redistributions of source code must retain the above copyright notice,
11
- # this list of conditions and the following disclaimer.
12
- # * Redistributions in binary form must reproduce the above copyright notice,
13
- # this list of conditions and the following disclaimer in the documentation
14
- # and/or other materials provided with the distribution.
15
- # * Neither the name of the copyright holder, nor the names of any other
16
- # contributors to this software, may be used to endorse or promote products
17
- # derived from this software without specific prior written permission.
18
- #
19
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
- # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
- # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
- # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
- # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
- # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
- # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
- # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
- # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
- # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
- # POSSIBILITY OF SUCH DAMAGE.
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
+ # IN THE SOFTWARE.
30
22
  ;
31
23
 
32
24
  module Toys
@@ -46,9 +38,9 @@ module Toys
46
38
  ##
47
39
  # Create the template settings for the Clean template.
48
40
  #
49
- # @param [String] name Name of the tool to create. Defaults to
41
+ # @param name [String] Name of the tool to create. Defaults to
50
42
  # {DEFAULT_TOOL_NAME}.
51
- # @param [Array<String>] paths An array of glob patterns indicating what
43
+ # @param paths [Array<String>] An array of glob patterns indicating what
52
44
  # to clean.
53
45
  #
54
46
  def initialize(name: DEFAULT_TOOL_NAME, paths: [])
@@ -59,7 +51,7 @@ module Toys
59
51
  attr_accessor :name
60
52
  attr_accessor :paths
61
53
 
62
- to_expand do |template|
54
+ on_expand do |template|
63
55
  tool(template.name) do
64
56
  desc "Clean built files and directories."
65
57