rant 0.4.6 → 0.4.8

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 (45) hide show
  1. data/INSTALL +44 -0
  2. data/NEWS +30 -0
  3. data/README +6 -46
  4. data/Rantfile +38 -7
  5. data/doc/c.rdoc +2 -0
  6. data/doc/command.rdoc +210 -0
  7. data/doc/examples/c_dependencies/Rantfile +1 -1
  8. data/doc/examples/directedrule/Rantfile +1 -1
  9. data/doc/homepage/index.html +12 -1
  10. data/doc/rant-import.rdoc +5 -0
  11. data/doc/rant_vs_rake.rdoc +107 -0
  12. data/doc/rantfile.rdoc +17 -17
  13. data/doc/rubyproject.rdoc +45 -45
  14. data/doc/subdirs.rdoc +1 -1
  15. data/lib/rant/coregen.rb +62 -22
  16. data/lib/rant/import/archive.rb +1 -0
  17. data/lib/rant/import/command.rb +206 -0
  18. data/lib/rant/import/nodes/default.rb +12 -6
  19. data/lib/rant/import/nodes/signed.rb +3 -3
  20. data/lib/rant/import/signedfile.rb +14 -15
  21. data/lib/rant/import/win32/rubycmdwrapper.rb +1 -0
  22. data/lib/rant/import.rb +52 -4
  23. data/lib/rant/metautils.rb +119 -0
  24. data/lib/rant/node.rb +11 -2
  25. data/lib/rant/rantenv.rb +5 -2
  26. data/lib/rant/rantlib.rb +30 -46
  27. data/lib/rant/rantsys.rb +81 -13
  28. data/lib/rant/rantvar.rb +1 -76
  29. data/lib/rant.rb +2 -2
  30. data/misc/TODO +21 -0
  31. data/test/deprecated/test_0_5_2.rb +28 -0
  32. data/test/deprecated/test_0_6_0.rb +24 -0
  33. data/test/dyn_dependencies.rf +25 -0
  34. data/test/import/command/Rantfile +102 -0
  35. data/test/import/command/test_command.rb +597 -0
  36. data/test/rant-import/test_rant-import.rb +23 -1
  37. data/test/rule.rf +2 -0
  38. data/test/test_dyn_dependencies.rb +45 -0
  39. data/test/test_env.rb +5 -4
  40. data/test/test_filelist.rb +60 -3
  41. data/test/test_rant_interface.rb +5 -0
  42. data/test/test_sys.rb +53 -2
  43. data/test/tutil.rb +14 -6
  44. metadata +17 -6
  45. data/test/deprecated/test_0_4_8.rb +0 -41
data/lib/rant/rantsys.rb CHANGED
@@ -138,15 +138,36 @@ module Rant
138
138
  end
139
139
  ##############################################################
140
140
 
141
- if Object.method_defined? :fcall # in Ruby 1.9 like __send__
141
+ if Object.method_defined?(:fcall) || Object.method_defined?(:funcall) # in Ruby 1.9 like __send__
142
+ @@__send_private__ = Object.method_defined?(:fcall) ? :fcall : :funcall
142
143
  def resolve
143
144
  @pending = false
144
- @actions.each{ |action| self.fcall(*action) }.clear
145
+ @actions.each{ |action| self.__send__(@@__send_private__, *action) }.clear
145
146
  ix = ignore_rx
146
147
  if ix
147
148
  @files.reject! { |f| f =~ ix && !@keep[f] }
148
149
  end
149
150
  end
151
+ elsif RUBY_VERSION < "1.8.2"
152
+ def resolve
153
+ @pending = false
154
+ @actions.each{ |action| self.__send__(*action) }.clear
155
+ ix = ignore_rx
156
+ @files.reject! { |f|
157
+ unless @keep[f]
158
+ next(true) if ix && f =~ ix
159
+ if @glob_flags & File::FNM_DOTMATCH != File::FNM_DOTMATCH
160
+ if ESC_ALT_SEPARATOR
161
+ f =~ /(^|(#{ESC_SEPARATOR}|#{ESC_ALT_SEPARATOR})+)\..*
162
+ ((#{ESC_SEPARATOR}|#{ESC_ALT_SEPARATOR})+|$)/x
163
+ else
164
+ f =~ /(^|#{ESC_SEPARATOR}+)\..*
165
+ (#{ESC_SEPARATOR}+|$)/x
166
+ end
167
+ end
168
+ end
169
+ }
170
+ end
150
171
  else
151
172
  def resolve
152
173
  @pending = false
@@ -359,9 +380,9 @@ end
359
380
  # will result on windows:
360
381
  # rdoc foo\bar "with space"
361
382
  # on other systems:
362
- # rdoc foo/bar 'with space'
383
+ # rdoc foo/bar with\ space
363
384
  def arglist
364
- to_ary.arglist
385
+ Rant::Sys.sp to_ary
365
386
  end
366
387
  alias to_s arglist
367
388
 
@@ -422,10 +443,15 @@ end
422
443
  @basedir = Dir.pwd
423
444
  super(*patterns)
424
445
  @ignore_hash = nil
446
+ @add_ignore_args = []
425
447
  update_ignore_rx
426
448
  end
427
449
 
428
- private :ignore
450
+ alias filelist_ignore ignore
451
+ def ignore(*patterns)
452
+ @add_ignore_args.concat patterns
453
+ self
454
+ end
429
455
 
430
456
  def ignore_rx
431
457
  update_ignore_rx
@@ -450,10 +476,11 @@ end
450
476
  private
451
477
  def update_ignore_rx
452
478
  ri = @rac.var[:ignore]
479
+ ri = ri ? (ri + @add_ignore_args) : @add_ignore_args
453
480
  rh = ri.hash
454
481
  unless rh == @ignore_hash
455
482
  @ignore_rx = nil
456
- ignore(*ri) if ri
483
+ filelist_ignore(*ri)
457
484
  @ignore_hash = rh
458
485
  end
459
486
  end
@@ -571,18 +598,51 @@ end
571
598
  # The empty string argument ensures that +system+
572
599
  # doesn't start a subshell but invokes ruby directly.
573
600
  # The empty string argument is ignored by ruby.
574
- sh(Env::RUBY, '', &block)
601
+ sh(Env::RUBY_EXE, '', &block)
575
602
  else
576
- sh(args.unshift(Env::RUBY), &block)
603
+ sh(args.unshift(Env::RUBY_EXE), &block)
577
604
  end
578
605
  end
579
606
 
580
607
  # Returns a string that can be used as a valid path argument
581
608
  # on the shell respecting portability issues.
582
- def sp path
583
- Env.shell_path path
609
+ def sp(arg)
610
+ if arg.respond_to? :to_ary
611
+ arg.to_ary.map{ |e| sp e }.join(' ')
612
+ else
613
+ _escaped_path arg
614
+ end
584
615
  end
585
616
 
617
+ # Escape special shell characters (currently only spaces).
618
+ # Flattens arrays and returns always a single string.
619
+ def escape(arg)
620
+ if arg.respond_to? :to_ary
621
+ arg.to_ary.map{ |e| escape e }.join(' ')
622
+ else
623
+ _escaped arg
624
+ end
625
+ end
626
+
627
+ if Env.on_windows?
628
+ def _escaped_path(path)
629
+ _escaped(path.to_s.tr("/", "\\"))
630
+ end
631
+ def _escaped(arg)
632
+ sarg = arg.to_s
633
+ return sarg unless sarg.include?(" ")
634
+ sarg << "\\" if sarg[-1].chr == "\\"
635
+ "\"#{sarg}\""
636
+ end
637
+ else
638
+ def _escaped_path(path)
639
+ path.to_s.gsub(/(?=\s)/, "\\")
640
+ end
641
+ alias _escaped _escaped_path
642
+ end
643
+ private :_escaped_path
644
+ private :_escaped
645
+
586
646
  # If supported, make a hardlink, otherwise
587
647
  # fall back to copying.
588
648
  def safe_ln(*args)
@@ -612,7 +672,7 @@ end
612
672
 
613
673
  extend self
614
674
 
615
- if RUBY_VERSION >= "1.9.0"
675
+ if RUBY_VERSION >= "1.8.4" # needed by 1.9.0, too
616
676
  class << self
617
677
  public(*::FileUtils::METHODS)
618
678
  end
@@ -634,12 +694,20 @@ end
634
694
  raise ArgumentError, "controller required"
635
695
  end
636
696
 
637
- def glob(*args, &block)
638
- fl = RacFileList.new(@rac, *args)
697
+ def glob(*patterns, &block)
698
+ fl = RacFileList.new(@rac, *patterns)
639
699
  fl.instance_eval(&block) if block
640
700
  fl
641
701
  end
642
702
 
703
+ def glob_all(*patterns, &block)
704
+ fl = RacFileList.new(@rac, *patterns)
705
+ fl.ignore(".", "..")
706
+ fl.glob_flags |= File::FNM_DOTMATCH
707
+ fl.instance_eval(&block) if block
708
+ fl
709
+ end
710
+
643
711
  def [](*patterns)
644
712
  RacFileList.new(@rac, *patterns)
645
713
  end
data/lib/rant/rantvar.rb CHANGED
@@ -16,14 +16,13 @@
16
16
  # If you're looking for general info about Rant, read the
17
17
  # README[link:files/README.html].
18
18
  module Rant
19
- VERSION = '0.4.6'
19
+ VERSION = '0.4.8'
20
20
 
21
21
  # Those are the filenames for rantfiles.
22
22
  # Case matters!
23
23
  ROOT_RANTFILE = "root.rant"
24
24
  SUB_RANTFILE = "sub.rant"
25
25
  RANTFILES = [ "Rantfile", "rantfile", ROOT_RANTFILE ]
26
- DEPRECATED_RANTFILES = [ "Rantfile.rb", "rantfile.rb" ]
27
26
 
28
27
  # Names of plugins and imports for which code was loaded.
29
28
  # Files that where loaded with the `import' commant are directly
@@ -49,80 +48,6 @@ module Rant
49
48
  @__rant_no_value__
50
49
  end
51
50
 
52
- module MetaUtils
53
- # Creates three accessor methods:
54
- # obj.attr_name:: Return value of instance variable
55
- # @attr_name
56
- # obj.attr_name = val:: Set value instance variable
57
- # @attr_name to val
58
- # obj.attr_name val:: same as above
59
- def rant_attr attr_name
60
- attr_name = valid_attr_name attr_name
61
- attr_writer attr_name
62
- module_eval <<-EOD
63
- def #{attr_name} val=Rant.__rant_no_value__
64
- if val.equal? Rant.__rant_no_value__
65
- @#{attr_name}
66
- else
67
- @#{attr_name} = val
68
- end
69
- end
70
- EOD
71
- nil
72
- end
73
- # Creates three accessor methods:
74
- # obj.attr_name?:: Return value, true or false
75
- # obj.attr_name:: Set attribute to true
76
- # obj.no_attr_name:: Set attribute to false
77
- def rant_flag attr_name
78
- attr_name = valid_attr_name attr_name
79
- module_eval <<-EOD
80
- def #{attr_name}?
81
- @#{attr_name}
82
- end
83
- def #{attr_name}
84
- @#{attr_name} = true
85
- end
86
- def no_#{attr_name}
87
- @#{attr_name} = false
88
- end
89
- EOD
90
- end
91
- # Creates accessor methods like #rant_attr for the attribute
92
- # attr_name. Additionally, values are converted with to_str
93
- # before assignment to instance variables happens.
94
- def string_attr attr_name
95
- attr_name = valid_attr_name attr_name
96
- module_eval <<-EOD
97
- def #{attr_name}=(val)
98
- if val.respond_to? :to_str
99
- @#{attr_name} = val.to_str
100
- else
101
- raise ArgumentError,
102
- "string (#to_str) value required", caller
103
- end
104
- end
105
- def #{attr_name} val=Rant.__rant_no_value__
106
- if val.equal? Rant.__rant_no_value__
107
- @#{attr_name}
108
- else
109
- self.__send__(:#{attr_name}=, val)
110
- end
111
- end
112
- EOD
113
- nil
114
- end
115
- # attr_name is converted to a string with #to_s and has to
116
- # match /^\w+$/. Returns attr_name.to_s.
117
- def valid_attr_name attr_name
118
- attr_name = attr_name.to_s
119
- attr_name =~ /^\w+$/ or
120
- raise ArgumentError,
121
- "argument has to match /^\w+$/", caller
122
- attr_name
123
- end
124
- end # module MetaUtils
125
-
126
51
  module RantVar
127
52
 
128
53
  class Error < Rant::Error
data/lib/rant.rb CHANGED
@@ -60,9 +60,9 @@ module Rant
60
60
  end
61
61
 
62
62
  def rant
63
- @__rant__
63
+ Rant.rant
64
64
  end
65
65
 
66
- @__rant__ = Rant::RantApp.new
66
+ Rant.instance_variable_set(:@__rant__, Rant::RantApp.new)
67
67
 
68
68
  include RantContext
data/misc/TODO CHANGED
@@ -1,6 +1,25 @@
1
1
 
2
2
  = TODO
3
3
 
4
+ == Don't use +invoke+ result of dependency to check if update is
5
+ necessary
6
+
7
+ It doesn't make sense since:
8
+ 1. The node (prerequisite) could have already been invoked by another
9
+ node as prerequisite. For the first node, the prerequisite would
10
+ return true, all following false.
11
+ 2. The node (prerequisite) *can* *not* know if the invoking node is
12
+ up to date compared to itself.
13
+
14
+ == Check +enhance+ for SourceNodes
15
+
16
+ Rant fails (infinite recursion) for enhance on SourceNodes.
17
+ Update: Infinite recursion occurs only when a <tt>require "rant"</tt>
18
+ was done. Else an appropriate message is printed. Can be
19
+ considered OK.
20
+
21
+ == Implement Rant::FileList#==
22
+
4
23
  == Update documentation with regards to resolve hooks.
5
24
 
6
25
  The argument list for resolve hooks has changed in version 0.4.5.
@@ -18,6 +37,8 @@ could get a common source of annoyance/bugs.
18
37
 
19
38
  Favorite candidate is currently <tt>@</tt>.
20
39
 
40
+ Done (0.4.5), using <tt>@</tt>.
41
+
21
42
  == Improve SourceNode types
22
43
 
23
44
  Currently a SourceNode can only have other SourceNodes or files as
@@ -30,4 +30,32 @@ class TestDeprecated_0_5_2 < Test::Unit::TestCase
30
30
  assert_match(/\bdeprecated\b/, err)
31
31
  end
32
32
  end
33
+ def test_ary_arglist
34
+ in_local_temp_dir do
35
+ write_to_file "Rantfile", <<-EOF
36
+ task :default do
37
+ sys(sys.sp(Env::RUBY_EXE) + " -e \\"puts ARGV\\" " +
38
+ ["a b", "c/d"].arglist + " > a.out")
39
+ end
40
+ EOF
41
+ out, err = assert_rant
42
+ content = Rant::Env.on_windows? ? "a b\nc\\d\n" : "a b\nc/d\n"
43
+ assert_file_content "a.out", content
44
+ assert_match(/\bWARNING\b/, err)
45
+ assert_match(/\barglist\b/, err)
46
+ assert_match(/\bsp\b/, err)
47
+ assert_match(/\bdeprecated\b/, err)
48
+ end
49
+ end
50
+ def test_ary_shell_pathes
51
+ out, err = capture_std do
52
+ sp = ["a b", "a/b"].shell_pathes
53
+ assert sp.respond_to?(:to_ary)
54
+ assert_equal 2, sp.size
55
+ end
56
+ assert_match(/\bWARNING\b/, err)
57
+ assert_match(/\bshell_pathes\b/, err)
58
+ assert_match(/\bsp\b/, err)
59
+ assert_match(/\bdeprecated\b/, err)
60
+ end
33
61
  end
@@ -0,0 +1,24 @@
1
+
2
+ require 'test/unit'
3
+ require 'tutil'
4
+ require 'rant/import'
5
+
6
+ $test_deprecated_dir ||= File.expand_path(File.dirname(__FILE__))
7
+
8
+ class TestDeprecated_0_6_0 < Test::Unit::TestCase
9
+ include Rant::TestUtil
10
+ def setup
11
+ Dir.chdir $test_deprecated_dir
12
+ end
13
+ def test_rant_import_option_v
14
+ out, err = capture_std do
15
+ assert_equal(0, Rant::RantImport.new("-v").run)
16
+ end
17
+ if Rant::VERSION > "0.4.8"
18
+ assert_match(/-v\bdeprecated\b.*-V.*--version\b/, err)
19
+ else
20
+ assert err.empty?
21
+ end
22
+ assert_match(/rant-import\s#{Regexp.escape Rant::VERSION}/, out)
23
+ end
24
+ end
@@ -0,0 +1,25 @@
1
+
2
+ import "sys/more", "autoclean"
3
+
4
+ @print = lambda { |t| puts t.name }
5
+ @write = lambda { |t|
6
+ sys.write_to_file(t.name, (var[t.name[0,1]]||t.name))
7
+ }
8
+
9
+ task :A => :B, &@print
10
+ task :B do |t|
11
+ enhance :A => [:C, :D]
12
+ @print[t]
13
+ end
14
+ task :C, &@print
15
+ task :D, &@print
16
+
17
+ file "a.t" => "b.t", &@write
18
+ file "b.t" do |t|
19
+ enhance "a.t" => ["c.t", "d.t"]
20
+ @write[t]
21
+ end
22
+ file "c.t", &@write
23
+ file "d.t", &@write
24
+
25
+ gen AutoClean
@@ -0,0 +1,102 @@
1
+
2
+ import "command", "autoclean"
3
+
4
+ @ruby = Env::RUBY_EXE
5
+ @sh_echo = "#{sys.sp Env::RUBY_EXE} -e \"puts ARGV.join(' ')\""
6
+ @sh_puts = "#{sys.sp Env::RUBY_EXE} -e \"puts ARGV\""
7
+ @sh_cat = "#{sys.sp Env::RUBY_EXE} -e \"print ARGF.read\""
8
+
9
+ desc "Build a.t"
10
+ gen Command, "a.t" => ["b.t", "c.t"] do |t|
11
+ "#@sh_echo #{sys.sp t.prerequisites} > #{t.name}"
12
+ end
13
+ gen Command, "f_a.t" do |t|
14
+ sys "#@sh_echo #{sys.escape "I will fail."} > #{t.name}"
15
+ end
16
+
17
+ var :btxt => "b"
18
+ var :be, :Bool
19
+
20
+ gen Command, "b.t", "$[sh_echo] $(btxt) > $(>)"
21
+
22
+ if var[:be]
23
+ enhance "b.t" => "d.t" do |t|
24
+ import "sys/more"
25
+ sys.write_to_file(t.name,
26
+ File.read(t.name) + File.read(t.source))
27
+ end
28
+ end
29
+
30
+ gen Command, "c.t", sys["d???.t"], "$[sh_echo] $(<) > $(>)"
31
+
32
+ gen Command, "with space/a.t",
33
+ ["b.t", "with space/b.t"],
34
+ "$[sh_puts] $(<) > $(>)"
35
+
36
+ var :fargs => "/I$(p_ath1)"
37
+ var :p_ath1 => "a bc"
38
+ gen Command, "f.t", "$[sh_echo] $[fargs] > $[>]"
39
+
40
+ var :eargs => "/I$(epath)"
41
+ var :epath => "a b/c/"
42
+ gen Command, "e.t", "$[sh_echo] $[eargs] > ${>}"
43
+
44
+ var :gargs => "/I${gpath}"
45
+ var :gpath => "a b/c/"
46
+ gen Command, "g.t", "$[sh_echo] $[gargs] > $(>)"
47
+
48
+ var :h1 => 1
49
+ var :h2 => 2
50
+ gen Command, "h.t", <<end
51
+ $[sh_echo] ${h1} > $(>)1
52
+ $[sh_echo] ${h2} > $(>)2
53
+ $[sh_cat] $(>)1 $(>)2 > $(>)
54
+ end
55
+
56
+ var :rargs => "$(prerequisites) $(source) > $(name)"
57
+ var :rcmd => "$[sh_echo] " + var[:rargs]
58
+ gen Rule, :out => [:in1, :in2] do |name, sources|
59
+ gen Command, name, sources, var[:rcmd]
60
+ end
61
+
62
+ gen Directory, "a.in1"
63
+
64
+ var :rc_dep => "puts 'a'"
65
+ gen Command, "dep1.t", "$(ruby) -e \"$[rc_dep]\" > $(>)"
66
+
67
+ gen Command, "t1.t", "dep1.t", "$[sh_echo] making t1 > $(>)"
68
+ gen Command, "t2.t", "dep1.t", "$[sh_echo] making t2 > $(>)"
69
+
70
+ gen Command, "sub1.t/a", "#@sh_echo ${>} > $(>)"
71
+ gen Command, "sub2.t/a", "$[sh_echo] ${>} > $(>)"
72
+ gen Directory, "sub2.t"
73
+
74
+ task :sub3 do
75
+ puts "task sub3"
76
+ end
77
+ gen Command, "sub3/a", "$[sh_echo] ${>} > $(>)"
78
+
79
+ gen Command, "x.t", '[#$[sh_puts] ${a}#] ${b} > $(>)'
80
+
81
+ gen Command, "delay.t", "$[sh_echo] ${foo} > $(>)"
82
+
83
+ gen Command, "p1.t", '$[sh_puts] ${p1} > $(>)'
84
+ gen Command, "p2.t", '$[sh_puts] ${p2} > $(>)'
85
+ gen Command, "p3.t", '$[sh_puts] ${p2} > $(>)'
86
+
87
+ var :foo => "foo value"
88
+ task :change_foo do
89
+ var[:foo] = "changed"
90
+ end
91
+
92
+ var[:p1] = lambda { |n| "#{n.full_name} $[foo]" }
93
+ var[:p2] = lambda { var[:foo] << "." }
94
+
95
+ if var[:inc_foo]
96
+ var[:p2].call
97
+ end
98
+
99
+ @h = {:a => "b"}
100
+ gen Command, "hash.t", "$[sh_puts] ${h} > $(>)"
101
+
102
+ gen AutoClean