sysbuild 1.0.3

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1440cdd35744897e112ced48488483835498f109
4
+ data.tar.gz: bfb8141d839c9e29340f393819c6f04e56cd1359
5
+ SHA512:
6
+ metadata.gz: 13090879de8c29e72eaf41096fabc5dd3478d5c9443514ebce6086e091c3fb0980a861a5d7abf25798b0120a7c1dcccc05fb4ee6331d54f58ae8414698d3fb8d
7
+ data.tar.gz: 977341327f82505a222fb0d3ae66a84f943712cc8fd8514e55b66092358a6f960e84960aeb627d60d198527f9fc29a621f8f81fd23f8a2c4326a19037802f0a0
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ /.idea
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ sysbuild-dev
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.3.0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in sysbuild.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,36 @@
1
+ # Sysbuild
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/sysbuild`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'sysbuild'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install sysbuild
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/sysbuild.
36
+
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
data/bin/sysbuild ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ require 'require_all'
3
+ require_rel '../lib'
4
+
5
+ app = Sysbuild_Main.new
6
+ app.main
data/doc/snippets ADDED
@@ -0,0 +1,5 @@
1
+ gem nexus pkg/sysbuild-1.0.3.gem
2
+
3
+ Install:
4
+
5
+ gem install -N -s http://jhawksley:jh96809486@www.hawksley.net:8081/repository/gems-hosted sysbuild
@@ -0,0 +1,107 @@
1
+ module Constants
2
+ TYPE_BOTH = "both"
3
+ TYPE_POM = "pom"
4
+ TYPE_MVN = "mvn"
5
+ TYPE_MVN_18 = "mvn18"
6
+
7
+ HASH_FOLDER = '.sysbuild/hashes'
8
+ end
9
+
10
+ require 'fileutils'
11
+ require 'digest'
12
+
13
+ class ChangeDetector
14
+
15
+
16
+ def initialize(source:, type: Constants::TYPE_BOTH)
17
+
18
+ @source_directory = source
19
+ raise "Change type #{type} unknown." unless [Constants::TYPE_BOTH, Constants::TYPE_POM, Constants::TYPE_MVN, Constants::TYPE_MVN_18].include? type
20
+ @type = type
21
+
22
+ end
23
+
24
+ def changed?
25
+
26
+ begin
27
+ cwd = `pwd`.strip!
28
+ Dir.chdir @source_directory
29
+
30
+ changed = pom_check
31
+
32
+ # If there is still no change registered, the pom was okay - check the file system.
33
+
34
+ if (! @type.eql? Constants::TYPE_POM )
35
+ changed = fs_check unless changed
36
+ end
37
+
38
+ changed
39
+ ensure
40
+ Dir.chdir cwd
41
+ end
42
+ end
43
+
44
+ def pom_check
45
+ # See if there's a hash for the pom. If not, create one.
46
+
47
+ changed = false
48
+
49
+ sha256 = Digest::SHA256.file 'pom.xml'
50
+
51
+ if !(File.exists?(Constants::HASH_FOLDER)) || !(File.exists?("#{Constants::HASH_FOLDER}/pom.xml.sha256"))
52
+ FileUtils::mkdir_p Constants::HASH_FOLDER
53
+ open("#{Constants::HASH_FOLDER}/pom.xml.sha256", 'w') {|f| f << sha256}
54
+ changed = true
55
+ else
56
+
57
+ loaded_hash = File.read("#{Constants::HASH_FOLDER}/pom.xml.sha256")
58
+
59
+ if (!(loaded_hash.to_s.eql? sha256.to_s))
60
+ open("#{Constants::HASH_FOLDER}/pom.xml.sha256", 'w') {|f| f << sha256}
61
+ changed = true
62
+ end
63
+ end
64
+
65
+ changed
66
+ end
67
+
68
+ def fs_check
69
+ return true if !File.exist?("target")
70
+
71
+ # get the newest file in the target folder
72
+
73
+ newest_target = nil
74
+
75
+ Find.find("target") do |path|
76
+ if (path.end_with?('jar')|| path.end_with?('zip'))
77
+ file = File.new(path)
78
+ newest_target = file if !newest_target
79
+ newest_target = file if file.mtime > newest_target.mtime
80
+ end
81
+ end
82
+
83
+ if !newest_target
84
+ return true
85
+ end
86
+
87
+ # puts "Newest target in #{Dir.pwd} is #{newest_target.path} => #{newest_target.mtime}"
88
+
89
+ #get the newest file in the source folder.
90
+
91
+ newest_source = nil
92
+
93
+ Find.find("src") do |path|
94
+ file = File.new(path)
95
+ newest_source = file if !newest_source
96
+ newest_source = file if file.mtime > newest_source.mtime
97
+ end
98
+
99
+ # puts "Newest source in #{Dir.pwd} is #{newest_source.path} => #{newest_source.mtime}"
100
+ # puts
101
+
102
+ newest_target.mtime < newest_source.mtime
103
+
104
+ end
105
+
106
+
107
+ end
data/lib/sysbuild.rb ADDED
@@ -0,0 +1,680 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # vim: ts=2:sw=2
4
+ #
5
+
6
+ # Required Gems
7
+ # ruby-terminfo
8
+ # open4
9
+ # paint
10
+ # fileutils
11
+ #
12
+ # gem install ruby-terminfo open4 paint fileutils nokogiri text-table
13
+
14
+ # https://github.com/janlelis/paint
15
+ require 'paint'
16
+
17
+ # http://rubydoc.info/gems/ruby-terminfo/0.1.1/frames
18
+ require 'terminfo'
19
+ require 'yaml'
20
+
21
+ # https://github.com/ahoward/open4
22
+ require 'open4'
23
+
24
+ require 'fileutils'
25
+ require 'nokogiri'
26
+ require 'text-table'
27
+ require 'ruby-progressbar'
28
+
29
+ # BUILTINS
30
+ require 'optparse'
31
+ require 'pp'
32
+ require 'tempfile'
33
+ require 'find'
34
+
35
+ class Sysbuild_Main
36
+
37
+
38
+ # COLOUR CONSTANTS
39
+
40
+ COL_SEPARATOR = 'ivory'
41
+ COL_TITLE = 'ivory2'
42
+ COL_VERSION = 'tan'
43
+ COL_SUBTITLE = 'ivory3'
44
+ COL_OUTPUT = 'ivory3'
45
+
46
+ COL_NORMAL = 'RoyalBlue'
47
+ COL_ERROR = 'red'
48
+ COL_HARD_ERROR = 'firebrick4'
49
+
50
+ COL_WARN = "yellow"
51
+
52
+ COL_HEADER = "yellow"
53
+
54
+ JAVA_18 = "JAVA_HOME=#{`/usr/libexec/java_home -v 1.8`.strip} PATH=#{`/usr/libexec/java_home -v 1.8`.strip}/bin:$PATH"
55
+ JAVA_17 = "JAVA_HOME=#{`/usr/libexec/java_home -v 1.7`.strip} PATH=#{`/usr/libexec/java_home -v 1.7`.strip}/bin:$PATH"
56
+
57
+
58
+ # ===========================================================================
59
+ # Main methods
60
+ # ===========================================================================
61
+
62
+ def main
63
+ start_time = Time.now
64
+
65
+ trap "SIGINT" do
66
+ exit 130
67
+ end
68
+
69
+ @script_args = Array.new(ARGV) # copy this because they seem to be consumed by optparser
70
+ @script_name = $0
71
+
72
+ # Set up some constants
73
+ @width = TermInfo.screen_size[1]
74
+ @separator = '-' * @width
75
+ @progname = 'sysbuild - modular system builder'
76
+
77
+ @options = {}
78
+ @options[:operation] = 'build'
79
+ @options[:specfile] = 'sysbuild.yaml'
80
+ @options[:clean] = false
81
+ @options[:partial] = nil
82
+ @options[:quiet] = true
83
+ @options[:inhibit_stages] = false
84
+
85
+ @valid_operations = %w"build distro check scm scm2"
86
+
87
+ @local_repo = get_local_repo
88
+
89
+ banner
90
+ setup_optparser
91
+ load_spec
92
+
93
+ case @options[:operation]
94
+ when 'build'
95
+ do_build
96
+ when 'distro'
97
+ do_distro
98
+ when 'check'
99
+ do_check
100
+ when 'scm'
101
+ do_scm
102
+ when 'scm2'
103
+ do_scm2
104
+ end
105
+
106
+ puts
107
+ completion_message = "Build complete. Elapsed time: #{(Time.now - start_time).to_i}s";
108
+ puts Paint[completion_message, COL_NORMAL]
109
+
110
+ # If on Mac, and osascript is available, fire a desktop notification
111
+ if File.executable?("/usr/bin/osascript")
112
+ subtitle = "#{@script_name} #{@script_args.join(' ')}"
113
+ system "/usr/bin/osascript -e 'display notification \"#{completion_message}\" with title \"Sysbuild\" subtitle \"#{subtitle}\"'"
114
+ end
115
+
116
+ end
117
+
118
+
119
+ def load_spec
120
+ # attempt to load the spec from @options[:specfile]
121
+ #
122
+ unless File.exists?(@options[:specfile]) && File.readable?(@options[:specfile])
123
+ abort "Couldn't load the system specification file #{@options[:specfile]}"
124
+ end
125
+
126
+
127
+ @spec = YAML.load_file(@options[:specfile])
128
+ @base_location = File.dirname( File.absolute_path( @options[:specfile] ) )
129
+
130
+ # Find the build target for the deploy goal
131
+ @target_list ||= 'fusionreactor-agent'
132
+ end
133
+
134
+
135
+ def setup_optparser
136
+ @opt_parser = OptionParser.new do |opt|
137
+ opt.on('-p', '--partial [list]', 'Comma-separated list of partial build targets') do |list|
138
+ abort '-p: A list of build targets must be supplied.' unless list
139
+ @options[:partial] = list.split(',')
140
+ end
141
+
142
+ opt.on('-d', '--detect-changes [list]', 'Causes the script to attempt to identify projects with changes, and build those.') do |list|
143
+ @options[:detect] = true
144
+ @options[:clean] = true
145
+ @options[:always_build] = list.split(',') if list
146
+ end
147
+
148
+ opt.on('-c', '--clean', 'Clean build target areas before building') do
149
+ @options[:clean] = true
150
+ end
151
+
152
+ opt.on('-n', '--no-build-stages', 'Don\'t run pre and post build stages, if specified.') do
153
+ @options[:inhibit_stages] = true
154
+ end
155
+
156
+ opt.on('-s', '--systemspec [FILE]', 'A yaml file containing the system spec (default sysbuild.yaml)') do |spec|
157
+ abort '-s: A system spec file must be provided.' unless spec
158
+ @options[:specfile] = spec
159
+ end
160
+
161
+ opt.on('-o', '--operation [OPER]', 'An operation: build, distro, check, scm') do |oper|
162
+ abort '-o: An operation must be specified' unless oper
163
+ @options[:operation] = oper
164
+ abort "-o: Operation #{oper} is not valid" unless @valid_operations.include?(oper)
165
+ end
166
+ end
167
+
168
+ @opt_parser.parse!
169
+ end
170
+
171
+ # ===========================================================================
172
+ # Command: Check
173
+ # ===========================================================================
174
+
175
+
176
+ def do_check
177
+ puts Paint['Checking structure.', COL_NORMAL]
178
+
179
+ @spec['modules'].each do |mod|
180
+ if !directory_exists?(mod.keys[0])
181
+ puts Paint[" Missing: #{mod.keys[0]}", COL_ERROR]
182
+ end
183
+ end
184
+ end
185
+
186
+ # ===========================================================================
187
+ # Command: SCM
188
+ # ===========================================================================
189
+
190
+ def do_scm
191
+ puts Paint['Performing SCM check.', COL_NORMAL]
192
+
193
+ @spec['modules'].each do |mod|
194
+ puts Paint["\n Checking: #{mod.keys[0]}", COL_NORMAL]
195
+ command = "svn status -u #{mod.keys[0]}"
196
+ pid, stdin, stdout, stderr = Open4::popen4 command
197
+ Process::waitpid2 pid
198
+ doc = stdout.read.strip
199
+ doc.lines do |line|
200
+ print Paint[" #{line}", COL_OUTPUT]
201
+ end
202
+
203
+ puts
204
+ end
205
+ end
206
+
207
+
208
+ # ===========================================================================
209
+ # Command: SCM2
210
+ # ===========================================================================
211
+
212
+
213
+ def do_scm2
214
+ puts Paint['Checking for SCM Changes.', COL_NORMAL]
215
+ puts
216
+
217
+
218
+ @spec['modules'].each do |mod|
219
+
220
+ result = `svn status --xml -u #{mod.keys[0]}`
221
+
222
+ doc = Nokogiri::XML(result)
223
+ doc.remove_namespaces!
224
+
225
+ change_entries = get_changes(doc)
226
+
227
+ if change_entries.length > 0
228
+
229
+ puts Paint["#{mod.keys[0]}", COL_NORMAL, :bright, :italic]
230
+
231
+ table = Text::Table.new :horizontal_padding => 1,
232
+ :vertical_boundary => '-',
233
+ :horizontal_boundary => '|',
234
+ :boundary_intersection => ' '
235
+
236
+ table.head = ['WC', 'Repo', 'Rev', 'Auth', 'Path']
237
+
238
+ change_entries.each do |entry|
239
+ path = entry.xpath('@path').to_s
240
+ path = path[path.index('/')..-1]
241
+
242
+ wc_status = entry.xpath('wc-status/@item').to_s
243
+ wc_revision = entry.xpath('wc-status/@revision').to_s
244
+ commit_revision = entry.xpath('wc-status/commit/@revision').to_s
245
+ commit_author = entry.xpath('wc-status/commit/author/text()').to_s
246
+ commit_date_s = entry.xpath('wc-status/commit/date/text()').to_s
247
+
248
+ repo_status_ns = entry.xpath('repos-status/@item')
249
+ repo_status = repo_status_ns.length > 0 ? repo_status_ns.to_s : "ok"
250
+
251
+ #puts " #{wc_status} #{wc_revision} (#{commit_author}) #{repo_status} #{path}"
252
+ #puts " #{status_to_symbol(wc_status)} #{wc_revision if repo_status != 'ok'} #{commit_author if repo_status != 'ok'} #{repo_status} #{path}"
253
+
254
+ # WC-STATUS # REPO STATUS #COMMIT-REV #COMMIT-AUTH #PATH
255
+
256
+ table.rows << [status_to_symbol(wc_status), status_to_symbol(repo_status), commit_revision, commit_author, path]
257
+
258
+ end
259
+
260
+ puts table.to_s
261
+
262
+ # abort
263
+
264
+ end
265
+ end
266
+
267
+ end
268
+
269
+ def get_changes(doc)
270
+ changes = doc.xpath('/status/target/entry')
271
+ clc = doc.xpath('/status/changelist/entry')
272
+
273
+ if clc.length > 0
274
+ clc.each do |c|
275
+ changes << c
276
+ end
277
+ end
278
+
279
+ changes.to_a.sort! do |a, b|
280
+
281
+ r_a = a.xpath('wc-status/commit/@revision').to_s.to_i
282
+ r_b = b.xpath('wc-status/commit/@revision').to_s.to_i
283
+
284
+ r_a <=> r_b
285
+
286
+ end
287
+
288
+ end
289
+
290
+
291
+ def status_to_symbol(status)
292
+ case status
293
+ when 'normal'
294
+ return ''
295
+ when 'none'
296
+ return '*'
297
+ when 'modified'
298
+ return 'M'
299
+ when 'ok'
300
+ return ''
301
+ when 'deleted'
302
+ return 'D'
303
+ when 'added'
304
+ return 'A'
305
+ when 'unversioned'
306
+ return 'X'
307
+ else
308
+ return "[#{status}]"
309
+ end
310
+ end
311
+
312
+
313
+ # ===========================================================================
314
+ # Command: Build and Change Detection
315
+ # ===========================================================================
316
+
317
+ def directory_exists?(directory)
318
+ File.directory?(directory)
319
+ end
320
+
321
+
322
+ def detect_changes
323
+
324
+ puts Paint["Detecting changes.", COL_NORMAL]
325
+
326
+ changed_projects = Array.new
327
+
328
+ @options[:partial] = changed_projects
329
+
330
+ progressbar = ProgressBar.create(:total => @spec['modules'].count,
331
+ :format => "%a %b\u{15E7}%i %p%% %e",
332
+ :progress_mark => ' ',
333
+ :remainder_mark => "\u{FF65}")
334
+
335
+ @spec['modules'].each do |mod|
336
+
337
+ progressbar.increment
338
+
339
+ name = mod.keys[0]
340
+ type = mod[name]
341
+
342
+ cd = ChangeDetector.new(source: name, type: type)
343
+
344
+ if cd.changed?
345
+ changed_projects << name
346
+ end
347
+
348
+ end
349
+
350
+ if changed_projects.length > 0
351
+
352
+ if (@options[:always_build])
353
+
354
+ @options[:always_build].each do |mod|
355
+ changed_projects << mod if !changed_projects.include?(mod)
356
+ end
357
+ end
358
+
359
+ return true
360
+
361
+ end
362
+
363
+ return false
364
+ end
365
+
366
+
367
+ def get_target_type(name)
368
+
369
+ pom = "#{name}/pom.xml"
370
+
371
+ doc = Nokogiri::XML(File.open(pom))
372
+ doc.remove_namespaces!
373
+ packaging = doc.xpath("/project/packaging/text()")
374
+
375
+ if !packaging || packaging.length == 0
376
+ packaging = 'jar'
377
+ end
378
+
379
+ packaging.to_s
380
+ end
381
+
382
+
383
+ def pom_requires_build?(name)
384
+
385
+ pom_file = File.new("#{name}/pom.xml")
386
+
387
+ # Generate effective pom - pom might have properties from super pom.
388
+ out = `cd #{name} && mvn help:effective-pom -Doutput=/tmp/ep.pom && cd ..`
389
+ pom_doc = File.open("/tmp/ep.pom") { |f| Nokogiri::XML(f) }
390
+
391
+ `rm /tmp/ep.pom`
392
+
393
+ pom_doc.remove_namespaces!
394
+
395
+ group_id = pom_doc.xpath("/project/groupId/text()").to_s
396
+ artifact_id = pom_doc.xpath("/project/artifactId/text()").to_s
397
+ version = pom_doc.xpath("/project/version/text()").to_s
398
+
399
+ repo_name = "#{artifact_id}-#{version}.pom"
400
+
401
+ candidate = "#{@local_repo}/#{group_id.tr('.', '/')}/#{artifact_id}/#{version}/#{repo_name}"
402
+
403
+ begin
404
+ repo_file = File.new(candidate)
405
+ # puts "#{repo_file.path} #{repo_file.mtime} <> #{pom_file.path} #{pom_file.mtime}"
406
+ return repo_file.mtime < pom_file.mtime
407
+ rescue Errno::ENOENT
408
+ # Not in local repo - needs building.
409
+ return true
410
+ rescue Exception => e
411
+ puts e.message
412
+ puts e.backtrace.inspect
413
+ return false
414
+ end
415
+ end
416
+
417
+
418
+
419
+ def do_build
420
+
421
+ current_dir = `pwd`.strip!
422
+
423
+ Dir.chdir(@base_location)
424
+
425
+ begin
426
+ if @options[:detect]
427
+ changes = detect_changes # puts changes into :partial
428
+ if !changes
429
+ puts Paint["No changes detected.", COL_NORMAL]
430
+ return
431
+ end
432
+ end
433
+
434
+ build_string = "Building #{@options[:partial] ? 'partial' : 'the full'} system."
435
+
436
+ do_stage(@spec['pre-build']) unless @options[:inhibit_stages]
437
+
438
+ puts Paint[build_string, COL_NORMAL]
439
+
440
+ if @options[:partial]
441
+ @options[:partial].each do |mod|
442
+ puts Paint[' ' << mod, COL_OUTPUT]
443
+ end
444
+
445
+ puts
446
+
447
+ @options[:partial].each do |mod|
448
+ build_single(mod)
449
+ end
450
+ else
451
+ # Build everything
452
+ puts
453
+ @spec['modules'].each do |modmap|
454
+ build_single(modmap)
455
+ end
456
+ end
457
+
458
+ do_stage(@spec['post-build']) unless @options[:inhibit_stages]
459
+
460
+ rescue Exception => e
461
+
462
+ puts e.message
463
+ puts e.backtrace.inspect
464
+
465
+ ensure
466
+
467
+ Dir.chdir( current_dir )
468
+
469
+ end
470
+ end
471
+
472
+
473
+ def build_single(something)
474
+ if something.kind_of?(String)
475
+ # look it up out of the spec.
476
+ modspec = lookup(something)
477
+ abort "Specified module \'#{something}\' not found in #{@options[:specfile]}" unless modspec
478
+ else
479
+ modspec = something
480
+ end
481
+
482
+ splits = modspec.values[0].split(' ')
483
+ buildtype = splits[0]
484
+
485
+ case buildtype
486
+ when 'mvn18'
487
+ build_maven(modspec.keys[0], JAVA_18)
488
+ when 'pom'
489
+ build_maven(modspec.keys[0], JAVA_17)
490
+ when 'mvn'
491
+ build_maven(modspec.keys[0], JAVA_17)
492
+ when 'gradle_libinstall'
493
+ build_gradle(modspec.keys[0], type: 'install')
494
+ when 'gradle'
495
+ build_gradle(modspec.keys[0])
496
+ else
497
+ abort "Build type #{buildtype} not supported."
498
+ end
499
+ end
500
+
501
+ def build_gradle(mod, type: 'build')
502
+
503
+ puts Paint["Gradle building #{mod}", COL_NORMAL]
504
+
505
+ if (type == 'build')
506
+ command = "cd #{mod} && gradle clean build -PuseLocalMavenRepo && cd .."
507
+ elsif (type == 'install')
508
+ command = "cd #{mod} && gradle clean install -PuseLocalMavenRepo && cd .."
509
+ end
510
+
511
+ pid, stdin, stdout, stderr = Open4::popen4 command
512
+
513
+ ignored, status = Process::waitpid2 pid
514
+
515
+ unless status.exitstatus == 0
516
+ abort ['Command returned nonzero status',
517
+ " command: #{command}",
518
+ " stdout: " << stdout.gets(sep=nil).to_s,
519
+ " stderr: " << stderr.gets(sep=nil).to_s]
520
+ end
521
+
522
+ end
523
+
524
+
525
+ def build_maven(mod, env='')
526
+
527
+ clean_flag = @options[:clean] ? '[clean]' : '[incremental]'
528
+
529
+ puts Paint["Maven building #{clean_flag} #{mod}", COL_NORMAL]
530
+
531
+ command = "cd #{mod} && #{env} mvn "
532
+
533
+ command << '-U ' if @options[:clean]
534
+
535
+ command << '-q ' if @options[:quiet]
536
+ command << '-DskipTests=true -Dskip.tests=true -Dmaven.test.skip -DskipITs '
537
+ command << 'clean ' if @options[:clean]
538
+ command << 'install'
539
+
540
+ command << ' && cd ..'
541
+
542
+ pid, stdin, stdout, stderr = Open4::popen4 command
543
+
544
+ ignored, status = Process::waitpid2 pid
545
+
546
+ unless status.exitstatus == 0
547
+ abort ['Command returned nonzero status',
548
+ " command: #{command}",
549
+ " stdout: " << stdout.gets(sep=nil).to_s,
550
+ " stderr: " << stderr.gets(sep=nil).to_s]
551
+ end
552
+ end
553
+
554
+
555
+ # ===========================================================================
556
+ # Build Stage
557
+ # ===========================================================================
558
+
559
+
560
+ def do_stage(text)
561
+ if text
562
+ file = Tempfile.new('sysbuild')
563
+ file.write text
564
+ file.close
565
+ FileUtils.chmod 0700, file.path
566
+ system(file.path)
567
+ file.unlink
568
+ end
569
+ end
570
+
571
+ # ===========================================================================
572
+ # Command: Distro
573
+ # ===========================================================================
574
+
575
+ def do_distro
576
+
577
+ puts Paint['Distributing build product', COL_NORMAL]
578
+
579
+ do_stage(@spec['pre-distro']) unless @options[:inhibit_stages]
580
+
581
+ # Load the distributions from the specfile.
582
+
583
+ @spec['distributions'].each do |map|
584
+ map.each do |location, type|
585
+
586
+ case type
587
+ when 'single'
588
+ distribute_single(location)
589
+ when 'multiple'
590
+ distribute_multiple(location)
591
+ end
592
+ end
593
+ end
594
+
595
+ do_stage(@spec['post-distro']) unless @options[:inhibit_stages]
596
+ end
597
+
598
+
599
+ # The build_product must be a list of files to distribute.
600
+ def distribute_single(location)
601
+ puts Paint[" Distribute to: #{location}", COL_NORMAL]
602
+
603
+ if !File.directory?(location)
604
+ puts Paint[" * Warning: location is not a directory - skipped.", COL_ERROR]
605
+ return
606
+ end
607
+
608
+
609
+ #Copy the build product to the location
610
+
611
+ unless File.exists?(location) && File.writable?(location)
612
+ abort "Couldn't find or write to the target area: #{location}"
613
+ end
614
+
615
+ @spec['products'].each do |product|
616
+ globpattern = Dir.glob(product)
617
+ FileUtils.cp(globpattern, location)
618
+ end
619
+ end
620
+
621
+
622
+ def distribute_multiple(location_stem)
623
+ #Copy the build product to all the directories listed in location_stem
624
+
625
+ Dir.glob(File.join(location_stem, "*")) do |folder|
626
+ distribute_single(folder)
627
+ end
628
+ end
629
+
630
+ # ===========================================================================
631
+ # Utils
632
+ # ===========================================================================
633
+
634
+ def banner
635
+ puts Paint[@separator, COL_SEPARATOR]
636
+ puts "#{Paint[@progname, COL_TITLE]} - r#{Paint[Sysbuild::VERSION, COL_VERSION]}"
637
+ puts Paint[@separator, COL_SEPARATOR]
638
+ puts
639
+ end
640
+
641
+
642
+ def abort(message = 'No message supplied.')
643
+ puts
644
+ puts Paint['SYSTEM BUILDER ABORT', COL_HARD_ERROR]
645
+
646
+ if message.kind_of?(Array)
647
+ message.each do |element|
648
+ puts Paint[' ' << element, COL_ERROR]
649
+ end
650
+ else
651
+ puts Paint[' ' << message, COL_ERROR]
652
+ end
653
+
654
+ Kernel.abort
655
+ end
656
+
657
+
658
+ def get_local_repo
659
+
660
+ system('mvn help:effective-settings -Doutput=/tmp/output.xml > /dev/null 2>&1 ')
661
+ doc = Nokogiri::XML(File.new("/tmp/output.xml"))
662
+ doc.remove_namespaces!
663
+
664
+ local_repo = doc.xpath('/settings/localRepository/text()').to_s
665
+
666
+ local_repo
667
+ end
668
+
669
+
670
+ def lookup(key)
671
+ # look up a module in the spec
672
+ @spec['modules'].each do |map|
673
+ if map.keys[0] == key
674
+ return map
675
+ end
676
+ end
677
+
678
+ nil
679
+ end
680
+ end
data/lib/version.rb ADDED
@@ -0,0 +1,3 @@
1
+ module Sysbuild
2
+ VERSION='1.0.3'
3
+ end
data/sysbuild.gemspec ADDED
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "sysbuild"
8
+ spec.version = Sysbuild::VERSION
9
+ spec.authors = ["John Hawksley"]
10
+ spec.email = ["john.hawksley@gmail.com"]
11
+
12
+ spec.summary = %q{Build a Maven non-reactor system}
13
+ spec.homepage = ""
14
+
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = "bin"
20
+ spec.executables = ['sysbuild']
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.14"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "nexus", "~> 1.3.0"
26
+
27
+ spec.add_runtime_dependency 'require_all', '~> 1.3.3'
28
+ spec.add_runtime_dependency 'ruby-terminfo', '~> 0.1.1'
29
+ spec.add_runtime_dependency 'open4', '~> 1.3.4'
30
+ spec.add_runtime_dependency 'paint', '~> 2.0.0'
31
+ spec.add_runtime_dependency 'nokogiri', '~> 1.7.1'
32
+ spec.add_runtime_dependency 'text-table', '~> 1.2.4'
33
+ spec.add_runtime_dependency 'ruby-progressbar', '~> 1.8.1'
34
+
35
+ end
metadata ADDED
@@ -0,0 +1,196 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sysbuild
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.3
5
+ platform: ruby
6
+ authors:
7
+ - John Hawksley
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-06-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.14'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.14'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: nexus
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 1.3.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 1.3.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: require_all
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.3.3
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.3.3
69
+ - !ruby/object:Gem::Dependency
70
+ name: ruby-terminfo
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.1.1
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.1.1
83
+ - !ruby/object:Gem::Dependency
84
+ name: open4
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 1.3.4
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 1.3.4
97
+ - !ruby/object:Gem::Dependency
98
+ name: paint
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 2.0.0
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 2.0.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: nokogiri
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 1.7.1
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 1.7.1
125
+ - !ruby/object:Gem::Dependency
126
+ name: text-table
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 1.2.4
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: 1.2.4
139
+ - !ruby/object:Gem::Dependency
140
+ name: ruby-progressbar
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: 1.8.1
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: 1.8.1
153
+ description:
154
+ email:
155
+ - john.hawksley@gmail.com
156
+ executables:
157
+ - sysbuild
158
+ extensions: []
159
+ extra_rdoc_files: []
160
+ files:
161
+ - ".gitignore"
162
+ - ".ruby-gemset"
163
+ - ".ruby-version"
164
+ - Gemfile
165
+ - README.md
166
+ - Rakefile
167
+ - bin/sysbuild
168
+ - doc/snippets
169
+ - lib/change_detector.rb
170
+ - lib/sysbuild.rb
171
+ - lib/version.rb
172
+ - sysbuild.gemspec
173
+ homepage: ''
174
+ licenses: []
175
+ metadata: {}
176
+ post_install_message:
177
+ rdoc_options: []
178
+ require_paths:
179
+ - lib
180
+ required_ruby_version: !ruby/object:Gem::Requirement
181
+ requirements:
182
+ - - ">="
183
+ - !ruby/object:Gem::Version
184
+ version: '0'
185
+ required_rubygems_version: !ruby/object:Gem::Requirement
186
+ requirements:
187
+ - - ">="
188
+ - !ruby/object:Gem::Version
189
+ version: '0'
190
+ requirements: []
191
+ rubyforge_project:
192
+ rubygems_version: 2.5.1
193
+ signing_key:
194
+ specification_version: 4
195
+ summary: Build a Maven non-reactor system
196
+ test_files: []