sysbuild 1.0.3

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