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.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ci.yml +44 -0
  3. data/.gitignore +10 -0
  4. data/Gemfile +8 -0
  5. data/LICENSE +8 -0
  6. data/README.md +60 -0
  7. data/Rakefile +8 -0
  8. data/TODO +84 -0
  9. data/baltix.gemspec +39 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +8 -0
  12. data/exe/baltix +4 -0
  13. data/lib/baltix/actor/copy.rb +19 -0
  14. data/lib/baltix/actor/link.rb +20 -0
  15. data/lib/baltix/actor/spec.rb +25 -0
  16. data/lib/baltix/actor/touch.rb +17 -0
  17. data/lib/baltix/actor.rb +75 -0
  18. data/lib/baltix/cli.rb +173 -0
  19. data/lib/baltix/deps.rb +280 -0
  20. data/lib/baltix/dsl.rb +311 -0
  21. data/lib/baltix/extensions.rb +536 -0
  22. data/lib/baltix/i18n.rb +64 -0
  23. data/lib/baltix/loader/cmake.rb +11 -0
  24. data/lib/baltix/loader/git-version-gen.rb +36 -0
  25. data/lib/baltix/loader/mast.rb +139 -0
  26. data/lib/baltix/loader/pom.rb +27 -0
  27. data/lib/baltix/loader/rookbook.rb +26 -0
  28. data/lib/baltix/loader/yaml.rb +18 -0
  29. data/lib/baltix/loader.rb +192 -0
  30. data/lib/baltix/log.rb +73 -0
  31. data/lib/baltix/rake.rb +57 -0
  32. data/lib/baltix/scheme.erb.yaml +20 -0
  33. data/lib/baltix/source/base.rb +438 -0
  34. data/lib/baltix/source/fake.rb +17 -0
  35. data/lib/baltix/source/gem.rb +407 -0
  36. data/lib/baltix/source/gemfile.rb +35 -0
  37. data/lib/baltix/source/rakefile.rb +24 -0
  38. data/lib/baltix/source.rb +57 -0
  39. data/lib/baltix/space/spec.rb +11 -0
  40. data/lib/baltix/space.rb +424 -0
  41. data/lib/baltix/spec/rpm/name.rb +155 -0
  42. data/lib/baltix/spec/rpm/parser.rb +412 -0
  43. data/lib/baltix/spec/rpm/secondary.rb +170 -0
  44. data/lib/baltix/spec/rpm/spec_core.rb +580 -0
  45. data/lib/baltix/spec/rpm.erb +188 -0
  46. data/lib/baltix/spec/rpm.rb +822 -0
  47. data/lib/baltix/spec.rb +48 -0
  48. data/lib/baltix/version.rb +3 -0
  49. data/lib/baltix.rb +19 -0
  50. data/locale/en_US.UTF-8.yaml +27 -0
  51. data/locale/ru_RU.UTF-8.yaml +23 -0
  52. metadata +216 -0
@@ -0,0 +1,407 @@
1
+ require 'bundler/dependency'
2
+ require 'tempfile'
3
+ require 'date'
4
+
5
+ require 'baltix/source/base'
6
+ require 'baltix/loader'
7
+ require 'baltix/loader/yaml'
8
+ require 'baltix/loader/pom'
9
+ require 'baltix/loader/rookbook'
10
+ require 'baltix/loader/cmake'
11
+ require 'baltix/loader/mast'
12
+ require 'baltix/loader/git-version-gen'
13
+
14
+ class Baltix::Source::Gem < Baltix::Source::Base
15
+ extend ::Baltix::Loader
16
+ extend ::Baltix::Loader::Yaml
17
+ extend ::Baltix::Loader::Pom
18
+ extend ::Baltix::Loader::Mast
19
+ extend ::Baltix::Loader::Rookbook
20
+ extend ::Baltix::Loader::Cmake
21
+ extend ::Baltix::Loader::GitVersionGen
22
+
23
+ TYPE = 'Gem::Specification'
24
+ BIN_IGNORES = %w(test)
25
+ OPTION_KEYS = %i(source_file source_names gemspec spec version replace_list aliases alias_names)
26
+
27
+ EXE_DIRS = ->(s) { s.spec.bindir || s.exedir || nil }
28
+ EXT_DIRS = ->(s) do
29
+ s.spec.extensions.map do |file|
30
+ File.dirname(file)
31
+ end.uniq
32
+ end
33
+ LIB_DIRS = ->(s) { s.require_pure_paths }
34
+ DOCSRC_DIRS = ->(s) { s.require_pure_paths }
35
+
36
+ INC_FILTER = ->(s, f, dir) { s.spec.files.include?(File.join(dir, f)) }
37
+
38
+ OPTIONS_IN = {
39
+ spec: true,
40
+ }
41
+
42
+ LOADERS = {
43
+ /\/pom.xml$/ => :pom,
44
+ /\/(cmake|CMakeLists.txt)$/ => :cmake,
45
+ /\/Rookbook.props$/ => :rookbook,
46
+ /\/GIT-VERSION-GEN$/ => :git_version_gen,
47
+ /\/(MANIFEST|Manifest.txt)$/ => :manifest,
48
+ /\/(#{Rake::Application::DEFAULT_RAKEFILES.join("|")})$/i => :app_file,
49
+ /\.gemspec$/i => [:app_file, :yaml],
50
+ }
51
+
52
+ attr_reader :gem_version_replace
53
+
54
+ Gem.load_yaml
55
+
56
+ class << self
57
+ def load spec_in
58
+ Kernel.yaml_load(spec_in)
59
+ end
60
+
61
+ def spec_for options_in = {}
62
+ spec_in = options_in["spec"]
63
+ spec = spec_in.is_a?(String) && load(spec_in) || spec_in
64
+ version =
65
+ if options_in[:version_replaces] && options_in[:version_replaces][spec.name]
66
+ options_in[:version_replaces][spec.name]
67
+ elsif options_in[:gem_version_replace] && !options_in[:gem_version_replace].empty?
68
+ prever = options_in[:gem_version_replace].find {|(n,v)| n == spec.name }&.last
69
+ /([=><]+\s*)?(?<version>.*)/ =~ prever
70
+ version
71
+ end
72
+
73
+ if version
74
+ spec.version = Gem::Version.new(version)
75
+ end
76
+ spec.require_paths = options_in["source-lib-folders"] if options_in["source-lib-folders"]
77
+
78
+ spec
79
+ end
80
+
81
+ def name_for options_in = {}
82
+ spec_for(options_in).name
83
+ end
84
+
85
+ def search dir, options_in = {}
86
+ files = Dir.glob("#{dir}/**/*", File::FNM_DOTMATCH).select {|f| File.file?(f) }.map do |f|
87
+ LOADERS.reduce(nil) { |res, (re, _method_name)| res || re =~ f && [re, f] || nil }
88
+ end.compact.sort do |x,y|
89
+ c = LOADERS.keys.index(x.first) <=> LOADERS.keys.index(y.first)
90
+
91
+ c == 0 && x.last <=> y.last || c
92
+ end
93
+
94
+ debug("Found source file list: " + files.map {|(_, x)| x }.join("\n\t"))
95
+
96
+ specs = files.reduce({}) do |res, (re, f)|
97
+ load_result =
98
+ [LOADERS[re]].flatten.reduce(nil) do |res, method_name|
99
+ next res if res
100
+
101
+ result = send(method_name, f)
102
+
103
+ result && result.objects.any? && [result, method_name]
104
+ end
105
+
106
+ if load_result
107
+ gemspecs = load_result.first.objects.reject do |s|
108
+ s.loaded_from && s.loaded_from !~ /#{dir}/
109
+ end.each {|x| x.loaded_from = f }.compact
110
+ debug("load messages:\n\t" + load_result.first.log.join("\n\t")) if !load_result.first.log.blank?
111
+ debug("Load errors:\n\t" + load_result.errlog.join("\n\t")) if !load_result.first.errlog.blank?
112
+
113
+ res.merge({ f => { gemspecs: gemspecs, loader: load_result.last }})
114
+ else
115
+ res
116
+ end
117
+ end.map do |(f, data)|
118
+ gemspecs = data[:gemspecs]
119
+ gemspecs.map do |gemspec|
120
+ self.new(source_options(options_in.merge(spec: gemspec, source_file: f, loader: data[:loader])))
121
+ end
122
+ end.flatten.compact
123
+ end
124
+ end
125
+
126
+ def gemfile
127
+ @gemfile ||= Baltix::Source::Gemfile.new({
128
+ source_file: gemfile_name && File.join(rootdir, gemfile_name) || dsl.fake_gemfile_path,
129
+ gem_version_replace: gem_version_replace,
130
+ gem_skip_list: [],# dsl.deps.map(&:name) | [name],
131
+ gem_append_list: [ self.dep ]}.to_os)
132
+ end
133
+
134
+ def gemfile_name
135
+ source_names.find {|x| x =~ /gemfile/i }
136
+ end
137
+
138
+ def dep
139
+ Bundler::Dependency.new("#{name}", Gem::Requirement.new(["~> #{version}"]), options: { type: :runtime })
140
+ end
141
+
142
+ def fullname
143
+ [ name, version ].compact.join('-')
144
+ end
145
+
146
+ def original_spec
147
+ return @original_spec if @original_spec.is_a?(Gem::Specification)
148
+
149
+ @original_spec =
150
+ if @original_spec.is_a?(String)
151
+ YAML.load(@original_spec)
152
+ else
153
+ self.class.spec_for(options)
154
+ end
155
+ end
156
+
157
+ def spec
158
+ return @spec if @spec
159
+
160
+ if aliases.any?
161
+ @spec ||= aliases.reduce(original_spec) { |spec, als|
162
+ spec.merge(als.original_spec) }
163
+ else
164
+ original_spec
165
+ end
166
+ end
167
+
168
+ def name
169
+ spec.name
170
+ end
171
+
172
+ def version
173
+ version = spec&.version&.to_s || "0"
174
+ parts = version.split(".")
175
+
176
+ (parts[0..2] + (parts[3..-1]&.map {|x| x.to_i <= 1024 && x || nil}&.compact || [])).join(".")
177
+ end
178
+
179
+ def gemspec_path
180
+ if @gemspec_file ||= Tempfile.create('gemspec.')
181
+ @gemspec_file.puts(dsl.to_ruby)
182
+ @gemspec_file.rewind
183
+ end
184
+
185
+ @gemspec_path ||= @gemspec_file.path
186
+ end
187
+
188
+ def gemfile_path
189
+ if gemfile.dsl.valid?
190
+ if @gemfile_file ||= Tempfile.create('Gemfile.')
191
+ @gemfile_file.puts(gemfile.dsl.to_gemfile)
192
+ @gemfile_file.rewind
193
+ end
194
+
195
+ @gemfile_path ||= @gemfile_file.path
196
+ end
197
+ end
198
+
199
+ # tree
200
+ def datatree
201
+ # TODO deep_merge
202
+ @datatree ||= super { { '.' => spec.files } }
203
+ end
204
+
205
+ def allfiles
206
+ @allfiles = (
207
+ spec.require_paths.map {|x| File.absolute_path?(x) && x || File.join(x, '**', '*') }.map {|x| Dir[x] }.flatten |
208
+ spec.executables.map {|x| Dir[File.join(spec.bindir, x)] }.flatten |
209
+ spec.files
210
+ )
211
+ end
212
+
213
+ def allfiles_for list_in
214
+ list_in.map do |(key, list)|
215
+ [key, list & allfiles.map {|x| /^#{key}\/(?<rest>.*)/.match(x)&.[](:rest) }.compact ]
216
+ end.to_h
217
+ end
218
+
219
+ def exttree
220
+ @exttree ||= super
221
+ end
222
+
223
+ def testtree
224
+ @testtree ||= allfiles_for(super)
225
+ end
226
+
227
+ def exetree
228
+ @exetree ||= super { Dir.chdir(rootdir) do
229
+ exedirs.map { |dir| [ dir, Dir.chdir(File.join(rootdir, dir)) { Dir.glob("{#{spec.executables.join(',')}}") } ] }.to_h
230
+ end }
231
+ end
232
+
233
+ def docsrctree
234
+ @docsrctree ||= super { { '.' => spec.extra_rdoc_files } }
235
+ end
236
+
237
+ def docs
238
+ # TODO make docs to docdir with lib/.rb replace to .ri
239
+ #require 'pry';binding.ry
240
+ (!spec.rdoc_options.blank? && [ default_ridir ] || files(:lib)) | spec.extra_rdoc_files
241
+ end
242
+
243
+ # custom
244
+
245
+ def extroot_for file
246
+ extroots.find { |extroot| extroot == file[0...extroot.size] }
247
+ end
248
+
249
+ # Queries
250
+
251
+ # +valid?+ returns state of validity of the gem: true or false
252
+ # Returns true when all the conditiona are true:
253
+ # * gem's name of the gem is set
254
+ # * gem's name is not a system's one (has zero char)
255
+ # * gem's version is present
256
+ # * gem's platform is "ruby" or current one
257
+ #
258
+ def valid?
259
+ !name.nil? &&
260
+ spec.version &&
261
+ (platform == 'ruby' || platform == Gem::Platform::CURRENT) &&
262
+ spec.name !~ /\u0000/
263
+ end
264
+
265
+ def platform
266
+ spec.platform
267
+ end
268
+
269
+ def compilable?
270
+ compilables.any?
271
+ end
272
+
273
+ def compilables
274
+ extfiles | spec.extensions
275
+ end
276
+
277
+ def to_h
278
+ # TODO !ruby/array:Files strangely appeared during building the securecompare gem, what leads to exceptions on load
279
+ super.merge(spec: spec.to_yaml.gsub(/!ruby\/array:Files/, ""))
280
+ end
281
+
282
+ def required_ruby_version
283
+ spec&.required_ruby_version || super
284
+ end
285
+
286
+ def required_rubygems_version
287
+ spec&.required_rubygems_version || super
288
+ end
289
+
290
+ def deps groups = nil
291
+ spec&.dependencies&.select { |dep| !groups || [ groups ].flatten.include?(dep.type) }
292
+ end
293
+
294
+ def require_pure_paths
295
+ @require_pure_paths ||= (
296
+ paths = spec.require_paths.select { |path| path !~ /^\// }
297
+ paths.any? && paths || ['lib'])
298
+ end
299
+
300
+ def rake
301
+ @rake ||= Baltix::Rake.new(File.join(rootdir, Dir["{#{Rake::Application::DEFAULT_RAKEFILES.join(",")}}"].first))
302
+ end
303
+
304
+ # Default group
305
+ def group
306
+ "Development/Ruby"
307
+ end
308
+
309
+ def summaries
310
+ localize(spec.summary) || aliased {|s| s.localize(s.summary) } || descriptions
311
+ end
312
+
313
+ def descriptions
314
+ localize(spec.description) || aliased {|s| localize(s.description) }
315
+ end
316
+
317
+ def aliased_locks
318
+ @aliased_locks ||= {}
319
+ end
320
+
321
+ def aliased &block
322
+ aliases.reduce(nil) {|res, a| res || a != self && block[a] }
323
+ end
324
+
325
+ def localize text
326
+ text && OpenStruct.new(Baltix::I18n.default_locale => text)
327
+ end
328
+
329
+ # Default prefix "gem" for gem names
330
+ def name_prefix
331
+ "gem"
332
+ end
333
+
334
+ def uri
335
+ spec.homepage || spec.metadata["homepage_uri"] || aliased_uri
336
+ end
337
+
338
+ def vcs
339
+ spec.metadata&.[]("source_code_uri")
340
+ end
341
+
342
+ def dependencies type = nil
343
+ (dsl.dependencies(type) | deps).group_by {|x| x.name }.reduce([]) do |res, (_name, deps)|
344
+ dep =
345
+ deps.reduce do |r, dep|
346
+ Gem::Dependency.new(r.name, r.requirement.merge(dep.requirement), [r.type, dep.type].max)
347
+ end
348
+
349
+ !type || dep.type == type ? res | [dep] : res
350
+ end
351
+ end
352
+
353
+ def provide
354
+ spec.version && Gem::Dependency.new(spec.name, Gem::Requirement.new(["= #{spec.version}"]), :runtime) || Gem::Dependency.new(spec.name)
355
+ end
356
+
357
+ def licenses
358
+ spec.licenses
359
+ end
360
+
361
+ protected
362
+
363
+ def detect_root
364
+ if spec
365
+ files = Dir['**/**/**']
366
+ (!spec.files.any? || (spec.files - files).any?) && super || Dir.pwd
367
+ else
368
+ super
369
+ end
370
+ end
371
+
372
+ def extroots
373
+ @extroots ||= extfiles.map { |extfile| File.dirname(extfile) }
374
+ end
375
+
376
+ def exedir
377
+ @exedir ||= if_exist('exe')
378
+ end
379
+
380
+ # system
381
+ def initialize options_in = {}
382
+ super
383
+
384
+ # @original_spec = self.class.spec_for(options_in)
385
+
386
+ gemfile
387
+ end
388
+
389
+ def with_lock &block
390
+ if !aliased_locks[name]
391
+ aliased_locks[name] = true
392
+ block[]
393
+ aliased_locks[name] = false
394
+ end
395
+ end
396
+
397
+ def method_missing name, *args
398
+ if /^aliased_(?<method>.*)/ =~ name
399
+ with_lock { aliased {|a| a.send(method, *args) } }
400
+ elsif spec.respond_to?(name)
401
+ spec.send(name, *args)
402
+ else
403
+ super
404
+ end
405
+ rescue NoMethodError
406
+ end
407
+ end
@@ -0,0 +1,35 @@
1
+ require 'baltix/dsl'
2
+ require 'baltix/source/base'
3
+
4
+ class Baltix::Source::Gemfile < Baltix::Source::Base
5
+ class << self
6
+ def search dir, options_in = {}
7
+ Dir.glob("#{dir}/**/Gemfile", File::FNM_DOTMATCH).select {|f| File.file?(f) }.map do |f|
8
+ self.new(source_options({ source_file: f, loader: :gemfile }.to_os.merge(options_in)))
9
+ end
10
+ end
11
+ end
12
+
13
+ def gemfile_path
14
+ gemspec_file = Tempfile.create('Gemfile.')
15
+ gemspec_file.puts(dsl.to_gemfile)
16
+ gemspec_file.rewind
17
+ gemspec_file.path
18
+ end
19
+
20
+ def dsl
21
+ @dsl ||=
22
+ Baltix::DSL.new(source_file,
23
+ replace_list: replace_list,
24
+ skip_list: (options[:gem_skip_list] || []) | [self.name],
25
+ append_list: options[:gem_append_list])
26
+ end
27
+
28
+ def valid?
29
+ dsl.valid?
30
+ end
31
+
32
+ def rake
33
+ @rake ||= Baltix::Rake.new(source_file)
34
+ end
35
+ end
@@ -0,0 +1,24 @@
1
+ require 'baltix/source/base'
2
+ require 'baltix/rake'
3
+
4
+ class Baltix::Source::Rakefile < Baltix::Source::Base
5
+ class << self
6
+ def search dir, options_in = {}
7
+ Dir.glob("#{dir}/**/Rakefile", File::FNM_DOTMATCH).select {|f| File.file?(f) }.map do |f|
8
+ self.new(source_options({ source_file: f, loader: :rakefile }.to_os.merge(options_in)))
9
+ end
10
+ end
11
+ end
12
+
13
+ def dsl
14
+ @dsl ||=
15
+ Baltix::DSL.new(source_file,
16
+ replace_list: replace_list,
17
+ skip_list: (options[:gem_skip_list] || []) | [self.name],
18
+ append_list: options[:gem_append_list])
19
+ end
20
+
21
+ def rake
22
+ @rake ||= Baltix::Rake.new(source_file)
23
+ end
24
+ end
@@ -0,0 +1,57 @@
1
+ require 'baltix'
2
+
3
+ module ::Baltix::Source
4
+ attr_reader :rootdir
5
+
6
+ TYPES =
7
+ %w(Gem Gemfile Rakefile Fake Base).reduce({}) do |types, name|
8
+ autoload(:"#{name}", File.dirname(__FILE__) + "/source/#{name.downcase}")
9
+ types.merge(name.downcase.to_sym => "Baltix::Source::#{name}")
10
+ end
11
+
12
+ class << self
13
+ def search_in dir_in, options = {}
14
+ dir = File.expand_path(dir_in)
15
+ sources_pre =
16
+ TYPES.map do |(name, const)|
17
+ kls = self.const_get(const)
18
+ kls.respond_to?(:search) && kls.search(dir, options) || []
19
+ end.flatten | [ self::Fake.new({ source_file: File.join(dir, '.fake') }.to_os) ]
20
+
21
+ sources_pre.group_by do |source|
22
+ source.rootdir
23
+ end.map do |_a, sources_in|
24
+ ina = sources_in.select {|s| TYPES.keys[-1] == s.class.to_s.split("::").last.downcase.to_sym }
25
+
26
+ TYPES.keys.reverse[1..-1].reduce(ina) do |res, kind|
27
+ selected =
28
+ sources_in.select do |s|
29
+ TYPES.keys[TYPES.keys.index(kind)] == s.class.to_s.split("::").last.downcase.to_sym
30
+ end
31
+
32
+ selected.any? && selected.map {|v| ([v] | res).reduce(&:+) } || res
33
+ end
34
+ end.flatten
35
+ end
36
+
37
+ def load_from sources_in
38
+ [ sources_in ].flatten.compact.map do |source_in|
39
+ type_code_in = source_in["type"].to_s.to_sym
40
+ type_code = TYPES.keys.include?(type_code_in) && type_code_in || :fake
41
+ require("baltix/source/#{type_code}")
42
+ TYPES[type_code].constantize.new(source_in)
43
+ end
44
+ end
45
+
46
+ def loaders
47
+ @loaders ||=
48
+ TYPES.map do |type, mod|
49
+ if mod.constantize.constants.include?(:LOADERS)
50
+ mod.constantize.const_get(:LOADERS).values
51
+ else
52
+ type
53
+ end
54
+ end.flatten.uniq
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,11 @@
1
+ module Baltix::Space::Spec
2
+ class << self
3
+ def load_from source_in, options = nil
4
+ space = Baltix::Space.new(options: options)
5
+ spec = Baltix::Spec.load_from(source: source_in, space: space)
6
+ space.spec = spec
7
+
8
+ space
9
+ end
10
+ end
11
+ end