From f0e4df0dc3eae855419a0e0b8cd33371f8314de2 Mon Sep 17 00:00:00 2001 From: Greg Neagle Date: Mon, 22 May 2017 10:19:53 -0700 Subject: [PATCH] application items in installs list now consider _only_ the given path if specified. To get the previous searching behavior, path must be absent and bundleid and/or name must be present. --- code/client/munkilib/updatecheck/compare.py | 87 +++++++++------------ 1 file changed, 38 insertions(+), 49 deletions(-) diff --git a/code/client/munkilib/updatecheck/compare.py b/code/client/munkilib/updatecheck/compare.py index 9b0096cf..705be262 100644 --- a/code/client/munkilib/updatecheck/compare.py +++ b/code/client/munkilib/updatecheck/compare.py @@ -22,6 +22,7 @@ Comparsion/checking functions used by updatecheck """ import os +from operator import itemgetter from .. import display from .. import munkihash @@ -56,8 +57,8 @@ def compare_versions(thisvers, thatvers): def compare_application_version(app): - """First checks the given path if it's available, - then uses system profiler data to look for the app + """Checks the given path if it's available, + otherwise uses LaunchServices and/or Spotlight to look for the app Args: app: dict with application bundle info @@ -76,26 +77,21 @@ def compare_application_version(app): if os.path.exists(filepath): return compare_bundle_version(app) display.display_debug2('%s doesn\'t exist.', filepath) - else: - display.display_debug2('No path given for application item.') + return ITEM_NOT_PRESENT - # not in default location, or no path specified, so let's search: + # no 'path' in dict + display.display_debug2('No path given for application item.') + # let's search: name = app.get('CFBundleName', '') bundleid = app.get('CFBundleIdentifier', '') version_comparison_key = app.get( 'version_comparison_key', 'CFBundleShortVersionString') versionstring = app.get(version_comparison_key) - minupvers = app.get('minimum_update_version') if name == '' and bundleid == '': - if 'path' in app: - # already looked at default path, and we don't have - # any additional info, so we have to assume it's not installed. - return ITEM_NOT_PRESENT - else: - # no path, no name, no bundleid. Error! - raise utils.Error( - 'No application name or bundleid was specified!') + # no path, no name, no bundleid. Error! + raise utils.Error( + 'No path, application name or bundleid was specified!') display.display_debug1( 'Looking for application %s with bundleid: %s, version %s...' % @@ -104,8 +100,9 @@ def compare_application_version(app): # find installed apps that match this item by name or bundleid appdata = info.filtered_app_data() appinfo = [item for item in appdata - if (item['bundleid'] == bundleid or - (name and item['name'] == name))] + if (item['path'] and + (item['bundleid'] == bundleid or + (name and item['name'] == name)))] if not appinfo: # No matching apps found @@ -113,44 +110,36 @@ def compare_application_version(app): '\tFound no matching applications on the startup disk.') return ITEM_NOT_PRESENT + # sort highest version first + try: + appinfo.sort(key=itemgetter('version'), reverse=True) + except KeyError: + # some item did not have a version key + pass + # iterate through matching applications + end_result = ITEM_NOT_PRESENT for item in appinfo: if 'name' in item: - display.display_debug2('\tName: \t %s', item['name']) - if 'path' in item: - apppath = item['path'] - display.display_debug2('\tPath: \t %s', apppath) - display.display_debug2( - '\tCFBundleIdentifier: \t %s', item['bundleid']) - - if apppath and version_comparison_key != 'CFBundleShortVersionString': - # if a specific plist version key has been supplied, - # if we're supposed to compare against a key other than - # 'CFBundleShortVersionString' we can't use item['version'] - installed_version = pkgutils.getBundleVersion( - apppath, version_comparison_key) + display.display_debug2('\tFound name: \t %s', item['name']) + display.display_debug2('\tFound path: \t %s', item['path']) + display.display_debug2( + '\tFound CFBundleIdentifier: \t %s', item['bundleid']) + # create a test_app item with our found path + test_app = {} + test_app.update(app) + test_app['path'] = item['path'] + compare_result = compare_bundle_version(test_app) + if compare_result in (VERSION_IS_THE_SAME, VERSION_IS_HIGHER): + return compare_result else: - # item['version'] is CFBundleShortVersionString - installed_version = item['version'] + end_result = compare_result - if minupvers: - if compare_versions(installed_version, minupvers) < 1: - display.display_debug1( - '\tVersion %s too old < %s', installed_version, minupvers) - # installed version is < minimum_update_version, - # too old to match, so act like it's not there at all - return ITEM_NOT_PRESENT - - if 'version' in item: - display.display_debug2('\tVersion: \t %s', installed_version) - compare_result = compare_versions(installed_version, versionstring) - if compare_result in (1, 2): - # same or greater - return compare_result - - # if we got this far, must only be older - display.display_debug1('An older version of this application is present.') - return VERSION_IS_LOWER + # didn't find an app with the same or higher version + if end_result == VERSION_IS_LOWER: + display.display_debug1( + 'An older version of this application is present.') + return end_result def compare_bundle_version(item):