lib/u3d/commands.rb in u3d-1.1.5 vs lib/u3d/commands.rb in u3d-1.2.0
- old
+ new
@@ -122,45 +122,46 @@
UI.message "Filtering available versions with release level '#{rl}' [letter '#{letter}']"
vcomparators.select! { |vc| vc.version.parts[3] == letter }
end
sorted_keys = vcomparators.sort.map { |v| v.version.to_s }
+ show_packages = options[:packages]
+ packages = UnityModule.load_modules(sorted_keys, cache_versions, os: os) if show_packages
+
sorted_keys.each do |k|
v = cache_versions[k]
UI.message "Version #{k}: " + v.to_s.cyan.underline
- next unless options[:packages]
- inif = nil
- begin
- inif = U3d::INIparser.load_ini(k, cache_versions, os: os)
- rescue StandardError => e
- UI.error "Could not load packages for this version (#{e})"
- else
- UI.message 'Packages:'
- inif.each_key { |pack| UI.message " - #{pack}" }
- end
+ next unless show_packages
+ version_packages = packages[k]
+ UI.message 'Packages:'
+ version_packages.each { |package| UI.message " - #{package.id.capitalize}" }
end
end
def install(args: [], options: {})
version = specified_or_current_project_version(args[0])
UI.user_error!("You cannot use the --operating_system and the --install options together") if options[:install] && options[:operating_system]
os = valid_os_or_current(options[:operating_system])
- packages = packages_with_unity_first(options)
-
cache_versions = cache_versions(os, offline: !options[:download])
version = interpret_latest(version, cache_versions)
unless cache_versions[version]
UI.crash! "No version '#{version}' was found in cache. Either it doesn't exist or u3d doesn't know about it yet. Try refreshing with 'u3d available -f'"
return
end
definition = UnityVersionDefinition.new(version, os, cache_versions)
unity = check_unity_presence(version: version)
- return unless enforce_setup_coherence(packages, options, unity, definition)
+ packages = options[:packages] || ['Unity']
+ begin
+ packages = enforce_setup_coherence(packages, options, unity, definition)
+ rescue InstallationSetupError
+ return
+ end
+
verify_package_names(definition, packages)
get_administrative_privileges(options) if options[:install]
files = Downloader.fetch_modules(definition, packages: packages, download: options[:download])
@@ -330,16 +331,10 @@
.version.to_s
UI.message "Version '#{version}' is #{iversion}."
iversion
end
- def packages_with_unity_first(options)
- temp = options[:packages] || ['Unity']
- temp.insert(0, 'Unity') if temp.delete('Unity')
- temp
- end
-
def check_unity_presence(version: nil)
# idea: we could support matching 5.3.6p3 if passed 5.3.6
installed = Installer.create.installed
unity = installed.find { |u| u.version == version }
if unity.nil?
@@ -355,10 +350,11 @@
def enforce_setup_coherence(packages, options, unity, definition)
if options[:all]
packages.clear
packages.concat(definition.available_packages)
end
+ packages = sort_packages(packages, definition)
if options[:install]
if unity
UI.important "Unity #{unity.version} is already installed"
# Not needed since Linux custom u3d files contain only one entry wich is Unity
# return false if definition.os == :linux
@@ -367,30 +363,75 @@
packages.delete('Unity')
# FIXME: Move me to the WindowsInstaller
options[:installation_path] ||= unity.root_path if definition.os == :win
end
- packages.select { |pack| unity.package_installed?(pack) }.each do |pack|
- packages.delete pack
- UI.important "Ignoring #{pack} module, it is already installed"
- end
- return false if packages.empty?
+ # FIXME: unity.package_installed? is not reliable
+ packages = detect_installed_packages(packages, unity)
+ packages = detect_missing_dependencies(packages, unity, definition)
+ raise InstallationSetupError if packages.empty?
else
- unless packages.include?('Unity')
+ unless packages.map(&:downcase).include?('unity')
UI.error 'Please install Unity before any of its packages'
- return false
+ raise InstallationSetupError
end
end
end
- true
+ packages
end
# rubocop:enable Metrics/BlockNesting
+ def sort_packages(packages, definition)
+ packages.sort do |a, b|
+ package_a = definition[a]
+ package_b = definition[b]
+ if package_a.depends_on?(package_b) # b must come first
+ 1
+ elsif package_b.depends_on?(package_a) # a must come first
+ -1
+ else
+ a <=> b # Resort to alphabetical sorting
+ end
+ end
+ end
+
+ def detect_installed_packages(packages, unity)
+ result = packages
+ packages.select { |pack| unity.package_installed?(pack) }.each do |pack|
+ result.delete pack
+ UI.important "Ignoring #{pack} module, it is already installed"
+ end
+ result
+ end
+
+ def detect_missing_dependencies(packages, unity, definition)
+ result = packages
+ packages.reject { |package| can_install?(package, unity, definition, packages) }.each do |pack|
+ # See FIXME for package_installed?
+ # result.delete pack
+ package = definition[pack]
+ UI.important "#{package.name} depends on #{package.depends_on}, but it's neither installed nor being installed."
+ end
+ result
+ end
+
+ def can_install?(package_name, unity, definition, installing)
+ package = definition[package_name]
+ return true unless package.depends_on
+ return true if unity.package_installed?(package.depends_on)
+ installing.map { |other| definition[other] }.any? do |other|
+ other.id == package.depends_on || other.name == package.depends_on
+ end
+ end
+
def get_administrative_privileges(options)
U3dCore::Globals.use_keychain = true if options[:keychain] && Helper.mac?
UI.important 'Root privileges are required'
raise 'Could not get administrative privileges' unless U3dCore::CommandExecutor.has_admin_privileges?
end
end
end
# rubocop:enable ClassLength
+end
+
+class InstallationSetupError < StandardError
end