mirror of
https://github.com/munki/munki.git
synced 2026-04-22 20:48:36 -05:00
Key name changes and behavior tweaks to Heig's submission for support for bundle/plist version keys other than CFBundleShortVersionString
This commit is contained in:
@@ -1165,22 +1165,34 @@ def padVersionString(versString, tupleCount):
|
||||
return '.'.join(components)
|
||||
|
||||
|
||||
def getVersionString(plist,key='CFBundleShortVersionString'):
|
||||
def getVersionString(plist, key=None):
|
||||
"""Gets a version string from the plist.
|
||||
By default, if there's a CFBundleShortVersionString, returns that.
|
||||
|
||||
If a key is explictly specified, the value of that key is
|
||||
returned without modification, or an empty string if the
|
||||
key does not exist.
|
||||
|
||||
If key is not specified:
|
||||
if there's a valid CFBundleShortVersionString, returns that.
|
||||
else if there's a CFBundleVersion, returns that
|
||||
else returns an empty string.
|
||||
|
||||
If a 'key' other than CFBundleShortVersionString is passed,
|
||||
and the 'key' exists in the plist, its value is returned,
|
||||
otherwise, returns an empty string and does NOT attempt to
|
||||
retrieve the version from CFBundleVersion.
|
||||
"""
|
||||
VersionString = ''
|
||||
if key:
|
||||
return plist.get(key, '')
|
||||
|
||||
# default to CFBundleShortVersionString plus magic
|
||||
key = 'CFBundleShortVersionString'
|
||||
if not 'CFBundleShortVersionString' in plist:
|
||||
if 'Bundle versions string, short' in plist:
|
||||
# workaround for broken Composer packages
|
||||
# where the key is actually named
|
||||
# 'Bundle versions string, short' instead of
|
||||
# 'CFBundleShortVersionString'
|
||||
key = 'Bundle versions string, short'
|
||||
if plist.get(key):
|
||||
VersionString = plist[key].split()[0]
|
||||
if 'Bundle versions string, short' in plist:
|
||||
VersionString = plist['Bundle versions string, short'].split()[0]
|
||||
if VersionString:
|
||||
if VersionString[0] in '0123456789':
|
||||
# starts with a number; that's good
|
||||
@@ -1188,12 +1200,11 @@ def getVersionString(plist,key='CFBundleShortVersionString'):
|
||||
# replace commas with periods
|
||||
VersionString = VersionString.replace(',','.')
|
||||
return VersionString
|
||||
if key != 'CFBundleShortVersionString':
|
||||
# an arbitrary key has been provided so return its value or,
|
||||
# if it doesn't exist, an empty string
|
||||
return VersionString
|
||||
if plist.get('CFBundleVersion'):
|
||||
# no CFBundleShortVersionString, or bad one
|
||||
# a future version of the Munki tools may drop this magic
|
||||
# and require admins to explicitly choose the CFBundleVersion
|
||||
# but for now Munki does some magic
|
||||
VersionString = str(plist['CFBundleVersion']).split()[0]
|
||||
if VersionString[0] in '0123456789':
|
||||
# starts with a number; that's good
|
||||
@@ -1205,15 +1216,20 @@ def getVersionString(plist,key='CFBundleShortVersionString'):
|
||||
return ''
|
||||
|
||||
|
||||
def getExtendedVersion(bundlepath):
|
||||
def getBundleVersion(bundlepath, key=None):
|
||||
"""
|
||||
Returns five-part version number like Apple uses in distribution
|
||||
and flat packages
|
||||
Returns version number from a bundle.
|
||||
Some extra code to deal with very old-style bundle packages
|
||||
|
||||
Specify key to use a specific key in the Info.plist for
|
||||
the version string.
|
||||
"""
|
||||
infoPlist = os.path.join(bundlepath, 'Contents', 'Info.plist')
|
||||
if not os.path.exists(infoPlist):
|
||||
infoPlist = os.path.join(bundlepath, 'Resources', 'Info.plist')
|
||||
if os.path.exists(infoPlist):
|
||||
plist = FoundationPlist.readPlist(infoPlist)
|
||||
versionstring = getVersionString(plist)
|
||||
versionstring = getVersionString(plist, key)
|
||||
if versionstring:
|
||||
return versionstring
|
||||
|
||||
@@ -1409,7 +1425,7 @@ def getOnePackageInfo(pkgpath):
|
||||
if 'IFPkgFlagInstalledSize' in plist:
|
||||
pkginfo['installed_size'] = plist['IFPkgFlagInstalledSize']
|
||||
|
||||
pkginfo['version'] = getExtendedVersion(pkgpath)
|
||||
pkginfo['version'] = getBundleVersion(pkgpath)
|
||||
except (AttributeError,
|
||||
FoundationPlist.NSPropertyListSerializationException):
|
||||
pkginfo['packageid'] = 'BAD PLIST in %s' % \
|
||||
@@ -1689,7 +1705,7 @@ def getPackageMetaData(pkgitem):
|
||||
|
||||
name = os.path.split(pkgitem)[1]
|
||||
shortname = os.path.splitext(name)[0]
|
||||
metaversion = getExtendedVersion(pkgitem)
|
||||
metaversion = getBundleVersion(pkgitem)
|
||||
if metaversion == '0.0.0.0.0':
|
||||
metaversion = nameAndVersion(shortname)[1]
|
||||
|
||||
@@ -2032,7 +2048,7 @@ def getAppData():
|
||||
iteminfo['bundleid'] = plist.get('CFBundleIdentifier','')
|
||||
if 'CFBundleName' in plist:
|
||||
iteminfo['name'] = plist['CFBundleName']
|
||||
iteminfo['version'] = getExtendedVersion(pathname)
|
||||
iteminfo['version'] = getBundleVersion(pathname)
|
||||
APPDATA.append(iteminfo)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@@ -392,16 +392,17 @@ def compareApplicationVersion(app):
|
||||
|
||||
Raises munkicommon.Error if there's an error in the input
|
||||
"""
|
||||
if 'path' in app and 'VersionString' in app:
|
||||
if 'path' in app:
|
||||
filepath = os.path.join(app['path'], 'Contents', 'Info.plist')
|
||||
if os.path.exists(filepath):
|
||||
return compareBundleVersion(app)
|
||||
|
||||
# not in default location, so let's search:
|
||||
# not in default location, or no path specified, so let's search:
|
||||
name = app.get('CFBundleName','')
|
||||
bundleid = app.get('CFBundleIdentifier','')
|
||||
versionstring = app.get('VersionString')
|
||||
plist_version_key = app.get('plist_version_key')
|
||||
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 == '':
|
||||
@@ -441,6 +442,7 @@ def compareApplicationVersion(app):
|
||||
'\tDid not find this application on the startup disk.')
|
||||
return 0
|
||||
|
||||
# iterate through matching applications
|
||||
for item in appinfo:
|
||||
if 'name' in item:
|
||||
munkicommon.display_debug2(
|
||||
@@ -452,14 +454,14 @@ def compareApplicationVersion(app):
|
||||
munkicommon.display_debug2(
|
||||
'\tCFBundleIdentifier: \t %s' % item['bundleid'])
|
||||
|
||||
if plist_version_key and apppath:
|
||||
if apppath and version_comparison_key != 'CFBundleShortVersionString':
|
||||
# if a specific plist version key has been supplied,
|
||||
# add the following keys to the discovered 'item'
|
||||
# so that a bundle version comparison can be made
|
||||
item['VersionString'] = versionstring
|
||||
item['plist_version_key'] = plist_version_key
|
||||
item['minimum_update_version'] = minupvers
|
||||
return compareBundleVersion(item)
|
||||
# if we're suppose to compare against a key other than
|
||||
# 'CFBundleShortVersionString' we can't use item['version'] as-is
|
||||
# so update item['version'] with info from the specific
|
||||
# version key
|
||||
item['version'] = munkicommon.getBundleVersion(
|
||||
apppath, version_comparison_key)
|
||||
|
||||
if minupvers:
|
||||
if compareVersions(item['version'], minupvers) < 1:
|
||||
@@ -497,14 +499,17 @@ def compareBundleVersion(item):
|
||||
|
||||
Raises munkicommon.Error if there's an error in the input
|
||||
"""
|
||||
if 'path' in item and 'VersionString' in item:
|
||||
vers = item['VersionString']
|
||||
version_comparison_key = item.get(
|
||||
'version_comparison_key', 'CFBundleShortVersionString')
|
||||
versionstring = item.get(version_comparison_key, None)
|
||||
|
||||
if 'path' in item and versionstring:
|
||||
minupvers = item.get('minimum_update_version')
|
||||
else:
|
||||
raise munkicommon.Error('Missing bundle path or version!')
|
||||
|
||||
munkicommon.display_debug1('Checking bundle %s for version %s...' %
|
||||
(item['path'], vers))
|
||||
munkicommon.display_debug1('Checking bundle %s for %s %s...' %
|
||||
(item['path'], version_comparison_key, versionstring))
|
||||
filepath = os.path.join(item['path'], 'Contents', 'Info.plist')
|
||||
if not os.path.exists(filepath):
|
||||
munkicommon.display_debug1('\tNo Info.plist found at %s' % filepath)
|
||||
@@ -521,14 +526,16 @@ def compareBundleVersion(item):
|
||||
munkicommon.display_debug1('\t%s may not be a plist!' % filepath)
|
||||
return 0
|
||||
|
||||
if 'plist_version_key' in item:
|
||||
# arbitrary key has been supplied,
|
||||
if 'version_comparison_key' in item:
|
||||
# specific key has been supplied,
|
||||
# so use this to determine installed version
|
||||
plist_version_key = item['plist_version_key']
|
||||
munkicommon.display_debug1(
|
||||
'\tUsing supplied plist key %s for comparison' % plist_version_key)
|
||||
installedvers = munkicommon.getVersionString(plist, plist_version_key)
|
||||
'\tUsing supplied plist key %s for comparison'
|
||||
% version_comparison_key)
|
||||
installedvers = munkicommon.getVersionString(
|
||||
plist, version_comparison_key)
|
||||
else:
|
||||
# use default behavior
|
||||
installedvers = munkicommon.getVersionString(plist)
|
||||
if installedvers:
|
||||
if minupvers:
|
||||
@@ -537,7 +544,7 @@ def compareBundleVersion(item):
|
||||
'\tVersion %s too old < %s' % (installedvers, minupvers))
|
||||
return 0
|
||||
|
||||
return compareVersions(installedvers, vers)
|
||||
return compareVersions(installedvers, versionstring)
|
||||
else:
|
||||
munkicommon.display_debug1('\tNo version info in %s.' % filepath)
|
||||
return 0
|
||||
@@ -553,15 +560,17 @@ def comparePlistVersion(item):
|
||||
|
||||
Raises munkicommon.Error if there's an error in the input
|
||||
"""
|
||||
if 'path' in item and 'VersionString' in item:
|
||||
vers = item['VersionString']
|
||||
version_comparison_key = item.get(
|
||||
'version_comparison_key', 'CFBundleShortVersionString')
|
||||
if 'path' in item and version_comparison_key in item:
|
||||
versionstring = item[version_comparison_key]
|
||||
filepath = item['path']
|
||||
minupvers = item.get('minimum_update_version')
|
||||
else:
|
||||
raise munkicommon.Error('Missing plist path or version!')
|
||||
|
||||
munkicommon.display_debug1('Checking %s for version %s...' %
|
||||
(filepath, vers))
|
||||
munkicommon.display_debug1('Checking %s for version %s %s...' %
|
||||
(filepath, version_comparison_key, versionstring))
|
||||
if not os.path.exists(filepath):
|
||||
munkicommon.display_debug1('\tNo plist found at %s' % filepath)
|
||||
return 0
|
||||
@@ -572,14 +581,16 @@ def comparePlistVersion(item):
|
||||
munkicommon.display_debug1('\t%s may not be a plist!' % filepath)
|
||||
return 0
|
||||
|
||||
if 'plist_version_key' in item:
|
||||
# arbitrary key has been supplied,
|
||||
if 'version_comparison_key' in item:
|
||||
# specific key has been supplied,
|
||||
# so use this to determine installed version
|
||||
plist_version_key = item['plist_version_key']
|
||||
munkicommon.display_debug1(
|
||||
'\tUsing supplied plist key %s for comparison' % plist_version_key)
|
||||
installedvers = munkicommon.getVersionString(plist, plist_version_key)
|
||||
'\tUsing supplied plist key %s for comparison'
|
||||
% version_comparison_key)
|
||||
installedvers = munkicommon.getVersionString(
|
||||
plist, version_comparison_key)
|
||||
else:
|
||||
# default behavior
|
||||
installedvers = munkicommon.getVersionString(plist)
|
||||
if installedvers:
|
||||
if minupvers:
|
||||
@@ -587,7 +598,7 @@ def comparePlistVersion(item):
|
||||
munkicommon.display_debug1(
|
||||
'\tVersion %s too old < %s' % (installedvers, minupvers))
|
||||
return 0
|
||||
return compareVersions(installedvers, vers)
|
||||
return compareVersions(installedvers, versionstring)
|
||||
else:
|
||||
munkicommon.display_debug1('\tNo version info in %s.' % filepath)
|
||||
return 0
|
||||
|
||||
Reference in New Issue
Block a user