asrake 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2012 Malachi Griffie <malachi@nexussays.com>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,156 @@
1
+ ASRake
2
+ ======
3
+
4
+ **Rake library for Actionscript 3 projects**
5
+
6
+ Overview
7
+ --------
8
+
9
+ Add the path(s) to your Flex SDK for all systems that will need to run the Rake tasks.
10
+ ```ruby
11
+ FlexSDK::SDK_PATHS << 'C:\develop\sdk\flex_sdk_4.6.0.23201'
12
+ FlexSDK::SDK_PATHS << "C:/develop/sdk/flex_sdk_4.5.1"
13
+ FlexSDK::SDK_PATHS << "/opt/lib/adobe/flex_4.6"
14
+ ```
15
+
16
+ ### Compiler Arguments
17
+
18
+ Arguments match those passed to the compiler (mxmlc, compc, adt, etc) with hyphens `-` replaced by underscores `_` (e.g., to set the `target-player` compiler argument assign to the `target_player` property)
19
+
20
+ > Since this is still in development, not all compiler arguments have a property mapped to them. Use `additional_args` to pass whatever text you want into the compiler.
21
+
22
+ 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
+
24
+ How to Use
25
+ ----------
26
+
27
+ ### Build a SWF or SWC
28
+
29
+ ```
30
+ ASRake::MxmlcTask(task_name = :build, compiler_args = nil) |self|
31
+ ```
32
+ ```
33
+ ASRake::CompcTask(task_name = :build, compiler_args = nil) |self|
34
+ ```
35
+
36
+ You can define the compile arguments elsewhere and pass it to the task, or set them inside the task block, or a combination of both. It is purely preference.
37
+
38
+ The following snippets produce identical tasks.
39
+
40
+ ```ruby
41
+ desc "Build swc"
42
+ 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
44
+ #compc = ASRake::CompcTask.new :build do |build|
45
+ build.target_player = 11.0
46
+ build.output = "bin/bin/my_project.swc"
47
+ build.debug = true
48
+ build.source_path << "bin/src"
49
+ build.statically_link_only_referenced_classes << "lib/lib_used_in_project.swc"
50
+ end
51
+ ```
52
+
53
+ ```ruby
54
+ args = ASRake::CompcArguments.new
55
+ args.target_player = 11.0
56
+ args.output = "bin/bin/my_project.swc"
57
+ args.debug = true
58
+ args.source_path << "bin/src"
59
+ args.statically_link_only_referenced_classes << "lib/lib_used_in_project.swc"
60
+
61
+ desc "Build swc"
62
+ ASRake::CompcTask.new :build, args
63
+ ```
64
+
65
+ ```ruby
66
+ args = ASRake::CompcArguments.new
67
+ args.target_player = 11.0
68
+ args.output = "bin/bin/my_project.swc"
69
+ args.debug = false
70
+ args.source_path << "bin/src"
71
+
72
+ desc "Build swc"
73
+ ASRake::CompcTask.new :build, args do |compc|
74
+ compc.debug = true
75
+ compc.statically_link_only_referenced_classes << "lib/lib_used_in_project.swc"
76
+ end
77
+ ```
78
+
79
+ ### Build an AIR
80
+
81
+ Compile your SWF file as normal, but set the `isAIR` property to true
82
+
83
+ ```ruby
84
+ desc "Build app"
85
+ ASRake::MxmlcTask.new :build do |build|
86
+ build.load_config << "mxmlc_config.xml"
87
+ build.output = "bin/my_app.swf"
88
+ build.isAIR = true
89
+ end
90
+ ```
91
+
92
+ Provide the package task with the AIR and keystore information. If the key doesn't exist, it will be created.
93
+
94
+ > Be sure that the swf file is included in the package (eg, it is included here by packaging everything in the bin directory with `-C bin .`)
95
+
96
+ ```ruby
97
+ ASRake::AdtTask.new :package => :build do |package|
98
+ package.output = "bin/my_app.air"
99
+ package.keystore = "my_app_cert.p12"
100
+ package.keystore_name = "my_app"
101
+ package.storepass = "my_app"
102
+ package.tsa = "none"
103
+ package.additional_args = "-C bin ."
104
+ end
105
+ ```
106
+
107
+ ### Versioning
108
+
109
+ ```
110
+ ASRake::VersionTask(task_name = :version, file_name = "VERSION")
111
+ ```
112
+
113
+ No additional arguments are needed to create a version task. Once added to your Rakefile, you can run `rake version:help` for information on how versioning works.
114
+
115
+ If you are fine with the defaults, you can just add:
116
+
117
+ ```ruby
118
+ ASRake::VersionTask.new
119
+ ```
120
+
121
+ Otherwise you can define the task name and filename as you wish
122
+
123
+ ```ruby
124
+ ASRake::VersionTask.new :v, "./config/version.txt"
125
+ ```
126
+
127
+ #### Version Sync
128
+
129
+ 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
+
131
+ ```ruby
132
+ #replace :version with whatever you provided to ASRake::VersionTask.new
133
+ namespace :version do
134
+ task :sync do
135
+ #update application.xml
136
+ end
137
+ end
138
+ ```
139
+
140
+ ### Clean
141
+
142
+ ```
143
+ ASRake::CleanTask.new(*compiler_args)
144
+ ```
145
+
146
+ Provide your compiler arguments to `ASRake::CleanTask` and it will automatically create clean and clobber tasks.
147
+
148
+ ```ruby
149
+ swf = ASRake::MxmlcTask.new :build do |build|
150
+ build.load_config << "mxmlc_config.xml"
151
+ build.output = "bin/my_app.swf"
152
+ build.isAIR = true
153
+ end
154
+
155
+ ASRake::CleanTask.new swf
156
+ ```
data/lib/asrake.rb ADDED
@@ -0,0 +1,25 @@
1
+ =begin MIT-LICENSE
2
+ Copyright (c) 2012 Malachi Griffie <malachi@nexussays.com>
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in
12
+ all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
21
+ =end
22
+
23
+ # require all the task files so users can create them just by requiring asrake
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 }
@@ -0,0 +1,146 @@
1
+ require 'rake/tasklib'
2
+ require 'nokogiri'
3
+
4
+ module ASRake
5
+ class AdtTask < Rake::TaskLib
6
+
7
+ attr_accessor :output
8
+ #http://help.adobe.com/en_US/air/build/WS5b3ccc516d4fbf351e63e3d118666ade46-7ff1.html
9
+ attr_accessor :application_descriptor
10
+
11
+ #
12
+ # The path to the keystore file for file-based store types.
13
+ #
14
+ attr_accessor :keystore
15
+ #
16
+ # The alias of a key in the keystore. Specifying an alias is not necessary when a keystore only contains
17
+ # a single certificate. If no alias is specified, ADT uses the first key in the keystore.
18
+ #
19
+ attr_accessor :alias
20
+ attr_accessor :storetype
21
+ attr_accessor :storepass
22
+ attr_accessor :keystore_name
23
+ #
24
+ # Specifies the URL of an RFC3161-compliant timestamp server to time-stamp the digital signature.
25
+ # If no URL is specified, a default time-stamp server provided by Geotrust is used. When the signature
26
+ # of an AIR application is time-stamped, the application can still be installed after the signing
27
+ # certificate expires, because the timestamp verifies that the certificate was valid at the time of signing.
28
+ #
29
+ attr_accessor :tsa
30
+
31
+ attr_accessor :additional_args
32
+
33
+ attr_reader :output_file
34
+ attr_reader :output_dir
35
+ attr_reader :keystore_file
36
+ attr_reader :keystore_dir
37
+
38
+ def initialize(name = :package)
39
+ self.application_descriptor = "application.xml";
40
+ self.storetype = "pkcs12"
41
+
42
+ yield self if block_given?
43
+
44
+ fail "You must define 'output' for #{self}" if self.output == nil
45
+ fail "You must define 'application_descriptor' for #{self}" if self.application_descriptor == nil || !File.exists?(self.application_descriptor)
46
+ fail "You must define 'keystore' for #{self}" if self.keystore == nil
47
+ fail "You must define 'keystore_name' for #{self}" if self.keystore_name == nil
48
+ fail "You must define 'storepass' for #{self}" if self.storepass == nil
49
+
50
+ #TODO: Somehow confirm that the initialWindow content is included in the build
51
+ app_xml = Nokogiri::XML(File.read(application_descriptor))
52
+ swf = app_xml.at_css("initialWindow > content").content.to_s
53
+ #swf = File.join(@output_dir, swf)
54
+ #puts swf
55
+
56
+ # define named task first so if desc was called it will be attached to it instead of the file task
57
+ Rake::Task.define_task name do
58
+ command = "#{FlexSDK::adt}"
59
+ command << " -package"
60
+ command << " -tsa #{self.tsa}" if self.tsa != nil
61
+ command << " -storetype #{self.storetype}"
62
+ command << " -keystore #{self.keystore}"
63
+ command << " -storepass #{self.storepass}"
64
+ command << " #{self.output} #{self.application_descriptor}"
65
+ command << " #{additional_args}" if self.additional_args != nil
66
+ status = run command, false
67
+ if status.exitstatus != 0
68
+ case status.exitstatus
69
+ when 2
70
+ fail "Usage error\n" +
71
+ "Check the command line arguments for errors"
72
+ when 5
73
+ fail "Unknown error\n" +
74
+ "This error indicates a situation that cannot be explained by common error conditions.\n" +
75
+ "Possible root causes include incompatibility between ADT and the Java Runtime Environment,\n"
76
+ "corrupt ADT or JRE installations, and programming errors within ADT."
77
+ when 6
78
+ fail "Could not write to output directory\n" +
79
+ "Make sure that the specified (or implied) output directory is accessible and\n" +
80
+ "that the containing drive has sufficient disk space."
81
+ when 7
82
+ fail "Could not access certificate\n" +
83
+ "Make sure that the path to the keystore is specified correctly: #{self.keystore}\n" +
84
+ "Make sure that the keystore password is correct: #{self.storepass}"
85
+ #"Check that the certificate within the keystore can be accessed."
86
+ when 8
87
+ fail "Invalid certificate\n" +
88
+ "The certificate file is malformed, modified, expired, or revoked."
89
+ when 9
90
+ fail "Could not sign AIR file\n" +
91
+ "Verify the signing options passed to ADT."
92
+ when 10
93
+ fail "Could not create time stamp\n" +
94
+ "ADT could not establish a connection to the timestamp server.\n" +
95
+ "If you connect to the internet through a proxy server, you may need to configure\n" +
96
+ "the JRE proxy settings. There have also been errors reported with Java 7: \n" +
97
+ "http://www.flashdevelop.org/community/viewtopic.php?p=41221\n" +
98
+ "You can disable checking a timestamp server by setting 'tsa' to 'none' in your task"
99
+ when 11
100
+ fail "Certificate creation error\n" +
101
+ "Verify the command line arguments used for creating signatures."
102
+ when 12
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>"
107
+ else
108
+ fail "Operation exited with status #{status.exitstatus}"
109
+ end
110
+ end
111
+ puts "#{c output} (#{File.size(self.output)} bytes)"
112
+ end
113
+
114
+ # if the task name is a hash (ie, has dependencies defined) make sure we pull out the task name from it
115
+ name, _ = name.first if name.is_a? Hash
116
+
117
+ @output_dir = File.dirname(self.output)
118
+ @output_file = File.basename(self.output)
119
+
120
+ @keystore_dir = File.dirname(self.keystore)
121
+ @keystore_file = File.basename(self.keystore)
122
+
123
+ directory self.output_dir
124
+
125
+ # setup file dependencies
126
+ #file output => output_dir
127
+ #files.each do |to, from|
128
+ # file output => [cf(from)]
129
+ #end
130
+
131
+ #add output file task as a dependency to the named task created
132
+ #task name => output
133
+
134
+ task name => self.output_dir
135
+
136
+ file self.keystore do
137
+ run "#{FlexSDK::adt} -certificate -cn #{self.keystore_name} 1024-RSA #{self.keystore} #{self.storepass}"
138
+ puts "Certificate created at #{self.keystore} with password '#{self.storepass}'"
139
+ end
140
+
141
+ task name => self.keystore
142
+
143
+ end
144
+
145
+ end
146
+ end
@@ -0,0 +1,191 @@
1
+ require 'asrake/flexsdk'
2
+ require 'nokogiri'
3
+
4
+ module ASRake
5
+
6
+ module BaseCompilerArguments_Module
7
+
8
+ #
9
+ # compiler arguments
10
+ #
11
+
12
+ @@args = [
13
+ :output,
14
+
15
+ :source_path,
16
+ :library_path,
17
+ :external_library_path,
18
+ :include_libraries,
19
+
20
+ :load_config,
21
+ :target_player,
22
+ :swf_version,
23
+
24
+ :debug,
25
+
26
+ :dump_config
27
+ ]
28
+ attr_accessor *@@args
29
+
30
+ attr_accessor :additional_args
31
+
32
+ #
33
+ # non-compiler arguments
34
+ #
35
+
36
+ attr_reader :output_file
37
+ attr_reader :output_dir
38
+
39
+ def initialize
40
+ super
41
+ @isAIR = false
42
+ @library_path = []
43
+ @external_library_path = []
44
+ @include_libraries = []
45
+ @source_path = []
46
+ @debug = false
47
+ #include default flex-config
48
+ @load_config = [ FlexSDK::flex_config ]
49
+ end
50
+
51
+ def output
52
+ @output
53
+ end
54
+
55
+ def output= value
56
+ @output = value
57
+ # if the output path ends in a path separator, it is a directory
58
+ if @output =~ /[\/\\]$/
59
+ @output_dir = @output
60
+ else
61
+ # forward-slashes required for File methods
62
+ @output = cf @output
63
+ @output_dir = File.dirname(@output)
64
+ @output_file = File.basename(@output)
65
+ end
66
+ end
67
+
68
+ def output_is_dir?
69
+ output_file == nil
70
+ end
71
+
72
+ # provide a more understandable alias
73
+ def statically_link_only_referenced_classes
74
+ library_path
75
+ end
76
+
77
+ def statically_link
78
+ include_libraries
79
+ end
80
+
81
+ def dynamically_link
82
+ external_library_path
83
+ end
84
+
85
+ # use the air configs if true
86
+ def isAIR
87
+ @isAIR
88
+ end
89
+ def isAIR= value
90
+ @isAIR = value
91
+ # if the default config is in the load-config array, replace it with the proper one
92
+ if @isAIR
93
+ self.load_config.map! {|val| val == FlexSDK::flex_config ? FlexSDK::air_config : val}
94
+ else
95
+ self.load_config.map! {|val| val == FlexSDK::air_config ? FlexSDK::flex_config : val}
96
+ end
97
+ end
98
+
99
+ def merge_in(args)
100
+ @@args.each do |arg|
101
+ # TODO: This needs to concat arrays not overwite them
102
+ self.send("#{arg}=", args.send(arg))
103
+ end
104
+ end
105
+
106
+ def to_s
107
+ generate_args
108
+ end
109
+
110
+ #
111
+ # Verify properties and then return build arguments
112
+ #
113
+ def generate_args
114
+
115
+ # set to true if the version is defined in one of the referenced configs
116
+ isTargetDefined = false
117
+ if self.target_player == nil
118
+ # try to find necessary args in any loaded config files
119
+ unless self.load_config.length == 1 && isDefaultConfig?(self.load_config[0])
120
+ # load config in reverse so last added has priority
121
+ self.load_config.reverse.each do |config|
122
+ flex_config = Nokogiri::XML(File.read(config))
123
+
124
+ isTargetDefined = true if flex_config.at_css('target-player')
125
+ #configSource? = true if
126
+ end
127
+ end
128
+ end
129
+
130
+ fail "You must define 'target_player' for #{self}" if self.target_player == nil && !isTargetDefined
131
+
132
+ # TODO: iterate over all non-default config files provided and look for source-path entries
133
+ #fail "You must add at least one path to 'source_path' for #{self}" if source_path.empty? && !configSource?
134
+
135
+ # TODO: iterate over all non-default config files provided and look for output
136
+ fail "You must define 'output' for #{self}" if self.output == nil
137
+
138
+ #
139
+ # validation complete, generate build args
140
+ #
141
+
142
+ args = ""
143
+ # set output as directory if it ends in a trailing slash
144
+ args << " -output=#{cf output}"
145
+ args << " -directory=true" if output_is_dir?
146
+
147
+ args << " -target-player=#{target_player}" if self.target_player != nil
148
+ args << " -swf-version=#{swf_version}" if self.swf_version != nil
149
+
150
+ args << " +configname=air" if self.isAIR
151
+
152
+ args << " -debug=#{debug}"
153
+ args << " -source-path=#{cf source_path.join(',')}" if !self.source_path.empty?
154
+
155
+ # add the -load-config option if it is anything other than the default
156
+ unless self.load_config.length == 1 && isDefaultConfig?(self.load_config[0])
157
+ # if the default flex config is still in the load_config array, then append all config files, otherwise have the first one replace
158
+ op = hasDefaultConfigFile? ? "+=" : "="
159
+ self.load_config.each do |config|
160
+ args << " -load-config#{op}#{cf config}" unless isDefaultConfig?(config)
161
+ op = "+="
162
+ end
163
+ end
164
+
165
+ args << " -library-path=#{cf library_path.join(',')}" if !self.library_path.empty?
166
+ args << " -external-library-path=#{cf external_library_path.join(',')}" if !self.external_library_path.empty?
167
+ args << " -include-libraries=#{cf include_libraries.join(',')}" if !self.include_libraries.empty?
168
+
169
+ args << " -dump-config=#{cf dump_config}" if self.dump_config != nil
170
+
171
+ args << " #{additional_args}" if self.additional_args != nil
172
+ #args << ' -include-file images\core_logo.png ..\nexuslib\code\etc\core_logo.png'
173
+
174
+ return args
175
+ end
176
+
177
+ private
178
+
179
+ def hasDefaultConfigFile?
180
+ self.load_config.each do |path|
181
+ return true if isDefaultConfig? path
182
+ end
183
+ return false
184
+ end
185
+
186
+ def isDefaultConfig?(path)
187
+ return (path == FlexSDK::flex_config || path == FlexSDK::air_config)
188
+ end
189
+
190
+ end
191
+ end