u3d 1.2.1 → 1.3.0
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 +4 -4
- data/.circleci/config.yml +43 -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 +90 -11
- data/DEVELOPMENT_PROCESS.md +1 -0
- data/Gemfile.lock +148 -88
- data/Rakefile +55 -6
- data/appveyor.yml +25 -6
- data/examples/Example1/Gemfile +4 -2
- data/examples/Example1/Gemfile.lock +12 -7
- 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 +22 -17
- data/lib/u3d/commands_generator.rb +9 -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 -32
- data/lib/u3d/installation.rb +77 -66
- data/lib/u3d/installer.rb +50 -34
- 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 +82 -15
- data/lib/u3d/version.rb +8 -6
- data/lib/u3d.rb +13 -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 +35 -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 +67 -0
- data/lib/u3d_core/update_checker/update_checker.rb +129 -0
- data/lib/u3d_core/version.rb +2 -0
- data/lib/u3d_core.rb +5 -0
- data/u3d.gemspec +20 -10
- metadata +106 -31
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
|
@@ -105,7 +110,7 @@ module U3d
|
|
105
110
|
end
|
106
111
|
end
|
107
112
|
|
108
|
-
class
|
113
|
+
class IvyPlaybackEngineUtils
|
109
114
|
def self.list_module_configs(playbackengine_parent_path)
|
110
115
|
Dir.glob("#{playbackengine_parent_path}/PlaybackEngines/*/ivy.xml")
|
111
116
|
end
|
@@ -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
|
@@ -127,6 +133,41 @@ module U3d
|
|
127
133
|
end
|
128
134
|
end
|
129
135
|
|
136
|
+
class ModulePlaybackEngineUtils
|
137
|
+
def self.list_module_configs(playbackengine_parent_path)
|
138
|
+
# this should work on all platforms, non existing paths being ignored...
|
139
|
+
Dir.glob("#{playbackengine_parent_path}/PlaybackEngines/*/modules.asset") |
|
140
|
+
Dir.glob("#{playbackengine_parent_path}/Unity.app/Contents/PlaybackEngines/*/modules.asset")
|
141
|
+
end
|
142
|
+
|
143
|
+
def self.module_name(config_path)
|
144
|
+
File.basename(File.dirname(config_path)).gsub("Support", "")
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
class InstallationUtils
|
149
|
+
def self.read_version_from_unity_builtin_extra(file)
|
150
|
+
File.open(file, "rb") do |f|
|
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)
|
160
|
+
s = ""
|
161
|
+
while (c = f.read(1))
|
162
|
+
break if c == "\x00"
|
163
|
+
|
164
|
+
s += c
|
165
|
+
end
|
166
|
+
s
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
130
171
|
class MacInstallation < Installation
|
131
172
|
require 'plist'
|
132
173
|
|
@@ -149,14 +190,19 @@ module U3d
|
|
149
190
|
def path
|
150
191
|
UI.deprecated("path is deprecated. Use root_path instead")
|
151
192
|
return @path if @path
|
193
|
+
|
152
194
|
"#{@root_path}/Unity.app"
|
153
195
|
end
|
154
196
|
|
155
197
|
def packages
|
156
198
|
pack = []
|
157
|
-
|
158
|
-
pack <<
|
199
|
+
IvyPlaybackEngineUtils.list_module_configs(root_path).each do |mpath|
|
200
|
+
pack << IvyPlaybackEngineUtils.module_name(mpath)
|
201
|
+
end
|
202
|
+
ModulePlaybackEngineUtils.list_module_configs(root_path).each do |mpath|
|
203
|
+
pack << ModulePlaybackEngineUtils.module_name(mpath)
|
159
204
|
end
|
205
|
+
|
160
206
|
NOT_PLAYBACKENGINE_PACKAGES.each do |module_name|
|
161
207
|
pack << module_name unless Dir[module_name_pattern(module_name)].empty?
|
162
208
|
end
|
@@ -187,13 +233,14 @@ module U3d
|
|
187
233
|
begin
|
188
234
|
fpath = "#{root_path}/Unity.app/Contents/Info.plist"
|
189
235
|
raise "#{fpath} doesn't exist" unless File.exist? fpath
|
236
|
+
|
190
237
|
Plist.parse_xml(fpath)
|
191
238
|
end
|
192
239
|
end
|
193
240
|
end
|
194
241
|
|
195
242
|
class LinuxInstallationHelper
|
196
|
-
STRINGS_FULL_VERSION_MATCHER = /^[0-9
|
243
|
+
STRINGS_FULL_VERSION_MATCHER = /^[0-9.abfp]+_[0-9a-f]{12}/.freeze
|
197
244
|
|
198
245
|
def find_build_number(root)
|
199
246
|
known_rev_locations.each do |p|
|
@@ -206,10 +253,10 @@ module U3d
|
|
206
253
|
private
|
207
254
|
|
208
255
|
def strings(path)
|
209
|
-
if `which strings`
|
210
|
-
binutils_strings(path)
|
211
|
-
else
|
256
|
+
if `which strings` == ''
|
212
257
|
Utils.strings(path).to_a
|
258
|
+
else
|
259
|
+
binutils_strings(path)
|
213
260
|
end
|
214
261
|
end
|
215
262
|
|
@@ -228,23 +275,17 @@ module U3d
|
|
228
275
|
|
229
276
|
def find_build_number_in(path = nil)
|
230
277
|
return nil unless File.exist? path
|
278
|
+
|
231
279
|
str = strings(path)
|
232
|
-
lines = str.
|
280
|
+
lines = str.grep(STRINGS_FULL_VERSION_MATCHER)
|
233
281
|
lines.empty? ? nil : lines[0].split('_')[1]
|
234
282
|
end
|
235
283
|
end
|
236
284
|
|
237
285
|
class LinuxInstallation < Installation
|
238
286
|
def version
|
239
|
-
|
240
|
-
path
|
241
|
-
package = PlaybackEngineUtils.list_module_configs(path).first
|
242
|
-
raise "Couldn't find a module under #{path}" unless package
|
243
|
-
version = PlaybackEngineUtils.unity_version(package)
|
244
|
-
if (m = version.match(/^(.*)x(.*)Linux$/))
|
245
|
-
version = "#{m[1]}#{m[2]}"
|
246
|
-
end
|
247
|
-
version
|
287
|
+
path = "#{root_path}/Editor/Data/Resources/unity_builtin_extra"
|
288
|
+
InstallationUtils.read_version_from_unity_builtin_extra(path)
|
248
289
|
end
|
249
290
|
|
250
291
|
def build_number
|
@@ -267,8 +308,11 @@ module U3d
|
|
267
308
|
def packages
|
268
309
|
path = "#{root_path}/Editor/Data/"
|
269
310
|
pack = []
|
270
|
-
|
271
|
-
pack <<
|
311
|
+
IvyPlaybackEngineUtils.list_module_configs(path).each do |mpath|
|
312
|
+
pack << IvyPlaybackEngineUtils.module_name(mpath)
|
313
|
+
end
|
314
|
+
ModulePlaybackEngineUtils.list_module_configs(root_path).each do |mpath|
|
315
|
+
pack << ModulePlaybackEngineUtils.module_name(mpath)
|
272
316
|
end
|
273
317
|
NOT_PLAYBACKENGINE_PACKAGES.each do |module_name|
|
274
318
|
pack << module_name unless Dir[module_name_pattern(module_name)].empty?
|
@@ -321,44 +365,7 @@ module U3d
|
|
321
365
|
private
|
322
366
|
|
323
367
|
def unity_version_info
|
324
|
-
@
|
325
|
-
end
|
326
|
-
|
327
|
-
def string_file_info(info, path)
|
328
|
-
require "Win32API"
|
329
|
-
get_file_version_info_size = Win32API.new('version.dll', 'GetFileVersionInfoSize', 'PP', 'L')
|
330
|
-
get_file_version_info = Win32API.new('version.dll', 'GetFileVersionInfo', 'PIIP', 'I')
|
331
|
-
ver_query_value = Win32API.new('version.dll', 'VerQueryValue', 'PPPP', 'I')
|
332
|
-
rtl_move_memory = Win32API.new('kernel32.dll', 'RtlMoveMemory', 'PLL', 'I')
|
333
|
-
|
334
|
-
file = path.tr("/", "\\")
|
335
|
-
|
336
|
-
buf = [0].pack('L')
|
337
|
-
version_size = get_file_version_info_size.call(file + "\0", buf)
|
338
|
-
raise Exception if version_size.zero? # TODO: use GetLastError
|
339
|
-
|
340
|
-
version_info = 0.chr * version_size
|
341
|
-
version_ok = get_file_version_info.call(file, 0, version_size, version_info)
|
342
|
-
raise Exception if version_ok.zero? # TODO: use GetLastError
|
343
|
-
|
344
|
-
# hardcoding lang codepage
|
345
|
-
struct_path = "\\StringFileInfo\\040904b0\\#{info}"
|
346
|
-
|
347
|
-
addr = [0].pack('L')
|
348
|
-
size = [0].pack('L')
|
349
|
-
query_ok = ver_query_value.call(version_info, struct_path + "\0", addr, size)
|
350
|
-
raise Exception if query_ok.zero?
|
351
|
-
|
352
|
-
raddr = addr.unpack('L')[0]
|
353
|
-
rsize = size.unpack('L')[0]
|
354
|
-
|
355
|
-
info = Array.new(rsize, 0).pack('L*')
|
356
|
-
rtl_move_memory.call(info, raddr, info.length)
|
357
|
-
info.strip
|
358
|
-
rescue StandardError => e
|
359
|
-
UI.verbose("Failure to find '#{info}' under '#{path}': #{e}")
|
360
|
-
UI.verbose(e.backtrace)
|
361
|
-
nil
|
368
|
+
@unity_version_info ||= U3d::Utils.windows_fileversion('Unity Version', @exe_path)
|
362
369
|
end
|
363
370
|
end
|
364
371
|
|
@@ -368,9 +375,10 @@ module U3d
|
|
368
375
|
return version unless version.nil?
|
369
376
|
|
370
377
|
path = "#{root_path}/Editor/Data/"
|
371
|
-
package =
|
378
|
+
package = IvyPlaybackEngineUtils.list_module_configs(path).first
|
372
379
|
raise "Couldn't find a module under #{path}" unless package
|
373
|
-
|
380
|
+
|
381
|
+
IvyPlaybackEngineUtils.unity_version(package)
|
374
382
|
end
|
375
383
|
|
376
384
|
def build_number
|
@@ -384,8 +392,8 @@ module U3d
|
|
384
392
|
log_dir = File.expand_path('Unity/Editor/', loc_appdata)
|
385
393
|
UI.important "Log directory (#{log_dir}) does not exist" unless Dir.exist? log_dir
|
386
394
|
@logfile = File.expand_path('Editor.log', log_dir)
|
387
|
-
rescue RuntimeError =>
|
388
|
-
UI.error "Unable to retrieve the editor logfile: #{
|
395
|
+
rescue RuntimeError => e
|
396
|
+
UI.error "Unable to retrieve the editor logfile: #{e}"
|
389
397
|
end
|
390
398
|
end
|
391
399
|
@logfile
|
@@ -403,8 +411,11 @@ module U3d
|
|
403
411
|
def packages
|
404
412
|
path = "#{root_path}/Editor/Data/"
|
405
413
|
pack = []
|
406
|
-
|
407
|
-
pack <<
|
414
|
+
IvyPlaybackEngineUtils.list_module_configs(path).each do |mpath|
|
415
|
+
pack << IvyPlaybackEngineUtils.module_name(mpath)
|
416
|
+
end
|
417
|
+
ModulePlaybackEngineUtils.list_module_configs(root_path).each do |mpath|
|
418
|
+
pack << ModulePlaybackEngineUtils.module_name(mpath)
|
408
419
|
end
|
409
420
|
NOT_PLAYBACKENGINE_PACKAGES.each do |module_name|
|
410
421
|
pack << module_name unless Dir[module_name_pattern(module_name)].empty?
|
data/lib/u3d/installer.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
|
#
|
@@ -30,13 +32,13 @@ require 'pathname'
|
|
30
32
|
require 'zip'
|
31
33
|
|
32
34
|
module U3d
|
33
|
-
DEFAULT_LINUX_INSTALL = '/opt/'
|
34
|
-
DEFAULT_MAC_INSTALL = '/'
|
35
|
-
DEFAULT_WINDOWS_INSTALL = 'C:/Program Files/'
|
36
|
-
UNITY_DIR = "Unity_%<version>s"
|
37
|
-
UNITY_DIR_LONG = "Unity_%<version>s_%<build_number>s"
|
38
|
-
UNITY_DIR_LINUX = "unity-editor-%<version>s"
|
39
|
-
UNITY_DIR_LINUX_LONG = "unity-editor-%<version>s_%<build_number>s"
|
35
|
+
DEFAULT_LINUX_INSTALL = '/opt/'
|
36
|
+
DEFAULT_MAC_INSTALL = '/'
|
37
|
+
DEFAULT_WINDOWS_INSTALL = 'C:/Program Files/'
|
38
|
+
UNITY_DIR = "Unity_%<version>s"
|
39
|
+
UNITY_DIR_LONG = "Unity_%<version>s_%<build_number>s"
|
40
|
+
UNITY_DIR_LINUX = "unity-editor-%<version>s"
|
41
|
+
UNITY_DIR_LINUX_LONG = "unity-editor-%<version>s_%<build_number>s"
|
40
42
|
|
41
43
|
class Installer
|
42
44
|
def self.create
|
@@ -57,7 +59,7 @@ module U3d
|
|
57
59
|
installer = Installer.create
|
58
60
|
files.each do |name, file, info|
|
59
61
|
UI.header "Installing #{info.name} (#{name})"
|
60
|
-
UI.message
|
62
|
+
UI.message "Installing with #{file}"
|
61
63
|
installer.install(file, version, installation_path: installation_path, info: info)
|
62
64
|
end
|
63
65
|
end
|
@@ -71,20 +73,24 @@ module U3d
|
|
71
73
|
class BaseInstaller
|
72
74
|
def sanitize_installs
|
73
75
|
return unless UI.interactive? || Helper.test?
|
76
|
+
|
74
77
|
unclean = []
|
75
78
|
installed.each { |unity| unclean << unity unless unity.clean_install? }
|
76
79
|
return if unclean.empty?
|
80
|
+
|
77
81
|
UI.important("u3d can optionally standardize the existing Unity installation names and locations.")
|
78
82
|
UI.important("Check the documentation for more information:")
|
79
83
|
UI.important("** https://github.com/DragonBox/u3d/blob/master/README.md#default-installation-paths **")
|
80
84
|
unclean.each { |unity| sanitize_install(unity, dry_run: true) }
|
81
85
|
return unless UI.confirm("#{unclean.count} Unity installation(s) will be moved. Proceed??")
|
86
|
+
|
82
87
|
unclean.each { |unity| sanitize_install(unity) }
|
83
88
|
end
|
84
89
|
|
85
90
|
def installed_sorted_by_versions
|
86
91
|
list = installed
|
87
92
|
return [] if list.empty?
|
93
|
+
|
88
94
|
list.sort { |a, b| UnityVersionComparator.new(a.version) <=> UnityVersionComparator.new(b.version) }
|
89
95
|
end
|
90
96
|
|
@@ -123,7 +129,7 @@ module U3d
|
|
123
129
|
end
|
124
130
|
end
|
125
131
|
|
126
|
-
if info
|
132
|
+
if info&.rename_from && info&.rename_to
|
127
133
|
rename_from = info.rename_from.gsub(/{UNITY_PATH}/, unity.root_path)
|
128
134
|
rename_to = info.rename_to.gsub(/{UNITY_PATH}/, unity.root_path)
|
129
135
|
Utils.ensure_dir(rename_to)
|
@@ -131,7 +137,7 @@ module U3d
|
|
131
137
|
if File.file? rename_from
|
132
138
|
FileUtils.mv(rename_from, rename_to)
|
133
139
|
else
|
134
|
-
Dir.glob(rename_from
|
140
|
+
Dir.glob("#{rename_from}/*").each { |path| FileUtils.mv(path, rename_to) }
|
135
141
|
end
|
136
142
|
end
|
137
143
|
|
@@ -139,23 +145,27 @@ module U3d
|
|
139
145
|
end
|
140
146
|
|
141
147
|
def package_destination(info, unity_root_path)
|
142
|
-
if info
|
148
|
+
if info&.destination
|
143
149
|
info.destination.gsub(/{UNITY_PATH}/, unity_root_path)
|
144
150
|
else
|
145
151
|
unity_root_path
|
146
152
|
end
|
147
153
|
end
|
148
154
|
|
155
|
+
# extra installation paths are stored in U3D_EXTRA_PATHS environment variable,
|
156
|
+
# following a standard PATH variable format.
|
157
|
+
# Returns an array of ruby style paths
|
149
158
|
def extra_installation_paths
|
150
159
|
return [] if ENV['U3D_EXTRA_PATHS'].nil?
|
151
|
-
|
160
|
+
|
161
|
+
ENV['U3D_EXTRA_PATHS'].strip.split(File::PATH_SEPARATOR).map { |p| File.expand_path p }
|
152
162
|
end
|
153
163
|
|
154
|
-
def find_installations_with_path(default_root_path: '', postfix: [])
|
164
|
+
def find_installations_with_path(default_root_path: '', postfix: [], &block)
|
155
165
|
([default_root_path] | extra_installation_paths).map do |path|
|
156
166
|
UI.verbose "Looking for installed Unity version under #{path}"
|
157
167
|
pattern = File.join([path] + postfix)
|
158
|
-
Dir.glob(pattern).map
|
168
|
+
Dir.glob(pattern).map(&block)
|
159
169
|
end.flatten
|
160
170
|
end
|
161
171
|
end
|
@@ -186,14 +196,17 @@ module U3d
|
|
186
196
|
end
|
187
197
|
|
188
198
|
def install(file_path, version, installation_path: nil, info: nil)
|
189
|
-
# rubocop:enable UnusedMethodArgument
|
190
199
|
extension = File.extname(file_path)
|
191
|
-
raise "Installation of #{extension} files is not supported on Mac" unless %w[.zip .po .pkg].include? extension
|
200
|
+
raise "Installation of #{extension} files is not supported on Mac" unless %w[.zip .po .pkg .dmg].include? extension
|
201
|
+
|
192
202
|
path = installation_path || DEFAULT_MAC_INSTALL
|
193
|
-
|
203
|
+
case extension
|
204
|
+
when '.po'
|
194
205
|
install_po(file_path, version, info: info)
|
195
|
-
|
206
|
+
when '.zip'
|
196
207
|
install_zip(file_path, version, info: info)
|
208
|
+
when '.dmg'
|
209
|
+
UI.important "Skipping installation of #{file_path} for now"
|
197
210
|
else
|
198
211
|
install_pkg(file_path, version: version, target_path: path)
|
199
212
|
end
|
@@ -273,7 +286,7 @@ module U3d
|
|
273
286
|
end
|
274
287
|
end
|
275
288
|
|
276
|
-
# rubocop:disable ClassLength
|
289
|
+
# rubocop:disable Metrics/ClassLength
|
277
290
|
class LinuxInstaller < BaseInstaller
|
278
291
|
def sanitize_install(unity, long: false, dry_run: false)
|
279
292
|
source_path = File.expand_path(unity.root_path)
|
@@ -291,26 +304,26 @@ module U3d
|
|
291
304
|
paths.map { |path| LinuxInstallation.new(root_path: path) }
|
292
305
|
end
|
293
306
|
|
294
|
-
# rubocop:disable PerceivedComplexity
|
295
307
|
def install(file_path, version, installation_path: nil, info: nil)
|
296
|
-
# rubocop:enable UnusedMethodArgument, PerceivedComplexity
|
297
308
|
extension = File.extname(file_path)
|
298
309
|
|
299
310
|
raise "Installation of #{extension} files is not supported on Linux" unless ['.zip', '.po', '.sh', '.xz', '.pkg'].include? extension
|
300
|
-
|
311
|
+
|
312
|
+
case extension
|
313
|
+
when '.sh'
|
301
314
|
path = installation_path || DEFAULT_LINUX_INSTALL
|
302
315
|
install_sh(file_path, installation_path: path)
|
303
|
-
|
316
|
+
when '.xz'
|
304
317
|
new_path = File.join(DEFAULT_LINUX_INSTALL, format(UNITY_DIR_LINUX, version: version))
|
305
318
|
path = installation_path || new_path
|
306
319
|
install_xz(file_path, installation_path: path)
|
307
|
-
|
320
|
+
when '.pkg'
|
308
321
|
new_path = File.join(DEFAULT_LINUX_INSTALL, format(UNITY_DIR_LINUX, version: version))
|
309
322
|
path = installation_path || new_path
|
310
323
|
install_pkg(file_path, installation_path: path)
|
311
|
-
|
324
|
+
when '.po'
|
312
325
|
install_po(file_path, version, info: info)
|
313
|
-
|
326
|
+
when '.zip'
|
314
327
|
install_zip(file_path, version, info: info)
|
315
328
|
end
|
316
329
|
|
@@ -394,6 +407,7 @@ module U3d
|
|
394
407
|
|
395
408
|
def pkg_install_path(unity_root_path, pinfo_path)
|
396
409
|
raise "PackageInfo not found under #{pinfo_path}" unless File.exist? pinfo_path
|
410
|
+
|
397
411
|
pinfo = File.read(pinfo_path)
|
398
412
|
require 'rexml/document'
|
399
413
|
d = REXML::Document.new(pinfo)
|
@@ -409,6 +423,7 @@ module U3d
|
|
409
423
|
else
|
410
424
|
install_location = d.root.attributes['install-location']
|
411
425
|
raise "Not sure how to install this module with identifier #{identifier} install-location: #{install_location}" unless install_location.start_with? '/Applications/Unity/'
|
426
|
+
|
412
427
|
install_location.gsub(%(\/Applications\/Unity), "#{unity_root_path}/Editor/Data")
|
413
428
|
end
|
414
429
|
end
|
@@ -437,7 +452,7 @@ module U3d
|
|
437
452
|
paths
|
438
453
|
end
|
439
454
|
end
|
440
|
-
# rubocop:enable ClassLength
|
455
|
+
# rubocop:enable Metrics/ClassLength
|
441
456
|
|
442
457
|
class WindowsInstaller < BaseInstaller
|
443
458
|
def sanitize_install(unity, long: false, dry_run: false)
|
@@ -465,10 +480,12 @@ module U3d
|
|
465
480
|
def install(file_path, version, installation_path: nil, info: nil)
|
466
481
|
extension = File.extname(file_path)
|
467
482
|
raise "Installation of #{extension} files is not supported on Windows" unless %w[.po .zip .exe .msi].include? extension
|
483
|
+
|
468
484
|
path = installation_path || File.join(DEFAULT_WINDOWS_INSTALL, format(UNITY_DIR, version: version))
|
469
|
-
|
485
|
+
case extension
|
486
|
+
when '.po'
|
470
487
|
install_po(file_path, version, info: info)
|
471
|
-
|
488
|
+
when '.zip'
|
472
489
|
install_zip(file_path, version, info: info)
|
473
490
|
else
|
474
491
|
install_exe(file_path, installation_path: path, info: info)
|
@@ -484,14 +501,14 @@ module U3d
|
|
484
501
|
if info.command
|
485
502
|
command = info.command
|
486
503
|
if /msiexec/ =~ command
|
487
|
-
command.sub!(/{FILENAME}/,
|
504
|
+
command.sub!(/{FILENAME}/, "\"#{U3dCore::Helper.windows_path(file_path)}\"")
|
488
505
|
else
|
489
506
|
command.sub!(/{FILENAME}/, file_path.argescape)
|
490
507
|
end
|
491
508
|
command.sub!(/{INSTDIR}/, final_path)
|
492
509
|
command.sub!(/{DOCDIR}/, final_path)
|
493
510
|
command.sub!(/{MODULEDIR}/, final_path)
|
494
|
-
command.sub!(%r{
|
511
|
+
command.sub!(%r{/D=}, '/S /D=') unless %r{/S} =~ command
|
495
512
|
end
|
496
513
|
command ||= file_path.argescape
|
497
514
|
U3dCore::CommandExecutor.execute(command: command, admin: true)
|
@@ -567,9 +584,8 @@ module U3d
|
|
567
584
|
raise 'Cannot install dependencies on your Linux distribution'
|
568
585
|
end
|
569
586
|
|
570
|
-
if UI.interactive?
|
571
|
-
|
572
|
-
end
|
587
|
+
return if UI.interactive? && !(UI.confirm "Install dependencies? (#{DEPENDENCIES.length} dependency(ies) to install)")
|
588
|
+
|
573
589
|
U3dCore::CommandExecutor.execute(command: "#{prefix} #{DEPENDENCIES.join(' ')}", admin: true)
|
574
590
|
end
|
575
591
|
end
|
data/lib/u3d/log_analyzer.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,9 @@ require 'u3d/failure_reporter'
|
|
25
27
|
|
26
28
|
module U3d
|
27
29
|
# Analyzes log by filtering output along a set of rules
|
28
|
-
# rubocop:disable ClassLength, PerceivedComplexity, BlockNesting
|
30
|
+
# rubocop:disable Metrics/ClassLength, Metrics/PerceivedComplexity, Metrics/BlockNesting
|
29
31
|
class LogAnalyzer
|
30
|
-
RULES_PATH = File.expand_path('
|
32
|
+
RULES_PATH = File.expand_path('../../config/log_rules.json', __dir__)
|
31
33
|
MEMORY_SIZE = 10
|
32
34
|
|
33
35
|
def initialize
|
@@ -55,6 +57,7 @@ module U3d
|
|
55
57
|
# Phase parsing
|
56
58
|
next unless phase['active']
|
57
59
|
next if phase['phase_start_pattern'].nil?
|
60
|
+
|
58
61
|
phase['phase_start_pattern'] = Regexp.new phase['phase_start_pattern']
|
59
62
|
phase['phase_end_pattern'] = Regexp.new phase['phase_end_pattern'] if phase['phase_end_pattern']
|
60
63
|
phase.delete('comment')
|
@@ -79,6 +82,7 @@ module U3d
|
|
79
82
|
@phases.each do |name, phase|
|
80
83
|
next if name == @active_phase
|
81
84
|
next unless line =~ phase['phase_start_pattern']
|
85
|
+
|
82
86
|
finish_phase if @active_phase
|
83
87
|
@active_phase = name
|
84
88
|
UI.verbose("--- Beginning #{name} phase ---")
|
@@ -116,12 +120,10 @@ module U3d
|
|
116
120
|
# It's not the end of the rules, should the line be stored?
|
117
121
|
elsif rule['store_lines']
|
118
122
|
match = false
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
break
|
124
|
-
end
|
123
|
+
rule['ignore_lines']&.each do |pat|
|
124
|
+
if line =~ pat
|
125
|
+
match = true
|
126
|
+
break
|
125
127
|
end
|
126
128
|
end
|
127
129
|
@rule_lines_buffer << line.chomp unless match
|
@@ -133,6 +135,7 @@ module U3d
|
|
133
135
|
ruleset.each do |rn, r|
|
134
136
|
pattern = r['start_pattern']
|
135
137
|
next unless line =~ pattern
|
138
|
+
|
136
139
|
@active_rule = rn if r['end_pattern']
|
137
140
|
match = line.match(pattern)
|
138
141
|
@context = match.names.map(&:to_sym).zip(match.captures).to_h
|
@@ -145,10 +148,12 @@ module U3d
|
|
145
148
|
match = false
|
146
149
|
r['fetch_first_line_not_matching'].each do |pat|
|
147
150
|
next unless l =~ pat
|
151
|
+
|
148
152
|
match = true
|
149
153
|
break
|
150
154
|
end
|
151
155
|
next if match
|
156
|
+
|
152
157
|
fetched_line = l
|
153
158
|
break
|
154
159
|
end
|
@@ -196,7 +201,7 @@ module U3d
|
|
196
201
|
if @active_rule
|
197
202
|
# Active rule should be finished
|
198
203
|
# If it is still active during phase change, it means that something went wrong
|
199
|
-
context = @lines_memory.map { |l| "> #{l}" }.join
|
204
|
+
context = @lines_memory.map { |l| "> #{l}" }.join
|
200
205
|
UI.error("[#{@active_phase}] Could not finish active rule '#{@active_rule}'. Aborting it. Context:\n#{context}")
|
201
206
|
|
202
207
|
U3d::FailureReporter.report(
|
@@ -237,26 +242,25 @@ module U3d
|
|
237
242
|
message
|
238
243
|
end
|
239
244
|
|
240
|
-
def parse_rule(
|
241
|
-
return false unless
|
242
|
-
return false if
|
243
|
-
|
244
|
-
|
245
|
-
if
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
if r['fetch_line_at_index'] || r['fetch_first_line_not_matching']
|
252
|
-
r['fetched_line_pattern'] = Regexp.new r['fetched_line_pattern'] if r['fetched_line_pattern']
|
245
|
+
def parse_rule(rule)
|
246
|
+
return false unless rule['active']
|
247
|
+
return false if rule['start_pattern'].nil?
|
248
|
+
|
249
|
+
rule['start_pattern'] = Regexp.new rule['start_pattern']
|
250
|
+
rule['end_pattern'] = Regexp.new rule['end_pattern'] if rule['end_pattern']
|
251
|
+
if rule['fetch_line_at_index']
|
252
|
+
rule.delete('fetch_line_at_index') if rule['fetch_line_at_index'] >= MEMORY_SIZE
|
253
|
+
rule.delete('fetch_line_at_index') if rule['fetch_line_at_index'] <= 0
|
254
|
+
elsif rule['fetch_first_line_not_matching']
|
255
|
+
rule['fetch_first_line_not_matching'].map! { |pat| Regexp.new pat }
|
253
256
|
end
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
257
|
+
rule['fetched_line_pattern'] = Regexp.new rule['fetched_line_pattern'] if (rule['fetch_line_at_index'] || rule['fetch_first_line_not_matching']) && (rule['fetched_line_pattern'])
|
258
|
+
rule['type'] = 'important' if rule['type'] == 'warning'
|
259
|
+
rule['type'] = 'message' if rule['type'] && rule['type'] != 'error' && rule['type'] != 'important' && rule['type'] != 'success'
|
260
|
+
rule['type'] ||= 'message'
|
261
|
+
rule['ignore_lines']&.map! { |pat| Regexp.new pat }
|
258
262
|
true
|
259
263
|
end
|
260
264
|
end
|
261
|
-
# rubocop:enable ClassLength, PerceivedComplexity, BlockNesting
|
265
|
+
# rubocop:enable Metrics/ClassLength, Metrics/PerceivedComplexity, Metrics/BlockNesting
|
262
266
|
end
|
data/lib/u3d/unity_license.rb
CHANGED
data/lib/u3d/unity_module.rb
CHANGED
data/lib/u3d/unity_project.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
|
#
|
@@ -46,9 +48,10 @@ module U3d
|
|
46
48
|
require 'yaml'
|
47
49
|
project_version = File.join(project_settings_path, 'ProjectVersion.txt')
|
48
50
|
return nil unless File.exist? project_version
|
51
|
+
|
49
52
|
yaml = YAML.safe_load(File.read(project_version))
|
50
53
|
version = yaml['m_EditorVersion']
|
51
|
-
version.gsub
|
54
|
+
version = version.gsub(/(\d+\.\d+\.\d+)(?:x)?(\w\d+)(?:Linux)?/, '\1\2') if Helper.linux?
|
52
55
|
version
|
53
56
|
end
|
54
57
|
end
|