flak 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +59 -0
- data/flak.gemspec +2 -2
- data/lib/flak.rb +16 -341
- data/lib/flak/rake/base.rb +312 -0
- data/lib/flak/{cpp.rb → rake/cpp.rb} +6 -4
- data/lib/flak/{delight.rb → rake/delight.rb} +3 -3
- data/lib/flak/rake/doc.rb +64 -0
- data/lib/flak/{gl.rb → rake/gl.rb} +1 -1
- data/lib/flak/{mac.rb → rake/mac.rb} +1 -1
- data/lib/flak/{max.rb → rake/max.rb} +1 -1
- data/lib/flak/{maya.rb → rake/maya.rb} +7 -7
- data/lib/flak/{maya_app.rb → rake/maya_app.rb} +1 -1
- data/lib/flak/{maya_plugin.rb → rake/maya_plugin.rb} +1 -1
- data/lib/flak/{nuke.rb → rake/nuke.rb} +1 -1
- data/lib/flak/{target.rb → rake/target.rb} +9 -19
- data/lib/flak/thor/generate.rb +108 -184
- data/lib/flak/thor/target_file.rb +62 -0
- data/lib/flak/thor/templates/INSTALL.tt +15 -13
- data/lib/flak/thor/templates/doc.tt +0 -0
- data/lib/flak/thor/templates/doc/Rules +77 -0
- data/lib/flak/thor/templates/doc/config.yaml +77 -0
- data/lib/flak/thor/templates/doc/content/assets/css/include.scss +14 -0
- data/lib/flak/thor/templates/doc/content/assets/css/page.scss +314 -0
- data/lib/flak/thor/templates/doc/content/assets/images/.empty_directory +1 -0
- data/lib/flak/thor/templates/doc/content/assets/images/screenshot.jpg +0 -0
- data/lib/flak/thor/templates/doc/content/assets/movies/.empty_directory +1 -0
- data/lib/flak/thor/templates/doc/content/assets/movies/sampleMovie.webm +0 -0
- data/lib/flak/thor/templates/doc/content/assets/site_images/array.gif +0 -0
- data/lib/flak/thor/templates/doc/content/assets/site_images/connectable.gif +0 -0
- data/lib/flak/thor/templates/doc/content/assets/site_images/create.gif +0 -0
- data/lib/flak/thor/templates/doc/content/assets/site_images/edit.gif +0 -0
- data/lib/flak/thor/templates/doc/content/assets/site_images/hidden.gif +0 -0
- data/lib/flak/thor/templates/doc/content/assets/site_images/input.gif +0 -0
- data/lib/flak/thor/templates/doc/content/assets/site_images/keyable.gif +0 -0
- data/lib/flak/thor/templates/doc/content/assets/site_images/logo.jpg +0 -0
- data/lib/flak/thor/templates/doc/content/assets/site_images/maya.png +0 -0
- data/lib/flak/thor/templates/doc/content/assets/site_images/miro_logo_bw.png +0 -0
- data/lib/flak/thor/templates/doc/content/assets/site_images/multiuse.gif +0 -0
- data/lib/flak/thor/templates/doc/content/assets/site_images/nanoc.png +0 -0
- data/lib/flak/thor/templates/doc/content/assets/site_images/nuke.png +0 -0
- data/lib/flak/thor/templates/doc/content/assets/site_images/output.gif +0 -0
- data/lib/flak/thor/templates/doc/content/assets/site_images/prman.png +0 -0
- data/lib/flak/thor/templates/doc/content/assets/site_images/python.png +0 -0
- data/lib/flak/thor/templates/doc/content/assets/site_images/query.gif +0 -0
- data/lib/flak/thor/templates/doc/content/assets/site_images/storable.gif +0 -0
- data/lib/flak/thor/templates/doc/content/assets/site_images/vfxoverflow_ribbon.png +0 -0
- data/lib/flak/thor/templates/doc/content/assets/site_images/vray.png +0 -0
- data/lib/flak/thor/templates/doc/content/index.txt.tt +31 -0
- data/lib/flak/thor/templates/doc/content/install_guide.txt.tt +64 -0
- data/lib/flak/thor/templates/doc/content/release_notes.txt.tt +44 -0
- data/lib/flak/thor/templates/doc/content/scenes/.empty_directory +1 -0
- data/lib/flak/thor/templates/doc/content/tutorial.txt.tt +81 -0
- data/lib/flak/thor/templates/doc/layouts/default.html +52 -0
- data/lib/flak/thor/templates/doc/lib/helpers.rb +147 -0
- data/lib/flak/thor/templates/env.tt +29 -1
- data/lib/flak/thor/templates/gitignore.tt +3 -0
- data/lib/flak/thor/templates/init.mel.tt +22 -0
- data/lib/flak/thor/templates/product.mel.tt +15 -10
- data/lib/flak/thor/wizard.rb +47 -0
- data/lib/flak/version.rb +1 -1
- metadata +120 -63
- data/lib/flak/doc.rb +0 -259
data/README.textile
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
h1. Flak
|
2
|
+
|
3
|
+
h2. _Flak is Under development - there are hardly any docs or anything at the moment. Best not to use until this message goes away_
|
4
|
+
|
5
|
+
h2. What is flak?
|
6
|
+
|
7
|
+
Flak is a framework to help you write VFX tools. You will find it especially useful if you write tools for Maya but it also helps you write shell scripts, Nuke tools, 3delight shaders and more.
|
8
|
+
|
9
|
+
Flak projects use Rake (Ruby Make), so there are common configuration files across all platforms.
|
10
|
+
|
11
|
+
Flak also encourages good documentation by setting up a website skeleton based on "nanoc":http://http://nanoc.stoneship.org/. There are templates for an introduction page, release notes, installation guide, and tutorials so you can concentrate on content and let flak handle presentation at compile time. In addition there are Maya tools to generate flak documentation for nodes and commands.
|
12
|
+
|
13
|
+
h2. Project structure
|
14
|
+
|
15
|
+
A flak project produces a module at build time. We'll use the word 'project' for the local source, and 'module' for the compiled result.
|
16
|
+
|
17
|
+
A module contains any number of tools, each of which can have at most one compiled target plus any number of scripts, icons or other support files. As such, your local flak project contains a subdirectory containing source files for each tool. In addition, the project will contain project wide-configuration files and a documentation tree.
|
18
|
+
|
19
|
+
Each tool directory contains a structure where you arrange your source code. This structure is flexible, although sensible defaults will be set up at generation time.
|
20
|
+
|
21
|
+
h2. Example workflow
|
22
|
+
|
23
|
+
Lets say you want a project called flintstone with tools fred and wilma. You would issue the generate command for the project:
|
24
|
+
|
25
|
+
flak generate project flintstone
|
26
|
+
|
27
|
+
It will ask a few questions about the kind of module you want to make. Then:
|
28
|
+
|
29
|
+
cd flintstone
|
30
|
+
flak generate tool fred
|
31
|
+
flak generate tool wilma
|
32
|
+
|
33
|
+
There are shortcuts: g = generate, p = project, t = tool. So the commands above could be entered as:
|
34
|
+
|
35
|
+
flak g p flintstone
|
36
|
+
flak g t fred
|
37
|
+
flak g t wilma
|
38
|
+
|
39
|
+
At this point, you have a skeleton project set up. Then you would edit config files where necessary, write your code and documentation and finally type:
|
40
|
+
|
41
|
+
rake
|
42
|
+
rake doc
|
43
|
+
|
44
|
+
This will build and release the module and the documentation site. Whether you release locally or in a shared location, users can install the module by in their environment by running the install script:
|
45
|
+
<pre><path to module>/bin/INSTALL_FLINTSTONE</pre>
|
46
|
+
|
47
|
+
There's much more coolness which we'll get into. So now you've seen how easy it is to develop using flak, lets get started.
|
48
|
+
|
49
|
+
h2. Getting flak
|
50
|
+
|
51
|
+
Flak is a ruby gem. So update rubygems, just to be sure, then install the gem:
|
52
|
+
|
53
|
+
gem update --system
|
54
|
+
|
55
|
+
gem install flak
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
|
data/flak.gemspec
CHANGED
data/lib/flak.rb
CHANGED
@@ -8,350 +8,25 @@ require 'erb'
|
|
8
8
|
require "thor"
|
9
9
|
require "thor/group"
|
10
10
|
require "ap"
|
11
|
-
|
11
|
+
require 'nanoc'
|
12
12
|
require 'core_ext/string'
|
13
13
|
|
14
|
-
require 'flak/cpp'
|
15
|
-
require 'flak/delight'
|
16
|
-
require 'flak/doc'
|
17
|
-
require 'flak/gl'
|
18
|
-
require 'flak/mac'
|
19
|
-
require 'flak/max'
|
20
|
-
require 'flak/maya'
|
21
|
-
require 'flak/maya_app'
|
22
|
-
require 'flak/maya_plugin'
|
23
|
-
require 'flak/nuke'
|
24
|
-
require 'flak/target'
|
14
|
+
require 'flak/rake/cpp'
|
15
|
+
require 'flak/rake/delight'
|
16
|
+
require 'flak/rake/doc'
|
17
|
+
require 'flak/rake/gl'
|
18
|
+
require 'flak/rake/mac'
|
19
|
+
require 'flak/rake/max'
|
20
|
+
require 'flak/rake/maya'
|
21
|
+
require 'flak/rake/maya_app'
|
22
|
+
require 'flak/rake/maya_plugin'
|
23
|
+
require 'flak/rake/nuke'
|
24
|
+
require 'flak/rake/target'
|
25
|
+
require 'flak/rake/base'
|
26
|
+
|
25
27
|
require 'flak/version'
|
28
|
+
require 'flak/thor/wizard'
|
29
|
+
require 'flak/thor/target_file'
|
26
30
|
require 'flak/thor/generate'
|
27
31
|
require 'flak/thor/cli'
|
28
32
|
|
29
|
-
|
30
|
-
|
31
|
-
module Flak
|
32
|
-
|
33
|
-
# return a slightly nicer OS string than the
|
34
|
-
# RUBY_PLATFORM variable
|
35
|
-
def self.os
|
36
|
-
case RUBY_PLATFORM
|
37
|
-
when /64-linux/
|
38
|
-
'linux_64'
|
39
|
-
when /i686_linux/
|
40
|
-
'linux_32'
|
41
|
-
when /darwin/
|
42
|
-
'darwin'
|
43
|
-
when /i386-cygwin/
|
44
|
-
'win_64'
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
# merge_setting TODO - move to a Hash#merge block
|
51
|
-
# if the same key is being offered and the value is an array, then we merge the arrays.
|
52
|
-
# otherwise it is a string, so the new one overrides the existing one.
|
53
|
-
def self.merge_setting(hash, setting_key, setting_value)
|
54
|
-
if hash.has_key?(setting_key)
|
55
|
-
if setting_value.kind_of?(Array)
|
56
|
-
hash[setting_key.to_sym] |= setting_value
|
57
|
-
else
|
58
|
-
hash[(setting_key.to_sym)] = setting_value
|
59
|
-
end
|
60
|
-
else
|
61
|
-
hash[(setting_key.to_sym)] = setting_value
|
62
|
-
end
|
63
|
-
hash
|
64
|
-
end
|
65
|
-
|
66
|
-
|
67
|
-
# given a yml settings file, resolve the configuration and OS
|
68
|
-
# and return the new flattened hash
|
69
|
-
def self.merge_settings(hash1,hash2)
|
70
|
-
hash2.each do |k,v|
|
71
|
-
merge_setting(hash1,k,v)
|
72
|
-
end
|
73
|
-
hash1
|
74
|
-
end
|
75
|
-
|
76
|
-
# given a yml settings file, resolve the configuration and OS
|
77
|
-
# and return the new flattened hash
|
78
|
-
def self.flatten_settings(yml,configuration, os)
|
79
|
-
|
80
|
-
h = Hash.new
|
81
|
-
y_hash = YAML::load_file( yml) || {}
|
82
|
-
y_hash.each do |k,v|
|
83
|
-
|
84
|
-
# root level settings
|
85
|
-
################
|
86
|
-
if ( ! ((k =~/^os_.*/) || (k =~/^configuration_.*/)) )
|
87
|
-
h =Flak.merge_setting(h,k.to_sym, v)
|
88
|
-
else
|
89
|
-
|
90
|
-
# os specific settings
|
91
|
-
################
|
92
|
-
if (k == "os_#{os}" )
|
93
|
-
# puts "OS => #{os}"
|
94
|
-
v.each do |k1,v1|
|
95
|
-
if (k1 =~ /^configuration_.*/ )
|
96
|
-
if (k1 == "configuration_#{configuration}" )
|
97
|
-
v1.each do |k2,v2|
|
98
|
-
h =Flak.merge_setting(h,k2.to_sym, v2)
|
99
|
-
end
|
100
|
-
end
|
101
|
-
else
|
102
|
-
h=Flak.merge_setting(h,k1.to_sym, v1)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
else
|
106
|
-
# configuration settings (not os specific)
|
107
|
-
################
|
108
|
-
if (k == "configuration_#{configuration}" )
|
109
|
-
v.each do |k1,v1|
|
110
|
-
h=Flak.merge_setting(h,k1.to_sym, v1)
|
111
|
-
end
|
112
|
-
end
|
113
|
-
################
|
114
|
-
end
|
115
|
-
|
116
|
-
end
|
117
|
-
################
|
118
|
-
end
|
119
|
-
# ap h
|
120
|
-
h
|
121
|
-
end
|
122
|
-
|
123
|
-
|
124
|
-
# method responsible for returning a flat and comprehensive
|
125
|
-
# settings hash by gathering all the base config settings from
|
126
|
-
# yaml and generating others programatically.
|
127
|
-
# This settings hash will be used by targets, and by the
|
128
|
-
# release mechanism.
|
129
|
-
def self.resolve_settings( existing_settings )
|
130
|
-
|
131
|
-
# bootstrap to get the configuration and the os up front because these are needed to
|
132
|
-
# handle the logic to extract the right configuration and os settings from this and
|
133
|
-
# all subsequent yml files
|
134
|
-
# f = File.dirname(File.dirname(__FILE__)) + '/config/base.yml'
|
135
|
-
# tmp = YAML::load_file( base_file )
|
136
|
-
|
137
|
-
f = existing_settings[:root] + '/config/env.yml'
|
138
|
-
h =Flak.flatten_settings(f, existing_settings[:configuration], existing_settings[:os] )
|
139
|
-
h[:root] = existing_settings[:root]
|
140
|
-
h[:os] = Flak.os
|
141
|
-
|
142
|
-
# after this point we get values from the hash (h) wherever possible -
|
143
|
-
# Why? - because h is the flattened hash - meaning that configuration and OS specific
|
144
|
-
# settings will be correct. For example, product_revision may be different for debug and release
|
145
|
-
# sr = File.dirname(File.dirname(File.dirname(__FILE__)))
|
146
|
-
# sr = File.join("/cygdrive/c/cygwin",sr) if (Flak.os == 'win_64')
|
147
|
-
|
148
|
-
#h.merge!({:os => Flak.os})
|
149
|
-
|
150
|
-
h[:build_dir] = File.join("build", h[:product_revision] , h[:os])
|
151
|
-
h[:release_root] = File.join(h[:target_release_path], h[:product_name])
|
152
|
-
|
153
|
-
|
154
|
-
h[:versioned_os_release_path] = File.join( h[:release_root] , "#{h[:product_revision]}-#{h[:os]}" )
|
155
|
-
h[:doc_dirname] = "#{h[:product_revision]}-doc"
|
156
|
-
h[:doc_release_root] = File.join( h[:release_root] , h[:doc_dirname] )
|
157
|
-
|
158
|
-
# ap h
|
159
|
-
|
160
|
-
|
161
|
-
h
|
162
|
-
end
|
163
|
-
|
164
|
-
# in order to make a symlink, we need to remove it
|
165
|
-
# if it already exists
|
166
|
-
def self.rebuild_symlink(target_file,new_file)
|
167
|
-
if File.symlink?(new_file)
|
168
|
-
File.unlink(new_file)
|
169
|
-
end
|
170
|
-
File.symlink(target_file, new_file)
|
171
|
-
end
|
172
|
-
|
173
|
-
# if we just copy src to dest and dest exists and is a directory,
|
174
|
-
# then the src is put in the dest, as opposed to overwriting it. For
|
175
|
-
# this reason, we delete dest first.
|
176
|
-
def self.copy_over(src,dest)
|
177
|
-
remove_file(dest, true)
|
178
|
-
cp_r src, dest
|
179
|
-
end
|
180
|
-
|
181
|
-
|
182
|
-
# make a directory for a file
|
183
|
-
def self.make_dir_for(file)
|
184
|
-
FileUtils.mkdir_p file.pathmap('%d')
|
185
|
-
end
|
186
|
-
|
187
|
-
|
188
|
-
####################################################################################
|
189
|
-
######################### I N S T A N C E M E T H O D S ##########################
|
190
|
-
####################################################################################
|
191
|
-
def filename
|
192
|
-
f = @settings[:name]
|
193
|
-
f = f.ext(@settings[:target_extension] ) unless @settings[:target_extension].nil?
|
194
|
-
f = File.join(@settings[:build_dir],f)
|
195
|
-
end
|
196
|
-
|
197
|
-
|
198
|
-
def shell_script_release_path(file)
|
199
|
-
File.join(@settings[:versioned_os_release_path], 'bin', file.pathmap('%f'))
|
200
|
-
end
|
201
|
-
|
202
|
-
|
203
|
-
def write_erb_template(erb_file,released_file, opts={})
|
204
|
-
if (!(opts[:no_force] && File.exists?(released_file) ))
|
205
|
-
product_name = @settings[:product_name]
|
206
|
-
template = ERB.new( File.read(erb_file) , 0, "%<>")
|
207
|
-
File.open(released_file, 'w') do |f|
|
208
|
-
f.puts(template.result(binding))
|
209
|
-
f.chmod(opts[:chmod].to_i) if opts[:chmod]
|
210
|
-
end
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
def base_instance_tasks
|
217
|
-
|
218
|
-
namespace @settings[:name].to_sym do
|
219
|
-
|
220
|
-
if @settings[:name] == 'jRelease'
|
221
|
-
desc "Build everything"
|
222
|
-
task :build
|
223
|
-
|
224
|
-
clobber_list = [File.dirname(@settings[:build_dir]) , @settings[:versioned_os_release_path]]
|
225
|
-
CLOBBER.include( clobber_list )
|
226
|
-
end
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
# We want to release erb files by binding them using ERB. To help identify erb files we define them in
|
231
|
-
# yaml files under the key <type>_erb_files e.g. shell_erb_files or maya_script_erb_files for example
|
232
|
-
|
233
|
-
##############################################
|
234
|
-
erb_keys = @settings.keys.find_all {|el| ( el.to_s =~ /^.*_erb_files$/)}
|
235
|
-
|
236
|
-
erb_keys.each do |k|
|
237
|
-
type = k.to_s.gsub("_erb_files", "") # shell or mel
|
238
|
-
files_key = type.to_sym # :shell or :mel
|
239
|
-
|
240
|
-
release_path_proc = "#{type}_release_path".to_sym
|
241
|
-
|
242
|
-
# ap [type, files_key, release_path_proc]
|
243
|
-
|
244
|
-
files = @settings[k]
|
245
|
-
unless files.nil?
|
246
|
-
|
247
|
-
files.each do |f|
|
248
|
-
|
249
|
-
# if a filename is a key in the settings hash
|
250
|
-
# and that key is a string, replace the filename with the
|
251
|
-
# value. Also, get rid of the erb extension
|
252
|
-
# For example, if @settings[:product_name] is 'jtools' then
|
253
|
-
# product_name.csh.erb becomes jtools.csh
|
254
|
-
filename_key = f.pathmap('%f').gsub(/\..*/,'').to_sym
|
255
|
-
|
256
|
-
|
257
|
-
# hack chmod for INSTALL - really must find a better way soon
|
258
|
-
write_erb_opts = (filename_key == :INSTALL) ? {:chmod => 0755} : {}
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
f_resolved = f.pathmap('%f').pathmap('%n')
|
263
|
-
#ap filename_key
|
264
|
-
if @settings.has_key?(filename_key)
|
265
|
-
|
266
|
-
#if @settings[filename_key].kind_of?(Symbol)
|
267
|
-
f_resolved = "#{@settings[filename_key]}#{f_resolved.pathmap('%x')}"
|
268
|
-
# puts f_resolved
|
269
|
-
#end
|
270
|
-
end
|
271
|
-
|
272
|
-
released_file = self.send release_path_proc, f_resolved
|
273
|
-
|
274
|
-
|
275
|
-
file released_file => f do
|
276
|
-
|
277
|
-
Flak.make_dir_for(released_file)
|
278
|
-
write_erb_template(f,released_file,write_erb_opts)
|
279
|
-
end
|
280
|
-
|
281
|
-
desc "bind and release ERB #{released_file.pathmap('%f')}"
|
282
|
-
task released_file.pathmap('%f') => released_file
|
283
|
-
|
284
|
-
task :release => released_file.pathmap('%f')
|
285
|
-
end
|
286
|
-
end
|
287
|
-
end
|
288
|
-
##############################################
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
# @settings[:copy_only] is an array of file types that should be copied
|
293
|
-
# for example ruby files.
|
294
|
-
# If so, there should be a proc called ruby_release_path which responsible for generating the release path
|
295
|
-
# this smells a bit - not sure if it can be fixed - we will see
|
296
|
-
##############################################
|
297
|
-
copy_keys = @settings.keys.find_all {|el| ( el.to_s =~ /^.*_copy_files$/)}
|
298
|
-
|
299
|
-
copy_keys.each do |k|
|
300
|
-
type = k.to_s.gsub("_copy_files", "")
|
301
|
-
|
302
|
-
#@settings[:copy_only].each do |type|
|
303
|
-
#files_key = "#{type}_files".to_sym
|
304
|
-
release_path_proc = "#{type}_release_path".to_sym
|
305
|
-
files = @settings[k]
|
306
|
-
|
307
|
-
ap files if release_path_proc == "shell_script_release_path"
|
308
|
-
|
309
|
-
#files = @settings[files_key]
|
310
|
-
unless files.nil?
|
311
|
-
|
312
|
-
files.each do |f|
|
313
|
-
released_file = self.send release_path_proc, f
|
314
|
-
file released_file => f do
|
315
|
-
Flak.make_dir_for(released_file)
|
316
|
-
sh "cp -r #{f} #{released_file}"
|
317
|
-
File.chmod 0755, released_file if (type == 'shell' )
|
318
|
-
end
|
319
|
-
task :release => released_file
|
320
|
-
end
|
321
|
-
end
|
322
|
-
end
|
323
|
-
##############################################
|
324
|
-
|
325
|
-
desc "See resolved configuration settings for #{@settings[:name].to_sym}"
|
326
|
-
task :inspect do
|
327
|
-
ap @settings
|
328
|
-
end
|
329
|
-
|
330
|
-
desc "Release #{@settings[:name].to_sym}"
|
331
|
-
task :release # => [:rebuild_label_link ]
|
332
|
-
|
333
|
-
|
334
|
-
# every target needs the ability to initialize a doc hierarchy
|
335
|
-
# so this is where it goes
|
336
|
-
namespace :doc do
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
end # namespace doc
|
341
|
-
|
342
|
-
end # namespace name
|
343
|
-
|
344
|
-
task :release => "#{@settings[:name].to_sym}:release"
|
345
|
-
|
346
|
-
task :default => ["release"]
|
347
|
-
|
348
|
-
task :inspect do
|
349
|
-
ap @settings
|
350
|
-
end
|
351
|
-
|
352
|
-
end
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
end
|
@@ -0,0 +1,312 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module Flak
|
4
|
+
|
5
|
+
module Base
|
6
|
+
# return a slightly nicer OS string than the
|
7
|
+
# RUBY_PLATFORM variable
|
8
|
+
def self.os
|
9
|
+
case RUBY_PLATFORM
|
10
|
+
when /64-linux/
|
11
|
+
'linux_64'
|
12
|
+
when /i686_linux/
|
13
|
+
'linux_32'
|
14
|
+
when /darwin/
|
15
|
+
'darwin'
|
16
|
+
when /i386-cygwin/
|
17
|
+
'win_64'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
# merge_setting TODO - move to a Hash#merge block
|
24
|
+
# if the same key is being offered and the value is an array, then we merge the arrays.
|
25
|
+
# otherwise it is a string, so the new one overrides the existing one.
|
26
|
+
def self.merge_setting(hash, setting_key, setting_value)
|
27
|
+
if hash.has_key?(setting_key)
|
28
|
+
if setting_value.kind_of?(Array)
|
29
|
+
hash[setting_key.to_sym] |= setting_value
|
30
|
+
else
|
31
|
+
hash[(setting_key.to_sym)] = setting_value
|
32
|
+
end
|
33
|
+
else
|
34
|
+
hash[(setting_key.to_sym)] = setting_value
|
35
|
+
end
|
36
|
+
hash
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
# given a yml settings file, resolve the configuration and OS
|
41
|
+
# and return the new flattened hash
|
42
|
+
def self.merge_settings(hash1,hash2)
|
43
|
+
hash2.each do |k,v|
|
44
|
+
merge_setting(hash1,k,v)
|
45
|
+
end
|
46
|
+
hash1
|
47
|
+
end
|
48
|
+
|
49
|
+
# given a yml settings file, resolve the configuration and OS
|
50
|
+
# and return the new flattened hash
|
51
|
+
def self.flatten_settings(yml,configuration, os)
|
52
|
+
|
53
|
+
h = Hash.new
|
54
|
+
y_hash = YAML::load_file( yml) || {}
|
55
|
+
y_hash.each do |k,v|
|
56
|
+
|
57
|
+
# root level settings
|
58
|
+
################
|
59
|
+
if ( ! ((k =~/^os_.*/) || (k =~/^configuration_.*/)) )
|
60
|
+
h =Flak::Base.merge_setting(h,k.to_sym, v)
|
61
|
+
else
|
62
|
+
|
63
|
+
# os specific settings
|
64
|
+
################
|
65
|
+
if (k == "os_#{os}" )
|
66
|
+
# puts "OS => #{os}"
|
67
|
+
v.each do |k1,v1|
|
68
|
+
if (k1 =~ /^configuration_.*/ )
|
69
|
+
if (k1 == "configuration_#{configuration}" )
|
70
|
+
v1.each do |k2,v2|
|
71
|
+
h =Flak::Base.merge_setting(h,k2.to_sym, v2)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
else
|
75
|
+
h=Flak::Base.merge_setting(h,k1.to_sym, v1)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
else
|
79
|
+
# configuration settings (not os specific)
|
80
|
+
################
|
81
|
+
if (k == "configuration_#{configuration}" )
|
82
|
+
v.each do |k1,v1|
|
83
|
+
h=Flak::Base.merge_setting(h,k1.to_sym, v1)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
################
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
################
|
91
|
+
end
|
92
|
+
# ap h
|
93
|
+
h
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
# method responsible for returning a flat and comprehensive
|
98
|
+
# settings hash by gathering all the base config settings from
|
99
|
+
# yaml and generating others programatically.
|
100
|
+
# This settings hash will be used by targets, and by the
|
101
|
+
# release mechanism.
|
102
|
+
def self.resolve_settings( existing_settings )
|
103
|
+
|
104
|
+
# bootstrap to get the configuration and the os up front because these are needed to
|
105
|
+
# handle the logic to extract the right configuration and os settings from this and
|
106
|
+
# all subsequent yml files
|
107
|
+
# f = File.dirname(File.dirname(__FILE__)) + '/config/base.yml'
|
108
|
+
# tmp = YAML::load_file( base_file )
|
109
|
+
|
110
|
+
f = existing_settings[:root] + '/config/env.yml'
|
111
|
+
h =Flak::Base.flatten_settings(f, existing_settings[:configuration], existing_settings[:os] )
|
112
|
+
h[:root] = existing_settings[:root]
|
113
|
+
|
114
|
+
h[:os] = Flak::Base.os
|
115
|
+
|
116
|
+
# after this point we get values from the hash (h) wherever possible -
|
117
|
+
# Why? - because h is the flattened hash - meaning that configuration and OS specific
|
118
|
+
# settings will be correct. For example, product_revision may be different for debug and release
|
119
|
+
# sr = File.dirname(File.dirname(File.dirname(__FILE__)))
|
120
|
+
# sr = File.join("/cygdrive/c/cygwin",sr) if (Flak::Base.os == 'win_64')
|
121
|
+
|
122
|
+
#h.merge!({:os => Flak::Base.os})
|
123
|
+
|
124
|
+
h[:build_dir] = File.join("build", h[:product_revision] , h[:os])
|
125
|
+
h[:release_root] = File.join(h[:target_release_path], h[:product_name])
|
126
|
+
|
127
|
+
|
128
|
+
h[:versioned_os_release_path] = File.join( h[:release_root] , h[:product_revision] )
|
129
|
+
h[:versioned_os_release_path] += "-#{h[:os]}" unless h[:agnostic]
|
130
|
+
|
131
|
+
h[:doc_dirname] = "#{h[:product_revision]}-doc"
|
132
|
+
h[:doc_release_root] = File.join( h[:release_root] , h[:doc_dirname] )
|
133
|
+
|
134
|
+
# ap h
|
135
|
+
|
136
|
+
|
137
|
+
h
|
138
|
+
end
|
139
|
+
|
140
|
+
# in order to make a symlink, we need to remove it
|
141
|
+
# if it already exists
|
142
|
+
def self.rebuild_symlink(target_file,new_file)
|
143
|
+
if File.symlink?(new_file)
|
144
|
+
File.unlink(new_file)
|
145
|
+
end
|
146
|
+
File.symlink(target_file, new_file)
|
147
|
+
end
|
148
|
+
|
149
|
+
# if we just copy src to dest and dest exists and is a directory,
|
150
|
+
# then the src is put in the dest, as opposed to overwriting it. For
|
151
|
+
# this reason, we delete dest first.
|
152
|
+
def self.copy_over(src,dest)
|
153
|
+
remove_file(dest, true)
|
154
|
+
cp_r src, dest
|
155
|
+
end
|
156
|
+
|
157
|
+
|
158
|
+
# make a directory for a file
|
159
|
+
def self.make_dir_for(file)
|
160
|
+
FileUtils.mkdir_p file.pathmap('%d')
|
161
|
+
end
|
162
|
+
|
163
|
+
|
164
|
+
####################################################################################
|
165
|
+
######################### I N S T A N C E M E T H O D S ##########################
|
166
|
+
####################################################################################
|
167
|
+
def filename
|
168
|
+
f = @settings[:name]
|
169
|
+
f = f.ext(@settings[:target_extension] ) unless @settings[:target_extension].nil?
|
170
|
+
f = File.join(@settings[:build_dir],f)
|
171
|
+
end
|
172
|
+
|
173
|
+
|
174
|
+
def shell_script_release_path(file)
|
175
|
+
File.join(@settings[:versioned_os_release_path], 'bin', file.pathmap('%f'))
|
176
|
+
end
|
177
|
+
|
178
|
+
|
179
|
+
def write_erb_template(erb_file,released_file, opts={})
|
180
|
+
if (!(opts[:no_force] && File.exists?(released_file) ))
|
181
|
+
product_name = @settings[:product_name]
|
182
|
+
template = ERB.new( File.read(erb_file) , 0, "%<>")
|
183
|
+
File.open(released_file, 'w') do |f|
|
184
|
+
puts "template #{erb_file} #{released_file}"
|
185
|
+
f.puts(template.result(binding))
|
186
|
+
f.chmod(opts[:chmod].to_i) if opts[:chmod]
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
|
192
|
+
|
193
|
+
def base_instance_tasks
|
194
|
+
|
195
|
+
|
196
|
+
namespace @settings[:name].to_sym do
|
197
|
+
|
198
|
+
desc "Build everything"
|
199
|
+
task :build
|
200
|
+
|
201
|
+
CLEAN.include( File.dirname(@settings[:build_dir]) ) unless CLEAN.include? File.dirname(@settings[:build_dir])
|
202
|
+
|
203
|
+
CLOBBER.include( @settings[:versioned_os_release_path]) unless CLOBBER.include? @settings[:versioned_os_release_path]
|
204
|
+
|
205
|
+
|
206
|
+
# We want to release erb files by binding them using ERB. To help identify erb files we define them in
|
207
|
+
# yaml files under the key <type>_erb_files e.g. shell_erb_files or maya_script_erb_files for example
|
208
|
+
|
209
|
+
##############################################
|
210
|
+
erb_keys = @settings.keys.find_all {|el| ( el.to_s =~ /^.*_erb_files$/)}
|
211
|
+
|
212
|
+
erb_keys.each do |k|
|
213
|
+
type = k.to_s.gsub("_erb_files", "") # shell or mel
|
214
|
+
files_key = type.to_sym # :shell or :mel
|
215
|
+
|
216
|
+
release_path_proc = "#{type}_release_path".to_sym
|
217
|
+
|
218
|
+
files = @settings[k]
|
219
|
+
unless files.nil?
|
220
|
+
|
221
|
+
files.each do |f|
|
222
|
+
|
223
|
+
# if a filename is a key in the settings hash
|
224
|
+
# and that key is a string, replace the filename with the
|
225
|
+
# value. Also, get rid of the erb extension
|
226
|
+
# For example, if @settings[:product_name] is 'jtools' then
|
227
|
+
# product_name.csh.erb becomes jtools.csh
|
228
|
+
filename_key = f.pathmap('%f').gsub(/\..*/,'').to_sym
|
229
|
+
|
230
|
+
# hack chmod for INSTALL - really must find a better way soon
|
231
|
+
# write_erb_opts = (filename_key == :INSTALL) ? {:chmod => 0755} : {}
|
232
|
+
write_erb_opts = {:chmod => 0755}
|
233
|
+
|
234
|
+
f_resolved = f.pathmap('%f').pathmap('%n')
|
235
|
+
if @settings.has_key?(filename_key)
|
236
|
+
f_resolved = "#{@settings[filename_key]}#{f_resolved.pathmap('%x')}"
|
237
|
+
end
|
238
|
+
|
239
|
+
released_file = self.send release_path_proc, f_resolved
|
240
|
+
|
241
|
+
|
242
|
+
file released_file => f do
|
243
|
+
|
244
|
+
Flak::Base.make_dir_for(released_file)
|
245
|
+
write_erb_template(f,released_file,write_erb_opts)
|
246
|
+
end
|
247
|
+
|
248
|
+
desc "bind and release ERB #{released_file.pathmap('%f')}"
|
249
|
+
task released_file.pathmap('%f') => released_file
|
250
|
+
|
251
|
+
task :release => released_file.pathmap('%f')
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
##############################################
|
256
|
+
|
257
|
+
|
258
|
+
|
259
|
+
# copy_keys is an array of keys representing file types that should be copied
|
260
|
+
# for example maya_script_copy_files
|
261
|
+
# If so, there should be a proc called maya_script_release_path which is responsible for generating the release path
|
262
|
+
# this smells a bit - not sure if it can be fixed - we will see
|
263
|
+
##############################################
|
264
|
+
copy_keys = @settings.keys.find_all {|el| ( el.to_s =~ /^.*_copy_files$/)}
|
265
|
+
|
266
|
+
copy_keys.each do |k|
|
267
|
+
type = k.to_s.gsub("_copy_files", "")
|
268
|
+
|
269
|
+
release_path_proc = "#{type}_release_path".to_sym
|
270
|
+
files = @settings[k]
|
271
|
+
|
272
|
+
unless files.nil?
|
273
|
+
|
274
|
+
files.each do |f|
|
275
|
+
released_file = self.send release_path_proc, f
|
276
|
+
file released_file => f do
|
277
|
+
Flak::Base.make_dir_for(released_file)
|
278
|
+
sh "cp -r #{f} #{released_file}"
|
279
|
+
File.chmod 0755, released_file if (type == 'shell' )
|
280
|
+
end
|
281
|
+
task :release => released_file
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
285
|
+
##############################################
|
286
|
+
|
287
|
+
desc "See resolved configuration settings for #{@settings[:name].to_sym}"
|
288
|
+
task :inspect do
|
289
|
+
ap @settings
|
290
|
+
end
|
291
|
+
|
292
|
+
desc "Release #{@settings[:name].to_sym}"
|
293
|
+
task :release # => [:rebuild_label_link ]
|
294
|
+
|
295
|
+
end # namespace name
|
296
|
+
|
297
|
+
task :release => "#{@settings[:name].to_sym}:release"
|
298
|
+
|
299
|
+
task :default => ["release"]
|
300
|
+
|
301
|
+
task :inspect do
|
302
|
+
ap @settings
|
303
|
+
end
|
304
|
+
|
305
|
+
end
|
306
|
+
|
307
|
+
|
308
|
+
end
|
309
|
+
|
310
|
+
|
311
|
+
|
312
|
+
end
|