metabuild 0.3.2 → 0.3.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.
Files changed (4) hide show
  1. data/Rakefile +1 -1
  2. data/lib/metabuild.rb +149 -73
  3. data/metabuild.gemspec +4 -4
  4. metadata +9 -4
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
2
2
  require 'rake'
3
3
  require 'echoe'
4
4
 
5
- Echoe.new('metabuild', '0.3.2') do |s|
5
+ Echoe.new('metabuild', '0.3.3') do |s|
6
6
  s.author = "F. Brault"
7
7
  s.email = "castorpilot@yahoo.com"
8
8
  s.description = "MetaBuild is a ruby make-like tool that builds components. It supports tracking of dependencies among components, and a hierarchical reporting facility."
@@ -42,7 +42,7 @@ module Metabuild
42
42
  DEFAULT_TAGS = [
43
43
  lambda {`uname -p`},
44
44
  lambda {`uname -o`},
45
- lambda {File.read("/etc/fedora-release")},
45
+ lambda {File.read("/etc/fedora-release") if File.exists? "/etc/fedora-release"},
46
46
  lambda {s = ""; 1.upto(ARGV.length-1) {|i| s += ARGV[i]};s}
47
47
  ]
48
48
 
@@ -55,8 +55,16 @@ module Metabuild
55
55
  "logfile" => "",
56
56
  "dep_graph" => ["no", "Output Dependency graph in Graphviz dot format"],
57
57
  "parallel" => ["no", "Run threads in parallel. Make sure that your dependency graph can handle this !"],
58
+ "prefix" => ["", "Prefix for the final installation"],
58
59
  }
59
60
 
61
+
62
+ METABUILD_VERSION = 0.4
63
+
64
+ def require_version(ver)
65
+ raise "Error, version #{ver} needed (current version is #{METABUILD_VERSION})" unless ver == METABUILD_VERSION
66
+ end
67
+
60
68
  # Function to extend fileutils
61
69
 
62
70
  # helper function that does (rm -rf dir; mkdir dir; cd dir)
@@ -66,65 +74,62 @@ module Metabuild
66
74
  cd dir
67
75
  end
68
76
 
69
- # helper function that does goes into dir if it exists, or create it and goes into it
77
+ # helper function that goes into dir if it exists, or create it and goes into it
70
78
  def cd!(dir)
71
79
  mkdir_p dir unless File.directory? dir
72
80
  cd dir
73
81
  end
74
82
 
75
83
 
76
- # Mother class for all SCM access, "virtual"
77
- class SCM
84
+ # Git access
85
+ class Git
78
86
 
79
- attr_accessor :path
87
+ attr_accessor :path, :dir
80
88
 
81
- def initialize(path)
82
- @path = path
89
+ def initialize(dir = nil, path = nil)
90
+ @path, @dir = path, dir
83
91
  end
84
92
 
85
- def cksum
86
- raise "Should be implemented in child class"
93
+ def inside_git_dir
94
+ raise "Directory not set for git repo #{@path}" if @dir.nil? or not File.exists? @dir
95
+ old_dir = pwd
96
+ cd dir
97
+ yield
98
+ cd old_dir
87
99
  end
88
100
 
101
+ # Like running "git diff" in a git repo
89
102
  def get_diff
90
- raise "Should be implemented in child class"
91
- end
92
-
93
- def apply_patch(patch)
94
- raise "Should be implemented in child class"
95
- end
96
-
97
- def clone(path)
98
- raise "Should be implemented in child class"
99
- end
100
-
101
- end
102
-
103
- # Git access, uses Grit ruby lib
104
- class Git < SCM
105
-
106
- def initialize(path)
107
- super
103
+ inside_git_dir do
104
+ `git diff`
105
+ end
108
106
  end
109
107
 
110
- # Like running "git diff" in a git repo
111
- def get_diff
112
- `cd #{path} && git diff`
108
+ def run(cmd)
109
+ inside_git_dir do
110
+ raise "Git command #{cmd} failed in #{@path}" unless system("git #{cmd}")
111
+ end
113
112
  end
114
113
 
115
114
  def apply_patch(patch)
116
- pipe = IO.popen("git apply -")
117
- pipe.puts patch
118
- pipe.close_write
115
+ inside_git_dir do
116
+ pipe = IO.popen("git apply -")
117
+ pipe.puts patch
118
+ pipe.close_write
119
+ end
119
120
  end
120
121
 
121
- def clone(path)
122
- raise "unable to clone #{path}" unless system("git clone " + path)
122
+ def clone
123
+ raise "Cannot clone empty path" if @path.nil?
124
+ @dir = pwd + File.basename(@path, ".git") if @dir.nil?
125
+ run("clone #{@path} #{@dir}")
123
126
  end
124
127
 
125
128
  # id is the SHA1 of head + of any diff (locals)
126
129
  def cksum
127
- `cd #{path};git log --pretty=format:'%H' | head -n 1`.to_i(16) ^ Digest::SHA1.hexdigest(get_diff).to_i(16)
130
+ inside_git_dir do
131
+ `git log --pretty=format:'%H' | head -n 1`.to_i(16) ^ Digest::SHA1.hexdigest(get_diff).to_i(16)
132
+ end
128
133
  end
129
134
 
130
135
  end
@@ -147,8 +152,8 @@ module Metabuild
147
152
  end
148
153
 
149
154
  # Run a shell command, log its status (override in child class)
150
- def run(command, env, fail_msg)
151
- env_system(command, env)
155
+ def run(command, env, fail_msg, skip)
156
+ env_system(command, env) unless skip
152
157
  end
153
158
 
154
159
  # Run a shell command, no logging (override in child class)
@@ -157,8 +162,8 @@ module Metabuild
157
162
  end
158
163
 
159
164
  # Run a shell command. Log success +and+ failure (override in child class)
160
- def valid(command, env, fail_msg, success_msg)
161
- env_system(command, env)
165
+ def valid(command, env, fail_msg, success_msg, skip)
166
+ env_system(command, env) unless skip
162
167
  end
163
168
 
164
169
  # Spawn with env
@@ -217,11 +222,11 @@ module Metabuild
217
222
  # Simple log that just prints out text (for console builds)
218
223
  class LogText < Log
219
224
 
220
- attr_reader :name, :success, :fail
225
+ attr_reader :name, :success, :fail, :skip
221
226
 
222
227
  def initialize(name)
223
228
  super(name)
224
- @fail, @success = [], []
229
+ @fail, @success, @skip = [], [], []
225
230
  @subscripts = []
226
231
  @report_done = false
227
232
  end
@@ -234,6 +239,10 @@ module Metabuild
234
239
  @success.push msg
235
240
  end
236
241
 
242
+ def add_skip(msg)
243
+ @skip.push "SKIPPED : #{msg}"
244
+ end
245
+
237
246
  def report
238
247
  return if @report_done # prevent reporting several times
239
248
  if @subscript
@@ -257,6 +266,9 @@ module Metabuild
257
266
  puts "Fail : "
258
267
  @fail.each {|s| puts s}
259
268
  puts "----------------------------------------------"
269
+ puts "Skipped : "
270
+ @skip.each {|s| puts s}
271
+ puts "----------------------------------------------"
260
272
  end
261
273
 
262
274
  def status
@@ -264,11 +276,15 @@ module Metabuild
264
276
  end
265
277
 
266
278
  # Run a shell command, log
267
- def run(command, env, fail_msg)
268
- if env_system(command, env)
269
- add_success "[#{@name}] #{command} SUCCESS"
279
+ def run(command, env, fail_msg, skip)
280
+ if skip
281
+ add_skip command
270
282
  else
271
- failure fail_msg
283
+ if env_system(command, env)
284
+ add_success "[#{@name}] #{command} SUCCESS"
285
+ else
286
+ failure fail_msg
287
+ end
272
288
  end
273
289
  end
274
290
 
@@ -278,11 +294,16 @@ module Metabuild
278
294
  end
279
295
 
280
296
  # Run a shell command. Log success +and+ failure
281
- def valid(command, env, fail_msg, success_msg)
282
- if env_system(command, env)
283
- add_success success_msg if success_msg != ""
297
+ def valid(command, env, fail_msg, success_msg, skip)
298
+ if skip
299
+ add_skip command
284
300
  else
285
- add_fail fail_msg
301
+ if env_system(command, env)
302
+ add_success success_msg if success_msg != ""
303
+ else
304
+ failure(fail_msg) if ENV.has_key? "METABUILD_PARALLEL"
305
+ add_fail fail_msg
306
+ end
286
307
  end
287
308
  end
288
309
 
@@ -290,6 +311,7 @@ module Metabuild
290
311
  @subscripts.push log.name
291
312
  log.success.each {|s| @success.push("[#{log.name}] " + s)}
292
313
  log.fail.each {|f| @fail.push("[#{log.name}] " + f)}
314
+ log.skip.each {|f| @skip.push("[#{log.name}] " + f)}
293
315
  end
294
316
 
295
317
  # Stop script, adding a message to the log
@@ -319,7 +341,7 @@ module Metabuild
319
341
  def initialize(name, file)
320
342
  super(name)
321
343
  @file = file
322
- @fail, @success = [], []
344
+ @fail, @success, @skip = [], [], []
323
345
  @subscripts = []
324
346
  @report_done = false
325
347
  @html = ""
@@ -334,6 +356,10 @@ module Metabuild
334
356
  @success.push [cmd, msg, output]
335
357
  end
336
358
 
359
+ def add_skip(cmd)
360
+ @skip.push "SKIPPED : #{cmd}"
361
+ end
362
+
337
363
  def report
338
364
  return if @report_done # prevent reporting several times
339
365
  fill_html
@@ -368,6 +394,19 @@ module Metabuild
368
394
  QvOlTS2eFNHN127bhzIuAgCRYlHJuiKikkWKVYhYsUbb28i4iOZN5agTRY+czl7VYnGaLE4Ty4o0
369
395
  7hNDXR5nNhTtXx5nJvXfpI7Pw9VhHly99rDX82v/7WHXlPfL/K1knVZOr707zeLjFH/6BQC8XLzY
370
396
  fvFVPXMe1qPe1y/ZDt7tn1jpQgAAAABJRU5ErkJggg=='>"
397
+ yellow = "<img src='data:image/png;base64,
398
+ iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAIAAABL1vtsAAAAAXNSR0IArs4c6QAAAg1JREFUOMul
399
+ lEFP20AQhWdtb8xuGttSUGK7WKVSEpVje0OiQlz7b7n02gM3iJpyKwSprQL1YpoqWcu7iR07PRjF
400
+ VkCJK+Zo6X2eeTvzUL/fh5eV9vRTkiRSSiGEECJJEgDAGFNKKaWEEIzxFoQQgjGGsoHb+tp1f9Up
401
+ B4BIGH8mb34HH5bKe9u2KaVlCSoPwjmP+Nle6/OefUN2ZA3HqpoCQJqqcVKTM3LLOrfBp7rx0TCM
402
+ Z7rgnE//ful4p539qxqOy/9R1ZSokuzIV/VvmipvRguAkxVFW/Uf8bNn9eWq4bizfwVw+tPXNO0k
403
+ n0jJ/WOMUf1is75MofoFYyw3WwEAKSXKBm5ruFW/oritIcoGUspHhBCC6KOmNa6+C01rTPSREKKM
404
+ CCxjUh1hGROiBwUiSRIEj+9XsVQ1RRAXXrywlHx/xcwKo0Z1WRg1xMzKl10BAErpLG5PuVkdMeXm
405
+ LG4Xe0EpnYQHI9+rjhj53iQ8KBCEEMN02UPPD5wqej9w2EPPMF1CSOGFbdvz7PD88mgrxQ+c88uj
406
+ eXZo23bhRT6L43RDebyZkutDeew43dXJrx+77w+j8Kbd/N57e+20/UY9zP33753rH7378bt6o+M4
407
+ 3fKxo7XgyyOHT++W2ThLp8vlHAAQ0hXVRErTMF8/jZz11KKUep4nd3fz4FssFgCgadp/BF/uLsa4
408
+ 3Orm+gdpYQabBkXtNgAAAABJRU5ErkJggg=='>"
409
+
371
410
 
372
411
  unless @subscript
373
412
  @html << "<html>\n"
@@ -545,6 +584,10 @@ module Metabuild
545
584
  id += 1
546
585
  end
547
586
 
587
+ @skip.each do |cmd|
588
+ @html << "<br>#{yellow} #{cmd}\n"
589
+ end
590
+
548
591
  @html << "<br></p>\n"
549
592
 
550
593
  @html << bottom + "</div>"
@@ -614,13 +657,17 @@ module Metabuild
614
657
 
615
658
 
616
659
  # Run a shell command, log exit status
617
- def run(command, env, fail_msg)
618
- success, output= env_system(command, env)
619
- if success
620
- add_success command, "#{command} success", output
660
+ def run(command, env, fail_msg, skip)
661
+ if skip
662
+ add_skip command
621
663
  else
622
- add_fail command, fail_msg, output
623
- stop
664
+ success, output= env_system(command, env)
665
+ if success
666
+ add_success command, "#{command} success", output
667
+ else
668
+ add_fail command, fail_msg, output
669
+ stop
670
+ end
624
671
  end
625
672
  end
626
673
 
@@ -631,12 +678,17 @@ module Metabuild
631
678
  end
632
679
 
633
680
  # Run a shell command. Log success +and+ failure, do not abort on failure
634
- def valid(command, env, fail_msg, success_msg)
635
- success, output = env_system(command, env)
636
- if success
637
- add_success command, success_msg, output
681
+ def valid(command, env, fail_msg, success_msg, skip)
682
+ if skip
683
+ add_skip command
638
684
  else
639
- add_fail command, fail_msg, output
685
+ success, output = env_system(command, env)
686
+ if success
687
+ add_success command, success_msg, output
688
+ else
689
+ failure(fail_msg) if ENV.has_key? "METABUILD_PARALLEL"
690
+ add_fail command, fail_msg, output
691
+ end
640
692
  end
641
693
  end
642
694
 
@@ -755,17 +807,25 @@ module Metabuild
755
807
 
756
808
  # Run according to dependency list, from bottom to top
757
809
  def propagate_run(use_cache=false, parallel=false)
810
+ success = true
758
811
  if parallel
759
812
  each_dep do |d|
760
- fork {d.propagate_run(use_cache, parallel)}
813
+ fork {
814
+ ENV["METABUILD_PARALLEL"] = "1"
815
+ d.propagate_run(use_cache, parallel)
816
+ }
761
817
  end
762
- Process.waitall unless @depends.empty?
818
+ Process.waitall.each { |a| success = false unless a[1].success? } unless @depends.empty?
763
819
  else
764
820
  each_dep do |d|
765
821
  d.propagate_run(use_cache, parallel)
766
822
  end
767
823
  end
768
- run(use_cache)
824
+ if success
825
+ run(use_cache)
826
+ else
827
+ raise "Dependency failed for #{name}"
828
+ end
769
829
  end
770
830
 
771
831
  def propagate_disable
@@ -775,6 +835,14 @@ module Metabuild
775
835
  end
776
836
  end
777
837
 
838
+ def propagate_restart_at(restart_at)
839
+ each_dep do |d|
840
+ return true if d.propagate_restart_at restart_at
841
+ d.done = true
842
+ end
843
+ return @name == restart_at
844
+ end
845
+
778
846
  def output_graph
779
847
  each_dep do |d|
780
848
  puts "#{@name} -> #{d.name};"
@@ -787,7 +855,7 @@ module Metabuild
787
855
  class Options
788
856
 
789
857
  extend Forwardable
790
- attr_reader :opts, :rest, :from_targets
858
+ attr_reader :opts, :rest, :from_targets, :restart_at
791
859
  def_delegators :@opts, :[], :fetch, :each
792
860
 
793
861
  # By default, the following options are set : --help, and DEFAULT_OPTIONS.
@@ -800,7 +868,9 @@ module Metabuild
800
868
  @parser = OptionParser.new
801
869
  @parser.on("--help") {|val| @help = true}
802
870
  @from_targets = []
871
+ @restart_at = nil
803
872
  @parser.on("--from=[target]", "Disable everything below target in dep tree. Only with dependency=yes") {|val| @from_targets.push val}
873
+ @parser.on("--restart-at=[target]", "Disable everything before target in sequential build order. Only with dependency=yes") {|val| @restart_at = val}
804
874
  hash.each do |opt, default|
805
875
  if default.kind_of? Array
806
876
  @parser.on("--#{opt}=[#{default[0]}]", default[1]) {|val| @opts[opt] = val}
@@ -889,6 +959,12 @@ module Metabuild
889
959
  use_cache = (@options.fetch("cache", "no").downcase == "yes")
890
960
  parallel = (@options.fetch("parallel", "no").downcase == "yes")
891
961
  targs = @options.rest.empty? ? @default_targets.map {|t| t.to_s} : @options.rest
962
+ if @options.restart_at
963
+ targs.each do |t|
964
+ break if get_target(t).propagate_restart_at(@options.restart_at)
965
+ end
966
+ end
967
+
892
968
  if @options.fetch("dependency", "yes").downcase != "yes"
893
969
  targs.each { |t| targ = get_target(t); targ.run(use_cache) unless targ.nil? }
894
970
  else
@@ -924,14 +1000,14 @@ module Metabuild
924
1000
  # Run a shell command, giving it (optional) env variables (a hashmap), and (optional) failure message
925
1001
  # Log success +and+ failure. Abort on failure.
926
1002
  # :call-seq:
927
- # run(:cmd => "cmd", :env => env, :msg => "msg") -> nil
1003
+ # run(:cmd => "cmd", :env => env, :msg => "msg", :skip => bool) -> nil
928
1004
  # run("cmd") -> nil
929
1005
  def run(h)
930
1006
  if h.kind_of? String
931
- @log.run(h, @env, "#{h} FAIL")
1007
+ @log.run(h, @env, "#{h} FAIL", false)
932
1008
  else
933
1009
  raise "run command needs a non nil command" if h[:cmd].nil?
934
- @log.run(h[:cmd], @env.merge(h.fetch(:env, @env)), h.fetch(:msg, "#{h[:cmd]} FAIL"))
1010
+ @log.run(h[:cmd], @env.merge(h.fetch(:env, @env)), h.fetch(:msg, "#{h[:cmd]} FAIL"), h.fetch(:skip, false))
935
1011
  end
936
1012
  end
937
1013
 
@@ -951,14 +1027,14 @@ module Metabuild
951
1027
  # Run a shell command, giving it (optional) env variables (a hashmap), and (optional) failure message
952
1028
  # Log success +and+ failure. Do not abort on failure.
953
1029
  # :call-seq:
954
- # valid(:cmd => "cmd", :env => env, :fail_msg => "msg", :success_msg => "msg") -> nil
1030
+ # valid(:cmd => "cmd", :env => env, :fail_msg => "msg", :success_msg => "msg", :skip => bool) -> nil
955
1031
  # valid("cmd") -> nil
956
1032
  def valid(h)
957
1033
  if h.kind_of? String
958
- @log.valid(h, @env, "#{h} FAIL", "#{h} SUCCESS")
1034
+ @log.valid(h, @env, "#{h} FAIL", "#{h} SUCCESS", false)
959
1035
  else
960
1036
  raise "valid command needs a non nil command" if h[:cmd].nil?
961
- @log.valid(h[:cmd], @env.merge(h.fetch(:env, {})), h.fetch(:fail_msg, "#{h[:cmd]} FAIL"), h.fetch(:success_msg, "#{h[:cmd]} SUCCESS"))
1037
+ @log.valid(h[:cmd], @env.merge(h.fetch(:env, {})), h.fetch(:fail_msg, "#{h[:cmd]} FAIL"), h.fetch(:success_msg, "#{h[:cmd]} SUCCESS"), h.fetch(:skip, false))
962
1038
  end
963
1039
  end
964
1040
 
@@ -1009,7 +1085,7 @@ module Metabuild
1009
1085
  @targets.each do |t|
1010
1086
  return t if t.name == name
1011
1087
  end
1012
- raise "Unkonwn target #{name} for build #{@name}"
1088
+ raise "Unknown target #{name} for build #{@name}"
1013
1089
  end
1014
1090
 
1015
1091
  # Set a block of code to be run as target, catching doing logging
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{metabuild}
5
- s.version = "0.3.2"
5
+ s.version = "0.3.3"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["F. Brault"]
9
- s.date = %q{2010-05-28}
9
+ s.date = %q{2010-09-14}
10
10
  s.description = %q{MetaBuild is a ruby make-like tool that builds components. It supports tracking of dependencies among components, and a hierarchical reporting facility.}
11
11
  s.email = %q{castorpilot@yahoo.com}
12
12
  s.extra_rdoc_files = ["README", "lib/metabuild.rb"]
@@ -15,14 +15,14 @@ Gem::Specification.new do |s|
15
15
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Metabuild", "--main", "README"]
16
16
  s.require_paths = ["lib"]
17
17
  s.rubyforge_project = %q{metabuild}
18
- s.rubygems_version = %q{1.3.6}
18
+ s.rubygems_version = %q{1.3.7}
19
19
  s.summary = %q{MetaBuild is a ruby make-like tool that builds components. It supports tracking of dependencies among components, and a hierarchical reporting facility.}
20
20
 
21
21
  if s.respond_to? :specification_version then
22
22
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
23
  s.specification_version = 3
24
24
 
25
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
25
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
26
26
  else
27
27
  end
28
28
  else
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metabuild
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 21
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
8
  - 3
8
- - 2
9
- version: 0.3.2
9
+ - 3
10
+ version: 0.3.3
10
11
  platform: ruby
11
12
  authors:
12
13
  - F. Brault
@@ -14,7 +15,7 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-05-28 00:00:00 +02:00
18
+ date: 2010-09-14 00:00:00 +02:00
18
19
  default_executable:
19
20
  dependencies: []
20
21
 
@@ -48,16 +49,20 @@ rdoc_options:
48
49
  require_paths:
49
50
  - lib
50
51
  required_ruby_version: !ruby/object:Gem::Requirement
52
+ none: false
51
53
  requirements:
52
54
  - - ">="
53
55
  - !ruby/object:Gem::Version
56
+ hash: 3
54
57
  segments:
55
58
  - 0
56
59
  version: "0"
57
60
  required_rubygems_version: !ruby/object:Gem::Requirement
61
+ none: false
58
62
  requirements:
59
63
  - - ">="
60
64
  - !ruby/object:Gem::Version
65
+ hash: 11
61
66
  segments:
62
67
  - 1
63
68
  - 2
@@ -65,7 +70,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
65
70
  requirements: []
66
71
 
67
72
  rubyforge_project: metabuild
68
- rubygems_version: 1.3.6
73
+ rubygems_version: 1.3.7
69
74
  signing_key:
70
75
  specification_version: 3
71
76
  summary: MetaBuild is a ruby make-like tool that builds components. It supports tracking of dependencies among components, and a hierarchical reporting facility.