Skip to content

Commit

Permalink
Merge pull request #280 from lacostej/revision
Browse files Browse the repository at this point in the history
u3d/list: display full revision number (prepares for #274)
  • Loading branch information
lacostej authored Apr 19, 2018
2 parents 79bb928 + 977feb5 commit 4964aa3
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 1 deletion.
3 changes: 2 additions & 1 deletion lib/u3d/commands.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ def list_installed(options: {})
sorted_keys = vcomparators.sort.map { |v| v.version.to_s }
sorted_keys.each do |k|
u = map[k]
UI.message "Version #{u.version.ljust(30)}(#{u.root_path})"
version = "#{u.version.ljust(13)} [#{u.build_number}]".ljust(30)
UI.message "Version #{version}(#{u.root_path})"
packages = u.packages
next unless options[:packages] && packages && !packages.empty?
UI.message 'Packages:'
Expand Down
95 changes: 95 additions & 0 deletions lib/u3d/installation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ def version
plist['CFBundleVersion']
end

def build_number
plist['UnityBuildNumber']
end

def default_log_file
"#{ENV['HOME']}/Library/Logs/Unity/Editor.log"
end
Expand Down Expand Up @@ -163,6 +167,39 @@ def plist
end
end

class LinuxInstallationHelper
STRINGS_FULL_VERSION_MATCHER = /^[0-9\.abfp]+_[0-9a-f]{12}/

def find_build_number(root)
known_rev_locations.each do |p|
rev = find_build_number_in("#{root}#{p}")
return rev if rev
end
end

private

def strings(path)
command = "strings #{path.shellescape}"
`#{command}`.split("\n")
end

# sorted by order of speed to fetch the strings data
def known_rev_locations
['/Editor/BugReporter/unity.bugreporter',
'/Editor/Data/PlaybackEngines/WebGLSupport/BuildTools/lib/UnityNativeJs/UnityNative.js.mem',
'/Editor/Data/PlaybackEngines/LinuxStandaloneSupport/Variations/linux32_headless_nondevelopment_mono/LinuxPlayer',
'/Editor/Unity']
end

def find_build_number_in(path = nil)
return nil unless File.exist? path
str = strings(path)
lines = str.select { |l| l =~ STRINGS_FULL_VERSION_MATCHER }
lines.empty? ? nil : lines[0].split('_')[1]
end
end

class LinuxInstallation < Installation
def version
# I don't find an easy way to extract the version on Linux
Expand All @@ -176,6 +213,10 @@ def version
version
end

def build_number
@build_number ||= LinuxInstallationHelper.new.find_build_number(root_path)
end

def default_log_file
"#{ENV['HOME']}/.config/unity3d/Editor.log"
end
Expand Down Expand Up @@ -220,6 +261,56 @@ def clean_install?
end
end

class WindowsInstallationHelper
def build_number(exe_path)
s = string_file_info("Unity Version", exe_path)
if s
a = s.split("_")
return a[1] if a.count > 1
end
nil
end

private

def string_file_info(info, path)
require "Win32API"
get_file_version_info_size = Win32API.new('version.dll', 'GetFileVersionInfoSize', 'PP', 'L')
get_file_version_info = Win32API.new('version.dll', 'GetFileVersionInfo', 'PIIP', 'I')
ver_query_value = Win32API.new('version.dll', 'VerQueryValue', 'PPPP', 'I')
rtl_move_memory = Win32API.new('kernel32.dll', 'RtlMoveMemory', 'PLL', 'I')

file = path.tr("/", "\\")

buf = [0].pack('L')
version_size = get_file_version_info_size.call(file + "\0", buf)
raise Exception if version_size.zero? # TODO: use GetLastError

version_info = 0.chr * version_size
version_ok = get_file_version_info.call(file, 0, version_size, version_info)
raise Exception if version_ok.zero? # TODO: use GetLastError

# hardcoding lang codepage
struct_path = "\\StringFileInfo\\040904b0\\#{info}"

addr = [0].pack('L')
size = [0].pack('L')
query_ok = ver_query_value.call(version_info, struct_path + "\0", addr, size)
raise Exception if query_ok.zero?

raddr = addr.unpack('L')[0]
rsize = size.unpack('L')[0]

info = Array.new(rsize, 0).pack('L*')
rtl_move_memory.call(info, raddr, info.length)
info.strip
rescue StandardError => e
UI.verbose("Failure to find '#{info}' under '#{path}': #{e}")
UI.verbose(e.backtrace)
nil
end
end

class WindowsInstallation < Installation
def version
path = "#{root_path}/Editor/Data/"
Expand All @@ -228,6 +319,10 @@ def version
PlaybackEngineUtils.unity_version(package)
end

def build_number
@build_number ||= WindowsInstallationHelper.new.build_number(exe_path)
end

def default_log_file
if @logfile.nil?
begin
Expand Down
9 changes: 9 additions & 0 deletions spec/support/installations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def macinstall_5_6_default
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) { '/Applications/Unity' }
return unity
Expand All @@ -34,6 +35,7 @@ def macinstall_5_6_custom_with_space
unity = double("MacInstallation")
# allow(unity).to receive(:path) { '/Applications/Unity 5.6.0f1/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) { '/Applications/Unity 5.6.0f1' }
return unity
Expand All @@ -43,6 +45,7 @@ def linux_5_6_standard
unity = double("LinuxInstallation")
# allow(unity).to receive(:path) { '/opt/unity-editor-5.6.0f1' }
allow(unity).to receive(:version) { '5.6.0f1' }
allow(unity).to receive(:build_number) { 'bf5cca3e2788' }
allow(unity).to receive(:clean_install?) { true }
allow(unity).to receive(:root_path) { '/opt/unity-editor-5.6.0f1' }
return unity
Expand All @@ -52,6 +55,7 @@ def linux_5_6_debian
unity = double("LinuxInstallation")
# allow(unity).to receive(:path) { '/opt/Unity' }
allow(unity).to receive(:version) { '5.6.0f2' }
allow(unity).to receive(:build_number) { 'a7535b2c1eb6' }
allow(unity).to receive(:clean_install?) { false }
allow(unity).to receive(:root_path) { '/opt/Unity' }
return unity
Expand All @@ -61,6 +65,7 @@ def linux_2017_1_weird
unity = double("LinuxInstallation")
# allow(unity).to receive(:path) { '/opt/unity-editor-2017.1.0xf3Linux' }
allow(unity).to receive(:version) { '2017.1.0f3' }
allow(unity).to receive(:build_number) { '061bcf22327f' }
allow(unity).to receive(:clean_install?) { false }
allow(unity).to receive(:root_path) { '/opt/unity-editor-2017.1.0xf3Linux' }
return unity
Expand All @@ -70,6 +75,7 @@ def windows_5_6_32bits_default
unity = double("WindowsInstallation")
# allow(unity).to receive(:path) { 'C:/Program Files (x86)/Unity' }
allow(unity).to receive(:version) { '5.6.0f1' }
allow(unity).to receive(:build_number) { 'bf5cca3e2788' }
allow(unity).to receive(:root_path) { 'C:/Program Files (x86)/Unity' }
return unity
end
Expand All @@ -78,13 +84,15 @@ def windows_2017_1_64bits_renamed
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) { 'C:/Program Files/Unity_2017.1.0f3' }
return unity
end

def fake_linux(version)
unity = double("LinuxInstallation")
allow(unity).to receive(:version) { version }
allow(unity).to receive(:build_number) { 'build_number' }
allow(unity).to receive(:root_path) { 'foo' }
allow(unity).to receive(:packages) { false }
return unity
Expand All @@ -93,6 +101,7 @@ def fake_linux(version)
def fake_installation(version, packages: [])
unity = double("Installation")
allow(unity).to receive(:version) { version }
allow(unity).to receive(:build_number) { 'build_number' }
allow(unity).to receive(:root_path) { 'foo' }
allow(unity).to receive(:packages) { packages }
allow(unity).to receive(:package_installed?) { |arg| packages.include?(arg) }
Expand Down

0 comments on commit 4964aa3

Please sign in to comment.