From 9c390d05c64644ddf3ed14d99edd364834ab450f Mon Sep 17 00:00:00 2001 From: Paul Niezborala Date: Mon, 4 Nov 2019 17:55:08 +0100 Subject: [PATCH 1/8] u3d/installer: support custom install paths through U3D_EXTRA_PATHS --- lib/u3d/installer.rb | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/lib/u3d/installer.rb b/lib/u3d/installer.rb index b9df3707..52cc25a2 100644 --- a/lib/u3d/installer.rb +++ b/lib/u3d/installer.rb @@ -86,6 +86,21 @@ def installed_sorted_by_versions return [] if list.empty? list.sort { |a, b| UnityVersionComparator.new(a.version) <=> UnityVersionComparator.new(b.version) } end + + protected + + def extra_installation_paths + return [] if ENV['U3D_EXTRA_PATHS'].nil? + ENV['U3D_EXTRA_PATHS'].strip.split(';') + end + + def find_installations_with_path(default_path, *postfix) + ([default_path] | extra_installation_paths).map do |path| + UI.verbose "Looking for installed Unity version under #{path}" + pattern = File.join([path] + postfix) + Dir.glob(pattern).map { |found_path| yield found_path } + end.flatten + end end # deprecated @@ -169,9 +184,11 @@ def uninstall(unity: nil) private def list_installed_paths - find = File.join(DEFAULT_MAC_INSTALL, 'Applications', 'Unity*', 'Unity.app') - paths = Dir[find] - paths = paths.map { |u| Pathname.new(u).parent.to_s } + paths = find_installations_with_path( + DEFAULT_MAC_INSTALL, + 'Applications', + 'Unity*', + 'Unity.app') { |u| Pathname.new(u).parent.to_s } UI.verbose "Found list_installed_paths: #{paths}" paths end @@ -332,9 +349,10 @@ def pkg_install_path(unity_root_path, pinfo_path) end def list_installed_paths - find = File.join(DEFAULT_LINUX_INSTALL, 'unity-editor-*', 'Editor') - paths = Dir[find] - paths = paths.map { |u| Pathname.new(u).parent.to_s } + paths = find_installations_with_path( + DEFAULT_LINUX_INSTALL, + 'unity-editor-*', + 'Editor') { |u| Pathname.new(u).parent.to_s } UI.verbose "Found list_installed_paths: #{paths}" paths end @@ -362,8 +380,11 @@ def sanitize_install(unity, long: false, dry_run: false) end def installed - find = File.join(DEFAULT_WINDOWS_INSTALL, 'Unity*', 'Editor', 'Uninstall.exe') - Dir[find].map { |path| WindowsInstallation.new(root_path: File.expand_path('../..', path)) } + find_installations_with_path( + DEFAULT_MAC_INSTALL, + 'Unity*', + 'Editor', + 'Uninstall.exe') { |path| WindowsInstallation.new(root_path: File.expand_path('../..', path)) } end def install(file_path, version, installation_path: nil, info: {}) From c69d3772d80d80397568f90fa8cc677fa9c975b0 Mon Sep 17 00:00:00 2001 From: Paul Niezborala Date: Mon, 4 Nov 2019 18:06:32 +0100 Subject: [PATCH 2/8] Rubocop compliance --- lib/u3d/installer.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/u3d/installer.rb b/lib/u3d/installer.rb index 52cc25a2..51dfdeed 100644 --- a/lib/u3d/installer.rb +++ b/lib/u3d/installer.rb @@ -188,7 +188,8 @@ def list_installed_paths DEFAULT_MAC_INSTALL, 'Applications', 'Unity*', - 'Unity.app') { |u| Pathname.new(u).parent.to_s } + 'Unity.app' + ) { |u| Pathname.new(u).parent.to_s } UI.verbose "Found list_installed_paths: #{paths}" paths end @@ -352,7 +353,8 @@ def list_installed_paths paths = find_installations_with_path( DEFAULT_LINUX_INSTALL, 'unity-editor-*', - 'Editor') { |u| Pathname.new(u).parent.to_s } + 'Editor' + ) { |u| Pathname.new(u).parent.to_s } UI.verbose "Found list_installed_paths: #{paths}" paths end @@ -384,7 +386,8 @@ def installed DEFAULT_MAC_INSTALL, 'Unity*', 'Editor', - 'Uninstall.exe') { |path| WindowsInstallation.new(root_path: File.expand_path('../..', path)) } + 'Uninstall.exe' + ) { |path| WindowsInstallation.new(root_path: File.expand_path('../..', path)) } end def install(file_path, version, installation_path: nil, info: {}) From 4ff11603177dff8715d8a837e80a208885205828 Mon Sep 17 00:00:00 2001 From: Paul Niezborala Date: Mon, 4 Nov 2019 18:12:13 +0100 Subject: [PATCH 3/8] Fix Linux installer spec --- lib/u3d/installer.rb | 8 +++++--- spec/u3d/installer_spec.rb | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/u3d/installer.rb b/lib/u3d/installer.rb index 51dfdeed..8ebcb659 100644 --- a/lib/u3d/installer.rb +++ b/lib/u3d/installer.rb @@ -360,9 +360,11 @@ def list_installed_paths end def debian_installed_paths - find = File.join(DEFAULT_LINUX_INSTALL, 'Unity', 'Editor') - paths = Dir[find] - paths = paths.map { |u| Pathname.new(u).parent.to_s } + paths = find_installations_with_path( + DEFAULT_LINUX_INSTALL, + 'Unity', + 'Editor' + ) { |u| Pathname.new(u).parent.to_s } UI.verbose "Found debian_installed_paths: #{paths}" paths end diff --git a/spec/u3d/installer_spec.rb b/spec/u3d/installer_spec.rb index 0c5ce645..e7f616c7 100644 --- a/spec/u3d/installer_spec.rb +++ b/spec/u3d/installer_spec.rb @@ -180,8 +180,8 @@ class DummyInstaller < U3d::BaseInstaller u1 = linux_5_6_standard u2 = linux_5_6_debian u3 = linux_2017_1_weird - allow(Dir).to receive(:[]).with('/opt/unity-editor-*/Editor') { ["#{u1.root_path}/Editor", "#{u3.root_path}/Editor"] } - allow(Dir).to receive(:[]).with('/opt/Unity/Editor') { ["#{u2.root_path}/Editor"] } + allow(Dir).to receive(:glob).with('/opt/unity-editor-*/Editor') { ["#{u1.root_path}/Editor", "#{u3.root_path}/Editor"] } + allow(Dir).to receive(:glob).with('/opt/Unity/Editor') { ["#{u2.root_path}/Editor"] } allow(U3d::LinuxInstallation).to receive(:new).with(root_path: u1.root_path) { u1 } allow(U3d::LinuxInstallation).to receive(:new).with(root_path: u2.root_path) { u2 } From 4dfd5691649d1161a4d52a7a4e487cd2bff134d9 Mon Sep 17 00:00:00 2001 From: Paul Niezborala Date: Wed, 6 Nov 2019 10:16:53 +0100 Subject: [PATCH 4/8] BaseInstaller#extra_installation_paths: use File::PATH_SEPARATOR instead of hardcoded ; --- lib/u3d/installer.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/u3d/installer.rb b/lib/u3d/installer.rb index 8ebcb659..53dd626f 100644 --- a/lib/u3d/installer.rb +++ b/lib/u3d/installer.rb @@ -91,7 +91,7 @@ def installed_sorted_by_versions def extra_installation_paths return [] if ENV['U3D_EXTRA_PATHS'].nil? - ENV['U3D_EXTRA_PATHS'].strip.split(';') + ENV['U3D_EXTRA_PATHS'].strip.split(File::PATH_SEPARATOR) end def find_installations_with_path(default_path, *postfix) From 295d30c572e020e21f0b87b7d804fbdfcd14c524 Mon Sep 17 00:00:00 2001 From: Paul Niezborala Date: Thu, 7 Nov 2019 12:15:29 +0100 Subject: [PATCH 5/8] Cleaner parameters for find_installations_with_path --- lib/u3d/installer.rb | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/lib/u3d/installer.rb b/lib/u3d/installer.rb index 53dd626f..5f923fcd 100644 --- a/lib/u3d/installer.rb +++ b/lib/u3d/installer.rb @@ -94,8 +94,8 @@ def extra_installation_paths ENV['U3D_EXTRA_PATHS'].strip.split(File::PATH_SEPARATOR) end - def find_installations_with_path(default_path, *postfix) - ([default_path] | extra_installation_paths).map do |path| + def find_installations_with_path(default_root_path: '', postfix: []) + ([default_root_path] | extra_installation_paths).map do |path| UI.verbose "Looking for installed Unity version under #{path}" pattern = File.join([path] + postfix) Dir.glob(pattern).map { |found_path| yield found_path } @@ -185,10 +185,12 @@ def uninstall(unity: nil) def list_installed_paths paths = find_installations_with_path( - DEFAULT_MAC_INSTALL, - 'Applications', - 'Unity*', - 'Unity.app' + default_root_path: DEFAULT_MAC_INSTALL, + postfix: %w[ + Applications + Unity* + Unity.app + ] ) { |u| Pathname.new(u).parent.to_s } UI.verbose "Found list_installed_paths: #{paths}" paths @@ -351,9 +353,11 @@ def pkg_install_path(unity_root_path, pinfo_path) def list_installed_paths paths = find_installations_with_path( - DEFAULT_LINUX_INSTALL, - 'unity-editor-*', - 'Editor' + default_root_path: DEFAULT_LINUX_INSTALL, + postfix: %w[ + unity-editor-* + Editor + ] ) { |u| Pathname.new(u).parent.to_s } UI.verbose "Found list_installed_paths: #{paths}" paths @@ -361,9 +365,11 @@ def list_installed_paths def debian_installed_paths paths = find_installations_with_path( - DEFAULT_LINUX_INSTALL, - 'Unity', - 'Editor' + default_root_path: DEFAULT_LINUX_INSTALL, + postfix: %w[ + Unity + Editor + ] ) { |u| Pathname.new(u).parent.to_s } UI.verbose "Found debian_installed_paths: #{paths}" paths @@ -385,10 +391,12 @@ def sanitize_install(unity, long: false, dry_run: false) def installed find_installations_with_path( - DEFAULT_MAC_INSTALL, - 'Unity*', - 'Editor', - 'Uninstall.exe' + default_root_path: DEFAULT_MAC_INSTALL, + postfix: %w[ + Unity* + Editor + Uninstall.exe + ] ) { |path| WindowsInstallation.new(root_path: File.expand_path('../..', path)) } end From 7682d6c47ae705189da258126feb474453ef4422 Mon Sep 17 00:00:00 2001 From: Paul Niezborala Date: Thu, 7 Nov 2019 12:16:41 +0100 Subject: [PATCH 6/8] WindowsInstaller: Use DEFAULT_WINDOWS_INSTALL in find_installations_with_path --- lib/u3d/installer.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/u3d/installer.rb b/lib/u3d/installer.rb index 5f923fcd..142a535d 100644 --- a/lib/u3d/installer.rb +++ b/lib/u3d/installer.rb @@ -391,7 +391,7 @@ def sanitize_install(unity, long: false, dry_run: false) def installed find_installations_with_path( - default_root_path: DEFAULT_MAC_INSTALL, + default_root_path: DEFAULT_WINDOWS_INSTALL, postfix: %w[ Unity* Editor From f3325e6fce4a9d6ea42e0edc3b6d424ac7ddec4b Mon Sep 17 00:00:00 2001 From: Paul Niezborala Date: Thu, 7 Nov 2019 16:56:01 +0100 Subject: [PATCH 7/8] Document U3D_EXTRA_PATHS in the README --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 734b423e..3bfae925 100644 --- a/README.md +++ b/README.md @@ -186,6 +186,14 @@ You can get further information on how to use U3d by running `u3d --help` (or `u ## How-tos +### Install in a custom location + +`u3d install` accepts an argument `--installation_path` which can install unity and its additional components to the location you want. + +However, there is a pitfall to that: you need to tell u3d where to look for the versions you installed in custom location. Doing so is quite easy, you just have to set the `U3D_EXTRA_PATHS`, to a list of paths that you want u3d to look for versions. + +_NOTE:_ The list of paths `U3D_EXTRA_PATHS` is formatted as your standard `PATH`, ie `U3D_EXTRA_PATHS=/path/to/something:/another/path` on Unix systems, and `U3D_EXTRA_PATHS=C:\Path\To\Something;E:\Another\Path` on Windows. + ### Run several Unity instances in parallel The only thing you have to watch for while trying to run multiple instances of Unity in parallel is the fact that they will share the same log file by default (the `Editor.log`). Therefore you will have to specify it using the [command line arguments](https://docs.unity3d.com/Manual/CommandLineArguments.html), you can do so with u3d the following way from each of your project root folder: From 5cce80efb757aefdaec32f538b1609dd2e951d7f Mon Sep 17 00:00:00 2001 From: Paul Niezborala Date: Thu, 7 Nov 2019 17:18:04 +0100 Subject: [PATCH 8/8] Unit tests for installer U3D_EXTRA_PATHS --- spec/support/installations.rb | 19 +++++++++++++ spec/u3d/installer_spec.rb | 53 +++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/spec/support/installations.rb b/spec/support/installations.rb index 1ac3d451..343b2544 100644 --- a/spec/support/installations.rb +++ b/spec/support/installations.rb @@ -31,6 +31,16 @@ def macinstall_5_6_default return unity end +def macinstall_5_6_custom_location + unity = double("MacInstallation") + # allow(unity).to receive(:path) { '/Applications/Unity/Unity.app' } + allow(unity).to receive(:version) { '5.6.0f1' } + allow(unity).to receive(:build_number) { 'bf5cca3e2788' } + allow(unity).to receive(:clean_install?) { false } + allow(unity).to receive(:root_path) { '/tmp/Applications/Unity' } + return unity +end + def macinstall_5_6_custom_with_space unity = double("MacInstallation") # allow(unity).to receive(:path) { '/Applications/Unity 5.6.0f1/Unity.app' } @@ -89,6 +99,15 @@ def windows_2017_1_64bits_renamed return unity end +def windows_2017_1_64bits_custom_location + unity = double("WindowsInstallation") + # allow(unity).to receive(:path) { 'C:/Program Files/Unity_2017.1.0f3' } + allow(unity).to receive(:version) { '2017.1.0f3' } + allow(unity).to receive(:build_number) { '472613c02cf7' } + allow(unity).to receive(:root_path) { 'E:/Program Files/Unity_2017.1.0f3' } + return unity +end + def fake_linux(version) unity = double("LinuxInstallation") allow(unity).to receive(:version) { version } diff --git a/spec/u3d/installer_spec.rb b/spec/u3d/installer_spec.rb index e7f616c7..f8e74cfe 100644 --- a/spec/u3d/installer_spec.rb +++ b/spec/u3d/installer_spec.rb @@ -91,6 +91,59 @@ class DummyInstaller < U3d::BaseInstaller end describe U3d::MacInstaller, unless: WINDOWS do + describe '.list' do + it 'finds installs in default locations' do + unity = macinstall_5_6_default + installer = U3d::MacInstaller.new + + allow(Dir).to receive(:glob).with('/Applications/Unity*/Unity.app') { ["#{unity.root_path}/Unity.app"] } + allow(U3d::MacInstallation).to receive(:new).with(root_path: unity.root_path) { unity } + allow(installer).to receive(:spotlight_installed_paths) { [] } + + expect(installer.installed).to eql [unity] + end + + it 'does not find installs in custom locations without U3D_EXTRA_PATHS' do + unity = macinstall_5_6_custom_location + installer = U3d::MacInstaller.new + + allow(Dir).to receive(:glob).with('/Applications/Unity*/Unity.app') { [] } + allow(Dir).to receive(:glob).with('/tmp/Applications/Unity*/Unity.app') { ["#{unity.root_path}/Unity.app"] } + allow(U3d::MacInstallation).to receive(:new).with(root_path: unity.root_path) { unity } + allow(installer).to receive(:spotlight_installed_paths) { [] } + + expect(installer.installed).to eql [] + end + + it 'finds installs in custom locations with U3D_EXTRA_PATHS' do + unity = macinstall_5_6_custom_location + installer = U3d::MacInstaller.new + + allow(ENV).to receive(:[]).with('U3D_EXTRA_PATHS') { '/tmp' } + allow(Dir).to receive(:glob).with('/Applications/Unity*/Unity.app') { [] } + allow(Dir).to receive(:glob).with('/tmp/Applications/Unity*/Unity.app') { ["#{unity.root_path}/Unity.app"] } + allow(U3d::MacInstallation).to receive(:new).with(root_path: unity.root_path) { unity } + allow(installer).to receive(:spotlight_installed_paths) { [] } + + expect(installer.installed).to eql [unity] + end + + it 'finds both custom and default installs' do + unity_default = macinstall_5_6_default + unity_custom = macinstall_5_6_custom_location + installer = U3d::MacInstaller.new + + allow(ENV).to receive(:[]).with('U3D_EXTRA_PATHS') { '/tmp' } + allow(Dir).to receive(:glob).with('/Applications/Unity*/Unity.app') { ["#{unity_default.root_path}/Unity.app"] } + allow(Dir).to receive(:glob).with('/tmp/Applications/Unity*/Unity.app') { ["#{unity_custom.root_path}/Unity.app"] } + allow(U3d::MacInstallation).to receive(:new).with(root_path: unity_default.root_path) { unity_default } + allow(U3d::MacInstallation).to receive(:new).with(root_path: unity_custom.root_path) { unity_custom } + allow(installer).to receive(:spotlight_installed_paths) { [] } + + expect(installer.installed).to eql [unity_default, unity_custom] + end + end + context 'when using a default install' do let(:unity) { macinstall_5_6_default } it 'sanitizes install' do