u3d 1.2.2 → 1.3.1

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