u3d 1.2.1 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|