filament 0.1.0

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 (56) hide show
  1. data/README +7 -0
  2. data/bin/filament +11 -0
  3. data/bin/filament-dbg +3 -0
  4. data/bin/filament-opt +3 -0
  5. data/bin/filament-test +3 -0
  6. data/bin/init +4 -0
  7. data/lib/filament/artifact.rb +49 -0
  8. data/lib/filament/context.rb +46 -0
  9. data/lib/filament/package/svn.rb +123 -0
  10. data/lib/filament/package.rb +326 -0
  11. data/lib/filament/platform.rb +79 -0
  12. data/lib/filament/plugins.rb +32 -0
  13. data/lib/filament/resolver.rb +91 -0
  14. data/lib/filament/target.rb +117 -0
  15. data/lib/filament/util/filelist2.rb +39 -0
  16. data/lib/filament/util/fileutils.rb +51 -0
  17. data/lib/filament/util/lazy_list.rb +74 -0
  18. data/lib/filament/workspace.rb +57 -0
  19. data/lib/filament.rb +199 -0
  20. data/lib/inflector.rb +124 -0
  21. data/lib/svn.rb +78 -0
  22. data/plugins/00util/lib/init.rb +47 -0
  23. data/plugins/01java/lib/filament/java/mixins/java_mixin.rb +19 -0
  24. data/plugins/01java/lib/filament/java/tools/compile.rb +41 -0
  25. data/plugins/01java/lib/filament/java/tools/execute.rb +37 -0
  26. data/plugins/01java/lib/filament/java/tools/jar.rb +59 -0
  27. data/plugins/01java/lib/filament/java/tools.rb +28 -0
  28. data/plugins/01java/lib/init.rb +1 -0
  29. data/plugins/02javame/lib/filament/javame/library.rb +16 -0
  30. data/plugins/02javame/lib/filament/javame/mixins/library_mixin.rb +144 -0
  31. data/plugins/02javame/lib/filament/javame/mixins/suite_mixin.rb +125 -0
  32. data/plugins/02javame/lib/filament/javame/platform.rb +105 -0
  33. data/plugins/02javame/lib/filament/javame/suite.rb +16 -0
  34. data/plugins/02javame/lib/filament/javame/tasks.rb +6 -0
  35. data/plugins/02javame/lib/filament/javame/tools/descriptor.rb +146 -0
  36. data/plugins/02javame/lib/filament/javame/tools/emulator.rb +36 -0
  37. data/plugins/02javame/lib/filament/javame/tools/external/mpp_sdk.rb +39 -0
  38. data/plugins/02javame/lib/filament/javame/tools/external/wtk.rb +60 -0
  39. data/plugins/02javame/lib/filament/javame/tools/preverifier.rb +43 -0
  40. data/plugins/02javame/lib/filament/javame/tools.rb +8 -0
  41. data/plugins/02javame/lib/init.rb +27 -0
  42. data/plugins/05push/lib/bluetooth.rb +66 -0
  43. data/plugins/05push/lib/filament/push/conduits/bluetooth_conduit.rb +25 -0
  44. data/plugins/05push/lib/filament/push/conduits/filter_conduit.rb +20 -0
  45. data/plugins/05push/lib/filament/push/conduits/scp_conduit.rb +35 -0
  46. data/plugins/05push/lib/filament/push.rb +21 -0
  47. data/plugins/05push/lib/init.rb +29 -0
  48. data/tests/build/artifact_name_test.rb +85 -0
  49. data/tests/build/artifact_test.rb +23 -0
  50. data/tests/gen/java/block_test.rb +42 -0
  51. data/tests/gen/java/callable_test.rb +23 -0
  52. data/tests/gen/java/method_test.rb +25 -0
  53. data/tests/gen/java/statement_test.rb +16 -0
  54. data/tests/java/tools_test.rb +8 -0
  55. data/tests/platform_test.rb +25 -0
  56. metadata +135 -0
data/README ADDED
@@ -0,0 +1,7 @@
1
+ Filament is a new spin on an old idea. Combine dependency-resolution, lazy-binding and rake (a ruby-based make alternative) and you get filament. Filament workspaces are a simple, cross-platform approach to managing complex build needs.
2
+
3
+ I created it satisfy my needs as a mobile application developer.
4
+
5
+ I am currently managing 20 inter-dependent libraries for a suite of JavaME platforms using only filament, its stock plugins, and minor dependencies.
6
+
7
+ This tool has been developed and tested on Ruby 1.8.4, Rake 0.7, Cygwin (XP sp2), OS X 10.4.5, and Gentoo Linux.
data/bin/filament ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #load "#{ENV['WR']}/tools/filament/lib/filament.rb"
4
+ require 'filament'
5
+
6
+ if FileTest.symlink?($0)
7
+ $actions << File.basename($0).to_sym
8
+ end
9
+
10
+ Filament::Application.new.run
11
+
data/bin/filament-dbg ADDED
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+
3
+ build BUILD_TYPE=DBG $@
data/bin/filament-opt ADDED
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+
3
+ build BUILD_TYPE=OPT $@
data/bin/filament-test ADDED
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+
3
+ build BUILD_TYPE=TEST test $@
data/bin/init ADDED
@@ -0,0 +1,4 @@
1
+ #!/bin/bash
2
+
3
+ export BUILD_PLUGINS=${BUILD}/plugins
4
+ #export PATH=`ls -1 ${BUILD_PLUGINS} | xargs -I qq echo -n "${BUILD_PLUGINS}/qq/script:"`${PATH}
@@ -0,0 +1,49 @@
1
+ require 'filament/package'
2
+ require 'filament/target'
3
+
4
+ module Filament
5
+ class Artifact < Target
6
+ attr_reader :directories, :name
7
+ attr_accessor :weak_deps, :deps, :package
8
+
9
+ def initialize(name, &block)
10
+ @directories = []
11
+ @tasks = []
12
+
13
+ super(:name => name) do
14
+ build_artifact
15
+ end
16
+
17
+ init
18
+ instance_eval(&block)
19
+ end
20
+
21
+ def init; end
22
+
23
+ def working_dir
24
+ return "#{$context[:working_dir]}/#{package.path}/#{name}"
25
+ end
26
+
27
+ def output_dir
28
+ return "#{$context[:output_dir]}/#{package.path}"
29
+ end
30
+
31
+ alias :orig_directory :directory
32
+ def directory(path, is_working_dir=true)
33
+ path = "#{working_dir}/#{path}" if is_working_dir
34
+ @directories << path
35
+ orig_directory(path)
36
+ return path
37
+ end
38
+
39
+ def invoke_tasks
40
+ # make output directory
41
+ mkdir_p(output_dir) unless File.exist?(output_dir)
42
+
43
+ # invoke them all
44
+ @tasks.each do |t|
45
+ t.invoke
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,46 @@
1
+ require 'fileutils'
2
+ require 'filament/package'
3
+
4
+ module Filament
5
+ class ExecutionContext
6
+ attr_reader :wrapper
7
+
8
+ def initialize(package)
9
+ @package = package
10
+ raise "package cannot be nil" if @package.nil?
11
+
12
+ @context = {}
13
+ @context[:context] = self
14
+ @context[:this_package] = @package
15
+ @context[:package_resolver] = @package.package_resolver
16
+ @context[:target_resolver] = @package.target_resolver
17
+ end
18
+
19
+ def wrap(*args, &block)
20
+ execute do
21
+ wrapper = Module.new
22
+ wrapper.instance_eval(*args, &block)
23
+ end
24
+ end
25
+
26
+ def execute(&block)
27
+ $context ||= Hash.new {|hash, key| raise "unknown context variable: #{key}"}
28
+
29
+ _context = $context.clone
30
+ $context.merge!(@context)
31
+
32
+ FileUtils.cd(@package.pathname, &block)
33
+
34
+ $context = _context
35
+ end
36
+ end
37
+
38
+ class BuildContext < ExecutionContext
39
+ def initialize(package)
40
+ super(package)
41
+
42
+ @context[:working_dir] = @package.working_dir
43
+ @context[:output_dir] = @package.output_dir
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,123 @@
1
+ require 'filament/package'
2
+
3
+ module Filament
4
+ class Package
5
+ # returns true if this package is under svn control
6
+ def svn?
7
+ p = @pathname + '.svn'
8
+ return p.exist?
9
+ end
10
+
11
+ def revision
12
+ return svn_revision
13
+ end
14
+
15
+ def update
16
+ return svn_update
17
+ end
18
+
19
+ def status
20
+ return svn_status
21
+ end
22
+
23
+ def commit(msg)
24
+ return svn_commit(msg)
25
+ end
26
+
27
+ def svn_info
28
+ stream = IO.popen("svn info #{@pathname.realpath}")
29
+ return YAML.load(stream)
30
+ end
31
+
32
+ def svn_revision
33
+ return 0 unless svn?
34
+ return svn_info['Last Changed Rev'].to_i
35
+ end
36
+
37
+ def svn_url
38
+ return nil unless svn?
39
+ return svn_info['URL']
40
+ end
41
+
42
+ def svn_base_url
43
+ return url.gsub(/\/(trunk|branches\/[.^\/]*|tags\/[.^\/]*)$/, '')
44
+ end
45
+
46
+ # if this package is under version control, it will update it
47
+ # if this package has subpackages, it will update them
48
+ def svn_update
49
+ if svn?
50
+ puts full_name
51
+ system('svn update')
52
+ end
53
+ subpackages.each { |s| s.update }
54
+ end
55
+
56
+ # if this package is under version control, it will print its status
57
+ # if this package has subpackages it will print their status
58
+ def svn_status
59
+ if svn?
60
+ puts full_name
61
+ system('svn status')
62
+ end
63
+ subpackages.each { |s| s.status }
64
+ end
65
+
66
+ # if this package is under version control, it will commit it with the
67
+ # given msg
68
+ # if this package has subpackages it will commit them
69
+ def svn_commit(msg)
70
+ if svn?
71
+ puts full_name
72
+ system("svn ci -m \"#{msg}\"")
73
+ end
74
+ subpackages.each { |s| s.commit(msg) }
75
+ end
76
+ end
77
+
78
+ def self.build_uri(h)
79
+ uri = h[:uri]
80
+
81
+ return uri unless @uri.nil?
82
+
83
+ package_path = h[:package_path]
84
+ base_uri = h[:root_uri] || ENV['BASE_SVN_URL']
85
+
86
+ tag = h[:tag]
87
+ branch = h[:branch]
88
+
89
+ return "#{base_uri}/tags/#{package_path}/#{tag}" unless tag.nil?
90
+ return "#{base_uri}/branches/#{package_path}/#{branch}" unless branch.nil?
91
+ return "#{base_uri}/trunk/#{package_path}"
92
+ end
93
+
94
+ # checks out the package into the current wd (preserving its path)
95
+ def self.checkout(h)
96
+ uri = Package.build_uri(h)
97
+ pkg = Package.create(h)
98
+ pkg.system("svn co #{uri} .")
99
+ return pkg
100
+ end
101
+
102
+ # exports a url to a given dir
103
+ def self.export(h)
104
+ uri = Package.build_uri(h)
105
+ pkg = Package.create(h)
106
+ pkg.system("svn export #{uri} .")
107
+ return pkg
108
+ end
109
+
110
+ end
111
+ end
112
+
113
+
114
+ #class URI::Generic
115
+ # def to_package
116
+ # s = SVN.new(uri)
117
+ # raise "not an svn uri" unless s.valid?
118
+ # pkg = export(:package_path => s.path,
119
+ # :uri => s.uri,
120
+ # :root_dir => Filament::Package.CACHE_DIR)
121
+ # return pkg
122
+ # end
123
+ #end
@@ -0,0 +1,326 @@
1
+ require 'fileutils'
2
+ require 'pathname'
3
+ require 'yaml'
4
+ require 'open-uri'
5
+
6
+ require 'filament/util/fileutils'
7
+ require 'filament/util/lazy_list'
8
+
9
+ require 'filament/context'
10
+
11
+ module Filament
12
+ class PackageList < LazyList
13
+ def initialize(*args)
14
+ @resolver = $context[:package_resolver]
15
+ super(*args)
16
+ end
17
+ end
18
+
19
+ class Package
20
+ attr_reader :parent, :name, :realpath, :workspace, :package_resolver, :target_resolver, :build_context
21
+ alias :pathname :realpath
22
+
23
+ def initialize(h)
24
+ @parent = h[:parent]
25
+ @workspace = h[:workspace]
26
+
27
+
28
+ if @workspace.nil?
29
+ unless @parent.nil?
30
+ @workspace = @parent.workspace
31
+ else
32
+ raise "all packages must belong to a workspace"
33
+ end
34
+ end
35
+
36
+ @package_resolver = h[:package_resolver] || PackageResolver.new(@workspace.package_resolver)
37
+
38
+ @name = h[:name]
39
+ @realpath = h[:realpath]
40
+
41
+ @subpackage_cache = {}
42
+
43
+ if @realpath.nil?
44
+ raise "package must have a name." if @name.nil?
45
+ raise "package must have a parent." if @parent.nil?
46
+
47
+ @realpath = @parent.realpath + @name
48
+ else
49
+ raise "package must not have a name." unless @name.nil?
50
+ raise "package must not have a parent." unless @parent.nil?
51
+
52
+ @realpath = Pathname.new(@realpath)
53
+ raise "realpath must be absolute" unless @realpath.absolute?
54
+ end
55
+
56
+ @descriptor_loaded = false
57
+
58
+ @targets = {}
59
+ @target_resolver = TargetResolver.new(self)
60
+
61
+ # add the "cache" directory for this package
62
+ @package_resolver << youngest_root_package.subpackage('cache')
63
+ # add the root directory for the current package to the list of search directories
64
+ @package_resolver << youngest_root_package
65
+ # add the "vendor" directory for this package
66
+ @package_resolver << subpackage('vendor')
67
+
68
+ @execution_context = ExecutionContext.new(self)
69
+ @build_context = BuildContext.new(self)
70
+ end
71
+
72
+ def exist?
73
+ return @realpath.exist?
74
+ end
75
+
76
+ def workspace?
77
+ p = @realpath + '.workspace'
78
+ return p.exist?
79
+ end
80
+
81
+ # returns true if this package is a root package.
82
+ # a root package is one that has a .root file.
83
+ def root?
84
+ return true if workspace?
85
+ p = @realpath + '.root'
86
+ return p.exist?
87
+ end
88
+
89
+ # returns true if this is root package or if one of its parents is
90
+ def has_valid_root?
91
+ return true if root?
92
+ return @parent.has_valid_root?
93
+ end
94
+
95
+ def youngest_root_package
96
+ return self if root?
97
+ return @parent.youngest_root_package
98
+ end
99
+
100
+ # returns true if this package is a parent package
101
+ # a parent package is one that is a root or has a .parent file
102
+ def parent?
103
+ return true if root?
104
+ p = @realpath + '.parent'
105
+ return p.exist?
106
+ end
107
+
108
+ # returns true if:
109
+ # 1. its parent thinks its a parent
110
+ # 2. its parent has a valid root
111
+ def has_valid_parent?
112
+ # should have a valid root
113
+ return false unless has_valid_root?
114
+
115
+ # roots shouldn't have parents
116
+ return @parent.nil? if root?
117
+
118
+ # everything else should
119
+ return false unless @parent.parent?
120
+
121
+ # walk up
122
+ return @parent.has_valid_parent?
123
+ end
124
+
125
+ # returns true if:
126
+ # 1. this package refers to a directory that exists
127
+ # 2. this package has a valid parent
128
+ def valid?
129
+ return false unless exist? and @pathname.directory?
130
+ return has_valid_parent?
131
+ end
132
+
133
+ def disabled?
134
+ p = @realpath + '.disabled'
135
+ return true if p.exist?
136
+ if root?
137
+ return false
138
+ else
139
+ return @parent.disabled?
140
+ end
141
+ end
142
+
143
+ def make_root!
144
+ return if root?
145
+ raise "won't convert parent to root" if parent?
146
+ touch(@realpath + '.root')
147
+ end
148
+
149
+ # if this package is not yet a parent, it will mark it as one
150
+ def make_parent!
151
+ return if parent?
152
+ return make_root! if @parent.nil?
153
+ touch(@realpath + '.parent')
154
+ end
155
+
156
+ def make_valid!
157
+ return if valid?
158
+
159
+ p = @parent
160
+ until p.nil?
161
+ p.make_parent!
162
+ p = p.parent
163
+ end
164
+
165
+ mkdir(@realpath) unless exist?
166
+ return nil
167
+ end
168
+
169
+ # returns the full name of the package
170
+ def uri
171
+ return '//' + path
172
+ end
173
+ alias :full_name :uri
174
+
175
+ # returns the path of the package (from the root_dir)
176
+ def path
177
+ return '' if workspace?
178
+ return @name if @parent.workspace?
179
+ return @parent.path + '/' + @name
180
+ end
181
+
182
+ # returns a list of subpackages. [] is returned if there are none.
183
+ def subpackages(include_disabled = false)
184
+ return [] unless parent?
185
+
186
+ children = @realpath.children.reject { |child| !child.directory? }
187
+
188
+ children.collect! do |child|
189
+ subpackage(child.basename.to_s)
190
+ end
191
+
192
+ unless include_disabled
193
+ children.reject! { |child| child.disabled? }
194
+ end
195
+
196
+ return children
197
+ end
198
+
199
+ # returns a Package object for the subpackage with the given name
200
+ # NOTE: a Package is returned, even when this package is not a valid parent
201
+ # or this package doesn't exist
202
+ def +(subpackage_name)
203
+ if subpackage_name.respond_to?(:to_ary)
204
+ name_stack = subpackage_name.to_ary
205
+ elsif subpackage_name.respond_to?(:to_s)
206
+ name_stack = subpackage_name.to_s.split(/\//).reverse
207
+ else
208
+ raise "illegal argument. only string or array is allowed here."
209
+ end
210
+
211
+ sub_name = name_stack.pop
212
+
213
+ if @subpackage_cache.key?(sub_name)
214
+ sub = @subpackage_cache[sub_name]
215
+ else
216
+ sub = Package.new(:name => sub_name, :parent => self)
217
+ @subpackage_cache[sub_name] = sub
218
+ end
219
+
220
+ if name_stack.empty?
221
+ return sub
222
+ else
223
+ return sub + name_stack
224
+ end
225
+ end
226
+
227
+ # returns nil if there is no such subpackage or
228
+ # the subpackage with the given name
229
+ def subpackage(subpackage_name)
230
+ return nil unless parent?
231
+
232
+ child = @realpath + subpackage_name
233
+ if child.exist?
234
+ # log "child found: #{subpackage_name} (#{child}) in #{full_name}"
235
+ return self + subpackage_name
236
+ else
237
+ # log "child not found: #{subpackage_name} (#{child}) in #{full_name}"
238
+ return nil
239
+ end
240
+
241
+ end
242
+
243
+ ### Recursive package operations
244
+ def list
245
+ subpackages.each do |s|
246
+ puts s.uri
247
+ end
248
+ end
249
+
250
+ # executes cmd with this packages as the wd, and with $this_package set to self
251
+ def execute(&block)
252
+ @execution_context.execute(&block)
253
+ end
254
+
255
+ @@orig_system = Kernel.method :system
256
+ def self.orig_system(*args); @@orig_system.call(*args); end
257
+
258
+ # executes cmd with this package as the wd
259
+ def system(cmd)
260
+ execute do |dir|
261
+ raise "error executing '#{cmd}' in #{dir}" unless Package.orig_system(cmd)
262
+ end
263
+ end
264
+
265
+ ### Target-related stuff
266
+ def descriptor_loaded?
267
+ return @descriptor_loaded
268
+ end
269
+
270
+ def descriptor
271
+ return "#{@realpath}/rakefile.rb"
272
+ end
273
+
274
+ def << (target)
275
+ @targets[target.name.to_sym] = target
276
+ return self
277
+ end
278
+
279
+ def load
280
+ return if descriptor_loaded?
281
+ @descriptor_loaded = true
282
+
283
+ pn = Pathname.new(descriptor)
284
+ unless pn.exist?
285
+ return if parent?
286
+ raise "package descriptor for #{@realpath} does not exist '#{pn}'"
287
+ end
288
+
289
+ @execution_context.wrap(pn.read, pn.realpath)
290
+ end
291
+
292
+ def target_dir(subdir=nil)
293
+ pn = @realpath + 'target'
294
+
295
+ unless subdir.nil?
296
+ pn += "#{subdir}/#{$build_dir_prefix}"
297
+ end
298
+
299
+ mkdir_p(pn) unless pn.exist?
300
+ return pn.realpath
301
+ end
302
+
303
+ def working_dir
304
+ target_dir('tmp')
305
+ end
306
+
307
+ def output_dir
308
+ target_dir('obj')
309
+ end
310
+
311
+ def clobber
312
+ rm_rf(working_dir)
313
+ rm_rf(output_dir)
314
+ end
315
+
316
+ def [](target_name)
317
+ load
318
+ return @targets[target_name.to_sym]
319
+ end
320
+
321
+ def targets
322
+ load
323
+ return @targets.values
324
+ end
325
+ end
326
+ end
@@ -0,0 +1,79 @@
1
+ module Filament
2
+ module Platform
3
+ TARGET_PLATFORMS = {}
4
+
5
+ def darwin?
6
+ return ! PLATFORM.index("darwin").nil?
7
+ end
8
+
9
+ def windows?
10
+ return cygwin?
11
+ end
12
+
13
+ def cygwin?
14
+ return ! PLATFORM.index("cygwin").nil?
15
+ end
16
+
17
+ def sys(c)
18
+ log c
19
+ raise "!!! Error executing '#{c}'" unless system(c)
20
+ end
21
+
22
+ def to_unix_path(path)
23
+ return nil if path.nil?
24
+ if cygwin?
25
+ return path unless /:\\/ === path
26
+ drive, path = path.split(":\\", 2)
27
+ path.gsub!(/\\/, '/')
28
+ return "/cygdrive/#{drive}/#{path}"
29
+ end
30
+ return path
31
+ end
32
+
33
+ def to_exec_path(path)
34
+ return nil if path.nil?
35
+ return to_unix_path(path) if cygwin?
36
+ return path
37
+ end
38
+
39
+ def to_windows_path(path)
40
+ return nil if path.nil?
41
+ if path.index('cygdrive').nil?
42
+ puts "#{path}\n"
43
+ return path
44
+ end
45
+
46
+ path = path.chomp.sub(/\/cygdrive\//, '')
47
+ drive, path = path.split(/\//, 2)
48
+
49
+ return "#{drive}:/#{path}"
50
+ end
51
+
52
+ def fix_paths(paths)
53
+ return nil if paths.nil?
54
+
55
+ if cygwin?
56
+ paths = paths.to_a.collect do |path|
57
+ to_windows_path(path)
58
+ end
59
+ end
60
+
61
+ return paths.to_a
62
+ end
63
+
64
+ def join_paths(paths)
65
+ return nil if paths.nil?
66
+
67
+ if windows?
68
+ joined = fix_paths(paths).join(';')
69
+ return "'#{joined}'"
70
+ end
71
+
72
+ return fix_paths(paths).join(':')
73
+ end
74
+
75
+ alias :u :to_unix_path
76
+ alias :w :to_windows_path
77
+ alias :fix :fix_paths
78
+ end
79
+ end
@@ -0,0 +1,32 @@
1
+ module Filament
2
+ def self.get_plugin_dirs(path)
3
+ pn = Pathname.new(path)
4
+ return pn.children.sort
5
+ end
6
+
7
+ def self.load_plugins(plugin_base_dir)
8
+ update_env(plugin_base_dir)
9
+
10
+ plugins = []
11
+ dirs = get_plugin_dirs(plugin_base_dir)
12
+ dirs.each do |child|
13
+ ln = child + 'lib'
14
+
15
+ if ln.exist?
16
+ $LOAD_PATH << ln.realpath
17
+ cn = ln + 'init.rb'
18
+ raise "cannot init filament plugin '#{child}'" unless cn.exist?
19
+ load cn.realpath
20
+ plugins << child.basename.to_s
21
+ end
22
+ end
23
+
24
+ puts "PLUGINS: #{plugins.join(', ')}"
25
+ end
26
+
27
+ def self.update_env(plugin_base_dir)
28
+ plugin_dirs = get_plugin_dirs(plugin_base_dir)
29
+ script_dirs = plugin_dirs.collect {|dir| dir + 'script' }
30
+ ENV['PATH'] = script_dirs.join(':') + ':' + ENV['PATH']
31
+ end
32
+ end