irpack 0.1.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/irpack +5 -31
- data/lib/irpack.rb +47 -459
- data/lib/irpack/application.rb +87 -0
- data/lib/irpack/bootloader.rb +110 -0
- data/lib/irpack/cscompiler.rb +115 -0
- data/lib/irpack/entrypoint.rb +217 -0
- data/lib/irpack/missing.rb +45 -0
- data/lib/irpack/packager.rb +51 -0
- data/test/test_application.rb +98 -0
- data/test/test_bootloader.rb +72 -0
- data/test/test_cscompiler.rb +54 -17
- data/test/test_entrypoint.rb +99 -0
- data/test/test_irpack.rb +75 -0
- data/test/test_missing.rb +37 -0
- data/test/test_packager.rb +30 -35
- data/test/utils.rb +79 -0
- metadata +16 -14
@@ -0,0 +1,45 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright (c) 2011 Ryuichi Sakamoto.
|
3
|
+
|
4
|
+
This software is provided 'as-is', without any express or implied
|
5
|
+
warranty. In no event will the authors be held liable for any damages
|
6
|
+
arising from the use of this software.
|
7
|
+
|
8
|
+
Permission is granted to anyone to use this software for any purpose,
|
9
|
+
including commercial applications, and to alter it and redistribute it
|
10
|
+
freely, subject to the following restrictions:
|
11
|
+
|
12
|
+
1. The origin of this software must not be misrepresented; you must not
|
13
|
+
claim that you wrote the original software. If you use this software
|
14
|
+
in a product, an acknowledgment in the product documentation would be
|
15
|
+
appreciated but is not required.
|
16
|
+
|
17
|
+
2. Altered source versions must be plainly marked as such, and must not be
|
18
|
+
misrepresented as being the original software.
|
19
|
+
|
20
|
+
3. This notice may not be removed or altered from any source
|
21
|
+
distribution.
|
22
|
+
=end
|
23
|
+
|
24
|
+
require 'fileutils'
|
25
|
+
require 'tmpdir'
|
26
|
+
|
27
|
+
if not Dir.respond_to?(:mktmpdir) or
|
28
|
+
not File::Stat.instance_methods.include?(:world_writable) then
|
29
|
+
def Dir.mktmpdir(prefix='d', tmpdir=Dir.tmpdir, &block)
|
30
|
+
n = 0
|
31
|
+
begin
|
32
|
+
path = File.join(tmpdir, "#{prefix}-#{Time.now.to_i}-#{$$}-#{rand(0x100000000).to_s(36)}-#{n}")
|
33
|
+
Dir.mkdir(path, 0700)
|
34
|
+
rescue Errno::EEXIST
|
35
|
+
n += 1
|
36
|
+
retry
|
37
|
+
end
|
38
|
+
begin
|
39
|
+
block.call(path)
|
40
|
+
ensure
|
41
|
+
FileUtils.remove_entry(path)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright (c) 2011 Ryuichi Sakamoto.
|
3
|
+
|
4
|
+
This software is provided 'as-is', without any express or implied
|
5
|
+
warranty. In no event will the authors be held liable for any damages
|
6
|
+
arising from the use of this software.
|
7
|
+
|
8
|
+
Permission is granted to anyone to use this software for any purpose,
|
9
|
+
including commercial applications, and to alter it and redistribute it
|
10
|
+
freely, subject to the following restrictions:
|
11
|
+
|
12
|
+
1. The origin of this software must not be misrepresented; you must not
|
13
|
+
claim that you wrote the original software. If you use this software
|
14
|
+
in a product, an acknowledgment in the product documentation would be
|
15
|
+
appreciated but is not required.
|
16
|
+
|
17
|
+
2. Altered source versions must be plainly marked as such, and must not be
|
18
|
+
misrepresented as being the original software.
|
19
|
+
|
20
|
+
3. This notice may not be removed or altered from any source
|
21
|
+
distribution.
|
22
|
+
=end
|
23
|
+
|
24
|
+
require 'WindowsBase'
|
25
|
+
|
26
|
+
module IRPack
|
27
|
+
module Packager
|
28
|
+
include System
|
29
|
+
include System::IO::Packaging
|
30
|
+
|
31
|
+
RelType = 'http://schemas.openxmlformats.org/package/2006/relationships/meta data/core-properties'
|
32
|
+
module_function
|
33
|
+
def pack(files, package_file, compress=false)
|
34
|
+
compress_option = compress ? CompressionOption.normal : CompressionOption.not_compressed
|
35
|
+
package = Package.open(package_file, System::IO::FileMode.create)
|
36
|
+
files.each do |src, dest|
|
37
|
+
uri = PackUriHelper.create_part_uri(Uri.new(dest, UriKind.relative))
|
38
|
+
part = package.create_part(uri, 'application/octet-stream', compress_option)
|
39
|
+
stream = part.get_stream
|
40
|
+
File.open(src, 'rb') do |f|
|
41
|
+
data = f.read
|
42
|
+
stream.write(data, 0, data.size)
|
43
|
+
end
|
44
|
+
stream.close
|
45
|
+
package.create_relationship(uri, TargetMode.internal, RelType)
|
46
|
+
end
|
47
|
+
package.close
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
@@ -0,0 +1,98 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright (c) 2011 Ryuichi Sakamoto.
|
3
|
+
|
4
|
+
This software is provided 'as-is', without any express or implied
|
5
|
+
warranty. In no event will the authors be held liable for any damages
|
6
|
+
arising from the use of this software.
|
7
|
+
|
8
|
+
Permission is granted to anyone to use this software for any purpose,
|
9
|
+
including commercial applications, and to alter it and redistribute it
|
10
|
+
freely, subject to the following restrictions:
|
11
|
+
|
12
|
+
1. The origin of this software must not be misrepresented; you must not
|
13
|
+
claim that you wrote the original software. If you use this software
|
14
|
+
in a product, an acknowledgment in the product documentation would be
|
15
|
+
appreciated but is not required.
|
16
|
+
|
17
|
+
2. Altered source versions must be plainly marked as such, and must not be
|
18
|
+
misrepresented as being the original software.
|
19
|
+
|
20
|
+
3. This notice may not be removed or altered from any source
|
21
|
+
distribution.
|
22
|
+
=end
|
23
|
+
|
24
|
+
require 'test/unit'
|
25
|
+
require 'irpack/application'
|
26
|
+
require 'utils'
|
27
|
+
require 'stringio'
|
28
|
+
|
29
|
+
class TC_ApplicationArguments < Test::Unit::TestCase
|
30
|
+
include Utils
|
31
|
+
def test_parse_without_args
|
32
|
+
argv = []
|
33
|
+
$stderr = StringIO.new
|
34
|
+
assert_nil(IRPack::Application::Arguments.parse!(argv))
|
35
|
+
assert_not_equal('', $stderr.to_s)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_parse
|
39
|
+
argv = ['entry.rb']
|
40
|
+
args = IRPack::Application::Arguments.parse!(argv)
|
41
|
+
assert(!args.compress)
|
42
|
+
assert(args.embed_references)
|
43
|
+
assert_equal(:exe, args.target)
|
44
|
+
assert_equal(File.expand_path('entry.exe'), File.expand_path(args.output_file))
|
45
|
+
assert_equal('entry.rb', args.entry_file)
|
46
|
+
assert_equal(1, args.files.size)
|
47
|
+
assert_equal('entry.rb', args.files[File.expand_path('entry.rb')])
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_parse_output_file
|
51
|
+
argv = ['-o', 'foo.exe', 'entry.rb']
|
52
|
+
args = IRPack::Application::Arguments.parse!(argv)
|
53
|
+
assert_equal(File.expand_path('foo.exe'), File.expand_path(args.output_file))
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_parse_window_app
|
57
|
+
argv = ['--window', 'entry.rb']
|
58
|
+
args = IRPack::Application::Arguments.parse!(argv)
|
59
|
+
assert_equal(:winexe, args.target)
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_parse_console_app
|
63
|
+
argv = ['--console', 'entry.rb']
|
64
|
+
args = IRPack::Application::Arguments.parse!(argv)
|
65
|
+
assert_equal(:exe, args.target)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_parse_no_embed_references
|
69
|
+
argv = ['--no-embed', 'entry.rb']
|
70
|
+
args = IRPack::Application::Arguments.parse!(argv)
|
71
|
+
assert(!args.embed_references)
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_parse_compress
|
75
|
+
argv = ['--compress', 'entry.rb']
|
76
|
+
args = IRPack::Application::Arguments.parse!(argv)
|
77
|
+
assert(args.compress)
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_parse_basedir
|
81
|
+
argv = [
|
82
|
+
'-b', 'foo/bar',
|
83
|
+
'entry.rb',
|
84
|
+
'foo/bar/baz.rb',
|
85
|
+
File.expand_path('foo/bar/hoge.rb'),
|
86
|
+
'foo/bar/hoge/fuga.rb',
|
87
|
+
]
|
88
|
+
args = IRPack::Application::Arguments.parse!(argv)
|
89
|
+
assert_equal(File.expand_path('entry.exe'), File.expand_path(args.output_file))
|
90
|
+
assert_equal('../../entry.rb', args.entry_file)
|
91
|
+
assert_equal(4, args.files.size)
|
92
|
+
assert_equal('../../entry.rb', args.files[File.expand_path('entry.rb')])
|
93
|
+
assert_equal('baz.rb', args.files[File.expand_path('foo/bar/baz.rb')])
|
94
|
+
assert_equal('hoge.rb', args.files[File.expand_path('foo/bar/hoge.rb')])
|
95
|
+
assert_equal('hoge/fuga.rb', args.files[File.expand_path('foo/bar/hoge/fuga.rb')])
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
@@ -0,0 +1,72 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright (c) 2011 Ryuichi Sakamoto.
|
3
|
+
|
4
|
+
This software is provided 'as-is', without any express or implied
|
5
|
+
warranty. In no event will the authors be held liable for any damages
|
6
|
+
arising from the use of this software.
|
7
|
+
|
8
|
+
Permission is granted to anyone to use this software for any purpose,
|
9
|
+
including commercial applications, and to alter it and redistribute it
|
10
|
+
freely, subject to the following restrictions:
|
11
|
+
|
12
|
+
1. The origin of this software must not be misrepresented; you must not
|
13
|
+
claim that you wrote the original software. If you use this software
|
14
|
+
in a product, an acknowledgment in the product documentation would be
|
15
|
+
appreciated but is not required.
|
16
|
+
|
17
|
+
2. Altered source versions must be plainly marked as such, and must not be
|
18
|
+
misrepresented as being the original software.
|
19
|
+
|
20
|
+
3. This notice may not be removed or altered from any source
|
21
|
+
distribution.
|
22
|
+
=end
|
23
|
+
|
24
|
+
require 'test/unit'
|
25
|
+
require 'irpack/bootloader'
|
26
|
+
require 'utils'
|
27
|
+
require 'erb'
|
28
|
+
|
29
|
+
class TC_IRPack_BootLoader < Test::Unit::TestCase
|
30
|
+
include Utils
|
31
|
+
ENTRYPOINT_SRC = <<-CS
|
32
|
+
using System;
|
33
|
+
using System.IO;
|
34
|
+
using System.IO.Packaging;
|
35
|
+
|
36
|
+
namespace <%= module_name %> {
|
37
|
+
public class EntryPoint
|
38
|
+
{
|
39
|
+
public static int Main(Package package, string[] args)
|
40
|
+
{
|
41
|
+
Console.WriteLine("Hello World!");
|
42
|
+
return 0;
|
43
|
+
}
|
44
|
+
}
|
45
|
+
}
|
46
|
+
CS
|
47
|
+
|
48
|
+
def compile_entrypoint(output_file, module_name)
|
49
|
+
sysasm = IRPack::CSCompiler.system_assemblies.collect {|asm|
|
50
|
+
IRPack::CSCompiler.assembly_location(asm)
|
51
|
+
}
|
52
|
+
IRPack::CSCompiler.compile(:dll, output_file, ERB.new(ENTRYPOINT_SRC).result(binding), sysasm, [])
|
53
|
+
output_file
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_compile
|
57
|
+
module_name = 'TestModule'
|
58
|
+
entrypoint = tempfilename
|
59
|
+
references = ironruby_assemblies
|
60
|
+
package_file = tempfilename
|
61
|
+
|
62
|
+
compile_entrypoint(entrypoint, module_name)
|
63
|
+
package = create_package(package_file, 'TestModule.EntryPoint.dll' => File.open(entrypoint, 'rb') {|f| f.read })
|
64
|
+
|
65
|
+
exe = tempfilename('.exe')
|
66
|
+
assert_equal(exe, IRPack::BootLoader.compile(:exe, exe, module_name, references, package_file))
|
67
|
+
res = `#{exe}`.chomp
|
68
|
+
assert_equal('Hello World!', res)
|
69
|
+
package.close
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
data/test/test_cscompiler.rb
CHANGED
@@ -1,17 +1,56 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright (c) 2011 Ryuichi Sakamoto.
|
1
3
|
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
This software is provided 'as-is', without any express or implied
|
5
|
+
warranty. In no event will the authors be held liable for any damages
|
6
|
+
arising from the use of this software.
|
7
|
+
|
8
|
+
Permission is granted to anyone to use this software for any purpose,
|
9
|
+
including commercial applications, and to alter it and redistribute it
|
10
|
+
freely, subject to the following restrictions:
|
11
|
+
|
12
|
+
1. The origin of this software must not be misrepresented; you must not
|
13
|
+
claim that you wrote the original software. If you use this software
|
14
|
+
in a product, an acknowledgment in the product documentation would be
|
15
|
+
appreciated but is not required.
|
8
16
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
17
|
+
2. Altered source versions must be plainly marked as such, and must not be
|
18
|
+
misrepresented as being the original software.
|
19
|
+
|
20
|
+
3. This notice may not be removed or altered from any source
|
21
|
+
distribution.
|
22
|
+
=end
|
23
|
+
|
24
|
+
require 'test/unit'
|
25
|
+
require 'irpack/cscompiler'
|
26
|
+
require 'utils'
|
13
27
|
|
14
28
|
class TC_CSCompiler < Test::Unit::TestCase
|
29
|
+
include Utils
|
30
|
+
def test_system_assemblies
|
31
|
+
assert_equal(IRPack::CSCompiler.system_assemblies(4), [
|
32
|
+
'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089',
|
33
|
+
'WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35',
|
34
|
+
'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089',
|
35
|
+
])
|
36
|
+
[2,3.0,3.5].each do |v|
|
37
|
+
assert_equal(IRPack::CSCompiler.system_assemblies(v), [
|
38
|
+
'System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089',
|
39
|
+
'WindowsBase, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35',
|
40
|
+
'System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089',
|
41
|
+
])
|
42
|
+
assert_raise(ArgumentError) do
|
43
|
+
IRPack::CSCompiler.system_assemblies(5)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_assembly_location
|
49
|
+
path = IRPack::CSCompiler.assembly_location(
|
50
|
+
'System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089')
|
51
|
+
assert_equal(File.basename(path), 'System.dll')
|
52
|
+
end
|
53
|
+
|
15
54
|
def test_compile_dll
|
16
55
|
src = <<-CS
|
17
56
|
using System;
|
@@ -26,19 +65,17 @@ class TC_CSCompiler < Test::Unit::TestCase
|
|
26
65
|
CS
|
27
66
|
references = []
|
28
67
|
resources = []
|
29
|
-
output_file =
|
30
|
-
output_file.close
|
68
|
+
output_file = tempfilename('.dll')
|
31
69
|
result = IRPack::CSCompiler.compile(
|
32
70
|
:dll,
|
71
|
+
output_file,
|
33
72
|
src,
|
34
73
|
references,
|
35
|
-
resources
|
36
|
-
|
37
|
-
)
|
38
|
-
assert_equal(output_file.path, result)
|
74
|
+
resources)
|
75
|
+
assert_equal(output_file, result)
|
39
76
|
asm = nil
|
40
77
|
assert_nothing_raised do
|
41
|
-
asm = System::Reflection::Assembly.load_from(output_file
|
78
|
+
asm = System::Reflection::Assembly.load_from(output_file)
|
42
79
|
end
|
43
80
|
assert(asm.get_type('hoge.Hoge'))
|
44
81
|
assert_nil(asm.entry_point)
|
@@ -0,0 +1,99 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright (c) 2011 Ryuichi Sakamoto.
|
3
|
+
|
4
|
+
This software is provided 'as-is', without any express or implied
|
5
|
+
warranty. In no event will the authors be held liable for any damages
|
6
|
+
arising from the use of this software.
|
7
|
+
|
8
|
+
Permission is granted to anyone to use this software for any purpose,
|
9
|
+
including commercial applications, and to alter it and redistribute it
|
10
|
+
freely, subject to the following restrictions:
|
11
|
+
|
12
|
+
1. The origin of this software must not be misrepresented; you must not
|
13
|
+
claim that you wrote the original software. If you use this software
|
14
|
+
in a product, an acknowledgment in the product documentation would be
|
15
|
+
appreciated but is not required.
|
16
|
+
|
17
|
+
2. Altered source versions must be plainly marked as such, and must not be
|
18
|
+
misrepresented as being the original software.
|
19
|
+
|
20
|
+
3. This notice may not be removed or altered from any source
|
21
|
+
distribution.
|
22
|
+
=end
|
23
|
+
|
24
|
+
require 'test/unit'
|
25
|
+
require 'irpack/entrypoint'
|
26
|
+
require 'utils'
|
27
|
+
|
28
|
+
class TC_IRPack_EntryPoint < Test::Unit::TestCase
|
29
|
+
include Utils
|
30
|
+
|
31
|
+
def test_compile
|
32
|
+
output_file = tempfilename('.dll')
|
33
|
+
module_name = 'TestModule'
|
34
|
+
entry_file = 'foo.rb'
|
35
|
+
references = ironruby_assemblies
|
36
|
+
|
37
|
+
assert_equal(output_file, IRPack::EntryPoint.compile(output_file, module_name, entry_file, references))
|
38
|
+
assert(File.exist?(output_file))
|
39
|
+
asm = nil
|
40
|
+
assert_nothing_raised do
|
41
|
+
asm = System::Reflection::Assembly.load_from(output_file)
|
42
|
+
end
|
43
|
+
entrypoint = asm.get_type("#{module_name}.EntryPoint")
|
44
|
+
assert_not_nil(entrypoint)
|
45
|
+
main = entrypoint.get_method('Main')
|
46
|
+
assert_not_nil(main)
|
47
|
+
create_package('foo.rb' => 'exit ARGV.size') do |package|
|
48
|
+
res = main.invoke(nil, System::Array[System::Object].new([package, System::Array[System::String].new(['hoge', 'fuga', 'piyo'])]))
|
49
|
+
assert_equal(3, res)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_run
|
54
|
+
output_file = tempfilename('.dll')
|
55
|
+
module_name = 'TestModule'
|
56
|
+
entry_file = 'main.rb'
|
57
|
+
references = ironruby_assemblies
|
58
|
+
|
59
|
+
IRPack::EntryPoint.compile(output_file, module_name, entry_file, references)
|
60
|
+
asm = System::Reflection::Assembly.load_from(output_file)
|
61
|
+
main = asm.get_type("#{module_name}.EntryPoint").get_method('Main')
|
62
|
+
assert_not_nil(main)
|
63
|
+
main_rb = <<-RB
|
64
|
+
puts 'Hello World!'
|
65
|
+
RB
|
66
|
+
create_package('main.rb' => main_rb) do |package|
|
67
|
+
res = main.invoke(nil, System::Array[System::Object].new([package, System::Array[System::String].new(0)]))
|
68
|
+
assert_equal(0, res)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_run_raised
|
73
|
+
output_file = tempfilename('.dll')
|
74
|
+
module_name = 'TestModule'
|
75
|
+
entry_file = 'main.rb'
|
76
|
+
references = ironruby_assemblies
|
77
|
+
|
78
|
+
IRPack::EntryPoint.compile(output_file, module_name, entry_file, references)
|
79
|
+
asm = System::Reflection::Assembly.load_from(output_file)
|
80
|
+
main = asm.get_type("#{module_name}.EntryPoint").get_method('Main')
|
81
|
+
assert_not_nil(main)
|
82
|
+
main_rb = <<-RB
|
83
|
+
raise RuntimeError, 'Hello Exception!'
|
84
|
+
RB
|
85
|
+
create_package('main.rb' => main_rb) do |package|
|
86
|
+
res = nil
|
87
|
+
err = System::IO::StringWriter.new
|
88
|
+
assert_nothing_raised do
|
89
|
+
prev_err = System::Console.error
|
90
|
+
System::Console.set_error(err)
|
91
|
+
res = main.invoke(nil, System::Array[System::Object].new([package, System::Array[System::String].new(0)]))
|
92
|
+
System::Console.set_error(prev_err)
|
93
|
+
end
|
94
|
+
assert_match(/Hello Exception!/, err.get_string_builder.to_string)
|
95
|
+
assert_equal(-1, res)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|