baltix 0.1.1
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 +7 -0
- data/.github/workflows/ci.yml +44 -0
- data/.gitignore +10 -0
- data/Gemfile +8 -0
- data/LICENSE +8 -0
- data/README.md +60 -0
- data/Rakefile +8 -0
- data/TODO +84 -0
- data/baltix.gemspec +39 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/baltix +4 -0
- data/lib/baltix/actor/copy.rb +19 -0
- data/lib/baltix/actor/link.rb +20 -0
- data/lib/baltix/actor/spec.rb +25 -0
- data/lib/baltix/actor/touch.rb +17 -0
- data/lib/baltix/actor.rb +75 -0
- data/lib/baltix/cli.rb +173 -0
- data/lib/baltix/deps.rb +280 -0
- data/lib/baltix/dsl.rb +311 -0
- data/lib/baltix/extensions.rb +536 -0
- data/lib/baltix/i18n.rb +64 -0
- data/lib/baltix/loader/cmake.rb +11 -0
- data/lib/baltix/loader/git-version-gen.rb +36 -0
- data/lib/baltix/loader/mast.rb +139 -0
- data/lib/baltix/loader/pom.rb +27 -0
- data/lib/baltix/loader/rookbook.rb +26 -0
- data/lib/baltix/loader/yaml.rb +18 -0
- data/lib/baltix/loader.rb +192 -0
- data/lib/baltix/log.rb +73 -0
- data/lib/baltix/rake.rb +57 -0
- data/lib/baltix/scheme.erb.yaml +20 -0
- data/lib/baltix/source/base.rb +438 -0
- data/lib/baltix/source/fake.rb +17 -0
- data/lib/baltix/source/gem.rb +407 -0
- data/lib/baltix/source/gemfile.rb +35 -0
- data/lib/baltix/source/rakefile.rb +24 -0
- data/lib/baltix/source.rb +57 -0
- data/lib/baltix/space/spec.rb +11 -0
- data/lib/baltix/space.rb +424 -0
- data/lib/baltix/spec/rpm/name.rb +155 -0
- data/lib/baltix/spec/rpm/parser.rb +412 -0
- data/lib/baltix/spec/rpm/secondary.rb +170 -0
- data/lib/baltix/spec/rpm/spec_core.rb +580 -0
- data/lib/baltix/spec/rpm.erb +188 -0
- data/lib/baltix/spec/rpm.rb +822 -0
- data/lib/baltix/spec.rb +48 -0
- data/lib/baltix/version.rb +3 -0
- data/lib/baltix.rb +19 -0
- data/locale/en_US.UTF-8.yaml +27 -0
- data/locale/ru_RU.UTF-8.yaml +23 -0
- metadata +216 -0
data/lib/baltix/space.rb
ADDED
@@ -0,0 +1,424 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
require 'baltix/version'
|
4
|
+
require 'baltix/log'
|
5
|
+
require 'baltix/source'
|
6
|
+
require 'baltix/spec'
|
7
|
+
require 'baltix/cli'
|
8
|
+
|
9
|
+
class Baltix::Space
|
10
|
+
include Baltix::Log
|
11
|
+
|
12
|
+
class InvalidSpaceFileError < StandardError; end
|
13
|
+
|
14
|
+
TYPES = {
|
15
|
+
sources: Baltix::Source
|
16
|
+
}
|
17
|
+
|
18
|
+
STATES = {
|
19
|
+
invalid: ->(_, source, _) { !source.valid? },
|
20
|
+
disabled: ->(space, source, _) { space.is_disabled?(source) },
|
21
|
+
duplicated: ->(_, _, dup) { dup },
|
22
|
+
}
|
23
|
+
|
24
|
+
TYPE_CHARS = {
|
25
|
+
fake: '·',
|
26
|
+
gem: '*',
|
27
|
+
gemfile: '&',
|
28
|
+
rakefile: '^',
|
29
|
+
}
|
30
|
+
|
31
|
+
STATUS_CHARS = {
|
32
|
+
invalid: 'X',
|
33
|
+
disabled: '-',
|
34
|
+
duplicated: '=',
|
35
|
+
valid: 'V',
|
36
|
+
}
|
37
|
+
|
38
|
+
|
39
|
+
Gem.load_yaml
|
40
|
+
|
41
|
+
@@space = {}
|
42
|
+
@@options = {}
|
43
|
+
|
44
|
+
# +options+ property returns the hash of the loaded options if any
|
45
|
+
#
|
46
|
+
# options #=> {...}
|
47
|
+
#
|
48
|
+
attr_reader :options, :state
|
49
|
+
|
50
|
+
# +name+ returns a default name of the space with a prefix if any. It returns name of a source when
|
51
|
+
# its root is the same as the space's root, or returns name defined in the spec if any.
|
52
|
+
# If no spec defined returns name of last folder in rootdir or "root" as a default main source name.
|
53
|
+
#
|
54
|
+
# space.name # => space-name
|
55
|
+
#
|
56
|
+
def name
|
57
|
+
return @name if @name
|
58
|
+
|
59
|
+
@name = spec&.name || main_source&.name
|
60
|
+
end
|
61
|
+
|
62
|
+
# +version+ returns a default version for the space. Returns version of a source when
|
63
|
+
# its root is the same as the space's root, or returns version defined in the spec if any,
|
64
|
+
# or returns default one.
|
65
|
+
#
|
66
|
+
# space.version # => 2.1.1
|
67
|
+
#
|
68
|
+
def version
|
69
|
+
return @version if @version
|
70
|
+
|
71
|
+
@version ||= main_source&.version || spec&.version
|
72
|
+
end
|
73
|
+
|
74
|
+
attr_writer :rootdir
|
75
|
+
|
76
|
+
# +rootdir+ returns the root dir for the space got from the options,
|
77
|
+
# defaulting to the current folder.
|
78
|
+
#
|
79
|
+
# rootdir #=> /root/dir/for/the/space
|
80
|
+
#
|
81
|
+
def rootdir
|
82
|
+
@rootdir ||= read_attribute(:rootdir) || Dir.pwd
|
83
|
+
end
|
84
|
+
|
85
|
+
# +main_source+ selects main source from the list of sources when source root dir is the space's one and
|
86
|
+
# source's name contains minimum name size among the matching sources
|
87
|
+
#
|
88
|
+
def main_source
|
89
|
+
return @main_source if @main_source
|
90
|
+
|
91
|
+
reals = valid_sources.select { |source| !source.is_a?(Baltix::Source::Fake) }
|
92
|
+
if spec && !spec.state.blank?
|
93
|
+
specen_source = reals.find { |real| spec.state["name"] === real.name }
|
94
|
+
end
|
95
|
+
|
96
|
+
root_source ||= valid_sources.sort {|x, y| x.name.size <=> y.name.size }.find { |source| source.rootdir == rootdir }
|
97
|
+
@main_source =
|
98
|
+
specen_source || root_source.is_a?(Baltix::Source::Fake) && reals.size == 1 && reals.first || root_source
|
99
|
+
end
|
100
|
+
|
101
|
+
def time_stamp
|
102
|
+
Time.now.strftime("%Y%m%d")
|
103
|
+
end
|
104
|
+
|
105
|
+
# +changes+ returns a list of open-struct formatted changes in the space or
|
106
|
+
# spec defined if any, otherwise returns blank array.
|
107
|
+
#
|
108
|
+
# space.changes # => []
|
109
|
+
#
|
110
|
+
def changes
|
111
|
+
@changes ||= spec&.changes || main_source&.respond_to?(:changes) && main_source.changes || []
|
112
|
+
end
|
113
|
+
|
114
|
+
# +summaries+ returns an open-struct formatted summaries with locales as keys
|
115
|
+
# in the space or spec defined if any, otherwise returns blank open struct.
|
116
|
+
#
|
117
|
+
# space.summaries # => #<OpenStruct en_US.UTF-8: ...>
|
118
|
+
#
|
119
|
+
def summaries
|
120
|
+
return @summaries if @summaries
|
121
|
+
|
122
|
+
if summaries = spec&.summaries || state.summaries
|
123
|
+
summaries
|
124
|
+
elsif summary = main_source&.summary
|
125
|
+
{ Baltix::I18n.default_locale => summary }.to_os
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# +licenses+ returns license list defined in all the valid sources found in the space.
|
130
|
+
#
|
131
|
+
# space.licenses => # ["MIT"]
|
132
|
+
#
|
133
|
+
def licenses
|
134
|
+
return @licenses if @licenses
|
135
|
+
|
136
|
+
licenses = valid_sources.map { |source| source.licenses rescue [] }.flatten.uniq
|
137
|
+
|
138
|
+
@licenses = !licenses.blank? && licenses || spec&.licenses || []
|
139
|
+
end
|
140
|
+
|
141
|
+
# +dependencies+ returns all the valid source dependencies list as an array of Gem::Dependency
|
142
|
+
# objects, otherwise returning blank array.
|
143
|
+
def dependencies
|
144
|
+
@dependencies ||= valid_sources.map do |source|
|
145
|
+
source.respond_to?(:dependencies) && source.dependencies || []
|
146
|
+
end.flatten.reject do |dep|
|
147
|
+
match_platform?(dep) || sources.any? do |s|
|
148
|
+
dep.name == s.name &&
|
149
|
+
dep.requirement.satisfied_by?(Gem::Version.new(s.version))
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def match_platform? dep
|
155
|
+
if dep.respond_to?(:platforms)
|
156
|
+
(dep.platforms & options.skip_platforms).any?
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def files
|
161
|
+
@files ||= valid_sources.map { |s| s.files rescue [] }.flatten.uniq
|
162
|
+
end
|
163
|
+
|
164
|
+
def executables
|
165
|
+
@executables ||= valid_sources.map { |s| s.executables rescue [] }.flatten.uniq
|
166
|
+
end
|
167
|
+
|
168
|
+
def docs
|
169
|
+
@docs ||= valid_sources.map { |s| s.docs rescue [] }.flatten.uniq
|
170
|
+
end
|
171
|
+
|
172
|
+
def compilables
|
173
|
+
@compilables ||= valid_sources.map { |s| s.extensions rescue [] }.flatten.uniq
|
174
|
+
end
|
175
|
+
|
176
|
+
# +sources+ returns all the sources in the space. It will load from the space sources,
|
177
|
+
# or by default will search sources in the provided folder or the current one.
|
178
|
+
#
|
179
|
+
# space.sources => # [#<Baltix::Source:...>, #<...>]
|
180
|
+
#
|
181
|
+
def sources
|
182
|
+
@sources ||= stat_sources.map { |x| x.first }
|
183
|
+
end
|
184
|
+
|
185
|
+
# +valid_sources+ returns all the valid sources based on the current source list.
|
186
|
+
#
|
187
|
+
# space.valid_sources => # [#<Baltix::Source:...>, #<...>]
|
188
|
+
#
|
189
|
+
# def valid_sources
|
190
|
+
# @valid_sources ||= sources.select do |source|
|
191
|
+
# source.valid? && is_regarded?(source)
|
192
|
+
# end
|
193
|
+
# end
|
194
|
+
def valid_sources
|
195
|
+
@valid_sources = stat_sources.map {|(source, status)| status == :valid && source || nil }.compact
|
196
|
+
end
|
197
|
+
|
198
|
+
# def is_regarded? source
|
199
|
+
# regarded_names.any? {|i| i === source.name } ||
|
200
|
+
# !ignored_names.any? {|i| i === source.name } &&
|
201
|
+
# !ignored_path_tokens.any? {|t| /\/#{t}\// =~ source.source_file }
|
202
|
+
# end
|
203
|
+
|
204
|
+
def ignored_names
|
205
|
+
@ignored_names ||= (read_attribute(:ignored_names) || [])
|
206
|
+
end
|
207
|
+
|
208
|
+
def regarded_names
|
209
|
+
@regarded_names ||= read_attribute(:regarded_names) || []
|
210
|
+
end
|
211
|
+
|
212
|
+
def ignored_path_tokens
|
213
|
+
@ignored_path_tokens ||= (read_attribute(:ignored_path_tokens) || [])
|
214
|
+
end
|
215
|
+
|
216
|
+
def spec_type
|
217
|
+
@spec_type ||= read_attribute(:spec_type) || spec && spec.class.to_s.split("::").last.downcase
|
218
|
+
end
|
219
|
+
|
220
|
+
def read_attribute attr
|
221
|
+
options.send(attr) || state.send(attr)
|
222
|
+
end
|
223
|
+
|
224
|
+
def options_for type
|
225
|
+
@@options[type] = type::OPTIONS.map do |option|
|
226
|
+
value = self.options[option] || self.respond_to?(option) && self.send(option) || nil
|
227
|
+
|
228
|
+
[ option, value ]
|
229
|
+
end.compact.to_os
|
230
|
+
end
|
231
|
+
|
232
|
+
# +spec+ property returns the hash of the loaded spec if any, it can be freely
|
233
|
+
# reassigned.
|
234
|
+
#
|
235
|
+
# spec #=> {...}
|
236
|
+
#
|
237
|
+
def spec
|
238
|
+
@spec ||= gen_spec
|
239
|
+
end
|
240
|
+
|
241
|
+
def spec= value
|
242
|
+
gen_spec(value)
|
243
|
+
end
|
244
|
+
|
245
|
+
def is_disabled? source
|
246
|
+
options.ignored_path_tokens.any? { |t| /\/#{t}\// =~ source.source_file } ||
|
247
|
+
options.regarded_names.all? { |i| !i.match?(source.name) } &&
|
248
|
+
options.ignored_names.any? { |i| i === source.name }
|
249
|
+
end
|
250
|
+
|
251
|
+
protected
|
252
|
+
|
253
|
+
def gen_spec spec_in = nil
|
254
|
+
spec_pre = spec_in || state.spec
|
255
|
+
|
256
|
+
@spec =
|
257
|
+
if spec_pre.is_a?(Baltix::Spec::Rpm)
|
258
|
+
spec_pre
|
259
|
+
elsif spec_pre.is_a?(String)
|
260
|
+
self.class.load(spec_pre)
|
261
|
+
elsif options&.spec_file
|
262
|
+
Baltix::Spec.load_from(source: IO.read(options.spec_file), options: options, space: self)
|
263
|
+
elsif @spec_type || options&.spec_type
|
264
|
+
Baltix::Spec.find(@spec_type || options.spec_type).new(options: options, space: self)
|
265
|
+
end
|
266
|
+
|
267
|
+
@spec.assign_space(self) if @spec
|
268
|
+
|
269
|
+
@spec
|
270
|
+
end
|
271
|
+
|
272
|
+
def initialize state_in = {}, options = {}
|
273
|
+
@options = Baltix::CLI::DEFAULT_OPTIONS.merge(options || {})
|
274
|
+
@state = (state_in || {}).to_os
|
275
|
+
|
276
|
+
baltix_log
|
277
|
+
end
|
278
|
+
|
279
|
+
# init log
|
280
|
+
def baltix_log
|
281
|
+
ios = DEFAULT_IO_NAMES.merge(%i(error warn info debug).map {|k| [k, options["#{k}_io"]]}.to_h)
|
282
|
+
Baltix::Log.setup(options.log_level.to_sym, ios)
|
283
|
+
end
|
284
|
+
|
285
|
+
def show_tree
|
286
|
+
info("Sources:")
|
287
|
+
stat_source_tree.each do |(path_in, stated_sources)|
|
288
|
+
stated_sources.each do |(source, status)|
|
289
|
+
path = source.source_path_from(rootdir) if source.source_file
|
290
|
+
stat = [STATUS_CHARS[status], TYPE_CHARS[source.type.to_sym]].join(" ")
|
291
|
+
namever = [source.name, source.version].compact.join(":")
|
292
|
+
info_in = "#{stat}#{namever} [#{path}]"
|
293
|
+
|
294
|
+
info(info_in)
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
# returns all the sources with their statuses, and sorted by a its rootdir value
|
300
|
+
#
|
301
|
+
def stat_sources &block
|
302
|
+
return @stat_sources if @stat_sources
|
303
|
+
|
304
|
+
@stat_sources =
|
305
|
+
read_attribute(:stat_sources) || Baltix::Source.search_in(rootdir, options).group_by do |x|
|
306
|
+
[x.name, x.version].compact.join(":")
|
307
|
+
end.map do |(full_name, v)|
|
308
|
+
sorten =
|
309
|
+
v.sort do |x,y|
|
310
|
+
c0 = ::Baltix::Source.loaders.index(x.loader) <=> ::Baltix::Source.loaders.index(y.loader)
|
311
|
+
c1 = c0 == 0 && x.name <=> y.name || c0
|
312
|
+
c2 = c1 == 0 && y.version <=> x.version || c1
|
313
|
+
c3 = c2 == 0 && y.platform <=> x.platform || c2
|
314
|
+
c4 = c3 == 0 && y.source_names.grep(/gemspec/).count <=> x.source_names.grep(/gemspec/).count
|
315
|
+
|
316
|
+
c2 == 0 && c3 == 0 && c4 == 0 && x.rootdir.size <=> y.rootdir.size || c4 != 0 && c4 || c3 != 0 && c3 || c2
|
317
|
+
end.reduce([[], 0]) do |(res, index), source|
|
318
|
+
dup = source.valid? && index > 0
|
319
|
+
dup_index = source.valid? && index + 1 || index
|
320
|
+
|
321
|
+
[res | [[source, source_status(source, dup)]], dup_index]
|
322
|
+
end.first
|
323
|
+
|
324
|
+
sorten[1..-1].each { |x| sorten.first.first.alias_to(x.first) }
|
325
|
+
|
326
|
+
sorten
|
327
|
+
end.flatten(1).sort_by {|(x, _)| x.rootdir.size }.each do |(source, status)|
|
328
|
+
block[source, status] if block_given?
|
329
|
+
end
|
330
|
+
|
331
|
+
show_tree
|
332
|
+
|
333
|
+
@stat_sources
|
334
|
+
end
|
335
|
+
|
336
|
+
# returns source tree, and sorted, and then grouped by a its rootdir value
|
337
|
+
#
|
338
|
+
def stat_source_tree
|
339
|
+
@stat_source_tree ||=
|
340
|
+
stat_sources.group_by {|(x, _)| x.rootdir }.map do |(path, sources)|
|
341
|
+
[File.join('.', path[rootdir.size..-1] || ''), sources]
|
342
|
+
end.to_h
|
343
|
+
end
|
344
|
+
|
345
|
+
# returns status for the source for the project
|
346
|
+
#
|
347
|
+
def source_status source, dup
|
348
|
+
%i(valid duplicated disabled invalid).reduce() do |res, status|
|
349
|
+
STATES[status][self, source, dup] && status || res
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
def context
|
354
|
+
@context ||= options[:context] || spec&.context || {}
|
355
|
+
end
|
356
|
+
|
357
|
+
def method_missing method, *args
|
358
|
+
value =
|
359
|
+
instance_variable_get(:"@#{method}") ||
|
360
|
+
(spec.send(method) rescue nil) ||
|
361
|
+
options&.[](method) ||
|
362
|
+
spec&.options&.[](method.to_s) ||
|
363
|
+
state[method]
|
364
|
+
|
365
|
+
instance_variable_set(:"@#{method}", value || super)
|
366
|
+
|
367
|
+
value
|
368
|
+
end
|
369
|
+
|
370
|
+
class << self
|
371
|
+
def load string
|
372
|
+
if Gem::Version.new(Psych::VERSION) >= Gem::Version.new("4.0.0")
|
373
|
+
YAML.load(string,
|
374
|
+
aliases: true,
|
375
|
+
permitted_classes: [
|
376
|
+
Baltix::Source::Fake,
|
377
|
+
Baltix::Source::Rakefile,
|
378
|
+
Baltix::Source::Gemfile,
|
379
|
+
Baltix::Source::Gem,
|
380
|
+
Baltix::Spec::Rpm,
|
381
|
+
Baltix::Spec::Rpm::Name,
|
382
|
+
Baltix::Spec::Rpm::Secondary,
|
383
|
+
Gem::Specification,
|
384
|
+
Gem::Version,
|
385
|
+
Gem::Dependency,
|
386
|
+
Gem::Requirement,
|
387
|
+
OpenStruct,
|
388
|
+
Symbol,
|
389
|
+
Time,
|
390
|
+
Date
|
391
|
+
])
|
392
|
+
else
|
393
|
+
YAML.load(string)
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
397
|
+
def load_from! state: Dir[".space"].first, options: {}
|
398
|
+
# system_path_check # TODO required to generate spec rubocop
|
399
|
+
|
400
|
+
state_tmp =
|
401
|
+
case state
|
402
|
+
when IO, StringIO
|
403
|
+
load(state.readlines.join(""))
|
404
|
+
when String
|
405
|
+
raise InvalidSpaceFileError.new(state: state) if !File.file?(state)
|
406
|
+
|
407
|
+
load(IO.read(state))
|
408
|
+
when NilClass
|
409
|
+
else
|
410
|
+
raise InvalidSpaceFileError
|
411
|
+
end.to_os
|
412
|
+
|
413
|
+
@@space[state_tmp.name] = self.new(state_tmp, options)
|
414
|
+
end
|
415
|
+
|
416
|
+
def load_from state: Dir[".space"].first, options: {}
|
417
|
+
load_from!(state: state, options: options)
|
418
|
+
rescue InvalidSpaceFileError
|
419
|
+
@@space[nil] = new(nil, options)
|
420
|
+
end
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
require 'baltix/space/spec'
|
@@ -0,0 +1,155 @@
|
|
1
|
+
class Baltix::Spec::Rpm::Name
|
2
|
+
class InvalidAdoptedNameError < StandardError; end
|
3
|
+
class UnsupportedMatchError < StandardError; end
|
4
|
+
|
5
|
+
PREFICES = %w(gem ruby rubygem)
|
6
|
+
RULE = /^(?<full_name>(?:(?<prefix>#{PREFICES.join('|')})-)?(?<name>.*?))(?:-(?<suffix>doc|devel))?$/
|
7
|
+
|
8
|
+
attr_reader :name, :kind, :suffix
|
9
|
+
attr_accessor :support_name
|
10
|
+
|
11
|
+
def aliases
|
12
|
+
@aliases ||= []
|
13
|
+
end
|
14
|
+
|
15
|
+
def prefix
|
16
|
+
@prefix ||= kind == "lib" && self.class.default_prefix || nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.default_prefix
|
20
|
+
"gem"
|
21
|
+
end
|
22
|
+
|
23
|
+
def support_name= value
|
24
|
+
case @support_name = value
|
25
|
+
when NilClass
|
26
|
+
@kind = kind == "exec" && "app" || @kind
|
27
|
+
else
|
28
|
+
@kind = kind == "app" && "exec" || @kind
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def eql? other, deep = false
|
33
|
+
case other
|
34
|
+
when self.class
|
35
|
+
self.eql_by?(:kind, other) && self.eql_by?(:name, other)
|
36
|
+
when String, Symbol
|
37
|
+
(([ autoname, fullname ] | [ aliases ].flatten) & self.class.parse(other).aliases).any?
|
38
|
+
else
|
39
|
+
other.to_s == self.fullname
|
40
|
+
end || deep && self.eql_by?(:support_name, other)
|
41
|
+
end
|
42
|
+
|
43
|
+
def == other
|
44
|
+
eql?(other)
|
45
|
+
end
|
46
|
+
|
47
|
+
def === other
|
48
|
+
eql?(other)
|
49
|
+
end
|
50
|
+
|
51
|
+
def =~ re
|
52
|
+
to_s =~ re
|
53
|
+
end
|
54
|
+
|
55
|
+
def to_s
|
56
|
+
fullname
|
57
|
+
end
|
58
|
+
|
59
|
+
def merge other
|
60
|
+
options =
|
61
|
+
%w(prefix suffix name support_name kind).map do |prop|
|
62
|
+
[ prop.to_sym, other.send(prop) || self.send(prop) ]
|
63
|
+
end.to_h
|
64
|
+
|
65
|
+
self.class.new(options.merge(aliases: self.aliases | other.aliases))
|
66
|
+
end
|
67
|
+
|
68
|
+
def eql_by? value, other
|
69
|
+
case value
|
70
|
+
when :name
|
71
|
+
([ self.name, self.aliases ].flatten & [ other.name, other.aliases ].flatten).any?
|
72
|
+
when :kind
|
73
|
+
self.kind == other.kind
|
74
|
+
when :support_name
|
75
|
+
self.support_name === (other.is_a?(self.class) && other.support_name || other)
|
76
|
+
else
|
77
|
+
raise(UnsupportedMatchError.new)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# +fullname+ returns newly reconstructed adopted full name based on the storen data.
|
82
|
+
# All the "." and "_" is replaced with "-", and "ruby" prefix with "gem".
|
83
|
+
#
|
84
|
+
# name.fullname #=> "gem-foo-bar-baz-doc"
|
85
|
+
#
|
86
|
+
def fullname
|
87
|
+
[ autoprefix, autoname, autosuffix ].compact.join("-")
|
88
|
+
end
|
89
|
+
|
90
|
+
def original_fullname
|
91
|
+
[ prefix, name, suffix ].compact.join("-")
|
92
|
+
end
|
93
|
+
|
94
|
+
def autoprefix
|
95
|
+
%w(exec app).include?(kind) || %w(app).include?(support_name&.kind) ? nil : self.class.default_prefix
|
96
|
+
end
|
97
|
+
|
98
|
+
def autoname
|
99
|
+
name&.downcase&.gsub(/[\._]/, "-")
|
100
|
+
end
|
101
|
+
|
102
|
+
def autosuffix
|
103
|
+
%w(doc devel).include?(kind) && kind || nil
|
104
|
+
end
|
105
|
+
|
106
|
+
protected
|
107
|
+
|
108
|
+
def initialize options = {}
|
109
|
+
@aliases = options.fetch(:aliases, []) | options.fetch(:name, "").gsub(/[\.\_]+/, "-").split(",")
|
110
|
+
@prefix = options[:prefix]
|
111
|
+
@suffix = options[:suffix]
|
112
|
+
@name = options[:name]
|
113
|
+
@support_name = options[:support_name]
|
114
|
+
@kind = options[:kind] && options[:kind].to_s ||
|
115
|
+
@suffix ||
|
116
|
+
@prefix && "lib" ||
|
117
|
+
@support_name && "exec" || "app"
|
118
|
+
end
|
119
|
+
|
120
|
+
class << self
|
121
|
+
def parse name_in, options_in = {}
|
122
|
+
m, kind =
|
123
|
+
if name_in.is_a?(self)
|
124
|
+
[name_in.original_fullname.match(RULE), name_in.kind]
|
125
|
+
else
|
126
|
+
[name_in.match(RULE)]
|
127
|
+
end
|
128
|
+
|
129
|
+
aliases_in = (options_in[:aliases] || []).flatten.uniq
|
130
|
+
subaliases = aliases_in - [ m["full_name"] ]
|
131
|
+
#aliases = subaliases | [ m["full_name"] ]
|
132
|
+
|
133
|
+
raise(InvalidAdoptedNameError) if !m
|
134
|
+
|
135
|
+
prefixed = subaliases.size >= aliases_in.size
|
136
|
+
options = {
|
137
|
+
prefix: prefixed && m["prefix"] || nil,
|
138
|
+
#prefix: subaliases.blank? && m["prefix"] || nil,
|
139
|
+
#prefix: m["prefix"],
|
140
|
+
suffix: m["suffix"],
|
141
|
+
kind: kind,
|
142
|
+
#name: m["name"],
|
143
|
+
name: prefixed && m["name"] || m["full_name"],
|
144
|
+
#name: subaliases.blank? && m["name"] || m["full_name"],
|
145
|
+
}.merge(options_in).merge({
|
146
|
+
aliases: subaliases | [ m["full_name"] ]
|
147
|
+
})
|
148
|
+
|
149
|
+
options[:name] = options[:name].blank? && options[:aliases].first || options[:name]
|
150
|
+
#binding.pry if name_in =~ /ruby/
|
151
|
+
|
152
|
+
new(options)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|