u3d 1.2.2 → 1.3.1

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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +33 -10
  3. data/.github/workflows/ci.yml +35 -0
  4. data/.github_changelog_generator +3 -1
  5. data/.gitignore +1 -0
  6. data/.rubocop.yml +15 -3
  7. data/CHANGELOG.md +83 -11
  8. data/Gemfile.lock +147 -87
  9. data/Rakefile +20 -12
  10. data/appveyor.yml +25 -6
  11. data/examples/Example1/Gemfile +4 -2
  12. data/examples/Example1/Gemfile.lock +8 -6
  13. data/examples/Example1/Rakefile +2 -0
  14. data/examples/Example1/fastlane/Fastfile +2 -0
  15. data/examples/Example2/Gemfile +4 -2
  16. data/examples/Example2/Gemfile.lock +12 -7
  17. data/examples/Example2/fastlane/Fastfile +2 -0
  18. data/exe/u3d +3 -1
  19. data/lib/u3d/asset.rb +6 -2
  20. data/lib/u3d/cache.rb +14 -10
  21. data/lib/u3d/commands.rb +15 -11
  22. data/lib/u3d/commands_generator.rb +6 -4
  23. data/lib/u3d/compatibility.rb +2 -0
  24. data/lib/u3d/download_validator.rb +6 -3
  25. data/lib/u3d/downloader.rb +12 -8
  26. data/lib/u3d/failure_reporter.rb +4 -3
  27. data/lib/u3d/hub_modules_parser.rb +24 -7
  28. data/lib/u3d/ini_modules_parser.rb +10 -32
  29. data/lib/u3d/installation.rb +77 -66
  30. data/lib/u3d/installer.rb +46 -33
  31. data/lib/u3d/log_analyzer.rb +31 -27
  32. data/lib/u3d/unity_license.rb +2 -0
  33. data/lib/u3d/unity_module.rb +2 -0
  34. data/lib/u3d/unity_project.rb +4 -1
  35. data/lib/u3d/unity_runner.rb +12 -10
  36. data/lib/u3d/unity_version_definition.rb +3 -0
  37. data/lib/u3d/unity_version_number.rb +8 -2
  38. data/lib/u3d/unity_versions.rb +28 -23
  39. data/lib/u3d/utils.rb +86 -15
  40. data/lib/u3d/version.rb +8 -6
  41. data/lib/u3d.rb +13 -0
  42. data/lib/u3d_core/admin_tools.rb +2 -0
  43. data/lib/u3d_core/command_executor.rb +11 -7
  44. data/lib/u3d_core/command_runner.rb +17 -19
  45. data/lib/u3d_core/core_ext/hash.rb +2 -0
  46. data/lib/u3d_core/core_ext/operating_system_symbol.rb +3 -0
  47. data/lib/u3d_core/core_ext/string.rb +2 -0
  48. data/lib/u3d_core/credentials.rb +9 -7
  49. data/lib/u3d_core/env.rb +3 -0
  50. data/lib/u3d_core/globals.rb +7 -7
  51. data/lib/u3d_core/helper.rb +6 -4
  52. data/lib/u3d_core/ui/disable_colors.rb +2 -0
  53. data/lib/u3d_core/ui/implementations/shell.rb +8 -5
  54. data/lib/u3d_core/ui/interface.rb +3 -0
  55. data/lib/u3d_core/ui/ui.rb +5 -4
  56. data/lib/u3d_core/update_checker/changelog.rb +4 -0
  57. data/lib/u3d_core/update_checker/update_checker.rb +7 -8
  58. data/lib/u3d_core/version.rb +2 -0
  59. data/lib/u3d_core.rb +2 -0
  60. data/u3d.gemspec +19 -9
  61. metadata +101 -29
@@ -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
- U3D_DO_NOT_MOVE = ".u3d_do_not_move".freeze
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 PlaybackEngineUtils
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
- PlaybackEngineUtils.list_module_configs(root_path).each do |mpath|
158
- pack << PlaybackEngineUtils.module_name(mpath)
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\.abfp]+_[0-9a-f]{12}/
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.select { |l| l =~ STRINGS_FULL_VERSION_MATCHER }
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
- # I don't find an easy way to extract the version on Linux
240
- path = "#{root_path}/Editor/Data/"
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
- PlaybackEngineUtils.list_module_configs(path).each do |mpath|
271
- pack << PlaybackEngineUtils.module_name(mpath)
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
- @uvf ||= string_file_info('Unity Version', @exe_path)
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 = PlaybackEngineUtils.list_module_configs(path).first
378
+ package = IvyPlaybackEngineUtils.list_module_configs(path).first
372
379
  raise "Couldn't find a module under #{path}" unless package
373
- PlaybackEngineUtils.unity_version(package)
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 => ex
388
- UI.error "Unable to retrieve the editor logfile: #{ex}"
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
- PlaybackEngineUtils.list_module_configs(path).each do |mpath|
407
- pack << PlaybackEngineUtils.module_name(mpath)
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/'.freeze
34
- DEFAULT_MAC_INSTALL = '/'.freeze
35
- DEFAULT_WINDOWS_INSTALL = 'C:/Program Files/'.freeze
36
- UNITY_DIR = "Unity_%<version>s".freeze
37
- UNITY_DIR_LONG = "Unity_%<version>s_%<build_number>s".freeze
38
- UNITY_DIR_LINUX = "unity-editor-%<version>s".freeze
39
- UNITY_DIR_LINUX_LONG = "unity-editor-%<version>s_%<build_number>s".freeze
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 'Installing with ' + file
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 && info.rename_from && info.rename_to
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 + '/*').each { |path| FileUtils.mv(path, rename_to) }
140
+ Dir.glob("#{rename_from}/*").each { |path| FileUtils.mv(path, rename_to) }
135
141
  end
136
142
  end
137
143
 
@@ -139,7 +145,7 @@ module U3d
139
145
  end
140
146
 
141
147
  def package_destination(info, unity_root_path)
142
- if info && info.destination
148
+ if info&.destination
143
149
  info.destination.gsub(/{UNITY_PATH}/, unity_root_path)
144
150
  else
145
151
  unity_root_path
@@ -151,14 +157,15 @@ module U3d
151
157
  # Returns an array of ruby style paths
152
158
  def extra_installation_paths
153
159
  return [] if ENV['U3D_EXTRA_PATHS'].nil?
160
+
154
161
  ENV['U3D_EXTRA_PATHS'].strip.split(File::PATH_SEPARATOR).map { |p| File.expand_path p }
155
162
  end
156
163
 
157
- def find_installations_with_path(default_root_path: '', postfix: [])
164
+ def find_installations_with_path(default_root_path: '', postfix: [], &block)
158
165
  ([default_root_path] | extra_installation_paths).map do |path|
159
166
  UI.verbose "Looking for installed Unity version under #{path}"
160
167
  pattern = File.join([path] + postfix)
161
- Dir.glob(pattern).map { |found_path| yield found_path }
168
+ Dir.glob(pattern).map(&block)
162
169
  end.flatten
163
170
  end
164
171
  end
@@ -189,14 +196,17 @@ module U3d
189
196
  end
190
197
 
191
198
  def install(file_path, version, installation_path: nil, info: nil)
192
- # rubocop:enable UnusedMethodArgument
193
199
  extension = File.extname(file_path)
194
- 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
+
195
202
  path = installation_path || DEFAULT_MAC_INSTALL
196
- if extension == '.po'
203
+ case extension
204
+ when '.po'
197
205
  install_po(file_path, version, info: info)
198
- elsif extension == '.zip'
206
+ when '.zip'
199
207
  install_zip(file_path, version, info: info)
208
+ when '.dmg'
209
+ UI.important "Skipping installation of #{file_path} for now"
200
210
  else
201
211
  install_pkg(file_path, version: version, target_path: path)
202
212
  end
@@ -276,7 +286,7 @@ module U3d
276
286
  end
277
287
  end
278
288
 
279
- # rubocop:disable ClassLength
289
+ # rubocop:disable Metrics/ClassLength
280
290
  class LinuxInstaller < BaseInstaller
281
291
  def sanitize_install(unity, long: false, dry_run: false)
282
292
  source_path = File.expand_path(unity.root_path)
@@ -294,26 +304,26 @@ module U3d
294
304
  paths.map { |path| LinuxInstallation.new(root_path: path) }
295
305
  end
296
306
 
297
- # rubocop:disable PerceivedComplexity
298
307
  def install(file_path, version, installation_path: nil, info: nil)
299
- # rubocop:enable UnusedMethodArgument, PerceivedComplexity
300
308
  extension = File.extname(file_path)
301
309
 
302
310
  raise "Installation of #{extension} files is not supported on Linux" unless ['.zip', '.po', '.sh', '.xz', '.pkg'].include? extension
303
- if extension == '.sh'
311
+
312
+ case extension
313
+ when '.sh'
304
314
  path = installation_path || DEFAULT_LINUX_INSTALL
305
315
  install_sh(file_path, installation_path: path)
306
- elsif extension == '.xz'
316
+ when '.xz'
307
317
  new_path = File.join(DEFAULT_LINUX_INSTALL, format(UNITY_DIR_LINUX, version: version))
308
318
  path = installation_path || new_path
309
319
  install_xz(file_path, installation_path: path)
310
- elsif extension == '.pkg'
320
+ when '.pkg'
311
321
  new_path = File.join(DEFAULT_LINUX_INSTALL, format(UNITY_DIR_LINUX, version: version))
312
322
  path = installation_path || new_path
313
323
  install_pkg(file_path, installation_path: path)
314
- elsif extension == '.po'
324
+ when '.po'
315
325
  install_po(file_path, version, info: info)
316
- elsif extension == '.zip'
326
+ when '.zip'
317
327
  install_zip(file_path, version, info: info)
318
328
  end
319
329
 
@@ -397,6 +407,7 @@ module U3d
397
407
 
398
408
  def pkg_install_path(unity_root_path, pinfo_path)
399
409
  raise "PackageInfo not found under #{pinfo_path}" unless File.exist? pinfo_path
410
+
400
411
  pinfo = File.read(pinfo_path)
401
412
  require 'rexml/document'
402
413
  d = REXML::Document.new(pinfo)
@@ -412,6 +423,7 @@ module U3d
412
423
  else
413
424
  install_location = d.root.attributes['install-location']
414
425
  raise "Not sure how to install this module with identifier #{identifier} install-location: #{install_location}" unless install_location.start_with? '/Applications/Unity/'
426
+
415
427
  install_location.gsub(%(\/Applications\/Unity), "#{unity_root_path}/Editor/Data")
416
428
  end
417
429
  end
@@ -440,7 +452,7 @@ module U3d
440
452
  paths
441
453
  end
442
454
  end
443
- # rubocop:enable ClassLength
455
+ # rubocop:enable Metrics/ClassLength
444
456
 
445
457
  class WindowsInstaller < BaseInstaller
446
458
  def sanitize_install(unity, long: false, dry_run: false)
@@ -468,10 +480,12 @@ module U3d
468
480
  def install(file_path, version, installation_path: nil, info: nil)
469
481
  extension = File.extname(file_path)
470
482
  raise "Installation of #{extension} files is not supported on Windows" unless %w[.po .zip .exe .msi].include? extension
483
+
471
484
  path = installation_path || File.join(DEFAULT_WINDOWS_INSTALL, format(UNITY_DIR, version: version))
472
- if extension == '.po'
485
+ case extension
486
+ when '.po'
473
487
  install_po(file_path, version, info: info)
474
- elsif extension == '.zip'
488
+ when '.zip'
475
489
  install_zip(file_path, version, info: info)
476
490
  else
477
491
  install_exe(file_path, installation_path: path, info: info)
@@ -487,14 +501,14 @@ module U3d
487
501
  if info.command
488
502
  command = info.command
489
503
  if /msiexec/ =~ command
490
- command.sub!(/{FILENAME}/, '"' + U3dCore::Helper.windows_path(file_path) + '"')
504
+ command.sub!(/{FILENAME}/, "\"#{U3dCore::Helper.windows_path(file_path)}\"")
491
505
  else
492
506
  command.sub!(/{FILENAME}/, file_path.argescape)
493
507
  end
494
508
  command.sub!(/{INSTDIR}/, final_path)
495
509
  command.sub!(/{DOCDIR}/, final_path)
496
510
  command.sub!(/{MODULEDIR}/, final_path)
497
- command.sub!(%r{\/D=}, '/S /D=') unless %r{\/S} =~ command
511
+ command.sub!(%r{/D=}, '/S /D=') unless %r{/S} =~ command
498
512
  end
499
513
  command ||= file_path.argescape
500
514
  U3dCore::CommandExecutor.execute(command: command, admin: true)
@@ -570,9 +584,8 @@ module U3d
570
584
  raise 'Cannot install dependencies on your Linux distribution'
571
585
  end
572
586
 
573
- if UI.interactive?
574
- return unless UI.confirm "Install dependencies? (#{DEPENDENCIES.length} dependency(ies) to install)"
575
- end
587
+ return if UI.interactive? && !(UI.confirm "Install dependencies? (#{DEPENDENCIES.length} dependency(ies) to install)")
588
+
576
589
  U3dCore::CommandExecutor.execute(command: "#{prefix} #{DEPENDENCIES.join(' ')}", admin: true)
577
590
  end
578
591
  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
  #
@@ -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('../../../config/log_rules.json', __FILE__)
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
- if rule['ignore_lines']
120
- rule['ignore_lines'].each do |pat|
121
- if line =~ pat
122
- match = true
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(r)
241
- return false unless r['active']
242
- return false if r['start_pattern'].nil?
243
- r['start_pattern'] = Regexp.new r['start_pattern']
244
- r['end_pattern'] = Regexp.new r['end_pattern'] if r['end_pattern']
245
- if r['fetch_line_at_index']
246
- r.delete('fetch_line_at_index') if r['fetch_line_at_index'] >= MEMORY_SIZE
247
- r.delete('fetch_line_at_index') if r['fetch_line_at_index'] <= 0
248
- elsif r['fetch_first_line_not_matching']
249
- r['fetch_first_line_not_matching'].map! { |pat| Regexp.new pat }
250
- end
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
- r['type'] = 'important' if r['type'] == 'warning'
255
- r['type'] = 'message' if r['type'] && r['type'] != 'error' && r['type'] != 'important' && r['type'] != 'success'
256
- r['type'] ||= 'message'
257
- r['ignore_lines'].map! { |pat| Regexp.new pat } if r['ignore_lines']
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
@@ -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
  #
@@ -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
  #
@@ -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!(/(\d+\.\d+\.\d+)(?:x)?(\w\d+)(?:Linux)?/, '\1\2') if Helper.linux?
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