releasy 0.2.0rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/.gitignore +17 -0
  2. data/.yardopts +4 -0
  3. data/CHANGELOG.md +24 -0
  4. data/Gemfile +3 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.md +165 -0
  7. data/Rakefile +31 -0
  8. data/bin/7z.sfx +0 -0
  9. data/bin/releasy +7 -0
  10. data/lib/releasy.rb +18 -0
  11. data/lib/releasy/archivers.rb +12 -0
  12. data/lib/releasy/archivers/archiver.rb +74 -0
  13. data/lib/releasy/archivers/dmg.rb +18 -0
  14. data/lib/releasy/archivers/exe.rb +23 -0
  15. data/lib/releasy/archivers/seven_zip.rb +12 -0
  16. data/lib/releasy/archivers/tar_archiver.rb +14 -0
  17. data/lib/releasy/archivers/tar_bzip2.rb +13 -0
  18. data/lib/releasy/archivers/tar_gzip.rb +13 -0
  19. data/lib/releasy/archivers/zip.rb +12 -0
  20. data/lib/releasy/builders.rb +12 -0
  21. data/lib/releasy/builders/builder.rb +52 -0
  22. data/lib/releasy/builders/ocra_builder.rb +43 -0
  23. data/lib/releasy/builders/osx_app.rb +158 -0
  24. data/lib/releasy/builders/source.rb +27 -0
  25. data/lib/releasy/builders/windows_builder.rb +65 -0
  26. data/lib/releasy/builders/windows_folder.rb +47 -0
  27. data/lib/releasy/builders/windows_folder_from_ruby_dist.rb +150 -0
  28. data/lib/releasy/builders/windows_installer.rb +117 -0
  29. data/lib/releasy/builders/windows_standalone.rb +37 -0
  30. data/lib/releasy/cli.rb +12 -0
  31. data/lib/releasy/cli/install_sfx.rb +66 -0
  32. data/lib/releasy/dsl_wrapper.rb +71 -0
  33. data/lib/releasy/mixins/exec.rb +14 -0
  34. data/lib/releasy/mixins/has_archivers.rb +37 -0
  35. data/lib/releasy/mixins/has_gemspecs.rb +42 -0
  36. data/lib/releasy/mixins/register.rb +47 -0
  37. data/lib/releasy/project.rb +300 -0
  38. data/lib/releasy/version.rb +3 -0
  39. data/lib/releasy/windows_wrapper_maker.rb +90 -0
  40. data/lib/releasy/windows_wrapper_maker/Gemfile +8 -0
  41. data/media/releasy.png +0 -0
  42. data/releasy.gemspec +37 -0
  43. data/test/releasy/archivers_test.rb +65 -0
  44. data/test/releasy/builders/data/Info.plist +51 -0
  45. data/test/releasy/builders/data/Main.rb +12 -0
  46. data/test/releasy/builders/data/relapse_runner.rb +1 -0
  47. data/test/releasy/builders/data/set_app_executable.sh +3 -0
  48. data/test/releasy/builders/helpers/helper.rb +47 -0
  49. data/test/releasy/builders/ocra_builder_test.rb +37 -0
  50. data/test/releasy/builders/osx_app_test.rb +107 -0
  51. data/test/releasy/builders/source_test.rb +43 -0
  52. data/test/releasy/builders/windows_builder_test.rb +26 -0
  53. data/test/releasy/builders/windows_folder_from_ruby_dist_test.rb +105 -0
  54. data/test/releasy/builders/windows_folder_test.rb +56 -0
  55. data/test/releasy/builders/windows_installer_test.rb +62 -0
  56. data/test/releasy/builders/windows_standalone_test.rb +58 -0
  57. data/test/releasy/cli/install_sfx_test.rb +90 -0
  58. data/test/releasy/dsl_wrapper_test.rb +79 -0
  59. data/test/releasy/integration/source_test.rb +122 -0
  60. data/test/releasy/mixins/register_test.rb +52 -0
  61. data/test/releasy/project_test.rb +198 -0
  62. data/test/releasy/windows_wrapper_maker_test.rb +61 -0
  63. data/test/teststrap.rb +52 -0
  64. data/test/yard_test.rb +61 -0
  65. data/test_project/Gemfile +9 -0
  66. data/test_project/LICENSE.txt +1 -0
  67. data/test_project/README.txt +2 -0
  68. data/test_project/bin/test_app +3 -0
  69. data/test_project/lib/test_app.rb +6 -0
  70. data/test_project/lib/test_app/stuff.rb +1 -0
  71. data/test_project/test_app.icns +0 -0
  72. data/test_project/test_app.ico +0 -0
  73. data/wrappers/put_wrappers_here_for_testing.txt +17 -0
  74. metadata +236 -0
@@ -0,0 +1,79 @@
1
+ require File.expand_path("../teststrap", File.dirname(__FILE__))
2
+
3
+ context Releasy::DSLWrapper do
4
+ helper :owner_class do
5
+ # Can't simply stub, since the DSLWrapper redirection methods are created when from the owner's methods.
6
+ Owner = Class.new do
7
+ def frog; end
8
+ def fish; end
9
+ def fish=(fish); end
10
+ def knees=(knees); end
11
+ def add_cheese(a, b); end
12
+ def add_peas(a, &block); end
13
+ end
14
+ end
15
+
16
+ helper(:owner) { @owner ||= owner_class.new }
17
+
18
+ setup { Releasy::DSLWrapper.new owner }
19
+
20
+ expected_methods = [:frog, :fish, :add_cheese, :owner, :add_peas, :knees]
21
+ expected_methods.map!(&:to_s) if RUBY_VERSION =~ /1\.8\./
22
+ asserts(:public_methods, false).same_elements expected_methods
23
+ asserts(:owner).equals { owner }
24
+
25
+ asserts("a method that doesn't exist on the owner") { topic.wibble }.raises NoMethodError, /<Owner:0x\w+> does not have either public method, #wibble or #wibble=/
26
+
27
+ should "redirect to a setter, that has no corresponding getter, even if no arguments are passed" do
28
+ topic.knees
29
+ end.raises ArgumentError
30
+
31
+ should "redirect to a getter, that has no corresponding setter, even if arguments are passed" do
32
+ topic.frog 25
33
+ end.raises ArgumentError
34
+
35
+ should "redirect a getter (that has no corresponding setter)" do
36
+ mock(owner, :frog).returns(5)
37
+ topic.frog == 5
38
+ end
39
+
40
+ should "redirect a setter (that has no corresponding getter)" do
41
+ mock(owner, :knees=).with(1).returns(5)
42
+ topic.knees(1) == 5
43
+ end
44
+
45
+ should "redirect a getter (that has a corresponding setter)" do
46
+ mock(owner, :fish).returns(5)
47
+ topic.fish == 5
48
+ end
49
+
50
+ should "redirect a setter (that has a corresponding getter)" do
51
+ mock(owner, :fish=).with(5).returns(5)
52
+ topic.fish(5) == 5
53
+ end
54
+
55
+ should "redirect a (non-setter) method with args" do
56
+ mock(owner).add_cheese(1, 2).returns(99)
57
+ topic.add_cheese(1, 2) == 99
58
+ end
59
+
60
+ should "redirect a block" do
61
+ mock(owner).add_peas(1).yields(:knees)
62
+ yielded = nil
63
+ topic.add_peas(1) do |arg|
64
+ yielded = arg
65
+ end
66
+ yielded == :knees
67
+ end
68
+
69
+ should "instance_eval when given a block on the constructor (.new)" do
70
+ mock(owner).frog(5)
71
+ Releasy::DSLWrapper.new owner do
72
+ frog 5
73
+ end
74
+ true
75
+ end
76
+
77
+ asserts(".wrap is an alias for .new without a block") { Releasy::DSLWrapper.wrap(owner).is_a? Releasy::DSLWrapper }
78
+ asserts(".wrap is an alias for .new given a block") { (Releasy::DSLWrapper.wrap(owner) {}).is_a? Releasy::DSLWrapper }
79
+ end
@@ -0,0 +1,122 @@
1
+ require File.expand_path("../../teststrap", File.dirname(__FILE__))
2
+
3
+ folder = File.join(output_path, "test_app_0_1_SOURCE")
4
+
5
+ def md5_created(extension)
6
+ file = "#{File.join(output_path, "test_app_0_1_SOURCE")}#{extension}.MD5"
7
+ asserts("MD5 file created") { File.exists?(file) }
8
+ asserts("MD5 file contents sensible") { File.read(file) =~ /^[0-9a-f]{32}$/ }
9
+ end
10
+
11
+ _output_path = output_path # Needed to get to work in the DSLWrapper.
12
+ context "Source in all formats" do
13
+ setup do
14
+ Releasy::Project.new do
15
+ name "Test App"
16
+ version "0.1"
17
+ files source_files
18
+ output_path _output_path
19
+ verbose
20
+ create_md5s
21
+
22
+ add_build :source do
23
+ add_archive :dmg
24
+ add_archive :exe
25
+ add_archive :zip
26
+ add_archive :"7z"
27
+ end
28
+
29
+ add_archive :tar_gz
30
+ add_archive :tar_bz2
31
+ end
32
+ end
33
+
34
+ teardown do
35
+ Rake::Task.clear
36
+ Dir.chdir $original_path
37
+ end
38
+
39
+ hookup do
40
+ Dir.chdir project_path
41
+ end
42
+
43
+ helper(:contents_description) { /#{source_files.size} files, 4 folders/m }
44
+
45
+ active_builders_valid
46
+
47
+ context "tasks" do
48
+ tasks = [
49
+ [ :Task, "package", %w[package:source] ],
50
+ [ :Task, "package:source", %w[package:source:dmg package:source:7z package:source:exe package:source:tar_gz package:source:tar_bz2 package:source:zip] ],
51
+ [ :Task, "package:source:dmg", ["#{folder}.dmg"] ],
52
+ [ :Task, "package:source:7z", ["#{folder}.7z"] ],
53
+ [ :Task, "package:source:exe", ["#{folder}.exe"] ],
54
+ [ :Task, "package:source:tar_gz", ["#{folder}.tar.gz"] ],
55
+ [ :Task, "package:source:tar_bz2", ["#{folder}.tar.bz2"] ],
56
+ [ :Task, "package:source:zip", ["#{folder}.zip"] ],
57
+
58
+ [ :Task, "build", %w[build:source] ],
59
+ [ :Task, "build:source", [folder] ],
60
+
61
+ [ :FileCreationTask, '..', [] ],
62
+ [ :FileCreationTask, output_path, [] ], # byproduct of using #directory
63
+ [ :FileCreationTask, folder, source_files ],
64
+ [ :FileTask, "#{folder}.dmg", [folder] ],
65
+ [ :FileTask, "#{folder}.7z", [folder] ],
66
+ [ :FileTask, "#{folder}.exe", [folder] ],
67
+ [ :FileTask, "#{folder}.tar.gz", [folder] ],
68
+ [ :FileTask, "#{folder}.tar.bz2", [folder] ],
69
+ [ :FileTask, "#{folder}.zip", [folder] ],
70
+ ]
71
+
72
+ test_tasks tasks
73
+ end
74
+
75
+ if osx_platform?
76
+ # TODO: Test this better?
77
+ context "dmg" do
78
+ hookup { Rake::Task["package:source:dmg"].invoke }
79
+
80
+ asserts("archive created") { File.size("#{folder}.dmg") > 0}
81
+ end
82
+ end
83
+
84
+ context ".exe" do
85
+ hookup { Rake::Task["package:source:exe"].invoke }
86
+
87
+ asserts("archive created") { File.size("#{folder}.exe") > 0}
88
+ md5_created ".exe"
89
+ end
90
+
91
+ context ".tar.gz" do
92
+ hookup { Rake::Task["package:source:tar_gz"].invoke }
93
+
94
+ asserts("archive created") { File.size("#{folder}.tar.gz") > 0}
95
+ asserts("archive contains expected files") { `7z x -so -bd -tgzip #{folder}.tar.gz | 7z l -si -bd -ttar` =~ contents_description }
96
+ md5_created ".tar.gz"
97
+ end
98
+
99
+ context ".tar.bz2" do
100
+ hookup { Rake::Task["package:source:tar_bz2"].invoke }
101
+
102
+ asserts("archive created") { File.size("#{folder}.tar.bz2") > 0}
103
+ asserts("archive contains expected files") { `7z x -so -bd -tbzip2 #{folder}.tar.bz2 | 7z l -si -bd -ttar` =~ contents_description }
104
+ md5_created ".tar.bz2"
105
+ end
106
+
107
+ context ".zip" do
108
+ hookup { Rake::Task["package:source:zip"].invoke }
109
+
110
+ asserts("archive created") { File.size("#{folder}.zip") > 0}
111
+ asserts("archive contains expected files") { `7z l -bd -tzip #{folder}.zip` =~ contents_description }
112
+ md5_created ".zip"
113
+ end
114
+
115
+ context ".7z" do
116
+ hookup { Rake::Task["package:source:7z"].invoke }
117
+
118
+ asserts("archive created") { File.size("#{folder}.7z") > 0}
119
+ asserts("archive contains expected files") { `7z l -bd -t7z #{folder}.7z` =~ contents_description }
120
+ md5_created ".7z"
121
+ end
122
+ end
@@ -0,0 +1,52 @@
1
+ require File.expand_path("../../teststrap", File.dirname(__FILE__))
2
+
3
+ context Releasy::Mixins::Register do
4
+ setup do
5
+ module RegisterTest
6
+ extend Releasy::Mixins::Register
7
+ end
8
+ end
9
+
10
+ asserts(:[], :blue).nil
11
+ asserts(:has_type?, :blue).equals false
12
+ asserts(:types).same_elements []
13
+ asserts(:values).same_elements []
14
+
15
+ hookup do
16
+ unless defined? NotInModule
17
+ class NotInModule; TYPE = :wibbly; end
18
+ class RegisterTest::Untyped; end
19
+ end
20
+ end
21
+
22
+ asserts("trying to register a non-class") { topic.register 12 }.raises TypeError, /Can only register classes/
23
+ asserts("trying to register a class not within the module") { topic.register NotInModule }.raises ArgumentError, /Can't register a class not within this module/
24
+ asserts("trying to register a class without TYPE, even if in the module") { topic.register topic::Untyped }.raises ArgumentError, /To register, a class must have TYPE defined/
25
+
26
+ context "with registered classes (blue and red frogs)" do
27
+ setup do
28
+ module Frogs
29
+ extend Releasy::Mixins::Register
30
+ end
31
+ end
32
+
33
+ hookup do
34
+ unless defined? Frogs::BlueFrog
35
+ class Frogs::BlueFrog
36
+ TYPE = :blue # Type must be defined before registering.
37
+ Frogs.register self
38
+ end
39
+
40
+ class Frogs::RedFrog
41
+ TYPE = :red # Type must be defined before registering.
42
+ Frogs.register self
43
+ end
44
+ end
45
+ end
46
+
47
+ asserts(:[], :blue).equals { Frogs::BlueFrog }
48
+ asserts(:has_type?, :blue).equals true
49
+ asserts(:types).same_elements [:blue, :red]
50
+ asserts(:values).same_elements { [Frogs::BlueFrog, Frogs::RedFrog] }
51
+ end
52
+ end
@@ -0,0 +1,198 @@
1
+ require File.expand_path("../teststrap", File.dirname(__FILE__))
2
+
3
+ # Change directory into the project, since that is where we work from normally.
4
+
5
+ # @author Bil Bas (Spooner)
6
+ context Releasy::Project do
7
+ teardown do
8
+ Rake::Task.clear
9
+ Dir.chdir $original_path
10
+ end
11
+
12
+ hookup do
13
+ Dir.chdir project_path
14
+ end
15
+
16
+ context "default" do
17
+ setup { Releasy::Project.new }
18
+
19
+ # Defaults are mostly nil.
20
+ asserts(:name).nil
21
+ asserts(:underscored_name).nil
22
+ asserts(:version).nil
23
+ asserts(:executable).nil
24
+ asserts(:files).empty
25
+ asserts(:files).kind_of Rake::FileList
26
+ asserts(:exposed_files).empty
27
+ asserts(:exposed_files).kind_of Rake::FileList
28
+ asserts(:verbose?).equals true
29
+ asserts(:links).equals Hash.new
30
+ asserts(:create_md5s?).equals false
31
+
32
+ asserts(:to_s).equals "<Releasy::Project>"
33
+ asserts(:output_path).equals "pkg"
34
+ asserts(:folder_base).equals "pkg/" # Would be more, but dependent on name.
35
+
36
+ asserts("attempting to generate tasks without any outputs") { topic.send :generate_tasks }.raises Releasy::ConfigError, /must specify at least one valid output/i
37
+
38
+ asserts(:active_builders).empty
39
+ asserts(:add_build, :source).kind_of Releasy::Builders::Source
40
+ asserts(:active_builders).size 1
41
+ asserts(:add_build, :source).raises(Releasy::ConfigError, /already have output :source/i)
42
+ asserts(:add_build, :unknown).raises(ArgumentError, /unsupported output/i)
43
+
44
+ asserts("active_archivers") { topic.send(:active_archivers, topic.send(:active_builders).first) }.empty
45
+ asserts(:add_archive, :zip).kind_of Releasy::Archivers::Zip
46
+ asserts("active_archivers") { topic.send(:active_archivers, topic.send(:active_builders).first) }.size 1
47
+ asserts(:add_archive, :zip).raises(Releasy::ConfigError, /already have archive format :zip/i)
48
+ asserts(:add_archive, :unknown).raises(ArgumentError, /unsupported archive/i)
49
+
50
+ context "#verbose" do
51
+ hookup { topic.quiet }
52
+ hookup { topic.verbose }
53
+ asserts(:verbose?).equals true
54
+ end
55
+
56
+ context "#quiet" do
57
+ hookup { topic.verbose }
58
+ hookup { topic.quiet }
59
+ asserts(:verbose?).equals false
60
+ end
61
+
62
+ context "#create_md5s" do
63
+ hookup { topic.create_md5s }
64
+ asserts(:create_md5s?).equals true
65
+ end
66
+
67
+ context "#files" do
68
+ hookup { topic.files = ["fish.rb"] }
69
+ asserts(:files).size 1
70
+ asserts(:files).kind_of Rake::FileList
71
+ end
72
+
73
+ context "#exposed_files" do
74
+ hookup { topic.exposed_files = "fish.rb" }
75
+ asserts(:exposed_files).size 1
76
+ asserts(:exposed_files).kind_of Rake::FileList
77
+ end
78
+ end
79
+
80
+ context "defined" do
81
+ setup do
82
+ Releasy::Project.new do
83
+ name "Test Project - (2a)"
84
+ version "v0.1.5"
85
+
86
+ add_archive :"7z"
87
+ add_archive :zip
88
+
89
+ add_build :source
90
+ add_build :osx_app do
91
+ add_archive :tar_gz do
92
+ extension "tgz"
93
+ end
94
+ wrapper Dir["../wrappers/gosu-mac-wrapper-*.tar.gz"].first
95
+ url "org.url.app"
96
+ end
97
+ add_build :windows_standalone do
98
+ exclude_encoding
99
+ end
100
+
101
+ files source_files
102
+
103
+ add_link "www.frog.com", "Frog"
104
+ add_link "www2.fish.com", "Fish"
105
+ end
106
+ end
107
+
108
+ asserts(:to_s).equals %[<Releasy::Project Test Project - (2a) v0.1.5>]
109
+ asserts(:name).equals "Test Project - (2a)"
110
+ asserts(:underscored_name).equals "test_project_2a"
111
+ asserts(:version).equals "v0.1.5"
112
+ asserts("file") { topic.files.to_a }.same_elements source_files
113
+ asserts(:underscored_version).equals "v0_1_5"
114
+ asserts(:executable).equals "bin/test_project_2a"
115
+ asserts(:folder_base).equals "pkg/test_project_2a_v0_1_5"
116
+ asserts(:links).equals "www.frog.com" => "Frog", "www2.fish.com" => "Fish"
117
+
118
+ asserts(:active_builders).size(Gem.win_platform? ? 3 : 2)
119
+ asserts("source active_archivers") { topic.send(:active_archivers, topic.send(:active_builders).find {|b| b.type == :source }) }.size 2
120
+ asserts("osx app active_archivers") { topic.send(:active_archivers, topic.send(:active_builders).find {|b| b.type == :osx_app }) }.size 3
121
+ if Gem.win_platform?
122
+ asserts("Windows standalone active_archivers") { topic.send(:active_archivers, topic.send(:active_builders).find {|b| b.type == :windows_standalone }) }.size 2
123
+ end
124
+
125
+ asserts "add_build yields an instance_eval-ed Releasy::DSLWrapper" do
126
+ correct = false
127
+ topic.add_build :windows_folder do
128
+ correct = (is_a?(Releasy::DSLWrapper) and owner.is_a?(Releasy::Builders::WindowsFolder))
129
+ end
130
+ correct
131
+ end
132
+
133
+ asserts "add_archive yields an instance_eval-ed Releasy::DSLWrapper" do
134
+ correct = false
135
+ topic.add_archive :tar_gz do
136
+ correct = (is_a?(Releasy::DSLWrapper) and owner.is_a?(Releasy::Archivers::TarGzip))
137
+ end
138
+ correct
139
+ end
140
+
141
+ context "#generate_archive_tasks" do
142
+ asserts(:generate_archive_tasks).equals { topic }
143
+
144
+ should "call generate_tasks on all archivers" do
145
+ topic.send(:active_builders).each do |builder|
146
+ topic.send(:active_archivers, builder).each {|a| mock(a).generate_tasks(builder.type.to_s.sub('_', ':'), builder.send(:folder)) }
147
+ end
148
+ topic.send :generate_archive_tasks
149
+ end
150
+ end
151
+
152
+ context "#generate_tasks" do
153
+ asserts(:generate_tasks).equals { topic }
154
+
155
+ should "call generate_tasks on all builders" do
156
+ topic.send(:active_builders) {|b| mock(b).generate_tasks }
157
+ topic.send :generate_tasks
158
+ end
159
+
160
+ should "call #generate_archive_tasks" do
161
+ mock(topic).generate_archive_tasks
162
+ topic.send :generate_tasks
163
+ end
164
+ end
165
+
166
+ context "defined with Object#tap-like syntax" do
167
+ setup do
168
+ Releasy::Project.new do |p|
169
+ p.name = "Test Project - (2a)"
170
+ p.version = "v0.1.5"
171
+
172
+ p.add_archive :"7z"
173
+ p.add_archive :zip
174
+
175
+ p.add_build :source
176
+ p.add_build :osx_app do |b|
177
+ b.add_archive :tar_gz do |a|
178
+ a.extension = ".tgz"
179
+ end
180
+ b.wrapper = Dir["../wrappers/gosu-mac-wrapper-*.tar.gz"].first
181
+ b.url = "org.url.app"
182
+ end
183
+ p.add_build :windows_standalone do |b|
184
+ b.exclude_encoding
185
+ end
186
+
187
+ p.files = source_files
188
+
189
+ p.add_link "www.frog.com", "Frog"
190
+ p.add_link "www2.fish.com", "Fish"
191
+ end
192
+ end
193
+
194
+ # Just needed to test that the project was passing into the block.
195
+ asserts(:name).equals "Test Project - (2a)"
196
+ end
197
+ end
198
+ end