u3d 1.2.3 → 1.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.circleci/config.yml +33 -10
- data/.github/workflows/ci.yml +35 -0
- data/.github_changelog_generator +3 -1
- data/.gitignore +1 -0
- data/.rubocop.yml +15 -3
- data/CHANGELOG.md +86 -11
- data/Gemfile.lock +149 -87
- data/Rakefile +13 -8
- data/examples/Example1/Gemfile +4 -2
- data/examples/Example1/Gemfile.lock +8 -6
- data/examples/Example1/Rakefile +2 -0
- data/examples/Example1/fastlane/Fastfile +2 -0
- data/examples/Example2/Gemfile +4 -2
- data/examples/Example2/Gemfile.lock +12 -7
- data/examples/Example2/fastlane/Fastfile +2 -0
- data/exe/u3d +3 -1
- data/lib/u3d/asset.rb +6 -2
- data/lib/u3d/cache.rb +14 -10
- data/lib/u3d/commands.rb +14 -9
- data/lib/u3d/commands_generator.rb +6 -4
- data/lib/u3d/compatibility.rb +2 -0
- data/lib/u3d/download_validator.rb +6 -3
- data/lib/u3d/downloader.rb +12 -8
- data/lib/u3d/failure_reporter.rb +4 -3
- data/lib/u3d/hub_modules_parser.rb +24 -7
- data/lib/u3d/ini_modules_parser.rb +10 -8
- data/lib/u3d/installation.rb +31 -49
- data/lib/u3d/installer.rb +44 -33
- data/lib/u3d/log_analyzer.rb +31 -27
- data/lib/u3d/unity_license.rb +2 -0
- data/lib/u3d/unity_module.rb +2 -0
- data/lib/u3d/unity_project.rb +4 -1
- data/lib/u3d/unity_runner.rb +12 -10
- data/lib/u3d/unity_version_definition.rb +3 -0
- data/lib/u3d/unity_version_number.rb +8 -2
- data/lib/u3d/unity_versions.rb +28 -23
- data/lib/u3d/utils.rb +86 -15
- data/lib/u3d/version.rb +8 -6
- data/lib/u3d.rb +2 -0
- data/lib/u3d_core/admin_tools.rb +2 -0
- data/lib/u3d_core/command_executor.rb +11 -7
- data/lib/u3d_core/command_runner.rb +17 -19
- data/lib/u3d_core/core_ext/hash.rb +2 -0
- data/lib/u3d_core/core_ext/operating_system_symbol.rb +3 -0
- data/lib/u3d_core/core_ext/string.rb +2 -0
- data/lib/u3d_core/credentials.rb +9 -7
- data/lib/u3d_core/env.rb +3 -0
- data/lib/u3d_core/globals.rb +7 -7
- data/lib/u3d_core/helper.rb +6 -4
- data/lib/u3d_core/ui/disable_colors.rb +2 -0
- data/lib/u3d_core/ui/implementations/shell.rb +8 -5
- data/lib/u3d_core/ui/interface.rb +3 -0
- data/lib/u3d_core/ui/ui.rb +5 -4
- data/lib/u3d_core/update_checker/changelog.rb +4 -0
- data/lib/u3d_core/update_checker/update_checker.rb +8 -9
- data/lib/u3d_core/version.rb +2 -0
- data/lib/u3d_core.rb +2 -0
- data/u3d.gemspec +20 -9
- metadata +112 -28
- data/appveyor.yml +0 -21
data/lib/u3d/commands.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
## --- BEGIN LICENSE BLOCK ---
|
2
4
|
# Copyright (c) 2016-present WeWantToKnow AS
|
3
5
|
#
|
@@ -37,7 +39,7 @@ require 'fileutils'
|
|
37
39
|
|
38
40
|
module U3d
|
39
41
|
# API for U3d, redirecting calls to class they concern
|
40
|
-
# rubocop:disable ClassLength
|
42
|
+
# rubocop:disable Metrics/ClassLength
|
41
43
|
class Commands
|
42
44
|
using ::CoreExtensions::Extractable
|
43
45
|
|
@@ -51,18 +53,18 @@ module U3d
|
|
51
53
|
return
|
52
54
|
end
|
53
55
|
list.each do |u|
|
54
|
-
version_format = "Version %-15
|
56
|
+
version_format = "Version %-15<version>s [%<build_number>s] %<do_not_move>s(%<root_path>s)"
|
55
57
|
do_not_move = u.do_not_move? ? '!'.red.bold : ' '
|
56
58
|
h = { version: u.version, build_number: u.build_number, root_path: u.root_path, do_not_move: do_not_move }
|
57
59
|
UI.message version_format % h
|
58
60
|
packages = u.packages
|
59
61
|
next unless options[:packages] && packages && !packages.empty?
|
62
|
+
|
60
63
|
UI.message 'Packages:'
|
61
64
|
packages.each { |pack| UI.message " - #{pack}" }
|
62
65
|
end
|
63
66
|
end
|
64
67
|
|
65
|
-
# rubocop:disable Style/FormatStringToken
|
66
68
|
def console
|
67
69
|
require 'irb'
|
68
70
|
ARGV.clear
|
@@ -81,7 +83,6 @@ module U3d
|
|
81
83
|
|
82
84
|
catch(:IRB_EXIT) { @irb.eval_input }
|
83
85
|
end
|
84
|
-
# rubocop:enable Style/FormatStringToken
|
85
86
|
|
86
87
|
def move(args: {}, options: {})
|
87
88
|
long_name = options[:long]
|
@@ -131,6 +132,7 @@ module U3d
|
|
131
132
|
v = cache_versions[k]
|
132
133
|
UI.message "Version #{k}: " + v.to_s.cyan.underline
|
133
134
|
next unless show_packages
|
135
|
+
|
134
136
|
version_packages = packages[k]
|
135
137
|
UI.message 'Packages:'
|
136
138
|
version_packages.each { |package| UI.message " - #{package.id.capitalize}" }
|
@@ -166,6 +168,7 @@ module U3d
|
|
166
168
|
files = Downloader.fetch_modules(definition, packages: packages, download: options[:download])
|
167
169
|
|
168
170
|
return unless options[:install]
|
171
|
+
|
169
172
|
Installer.install_modules(files, definition.version, installation_path: options[:installation_path])
|
170
173
|
end
|
171
174
|
|
@@ -222,12 +225,14 @@ module U3d
|
|
222
225
|
action = args[0]
|
223
226
|
raise "Please specify an action to perform, one of #{credentials_actions.join(',')}" unless action
|
224
227
|
raise "Unknown action '#{action}'. Use one of #{credentials_actions.join(',')}" unless credentials_actions.include? action
|
225
|
-
|
228
|
+
|
229
|
+
case action
|
230
|
+
when 'add'
|
226
231
|
U3dCore::Globals.use_keychain = true
|
227
232
|
# credentials = U3dCore::Credentials.new(user: ENV['USER'])
|
228
233
|
# credentials.login # ask password
|
229
234
|
UI.error 'Invalid credentials' unless U3dCore::CommandExecutor.has_admin_privileges?
|
230
|
-
|
235
|
+
when 'remove'
|
231
236
|
U3dCore::Globals.use_keychain = true
|
232
237
|
U3dCore::Credentials.new(user: ENV['USER']).forget_credentials(force: true)
|
233
238
|
else
|
@@ -269,8 +274,7 @@ module U3d
|
|
269
274
|
def cache_versions(os, offline: false, force_refresh: false, central_cache: true)
|
270
275
|
cache = Cache.new(force_os: os, offline: offline, force_refresh: force_refresh, central_cache: central_cache)
|
271
276
|
cache_os = cache[os.id2name] || {}
|
272
|
-
|
273
|
-
cache_versions
|
277
|
+
cache_os['versions'] || {}
|
274
278
|
end
|
275
279
|
|
276
280
|
def verify_package_names(packages, definition)
|
@@ -418,6 +422,7 @@ module U3d
|
|
418
422
|
package = definition[package_name]
|
419
423
|
return true unless package.depends_on
|
420
424
|
return true if unity.package_installed?(package.depends_on)
|
425
|
+
|
421
426
|
installing.map { |other| definition[other] }.any? do |other|
|
422
427
|
other.id == package.depends_on || other.name == package.depends_on
|
423
428
|
end
|
@@ -430,7 +435,7 @@ module U3d
|
|
430
435
|
end
|
431
436
|
end
|
432
437
|
end
|
433
|
-
# rubocop:enable ClassLength
|
438
|
+
# rubocop:enable Metrics/ClassLength
|
434
439
|
end
|
435
440
|
|
436
441
|
class InstallationSetupError < StandardError
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
## --- BEGIN LICENSE BLOCK ---
|
2
4
|
# Copyright (c) 2016-present WeWantToKnow AS
|
3
5
|
#
|
@@ -28,12 +30,12 @@ HighLine.track_eof = false
|
|
28
30
|
|
29
31
|
module U3d
|
30
32
|
# CLI using commander gem for u3d
|
31
|
-
# rubocop:disable ClassLength
|
33
|
+
# rubocop:disable Metrics/ClassLength
|
32
34
|
class CommandsGenerator
|
33
35
|
include Commander::Methods
|
34
36
|
UI = U3dCore::UI
|
35
37
|
|
36
|
-
UNICODE_FILE = File.expand_path('
|
38
|
+
UNICODE_FILE = File.expand_path('../assets/utf8.txt', __dir__)
|
37
39
|
|
38
40
|
def self.start
|
39
41
|
U3dCore::UpdateChecker.start_looking_for_update('u3d')
|
@@ -97,7 +99,7 @@ Fore more information about how the rules work, see https://github.com/DragonBox
|
|
97
99
|
c.option '-u', '--unity_version STRING', String, 'Version of Unity to run with. If not specified, it runs with the version of the project (either specified as -projectPath or current)'
|
98
100
|
c.option '-r', '--raw_logs', 'Raw Unity output, not filtered by u3d\'s log prettifier'
|
99
101
|
c.action do |args, options|
|
100
|
-
UI.user_error! "Run doesn't take arguments. Did you forget '--' or did you mistake your command? (#{args})" if args.count
|
102
|
+
UI.user_error! "Run doesn't take arguments. Did you forget '--' or did you mistake your command? (#{args})" if args.count.positive?
|
101
103
|
U3dCore::Globals.log_timestamps = true
|
102
104
|
Commands.run(options: convert_options(options), run_args: run_args)
|
103
105
|
end
|
@@ -263,5 +265,5 @@ More on that: https://forum.unity3d.com/threads/unity-on-linux-release-notes-and
|
|
263
265
|
run!
|
264
266
|
end
|
265
267
|
end
|
266
|
-
# rubocop:enable ClassLength
|
268
|
+
# rubocop:enable Metrics/ClassLength
|
267
269
|
end
|
data/lib/u3d/compatibility.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
## --- BEGIN LICENSE BLOCK ---
|
2
4
|
# Copyright (c) 2016-present WeWantToKnow AS
|
3
5
|
#
|
@@ -51,7 +53,8 @@ module U3d
|
|
51
53
|
|
52
54
|
class LinuxValidator < DownloadValidator
|
53
55
|
def validate(package, file, definition)
|
54
|
-
return size_validation(expected: definition[package].download_size, actual: File.size(file)) if definition[package]
|
56
|
+
return size_validation(expected: definition[package].download_size, actual: File.size(file)) if definition[package]&.download_size
|
57
|
+
|
55
58
|
UI.important "No file validation available, #{file} is assumed to be correct"
|
56
59
|
true
|
57
60
|
end
|
@@ -59,7 +62,7 @@ module U3d
|
|
59
62
|
|
60
63
|
class MacValidator < DownloadValidator
|
61
64
|
def validate(package, file, definition)
|
62
|
-
if definition[package].download_size % 1000 && definition[package].checksum.nil?
|
65
|
+
if (definition[package].download_size % 1000) && definition[package].checksum.nil?
|
63
66
|
UI.verbose "File '#{definition[package].name}' seems external. Validation skipped"
|
64
67
|
return true
|
65
68
|
end
|
@@ -71,7 +74,7 @@ module U3d
|
|
71
74
|
class WindowsValidator < DownloadValidator
|
72
75
|
def validate(package, file, definition)
|
73
76
|
# External packages have no md5 and a false size value
|
74
|
-
if definition[package].download_size % 1000 && definition[package].checksum.nil?
|
77
|
+
if (definition[package].download_size % 1000) && definition[package].checksum.nil?
|
75
78
|
UI.verbose "File '#{definition[package].name}' seems external. Validation skipped"
|
76
79
|
return true
|
77
80
|
end
|
data/lib/u3d/downloader.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
## --- BEGIN LICENSE BLOCK ---
|
2
4
|
# Copyright (c) 2016-present WeWantToKnow AS
|
3
5
|
#
|
@@ -27,13 +29,13 @@ module U3d
|
|
27
29
|
# Take care of downloading files and packages
|
28
30
|
module Downloader
|
29
31
|
# Name of the directory for the package downloading
|
30
|
-
DOWNLOAD_DIRECTORY = 'Unity_Packages'
|
32
|
+
DOWNLOAD_DIRECTORY = 'Unity_Packages'
|
31
33
|
# Path to the directory for the package downloading
|
32
|
-
DOWNLOAD_PATH = "#{ENV['HOME']}/Downloads"
|
34
|
+
DOWNLOAD_PATH = "#{ENV['HOME']}/Downloads"
|
33
35
|
# Regex to get the name of a localization asset
|
34
|
-
UNITY_LANGUAGE_FILE_REGEX = %r{
|
36
|
+
UNITY_LANGUAGE_FILE_REGEX = %r{/\d+/[0-9.]+/([\w-]+)$}.freeze
|
35
37
|
# Regex to get the name of a package out of its file name
|
36
|
-
UNITY_MODULE_FILE_REGEX = %r{
|
38
|
+
UNITY_MODULE_FILE_REGEX = %r{/([\w\-_.+]+\.(?:pkg|dmg|exe|zip|sh|deb|msi|xz))[^/]*$}.freeze
|
37
39
|
|
38
40
|
class << self
|
39
41
|
def download_directory
|
@@ -112,15 +114,15 @@ module U3d
|
|
112
114
|
return
|
113
115
|
else
|
114
116
|
extension = File.extname(path)
|
115
|
-
new_path = File.join(File.dirname(path), File.basename(path, extension)
|
117
|
+
new_path = File.join(File.dirname(path), "#{File.basename(path, extension)}_CORRUPTED#{extension}")
|
116
118
|
UI.important "File present at #{path} is not correct, it has been renamed to #{new_path}"
|
117
119
|
File.rename(path, new_path)
|
118
120
|
end
|
119
121
|
end
|
120
122
|
|
121
123
|
UI.header "Downloading #{package_info.name} version #{definition.version}"
|
122
|
-
UI.message
|
123
|
-
UI.message
|
124
|
+
UI.message "Downloading from #{url.to_s.cyan.underline}"
|
125
|
+
UI.message "Download will be found at #{path}"
|
124
126
|
download_package(path, url, size: package_info.download_size)
|
125
127
|
|
126
128
|
if validator.validate(package, path, definition)
|
@@ -153,7 +155,7 @@ module U3d
|
|
153
155
|
Utils.ensure_dir(dir)
|
154
156
|
|
155
157
|
file_name = if (language_match = UNITY_LANGUAGE_FILE_REGEX.match(final_url))
|
156
|
-
language_match[1]
|
158
|
+
"#{language_match[1]}.po" # Unity uses PO (Portable object files) for localization
|
157
159
|
elsif (module_match = UNITY_MODULE_FILE_REGEX.match(final_url))
|
158
160
|
module_match[1]
|
159
161
|
else
|
@@ -182,8 +184,10 @@ module U3d
|
|
182
184
|
# for backward compatibility
|
183
185
|
class MacDownloader < StandardPackageDownloader
|
184
186
|
end
|
187
|
+
|
185
188
|
class LinuxDownloader < StandardPackageDownloader
|
186
189
|
end
|
190
|
+
|
187
191
|
class WindowsDownloader < StandardPackageDownloader
|
188
192
|
end
|
189
193
|
end
|
data/lib/u3d/failure_reporter.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'date'
|
2
4
|
require 'fileutils'
|
3
5
|
require 'json'
|
@@ -9,6 +11,7 @@ module U3d
|
|
9
11
|
class << self
|
10
12
|
def report(failure_type: "DEFAULT", failure_message: "", data: {})
|
11
13
|
return unless ENV['U3D_REPORT_FAILURES']
|
14
|
+
|
12
15
|
report = {
|
13
16
|
type: failure_type,
|
14
17
|
message: failure_message,
|
@@ -21,9 +24,7 @@ module U3d
|
|
21
24
|
"#{failure_type}.#{Date.now.strftime('%Y%m%dT%H%M')}.failure.json"
|
22
25
|
)
|
23
26
|
|
24
|
-
File.
|
25
|
-
file.write JSON.pretty_generate(report)
|
26
|
-
end
|
27
|
+
File.write(report_file, JSON.pretty_generate(report))
|
27
28
|
rescue StandardError => e
|
28
29
|
UI.important "Unable to report a #{failure_type} failure. Please use --verbose to get more information about the failure"
|
29
30
|
UI.verbose "Unable to report failure: #{e}"
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
## --- BEGIN LICENSE BLOCK ---
|
2
4
|
# Copyright (c) 2016-present WeWantToKnow AS
|
3
5
|
#
|
@@ -28,19 +30,34 @@ require 'u3d_core/helper'
|
|
28
30
|
module U3d
|
29
31
|
module HubModulesParser
|
30
32
|
class << self
|
31
|
-
HUB_MODULES_NAME = '%<version>s-%<os>s-modules.json'
|
33
|
+
HUB_MODULES_NAME = '%<version>s-%<os>s-modules.json'
|
32
34
|
|
33
35
|
def load_modules(version, os: U3dCore::Helper.operating_system, offline: false)
|
34
36
|
path = modules_path(version, os)
|
35
37
|
|
36
|
-
|
37
|
-
|
38
|
-
|
38
|
+
# force download if no hub file present
|
39
|
+
download_modules(os: os) if !Utils.file_exists_not_empty?(path) && !offline
|
40
|
+
|
41
|
+
unless Utils.file_exists_not_empty?(path)
|
42
|
+
UI.verbose "No modules registered for UnityHub for version #{version}"
|
43
|
+
# cached_versions.keys.map{|s| UnityVersionNumber.new(s)}
|
44
|
+
# searching for closest version
|
45
|
+
files = Dir.glob("#{default_modules_path}/*-#{os}-modules.json")
|
46
|
+
|
47
|
+
vn = UnityVersionNumber.new(version)
|
48
|
+
|
49
|
+
versions_and_paths = files.map do |p|
|
50
|
+
v = File.basename(p).split('-')[0]
|
51
|
+
[UnityVersionNumber.new(v), p]
|
52
|
+
end
|
53
|
+
# filtered by version major.minor.patch (same major & minor and patch higher or equal)
|
54
|
+
versions_and_paths = versions_and_paths.select { |a| a[0].parts[0] == vn.parts[0] && a[0].parts[1] == vn.parts[1] && a[0].parts[2] >= vn.parts[2] }
|
39
55
|
|
40
|
-
|
41
|
-
UI.
|
56
|
+
if versions_and_paths.empty?
|
57
|
+
UI.info "No closest version from UnityHub found for version #{version}"
|
42
58
|
return []
|
43
59
|
end
|
60
|
+
path = versions_and_paths.first[1]
|
44
61
|
end
|
45
62
|
|
46
63
|
return JSON.parse(File.read(path))
|
@@ -81,7 +98,7 @@ module U3d
|
|
81
98
|
path = modules_path(build['version'], os)
|
82
99
|
Utils.ensure_dir(File.dirname(path))
|
83
100
|
|
84
|
-
File.
|
101
|
+
File.write(path, build['modules'].to_json)
|
85
102
|
end
|
86
103
|
end
|
87
104
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
## --- BEGIN LICENSE BLOCK ---
|
2
4
|
# Copyright (c) 2016-present WeWantToKnow AS
|
3
5
|
#
|
@@ -30,7 +32,7 @@ module U3d
|
|
30
32
|
#####################################################
|
31
33
|
# @!group INI parameters to load and save ini files
|
32
34
|
#####################################################
|
33
|
-
INI_NAME = 'unity-%<version>s-%<os>s.ini'
|
35
|
+
INI_NAME = 'unity-%<version>s-%<os>s.ini'
|
34
36
|
|
35
37
|
class << self
|
36
38
|
def load_ini(version, cached_versions, os: U3dCore::Helper.operating_system, offline: false)
|
@@ -42,8 +44,9 @@ module U3d
|
|
42
44
|
ini_name = format(INI_NAME, version: version, os: os)
|
43
45
|
Utils.ensure_dir(default_ini_path)
|
44
46
|
ini_path = File.expand_path(ini_name, default_ini_path)
|
45
|
-
unless
|
47
|
+
unless Utils.file_exists_not_empty?(ini_path)
|
46
48
|
raise "INI file does not exist at #{ini_path}" if offline
|
49
|
+
|
47
50
|
download_ini(version, cached_versions, os, ini_name, ini_path)
|
48
51
|
end
|
49
52
|
begin
|
@@ -58,7 +61,8 @@ module U3d
|
|
58
61
|
ini_name = format(INI_NAME, version: version, os: 'linux')
|
59
62
|
Utils.ensure_dir(default_ini_path)
|
60
63
|
ini_path = File.expand_path(ini_name, default_ini_path)
|
61
|
-
return if File.file?(ini_path) && File.size(ini_path)
|
64
|
+
return if File.file?(ini_path) && File.size(ini_path).positive?
|
65
|
+
|
62
66
|
data = %([Unity]
|
63
67
|
; -- NOTE --
|
64
68
|
; This is not an official Unity file
|
@@ -90,16 +94,14 @@ url=#{url}
|
|
90
94
|
UI.verbose("Searching for ini file at #{uri}")
|
91
95
|
|
92
96
|
data = Net::HTTP.get(uri)
|
93
|
-
data.tr
|
94
|
-
data.gsub
|
97
|
+
data = data.tr("\"", '')
|
98
|
+
data = data.gsub(/Note:.+\n/, '')
|
95
99
|
|
96
100
|
write_ini_file(ini_path, data)
|
97
101
|
end
|
98
102
|
|
99
103
|
def write_ini_file(ini_path, data)
|
100
|
-
File.
|
101
|
-
f.write(data)
|
102
|
-
end
|
104
|
+
File.binwrite(ini_path, data)
|
103
105
|
end
|
104
106
|
|
105
107
|
def default_ini_path
|
data/lib/u3d/installation.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
## --- BEGIN LICENSE BLOCK ---
|
2
4
|
# Copyright (c) 2016-present WeWantToKnow AS
|
3
5
|
#
|
@@ -25,9 +27,12 @@ require 'u3d_core/admin_tools'
|
|
25
27
|
require 'fileutils'
|
26
28
|
|
27
29
|
module U3d
|
28
|
-
UNITY_DIR_CHECK = /Unity_\d+\.\d+\.\d+[a-z]\d
|
29
|
-
UNITY_DIR_CHECK_LINUX = /unity-editor-\d+\.\d+\.\d+[a-z]\d+\z
|
30
|
-
|
30
|
+
UNITY_DIR_CHECK = /Unity_\d+\.\d+\.\d+[a-z]\d+/.freeze
|
31
|
+
UNITY_DIR_CHECK_LINUX = /unity-editor-\d+\.\d+\.\d+[a-z]\d+\z/.freeze
|
32
|
+
# Linux unity_builtin_extra seek position for version
|
33
|
+
UNITY_VERSION_LINUX_POS_LE_2019 = 20
|
34
|
+
UNITY_VERSION_LINUX_POS_GT_2019 = 48
|
35
|
+
U3D_DO_NOT_MOVE = ".u3d_do_not_move"
|
31
36
|
|
32
37
|
class Installation
|
33
38
|
attr_accessor :root_path
|
@@ -114,6 +119,7 @@ module U3d
|
|
114
119
|
require 'rexml/document'
|
115
120
|
UI.verbose("reading #{config_path}")
|
116
121
|
raise "File not found at #{config_path}" unless File.exist? config_path
|
122
|
+
|
117
123
|
doc = REXML::Document.new(File.read(config_path))
|
118
124
|
REXML::XPath.first(doc, node_name).value
|
119
125
|
end
|
@@ -142,10 +148,19 @@ module U3d
|
|
142
148
|
class InstallationUtils
|
143
149
|
def self.read_version_from_unity_builtin_extra(file)
|
144
150
|
File.open(file, "rb") do |f|
|
145
|
-
|
151
|
+
# Check if it is version lower or equal to 2019
|
152
|
+
seek_pos = UNITY_VERSION_LINUX_POS_LE_2019
|
153
|
+
f.seek(seek_pos)
|
154
|
+
z = f.read(1)
|
155
|
+
if z == "\x00"
|
156
|
+
# Version is greater than 2019
|
157
|
+
seek_pos = UNITY_VERSION_LINUX_POS_GT_2019
|
158
|
+
end
|
159
|
+
f.seek(seek_pos)
|
146
160
|
s = ""
|
147
161
|
while (c = f.read(1))
|
148
162
|
break if c == "\x00"
|
163
|
+
|
149
164
|
s += c
|
150
165
|
end
|
151
166
|
s
|
@@ -175,6 +190,7 @@ module U3d
|
|
175
190
|
def path
|
176
191
|
UI.deprecated("path is deprecated. Use root_path instead")
|
177
192
|
return @path if @path
|
193
|
+
|
178
194
|
"#{@root_path}/Unity.app"
|
179
195
|
end
|
180
196
|
|
@@ -217,13 +233,14 @@ module U3d
|
|
217
233
|
begin
|
218
234
|
fpath = "#{root_path}/Unity.app/Contents/Info.plist"
|
219
235
|
raise "#{fpath} doesn't exist" unless File.exist? fpath
|
236
|
+
|
220
237
|
Plist.parse_xml(fpath)
|
221
238
|
end
|
222
239
|
end
|
223
240
|
end
|
224
241
|
|
225
242
|
class LinuxInstallationHelper
|
226
|
-
STRINGS_FULL_VERSION_MATCHER = /^[0-9
|
243
|
+
STRINGS_FULL_VERSION_MATCHER = /^[0-9.abfp]+_[0-9a-f]{12}/.freeze
|
227
244
|
|
228
245
|
def find_build_number(root)
|
229
246
|
known_rev_locations.each do |p|
|
@@ -236,10 +253,10 @@ module U3d
|
|
236
253
|
private
|
237
254
|
|
238
255
|
def strings(path)
|
239
|
-
if `which strings`
|
240
|
-
binutils_strings(path)
|
241
|
-
else
|
256
|
+
if `which strings` == ''
|
242
257
|
Utils.strings(path).to_a
|
258
|
+
else
|
259
|
+
binutils_strings(path)
|
243
260
|
end
|
244
261
|
end
|
245
262
|
|
@@ -258,8 +275,9 @@ module U3d
|
|
258
275
|
|
259
276
|
def find_build_number_in(path = nil)
|
260
277
|
return nil unless File.exist? path
|
278
|
+
|
261
279
|
str = strings(path)
|
262
|
-
lines = str.
|
280
|
+
lines = str.grep(STRINGS_FULL_VERSION_MATCHER)
|
263
281
|
lines.empty? ? nil : lines[0].split('_')[1]
|
264
282
|
end
|
265
283
|
end
|
@@ -347,44 +365,7 @@ module U3d
|
|
347
365
|
private
|
348
366
|
|
349
367
|
def unity_version_info
|
350
|
-
@
|
351
|
-
end
|
352
|
-
|
353
|
-
def string_file_info(info, path)
|
354
|
-
require "Win32API"
|
355
|
-
get_file_version_info_size = Win32API.new('version.dll', 'GetFileVersionInfoSize', 'PP', 'L')
|
356
|
-
get_file_version_info = Win32API.new('version.dll', 'GetFileVersionInfo', 'PIIP', 'I')
|
357
|
-
ver_query_value = Win32API.new('version.dll', 'VerQueryValue', 'PPPP', 'I')
|
358
|
-
rtl_move_memory = Win32API.new('kernel32.dll', 'RtlMoveMemory', 'PLL', 'I')
|
359
|
-
|
360
|
-
file = path.tr("/", "\\")
|
361
|
-
|
362
|
-
buf = [0].pack('L')
|
363
|
-
version_size = get_file_version_info_size.call(file + "\0", buf)
|
364
|
-
raise Exception if version_size.zero? # TODO: use GetLastError
|
365
|
-
|
366
|
-
version_info = 0.chr * version_size
|
367
|
-
version_ok = get_file_version_info.call(file, 0, version_size, version_info)
|
368
|
-
raise Exception if version_ok.zero? # TODO: use GetLastError
|
369
|
-
|
370
|
-
# hardcoding lang codepage
|
371
|
-
struct_path = "\\StringFileInfo\\040904b0\\#{info}"
|
372
|
-
|
373
|
-
addr = [0].pack('L')
|
374
|
-
size = [0].pack('L')
|
375
|
-
query_ok = ver_query_value.call(version_info, struct_path + "\0", addr, size)
|
376
|
-
raise Exception if query_ok.zero?
|
377
|
-
|
378
|
-
raddr = addr.unpack('L')[0]
|
379
|
-
rsize = size.unpack('L')[0]
|
380
|
-
|
381
|
-
info = Array.new(rsize, 0).pack('L*')
|
382
|
-
rtl_move_memory.call(info, raddr, info.length)
|
383
|
-
info.strip
|
384
|
-
rescue StandardError => e
|
385
|
-
UI.verbose("Failure to find '#{info}' under '#{path}': #{e}")
|
386
|
-
UI.verbose(e.backtrace)
|
387
|
-
nil
|
368
|
+
@unity_version_info ||= U3d::Utils.windows_fileversion('Unity Version', @exe_path)
|
388
369
|
end
|
389
370
|
end
|
390
371
|
|
@@ -396,6 +377,7 @@ module U3d
|
|
396
377
|
path = "#{root_path}/Editor/Data/"
|
397
378
|
package = IvyPlaybackEngineUtils.list_module_configs(path).first
|
398
379
|
raise "Couldn't find a module under #{path}" unless package
|
380
|
+
|
399
381
|
IvyPlaybackEngineUtils.unity_version(package)
|
400
382
|
end
|
401
383
|
|
@@ -410,8 +392,8 @@ module U3d
|
|
410
392
|
log_dir = File.expand_path('Unity/Editor/', loc_appdata)
|
411
393
|
UI.important "Log directory (#{log_dir}) does not exist" unless Dir.exist? log_dir
|
412
394
|
@logfile = File.expand_path('Editor.log', log_dir)
|
413
|
-
rescue RuntimeError =>
|
414
|
-
UI.error "Unable to retrieve the editor logfile: #{
|
395
|
+
rescue RuntimeError => e
|
396
|
+
UI.error "Unable to retrieve the editor logfile: #{e}"
|
415
397
|
end
|
416
398
|
end
|
417
399
|
@logfile
|