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,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