u3d 0.9.3 → 0.9.4

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.
@@ -0,0 +1,167 @@
1
+ ## --- BEGIN LICENSE BLOCK ---
2
+ # Copyright (c) 2016-present WeWantToKnow AS
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in all
12
+ # copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ # SOFTWARE.
21
+ ## --- END LICENSE BLOCK ---
22
+
23
+ require 'u3d/utils'
24
+
25
+ module U3d
26
+ UNITY_DIR_CHECK = /Unity_\d+\.\d+\.\d+[a-z]\d+/
27
+ UNITY_DIR_CHECK_LINUX = /unity-editor-\d+\.\d+\.\d+[a-z]\d+\z/
28
+
29
+ class Installation
30
+ def self.create(path: nil)
31
+ if Helper.mac?
32
+ MacInstallation.new path
33
+ elsif Helper.linux?
34
+ LinuxInstallation.new path
35
+ else
36
+ WindowsInstallation.new path
37
+ end
38
+ end
39
+ end
40
+
41
+ class MacInstallation < Installation
42
+ attr_reader :path
43
+
44
+ require 'plist'
45
+
46
+ def initialize(path: nil)
47
+ @path = path
48
+ end
49
+
50
+ def version
51
+ plist['CFBundleVersion']
52
+ end
53
+
54
+ def default_log_file
55
+ "#{ENV['HOME']}/Library/Logs/Unity/Editor.log"
56
+ end
57
+
58
+ def exe_path
59
+ "#{path}/Contents/MacOS/Unity"
60
+ end
61
+
62
+ def packages
63
+ if Utils.parse_unity_version(version)[0].to_i <= 4
64
+ # Unity < 5 doesn't have packages
65
+ return []
66
+ end
67
+ fpath = File.expand_path('../PlaybackEngines', path)
68
+ return [] unless Dir.exist? fpath # install without package
69
+ Dir.entries(fpath).select { |e| File.directory?(File.join(fpath, e)) && !(e == '.' || e == '..') }
70
+ end
71
+
72
+ def clean_install?
73
+ path =~ UNITY_DIR_CHECK
74
+ end
75
+
76
+ private
77
+
78
+ def plist
79
+ @plist ||= Plist.parse_xml("#{@path}/Contents/Info.plist")
80
+ end
81
+ end
82
+
83
+ class LinuxInstallation < Installation
84
+ attr_reader :path
85
+
86
+ def initialize(path: nil)
87
+ @path = path
88
+ end
89
+
90
+ def version
91
+ # I don't find an easy way to extract the version on Linux
92
+ require 'rexml/document'
93
+ fpath = "#{path}/Editor/Data/PlaybackEngines/LinuxStandaloneSupport/ivy.xml"
94
+ raise "Couldn't find file #{fpath}" unless File.exist? fpath
95
+ doc = REXML::Document.new(File.read(fpath))
96
+ version = REXML::XPath.first(doc, 'ivy-module/info/@e:unityVersion').value
97
+ if (m = version.match(/^(.*)x(.*)Linux$/))
98
+ version = "#{m[1]}#{m[2]}"
99
+ end
100
+ version
101
+ end
102
+
103
+ def default_log_file
104
+ "#{ENV['HOME']}/.config/unity3d/Editor.log"
105
+ end
106
+
107
+ def exe_path
108
+ "#{path}/Editor/Unity"
109
+ end
110
+
111
+ def packages
112
+ false
113
+ end
114
+
115
+ def clean_install?
116
+ path =~ UNITY_DIR_CHECK_LINUX
117
+ end
118
+ end
119
+
120
+ class WindowsInstallation < Installation
121
+ attr_reader :path
122
+
123
+ def initialize(path: nil)
124
+ @path = path
125
+ end
126
+
127
+ def version
128
+ require 'rexml/document'
129
+ fpath = "#{path}/Editor/Data/PlaybackEngines/windowsstandalonesupport/ivy.xml"
130
+ raise "Couldn't find file #{fpath}" unless File.exist? fpath
131
+ doc = REXML::Document.new(File.read(fpath))
132
+ version = REXML::XPath.first(doc, 'ivy-module/info/@e:unityVersion').value
133
+
134
+ version
135
+ end
136
+
137
+ def default_log_file
138
+ if @logfile.nil?
139
+ begin
140
+ loc_appdata = Utils.windows_local_appdata
141
+ log_dir = File.expand_path('Unity/Editor/', loc_appdata)
142
+ UI.important "Log directory (#{log_dir}) does not exist" unless Dir.exist? log_dir
143
+ @logfile = File.expand_path('Editor.log', log_dir)
144
+ rescue RuntimeError => ex
145
+ UI.error "Unable to retrieve the editor logfile: #{ex}"
146
+ end
147
+ end
148
+ @logfile
149
+ end
150
+
151
+ def exe_path
152
+ File.join(@path, 'Editor', 'Unity.exe')
153
+ end
154
+
155
+ def packages
156
+ # Unity prior to Unity5 did not have package
157
+ return [] if Utils.parse_unity_version(version)[0].to_i <= 4
158
+ fpath = "#{path}/Editor/Data/PlaybackEngines/"
159
+ return [] unless Dir.exist? fpath # install without package
160
+ Dir.entries(fpath).select { |e| File.directory?(File.join(fpath, e)) && !(e == '.' || e == '..') }
161
+ end
162
+
163
+ def clean_install?
164
+ path =~ UNITY_DIR_CHECK
165
+ end
166
+ end
167
+ end
@@ -21,157 +21,16 @@
21
21
  ## --- END LICENSE BLOCK ---
22
22
 
23
23
  require 'u3d/utils'
24
+ require 'u3d/installation'
24
25
  require 'fileutils'
25
26
  require 'file-tail'
26
27
 
27
- # Mac specific only right now
28
28
  module U3d
29
29
  DEFAULT_LINUX_INSTALL = '/opt/'.freeze
30
30
  DEFAULT_MAC_INSTALL = '/'.freeze
31
31
  DEFAULT_WINDOWS_INSTALL = 'C:/Program Files/'.freeze
32
32
  UNITY_DIR = "Unity_%s".freeze
33
33
  UNITY_DIR_LINUX = "unity-editor-%s".freeze
34
- UNITY_DIR_CHECK = /Unity_\d+\.\d+\.\d+[a-z]\d+/
35
- UNITY_DIR_CHECK_LINUX = /unity-editor-\d+\.\d+\.\d+[a-z]\d+\z/
36
-
37
- class Installation
38
- def self.create(path: nil)
39
- if Helper.mac?
40
- MacInstallation.new path
41
- elsif Helper.linux?
42
- LinuxInstallation.new path
43
- else
44
- WindowsInstallation.new path
45
- end
46
- end
47
- end
48
-
49
- class MacInstallation < Installation
50
- attr_reader :path
51
-
52
- require 'plist'
53
-
54
- def initialize(path: nil)
55
- @path = path
56
- end
57
-
58
- def version
59
- plist['CFBundleVersion']
60
- end
61
-
62
- def default_log_file
63
- "#{ENV['HOME']}/Library/Logs/Unity/Editor.log"
64
- end
65
-
66
- def exe_path
67
- "#{path}/Contents/MacOS/Unity"
68
- end
69
-
70
- def packages
71
- if Utils.parse_unity_version(version)[0].to_i <= 4
72
- # Unity < 5 doesn't have packages
73
- return []
74
- end
75
- fpath = File.expand_path('../PlaybackEngines', path)
76
- raise "Unity installation does not seem correct. Couldn't locate PlaybackEngines." unless Dir.exist? fpath
77
- Dir.entries(fpath).select { |e| File.directory?(File.join(fpath, e)) && !(e == '.' || e == '..') }
78
- end
79
-
80
- def clean_install?
81
- path =~ UNITY_DIR_CHECK
82
- end
83
-
84
- private
85
-
86
- def plist
87
- @plist ||= Plist.parse_xml("#{@path}/Contents/Info.plist")
88
- end
89
- end
90
-
91
- class LinuxInstallation < Installation
92
- attr_reader :path
93
-
94
- def initialize(path: nil)
95
- @path = path
96
- end
97
-
98
- def version
99
- # I don't find an easy way to extract the version on Linux
100
- require 'rexml/document'
101
- fpath = "#{path}/Editor/Data/PlaybackEngines/LinuxStandaloneSupport/ivy.xml"
102
- raise "Couldn't find file #{fpath}" unless File.exist? fpath
103
- doc = REXML::Document.new(File.read(fpath))
104
- version = REXML::XPath.first(doc, 'ivy-module/info/@e:unityVersion').value
105
- if m = version.match(/^(.*)x(.*)Linux$/)
106
- version = "#{m[1]}#{m[2]}"
107
- end
108
- version
109
- end
110
-
111
- def default_log_file
112
- "#{ENV['HOME']}/.config/unity3d/Editor.log"
113
- end
114
-
115
- def exe_path
116
- "#{path}/Editor/Unity"
117
- end
118
-
119
- def packages
120
- false
121
- end
122
-
123
- def clean_install?
124
- path =~ UNITY_DIR_CHECK_LINUX
125
- end
126
- end
127
-
128
- class WindowsInstallation < Installation
129
- attr_reader :path
130
-
131
- def initialize(path: nil)
132
- @path = path
133
- end
134
-
135
- def version
136
- require 'rexml/document'
137
- fpath = "#{path}/Editor/Data/PlaybackEngines/windowsstandalonesupport/ivy.xml"
138
- raise "Couldn't find file #{fpath}" unless File.exist? fpath
139
- doc = REXML::Document.new(File.read(fpath))
140
- version = REXML::XPath.first(doc, 'ivy-module/info/@e:unityVersion').value
141
-
142
- version
143
- end
144
-
145
- def default_log_file
146
- if @logfile.nil?
147
- begin
148
- loc_appdata = Utils.windows_local_appdata
149
- log_dir = File.expand_path('Unity/Editor/', loc_appdata)
150
- UI.important "Log directory (#{log_dir}) does not exist" unless Dir.exist? log_dir
151
- @logfile = File.expand_path('Editor.log', log_dir)
152
- rescue RuntimeError => ex
153
- UI.error "Unable to retrieve the editor logfile: #{ex}"
154
- end
155
- end
156
- @logfile
157
- end
158
-
159
- def exe_path
160
- File.join(@path, 'Editor', 'Unity.exe')
161
- end
162
-
163
- def packages
164
- # Unity prior to Unity5 did not have package
165
- return [] if Utils.parse_unity_version(version)[0].to_i <= 4
166
- fpath = "#{path}/Editor/Data/PlaybackEngines/"
167
- raise "Unity installation does not seem correct. Couldn't locate PlaybackEngines." unless Dir.exist? fpath
168
- Dir.entries(fpath).select { |e| File.directory?(File.join(fpath, e)) && !(e == '.' || e == '..') }
169
- end
170
-
171
- def clean_install?
172
- path =~ UNITY_DIR_CHECK
173
- end
174
- end
175
34
 
176
35
  class Installer
177
36
  def self.create
@@ -182,16 +41,23 @@ module U3d
182
41
  else
183
42
  WindowsInstaller.new
184
43
  end
185
- if UI.interactive?
186
- unclean = []
187
- installer.installed.each { |unity| unclean << unity unless unity.clean_install? }
188
- if !unclean.empty? && UI.confirm("#{unclean.count} Unity installation should be moved. Proceed?")
189
- unclean.each { |unity| installer.sanitize_install(unity) }
190
- end
191
- end
44
+ sanitize_installs(installer)
192
45
  installer
193
46
  end
194
47
 
48
+ def self.sanitize_installs(installer)
49
+ return unless UI.interactive? || Helper.test?
50
+ unclean = []
51
+ installer.installed.each { |unity| unclean << unity unless unity.clean_install? }
52
+ return if unclean.empty?
53
+ UI.important("u3d can optionally standardize the existing Unity3d installation names and locations.")
54
+ UI.important("Check the documentation for more information:")
55
+ UI.important("** https://github.com/DragonBox/u3d/blob/master/README.md#default-installation-paths **")
56
+ unclean.each { |unity| installer.sanitize_install(unity, dry_run: true) }
57
+ return unless UI.confirm("#{unclean.count} Unity installation(s) will be moved. Proceed??")
58
+ unclean.each { |unity| installer.sanitize_install(unity) }
59
+ end
60
+
195
61
  def self.install_modules(files, version, installation_path: nil)
196
62
  installer = Installer.create
197
63
  files.each do |name, file, info|
@@ -201,19 +67,36 @@ module U3d
201
67
  end
202
68
  end
203
69
 
70
+ class CommonInstaller
71
+ def self.sanitize_install(source_path, new_path, command, dry_run: false)
72
+ if source_path == new_path
73
+ UI.important "sanitize_install does nothing if the path won't change (#{source_path})"
74
+ return
75
+ end
76
+
77
+ if dry_run
78
+ UI.message "'#{source_path}' would move to '#{new_path}'"
79
+ else
80
+ UI.important "Moving '#{source_path}' to '#{new_path}'..."
81
+ U3dCore::CommandExecutor.execute(command: command, admin: true)
82
+ UI.success "Successfully moved '#{source_path}' to '#{new_path}'"
83
+ end
84
+ rescue => e
85
+ UI.error "Unable to move '#{source_path}' to '#{new_path}': #{e}"
86
+ end
87
+ end
88
+
204
89
  class MacInstaller
205
- def sanitize_install(unity)
90
+ def sanitize_install(unity, dry_run: false)
206
91
  source_path = File.expand_path('..', unity.path)
207
92
  parent = File.expand_path('..', source_path)
208
93
  new_path = File.join(parent, UNITY_DIR % unity.version)
209
- UI.important "Moving #{source_path} to #{new_path}..."
210
- source_path = "\"#{source_path}\"" if source_path =~ / /
211
- new_path = "\"#{new_path}\"" if new_path =~ / /
212
- U3dCore::CommandExecutor.execute(command: "mv #{source_path} #{new_path}", admin: true)
213
- rescue => e
214
- UI.error "Unable to move #{source_path} to #{new_path}: #{e}"
215
- else
216
- UI.success "Successfully moved #{source_path} to #{new_path}"
94
+ source_path = source_path.shellescape
95
+ new_path = new_path.shellescape
96
+
97
+ command = "mv #{source_path} #{new_path}"
98
+
99
+ CommonInstaller.sanitize_install(source_path, new_path, command, dry_run: dry_run)
217
100
  end
218
101
 
219
102
  def installed
@@ -234,7 +117,9 @@ module U3d
234
117
  versions.sort! { |x, y| x.version <=> y.version }
235
118
  end
236
119
 
120
+ # rubocop:disable UnusedMethodArgument
237
121
  def install(file_path, version, installation_path: nil, info: {})
122
+ # rubocop:enable UnusedMethodArgument
238
123
  extension = File.extname(file_path)
239
124
  raise "Installation of #{extension} files is not supported on Mac" if extension != '.pkg'
240
125
  path = installation_path || DEFAULT_MAC_INSTALL
@@ -249,13 +134,15 @@ module U3d
249
134
  target_path ||= DEFAULT_MAC_INSTALL
250
135
  command = "installer -pkg #{file_path.shellescape} -target #{target_path.shellescape}"
251
136
  unity = installed.find { |u| u.version == version }
137
+ temp_path = File.join(target_path, 'Applications', 'Unity')
252
138
  if unity.nil?
253
139
  UI.verbose "No Unity install for version #{version} was found"
254
140
  U3dCore::CommandExecutor.execute(command: command, admin: true)
141
+ destination_path = File.join(target_path, 'Applications', UNITY_DIR % version)
142
+ FileUtils.mv temp_path, destination_path
255
143
  else
256
144
  begin
257
145
  path = File.expand_path('..', unity.path)
258
- temp_path = File.join(target_path, 'Applications', 'Unity')
259
146
  move_to_temp = (temp_path != path)
260
147
  if move_to_temp
261
148
  UI.verbose "Temporary switching location of #{path} to #{temp_path} for installation purpose"
@@ -274,18 +161,16 @@ module U3d
274
161
  end
275
162
 
276
163
  class LinuxInstaller
277
- def sanitize_install(unity)
164
+ def sanitize_install(unity, dry_run: false)
278
165
  source_path = File.expand_path(unity.path)
279
166
  parent = File.expand_path('..', source_path)
280
167
  new_path = File.join(parent, UNITY_DIR_LINUX % unity.version)
281
- UI.important "Moving #{source_path} to #{new_path}..."
282
- source_path = "\"#{source_path}\"" if source_path =~ / /
283
- new_path = "\"#{new_path}\"" if new_path =~ / /
284
- U3dCore::CommandExecutor.execute(command: "mv #{source_path} #{new_path}", admin: true)
285
- rescue => e
286
- UI.error "Unable to move #{source_path} to #{new_path}: #{e}"
287
- else
288
- UI.success "Successfully moved #{source_path} to #{new_path}"
168
+ source_path = source_path.shellescape
169
+ new_path = new_path.shellescape
170
+
171
+ command = "mv #{source_path} #{new_path}"
172
+
173
+ CommonInstaller.sanitize_install(source_path, new_path, command, dry_run: dry_run)
289
174
  end
290
175
 
291
176
  def installed
@@ -296,7 +181,9 @@ module U3d
296
181
  versions.sort! { |x, y| x.version <=> y.version }
297
182
  end
298
183
 
184
+ # rubocop:disable UnusedMethodArgument
299
185
  def install(file_path, version, installation_path: nil, info: {})
186
+ # rubocop:enable UnusedMethodArgument
300
187
  extension = File.extname(file_path)
301
188
  raise "Installation of #{extension} files is not supported on Linux" if extension != '.sh'
302
189
  path = installation_path || DEFAULT_LINUX_INSTALL
@@ -327,20 +214,19 @@ module U3d
327
214
  end
328
215
 
329
216
  class WindowsInstaller
330
- def sanitize_install(unity)
217
+ def sanitize_install(unity, dry_run: false)
331
218
  source_path = File.expand_path(unity.path)
332
219
  parent = File.expand_path('..', source_path)
333
220
  new_path = File.join(parent, UNITY_DIR % unity.version)
334
- UI.important "Moving #{source_path} to #{new_path}..."
221
+
335
222
  source_path.tr!('/', '\\')
336
223
  new_path.tr!('/', '\\')
337
224
  source_path = "\"" + source_path + "\"" if source_path =~ / /
338
225
  new_path = "\"" + new_path + "\"" if new_path =~ / /
339
- U3dCore::CommandExecutor.execute(command: "move #{source_path} #{new_path}", admin: true)
340
- rescue => e
341
- UI.error "Unable to move #{source_path} to #{new_path}: #{e}"
342
- else
343
- UI.success "Successfully moved #{source_path} to #{new_path}"
226
+
227
+ command = "move #{source_path} #{new_path}"
228
+
229
+ CommonInstaller.sanitize_install(source_path, new_path, command, dry_run: dry_run)
344
230
  end
345
231
 
346
232
  def installed
@@ -374,7 +260,7 @@ module U3d
374
260
  command.sub!(/{INSTDIR}/, final_path)
375
261
  command.sub!(/{DOCDIR}/, final_path)
376
262
  command.sub!(/{MODULEDIR}/, final_path)
377
- command.sub!(/\/D=/, '/S /D=') unless /\/S/ =~ command
263
+ command.sub!(%r{\/D=}, '/S /D=') unless %r{\/S} =~ command
378
264
  end
379
265
  command ||= file_path.to_s
380
266
  U3dCore::CommandExecutor.execute(command: command, admin: true)
@@ -385,24 +271,4 @@ module U3d
385
271
  end
386
272
  end
387
273
  end
388
-
389
- class UnityProject
390
- attr_reader :path
391
-
392
- def initialize(path)
393
- @path = path
394
- end
395
-
396
- def exist?
397
- Dir.exist?("#{@path}/Assets") && Dir.exist?("#{@path}/ProjectSettings")
398
- end
399
-
400
- def editor_version
401
- require 'yaml'
402
- yaml = YAML.load(File.read("#{@path}/ProjectSettings/ProjectVersion.txt"))
403
- version = yaml['m_EditorVersion']
404
- version.gsub!(/(\d+\.\d+\.\d+)(?:x)?(\w\d+)(?:Linux)?/, '\1\2') if Helper.linux?
405
- version
406
- end
407
- end
408
274
  end