baltix 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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