releasy 0.2.0rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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,43 @@
1
+ require File.expand_path("helpers/helper", File.dirname(__FILE__))
2
+
3
+ folder = File.join(output_path, "test_app_0_1_SOURCE")
4
+ context Releasy::Builders::Source do
5
+ setup { Releasy::Builders::Source.new new_project }
6
+
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 "valid" do
17
+ hookup do
18
+
19
+ topic.send :generate_tasks
20
+ end
21
+
22
+ asserts(:folder).equals folder
23
+ asserts(:folder_suffix).equals "SOURCE"
24
+
25
+ context "tasks" do
26
+ tasks = [
27
+ [ :Task, "build:source", [folder] ],
28
+ [ :FileCreationTask, '..', [] ], # byproduct of using #directory
29
+ [ :FileCreationTask, output_path, [] ], # byproduct of using #directory
30
+ [ :FileCreationTask, folder, source_files ],
31
+ ]
32
+
33
+ test_tasks tasks
34
+ end
35
+
36
+ context "generate folder" do
37
+ hookup { Rake::Task["build:source"].invoke }
38
+
39
+ asserts("files copied to folder") { source_files.all? {|f| same_contents? "#{folder}/#{f}", f } }
40
+ asserts("program output") { %x[ruby "#{folder}/bin/test_app"] }.equals "test run!\n"
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,26 @@
1
+ require File.expand_path("helpers/helper", File.dirname(__FILE__))
2
+
3
+ context Releasy::Builders::WindowsBuilder do
4
+ setup do
5
+ Class.new(Releasy::Builders::WindowsBuilder) do
6
+ const_set :DEFAULT_FOLDER_SUFFIX, ''
7
+ end.new new_project
8
+ end
9
+
10
+ context "#executable_type undefined and Project#executable doesn't have meaningful extension" do
11
+ hookup { topic.project.executable = "fred" }
12
+ asserts(:effective_executable_type).raises Releasy::ConfigError, /Unless the executable file extension is .rbw or .rb, then #executable_type must be explicitly :windows or :console/
13
+ end
14
+
15
+ context "valid" do
16
+ hookup { topic.executable_type = :console }
17
+
18
+ asserts(:effective_executable_type).equals :console
19
+ asserts(:encoding_excluded?).equals false
20
+
21
+ context "exclude_encoding" do
22
+ hookup { topic.exclude_encoding }
23
+ asserts(:encoding_excluded?).equals true
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,105 @@
1
+ require File.expand_path("helpers/helper", File.dirname(__FILE__))
2
+
3
+ Dir[File.expand_path("wrappers/ruby-*.7z", $original_path)].each do |path_to_ruby_dist|
4
+ ruby_version = path_to_ruby_dist[/\d\.\d\.\d-p\d+/]
5
+ suffix = "WIN32_FROM_RUBY_DIST_#{ruby_version.tr(".", "_")}"
6
+ folder = File.join(output_path, "test_app_0_1_#{suffix}")
7
+
8
+ context "#{Releasy::Builders::WindowsFolderFromRubyDist} for #{ruby_version}" do
9
+ setup { Releasy::Builders::WindowsFolderFromRubyDist.new new_project }
10
+
11
+ teardown do
12
+ Dir.chdir $original_path
13
+ Rake::Task.clear
14
+ end
15
+
16
+ hookup do
17
+ Dir.chdir project_path
18
+ end
19
+
20
+ asserts(:ruby_dist).nil
21
+ asserts(:folder_suffix).equals "WIN32"
22
+ asserts(:generate_tasks).raises Releasy::ConfigError, /ruby_dist not set/
23
+ denies(:gemspecs).empty
24
+
25
+ if Gem.win_platform?
26
+ denies(:valid_for_platform?)
27
+ else
28
+ asserts(:valid_for_platform?)
29
+ end
30
+
31
+ context "invalid ruby_dist" do
32
+ hookup do
33
+ topic.ruby_dist = "ruby_dist"
34
+ end
35
+
36
+ asserts(:generate_tasks).raises Releasy::ConfigError, /ruby_dist not valid/
37
+ end
38
+
39
+ context "valid" do
40
+ hookup do
41
+ stub(topic).valid_for_platform?.returns(true) # Need to do this so we can test on all platforms.
42
+ topic.ruby_dist = path_to_ruby_dist
43
+ topic.folder_suffix = suffix
44
+ topic.executable_type = :console
45
+ topic.gemspecs = gemspecs_to_use
46
+ topic.exclude_tcl_tk
47
+ topic.exclude_encoding
48
+ topic.send :generate_tasks
49
+ end
50
+
51
+ asserts(:output_path).equals output_path
52
+ asserts(:folder_suffix).equals suffix
53
+ asserts(:ruby_dist).equals path_to_ruby_dist
54
+ asserts("gemspecs correct") { topic.gemspecs == gemspecs_to_use }
55
+
56
+ context "tasks" do
57
+ tasks = [
58
+ [ :Task, "build:windows:folder_from_ruby_dist", [folder] ],
59
+ [ :FileTask, '..', [] ], # byproduct of using #directory
60
+ [ :FileTask, output_path, [] ], # byproduct of using #directory
61
+ [ :FileTask, folder, source_files + [path_to_ruby_dist]],
62
+ ]
63
+
64
+ test_tasks tasks
65
+ end
66
+
67
+ context "generate" do
68
+ hookup { Rake::Task["build:windows:folder_from_ruby_dist"].invoke }
69
+
70
+ asserts("files copied to folder") { source_files.all? {|f| same_contents? "#{folder}/src/#{f}", f } }
71
+ asserts("readme copied to folder") { same_contents? "#{folder}/README.txt", "README.txt" }
72
+ asserts("license copied to folder") { same_contents? "#{folder}/LICENSE.txt", "LICENSE.txt" }
73
+
74
+ asserts("test_app.exe has been created") { File.exists?("#{folder}/test_app.exe") }
75
+ denies("console.exe left in folder") { File.exists?("#{folder}/console.exe") }
76
+ denies("windows.exe left in folder") { File.exists?("#{folder}/windows.exe") }
77
+
78
+ asserts("ruby.exe left in bin/") { File.exists?("#{folder}/bin/ruby.exe") }
79
+ denies("rubyw.exe left in bin/") { File.exists?("#{folder}/bin/rubyw.exe") }
80
+
81
+ asserts("plenty of dlls copied") { Dir["#{folder}/bin/*.dll"].size >= 6 }
82
+
83
+ denies("tcl/tk left") { (Dir["#{folder}/**/tk*", "#{folder}/**/tcl*"].reject {|f| f =~ %r[test/unit] }).any? }
84
+ denies("share folder left") { File.exist?("#{folder}/share") }
85
+
86
+ if ruby_version =~ /^1\.9\.\d/
87
+ helper(:enc_folder) { "#{folder}/lib/ruby/1.9.1/i386-mingw32/enc" }
88
+ denies("include folder left") { File.exist?("#{folder}/include") }
89
+
90
+ asserts("remaining encoding files") { Dir["#{enc_folder}/**/*.so"].map {|f| f[(enc_folder.size + 1)..-1] } }.same_elements %w[encdb.so iso_8859_1.so utf_16le.so trans/single_byte.so trans/transdb.so trans/utf_16_32.so]
91
+ end
92
+
93
+ gemspecs_to_use.each do |gemspec|
94
+ name = "#{gemspec.name}-#{gemspec.version}"
95
+ asserts("#{name} gem specification copied") { File.exists? "#{folder}/vendor/specifications/#{name}.gemspec" }
96
+ asserts("#{name} gem folder copied") { File.directory? "#{folder}/vendor/gems/#{name}" }
97
+ end
98
+
99
+ if Gem.win_platform?
100
+ asserts("program output") { %x[#{folder}/test_app.exe] }.equals "test run!\n"
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,56 @@
1
+ require File.expand_path("helpers/helper", File.dirname(__FILE__))
2
+
3
+ folder = File.join(output_path, "test_app_0_1_WIN32")
4
+
5
+ context Releasy::Builders::WindowsFolder do
6
+ setup { Releasy::Builders::WindowsFolder.new new_project }
7
+
8
+ teardown do
9
+ Rake::Task.clear
10
+ Dir.chdir $original_path
11
+ end
12
+
13
+ hookup { Dir.chdir project_path }
14
+
15
+ context "valid" do
16
+ if Gem.win_platform?
17
+ context "on Windows" do
18
+ hookup do
19
+ topic.exclude_encoding
20
+ topic.executable_type = :console
21
+ topic.send :generate_tasks
22
+ end
23
+
24
+ asserts(:valid_for_platform?)
25
+ asserts(:folder_suffix).equals "WIN32"
26
+ asserts(:executable_name).equals "test_app.exe"
27
+ asserts(:folder).equals folder
28
+ asserts(:icon=, "test_app.icns").raises ArgumentError, /icon must be a .ico file/
29
+
30
+ context "tasks" do
31
+ tasks = [
32
+ [ :Task, "build:windows:folder", [folder] ],
33
+ [ :FileTask, '..', [] ], # byproduct of using #directory
34
+ [ :FileTask, output_path, [] ],
35
+ [ :FileTask, folder, source_files ],
36
+ ]
37
+
38
+ test_tasks tasks
39
+ end
40
+
41
+ context "generate folder" do
42
+ hookup { clear_bundler_env { Rake::Task["build:windows:folder"].invoke } }
43
+
44
+ asserts("files copied to folder") { source_files.all? {|f| same_contents? "#{folder}/src/#{f}", f } }
45
+ asserts("folder includes link") { File.read("#{folder}/Releasy website.url") == link_file }
46
+ asserts("executable created in folder and is of reasonable size") { File.size("#{folder}/test_app.exe") > 0 }
47
+ asserts("program output") { %x[#{folder}/test_app.exe] }.equals "test run!\n"
48
+ end
49
+ end
50
+ else
51
+ context "NOT on Windows" do
52
+ denies(:valid_for_platform?)
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,62 @@
1
+ require File.expand_path("helpers/helper", File.dirname(__FILE__))
2
+
3
+ folder = File.join(output_path, "test_app_0_1_WIN32_INSTALLER")
4
+
5
+ context Releasy::Builders::WindowsInstaller do
6
+ setup { Releasy::Builders::WindowsInstaller.new new_project }
7
+
8
+ teardown do
9
+ Rake::Task.clear
10
+ Dir.chdir $original_path
11
+ end
12
+
13
+ hookup { Dir.chdir project_path }
14
+
15
+ context "valid" do
16
+ if Gem.win_platform?
17
+ context "on Windows" do
18
+ hookup do
19
+ topic.start_menu_group = "Releasy Test Apps"
20
+ topic.exclude_encoding
21
+ topic.icon = "test_app.ico"
22
+ topic.license = "LICENSE.txt"
23
+ topic.readme = "README.txt"
24
+ topic.executable_type = :console
25
+ topic.send :generate_tasks
26
+ end
27
+
28
+ asserts(:valid_for_platform?)
29
+ asserts(:start_menu_group).equals "Releasy Test Apps"
30
+ asserts(:folder_suffix).equals "WIN32_INSTALLER"
31
+ asserts(:temp_installer_script).equals "#{output_path}/windows_installer.iss"
32
+ asserts(:folder).equals folder
33
+ asserts(:installer_name).equals "#{folder}/test_app_setup.exe"
34
+ asserts(:icon=, "test_app.icns").raises ArgumentError, /icon must be a .ico file/
35
+
36
+ context "tasks" do
37
+ tasks = [
38
+ [ :Task, "build:windows:installer", [folder] ],
39
+ [ :FileCreationTask, '..', [] ], # byproduct of using #directory
40
+ [ :FileCreationTask, output_path, [] ], # byproduct of using #directory
41
+ [ :FileCreationTask, folder, source_files ],
42
+ ]
43
+
44
+ test_tasks tasks
45
+ end
46
+
47
+ context "generate folder" do
48
+ hookup { clear_bundler_env { Rake::Task["build:windows:installer"].invoke } }
49
+
50
+ asserts("readme copied to folder") { same_contents? "#{folder}/README.txt", "README.txt" }
51
+ asserts("license copied to folder") { same_contents? "#{folder}/LICENSE.txt", "LICENSE.txt" }
52
+ asserts("folder includes link") { File.read("#{folder}/Releasy website.url") == link_file }
53
+ asserts("executable created in folder and is of reasonable size") { File.size("#{folder}/test_app_setup.exe") > 2**20 }
54
+ end
55
+ end
56
+ else
57
+ context "NOT on Windows" do
58
+ denies(:valid_for_platform?)
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,58 @@
1
+ require File.expand_path("helpers/helper", File.dirname(__FILE__))
2
+
3
+ folder = File.join(output_path, "test_app_0_1_WIN32_EXE")
4
+
5
+ context Releasy::Builders::WindowsStandalone do
6
+ setup { Releasy::Builders::WindowsStandalone.new new_project }
7
+
8
+ teardown do
9
+ Rake::Task.clear
10
+ Dir.chdir $original_path
11
+ end
12
+
13
+ hookup { Dir.chdir project_path }
14
+
15
+ context "valid" do
16
+ if Gem.win_platform?
17
+ context "on Windows" do
18
+ hookup do
19
+ topic.exclude_encoding
20
+ topic.executable_type = :console
21
+ topic.icon = "test_app.ico"
22
+ topic.send :generate_tasks
23
+ end
24
+
25
+ asserts(:valid_for_platform?)
26
+ asserts(:folder_suffix).equals "WIN32_EXE"
27
+ asserts(:executable_name).equals "test_app.exe"
28
+ asserts(:folder).equals folder
29
+ asserts(:icon=, "test_app.icns").raises ArgumentError, /icon must be a .ico file/
30
+
31
+ context "tasks" do
32
+ tasks = [
33
+ [ :Task, "build:windows:standalone", [folder] ],
34
+ [ :FileCreationTask, '..', [] ], # byproduct of using #directory
35
+ [ :FileCreationTask, output_path, [] ], # byproduct of using #directory
36
+ [ :FileCreationTask, folder, source_files ],
37
+ ]
38
+
39
+ test_tasks tasks
40
+ end
41
+
42
+ context "generate folder" do
43
+ hookup { clear_bundler_env { Rake::Task["build:windows:standalone"].invoke } }
44
+
45
+ asserts("readme copied to folder") { same_contents? "#{folder}/README.txt", "README.txt" }
46
+ asserts("license copied to folder") { same_contents? "#{folder}/LICENSE.txt", "LICENSE.txt" }
47
+ asserts("folder includes link") { File.read("#{folder}/Releasy website.url") == link_file }
48
+ asserts("executable created in folder and is of reasonable size") { File.size("#{folder}/test_app.exe") > 2**20 }
49
+ asserts("program output") { clear_bundler_env { %x[#{folder}/test_app.exe] } }.equals "test run!\n"
50
+ end
51
+ end
52
+ else
53
+ context "NOT on Windows" do
54
+ denies(:valid_for_platform?)
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,90 @@
1
+ require File.expand_path("../../teststrap", File.dirname(__FILE__))
2
+
3
+ require "releasy/cli"
4
+
5
+ module Riot
6
+ class CommandPutsMacro < AssertionMacro
7
+ register :command_puts
8
+
9
+ def evaluate(argv, expected)
10
+ $puts_string = nil
11
+ Releasy::Cli.run argv
12
+ if $puts_string =~ expected
13
+ pass ": command #{argv} expected to print #{expected.inspect} and got #{$puts_string.inspect}"
14
+ else
15
+ fail ": command #{argv} expected to print #{expected.inspect}, but got #{$puts_string.inspect}"
16
+ end
17
+ end
18
+
19
+ def devaluate(argv, expected); raise NotImplementedError; end
20
+ end
21
+
22
+ class CommandExitsAndPutsMacro < CommandPutsMacro
23
+ register :command_exits_and_puts
24
+
25
+ def evaluate(argv, expected)
26
+ $puts_string = nil
27
+ begin
28
+ Releasy::Cli.run argv
29
+ fail ": command #{argv} didn't exit"
30
+ rescue SystemExit
31
+ if $puts_string =~ expected
32
+ pass ": command #{argv} expected to print #{expected.inspect} and got #{$puts_string.inspect}"
33
+ else
34
+ fail ": command #{argv} expected to print #{expected.inspect}, but got #{$puts_string.inspect}"
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ context "releasy install-sfx" do
42
+ context "on Windows" do
43
+ should "refuse on windows" do
44
+ mock(Gem).win_platform?.returns true
45
+ any_instance_of(Cri::CommandDSL) {|o| stub(o).puts {|s| $puts_string = s } }
46
+ dont_allow(FileUtils).cp
47
+
48
+ ["install-sfx"]
49
+ end.command_exits_and_puts /only required when not on a Windows platform/
50
+ end
51
+
52
+ context "on non-Windows" do
53
+
54
+ helper :stubs do |which_7z|
55
+ mock(Gem).win_platform?.returns false
56
+ any_instance_of(Cri::CommandDSL) do |o|
57
+ stub(o).puts {|s| $puts_string = s }
58
+ stub(o, :`).with("which 7z").returns which_7z
59
+ end
60
+ end
61
+
62
+ should "refuse unless 7z installed" do
63
+ stubs ""
64
+ dont_allow(FileUtils).cp
65
+
66
+ ["install-sfx"]
67
+ end.command_exits_and_puts /7z \(p7zip\) not installed; install it before trying to use this command/
68
+
69
+ should "refuse when file exists" do
70
+ stubs "/usr/bin/7z"
71
+ stub(File).exists?("/usr/lib/p7zip/7z.sfx").returns true
72
+ dont_allow(FileUtils).cp
73
+
74
+ ["install-sfx"]
75
+ end.command_exits_and_puts /already exists; no need to install it again/
76
+
77
+ should "copy sfx file" do
78
+ stubs "/usr/bin/7z"
79
+ stub(File).exists?("/usr/lib/p7zip/7z.sfx").returns false
80
+ stub(FileUtils).cp(File.expand_path("bin/7z.sfx"), "/usr/lib/p7zip", :verbose => true) { raise Errno::ENOENT }
81
+ any_instance_of(Cri::CommandDSL) do |o|
82
+ mock(o).exec(%[sudo cp "#{File.expand_path('bin/7z.sfx')}" "/usr/lib/p7zip"]) do
83
+ stub(File).exists?("/usr/lib/p7zip/7z.sfx").returns true
84
+ end
85
+ end
86
+
87
+ ["install-sfx"]
88
+ end.command_puts %r[7z.sfx copied to /usr/lib/p7zip]
89
+ end
90
+ end