asrake 0.8.1 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,7 +1,10 @@
1
1
  ASRake
2
2
  ======
3
3
 
4
- **Rake library for Actionscript 3 projects**
4
+ **A Rake library for Actionscript 3, Flex, and AIR projects.**
5
+
6
+ ### `gem install asrake`
7
+
5
8
 
6
9
  Overview
7
10
  --------
@@ -21,6 +24,7 @@ Arguments match those passed to the compiler (mxmlc, compc, adt, etc) with hyphe
21
24
 
22
25
  Convenience methods are provided for `include_libraries`, `external_library_path`, and `library_path`; you can instead use `statically_link`, `dynamically_link`, and `statically_link_only_referenced_classes` respectively.
23
26
 
27
+
24
28
  How to Use
25
29
  ----------
26
30
 
@@ -40,7 +44,8 @@ The following snippets produce identical tasks.
40
44
  ```ruby
41
45
  desc "Build swc"
42
46
  ASRake::CompcTask.new :build do |build|
43
- # you can store the compiler arguments, for example, maybe we need to know the output_dir later on
47
+ # You can store the compiler arguments for later
48
+ # For example, maybe we need to know the output_dir later on
44
49
  #compc = ASRake::CompcTask.new :build do |build|
45
50
  build.target_player = 11.0
46
51
  build.output = "bin/bin/my_project.swc"
@@ -104,7 +109,7 @@ ASRake::AdtTask.new :package => :build do |package|
104
109
  end
105
110
  ```
106
111
 
107
- ### Versioning
112
+ ### Version
108
113
 
109
114
  ```
110
115
  ASRake::VersionTask(task_name = :version, file_name = "VERSION")
@@ -129,7 +134,7 @@ ASRake::VersionTask.new :v, "./config/version.txt"
129
134
  There is a task `version:sync` that is run every time the version changes. This can be useful for things like updating configuration files automatically. To use, add a block to the task:
130
135
 
131
136
  ```ruby
132
- #replace :version with whatever you provided to ASRake::VersionTask.new
137
+ # replace :version with whatever you provided to ASRake::VersionTask.new
133
138
  namespace :version do
134
139
  task :sync do
135
140
  #update application.xml
@@ -153,4 +158,24 @@ swf = ASRake::MxmlcTask.new :build do |build|
153
158
  end
154
159
 
155
160
  ASRake::CleanTask.new swf
161
+ ```
162
+
163
+ ### New copy method
164
+
165
+ ASRake introduces a new copy method `cp_u` on FileUtils and in the global namespace.
166
+
167
+ This copies all files from the source that do not exist or are older at the destination
168
+
169
+ ```ruby
170
+ # copy a single file to a destination folder
171
+ cp_u "path/to/file.xml", "/dest/"
172
+
173
+ # copy a single file to a differently named file
174
+ cp_u "path/to/file.xml", "/dest/dest.xml"
175
+
176
+ # copy an array of files
177
+ cp_u %w{application.xml my_app.swf config.json}, "/dest"
178
+
179
+ # use FileList, Dir.glob(), or othr methods to copy groups of files
180
+ cp_u FileList["lib/**/*.swc"], "bin/lib"
156
181
  ```
@@ -5,7 +5,7 @@ module ASRake
5
5
  class AdtTask < Rake::TaskLib
6
6
 
7
7
  attr_accessor :output
8
- #http://help.adobe.com/en_US/air/build/WS5b3ccc516d4fbf351e63e3d118666ade46-7ff1.html
8
+ # http://help.adobe.com/en_US/air/build/WS5b3ccc516d4fbf351e63e3d118666ade46-7ff1.html
9
9
  attr_accessor :application_descriptor
10
10
 
11
11
  #
@@ -47,7 +47,7 @@ class AdtTask < Rake::TaskLib
47
47
  fail "You must define 'keystore_name' for #{self}" if self.keystore_name == nil
48
48
  fail "You must define 'storepass' for #{self}" if self.storepass == nil
49
49
 
50
- #TODO: Somehow confirm that the initialWindow content is included in the build
50
+ # TODO: Somehow confirm that the initialWindow content is included in the build
51
51
  app_xml = Nokogiri::XML(File.read(application_descriptor))
52
52
  swf = app_xml.at_css("initialWindow > content").content.to_s
53
53
  #swf = File.join(@output_dir, swf)
@@ -101,9 +101,9 @@ class AdtTask < Rake::TaskLib
101
101
  "Verify the command line arguments used for creating signatures."
102
102
  when 12
103
103
  fail "Invalid input\n" +
104
- "Verify file paths and other arguments passed to ADT on the command line.\n" +
105
- "Be sure the initial content in #{self.application_descriptor} is included in the build:\n" +
106
- "<initialWindow>\n <content>#{swf}</content>\n</initialWindow>"
104
+ "Verify file paths and other arguments passed to ADT on the command line."#\n" +
105
+ #"Be sure the initial content in #{self.application_descriptor} is included in the build:\n" +
106
+ #"<initialWindow>\n <content>#{swf}</content>\n</initialWindow>"
107
107
  else
108
108
  fail "Operation exited with status #{status.exitstatus}"
109
109
  end
@@ -36,8 +36,7 @@ module BaseCompilerArguments_Module
36
36
  attr_reader :output_file
37
37
  attr_reader :output_dir
38
38
 
39
- def initialize
40
- super
39
+ def initialize(args=nil)
41
40
  @isAIR = false
42
41
  @library_path = []
43
42
  @external_library_path = []
@@ -46,6 +45,15 @@ module BaseCompilerArguments_Module
46
45
  @debug = false
47
46
  #include default flex-config
48
47
  @load_config = [ FlexSDK::flex_config ]
48
+
49
+ self.merge_in args if args != nil
50
+
51
+ yield self if block_given?
52
+ end
53
+
54
+ # compiler needs to be defined in subclass
55
+ def compiler
56
+ fail "'compiler' must be defined in subclass"
49
57
  end
50
58
 
51
59
  def output
@@ -88,13 +96,16 @@ module BaseCompilerArguments_Module
88
96
  end
89
97
  def isAIR= value
90
98
  @isAIR = value
91
- # if the default config is in the load-config array, replace it with the proper one
99
+ # if the default config is in the load-config array, replace it with the proper one based on context
92
100
  if @isAIR
93
101
  self.load_config.map! {|val| val == FlexSDK::flex_config ? FlexSDK::air_config : val}
94
102
  else
95
103
  self.load_config.map! {|val| val == FlexSDK::air_config ? FlexSDK::flex_config : val}
96
104
  end
97
105
  end
106
+ # alias them as well
107
+ alias_method :isAir, :isAIR
108
+ alias_method :isAir=, :isAIR=
98
109
 
99
110
  def merge_in(args)
100
111
  @@args.each do |arg|
@@ -112,6 +123,17 @@ module BaseCompilerArguments_Module
112
123
  #
113
124
  def generate_args
114
125
 
126
+ #
127
+ # allow all the array arguments to be set as single strings
128
+ #
129
+
130
+ # TODO: have this be part of the attribute accessor
131
+ self.source_path = [self.source_path] if self.source_path.is_a? String
132
+ self.load_config = [self.load_config] if self.load_config.is_a? String
133
+ self.library_path = [self.library_path] if self.library_path.is_a? String
134
+ self.external_library_path = [self.external_library_path] if self.external_library_path.is_a? String
135
+ self.include_libraries = [self.include_libraries] if self.include_libraries.is_a? String
136
+
115
137
  # set to true if the version is defined in one of the referenced configs
116
138
  isTargetDefined = false
117
139
  if self.target_player == nil
@@ -174,6 +196,17 @@ module BaseCompilerArguments_Module
174
196
  return args
175
197
  end
176
198
 
199
+ def build(tips=true)
200
+ fail "Compiler not defined in #{self}" if compiler == nil
201
+ if tips
202
+ run "#{compiler}#{generate_args}" do |line|
203
+ generate_error_message_tips(line)
204
+ end
205
+ else
206
+ run "#{compiler}#{generate_args}"
207
+ end
208
+ end
209
+
177
210
  private
178
211
 
179
212
  def hasDefaultConfigFile?
@@ -187,5 +220,44 @@ module BaseCompilerArguments_Module
187
220
  return (path == FlexSDK::flex_config || path == FlexSDK::air_config)
188
221
  end
189
222
 
223
+ # Try to include helpful information about specific errors
224
+ def generate_error_message_tips(line)
225
+ advice = []
226
+ if((target_player == nil || Float(target_player) < 11) && line.include?("Error: Access of undefined property JSON"))
227
+ advice << "Be sure you are compiling with 'target_player' set to 11.0 or higher"
228
+ advice << "to have access to the native JSON parser. It is currently set to #{target_player}"
229
+ elsif line.include?("Error: The definition of base class Object was not found")
230
+ advice << "If you have removed the default flex-config by setting 'load_config' to"
231
+ advice << "an empty or alternate value (i.e., not appended to it) you must be sure to"
232
+ advice << "still reference the necessary core Flash files, especially playerglobal.swc"
233
+ end
234
+
235
+ if !advice.empty?
236
+ puts "*********************************"
237
+ puts "ASRake Note: " + advice.join("\n")
238
+ puts "*********************************"
239
+ end
240
+ end
241
+
190
242
  end
191
- end
243
+ end
244
+
245
+ ##fill config with the default flex_config options
246
+ #if use_default_flex_config
247
+ # #initialize with default values from flex-config
248
+ # flex_config = Nokogiri::XML(File.read(FlexSDK::flex_config))
249
+ #
250
+ # target_player = flex_config.css('target-player').children.to_s
251
+ # swf_version = flex_config.css('swf-version').children.to_s
252
+ #
253
+ # flex_config.css('compiler external-library-path path-element').each { |ext|
254
+ # puts ext.children
255
+ # }
256
+ #end
257
+
258
+ #http://fpdownload.macromedia.com/get/flashplayer/updaters/11/playerglobal11_2.swc
259
+ #frameworks\libs\player
260
+
261
+ #-dump-config compiler_config.xml
262
+ #-link-report compiler_linkreport.xml
263
+ #-size-report compiler_sizereport.xml
@@ -1,5 +1,4 @@
1
1
  require 'rake/tasklib'
2
-
3
2
  require 'asrake/base_compiler_args'
4
3
 
5
4
  module ASRake
@@ -7,11 +6,7 @@ class BaseCompilerTask < Rake::TaskLib
7
6
  include BaseCompilerArguments_Module
8
7
 
9
8
  def initialize(name, args)
10
- super()
11
-
12
- self.merge_in args if args != nil
13
-
14
- yield self if block_given?
9
+ super(args)
15
10
 
16
11
  @name = name
17
12
 
@@ -23,52 +18,5 @@ class BaseCompilerTask < Rake::TaskLib
23
18
 
24
19
  end
25
20
 
26
- protected
27
-
28
- def build
29
- fail "build must be defined in subclass"
30
- end
31
-
32
- private
33
-
34
- # Try to include helpful information about specific errors
35
- def generate_error_message_tips(line)
36
- advice = []
37
- if((target_player == nil || Float(target_player) < 11) && line.include?("Error: Access of undefined property JSON"))
38
- advice << "Be sure you are compiling with 'target_player' set to 11.0 or higher"
39
- advice << "to have access to the native JSON parser. It is currently set to #{target_player}"
40
- elsif line.include?("Error: The definition of base class Object was not found")
41
- advice << "If you have removed the default flex-config by setting 'load_config' to"
42
- advice << "an empty or alternate value (i.e., not appended to it) you must be sure to"
43
- advice << "still reference the necessary core Flash files, especially playerglobal.swc"
44
- end
45
-
46
- if !advice.empty?
47
- puts "*********************************"
48
- puts "ASRake Note: " + advice.join("\n")
49
- puts "*********************************"
50
- end
51
- end
52
-
53
- end
54
21
  end
55
-
56
- ##fill config with the default flex_config options
57
- #if use_default_flex_config
58
- # #initialize with default values from flex-config
59
- # flex_config = Nokogiri::XML(File.read(FlexSDK::flex_config))
60
- #
61
- # target_player = flex_config.css('target-player').children.to_s
62
- # swf_version = flex_config.css('swf-version').children.to_s
63
- #
64
- # flex_config.css('compiler external-library-path path-element').each { |ext|
65
- # puts ext.children
66
- # }
67
- #end
68
-
69
- #http://fpdownload.macromedia.com/get/flashplayer/updaters/11/playerglobal11_2.swc
70
- #frameworks\libs\player
71
-
72
- #-dump-config compiler_config.xml
73
- #-link-report compiler_linkreport.xml
74
- #-size-report compiler_sizereport.xml
22
+ end
@@ -6,6 +6,10 @@ module ASRake
6
6
  module CompcArguments_Module
7
7
  include BaseCompilerArguments_Module
8
8
 
9
+ def compiler
10
+ FlexSDK::compc
11
+ end
12
+
9
13
  def generate_args
10
14
  compc = super
11
15
 
@@ -20,9 +20,12 @@ class CompcTask < BaseCompilerTask
20
20
  self.build
21
21
  end
22
22
 
23
+ # allow setting source_path with '=' instead of '<<'
24
+ self.source_path = [self.source_path] if self.source_path.is_a? String
25
+
23
26
  # set dependencies on all .as and .mxml files in the source paths
24
27
  dependencies = FileList.new
25
- source_path.each do |path|
28
+ self.source_path.each do |path|
26
29
  path = cf path
27
30
  dependencies.include(File.join(path, "*.as"))
28
31
  dependencies.include(File.join(path, "*.mxml"))
@@ -40,13 +43,5 @@ class CompcTask < BaseCompilerTask
40
43
 
41
44
  end
42
45
 
43
- protected
44
-
45
- def build
46
- run "#{FlexSDK::compc}#{generate_args}" do |line|
47
- generate_error_message_tips(line)
48
- end
49
- end
50
-
51
46
  end
52
47
  end
@@ -0,0 +1,81 @@
1
+ require 'fileutils'
2
+
3
+ module ASRake
4
+ module FileUtilsExt
5
+
6
+ #
7
+ # Copies files recursivly only if they don't exist at the destination or the destination
8
+ # files are older.
9
+ #
10
+ # There are two possible ways to copy, multiple files, or a single file
11
+ #
12
+ # 1. Copying multiple files
13
+ # Examples:
14
+ # * `cp_u FileList["/path/*.ext"], "/dest"`
15
+ # * `cp_u %w{src1 /path/src2}, "/dest"`
16
+ # * `cp_u /path/to/src/, "/dest"`
17
+ # An error will be thrown if the destination already exists and is not a directory.
18
+ # 2. Copying a single file
19
+ # For example, copying file "src"
20
+ # 1. If destination is, or is infered to be, a directory, the src file is copied to
21
+ # an identically named file at the destination directory
22
+ # `cp_u /path/src, /path/dest/`
23
+ # `cp_u /path/src, /path/dest` <- dest is an existing directory
24
+ # 2. If destination is, or is infered to be, a file, the src file is copied and renamed
25
+ # to the destination file
26
+ # `cp_u /path/src, /path/dest` <- dest does not exist or is a file
27
+ #
28
+ def cp_u(src, dest, options = {})
29
+ if tmp = Array.try_convert(src)
30
+ tmp.each do |s|
31
+ copy_files(s, File.join(dest, File.basename(s)), options)
32
+ end
33
+ else
34
+ copy_files(src, dest, options)
35
+ end
36
+ #puts "Files copied. #{src} => #{dest}"
37
+ end
38
+
39
+ private
40
+
41
+ def copy_files(src, dest, options)
42
+ if File.directory?(src)
43
+ #recurse the "src" dir tree, appending the path to dest
44
+ Dir.foreach(src) do |src_file|
45
+ if src_file != ".." && src_file != "."
46
+ #puts src_file + "|" + File.join(src, src_file) + "|" + File.join(dest, src_file)
47
+ copy_files(File.join(src, src_file), File.join(dest, src_file), options)
48
+ end
49
+ end
50
+ else
51
+ # If the destination is an existing directory, or ends in a path separator, then
52
+ # append the source file name to it
53
+ dest = File.join(dest, File.basename(src)) if File.directory?(dest) || dest =~ /[\\\/]$/
54
+
55
+ if !File.exist?(dest) || (File.mtime(dest) < File.mtime(src))
56
+ puts "cp -u #{[src,dest].flatten.join ' '}" if options[:verbose]
57
+ return if options[:noop]
58
+ begin
59
+ dir = File.dirname(dest)
60
+ mkdir_p(dir, :verbose => false) if !File.exist?(dir)
61
+ rescue
62
+ fail "Error copying #{src} to #{dest}. Cannot create directory. #{$!}"
63
+ end
64
+ begin
65
+ FileUtils::copy_file src, dest
66
+ rescue
67
+ fail "Error copying #{src} to #{dest}. #{$!}"
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+
75
+ module FileUtils
76
+ include ASRake::FileUtilsExt
77
+ module_function :cp_u
78
+ module_function :copy_files
79
+ end
80
+
81
+ self.extend ASRake::FileUtilsExt
@@ -1,81 +1,78 @@
1
1
  require 'asrake/host'
2
2
 
3
3
  class FlexSDK
4
- SDK_PATHS = []
4
+
5
+ SDK_PATHS = []
6
+
7
+ class << self
8
+
9
+ @@initialized = false
10
+
11
+ # dynamically create getters for the executables and config files
12
+ @@executables = %w[adt adl asdoc mxmlc compc]
13
+ @@configs = %w[flex-config air-config]
5
14
 
6
- class << self
15
+ def root
16
+ init()
17
+ return @root
18
+ end
7
19
 
8
- @@initialized = false
9
-
10
- @@executables = %w[adt adl asdoc mxmlc compc]
11
- @@configs = %w[flex-config air-config]
12
-
13
- def root
20
+ [].concat(@@configs).concat(@@executables).each do |name|
21
+ name = name.gsub('-','_')
22
+ define_method name do
14
23
  init()
15
- return @root
24
+ instance_variable_get "@#{name}"
16
25
  end
26
+ end
17
27
 
18
- @@configs.each do |name|
19
- method = name.gsub('-','_')
20
- define_method method do
21
- init()
22
- instance_variable_get "@#{method}"
23
- end
24
- end
28
+ private
25
29
 
26
- @@executables.each do |name|
27
- define_method name do
28
- init()
29
- instance_variable_get "@#{name}"
30
- end
30
+ def init()
31
+ if @@initialized
32
+ return
31
33
  end
34
+ @@initialized = true
35
+ @@root = nil
36
+ missing = {}
37
+ # Find where the flex sdk is installed
38
+ SDK_PATHS.each do |path|
39
+ #remove /bin/ fom the end of the path if it exists
40
+ path.sub!(/[\/\\]bin[\/\\]?$/,'')
41
+ if File.exists?(path)
42
+ missing[SDK_PATHS] = []
32
43
 
33
- private
44
+ @@configs.each do |name|
45
+ config = c File.join(path, 'frameworks', "#{name}.xml")
46
+ missing[SDK_PATHS] << config if !File.exists?(config)
47
+ instance_variable_set "@#{name.gsub('-','_')}", config
48
+ end
34
49
 
35
- def init()
36
- if !@@initialized
37
- @@root = nil
50
+ @@executables.each do |name|
51
+ exec = c File.join(path, 'bin', name)
52
+ missing[SDK_PATHS] << exec if !File.exists?(exec)
53
+ instance_variable_set "@#{name}", exec
54
+ end
38
55
 
39
- # Find where the flex sdk is installed
40
- SDK_PATHS.each do |path|
41
- #remove /bin/ fom the end of the path if it exists
42
- path.sub!(/[\/\\]bin[\/\\]?$/,'')
43
- if File.exists?(path)
44
- allValid = true
45
-
46
- @@configs.each do |name|
47
- config = c File.join(path, 'frameworks', "#{name}.xml")
48
- allValid = false if !File.exists?(config)
49
- instance_variable_set "@#{name.gsub('-','_')}", config
50
- end
51
-
52
- @@executables.each do |name|
53
- exec = c File.join(path, 'bin', name)
54
- allValid = false if !File.exists?(exec)
55
- instance_variable_set "@#{name}", exec
56
- end
57
-
58
- if allValid
59
- @@root = path
60
- break
61
- end
62
- end
56
+ if missing[SDK_PATHS].empty?
57
+ @@root = path
58
+ break
63
59
  end
60
+ end
61
+ end
64
62
 
65
- if @@root == nil
66
- str = ""
67
- if !SDK_PATHS.empty?
68
- str << "Could not find a valid Flex SDK at any of the paths in FlexSDK::SDK_PATHS\n=> "
69
- str << SDK_PATHS.join("\n=> ")
70
- str << "\n"
71
- end
72
- str << "Append a valid SDK path in your rakefile, e.g.:\nFlexSDK::SDK_PATHS << 'C:\\develop\\sdk\\flex_sdk_4.6.0.23201'"
73
- str << "\nFor more information, see: http://adobe.com/go/flex_sdk/"
74
- fail str
75
- end
63
+ if @@root == nil
64
+ str = ""
65
+ if !SDK_PATHS.empty?
66
+ str << "Could not find a valid Flex SDK at any of the paths in FlexSDK::SDK_PATHS\n=> "
67
+ # TODO: output which paths are invalid and which are missing a particular binary from missing[] above
68
+ str << SDK_PATHS.join("\n=> ")
69
+ str << "\n"
76
70
  end
77
- @@initialized = true
71
+ str << "Append a valid SDK path in your rakefile, e.g.:\nFlexSDK::SDK_PATHS << 'C:\\develop\\sdk\\flex_sdk_4.6.0.23201'"
72
+ str << "\nFor more information, see: http://adobe.com/go/flex_sdk/"
73
+ fail str
78
74
  end
79
75
  end
76
+ end
80
77
 
81
78
  end
@@ -5,6 +5,10 @@ module ASRake
5
5
 
6
6
  module MxmlcArguments_Module
7
7
  include BaseCompilerArguments_Module
8
+
9
+ def compiler
10
+ FlexSDK::mxmlc
11
+ end
8
12
  end
9
13
 
10
14
  class MxmlcArguments
@@ -25,13 +25,5 @@ class MxmlcTask < BaseCompilerTask
25
25
 
26
26
  end
27
27
 
28
- protected
29
-
30
- def build
31
- run "#{FlexSDK::mxmlc}#{generate_args}" do |line|
32
- generate_error_message_tips(line)
33
- end
34
- end
35
-
36
28
  end
37
29
  end
data/lib/asrake.rb CHANGED
@@ -22,4 +22,6 @@ THE SOFTWARE.
22
22
 
23
23
  # require all the task files so users can create them just by requiring asrake
24
24
  Dir.glob(File.join(File.expand_path(File.dirname(__FILE__)), "asrake/*_task.rb")).each {|f| require f }
25
- Dir.glob(File.join(File.expand_path(File.dirname(__FILE__)), "asrake/*_args.rb")).each {|f| require f }
25
+ Dir.glob(File.join(File.expand_path(File.dirname(__FILE__)), "asrake/*_args.rb")).each {|f| require f }
26
+
27
+ require 'asrake/file_utils'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asrake
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.9.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-05 00:00:00.000000000 Z
12
+ date: 2012-08-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
@@ -75,7 +75,7 @@ files:
75
75
  - lib/asrake/clean_task.rb
76
76
  - lib/asrake/compc_args.rb
77
77
  - lib/asrake/compc_task.rb
78
- - lib/asrake/copy_task.rb
78
+ - lib/asrake/file_utils.rb
79
79
  - lib/asrake/flexsdk.rb
80
80
  - lib/asrake/host.rb
81
81
  - lib/asrake/mxmlc_args.rb
@@ -111,5 +111,5 @@ rubyforge_project:
111
111
  rubygems_version: 1.8.24
112
112
  signing_key:
113
113
  specification_version: 3
114
- summary: A Rake library for Actionscript projects
114
+ summary: A Rake library for Actionscript 3, Flex, and AIR projects
115
115
  test_files: []
@@ -1,87 +0,0 @@
1
- require 'rake/tasklib'
2
-
3
- module ASRake
4
- class CopyTask < Rake::TaskLib
5
-
6
- attr_accessor :copy_list
7
-
8
- def initialize(name = :copy)
9
- self.copy_list = Hash.new
10
-
11
- yield self if block_given?
12
-
13
- #define named task first so if desc was called it will be attached to it instead of the file task
14
- Rake::Task.define_task name do
15
- # use longest source path to space the output. yup, seriously that OCD
16
- len = self.copy_list.keys.group_by(&:size).max.last[0].length
17
- self.copy_list.each do |from, to|
18
- copy_files from, to
19
- puts "Files copied. %#{len}s => %s" % [from, to]
20
- end
21
- end
22
- end
23
-
24
- def copy(from_path, to_path=nil)
25
- if from_path == nil
26
- fail puts "Cannot copy files. No source provided."
27
- end
28
-
29
- # special case getting a hash as an argument
30
- if from_path.is_a? Hash
31
- from_path.each {|from, to| copy from, to}
32
- return
33
- end
34
-
35
- if to_path == nil
36
- fail puts "Cannot copy files from #{from_path}. No destination provided."
37
- end
38
-
39
- self.copy_list[from_path] = to_path
40
- end
41
- alias_method :add, :copy
42
-
43
- private
44
-
45
- def copy_files(from_path, to_path, times=0)
46
- from = FileList[from_path]
47
- unless from.length == 0
48
- from.each do |from|
49
- if File.directory?(from)
50
- #recurse the "from" dir tree, appending the path to to_path
51
- Dir.foreach(from) do |fr|
52
- if fr != ".." && fr != "."
53
- #puts fr + "|" + File.join(from, fr) + "|" + File.join(to_path, fr)
54
- copy_files(File.join(from, fr), File.join(to_path, fr), times+1)
55
- end
56
- end
57
- else
58
- # if this is the first iteration, we haven't gotten to join the "to" path in the directory loop above, so
59
- # append it to the file here if either the to or from path are a directory
60
- if times == 0 && (File.directory?(to_path) || File.directory?(from_path) || from_path =~ /\*/)
61
- to = File.join(to_path, File.basename(from))
62
- else
63
- to = to_path
64
- end
65
-
66
- if !File.exists?(to) || (File.mtime(to.to_s) < File.mtime(from.to_s))
67
- begin
68
- dir = File.dirname(to)
69
- mkdir_p(dir, :verbose => false) if !File.exist?(dir)
70
- rescue
71
- fail "Error copying #{from} to #{to}. Cannot create directory. #{$!}"
72
- end
73
- begin
74
- cp_r from, to#, :verbose => false
75
- rescue
76
- fail "Error copying #{from} to #{to}. #{$!}"
77
- end
78
- end
79
- end
80
- end
81
- else
82
- puts "Error copying to #{to_path}. No files exist at source #{from_path}."
83
- end
84
- end
85
-
86
- end
87
- end