ocra 1.0.3 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,15 @@
1
+ === 1.1.0
2
+
3
+ * Added an icon to the executable. Can be replaced from a .ico file
4
+ using the --icon <ico> option.
5
+
6
+ * Improved handling of load paths added either from the command line
7
+ (ruby -I), RUBYLIB environment variable or during the script (by
8
+ modifying $: or $LOAD_PATH).
9
+
10
+ * Now automatically detects loaded DLLs through Win32::API. Disable
11
+ with --no-autodll.
12
+
1
13
  === 1.0.3 / 2009-05-25
2
14
 
3
15
  * Fixed invokation of executables with spaces in path names (#25966).
@@ -21,4 +33,3 @@
21
33
  * 1 major enhancement
22
34
 
23
35
  * Birthday!
24
-
@@ -6,5 +6,6 @@ bin/ocra.rb
6
6
  share/ocra/lzma.exe
7
7
  share/ocra/stub.exe
8
8
  share/ocra/stubw.exe
9
+ share/ocra/edicon.exe
9
10
  test/test_ocra.rb
10
11
  lib/ocra.rb
data/README.txt CHANGED
@@ -18,6 +18,11 @@ any additionally needed ruby libraries or DLL.
18
18
  * Both console programs and desktop programs supported (no console will
19
19
  pop up with .rbw files).
20
20
 
21
+ If you experience problems with Ocra or have found a bug, please use
22
+ the tracker on the RubyForge project page
23
+ http://rubyforge.org/projects/ocra/. You are welcome to ask questions
24
+ in the forums there aswell.
25
+
21
26
  == TODO:
22
27
 
23
28
  * Clean up using manual recursive deletion (not SHop).
@@ -32,16 +37,18 @@ ocra.rb [option] your/script.rb
32
37
  * Your program should 'require' all necessary files when invoked without
33
38
  arguments, so ocra can detect all dependencies.
34
39
 
35
- * Autoloaded constants (e.g. modules and classes) should work. Ocra
36
- attempts to load all autoload definitions.
40
+ * Ocra executables clear the RUBYLIB environment variable but set
41
+ RUBYOPT to whatever value it had when you invoked Ocra.
37
42
 
38
43
  * Ocra does not set up the include path. Use "$:.unshift
39
44
  File.dirname(__FILE__)" at the start of your script if you need to
40
45
  'require' additional source files in the same directory no matter
41
46
  what the user's current working directory is.
42
47
 
43
- * DLLs needs to be added manually (e.g. sqlite3.dll, gdbm.dll,
44
- etc.). Use the --dll option.
48
+ * Loaded DLLs are detected automatically but only those located in
49
+ your Ruby installation are included. Automatic detection can be
50
+ disabled using --no-autodll. DLLs can be manually added using the
51
+ --dll option.
45
52
 
46
53
  == REQUIREMENTS:
47
54
 
@@ -57,29 +64,96 @@ ocra.rb [option] your/script.rb
57
64
 
58
65
  Can also be downloaded from http://rubyforge.org/frs/?group_id=8185
59
66
 
60
- == Stand-alone
67
+ === Stand-alone
61
68
 
62
69
  Get ocrasa.rb from http://rubyforge.org/frs/?group_id=8185. Requires
63
70
  nothing but a working Ruby installation on Windows.
64
71
 
65
72
  == TECHNICAL DETAILS
66
73
 
67
- The Ocra stub extracts the contents into a temporary directory
68
- (Windows' default temporary directory). The directory will contains
69
- the same directory layout as your Ruby installlation. The source files
70
- for your application will be put in the 'src' subdirectory.
74
+ The Ocra stub extracts the Ruby interpreter and your scripts into a
75
+ temporary directory. The directory will contains the same directory
76
+ layout as your Ruby installlation. The source files for your
77
+ application will be put in the 'src' subdirectory.
78
+
79
+ === Libraries
80
+
81
+ Rubygems will be automatically included in the Ocra executable.
71
82
 
72
83
  Libraries found in non-standard path (for example, if you invoke Ocra
73
84
  with "ruby -I some/path") will be placed into the site dir
74
- (lib/ruby/site_ruby).
85
+ (lib/ruby/site_ruby). Avoid changing $LOAD_PATH / $: from your script
86
+ to include paths outside your source tree.
75
87
 
76
- The RUBYOPT and RUBYLIB variables are cleared before your program is
77
- launched by the executable in order not to interfere with any Ruby
78
- installation on the end user's installation.
79
-
80
- Autoloaded constants will be attempted loaded when building the
88
+ Autoloaded libraries will be attempted loaded when building the
81
89
  executable. Modules that doesn't exist will be ignore (but a warning
82
- will be logged.)
90
+ will be logged).
91
+
92
+ === Environment variables
93
+
94
+ Ocra executables clear the RUBYLIB environment variable before your
95
+ script is launched. This is done to ensure that your script does not
96
+ use load paths from the end user's Ruby installation.
97
+
98
+ Ocra executables set the RUBYOPT environment variable to the value it
99
+ had when you invoked Ocra. For example, if you had "RUBYOPT=rubygems"
100
+ on your build PC, Ocra ensures that it is also set on PC's running the
101
+ executables.
102
+
103
+ === Working directory
104
+
105
+ You should not assume that the current working directory when invoking
106
+ an executable built with .exe is the location of the source script. It
107
+ can be the directory where the executable is placed (when invoked
108
+ through the Windows Explorer), the users' current working directory
109
+ (when invoking from the Command Prompt), or even C:\WINDOWS\SYSTEM32
110
+ when the executable is invoked through a file association. You can
111
+ optionally change the directory yourself:
112
+
113
+ Dir.chdir File.dirname(__FILE__)
114
+
115
+ If you wish to maintain the user's working directory, but need to
116
+ 'require' additional Ruby scripts from the source directory, you can
117
+ add the following line to your script:
118
+
119
+ $LOAD_PATH.unshift File.dirname(__FILE__)
120
+
121
+ === $LOAD_PATH/$: mangling
122
+
123
+ Adding paths to $LOAD_PATH or $: at runtime is not recommended. Adding
124
+ relative load paths depends on the working directory being the same as
125
+ where the script is located (See above). If you have additional
126
+ library files in directories below the directory containing your
127
+ source script you can use this idiom:
128
+
129
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), 'path/to/script')
130
+
131
+ === Detecting OCRA
132
+
133
+ You can detect whether Ocra is currently building your script by
134
+ looking for the 'Ocra' constant. If it is defined, Ocra is currenly
135
+ building the executable from your script. For example, you can use
136
+ this to avoid opening a GUI window when compiling executables:
137
+
138
+ app = MyApp.new
139
+ if not defined?(Ocra)
140
+ app.main_loop
141
+ end
142
+
143
+ === Additional files and resources
144
+
145
+ You can add additional files to the Ocra executable (for example
146
+ images) by appending them to the command line. They should be placed
147
+ in the source directory with your main script (or a subdirectory).
148
+
149
+ ocra.rb mainscript.rb someimage.jpeg docs/document.txt
150
+
151
+ This will create the following layout in the temporary directory when
152
+ your program is executed:
153
+
154
+ src/mainscript.rb
155
+ src/someimage.jpeg
156
+ src/docs/document.txt
83
157
 
84
158
  == CREDITS:
85
159
 
@@ -88,6 +162,9 @@ source code used was place into Public Domain by Igor Pavlov.
88
162
 
89
163
  Erik Veenstra for rubyscript2exe which provided inspiration.
90
164
 
165
+ Dice for the default .exe icon (vit-ruby.ico,
166
+ http://ruby.morphball.net/vit-ruby-ico_en.html)
167
+
91
168
  == LICENSE:
92
169
 
93
170
  (The MIT License)
data/Rakefile CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'rubygems'
4
4
  require 'hoe'
5
- require './lib/ocra.rb'
5
+ require 'bin/ocra'
6
6
 
7
7
  Hoe.new('ocra', Ocra::VERSION) do |p|
8
8
  p.developer('Lars Christensen', 'larsch@belunktum.dk')
@@ -12,17 +12,26 @@ task :stub do
12
12
  sh "mingw32-make -C src"
13
13
  cp 'src/stub.exe', 'share/ocra/stub.exe'
14
14
  cp 'src/stubw.exe', 'share/ocra/stubw.exe'
15
+ cp 'src/edicon.exe', 'share/ocra/edicon.exe'
15
16
  end
16
17
 
17
18
  task :test => :stub
18
19
 
19
20
  task :standalone => [ 'bin/ocrasa.rb' ]
20
21
 
21
- task :release_standalone => :standalone do
22
- sh "rubyforge add_release ocra ocra-standalone #{Ocra::VERSION} bin/ocrasa.rb"
22
+ standalone_zip = "bin/ocrasa-#{ENV['VERSION']}.zip"
23
+
24
+ file standalone_zip => 'bin/ocrasa.rb' do
25
+ chdir('bin') do
26
+ system("zip ocrasa-#{ENV['VERSION']}.zip ocrasa.rb")
27
+ end
28
+ end
29
+
30
+ task :release_standalone => standalone_zip do
31
+ sh "rubyforge add_release ocra ocra-standalone #{Ocra::VERSION} #{standalone_zip}"
23
32
  end
24
33
 
25
- file 'bin/ocrasa.rb' => [ 'bin/ocra.rb', 'share/ocra/stub.exe', 'share/ocra/stubw.exe', 'share/ocra/lzma.exe' ] do
34
+ file 'bin/ocrasa.rb' => [ 'bin/ocra.rb', 'share/ocra/stub.exe', 'share/ocra/stubw.exe', 'share/ocra/lzma.exe', 'share/ocra/edicon.exe' ] do
26
35
  cp 'bin/ocra.rb', 'bin/ocrasa.rb'
27
36
  File.open("bin/ocrasa.rb", "a") do |f|
28
37
  f.puts "__END__"
@@ -41,6 +50,11 @@ file 'bin/ocrasa.rb' => [ 'bin/ocra.rb', 'share/ocra/stub.exe', 'share/ocra/stub
41
50
  lzma64 = [lzma].pack("m")
42
51
  f.puts lzma64.size
43
52
  f.puts lzma64
53
+
54
+ lzma = File.open("share/ocra/edicon.exe", "rb") {|g| g.read}
55
+ lzma64 = [lzma].pack("m")
56
+ f.puts lzma64.size
57
+ f.puts lzma64
44
58
  end
45
59
  end
46
60
 
@@ -10,6 +10,10 @@ module Ocra
10
10
  OP_DECOMPRESS_LZMA = 4
11
11
  OP_SETENV = 5
12
12
 
13
+ VERSION = "1.1.0"
14
+
15
+ IGNORE_MODULES = /^enumerator.so$/
16
+
13
17
  class << self
14
18
  attr_accessor :lzma_mode
15
19
  attr_accessor :extra_dlls
@@ -17,8 +21,11 @@ module Ocra
17
21
  attr_accessor :load_autoload
18
22
  attr_accessor :force_windows
19
23
  attr_accessor :force_console
24
+ attr_accessor :icon_filename
20
25
  attr_accessor :quiet
26
+ attr_accessor :autodll
21
27
  attr_reader :lzmapath
28
+ attr_reader :ediconpath
22
29
  attr_reader :stubimage
23
30
  attr_reader :stubwimage
24
31
 
@@ -28,18 +35,23 @@ module Ocra
28
35
  end
29
36
 
30
37
  def Ocra.initialize_ocra
38
+ @load_path_before = $LOAD_PATH.dup
39
+
31
40
  if defined?(DATA)
32
41
  @stubimage = get_next_embedded_image
33
42
  @stubwimage = get_next_embedded_image
34
43
  lzmaimage = get_next_embedded_image
35
44
  @lzmapath = File.join(ENV['TEMP'], 'lzma.exe').tr('/','\\')
36
45
  File.open(@lzmapath, "wb") { |file| file << lzmaimage }
46
+ ediconimage = get_next_embedded_image
47
+ @ediconpath = File.join(ENV['TEMP'], 'edicon.exe').tr('/','\\')
48
+ File.open(@ediconpath, "wb") { |file| file << ediconimage }
37
49
  else
38
50
  ocrapath = File.dirname(__FILE__)
39
51
  @stubimage = File.open(File.join(ocrapath, '../share/ocra/stub.exe'), "rb") { |file| file.read }
40
52
  @stubwimage = File.open(File.join(ocrapath, '../share/ocra/stubw.exe'), "rb") { |file| file.read }
41
53
  @lzmapath = File.expand_path('../share/ocra/lzma.exe', ocrapath).tr('/','\\')
42
- raise "lzma.exe not found" unless File.exist?(@lzmapath)
54
+ @ediconpath = File.expand_path('../share/ocra/edicon.exe', ocrapath).tr('/','\\')
43
55
  end
44
56
  end
45
57
 
@@ -50,7 +62,9 @@ module Ocra
50
62
  load_autoload = true
51
63
  force_windows = false
52
64
  force_console = false
65
+ icon_filename = nil
53
66
  quiet = false
67
+ autodll = true
54
68
 
55
69
  usage = <<EOF
56
70
  ocra [options] script.rb
@@ -62,6 +76,8 @@ ocra [options] script.rb
62
76
  --windows Force Windows application (rubyw.exe)
63
77
  --console Force console application (ruby.exe)
64
78
  --no-autoload Don't load/include script.rb's autoloads
79
+ --icon <ico> Replace icon with a custom one
80
+ --version Display version number
65
81
  EOF
66
82
 
67
83
  while arg = argv.shift
@@ -78,6 +94,14 @@ EOF
78
94
  force_console = true
79
95
  when /\A--no-autoload\z/
80
96
  load_autoload = false
97
+ when /\A--icon\z/
98
+ icon_filename = argv.shift
99
+ raise "Icon file #{icon_filename} not found.\n" unless File.exist?(icon_filename)
100
+ when /\A--no-autodll\z/
101
+ autodll = false
102
+ when /\A--version\z/
103
+ puts "Ocra #{VERSION}"
104
+ exit
81
105
  when /\A--help\z/, /\A--/
82
106
  puts usage
83
107
  exit
@@ -97,6 +121,8 @@ EOF
97
121
  @force_windows = force_windows
98
122
  @force_console = force_console
99
123
  @load_autoload = load_autoload
124
+ @icon_filename = icon_filename
125
+ @autodll = autodll
100
126
  @files = files
101
127
  end
102
128
 
@@ -130,8 +156,32 @@ EOF
130
156
  end
131
157
  end
132
158
  end
159
+
160
+ def Ocra.relative_path(src, tgt)
161
+ a = src.split('/')
162
+ b = tgt.split('/')
163
+ while a.first && a.first.downcase == b.first.downcase
164
+ a.shift
165
+ b.shift
166
+ end
167
+ return tgt if b.first =~ /^[a-z]:/i
168
+ a.size.times { b.unshift '..' }
169
+ return b.join('/')
170
+ end
171
+
172
+ def Ocra.find_load_path(paths, path)
173
+ if path[1,1] == ":"
174
+ rps = paths.map {|p| relative_path(p, path) }
175
+ rps.zip(paths).sort_by {|x| x[0].size }.first[1]
176
+ else
177
+ candidates = paths.select { |p| File.exist?(File.expand_path(path, p)) }
178
+ candidates.sort_by {|p| p.size}.last
179
+ end
180
+ end
133
181
 
134
182
  def Ocra.build_exe
183
+ @added_load_paths = $LOAD_PATH - @load_path_before
184
+
135
185
  # Attempt to autoload libraries before doing anything else.
136
186
  attempt_load_autoload if Ocra.load_autoload
137
187
 
@@ -154,25 +204,40 @@ EOF
154
204
  libruby_so = RbConfig::CONFIG['LIBRUBY_SO']
155
205
 
156
206
  instsitelibdir = sitelibdir[exec_prefix.size+1..-1]
207
+
208
+ load_path = []
157
209
 
158
210
  # Find loaded files
159
211
  libs = []
160
212
  features.each do |filename|
161
- path = $:.find { |path| File.exist?(File.expand_path(filename, path)) }
213
+ path = find_load_path($:, filename)
162
214
  if path
215
+ if filename[1,1] == ":"
216
+ filename = relative_path(File.expand_path(path), filename)
217
+ end
218
+ if filename =~ /^\.\.\//
219
+ puts "=== WARNING: Detected a relative require (#{filename}). This is not recommended."
220
+ end
163
221
  fullpath = File.expand_path(filename, path)
164
222
  if fullpath.index(exec_prefix) == 0
165
223
  libs << [ fullpath, fullpath[exec_prefix.size+1..-1] ]
166
224
  elsif fullpath.index(src_prefix) == 0
167
- libs << [ fullpath, "src/" + fullpath[src_prefix.size+1..-1]]
225
+ targetpath = "src/" + fullpath[src_prefix.size+1..-1]
226
+ libs << [ fullpath, targetpath ]
227
+ if not @added_load_paths.include?(path) and not load_path.include?(path)
228
+ load_path << File.join("\xFF", File.dirname(targetpath))
229
+ end
168
230
  else
169
231
  libs << [ fullpath, File.join(instsitelibdir, filename) ]
170
232
  end
171
233
  else
172
- puts "=== WARNING: Couldn't find #{filename}"
234
+ puts "=== WARNING: Couldn't find #{filename}" unless filename =~ IGNORE_MODULES
173
235
  end
174
236
  end
175
237
 
238
+ # Detect additional DLLs
239
+ dlls = Ocra.autodll ? LibraryDetector.detect_dlls : []
240
+
176
241
  executable = Ocra.files[0].sub(/(\.rbw?)?$/, '.exe')
177
242
 
178
243
  windowed = (Ocra.files[0] =~ /\.rbw$/ || Ocra.force_windows) && !Ocra.force_console
@@ -196,6 +261,16 @@ EOF
196
261
  sb.createfile(File.join(bindir, libruby_so), "bin\\#{libruby_so}")
197
262
  end
198
263
 
264
+ # Add detected DLLs
265
+ dlls.each do |dll|
266
+ if dll.tr('\\','/').index(exec_prefix) == 0
267
+ target = dll[exec_prefix.size+1..-1]
268
+ else
269
+ target = File.join('bin', File.basename(dll))
270
+ end
271
+ sb.createfile(dll, target)
272
+ end
273
+
199
274
  # Add extra DLLs
200
275
  Ocra.extra_dlls.each do |dll|
201
276
  sb.createfile(File.join(bindir, dll), File.join("bin", dll).tr('/','\\'))
@@ -218,7 +293,7 @@ EOF
218
293
 
219
294
  # Set environment variable
220
295
  sb.setenv('RUBYOPT', '')
221
- sb.setenv('RUBYLIB', '')
296
+ sb.setenv('RUBYLIB', load_path.join(';'))
222
297
 
223
298
  # Launch the script
224
299
  sb.createprocess("bin\\" + rubyexe, "#{rubyexe} \xff\\src\\" + Ocra.files[0])
@@ -227,6 +302,52 @@ EOF
227
302
  end
228
303
  puts "=== Finished (Final size was #{File.size(executable)})" unless Ocra.quiet
229
304
  end
305
+
306
+ module LibraryDetector
307
+ def LibraryDetector.loaded_dlls
308
+ begin
309
+ require 'rubygems'
310
+ gem 'win32-api', '>=1.4.0'
311
+ require 'win32/api'
312
+ rescue Exception => e
313
+ puts "=== ERROR: Failed to load the win32-api gem. Install win32-api or use --no-autodll."
314
+ puts "=== CAUSE: #{e.class.name}: #{e.message.chomp}"
315
+ exit
316
+ end
317
+
318
+ enumprocessmodules = Win32::API.new('EnumProcessModules', 'LPLP', 'B', 'psapi')
319
+ getmodulefilename = Win32::API.new('GetModuleFileName', 'LPL', 'L')
320
+ getcurrentprocess = Win32::API.new('GetCurrentProcess', 'V', 'L')
321
+
322
+ bytes_needed = 4 * 32
323
+ module_handle_buffer = nil
324
+ process_handle = getcurrentprocess.call()
325
+ loop do
326
+ module_handle_buffer = "\x00" * bytes_needed
327
+ bytes_needed_buffer = [0].pack("I")
328
+ r = enumprocessmodules.call(process_handle, module_handle_buffer, module_handle_buffer.size, bytes_needed_buffer)
329
+ bytes_needed = bytes_needed_buffer.unpack("I")[0]
330
+ break if bytes_needed <= module_handle_buffer.size
331
+ end
332
+
333
+ handles = module_handle_buffer.unpack("I*")
334
+ handles.select{|x|x>0}.map do |h|
335
+ str = "\x00" * 256
336
+ r = getmodulefilename.call(h, str, str.size)
337
+ str[0,r]
338
+ end
339
+ end
340
+
341
+ def LibraryDetector.detect_dlls
342
+ loaded = loaded_dlls
343
+ exec_prefix = RbConfig::CONFIG['exec_prefix']
344
+ loaded.select do |path|
345
+ path.tr('\\','/').index(exec_prefix) == 0 and
346
+ File.basename(path) =~ /\.dll$/ and
347
+ File.basename(path).downcase != RbConfig::CONFIG['LIBRUBY_SO'].downcase
348
+ end
349
+ end
350
+ end
230
351
 
231
352
  class OcraBuilder
232
353
  def initialize(path, windowed)
@@ -238,7 +359,16 @@ EOF
238
359
  else
239
360
  ocrafile.write(Ocra.stubimage)
240
361
  end
241
-
362
+ end
363
+
364
+ if Ocra.icon_filename
365
+ system("#{Ocra.ediconpath} #{path} #{Ocra.icon_filename}")
366
+ end
367
+
368
+ opcode_offset = File.size(path)
369
+
370
+ File.open(path, "ab") do |ocrafile|
371
+
242
372
  if Ocra.lzma_mode
243
373
  @of = ""
244
374
  else
@@ -263,7 +393,7 @@ EOF
263
393
  end
264
394
 
265
395
  ocrafile.write([OP_END].pack("V"))
266
- ocrafile.write([Ocra.stubimage.size].pack("V")) # Pointer to start of opcodes
396
+ ocrafile.write([opcode_offset].pack("V")) # Pointer to start of opcodes
267
397
  ocrafile.write(Signature.pack("C*"))
268
398
  end
269
399
  end
@@ -308,7 +438,7 @@ if File.basename(__FILE__) == File.basename($0)
308
438
  Ocra.build_exe
309
439
  exit(0)
310
440
  end
311
-
441
+
312
442
  puts "=== Loading script to check dependencies" unless Ocra.quiet
313
443
  $0 = Ocra.files[0]
314
444
  load Ocra.files[0]
@@ -1,3 +1,3 @@
1
1
  class Ocra
2
- VERSION = '1.0.3'
2
+ VERSION = '1.1.0'
3
3
  end
Binary file
Binary file
Binary file
@@ -3,9 +3,12 @@ require "ocra"
3
3
  require "tmpdir"
4
4
  require "fileutils"
5
5
  require "rbconfig"
6
+ include FileUtils
6
7
 
7
8
  class TestOcra < Test::Unit::TestCase
8
9
 
10
+ DefaultArgs = [ '--quiet', '--no-lzma' ]
11
+
9
12
  TESTED_OCRA = ENV['TESTED_OCRA'] || 'ocra.rb'
10
13
 
11
14
  def initialize(*args)
@@ -18,6 +21,41 @@ class TestOcra < Test::Unit::TestCase
18
21
  def ocra
19
22
  @ocra
20
23
  end
24
+
25
+ OcraRoot = File.expand_path(File.join(File.dirname(__FILE__), '..'))
26
+
27
+ FixturePath = File.expand_path(File.join(File.dirname(__FILE__), 'fixtures'))
28
+
29
+ # Sets up an directory with a copy of a fixture and yields to the
30
+ # block, then cleans up everything. A fixture here is a hierachy of
31
+ # files located in test/fixtures.
32
+ def with_fixture(name)
33
+ path = File.join(FixturePath, name)
34
+ FileUtils.cp_r path, '.'
35
+ begin
36
+ cd name do
37
+ yield
38
+ end
39
+ ensure
40
+ rm_rf 'name'
41
+ end
42
+ end
43
+
44
+ # Sets up temporary environment variable and yields to the block.
45
+ def with_env(hash)
46
+ old = {}
47
+ hash.each do |k,v|
48
+ old[k] = ENV[k]
49
+ ENV[k] = v
50
+ end
51
+ begin
52
+ yield
53
+ ensure
54
+ hash.each do |k,v|
55
+ ENV[k] = old[k]
56
+ end
57
+ end
58
+ end
21
59
 
22
60
  def setup
23
61
  @testnum += 1
@@ -32,168 +70,206 @@ class TestOcra < Test::Unit::TestCase
32
70
  end
33
71
 
34
72
  def test_helloworld
35
- File.open("helloworld.rb", "w") do |f|
36
- f << "hello_world = \"Hello, World!\"\n"
73
+ with_fixture 'helloworld' do
74
+ assert system("ruby", ocra, "helloworld.rb", *DefaultArgs)
75
+ assert File.exist?("helloworld.exe")
76
+ assert system("helloworld.exe")
37
77
  end
38
- assert system("ruby", ocra, "--quiet", "helloworld.rb")
39
- assert File.exist?("helloworld.exe")
40
- assert system("helloworld.exe")
41
78
  end
42
79
 
43
80
  def test_writefile
44
- File.open("writefile.rb", "w") do |f|
45
- f << "File.open(\"output.txt\", \"w\") do |f| f.write \"output\"; end"
81
+ with_fixture 'writefile' do
82
+ assert system("ruby", ocra, "writefile.rb", *DefaultArgs)
83
+ assert File.exist?("writefile.exe")
84
+ assert system("writefile.exe")
85
+ assert File.exist?("output.txt")
86
+ assert "output", File.read("output.txt")
46
87
  end
47
- assert system("ruby", ocra, "--quiet", "writefile.rb")
48
- assert File.exist?("writefile.exe")
49
- assert system("writefile.exe")
50
- assert File.exist?("output.txt")
51
- assert "output", File.read("output.txt")
52
88
  end
53
89
 
54
90
  def test_exitstatus
55
- File.open("exitstatus.rb", "w") do |f|
56
- f << "exit 167 if __FILE__ == $0"
91
+ with_fixture 'exitstatus' do
92
+ assert system("ruby", ocra, "exitstatus.rb", *DefaultArgs)
93
+ system("exitstatus.exe")
94
+ assert_equal 167, $?.exitstatus
57
95
  end
58
- assert system("ruby", ocra, "--quiet", "exitstatus.rb")
59
- system("exitstatus.exe")
60
- assert_equal 167, $?.exitstatus
61
96
  end
62
97
 
63
98
  def test_arguments
64
- File.open("arguments.rb", "w") do |f|
65
- f << "if $0 == __FILE__\n"
66
- f << "exit 1 if ARGV.size != 2\n"
67
- f << "exit 2 if ARGV[0] != \"foo\"\n"
68
- f << "exit 3 if ARGV[1] != \"bar baz\"\n"
69
- # f << "exit 4 if ARGV[2] != \"\\\"smile\\\"\"\n"
70
- f << "exit(5)\n"
71
- f << "end"
72
- end
73
- assert system("ruby", ocra, "--quiet", "arguments.rb")
74
- assert File.exist?("arguments.exe")
75
- # system(File.expand_path("arguments.exe"), "foo", "bar baz", "\"smile\"")
76
- system("arguments.exe foo \"bar baz\"")
77
- assert_equal 5, $?.exitstatus
99
+ with_fixture 'arguments' do
100
+ assert system("ruby", ocra, "arguments.rb", *DefaultArgs)
101
+ assert File.exist?("arguments.exe")
102
+ system("arguments.exe foo \"bar baz\"")
103
+ assert_equal 5, $?.exitstatus
104
+ end
78
105
  end
79
106
 
80
107
  def test_stdout_redir
81
- File.open("stdoutredir.rb", "w") do |f|
82
- f << "if $0 == __FILE__\n"
83
- f << "puts \"Hello, World!\"\n"
84
- f << "end\n"
108
+ with_fixture 'stdoutredir' do
109
+ assert system("ruby", ocra, "stdoutredir.rb", *DefaultArgs)
110
+ assert File.exist?("stdoutredir.exe")
111
+ system("stdoutredir.exe > output.txt")
112
+ assert File.exist?("output.txt")
113
+ assert_equal "Hello, World!\n", File.read("output.txt")
85
114
  end
86
- assert system("ruby", ocra, "--quiet", "stdoutredir.rb")
87
- assert File.exist?("stdoutredir.exe")
88
- system("stdoutredir.exe > output.txt")
89
- assert File.exist?("output.txt")
90
- assert_equal "Hello, World!\n", File.read("output.txt")
91
115
  end
92
116
 
93
117
  def test_stdin_redir
94
- File.open("input.txt", "w") do |f|
95
- f << "Hello, World!\n"
118
+ with_fixture 'stdinredir' do
119
+ assert system("ruby", ocra, "stdinredir.rb", *DefaultArgs)
120
+ assert File.exist?("stdinredir.exe")
121
+ system("stdinredir.exe < input.txt")
122
+ assert 104, $?.exitstatus
96
123
  end
97
- File.open("stdinredir.rb", "w") do |f|
98
- f << "if $0 == __FILE__\n"
99
- f << " exit 104 if gets == \"Hello, World!\\n\""
100
- f << "end\n"
101
- end
102
- assert system("ruby", ocra, "--quiet", "stdinredir.rb")
103
- assert File.exist?("stdinredir.exe")
104
- system("stdinredir.exe < input.txt")
105
- assert 104, $?.exitstatus
106
124
  end
107
125
 
108
126
  def test_gdbmdll
109
- File.open("gdbmdll.rb", "w") do |f|
110
- f << "require 'gdbm'\n"
111
- f << "exit 104 if $0 == __FILE__ and defined?(GDBM)\n"
112
- end
113
- bindir = RbConfig::CONFIG['bindir']
114
-
115
- gdbmdllpath = Dir[File.join(bindir, 'gdbm*.dll')][0]
116
- raise "gdbm dll was not found" unless gdbmdllpath
117
- gdbmdll = File.basename(gdbmdllpath)
118
- assert system("ruby", ocra, "--quiet", "--dll", gdbmdll, "gdbmdll.rb")
119
- path = ENV['PATH']
120
- ENV['PATH'] = "."
121
- begin
122
- system("gdbmdll.exe")
123
- ensure
124
- ENV['PATH'] = path
127
+ with_fixture 'gdbmdll' do
128
+ assert system("ruby", ocra, "gdbmdll.rb", *DefaultArgs)
129
+ with_env 'PATH' => '.' do
130
+ system("gdbmdll.exe")
131
+ assert_equal 104, $?.exitstatus
132
+ end
125
133
  end
126
- assert_equal 104, $?.exitstatus
127
134
  end
128
135
 
129
136
  def test_relative_require
130
- File.open("relativerequire.rb", "w") do |f|
131
- f << "require 'somedir/somefile.rb'\n"
132
- f << "exit 160 if __FILE__ == $0 and defined?(SomeConst)"
137
+ with_fixture 'relativerequire' do
138
+ assert system("ruby", ocra, "relativerequire.rb", *DefaultArgs)
139
+ assert File.exist?("relativerequire.exe")
140
+ system("relativerequire.exe")
141
+ assert_equal 160, $?.exitstatus
133
142
  end
134
- Dir.mkdir('somedir')
135
- File.open("somedir/somefile.rb", "w") do |f|
136
- f << "SomeConst = 12312\n"
143
+ end
144
+
145
+ # Test that autoloaded files which are not actually loaded while
146
+ # running the script through Ocra are included in the resulting
147
+ # executable.
148
+ def test_autoload
149
+ with_fixture 'autoload' do
150
+ assert system("ruby", ocra, "autoload.rb", *DefaultArgs)
151
+ assert File.exist?("autoload.exe")
152
+ File.unlink('foo.rb')
153
+ assert system("autoload.exe")
137
154
  end
138
- assert system("ruby", ocra, "--quiet", "relativerequire.rb")
139
- assert File.exist?("relativerequire.exe")
140
- system("relativerequire.exe")
141
- assert_equal 160, $?.exitstatus
142
155
  end
143
156
 
144
- def test_exiting
145
- File.open("exiting.rb", "w") do |f|
146
- f << "exit 214\n"
157
+ # Test that autoload statement which point to non-existing files are
158
+ # ignored by Ocra (a warning may be logged).
159
+ def test_autoload_missing
160
+ with_fixture 'autoloadmissing' do
161
+ assert system("ruby", ocra, "autoloadmissing.rb", *DefaultArgs)
162
+ assert File.exist?("autoloadmissing.exe")
163
+ assert system("autoloadmissing.exe")
147
164
  end
148
- assert system("ruby", ocra, "--quiet", "exiting.rb")
149
- assert File.exist?("exiting.exe")
150
- system("exiting.exe")
151
- assert_equal 214, $?.exitstatus
152
165
  end
153
166
 
154
- def test_autoload
155
- File.open("autoload.rb", "w") do |f|
156
- f << "$:.unshift File.dirname(__FILE__)\n"
157
- f << "autoload :Foo, 'foo'\n"
158
- f << "Foo if __FILE__ == $0\n"
167
+ # Test that Ocra picks up autoload statement nested in modules.
168
+ def test_autoload_nested
169
+ with_fixture 'autoloadnested' do
170
+ assert system("ruby", ocra, "autoloadnested.rb", *DefaultArgs)
171
+ assert File.exist?("autoloadnested.exe")
172
+ File.unlink('foo.rb')
173
+ assert system("autoloadnested.exe")
174
+ end
175
+ end
176
+
177
+ # Test that we can use custom include paths when invoking Ocra (ruby
178
+ # -I somepath). In this case the lib scripts are put in the src/
179
+ # directory.
180
+ def test_relative_loadpath1_ilib
181
+ with_fixture 'relloadpath1' do
182
+ assert system('ruby', '-I', 'lib', ocra, 'relloadpath1.rb', *DefaultArgs)
183
+ assert File.exist?('relloadpath1.exe')
184
+ assert system('relloadpath1.exe')
159
185
  end
160
- File.open("foo.rb", "w") do |f|
161
- f << "class Foo; end\n"
186
+ end
187
+
188
+ # Same as above with './lib'
189
+ def test_relative_loadpath_idotlib
190
+ with_fixture 'relloadpath1' do
191
+ assert system('ruby', '-I', './lib', ocra, 'relloadpath1.rb', *DefaultArgs)
192
+ assert File.exist?('relloadpath1.exe')
193
+ assert system('relloadpath1.exe')
162
194
  end
163
- assert system("ruby", ocra, "--quiet", "autoload.rb")
164
- assert File.exist?("autoload.exe")
165
- File.unlink('foo.rb')
166
- assert system("autoload.exe")
167
- # assert_equal 214, $?.exitstatus
168
195
  end
169
196
 
170
- def test_autoload_missing
171
- File.open("autoloadmissing.rb", "w") do |f|
172
- f << "$:.unshift File.dirname(__FILE__)\n"
173
- f << "autoload :Foo, 'foo'\n"
197
+ # Test that we can use custom include paths when invoking Ocra (env
198
+ # RUBYLIB=lib). In this case the lib scripts are put in the src/
199
+ # directory.
200
+ def test_relative_loadpath_rubyliblib
201
+ with_fixture 'relloadpath1' do
202
+ with_env 'RUBYLIB' => 'lib' do
203
+ assert system('ruby', ocra, 'relloadpath1.rb', *DefaultArgs)
204
+ assert File.exist?('relloadpath1.exe')
205
+ assert system('relloadpath1.exe')
206
+ end
174
207
  end
175
- assert system("ruby", ocra, "--quiet", "autoloadmissing.rb")
176
- assert File.exist?("autoloadmissing.exe")
177
- assert system("autoloadmissing.exe")
178
208
  end
179
-
180
- def test_autoload_nested
181
- File.open("autoloadnested.rb", "w") do |f|
182
- f << "$:.unshift File.dirname(__FILE__)\n"
183
- f << "module Bar\n"
184
- f << " autoload :Foo, 'foo'\n"
185
- f << "end\n"
186
- f << "Bar::Foo if __FILE__ == $0\n"
187
- end
188
- File.open("foo.rb", "w") do |f|
189
- f << "module Bar\n"
190
- f << "class Foo; end\n"
191
- f << "end\n"
192
- end
193
- assert system("ruby", ocra, "--quiet", "autoloadnested.rb")
194
- assert File.exist?("autoloadnested.exe")
195
- File.unlink('foo.rb')
196
- assert system("autoloadnested.exe")
197
- # assert_equal 214, $?.exitstatus
209
+
210
+ # Same as above with './lib'
211
+ def test_relative_loadpath_rubylibdotlib
212
+ with_fixture 'relloadpath1' do
213
+ with_env 'RUBYLIB' => './lib' do
214
+ assert system('ruby', ocra, 'relloadpath1.rb', *DefaultArgs)
215
+ assert File.exist?('relloadpath1.exe')
216
+ assert system('relloadpath1.exe')
217
+ end
218
+ end
219
+ end
220
+
221
+ # Relative path with .. prefix (../lib).
222
+ def test_relative_loadpath2_idotdotlib
223
+ with_fixture 'relloadpath2' do
224
+ cd 'src' do
225
+ assert system('ruby', '-I', '../lib', ocra, 'relloadpath2.rb', *DefaultArgs)
226
+ assert File.exist?('relloadpath2.exe')
227
+ assert system('relloadpath2.exe')
228
+ end
229
+ end
230
+ end
231
+
232
+ # Test that scripts which modify $LOAD_PATH with a relative path
233
+ # (./lib) work correctly.
234
+ def test_relloadpath3
235
+ with_fixture 'relloadpath3' do
236
+ assert system('ruby', ocra, 'relloadpath3.rb', *DefaultArgs)
237
+ assert File.exist?('relloadpath3.exe')
238
+ assert system('relloadpath3.exe')
239
+ end
240
+ end
241
+
242
+ # Test that scripts which modify $LOAD_PATH with a relative path
243
+ # (../lib) work correctly.
244
+ def test_relloadpath4
245
+ with_fixture 'relloadpath4' do
246
+ cd 'src' do
247
+ assert system('ruby', ocra, 'relloadpath4.rb', *DefaultArgs)
248
+ assert File.exist?('relloadpath4.exe')
249
+ assert system('relloadpath4.exe')
250
+ end
251
+ end
252
+ end
253
+
254
+ def test_version
255
+ assert_match(/^Ocra \d+(\.\d)+$/, `ruby #{ocra} --version`)
256
+ end
257
+
258
+ def test_icon
259
+ with_fixture 'helloworld' do
260
+ icofile = File.join(OcraRoot, 'src', 'vit-ruby.ico')
261
+ assert system("ruby", ocra, '--icon', icofile, "helloworld.rb", *DefaultArgs)
262
+ assert File.exist?("helloworld.exe")
263
+ assert system("helloworld.exe")
264
+ end
265
+ end
266
+
267
+ def test_resource
268
+ with_fixture 'resource' do
269
+ assert system("ruby", ocra, "resource.rb", "resource.txt", "res/resource.txt", *DefaultArgs)
270
+ assert File.exist?("resource.exe")
271
+ assert system("resource.exe")
272
+ end
198
273
  end
199
274
  end
275
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ocra
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lars Christensen
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-05-25 00:00:00 +02:00
12
+ date: 2009-05-27 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -46,6 +46,7 @@ files:
46
46
  - share/ocra/lzma.exe
47
47
  - share/ocra/stub.exe
48
48
  - share/ocra/stubw.exe
49
+ - share/ocra/edicon.exe
49
50
  - test/test_ocra.rb
50
51
  - lib/ocra.rb
51
52
  has_rdoc: true