sleeping_king_studios-tasks 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cc8e07d6f211c9e3dbf15ddc93b851b6b27114987be947ee082ed67271997d47
4
- data.tar.gz: b33121e54e1c6ce5d4c76b03e205985bcee11d551dc958f00acc73fc81b40eb8
3
+ metadata.gz: c9380cfb581917cac00ae5102325dd895fcbd1364b4d8a53844f9ead55a41173
4
+ data.tar.gz: 69647411117043bf53bf24c4f47231de7d970de6c3adff412cc4a5228af7939e
5
5
  SHA512:
6
- metadata.gz: 78f51530a5a325edcd1fca06464a01424fcce2de696e5d365d961bc8a871bfdde893c33b0d230cd1ff8fa67384ef269fdab25618582d98287f6e4c68d8d88366
7
- data.tar.gz: b5c7433200eb5c7fb91530136405d52b739491f953aeabc438e8c0d4b5cdbb29003c824a37e1c43deda991624c9e546997e83893751c2996a94d68c065653046
6
+ metadata.gz: 563983af6ab016118a21b810e8c5b2f61ef915ddee3bdce425f8945c5bf2bfb5dfc21a14acf8a07a7c08776443fd0cf7e46e5f96ff2c708a88f0834e4d856e51
7
+ data.tar.gz: 0b2d75151cc7513903514ed8f60041c5b7e73b2723373ceedb7f904a65059e8815f100f9cb54f745c6619274650f3ca7b2da063b50082b5548159fcf0d3918d9
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.0
4
+
5
+ - Fix deprecation warnings in Ruby 2.7.
6
+ - Add support for Thor 1.0.
7
+
3
8
  ## 0.2.0
4
9
 
5
10
  ### Ci
@@ -29,8 +29,8 @@ module SleepingKingStudios::Tasks
29
29
  end # method base_command
30
30
 
31
31
  def build_command **kwargs
32
- env = build_environment(kwargs)
33
- opts = build_options(kwargs)
32
+ env = build_environment(**kwargs)
33
+ opts = build_options(**kwargs)
34
34
 
35
35
  "#{env} #{base_command} #{opts}".strip
36
36
  end # method build_command
@@ -52,7 +52,7 @@ module SleepingKingStudios::Tasks
52
52
  end # method build_options
53
53
 
54
54
  def stream_process command
55
- Bundler.with_clean_env do
55
+ unbundled_env do
56
56
  IO.popen(command) do |io|
57
57
  loop do
58
58
  char = io.getc
@@ -60,11 +60,21 @@ module SleepingKingStudios::Tasks
60
60
  char ? print(char) : break
61
61
  end # loop
62
62
  end # popen
63
- end # with_clean_env
63
+ end # with_unbundled_env
64
64
  end # method stream_process
65
65
 
66
66
  def tools
67
67
  SleepingKingStudios::Tools::Toolbelt.new
68
68
  end # method tools
69
+
70
+ def unbundled_env
71
+ # :nocov:
72
+ if Bundler.respond_to?(:with_unbundled_env)
73
+ Bundler.with_unbundled_env { yield }
74
+ else
75
+ Bundler.with_clean_env { yield }
76
+ end
77
+ # :nocov:
78
+ end
69
79
  end # class
70
80
  end # module
@@ -11,7 +11,7 @@ module SleepingKingStudios
11
11
  # Major version.
12
12
  MAJOR = 0
13
13
  # Minor version.
14
- MINOR = 2
14
+ MINOR = 3
15
15
  # Patch version.
16
16
  PATCH = 0
17
17
  # Prerelease version.
@@ -0,0 +1,280 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sleeping_king_studios/tools/core_tools'
4
+ require 'sleeping_king_studios/tools/toolbox'
5
+
6
+ # :nocov:
7
+ module SleepingKingStudios::Tools::Toolbox
8
+ # Abstract base class for defining configuration objects.
9
+ class Configuration # rubocop:disable Metrics/ClassLength
10
+ # Class methods for configuration objects.
11
+ module ClassMethods
12
+ DEFAULT_OPTION = Object.new.freeze
13
+
14
+ # Defines a nested namespace for the configuration object.
15
+ #
16
+ # A namespace is represented by a nested configuration object, which has
17
+ # its own options and namespaces.
18
+ #
19
+ # @param namespace_name [String] The name of the namespace.
20
+ #
21
+ # @yield namespace If a block is given, that block will be executed in the
22
+ # context of the newly created namespace.
23
+ #
24
+ # @return [Configuration] the created namespace object.
25
+ def namespace(namespace_name, &block)
26
+ guard_abstract_class!
27
+
28
+ namespace =
29
+ (@namespaces ||= {}).fetch(namespace_name) do
30
+ @namespaces[namespace_name] = define_namespace namespace_name
31
+ end
32
+
33
+ namespace.instance_exec(namespace, &block) if block_given?
34
+
35
+ namespace
36
+ end
37
+
38
+ # Defines an option for the configuration object.
39
+ #
40
+ # A configuration option has a name and a value. It can be defined with a
41
+ # default value, or to allow or prohibit nil values or restrict possible
42
+ # values to a given set.
43
+ #
44
+ # @param option_name [String] The name of the option.
45
+ # @param allow_nil [true, false] If false, setting the option value to nil
46
+ # or an empty value will raise an error, as will trying to access the
47
+ # value when it has not been set. Defaults to false.
48
+ # @param default [Object] The default value for the option. If this is not
49
+ # set, the default value for the option will be nil.
50
+ # @param enum [Array] An enumerable list of valid values for the option.
51
+ def option(
52
+ option_name,
53
+ allow_nil: false,
54
+ default: DEFAULT_OPTION,
55
+ enum: nil
56
+ )
57
+ guard_abstract_class!
58
+
59
+ options = {
60
+ allow_nil: allow_nil,
61
+ default: default,
62
+ enum: enum
63
+ }
64
+
65
+ define_option_accessor option_name, options
66
+ define_option_mutator option_name, options
67
+
68
+ option_name.intern
69
+ end
70
+
71
+ private
72
+
73
+ def define_namespace(namespace_name)
74
+ namespace =
75
+ Class.new(SleepingKingStudios::Tools::Toolbox::Configuration)
76
+
77
+ define_namespace_accessor(namespace_name, namespace)
78
+
79
+ namespace
80
+ end
81
+
82
+ def define_namespace_accessor(namespace_name, namespace_class)
83
+ namespace_ivar = :"@#{namespace_name}"
84
+
85
+ define_method namespace_name do |&block|
86
+ if instance_variable_defined?(namespace_ivar)
87
+ return instance_variable_get(namespace_ivar).tap do |config|
88
+ block&.call(config)
89
+ end
90
+ end
91
+
92
+ initialize_namespace(namespace_name, namespace_class, &block)
93
+ end
94
+ end
95
+
96
+ def define_option_accessor(option_name, options)
97
+ define_method option_name do
98
+ get_value(option_name, options)
99
+ end
100
+ end
101
+
102
+ def define_option_mutator(option_name, options)
103
+ writer_name = :"#{option_name}="
104
+
105
+ define_method writer_name do |value|
106
+ set_value(option_name, value, options)
107
+ end
108
+ end
109
+
110
+ def guard_abstract_class!
111
+ return unless self == SleepingKingStudios::Tools::Toolbox::Configuration
112
+
113
+ raise "can't define namespace or option on abstract class"
114
+ end
115
+ end
116
+ extend ClassMethods
117
+
118
+ DEFAULT_OPTION = ClassMethods::DEFAULT_OPTION
119
+
120
+ # @param data [Hash, Object] The data source used to populate configuration
121
+ # values. Can be a Hash or a data object. If the data source is nil, or no
122
+ # data source is given, values will be set to their respective defaults.
123
+ #
124
+ # @yieldparam [Class] The singleton class of the new configuration object.
125
+ def initialize(data = nil)
126
+ @data = convert_data_to_struct(data)
127
+ @root_namespace = self
128
+
129
+ return unless block_given?
130
+
131
+ SleepingKingStudios::Tools::CoreTools
132
+ .deprecate('Configuration#initialize with a block')
133
+
134
+ yield(singleton_class)
135
+ end
136
+
137
+ def [](key)
138
+ send(key) if respond_to?(key)
139
+ end
140
+
141
+ def []=(key, value)
142
+ send(:"#{key}=", value) if respond_to?(key)
143
+ end
144
+
145
+ def dig(*keys)
146
+ keys.reduce(self) do |config, key|
147
+ value = config[key]
148
+
149
+ return value if value.nil?
150
+
151
+ value
152
+ end
153
+ end
154
+
155
+ def fetch(key, default = DEFAULT_OPTION)
156
+ return send(key) if respond_to?(key)
157
+
158
+ return default unless default == DEFAULT_OPTION
159
+
160
+ return yield(key) if block_given?
161
+
162
+ raise KeyError, "key not found: #{key.inspect}"
163
+ end
164
+
165
+ protected
166
+
167
+ attr_accessor :root_namespace
168
+
169
+ private
170
+
171
+ attr_reader :data
172
+
173
+ def blank_value?(value)
174
+ value.nil? || (value.respond_to?(:empty?) && value.empty?)
175
+ end
176
+
177
+ def convert_data_to_struct(data)
178
+ return data unless data.is_a?(Hash)
179
+
180
+ return Object.new if data.empty?
181
+
182
+ obj = Struct.new(*data.keys).new
183
+
184
+ data.each do |key, value|
185
+ val = value.is_a?(Hash) ? convert_data_to_struct(value) : value
186
+
187
+ obj.send :"#{key}=", val
188
+ end
189
+
190
+ obj
191
+ end
192
+
193
+ def evaluate_default(default)
194
+ return default unless default.is_a?(Proc)
195
+
196
+ root_namespace.instance_exec(&default)
197
+ end
198
+
199
+ def get_default_value(options)
200
+ value = evaluate_default(options[:default])
201
+
202
+ validate_value value, options
203
+
204
+ value
205
+ end
206
+
207
+ def get_method_value(name, options)
208
+ value = data.send(name)
209
+
210
+ if value.nil? && options[:default] != DEFAULT_OPTION
211
+ value = evaluate_default(options[:default])
212
+ end
213
+
214
+ validate_value(value, options)
215
+
216
+ value
217
+ end
218
+
219
+ def get_value(name, options)
220
+ if data.respond_to?(name)
221
+ get_method_value(name, options)
222
+ elsif instance_variable_defined?(:"@#{name}")
223
+ instance_variable_get(:"@#{name}")
224
+ elsif options[:default] != DEFAULT_OPTION
225
+ get_default_value(options)
226
+ else
227
+ validate_value(nil, options)
228
+
229
+ nil
230
+ end
231
+ end
232
+
233
+ def initialize_namespace(namespace_name, namespace_class, &block)
234
+ data = get_value(namespace_name, default: Object.new)
235
+ config = namespace_class.new(data)
236
+
237
+ config.root_namespace = root_namespace || self
238
+
239
+ instance_variable_set(:"@#{namespace_name}", config)
240
+
241
+ block.call(config) if block_given?
242
+
243
+ config
244
+ end
245
+
246
+ def invalid_value_message(value, options)
247
+ array_tools = ::SleepingKingStudios::Tools::ArrayTools
248
+ valid_options =
249
+ array_tools
250
+ .humanize_list(
251
+ options[:enum].map(&:inspect),
252
+ last_separator: ' or '
253
+ )
254
+
255
+ "expected option to be #{valid_options}, but was #{value.inspect}"
256
+ end
257
+
258
+ def set_value(name, value, options)
259
+ writer_name = :"#{name}="
260
+
261
+ validate_value value, options
262
+
263
+ if data.respond_to?(writer_name)
264
+ data.send(writer_name, value)
265
+ else
266
+ # Store values locally if data source is immutable.
267
+ instance_variable_set(:"@#{name}", value)
268
+ end
269
+ end
270
+
271
+ def validate_value(value, options)
272
+ return if blank_value?(value) && options[:allow_nil]
273
+
274
+ return unless options[:enum] && !options[:enum].include?(value)
275
+
276
+ raise invalid_value_message(value, options)
277
+ end
278
+ end
279
+ end
280
+ # :nocov:
metadata CHANGED
@@ -1,49 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sleeping_king_studios-tasks
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rob "Merlin" Smith
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-06 00:00:00.000000000 Z
11
+ date: 2020-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: rake
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '12.0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '12.0'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: thor
29
15
  requirement: !ruby/object:Gem::Requirement
30
16
  requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '0.19'
34
17
  - - ">="
35
18
  - !ruby/object:Gem::Version
36
19
  version: 0.19.4
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '2.0'
37
23
  type: :runtime
38
24
  prerelease: false
39
25
  version_requirements: !ruby/object:Gem::Requirement
40
26
  requirements:
41
- - - "~>"
42
- - !ruby/object:Gem::Version
43
- version: '0.19'
44
27
  - - ">="
45
28
  - !ruby/object:Gem::Version
46
29
  version: 0.19.4
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '2.0'
47
33
  - !ruby/object:Gem::Dependency
48
34
  name: sleeping_king_studios-tools
49
35
  requirement: !ruby/object:Gem::Requirement
@@ -262,6 +248,7 @@ files:
262
248
  - lib/sleeping_king_studios/tasks/task.rb
263
249
  - lib/sleeping_king_studios/tasks/task_group.rb
264
250
  - lib/sleeping_king_studios/tasks/version.rb
251
+ - lib/sleeping_king_studios/tools/toolbox/configuration.rb
265
252
  homepage: http://sleepingkingstudios.com
266
253
  licenses:
267
254
  - MIT
@@ -281,7 +268,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
281
268
  - !ruby/object:Gem::Version
282
269
  version: '0'
283
270
  requirements: []
284
- rubygems_version: 3.0.3
271
+ rubygems_version: 3.1.2
285
272
  signing_key:
286
273
  specification_version: 4
287
274
  summary: A tasks toolkit for rapid development.