ocran 1.4.0-x86_64-linux
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.
- checksums.yaml +7 -0
- data/CHANGELOG.txt +306 -0
- data/LICENSE.txt +23 -0
- data/README.md +549 -0
- data/exe/ocran +5 -0
- data/lib/ocran/build_constants.rb +16 -0
- data/lib/ocran/build_facade.rb +17 -0
- data/lib/ocran/build_helper.rb +110 -0
- data/lib/ocran/command_output.rb +22 -0
- data/lib/ocran/dir_builder.rb +162 -0
- data/lib/ocran/direction.rb +623 -0
- data/lib/ocran/empty_source +0 -0
- data/lib/ocran/file_path_set.rb +69 -0
- data/lib/ocran/gem_spec_queryable.rb +172 -0
- data/lib/ocran/host_config_helper.rb +57 -0
- data/lib/ocran/inno_setup_script_builder.rb +111 -0
- data/lib/ocran/launcher_batch_builder.rb +85 -0
- data/lib/ocran/library_detector.rb +61 -0
- data/lib/ocran/library_detector_posix.rb +55 -0
- data/lib/ocran/option.rb +323 -0
- data/lib/ocran/refine_pathname.rb +104 -0
- data/lib/ocran/runner.rb +115 -0
- data/lib/ocran/runtime_environment.rb +46 -0
- data/lib/ocran/stub_builder.rb +298 -0
- data/lib/ocran/version.rb +5 -0
- data/lib/ocran/windows_command_escaping.rb +15 -0
- data/lib/ocran.rb +7 -0
- data/share/ocran/lzma.exe +0 -0
- data/share/ocran/stub +0 -0
- metadata +109 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require "pathname"
|
|
3
|
+
require_relative "refine_pathname"
|
|
4
|
+
require_relative "command_output"
|
|
5
|
+
require_relative "build_constants"
|
|
6
|
+
|
|
7
|
+
module Ocran
|
|
8
|
+
module BuildHelper
|
|
9
|
+
using RefinePathname
|
|
10
|
+
|
|
11
|
+
include BuildConstants, CommandOutput
|
|
12
|
+
|
|
13
|
+
EMPTY_SOURCE = File.expand_path("empty_source", __dir__).freeze
|
|
14
|
+
|
|
15
|
+
def mkdir(target)
|
|
16
|
+
verbose "mkdir #{target}"
|
|
17
|
+
super
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def cp(source, target)
|
|
21
|
+
verbose "cp #{source} #{target}"
|
|
22
|
+
super
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def exec(image, script, *argv)
|
|
26
|
+
args = argv.map { |s| replace_placeholder(s) }.join(" ")
|
|
27
|
+
verbose "exec #{image} #{script} #{args}"
|
|
28
|
+
super
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def export(name, value)
|
|
32
|
+
verbose "export #{name}=#{replace_placeholder(value)}"
|
|
33
|
+
super
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def replace_placeholder(s)
|
|
37
|
+
s.to_s.gsub(EXTRACT_ROOT.to_s, "<tempdir>")
|
|
38
|
+
end
|
|
39
|
+
private :replace_placeholder
|
|
40
|
+
|
|
41
|
+
def copy_to_bin(source, target)
|
|
42
|
+
cp(source, BINDIR / target)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def symlink_in_bin(target, link_name)
|
|
46
|
+
verbose "symlink #{BINDIR / link_name} -> #{target}"
|
|
47
|
+
symlink(BINDIR / link_name, target.to_s)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def copy_to_gem(source, target)
|
|
51
|
+
cp(source, GEMDIR / target)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def copy_to_lib(source, target)
|
|
55
|
+
cp(source, LIBDIR / target)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def duplicate_to_exec_prefix(source)
|
|
59
|
+
cp(source, Pathname(source).relative_path_from(HostConfigHelper.exec_prefix))
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def duplicate_to_gem_home(source, gem_path)
|
|
63
|
+
copy_to_gem(source, Pathname(source).relative_path_from(gem_path))
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def resolve_source_path(source, root_prefix)
|
|
67
|
+
source = Pathname(source)
|
|
68
|
+
|
|
69
|
+
if source.subpath?(HostConfigHelper.exec_prefix)
|
|
70
|
+
source.relative_path_from(HostConfigHelper.exec_prefix)
|
|
71
|
+
elsif source.subpath?(root_prefix)
|
|
72
|
+
SRCDIR / source.relative_path_from(root_prefix)
|
|
73
|
+
else
|
|
74
|
+
SRCDIR / source.basename
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Sets an environment variable with a joined path value.
|
|
79
|
+
# This method processes an array of path strings or Pathname objects, accepts
|
|
80
|
+
# absolute paths as is, and appends a placeholder to relative paths to convert
|
|
81
|
+
# them into absolute paths. The converted paths are then joined into a single
|
|
82
|
+
# string using the system's path separator.
|
|
83
|
+
#
|
|
84
|
+
# @param name [String] the name of the environment variable to set.
|
|
85
|
+
# @param paths [Array<String, Pathname>] an array of path arguments which can
|
|
86
|
+
# be either absolute or relative.
|
|
87
|
+
#
|
|
88
|
+
# Example:
|
|
89
|
+
# set_env_path("RUBYLIB", "lib", "ext", "vendor/lib")
|
|
90
|
+
# # This sets RUBYLIB to a string such as "C:/ProjectRoot/lib;C:/ProjectRoot/ext;C:/ProjectRoot/vendor/lib"
|
|
91
|
+
# # assuming each path is correctly converted to an absolute path through a placeholder.
|
|
92
|
+
#
|
|
93
|
+
def set_env_path(name, *paths)
|
|
94
|
+
value = paths.map { |path|
|
|
95
|
+
if File.absolute_path?(path)
|
|
96
|
+
path
|
|
97
|
+
else
|
|
98
|
+
File.join(EXTRACT_ROOT, path)
|
|
99
|
+
end
|
|
100
|
+
}.join(File::PATH_SEPARATOR)
|
|
101
|
+
|
|
102
|
+
export(name, value)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def touch(target)
|
|
106
|
+
verbose "touch #{target}"
|
|
107
|
+
cp(EMPTY_SOURCE, target)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
load File.expand_path("../ocran.rb", __dir__)
|
|
3
|
+
|
|
4
|
+
module Ocran
|
|
5
|
+
module CommandOutput
|
|
6
|
+
def say(s)
|
|
7
|
+
puts "=== #{s}" unless Ocran.option&.quiet?
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def verbose(s)
|
|
11
|
+
puts s if Ocran.option&.verbose?
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def warning(s)
|
|
15
|
+
STDERR.puts "WARNING: #{s}" if Ocran.option&.warning?
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def error(s)
|
|
19
|
+
STDERR.puts "ERROR: #{s}"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require "pathname"
|
|
3
|
+
require "fileutils"
|
|
4
|
+
require_relative "build_constants"
|
|
5
|
+
|
|
6
|
+
module Ocran
|
|
7
|
+
# Builder that outputs all files to a plain directory instead of a self-extracting
|
|
8
|
+
# executable. A launch script (`.sh` on POSIX, `.bat` on Windows) is written at
|
|
9
|
+
# the root of the directory so the packaged app can be started directly.
|
|
10
|
+
class DirBuilder
|
|
11
|
+
include BuildConstants
|
|
12
|
+
|
|
13
|
+
WINDOWS = Gem.win_platform?
|
|
14
|
+
|
|
15
|
+
attr_reader :data_size
|
|
16
|
+
|
|
17
|
+
def initialize(path)
|
|
18
|
+
@path = Pathname(path)
|
|
19
|
+
@path.mkpath
|
|
20
|
+
@env = {}
|
|
21
|
+
@exec_args = nil
|
|
22
|
+
@symlinks = []
|
|
23
|
+
@data_size = 0
|
|
24
|
+
|
|
25
|
+
yield(self) if block_given?
|
|
26
|
+
|
|
27
|
+
finalize
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def mkdir(target)
|
|
31
|
+
(@path / target).mkpath
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def cp(source, target)
|
|
35
|
+
dest = @path / target
|
|
36
|
+
dest.dirname.mkpath
|
|
37
|
+
src = source.to_s
|
|
38
|
+
FileUtils.cp(src, dest.to_s)
|
|
39
|
+
@data_size += File.size(src)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def symlink(link_path, target)
|
|
43
|
+
@symlinks << [link_path.to_s, target.to_s]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def export(name, value)
|
|
47
|
+
@env[name.to_s] = value.to_s
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def exec(image, script, *argv)
|
|
51
|
+
raise "Script is already set" if @exec_args
|
|
52
|
+
@exec_args = [image.to_s, script.to_s, argv.map(&:to_s)]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Create a zip archive from a source directory.
|
|
56
|
+
# Uses the `zip` command on POSIX and PowerShell on Windows.
|
|
57
|
+
def self.create_zip(zip_path, source_dir)
|
|
58
|
+
zip_path = File.expand_path(zip_path.to_s)
|
|
59
|
+
if Gem.win_platform?
|
|
60
|
+
system("powershell", "-NoProfile", "-Command",
|
|
61
|
+
"Compress-Archive -Path '#{source_dir}\\*' -DestinationPath '#{zip_path}'",
|
|
62
|
+
exception: true)
|
|
63
|
+
else
|
|
64
|
+
Dir.chdir(source_dir) do
|
|
65
|
+
system("zip", "-r", zip_path, ".", exception: true)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
private
|
|
71
|
+
|
|
72
|
+
def finalize
|
|
73
|
+
unless WINDOWS
|
|
74
|
+
@symlinks.each do |link_path, target|
|
|
75
|
+
dest = @path / link_path
|
|
76
|
+
dest.dirname.mkpath
|
|
77
|
+
File.symlink(target, dest) unless dest.exist?
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
write_launch_script
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Replace the EXTRACT_ROOT placeholder ("|") in a value string with
|
|
85
|
+
# the runtime directory variable.
|
|
86
|
+
def replace_root(value, root_var)
|
|
87
|
+
value.gsub("#{EXTRACT_ROOT}/", "#{root_var}/")
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def script_basename
|
|
91
|
+
@exec_args ? Pathname(@exec_args[1]).basename.sub_ext("").to_s : "run"
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def write_launch_script
|
|
95
|
+
WINDOWS ? write_batch_script : write_shell_script
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def write_shell_script
|
|
99
|
+
script_path = @path / "#{script_basename}.sh"
|
|
100
|
+
|
|
101
|
+
lines = [
|
|
102
|
+
"#!/bin/sh",
|
|
103
|
+
'SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"',
|
|
104
|
+
]
|
|
105
|
+
|
|
106
|
+
@env.each do |name, value|
|
|
107
|
+
replaced = replace_root(value, "$SCRIPT_DIR")
|
|
108
|
+
lines << "export #{name}=\"#{replaced}\""
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
if @exec_args
|
|
112
|
+
image, script, argv = @exec_args
|
|
113
|
+
image_r = replace_root(image, "$SCRIPT_DIR")
|
|
114
|
+
script_r = replace_root(script, "$SCRIPT_DIR")
|
|
115
|
+
|
|
116
|
+
# Prepend SCRIPT_DIR to relative paths
|
|
117
|
+
image_r = "$SCRIPT_DIR/#{image_r}" unless image_r.start_with?("/", "$SCRIPT_DIR")
|
|
118
|
+
script_r = "$SCRIPT_DIR/#{script_r}" unless script_r.start_with?("/", "$SCRIPT_DIR")
|
|
119
|
+
|
|
120
|
+
args = argv.map { |a| "\"#{replace_root(a, "$SCRIPT_DIR")}\"" }.join(" ")
|
|
121
|
+
exec_line = "exec \"#{image_r}\" \"#{script_r}\""
|
|
122
|
+
exec_line += " #{args}" unless args.empty?
|
|
123
|
+
exec_line += ' "$@"'
|
|
124
|
+
lines << exec_line
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
File.write(script_path, lines.join("\n") + "\n")
|
|
128
|
+
File.chmod(0755, script_path)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def write_batch_script
|
|
132
|
+
script_path = @path / "#{script_basename}.bat"
|
|
133
|
+
|
|
134
|
+
lines = [
|
|
135
|
+
"@echo off",
|
|
136
|
+
"set SCRIPT_DIR=%~dp0",
|
|
137
|
+
]
|
|
138
|
+
|
|
139
|
+
@env.each do |name, value|
|
|
140
|
+
replaced = replace_root(value, "%SCRIPT_DIR%").tr("/", "\\")
|
|
141
|
+
lines << "set #{name}=#{replaced}"
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
if @exec_args
|
|
145
|
+
image, script, argv = @exec_args
|
|
146
|
+
image_r = replace_root(image, "%SCRIPT_DIR%").tr("/", "\\")
|
|
147
|
+
script_r = replace_root(script, "%SCRIPT_DIR%").tr("/", "\\")
|
|
148
|
+
|
|
149
|
+
image_r = "%SCRIPT_DIR%#{image_r}" unless image_r.include?("%SCRIPT_DIR%") || File.absolute_path?(image_r)
|
|
150
|
+
script_r = "%SCRIPT_DIR%#{script_r}" unless script_r.include?("%SCRIPT_DIR%") || File.absolute_path?(script_r)
|
|
151
|
+
|
|
152
|
+
args = argv.map { |a| replace_root(a, "%SCRIPT_DIR%") }.join(" ")
|
|
153
|
+
exec_line = "\"#{image_r}\" \"#{script_r}\""
|
|
154
|
+
exec_line += " #{args}" unless args.empty?
|
|
155
|
+
exec_line += " %*"
|
|
156
|
+
lines << exec_line
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
File.write(script_path, lines.join("\r\n") + "\r\n")
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|