metabuild 0.3.2 → 0.3.3

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