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,412 @@
1
+ class Baltix::Spec::Rpm::Parser
2
+ MATCHER = /^Name:\s+([^\s]+)/i
3
+
4
+ SCHEME = {
5
+ name: {
6
+ non_contexted: true,
7
+ regexp: /^Name:\s+([^\s]+)/i,
8
+ parse_func: :parse_name
9
+ },
10
+ version: {
11
+ non_contexted: true,
12
+ regexp: /Version:\s+([^\s]+)/i,
13
+ parse_func: :parse_version,
14
+ mode: :replace
15
+ },
16
+ epoch: {
17
+ non_contexted: true,
18
+ regexp: /Epoch:\s+([^\s]+)/i,
19
+ mode: :replace
20
+ },
21
+ release: {
22
+ non_contexted: true,
23
+ regexp: /Release:\s+([^\s]+)/i,
24
+ mode: :replace
25
+ },
26
+ summaries: {
27
+ regexp: /Summary(?:\(([^\s:]+)\))?:\s+([^\s].+)/i,
28
+ parse_func: :parse_summary,
29
+ mode: :replace
30
+ },
31
+ licenses: {
32
+ non_contexted: true,
33
+ regexp: /License:\s+([^\s].+)/i,
34
+ parse_func: :parse_license
35
+ },
36
+ group: /Group:\s+([^\s]+)/i,
37
+ uri: /Url:\s+([^\s]+)/i,
38
+ vcs: /Vcs:\s+([^\s]+)/i,
39
+ packager: {
40
+ non_contexted: true,
41
+ regexp: /Packager:\s+(.*)\s*(?:<(.*)>)$/i,
42
+ parse_func: :parse_packager
43
+ },
44
+ build_arch: /BuildArch:\s+([^\s]+)/i,
45
+ patches: {
46
+ non_contexted: true,
47
+ regexp: /Patch(\d+)?:\s+([^\s]+)/i,
48
+ parse_func: :parse_file
49
+ },
50
+ source_files: {
51
+ non_contexted: true,
52
+ regexp: /Source(\d+)?:\s+([^\s]+)/i,
53
+ parse_func: :parse_file
54
+ },
55
+ build_pre_requires: {
56
+ non_contexted: true,
57
+ regexp: /(?:BuildPreReq|BuildRequires\(pre\)):\s+([\w\s<=>\.\-_]+)/i,
58
+ parse_func: :parse_dep
59
+ },
60
+ build_requires: {
61
+ non_contexted: true,
62
+ regexp: /^BuildRequires:\s*([^#]+)/i,
63
+ parse_func: :parse_dep
64
+ },
65
+ obsoletes: {
66
+ regexp: /^Obsoletes:\s*([^#]+)/i,
67
+ parse_func: :parse_dep
68
+ },
69
+ provides: {
70
+ regexp: /^Provides:\s*([^#]+)/i,
71
+ parse_func: :parse_dep
72
+ },
73
+ requires: {
74
+ regexp: /^Requires:\s*([^#]+)/i,
75
+ parse_func: :parse_dep
76
+ },
77
+ conflicts: {
78
+ regexp: /^Conflicts:\s*([^#]+)/i,
79
+ parse_func: :parse_dep
80
+ },
81
+ ignored_names: {
82
+ non_contexted: true,
83
+ regexp: /(^%ruby_ignore|--ignore=)\s*([^\s$]+)/i,
84
+ parse_func: :parse_ignore
85
+ },
86
+ descriptions: {
87
+ regexp: /^%description\s*([^\s].*)?/i,
88
+ parse_func: :parse_description
89
+ },
90
+ secondaries: {
91
+ non_contexted: true,
92
+ regexp: /^%package\s+(.+)/i,
93
+ parse_func: :parse_secondary
94
+ },
95
+ prep: {
96
+ non_contexted: true,
97
+ regexp: /^%prep/i,
98
+ parse_func: :parse_plain_section
99
+ },
100
+ build: {
101
+ non_contexted: true,
102
+ regexp: /^%build/i,
103
+ parse_func: :parse_plain_section
104
+ },
105
+ install: {
106
+ non_contexted: true,
107
+ regexp: /^%install/i,
108
+ parse_func: :parse_plain_section
109
+ },
110
+ check: {
111
+ non_contexted: true,
112
+ regexp: /^%check/i,
113
+ parse_func: :parse_plain_section
114
+ },
115
+ file_list: {
116
+ regexp: /^%files\s*([^\s].*)?/i,
117
+ parse_func: :parse_file_list
118
+ },
119
+ changes: {
120
+ non_contexted: true,
121
+ regexp: /^%changelog/i,
122
+ parse_func: :parse_changes
123
+ },
124
+ context: {
125
+ non_contexted: true,
126
+ regexp: /^%(?:(?:global|define)|((?!description|package|files)[^\s]+))\s+(?:([^\s]+)\s+([^\s].*)|(.*))/i,
127
+ parse_func: :parse_context
128
+ },
129
+ comment: {
130
+ non_contexted: true,
131
+ parse_func: :parse_comment
132
+ }
133
+ }.to_os(hash: true)
134
+
135
+ def source source_in
136
+ if source_in.respond_to?(:readlines)
137
+ source_in.rewind
138
+ source_in.readlines
139
+ else
140
+ source_in.split("\n")
141
+ end
142
+ end
143
+
144
+ def parse source_in, options = {}
145
+ context = {}.to_os
146
+ matched = {}.to_os
147
+ match = nil
148
+ state_in = {
149
+ "context" => {
150
+ "__options" => options.to_os,
151
+ "__custom" => { 'gemname' => '%pkgname' }.to_os
152
+ }
153
+ }.to_os(hash: true)
154
+
155
+ state = source(source_in).reduce(state_in) do |state, line|
156
+ SCHEME.find do |key, rule|
157
+ match = rule.is_a?(Regexp) && rule.match(line) ||
158
+ rule.is_a?(OpenStruct) && rule[:regexp] && rule[:regexp].match(line)
159
+
160
+ if match
161
+ if matched.name
162
+ if matched.name != key
163
+ # binding.pry if matched[:match][0] =~ /description/
164
+ store_value(state, matched[:match], matched[:name], matched[:flow], context)
165
+ matched = { name: key.to_s, flow: "", match: match }.to_os
166
+ end
167
+ else
168
+ matched = { name: key.to_s, flow: "", match: match }.to_os
169
+ end
170
+ end
171
+ end
172
+
173
+ if matched.name
174
+ if matched.flow
175
+ matched.flow << line + "\n"
176
+ else
177
+ matched.flow = line + "\n"
178
+ end
179
+ else
180
+ matched = { name: "comment", flow: line + "\n", match: [] }.to_os
181
+ end
182
+
183
+ state
184
+ end
185
+
186
+ store_value(state, matched.match, matched.name, matched.flow, context)
187
+
188
+ #binding.pry
189
+ state
190
+ end
191
+
192
+ def store_value opts, match, key, flow, context
193
+ data = SCHEME[key]
194
+ rule = data.is_a?(OpenStruct) && data.rule || data
195
+ parse_func = data.is_a?(OpenStruct) && data.parse_func || :parse_default
196
+ non_contexted = data.is_a?(OpenStruct) && data.non_contexted
197
+ reflown = reeval(flow, opts)
198
+ rematched = match.to_a.map { |x| x.is_a?(String) && reeval(x, opts) || x }
199
+ value = method(parse_func)[rematched, reflown, opts, context]
200
+ mode = data.is_a?(OpenStruct) && data.mode || :append
201
+ copts = !non_contexted && context.name && opts.secondaries.find do |sec|
202
+ #binding.pry
203
+ sec.name == Baltix::Spec::Rpm::Name.parse(
204
+ context.name,
205
+ support_name: opts.name,
206
+ aliases: aliased_names(opts))
207
+ end || opts
208
+ #binding.pry if key =~ /summar/
209
+ #binding.pry if context[:kind]
210
+ if !non_contexted && context.kind && context.kind.to_s != copts["name"].kind
211
+ copts["name"] =
212
+ Baltix::Spec::Rpm::Name.parse(copts["name"].original_fullname,
213
+ kind: context.kind,
214
+ support_name: copts["name"].support_name)
215
+ end
216
+
217
+ copts[key] =
218
+ case copts[key]
219
+ when NilClass
220
+ value
221
+ when Array
222
+ copts[key] | [ value.is_a?(OpenStruct) && value || value ].flatten
223
+ when OpenStruct
224
+ copts[key].deep_merge(value, mode: mode)
225
+ else
226
+ value
227
+ end
228
+
229
+ #binding.pry if key =~ /summar/
230
+ opts
231
+ end
232
+
233
+ def secondary_for_context opts, context
234
+ opts.secondaries.find do |sec|
235
+ #binding.pry
236
+ sec.name == Baltix::Spec::Rpm::Name.parse(
237
+ context.name,
238
+ support_name: opts.name,
239
+ aliases: aliased_names(opts))
240
+ end
241
+ end
242
+
243
+ def reeval flow, opts
244
+ #binding.pry if flow =~ /%gemname/
245
+ [opts.context.__options, opts.context.__macros, opts, opts.context.__custom].compact.reduce(flow) do |reflown_in, source|
246
+ source.table.keys.sort_by {|x|x.size}.reverse.reduce(reflown_in) do |reflown, name|
247
+ next reflown if /context|__macros|__options/ =~ name
248
+ value = source[name]
249
+ #binding.pry if flow =~ /%gemname/ && name =~ /%gemname/
250
+ r = reflown.dup
251
+ r.gsub!(/%({#{name}}|#{name})/, value.to_s) && value.is_a?(String) && /^%/ =~ value ? reeval(r, opts) : r
252
+ end
253
+ end || raise #flow
254
+ end
255
+
256
+ def parse_name match, *_
257
+ Baltix::Spec::Rpm::Name.parse(match[1])
258
+ end
259
+
260
+ def parse_comment match, flow, *_
261
+ flow
262
+ end
263
+
264
+ def parse_file match, *_
265
+ { match[1] || "0" => match[2] }.to_os
266
+ end
267
+
268
+ def parse_file_list match, flow, opts, context
269
+ kind = {
270
+ lib: /ruby_gemspec|ruby_gemlibdir/,
271
+ doc: /ruby_gemdocdir/,
272
+ exec: /_bindir/,
273
+ }.find { |(k, re)| re =~ flow }&.[](0)
274
+ context.replace(parse_context_line(match[1], opts).merge(kind: kind))
275
+ splitten_flow(flow)
276
+ end
277
+
278
+ def parse_changes _, flow, *_
279
+ rows = flow.split("\n* ").map { |p| p.strip }.compact.map { |p| p.split("\n") }
280
+
281
+ rows[1..-1].map do |row|
282
+ /(?<date>^\w+\s+\w+\s+\w+\s+\w+)\s+(?<author>.*)\s*(?:<(?<email>.*)>)\s+(?:(?<epoch>[0-9]+):)?(?<version>[\w\.]+)(?:-(?<release>[\w\._]+))?$/ =~ row[0]
283
+
284
+ {
285
+ date: date,
286
+ author: author.strip,
287
+ email: email,
288
+ version: Gem::Version.new(version),
289
+ release: release,
290
+ epoch: epoch,
291
+ description: row[1..-1].join("\n")
292
+ }.to_os
293
+ end.reverse
294
+ end
295
+
296
+ def parse_dep match, *_
297
+ deps = match[1].scan(/[^\s]+(?:\s+[<=>]+\s+[^\s]+)?/)
298
+ deps.reject {|d| /^(gem|rubygem|ruby-gem)\(/ =~ d }
299
+ end
300
+
301
+ def parse_ignore match, *_
302
+ match[2].split(/,/).map {|x| x =~ /^\/(.*)/ && /#{$1}/ || x }
303
+ end
304
+
305
+ def parse_default match, *_
306
+ match[1]
307
+ end
308
+
309
+ def parse_plain_section _, flow, *_
310
+ splitten_flow(flow)
311
+ end
312
+
313
+ # secondary without suffix by default has kind of lib
314
+ def parse_secondary match, flow, opts, context
315
+ context.replace(parse_context_line(match[1], opts))
316
+ name = Baltix::Spec::Rpm::Name.parse(context.name, support_name: opts.name, aliases: aliased_names(opts))
317
+
318
+ [{ "name" => name, "version" => opts.version, "release" => opts.release, "summaries" => opts.summaries.dup }.to_os ]
319
+ end
320
+
321
+ def parse_description match, flow, opts, context
322
+ context.replace(parse_context_line(match[1], opts))
323
+ { context.cp || Baltix::I18n.default_locale => splitten_flow(flow) }.to_os
324
+ end
325
+
326
+ def parse_license match, *_
327
+ match[1].split(/(?: or |\/)/).map(&:strip)
328
+ end
329
+
330
+ def parse_summary match, _, opts, *_
331
+ opts.summary = match[2]
332
+ { match[1] || Baltix::I18n.default_locale => match[2] }.to_os
333
+ end
334
+
335
+ def parse_context match, *_
336
+ if match[1]
337
+ {
338
+ "__macros" => {
339
+ match[1] => match[4]&.strip || [match[2], match[3]].compact.join(" ").strip
340
+ }
341
+ }.to_os(hash: true)
342
+ elsif match[2]
343
+ {
344
+ "__macros" => {
345
+ match[2] => match[5]&.strip || [match[3], match[4]].compact.join(" ").strip
346
+ }
347
+ }.to_os(hash: true)
348
+ else
349
+ { match[3] => match[4] }.to_os
350
+ end
351
+ end
352
+
353
+ def parse_version match, *_
354
+ Gem::Version.new(match[1])
355
+ end
356
+
357
+ def parse_packager match, *_
358
+ OpenStruct.new(name: match[1]&.strip, email: match[2]&.strip)
359
+ end
360
+
361
+ def parse_context_line line, opts
362
+ key = nil
363
+ context = line.to_s.split(/\s+/).reduce({}.to_os) do |res, arg|
364
+ #binding.pry
365
+ case arg
366
+ when '-l'
367
+ key = :cp
368
+ when '-n'
369
+ key = :fullname
370
+ else
371
+ case key
372
+ when :cp
373
+ res.cp = arg
374
+ when :fullname
375
+ res.name = arg
376
+ else
377
+ res.name = "#{opts.name}-#{arg}"
378
+ end
379
+ end
380
+
381
+ res
382
+ end
383
+
384
+ if context.name
385
+ opts.secondaries ||= []
386
+ # name = Baltix::Spec::Rpm::Name.parse(context[:name])
387
+ # binding.pry
388
+ # sel = opts["secondaries"].select { |sec| sec.name == name }
389
+
390
+ # opts["secondaries"] << { "name" => name }.to_os if sel.blank?
391
+ end
392
+ # binding.pry
393
+
394
+ context
395
+ end
396
+
397
+ def aliased_names opts
398
+ opts.context.__options&.aliased_names
399
+ end
400
+
401
+ protected
402
+
403
+ def splitten_flow flow
404
+ (flow.split("\n")[1..-1] || []).join("\n")
405
+ end
406
+
407
+ class << self
408
+ def match? source_in
409
+ MATCHER =~ source_in
410
+ end
411
+ end
412
+ end
@@ -0,0 +1,170 @@
1
+ class Baltix::Spec::Rpm::Secondary
2
+ attr_reader :source, :spec, :host, :source
3
+
4
+ STATE = {
5
+ name: {
6
+ seq: %w(of_options of_source of_state of_default _name _local_rename),
7
+ default: "",
8
+ },
9
+ pre_name: {
10
+ seq: %w(of_options of_state of_default _pre_name),
11
+ default: "",
12
+ },
13
+ epoch: {
14
+ seq: %w(of_options of_state),
15
+ default: nil,
16
+ },
17
+ version: {
18
+ seq: %w(of_options of_source of_state of_default _version),
19
+ default: ->(_) { Time.now.strftime("%Y%m%d") },
20
+ },
21
+ release: {
22
+ seq: %w(of_options of_state _release),
23
+ default: "alt1",
24
+ },
25
+ build_arch: {
26
+ seq: %w(of_options of_state of_source),
27
+ default: "noarch",
28
+ },
29
+ summaries: {
30
+ seq: %w(of_options of_state of_source of_default _summaries),
31
+ default: ""
32
+ },
33
+ group: {
34
+ seq: %w(of_options _group),
35
+ default: ->(this) { Baltix::I18n.t("spec.rpm.#{this.kind}.group") },
36
+ },
37
+ requires: {
38
+ seq: %w(of_options of_state of_default _requires_plain_only _requires),
39
+ default: [],
40
+ },
41
+ conflicts: {
42
+ seq: %w(of_options of_state of_default _conflicts_plain_only _conflicts),
43
+ default: [],
44
+ },
45
+ provides: {
46
+ seq: %w(of_options of_state of_default _provides),
47
+ default: [],
48
+ },
49
+ obsoletes: {
50
+ seq: %w(of_options of_state of_default _obsoletes),
51
+ default: [],
52
+ },
53
+ file_list: {
54
+ seq: %w(of_options of_state of_source),
55
+ default: "",
56
+ },
57
+ compilables: {
58
+ seq: %w(of_options of_state of_source),
59
+ default: [],
60
+ },
61
+ descriptions: {
62
+ seq: %w(of_options of_state of_source of_default _proceed_description _descriptions _format_descriptions),
63
+ default: {}
64
+ },
65
+ readme: {
66
+ seq: %w(of_options of_source _readme of_state),
67
+ default: nil,
68
+ },
69
+ executables: {
70
+ seq: %w(of_options of_source of_state),
71
+ default: [],
72
+ },
73
+ docs: {
74
+ seq: %w(of_options _docs of_state),
75
+ default: nil,
76
+ },
77
+ devel: {
78
+ seq: %w(of_options _devel of_state),
79
+ default: nil,
80
+ },
81
+ devel_requires: {
82
+ seq: %w(of_options of_state _devel_requires),
83
+ default: nil,
84
+ },
85
+ devel_conflicts: {
86
+ seq: %w(of_options of_state _devel_conflicts),
87
+ default: nil,
88
+ },
89
+ devel_sources: {
90
+ seq: %w(of_options _devel_sources of_state),
91
+ default: [],
92
+ },
93
+ files: {
94
+ seq: %w(of_options _files of_state),
95
+ default: []
96
+ },
97
+ context: {
98
+ seq: %w(of_options of_state),
99
+ default: {},
100
+ },
101
+ dependencies: {
102
+ seq: %w(of_options of_state of_source),
103
+ default: []
104
+ },
105
+ gem_versionings: {
106
+ seq: %w(of_options of_state _gem_versionings),
107
+ default: []
108
+ },
109
+ available_gem_list: {
110
+ seq: %w(of_options of_state _available_gem_list),
111
+ default: {}
112
+ },
113
+ available_gem_ranges: {
114
+ seq: %w(of_options of_state _available_gem_ranges),
115
+ default: {}
116
+ },
117
+ use_gem_obsolete_list: {
118
+ seq: %w(of_options of_state),
119
+ default: {}.to_os
120
+ },
121
+ rootdir: {
122
+ seq: %w(of_options of_state),
123
+ default: nil
124
+ }
125
+ }.to_os(hash: true)
126
+
127
+ include Baltix::Spec::Rpm::SpecCore
128
+
129
+ def resourced_from secondary
130
+ @kind = secondary.kind.to_sym
131
+ @spec = secondary.spec
132
+ @source = secondary.source
133
+
134
+ self
135
+ end
136
+
137
+ def state_kind
138
+ return @state_kind if @state_kind
139
+
140
+ # binding.pry
141
+ @state_kind ||= options.source.is_a?(Baltix::Source::Gem) && "lib" || file_list.blank? && "app" || pre_name&.kind
142
+ end
143
+
144
+ def default_state_kind
145
+ "app"
146
+ end
147
+
148
+ def kind
149
+ @kind ||= source.is_a?(Baltix::Source::Gem) && :lib || :app
150
+ end
151
+
152
+ protected
153
+
154
+ def _group value_in
155
+ value_in || (is_exec? || is_app?) && of_state(:group)
156
+ end
157
+
158
+ def _release _value_in
159
+ spec.changes.last.release
160
+ end
161
+
162
+ def initialize spec: raise, source: nil, host: nil, kind: nil, state: {}, options: {}
163
+ @source = source
164
+ @spec = spec
165
+ @host = host
166
+ @kind = kind&.to_sym || self.kind
167
+ @state = state.to_os
168
+ @options = options.to_os
169
+ end
170
+ end