u3d 1.2.3 → 1.3.0

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 +5 -5
  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 +62 -11
  8. data/Gemfile.lock +147 -87
  9. data/Rakefile +12 -7
  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 +14 -9
  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 -8
  29. data/lib/u3d/installation.rb +31 -49
  30. data/lib/u3d/installer.rb +44 -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 +82 -15
  40. data/lib/u3d/version.rb +8 -6
  41. data/lib/u3d.rb +2 -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 -30
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,15 +196,16 @@ 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
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)
200
- elsif extension == '.dmg'
208
+ when '.dmg'
201
209
  UI.important "Skipping installation of #{file_path} for now"
202
210
  else
203
211
  install_pkg(file_path, version: version, target_path: path)
@@ -278,7 +286,7 @@ module U3d
278
286
  end
279
287
  end
280
288
 
281
- # rubocop:disable ClassLength
289
+ # rubocop:disable Metrics/ClassLength
282
290
  class LinuxInstaller < BaseInstaller
283
291
  def sanitize_install(unity, long: false, dry_run: false)
284
292
  source_path = File.expand_path(unity.root_path)
@@ -296,26 +304,26 @@ module U3d
296
304
  paths.map { |path| LinuxInstallation.new(root_path: path) }
297
305
  end
298
306
 
299
- # rubocop:disable PerceivedComplexity
300
307
  def install(file_path, version, installation_path: nil, info: nil)
301
- # rubocop:enable UnusedMethodArgument, PerceivedComplexity
302
308
  extension = File.extname(file_path)
303
309
 
304
310
  raise "Installation of #{extension} files is not supported on Linux" unless ['.zip', '.po', '.sh', '.xz', '.pkg'].include? extension
305
- if extension == '.sh'
311
+
312
+ case extension
313
+ when '.sh'
306
314
  path = installation_path || DEFAULT_LINUX_INSTALL
307
315
  install_sh(file_path, installation_path: path)
308
- elsif extension == '.xz'
316
+ when '.xz'
309
317
  new_path = File.join(DEFAULT_LINUX_INSTALL, format(UNITY_DIR_LINUX, version: version))
310
318
  path = installation_path || new_path
311
319
  install_xz(file_path, installation_path: path)
312
- elsif extension == '.pkg'
320
+ when '.pkg'
313
321
  new_path = File.join(DEFAULT_LINUX_INSTALL, format(UNITY_DIR_LINUX, version: version))
314
322
  path = installation_path || new_path
315
323
  install_pkg(file_path, installation_path: path)
316
- elsif extension == '.po'
324
+ when '.po'
317
325
  install_po(file_path, version, info: info)
318
- elsif extension == '.zip'
326
+ when '.zip'
319
327
  install_zip(file_path, version, info: info)
320
328
  end
321
329
 
@@ -399,6 +407,7 @@ module U3d
399
407
 
400
408
  def pkg_install_path(unity_root_path, pinfo_path)
401
409
  raise "PackageInfo not found under #{pinfo_path}" unless File.exist? pinfo_path
410
+
402
411
  pinfo = File.read(pinfo_path)
403
412
  require 'rexml/document'
404
413
  d = REXML::Document.new(pinfo)
@@ -414,6 +423,7 @@ module U3d
414
423
  else
415
424
  install_location = d.root.attributes['install-location']
416
425
  raise "Not sure how to install this module with identifier #{identifier} install-location: #{install_location}" unless install_location.start_with? '/Applications/Unity/'
426
+
417
427
  install_location.gsub(%(\/Applications\/Unity), "#{unity_root_path}/Editor/Data")
418
428
  end
419
429
  end
@@ -442,7 +452,7 @@ module U3d
442
452
  paths
443
453
  end
444
454
  end
445
- # rubocop:enable ClassLength
455
+ # rubocop:enable Metrics/ClassLength
446
456
 
447
457
  class WindowsInstaller < BaseInstaller
448
458
  def sanitize_install(unity, long: false, dry_run: false)
@@ -470,10 +480,12 @@ module U3d
470
480
  def install(file_path, version, installation_path: nil, info: nil)
471
481
  extension = File.extname(file_path)
472
482
  raise "Installation of #{extension} files is not supported on Windows" unless %w[.po .zip .exe .msi].include? extension
483
+
473
484
  path = installation_path || File.join(DEFAULT_WINDOWS_INSTALL, format(UNITY_DIR, version: version))
474
- if extension == '.po'
485
+ case extension
486
+ when '.po'
475
487
  install_po(file_path, version, info: info)
476
- elsif extension == '.zip'
488
+ when '.zip'
477
489
  install_zip(file_path, version, info: info)
478
490
  else
479
491
  install_exe(file_path, installation_path: path, info: info)
@@ -489,14 +501,14 @@ module U3d
489
501
  if info.command
490
502
  command = info.command
491
503
  if /msiexec/ =~ command
492
- command.sub!(/{FILENAME}/, '"' + U3dCore::Helper.windows_path(file_path) + '"')
504
+ command.sub!(/{FILENAME}/, "\"#{U3dCore::Helper.windows_path(file_path)}\"")
493
505
  else
494
506
  command.sub!(/{FILENAME}/, file_path.argescape)
495
507
  end
496
508
  command.sub!(/{INSTDIR}/, final_path)
497
509
  command.sub!(/{DOCDIR}/, final_path)
498
510
  command.sub!(/{MODULEDIR}/, final_path)
499
- command.sub!(%r{\/D=}, '/S /D=') unless %r{\/S} =~ command
511
+ command.sub!(%r{/D=}, '/S /D=') unless %r{/S} =~ command
500
512
  end
501
513
  command ||= file_path.argescape
502
514
  U3dCore::CommandExecutor.execute(command: command, admin: true)
@@ -572,9 +584,8 @@ module U3d
572
584
  raise 'Cannot install dependencies on your Linux distribution'
573
585
  end
574
586
 
575
- if UI.interactive?
576
- return unless UI.confirm "Install dependencies? (#{DEPENDENCIES.length} dependency(ies) to install)"
577
- end
587
+ return if UI.interactive? && !(UI.confirm "Install dependencies? (#{DEPENDENCIES.length} dependency(ies) to install)")
588
+
578
589
  U3dCore::CommandExecutor.execute(command: "#{prefix} #{DEPENDENCIES.join(' ')}", admin: true)
579
590
  end
580
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
@@ -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
  #
@@ -45,6 +47,7 @@ module U3d
45
47
  if log_file
46
48
  tail_thread = start_tail_thread(log_file, output_callback)
47
49
  return unless tail_thread.status
50
+
48
51
  tail_thread.run
49
52
  end
50
53
 
@@ -78,9 +81,9 @@ module U3d
78
81
  end
79
82
 
80
83
  class << self
81
- # rubocop:disable MethodName
84
+ # rubocop:disable Naming/MethodName
82
85
  def find_logFile_in_args(args)
83
- # rubocop:enable MethodName
86
+ # rubocop:enable Naming/MethodName
84
87
  find_arg_in_args('-logFile', args)
85
88
  end
86
89
 
@@ -90,6 +93,7 @@ module U3d
90
93
 
91
94
  def find_arg_in_args(arg_to_find, args)
92
95
  raise 'Only arguments of type array supported right now' unless args.is_a?(Array)
96
+
93
97
  args.each_with_index do |arg, index|
94
98
  return args[index + 1] if arg == arg_to_find && index < args.count - 1
95
99
  end
@@ -101,12 +105,10 @@ module U3d
101
105
 
102
106
  def start_tail_thread(log_file, output_callback)
103
107
  tail_thread = Thread.new do
104
- begin
105
- pipe(log_file) { |line| output_callback.call(line) }
106
- rescue StandardError => e
107
- UI.error "Failure while trying to pipe #{log_file}: #{e.message}"
108
- e.backtrace.each { |l| UI.error " #{l}" }
109
- end
108
+ pipe(log_file) { |line| output_callback.call(line) }
109
+ rescue StandardError => e
110
+ UI.error "Failure while trying to pipe #{log_file}: #{e.message}"
111
+ e.backtrace.each { |l| UI.error " #{l}" }
110
112
  end
111
113
 
112
114
  # Wait for tail_thread setup to be complete
@@ -114,14 +116,14 @@ module U3d
114
116
  tail_thread
115
117
  end
116
118
 
117
- def pipe(file)
119
+ def pipe(file, &block)
118
120
  File.open(file, 'r') do |f|
119
121
  f.extend File::Tail
120
122
  f.interval = 0.1
121
123
  f.max_interval = 0.4
122
124
  f.backward 0
123
125
  Thread.stop
124
- f.tail { |l| yield l }
126
+ f.tail(&block)
125
127
  end
126
128
  end
127
129
  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
  #
@@ -51,6 +53,7 @@ module U3d
51
53
 
52
54
  def [](package)
53
55
  return nil unless available_package? package
56
+
54
57
  @packages.find { |pack| pack.id == package.downcase }
55
58
  end
56
59
 
@@ -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
  #
@@ -24,14 +26,14 @@ require 'u3d/utils'
24
26
 
25
27
  module U3d
26
28
  class UnityVersionNumber
27
- attr_reader :unity_version
28
- attr_reader :parts
29
+ attr_reader :unity_version, :parts
29
30
 
30
31
  def initialize(version)
31
32
  @unity_version = version
32
33
  parsed = Utils.parse_unity_version(@unity_version)
33
34
  parsed.each_with_index do |val, index|
34
35
  next if val.nil? || (index == 3)
36
+
35
37
  parsed[index] = val.to_i
36
38
  end
37
39
  @parts = parsed
@@ -52,12 +54,16 @@ module U3d
52
54
  def <=>(other)
53
55
  comp = @version.parts[0] <=> other.version.parts[0]
54
56
  return comp if comp.nonzero?
57
+
55
58
  comp = @version.parts[1] <=> other.version.parts[1]
56
59
  return comp if comp.nonzero?
60
+
57
61
  comp = @version.parts[2] <=> other.version.parts[2]
58
62
  return comp if comp.nonzero?
63
+
59
64
  comp = RELEASE_LETTER_STRENGTH[@version.parts[3].to_sym] <=> RELEASE_LETTER_STRENGTH[other.version.parts[3].to_sym]
60
65
  return comp if comp.nonzero?
66
+
61
67
  return @version.parts[4] <=> other.version.parts[4]
62
68
  end
63
69
 
@@ -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
  #
@@ -47,6 +49,7 @@ module U3d
47
49
  def fetch_cookie
48
50
  UI.verbose "FetchCookie? #{@cookie}"
49
51
  return @cookie if @cookie
52
+
50
53
  cookie_str = ''
51
54
  url = 'https://forum.unity.com/forums/linux-editor.93/' # a page that triggers cookies
52
55
  uri = URI(url)
@@ -56,15 +59,15 @@ module U3d
56
59
  response = http.request request
57
60
 
58
61
  case response
59
- when Net::HTTPSuccess then
62
+ when Net::HTTPSuccess
60
63
  UI.verbose "unexpected result"
61
- when Net::HTTPRedirection then
64
+ when Net::HTTPRedirection
62
65
  # A session must be opened with the server before accessing forum
63
66
  res = nil
64
67
  cookie_str = ''
65
68
  # Store the name and value of the cookies returned by the server
66
69
  response['set-cookie'].gsub(/\s+/, '').split(',').each do |c|
67
- cookie_str << c.split(';', 2)[0] + '; '
70
+ cookie_str << ("#{c.split(';', 2)[0]}; ")
68
71
  end
69
72
  cookie_str.chomp!('; ')
70
73
 
@@ -78,6 +81,7 @@ module U3d
78
81
  end
79
82
 
80
83
  raise 'Unexpected result' unless res.is_a? Net::HTTPRedirection
84
+
81
85
  # It should be a redirection to the forum to perform authentication
82
86
  uri = URI(res['location'])
83
87
  UI.verbose "Redirecting to #{uri}"
@@ -90,50 +94,51 @@ module U3d
90
94
  raise 'Unable to establish a session with Unity forum' unless res.is_a? Net::HTTPRedirection
91
95
 
92
96
  UI.verbose "Found cookie_str #{cookie_str}"
93
- cookie_str << '; ' + res['set-cookie'].gsub(/\s+/, '').split(';', 2)[0]
97
+ cookie_str << ("; #{res['set-cookie'].gsub(/\s+/, '').split(';', 2)[0]}")
94
98
  end
95
99
  end
96
100
  UI.verbose "Found @cookie #{cookie_str}"
97
101
  @cookie = cookie_str
98
102
  end
99
103
  end
104
+
100
105
  # Takes care of fectching versions and version list
101
106
  module UnityVersions
102
107
  #####################################################
103
108
  # @!group URLS: Locations to fetch information from
104
109
  #####################################################
105
110
  # URL for the forum thread listing all the Linux releases
106
- UNITY_LINUX_DOWNLOADS = 'https://forum.unity.com/threads/unity-on-linux-release-notes-and-known-issues.350256/'.freeze
111
+ UNITY_LINUX_DOWNLOADS = 'https://forum.unity.com/threads/unity-on-linux-release-notes-and-known-issues.350256/'
107
112
  # URL for the main releases for Windows and Macintosh
108
- UNITY_DOWNLOADS = 'https://unity3d.com/get-unity/download/archive'.freeze
113
+ UNITY_DOWNLOADS = 'https://unity3d.com/get-unity/download/archive'
109
114
  # URL for the LTS releases for Windows and Macintosh
110
- UNITY_LTSES = 'https://unity3d.com/unity/qa/lts-releases'.freeze
115
+ UNITY_LTSES = 'https://unity3d.com/unity/qa/lts-releases'
111
116
  # URL for the patch releases for Windows and Macintosh
112
- UNITY_PATCHES = 'https://unity3d.com/unity/qa/patch-releases'.freeze
117
+ UNITY_PATCHES = 'https://unity3d.com/unity/qa/patch-releases'
113
118
  # URL for the beta releases list, they need to be accessed after
114
- UNITY_BETAS = 'https://unity3d.com/unity/beta/archive'.freeze
119
+ UNITY_BETAS = 'https://unity3d.com/unity/beta/archive'
115
120
  # URL for a specific beta, takes into parameter a version string (%s)
116
- UNITY_BETA_URL = 'https://unity3d.com/unity/beta/unity%<version>s'.freeze
121
+ UNITY_BETA_URL = 'https://unity3d.com/unity/beta/unity%<version>s'
117
122
  # URL for latest releases listing (since Unity 2017.1.5f1), takes into parameter os (windows => win32, mac => darwin)
118
- UNITY_LATEST_JSON_URL = 'https://public-cdn.cloud.unity3d.com/hub/prod/releases-%<os>s.json'.freeze
123
+ UNITY_LATEST_JSON_URL = 'https://public-cdn.cloud.unity3d.com/hub/prod/releases-%<os>s.json'
119
124
 
120
125
  #####################################################
121
126
  # @!group REGEX: expressions to interpret data
122
127
  #####################################################
123
128
  # Captures a version and its base url
124
- LINUX_DOWNLOAD = %r{['"](https?:\/\/[\w/\.-]+/[0-9a-f\+]{12,13}\/)(.\/)?UnitySetup-(\d+\.\d+\.\d+\w\d+)['"]}
129
+ LINUX_DOWNLOAD = %r{['"](https?://[\w/.-]+/[0-9a-f+]{12,13}/)(./)?UnitySetup-(\d+\.\d+\.\d+\w\d+)['"]}.freeze
125
130
 
126
- MAC_WIN_SHADERS = %r{"(https?://[\w/\.-]+/[0-9a-f\+]{12,13}/)builtin_shaders-(\d+\.\d+\.\d+\w\d+)\.?\w+"}
127
- LINUX_INSTALLER = %r{(https?://[\w/\.-]+/[0-9a-f\+]{12,13}/)LinuxEditorInstaller/Unity.tar.xz}
131
+ MAC_WIN_SHADERS = %r{"(https?://[\w/.-]+/[0-9a-f+]{12,13}/)builtin_shaders-(\d+\.\d+\.\d+\w\d+)\.?\w+"}.freeze
132
+ LINUX_INSTALLER = %r{(https?://[\w/.-]+/[0-9a-f+]{12,13}/)LinuxEditorInstaller/Unity.tar.xz}.freeze
128
133
 
129
- LINUX_DOWNLOAD_DATED = %r{"(https?://[\w/\._-]+/unity\-editor\-installer\-(\d+\.\d+\.\d+\w\d+).*\.sh)"}
130
- LINUX_DOWNLOAD_RECENT_PAGE = %r{"(https?://beta\.unity3d\.com/download/[a-zA-Z0-9/\.\+]+/public_download\.html)"}
131
- LINUX_DOWNLOAD_RECENT_FILE = %r{'(https?://beta\.unity3d\.com/download/[a-zA-Z0-9/\.\+]+/unity\-editor\-installer\-(\d+\.\d+\.\d+(?:x)?\w\d+).*\.sh)'}
134
+ LINUX_DOWNLOAD_DATED = %r{"(https?://[\w/._-]+/unity-editor-installer-(\d+\.\d+\.\d+\w\d+).*\.sh)"}.freeze
135
+ LINUX_DOWNLOAD_RECENT_PAGE = %r{"(https?://beta\.unity3d\.com/download/[a-zA-Z0-9/.+]+/public_download\.html)"}.freeze
136
+ LINUX_DOWNLOAD_RECENT_FILE = %r{'(https?://beta\.unity3d\.com/download/[a-zA-Z0-9/.+]+/unity-editor-installer-(\d+\.\d+\.\d+(?:x)?\w\d+).*\.sh)'}.freeze
132
137
  # Captures a beta version in html page
133
- UNITY_BETAVERSION_REGEX = %r{\/unity\/beta\/unity(\d+\.\d+\.\d+\w\d+)"}
134
- UNITY_EXTRA_DOWNLOAD_REGEX = %r{"(https?:\/\/[\w\/.-]+\.unity3d\.com\/(\w+))\/[a-zA-Z\/.-]+\/download.html"}
138
+ UNITY_BETAVERSION_REGEX = %r{/unity/beta/unity(\d+\.\d+\.\d+\w\d+)"}.freeze
139
+ UNITY_EXTRA_DOWNLOAD_REGEX = %r{"(https?://[\w/.-]+\.unity3d\.com/(\w+))/[a-zA-Z/.-]+/download.html"}.freeze
135
140
  # For the latest releases fetched from json
136
- UNITY_LATEST_JSON = %r{(https?://[\w/\.-]+/[0-9a-f\+]{12,13}/)}
141
+ UNITY_LATEST_JSON = %r{(https?://[\w/.-]+/[0-9a-f+]{12,13}/)}.freeze
137
142
 
138
143
  class << self
139
144
  def list_available(os: nil)
@@ -191,7 +196,7 @@ module U3d
191
196
  end
192
197
 
193
198
  class LinuxVersions
194
- JSON_OS = 'linux'.freeze
199
+ JSON_OS = 'linux'
195
200
 
196
201
  @unity_forums = U3d::UnityForums.new
197
202
  class << self
@@ -300,7 +305,7 @@ module U3d
300
305
  end
301
306
 
302
307
  class MacVersions
303
- JSON_OS = 'darwin'.freeze
308
+ JSON_OS = 'darwin'
304
309
 
305
310
  class << self
306
311
  def list_available
@@ -312,7 +317,7 @@ module U3d
312
317
  end
313
318
 
314
319
  class WindowsVersions
315
- JSON_OS = 'win32'.freeze
320
+ JSON_OS = 'win32'
316
321
 
317
322
  class << self
318
323
  def list_available