Commit 09ab75a5 authored by Avi Drissman's avatar Avi Drissman Committed by Commit Bot

Mac packaging: make distributions that can share app bundles do so

Bug: 1142508
Change-Id: I8e310994740653c0d5174528b5b0ef36e9b0e32b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2499881Reviewed-by: default avatarRobert Sesek <rsesek@chromium.org>
Reviewed-by: default avatarMark Mentovai <mark@chromium.org>
Commit-Queue: Avi Drissman <avi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#822666}
parent 5beedd01
...@@ -227,6 +227,18 @@ class Distribution(object): ...@@ -227,6 +227,18 @@ class Distribution(object):
self.package_as_dmg = package_as_dmg self.package_as_dmg = package_as_dmg
self.package_as_pkg = package_as_pkg self.package_as_pkg = package_as_pkg
def brandless_copy(self):
"""Derives and returns a copy of this Distribution object, identical
except for not having a branding code.
This is useful in the case where a non-branded app bundle needs to be
created with otherwise the same configuration.
"""
return Distribution(self.channel, None, self.app_name_fragment,
self.packaging_name_fragment, self.product_dirname,
self.creator_code, self.channel_customize,
self.package_as_dmg, self.package_as_pkg)
def to_config(self, base_config): def to_config(self, base_config):
"""Produces a derived |config.CodeSignConfig| for the Distribution. """Produces a derived |config.CodeSignConfig| for the Distribution.
......
...@@ -15,6 +15,22 @@ import plistlib ...@@ -15,6 +15,22 @@ import plistlib
from . import commands, model, modification, notarize, parts, signing from . import commands, model, modification, notarize, parts, signing
def _include_branding_code_in_app(dist):
"""Returns whether to omit the branding code from the Chrome .app bundle.
If a distribution is packaged in a PKG (but is not also packaged in a DMG),
then the brand code is carried in the PKG script, and should not be added to
the .app bundle's Info.plist.
Args:
dist: The |model.Distribution|.
Returns:
Whether to include the branding code in the app bundle.
"""
return dist.package_as_dmg or not dist.package_as_pkg
def _customize_and_sign_chrome(paths, dist_config, dest_dir, signed_frameworks): def _customize_and_sign_chrome(paths, dist_config, dest_dir, signed_frameworks):
"""Does channel customization and signing of a Chrome distribution. The """Does channel customization and signing of a Chrome distribution. The
resulting app bundle is moved into |dest_dir|. resulting app bundle is moved into |dest_dir|.
...@@ -38,8 +54,15 @@ def _customize_and_sign_chrome(paths, dist_config, dest_dir, signed_frameworks): ...@@ -38,8 +54,15 @@ def _customize_and_sign_chrome(paths, dist_config, dest_dir, signed_frameworks):
os.path.join(paths.input, dist_config.base_config.app_dir), paths.work) os.path.join(paths.input, dist_config.base_config.app_dir), paths.work)
# Customize the app bundle. # Customize the app bundle.
modification.customize_distribution(paths, dist_config.distribution, customization_dist = dist_config.distribution
dist_config) customization_dist_config = dist_config
if not _include_branding_code_in_app(customization_dist):
customization_dist = dist_config.distribution.brandless_copy()
customization_dist_config = customization_dist.to_config(
dist_config.base_config)
modification.customize_distribution(paths, customization_dist,
customization_dist_config)
work_dir_framework_path = os.path.join(paths.work, work_dir_framework_path = os.path.join(paths.work,
dist_config.framework_dir) dist_config.framework_dir)
...@@ -171,23 +194,25 @@ def _component_property_path(paths, dist_config): ...@@ -171,23 +194,25 @@ def _component_property_path(paths, dist_config):
return component_property_path return component_property_path
def _productbuild_distribution_path(paths, dist_config, component_pkg_path): def _productbuild_distribution_path(app_paths, pkg_paths, dist_config,
component_pkg_path):
"""Creates a distribution XML file for use by `productbuild`. This copies """Creates a distribution XML file for use by `productbuild`. This copies
the OS requirement from the copy of Chrome being packaged. the OS requirement from the copy of Chrome being packaged.
Args: Args:
paths: A |model.Paths| object. app_paths: A |model.Paths| object for the app.
pkg_paths: A |model.Paths| object for the pkg files.
dist_config: The |config.CodeSignConfig| object. dist_config: The |config.CodeSignConfig| object.
component_pkg_path: The path to the existing component .pkg file. component_pkg_path: The path to the existing component .pkg file.
Returns: Returns:
The path to the distribution file. The path to the distribution file.
""" """
distribution_path = os.path.join(paths.work, distribution_path = os.path.join(pkg_paths.work,
'{}.dist'.format(dist_config.app_product)) '{}.dist'.format(dist_config.app_product))
app_plist_path = os.path.join(paths.work, dist_config.app_dir, 'Contents', app_plist_path = os.path.join(app_paths.work, dist_config.app_dir,
'Info.plist') 'Contents', 'Info.plist')
with commands.PlistContext(app_plist_path) as app_plist: with commands.PlistContext(app_plist_path) as app_plist:
# For now, restrict installation to only the boot volume (the <domains/> # For now, restrict installation to only the boot volume (the <domains/>
# tag) to simplify the Keystone installation. # tag) to simplify the Keystone installation.
...@@ -248,61 +273,68 @@ def _package_and_sign_pkg(paths, dist_config): ...@@ -248,61 +273,68 @@ def _package_and_sign_pkg(paths, dist_config):
""" """
assert dist_config.installer_identity assert dist_config.installer_identity
# There are two .pkg files to be built: # Because several .pkg distributions might be built from the same underlying
# 1. The inner component package (which is the one that can contain things # .app, separate the .pkg construction into its own work directory.
# like postinstall scripts). This is built with `pkgbuild`. with commands.WorkDirectory(paths) as pkg_paths:
# 2. The outer distribution package (which is the installable thing that # There are two .pkg files to be built:
# has pre-install requirements). This is built with `productbuild`. # 1. The inner component package (which is the one that can contain
# things like postinstall scripts). This is built with `pkgbuild`.
## The component package. # 2. The outer distribution package (which is the installable thing
# that has pre-install requirements). This is built with
# Because the component package is built using the --root option, copy the # `productbuild`.
# .app into a directory by itself, as `pkgbuild` archives the entire
# directory specified as the root directory. ## The component package.
root_directory = os.path.join(paths.work, 'payload')
commands.make_dir(root_directory) # Because the component package is built using the --root option, copy
app_path = os.path.join(paths.work, dist_config.app_dir) # the .app into a directory by itself, as `pkgbuild` archives the entire
new_app_path = os.path.join(root_directory, dist_config.app_dir) # directory specified as the root directory.
commands.copy_files(app_path, root_directory) root_directory = os.path.join(pkg_paths.work, 'payload')
commands.make_dir(root_directory)
# The spaces are removed from |dist_config.app_product| for the component app_path = os.path.join(paths.work, dist_config.app_dir)
# package path due to a bug in Installer.app that causes the "Show Files" new_app_path = os.path.join(root_directory, dist_config.app_dir)
# window to be blank if there is a space in a component package name. commands.copy_files(app_path, root_directory)
# https://stackoverflow.com/questions/43031272/
component_pkg_name = '{}.pkg'.format(dist_config.app_product).replace( # The spaces are removed from |dist_config.app_product| for the
' ', '') # component package path due to a bug in Installer.app that causes the
component_pkg_path = os.path.join(paths.work, component_pkg_name) # "Show Files" window to be blank if there is a space in a component
component_property_path = _component_property_path(paths, dist_config) # package name. https://stackoverflow.com/questions/43031272/
scripts_path = _create_pkgbuild_scripts(paths, dist_config) component_pkg_name = '{}.pkg'.format(dist_config.app_product).replace(
' ', '')
commands.run_command([ component_pkg_path = os.path.join(pkg_paths.work, component_pkg_name)
'pkgbuild', '--root', root_directory, '--component-plist', component_property_path = _component_property_path(
component_property_path, '--identifier', dist_config.base_bundle_id, pkg_paths, dist_config)
'--version', dist_config.version, '--install-location', '/Applications', scripts_path = _create_pkgbuild_scripts(pkg_paths, dist_config)
'--scripts', scripts_path, component_pkg_path
]) commands.run_command([
'pkgbuild', '--root', root_directory, '--component-plist',
## The distribution package. component_property_path, '--identifier', dist_config.base_bundle_id,
'--version', dist_config.version, '--install-location',
distribution_path = _productbuild_distribution_path(paths, dist_config, '/Applications', '--scripts', scripts_path, component_pkg_path
component_pkg_path) ])
product_pkg_path = os.path.join( ## The distribution package.
paths.output, '{}.pkg'.format(dist_config.packaging_basename))
distribution_path = _productbuild_distribution_path(
command = [ paths, pkg_paths, dist_config, component_pkg_path)
'productbuild', '--identifier', dist_config.base_bundle_id, '--version',
dist_config.version, '--distribution', distribution_path, product_pkg_path = os.path.join(
'--package-path', paths.work, '--sign', dist_config.installer_identity pkg_paths.output, '{}.pkg'.format(dist_config.packaging_basename))
]
if dist_config.notary_user: command = [
# Assume if the config has notary authentication information that the 'productbuild', '--identifier', dist_config.base_bundle_id,
# products will be notarized, which requires a secure timestamp. '--version', dist_config.version, '--distribution',
command.append('--timestamp') distribution_path, '--package-path', pkg_paths.work, '--sign',
command.append(product_pkg_path) dist_config.installer_identity
commands.run_command(command) ]
if dist_config.notary_user:
# Assume if the config has notary authentication information that
# the products will be notarized, which requires a secure
# timestamp.
command.append('--timestamp')
command.append(product_pkg_path)
commands.run_command(command)
return product_pkg_path return product_pkg_path
def _package_and_sign_dmg(paths, dist_config): def _package_and_sign_dmg(paths, dist_config):
...@@ -442,20 +474,40 @@ def _package_installer_tools(paths, config): ...@@ -442,20 +474,40 @@ def _package_installer_tools(paths, config):
cwd=paths.work) cwd=paths.work)
def _intermediate_work_dir_name(dist_config): def _intermediate_work_dir_name(dist):
"""Returns the name of an intermediate work directory for a distribution. """Returns the name of an intermediate work directory for a distribution.
All distributions that can share the same app bundle share the intermediate
work directory.
Just about any customization in the distribution will require it to have its
own app bundle. However, if a distribution is packaged in a PKG (but is not
also packaged in a DMG), then the brand code is carried in the PKG script,
and the distribution can share the app bundle of a different distribution
which is unbranded but for which all the other customizations match.
Args: Args:
dist_config: A |config.CodeSignConfig| for the |model.Distribution|. dist: The |model.Distribution|.
Returns: Returns:
The work directory name to use. The work directory name to use.
""" """
if dist_config.distribution.branding_code: customizations = []
return '{}-{}'.format(dist_config.packaging_basename, if dist.channel_customize:
dist_config.distribution.branding_code) customizations.append('sxs')
if dist.channel:
customizations.append(dist.channel)
else:
customizations.append('stable')
if dist.app_name_fragment:
customizations.append(dist.app_name_fragment)
if dist.product_dirname:
customizations.append(dist.product_dirname.replace('/', ' '))
if dist.creator_code:
customizations.append(dist.creator_code)
if dist.branding_code and _include_branding_code_in_app(dist):
customizations.append(dist.branding_code)
return dist_config.packaging_basename return '-'.join(customizations)
def sign_all(orig_paths, def sign_all(orig_paths,
...@@ -470,9 +522,10 @@ def sign_all(orig_paths, ...@@ -470,9 +522,10 @@ def sign_all(orig_paths,
Args: Args:
orig_paths: A |model.Paths| object. orig_paths: A |model.Paths| object.
config: The |config.CodeSignConfig| object. config: The |config.CodeSignConfig| object.
package_dmg: If True, the signed application bundle will be packaged disable_packaging: Whether all packaging is disabled. If True, the
into a DMG, which will also be signed. If False, the signed app unpackaged signed app bundle will be copied to |paths.output|. If
bundle will be copied to |paths.output|. False, the packaging specified in the distribution will be
performed.
do_notarization: If True, the signed application bundle will be sent for do_notarization: If True, the signed application bundle will be sent for
notarization by Apple. The resulting notarization ticket will then notarization by Apple. The resulting notarization ticket will then
be stapled. If |package_dmg| is also True, the stapled application be stapled. If |package_dmg| is also True, the stapled application
...@@ -486,6 +539,7 @@ def sign_all(orig_paths, ...@@ -486,6 +539,7 @@ def sign_all(orig_paths,
# notarization requests. # notarization requests.
uuids_to_config = {} uuids_to_config = {}
signed_frameworks = {} signed_frameworks = {}
created_app_bundles = set()
for dist in config.distributions: for dist in config.distributions:
if dist.branding_code in skip_brands: if dist.branding_code in skip_brands:
continue continue
...@@ -502,8 +556,17 @@ def sign_all(orig_paths, ...@@ -502,8 +556,17 @@ def sign_all(orig_paths,
else: else:
dest_dir = notary_paths.work dest_dir = notary_paths.work
dest_dir = os.path.join( dest_dir = os.path.join(dest_dir,
dest_dir, _intermediate_work_dir_name(dist_config)) _intermediate_work_dir_name(dist))
# Different distributions might share the same underlying app
# bundle, and if they do, then the _intermediate_work_dir_name
# function will return the same value. Skip creating another app
# bundle if that is the case.
if dest_dir in created_app_bundles:
continue
created_app_bundles.add(dest_dir)
_customize_and_sign_chrome(paths, dist_config, dest_dir, _customize_and_sign_chrome(paths, dist_config, dest_dir,
signed_frameworks) signed_frameworks)
...@@ -527,7 +590,8 @@ def sign_all(orig_paths, ...@@ -527,7 +590,8 @@ def sign_all(orig_paths,
config): config):
dist_config = uuids_to_config[result] dist_config = uuids_to_config[result]
dest_dir = os.path.join( dest_dir = os.path.join(
notary_paths.work, _intermediate_work_dir_name(dist_config)) notary_paths.work,
_intermediate_work_dir_name(dist_config.distribution))
_staple_chrome(notary_paths.replace_work(dest_dir), dist_config) _staple_chrome(notary_paths.replace_work(dest_dir), dist_config)
# After all apps are optionally notarized, package as required. # After all apps are optionally notarized, package as required.
...@@ -539,8 +603,9 @@ def sign_all(orig_paths, ...@@ -539,8 +603,9 @@ def sign_all(orig_paths,
dist_config = dist.to_config(config) dist_config = dist.to_config(config)
paths = orig_paths.replace_work( paths = orig_paths.replace_work(
os.path.join(notary_paths.work, os.path.join(
_intermediate_work_dir_name(dist_config))) notary_paths.work,
_intermediate_work_dir_name(dist_config.distribution)))
if dist.package_as_dmg: if dist.package_as_dmg:
dmg_path = _package_and_sign_dmg(paths, dist_config) dmg_path = _package_and_sign_dmg(paths, dist_config)
......
...@@ -20,15 +20,15 @@ _get_work_dir.count = 0 ...@@ -20,15 +20,15 @@ _get_work_dir.count = 0
def _component_property_path(paths, dist_config): def _component_property_path(paths, dist_config):
return '/$W/App Product.plist' return '/$W_1/App Product.plist'
def _productbuild_distribution_path(p, d, c): def _productbuild_distribution_path(ap, pp, d, c):
return '/$W/App Product.dist' return '/$W_1/App Product.dist'
def _create_pkgbuild_scripts(p, d): def _create_pkgbuild_scripts(p, d):
return '/$W/scripts' return '/$W_1/scripts'
def _read_plist(p): def _read_plist(p):
...@@ -361,7 +361,7 @@ framework dir is 'App Product.app/Contents/Frameworks/Product Framework.framewor ...@@ -361,7 +361,7 @@ framework dir is 'App Product.app/Contents/Frameworks/Product Framework.framewor
self.assertEqual( self.assertEqual(
'/$W/App Product.dist', '/$W/App Product.dist',
pipeline._productbuild_distribution_path(paths, dist_config, pipeline._productbuild_distribution_path(paths, paths, dist_config,
component_pkg_path)) component_pkg_path))
manager.assert_has_calls([ manager.assert_has_calls([
...@@ -439,15 +439,15 @@ framework dir is 'App Product.app/Contents/Frameworks/Product Framework.framewor ...@@ -439,15 +439,15 @@ framework dir is 'App Product.app/Contents/Frameworks/Product Framework.framewor
pkgbuild_args = run_commands[0][1][0] pkgbuild_args = run_commands[0][1][0]
productbuild_args = run_commands[1][1][0] productbuild_args = run_commands[1][1][0]
self.assertEqual('/$W/payload', self.assertEqual('/$W_1/payload',
_get_adjacent_item(pkgbuild_args, '--root')) _get_adjacent_item(pkgbuild_args, '--root'))
self.assertEqual('/$W/App Product.plist', self.assertEqual('/$W_1/App Product.plist',
_get_adjacent_item(pkgbuild_args, '--component-plist')) _get_adjacent_item(pkgbuild_args, '--component-plist'))
self.assertEqual('test.signing.bundle_id', self.assertEqual('test.signing.bundle_id',
_get_adjacent_item(pkgbuild_args, '--identifier')) _get_adjacent_item(pkgbuild_args, '--identifier'))
self.assertEqual('99.0.9999.99', self.assertEqual('99.0.9999.99',
_get_adjacent_item(pkgbuild_args, '--version')) _get_adjacent_item(pkgbuild_args, '--version'))
self.assertEqual('/$W/scripts', self.assertEqual('/$W_1/scripts',
_get_adjacent_item(pkgbuild_args, '--scripts')) _get_adjacent_item(pkgbuild_args, '--scripts'))
self.assertEqual('test.signing.bundle_id', self.assertEqual('test.signing.bundle_id',
...@@ -455,10 +455,10 @@ framework dir is 'App Product.app/Contents/Frameworks/Product Framework.framewor ...@@ -455,10 +455,10 @@ framework dir is 'App Product.app/Contents/Frameworks/Product Framework.framewor
self.assertEqual('99.0.9999.99', self.assertEqual('99.0.9999.99',
_get_adjacent_item(productbuild_args, '--version')) _get_adjacent_item(productbuild_args, '--version'))
self.assertEqual( self.assertEqual(
'/$W/App Product.dist', '/$W_1/App Product.dist',
_get_adjacent_item(productbuild_args, '--distribution')) _get_adjacent_item(productbuild_args, '--distribution'))
self.assertEqual( self.assertEqual(
'/$W', _get_adjacent_item(productbuild_args, '--package-path')) '/$W_1', _get_adjacent_item(productbuild_args, '--package-path'))
self.assertEqual('[INSTALLER-IDENTITY]', self.assertEqual('[INSTALLER-IDENTITY]',
_get_adjacent_item(productbuild_args, '--sign')) _get_adjacent_item(productbuild_args, '--sign'))
...@@ -531,15 +531,15 @@ framework dir is 'App Product.app/Contents/Frameworks/Product Framework.framewor ...@@ -531,15 +531,15 @@ framework dir is 'App Product.app/Contents/Frameworks/Product Framework.framewor
pkgbuild_args = run_commands[0][1][0] pkgbuild_args = run_commands[0][1][0]
productbuild_args = run_commands[1][1][0] productbuild_args = run_commands[1][1][0]
self.assertEqual('/$W/payload', self.assertEqual('/$W_1/payload',
_get_adjacent_item(pkgbuild_args, '--root')) _get_adjacent_item(pkgbuild_args, '--root'))
self.assertEqual('/$W/App Product.plist', self.assertEqual('/$W_1/App Product.plist',
_get_adjacent_item(pkgbuild_args, '--component-plist')) _get_adjacent_item(pkgbuild_args, '--component-plist'))
self.assertEqual('test.signing.bundle_id', self.assertEqual('test.signing.bundle_id',
_get_adjacent_item(pkgbuild_args, '--identifier')) _get_adjacent_item(pkgbuild_args, '--identifier'))
self.assertEqual('99.0.9999.99', self.assertEqual('99.0.9999.99',
_get_adjacent_item(pkgbuild_args, '--version')) _get_adjacent_item(pkgbuild_args, '--version'))
self.assertEqual('/$W/scripts', self.assertEqual('/$W_1/scripts',
_get_adjacent_item(pkgbuild_args, '--scripts')) _get_adjacent_item(pkgbuild_args, '--scripts'))
self.assertEqual('test.signing.bundle_id', self.assertEqual('test.signing.bundle_id',
...@@ -547,10 +547,10 @@ framework dir is 'App Product.app/Contents/Frameworks/Product Framework.framewor ...@@ -547,10 +547,10 @@ framework dir is 'App Product.app/Contents/Frameworks/Product Framework.framewor
self.assertEqual('99.0.9999.99', self.assertEqual('99.0.9999.99',
_get_adjacent_item(productbuild_args, '--version')) _get_adjacent_item(productbuild_args, '--version'))
self.assertEqual( self.assertEqual(
'/$W/App Product.dist', '/$W_1/App Product.dist',
_get_adjacent_item(productbuild_args, '--distribution')) _get_adjacent_item(productbuild_args, '--distribution'))
self.assertEqual( self.assertEqual(
'/$W', _get_adjacent_item(productbuild_args, '--package-path')) '/$W_1', _get_adjacent_item(productbuild_args, '--package-path'))
self.assertEqual('[INSTALLER-IDENTITY]', self.assertEqual('[INSTALLER-IDENTITY]',
_get_adjacent_item(productbuild_args, '--sign')) _get_adjacent_item(productbuild_args, '--sign'))
...@@ -795,21 +795,20 @@ class TestSignAll(unittest.TestCase): ...@@ -795,21 +795,20 @@ class TestSignAll(unittest.TestCase):
manager.assert_has_calls([ manager.assert_has_calls([
# First customize the distribution and sign it. # First customize the distribution and sign it.
mock.call._customize_and_sign_chrome( mock.call._customize_and_sign_chrome(mock.ANY, mock.ANY,
mock.ANY, mock.ANY, '/$W_1/AppProduct-99.0.9999.99', mock.ANY), '/$W_1/stable', mock.ANY),
# Prepare the app for notarization. # Prepare the app for notarization.
mock.call.run_command([ mock.call.run_command([
'zip', '--recurse-paths', '--symlinks', '--quiet', 'zip', '--recurse-paths', '--symlinks', '--quiet',
'/$W_1/AppProduct-99.0.9999.99.zip', 'App Product.app' '/$W_1/AppProduct-99.0.9999.99.zip', 'App Product.app'
], ],
cwd='/$W_1/AppProduct-99.0.9999.99'), cwd='/$W_1/stable'),
mock.call.submit('/$W_1/AppProduct-99.0.9999.99.zip', mock.ANY), mock.call.submit('/$W_1/AppProduct-99.0.9999.99.zip', mock.ANY),
mock.call.shutil.rmtree('/$W_2'), mock.call.shutil.rmtree('/$W_2'),
mock.call.wait_for_results({app_uuid: None}.keys(), mock.ANY), mock.call.wait_for_results({app_uuid: None}.keys(), mock.ANY),
mock.call._staple_chrome( mock.call._staple_chrome(
self.paths.replace_work('/$W_1/AppProduct-99.0.9999.99'), self.paths.replace_work('/$W_1/stable'), mock.ANY),
mock.ANY),
# Make the DMG. # Make the DMG.
mock.call._package_and_sign_dmg(mock.ANY, mock.ANY), mock.call._package_and_sign_dmg(mock.ANY, mock.ANY),
...@@ -854,21 +853,20 @@ class TestSignAll(unittest.TestCase): ...@@ -854,21 +853,20 @@ class TestSignAll(unittest.TestCase):
manager.assert_has_calls([ manager.assert_has_calls([
# First customize the distribution and sign it. # First customize the distribution and sign it.
mock.call._customize_and_sign_chrome( mock.call._customize_and_sign_chrome(mock.ANY, mock.ANY,
mock.ANY, mock.ANY, '/$W_1/AppProduct-99.0.9999.99', mock.ANY), '/$W_1/stable', mock.ANY),
# Prepare the app for notarization. # Prepare the app for notarization.
mock.call.run_command([ mock.call.run_command([
'zip', '--recurse-paths', '--symlinks', '--quiet', 'zip', '--recurse-paths', '--symlinks', '--quiet',
'/$W_1/AppProduct-99.0.9999.99.zip', 'App Product.app' '/$W_1/AppProduct-99.0.9999.99.zip', 'App Product.app'
], ],
cwd='/$W_1/AppProduct-99.0.9999.99'), cwd='/$W_1/stable'),
mock.call.submit('/$W_1/AppProduct-99.0.9999.99.zip', mock.ANY), mock.call.submit('/$W_1/AppProduct-99.0.9999.99.zip', mock.ANY),
mock.call.shutil.rmtree('/$W_2'), mock.call.shutil.rmtree('/$W_2'),
mock.call.wait_for_results({app_uuid: None}.keys(), mock.ANY), mock.call.wait_for_results({app_uuid: None}.keys(), mock.ANY),
mock.call._staple_chrome( mock.call._staple_chrome(
self.paths.replace_work('/$W_1/AppProduct-99.0.9999.99'), self.paths.replace_work('/$W_1/stable'), mock.ANY),
mock.ANY),
# Make the DMG. # Make the DMG.
mock.call._package_and_sign_pkg(mock.ANY, mock.ANY), mock.call._package_and_sign_pkg(mock.ANY, mock.ANY),
...@@ -916,21 +914,20 @@ class TestSignAll(unittest.TestCase): ...@@ -916,21 +914,20 @@ class TestSignAll(unittest.TestCase):
manager.assert_has_calls([ manager.assert_has_calls([
# First customize the distribution and sign it. # First customize the distribution and sign it.
mock.call._customize_and_sign_chrome( mock.call._customize_and_sign_chrome(mock.ANY, mock.ANY,
mock.ANY, mock.ANY, '/$W_1/AppProduct-99.0.9999.99', mock.ANY), '/$W_1/stable', mock.ANY),
# Prepare the app for notarization. # Prepare the app for notarization.
mock.call.run_command([ mock.call.run_command([
'zip', '--recurse-paths', '--symlinks', '--quiet', 'zip', '--recurse-paths', '--symlinks', '--quiet',
'/$W_1/AppProduct-99.0.9999.99.zip', 'App Product.app' '/$W_1/AppProduct-99.0.9999.99.zip', 'App Product.app'
], ],
cwd='/$W_1/AppProduct-99.0.9999.99'), cwd='/$W_1/stable'),
mock.call.submit('/$W_1/AppProduct-99.0.9999.99.zip', mock.ANY), mock.call.submit('/$W_1/AppProduct-99.0.9999.99.zip', mock.ANY),
mock.call.shutil.rmtree('/$W_2'), mock.call.shutil.rmtree('/$W_2'),
mock.call.wait_for_results({app_uuid: None}.keys(), mock.ANY), mock.call.wait_for_results({app_uuid: None}.keys(), mock.ANY),
mock.call._staple_chrome( mock.call._staple_chrome(
self.paths.replace_work('/$W_1/AppProduct-99.0.9999.99'), self.paths.replace_work('/$W_1/stable'), mock.ANY),
mock.ANY),
# Make the DMG, and submit for notarization. # Make the DMG, and submit for notarization.
mock.call._package_and_sign_dmg(mock.ANY, mock.ANY), mock.call._package_and_sign_dmg(mock.ANY, mock.ANY),
...@@ -967,21 +964,20 @@ class TestSignAll(unittest.TestCase): ...@@ -967,21 +964,20 @@ class TestSignAll(unittest.TestCase):
manager.assert_has_calls([ manager.assert_has_calls([
# First customize the distribution and sign it. # First customize the distribution and sign it.
mock.call._customize_and_sign_chrome( mock.call._customize_and_sign_chrome(mock.ANY, mock.ANY,
mock.ANY, mock.ANY, '/$W_1/AppProduct-99.0.9999.99', mock.ANY), '/$W_1/stable', mock.ANY),
# Prepare the app for notarization. # Prepare the app for notarization.
mock.call.run_command([ mock.call.run_command([
'zip', '--recurse-paths', '--symlinks', '--quiet', 'zip', '--recurse-paths', '--symlinks', '--quiet',
'/$W_1/AppProduct-99.0.9999.99.zip', 'App Product.app' '/$W_1/AppProduct-99.0.9999.99.zip', 'App Product.app'
], ],
cwd='/$W_1/AppProduct-99.0.9999.99'), cwd='/$W_1/stable'),
mock.call.submit('/$W_1/AppProduct-99.0.9999.99.zip', mock.ANY), mock.call.submit('/$W_1/AppProduct-99.0.9999.99.zip', mock.ANY),
mock.call.shutil.rmtree('/$W_2'), mock.call.shutil.rmtree('/$W_2'),
mock.call.wait_for_results({app_uuid: None}.keys(), mock.ANY), mock.call.wait_for_results({app_uuid: None}.keys(), mock.ANY),
mock.call._staple_chrome( mock.call._staple_chrome(
self.paths.replace_work('/$W_1/AppProduct-99.0.9999.99'), self.paths.replace_work('/$W_1/stable'), mock.ANY),
mock.ANY),
mock.call.shutil.rmtree('/$W_1'), mock.call.shutil.rmtree('/$W_1'),
# Package the installer tools. # Package the installer tools.
...@@ -1003,8 +999,8 @@ class TestSignAll(unittest.TestCase): ...@@ -1003,8 +999,8 @@ class TestSignAll(unittest.TestCase):
manager.assert_has_calls([ manager.assert_has_calls([
# First customize the distribution and sign it. # First customize the distribution and sign it.
mock.call._customize_and_sign_chrome( mock.call._customize_and_sign_chrome(mock.ANY, mock.ANY,
mock.ANY, mock.ANY, '/$W_1/AppProduct-99.0.9999.99', mock.ANY), '/$W_1/stable', mock.ANY),
mock.call.shutil.rmtree('/$W_2'), mock.call.shutil.rmtree('/$W_2'),
# Make the DMG. # Make the DMG.
...@@ -1027,8 +1023,7 @@ class TestSignAll(unittest.TestCase): ...@@ -1027,8 +1023,7 @@ class TestSignAll(unittest.TestCase):
manager.assert_has_calls([ manager.assert_has_calls([
# First customize the distribution and sign it. # First customize the distribution and sign it.
mock.call._customize_and_sign_chrome(mock.ANY, mock.ANY, mock.call._customize_and_sign_chrome(mock.ANY, mock.ANY,
'/$O/AppProduct-99.0.9999.99', '/$O/stable', mock.ANY),
mock.ANY),
mock.call.shutil.rmtree('/$W_2'), mock.call.shutil.rmtree('/$W_2'),
mock.call.shutil.rmtree('/$W_1'), mock.call.shutil.rmtree('/$W_1'),
...@@ -1071,42 +1066,32 @@ class TestSignAll(unittest.TestCase): ...@@ -1071,42 +1066,32 @@ class TestSignAll(unittest.TestCase):
pipeline.sign_all(self.paths, config, do_notarization=False) pipeline.sign_all(self.paths, config, do_notarization=False)
self.assertEqual(1, kwargs['_package_installer_tools'].call_count) self.assertEqual(1, kwargs['_package_installer_tools'].call_count)
self.assertEqual(4, kwargs['_customize_and_sign_chrome'].call_count) self.assertEqual(3, kwargs['_customize_and_sign_chrome'].call_count)
manager.assert_has_calls([ manager.assert_has_calls([
# Customizations. # Customizations.
mock.call._customize_and_sign_chrome( mock.call._customize_and_sign_chrome(mock.ANY, mock.ANY,
mock.ANY, mock.ANY, '/$W_1/AppProduct-99.0.9999.99', mock.ANY), '/$W_1/stable', mock.ANY),
mock.call.shutil.rmtree('/$W_2'), mock.call.shutil.rmtree('/$W_2'),
mock.call._customize_and_sign_chrome( mock.call._customize_and_sign_chrome(mock.ANY, mock.ANY,
mock.ANY, mock.ANY, '/$W_1/AppProduct-99.0.9999.99-ForCows-MOO', '/$W_1/stable-MOO', mock.ANY),
mock.ANY),
mock.call.shutil.rmtree('/$W_3'), mock.call.shutil.rmtree('/$W_3'),
mock.call._customize_and_sign_chrome(
mock.ANY, mock.ANY, '/$W_1/AppProduct-99.0.9999.99-ForDogs-ARF',
mock.ANY),
mock.call.shutil.rmtree('/$W_4'), mock.call.shutil.rmtree('/$W_4'),
mock.call._customize_and_sign_chrome( mock.call._customize_and_sign_chrome(mock.ANY, mock.ANY,
mock.ANY, mock.ANY, '/$W_1/stable-MOOF', mock.ANY),
'/$W_1/AppProduct-99.0.9999.99-ForDogcows-MOOF', mock.ANY),
mock.call.shutil.rmtree('/$W_5'), mock.call.shutil.rmtree('/$W_5'),
# Packaging and signing. # Packaging and signing.
mock.call._package_and_sign_dmg( mock.call._package_and_sign_dmg(
self.paths.replace_work('/$W_1/AppProduct-99.0.9999.99'), self.paths.replace_work('/$W_1/stable'), mock.ANY),
mock.ANY),
mock.call._package_and_sign_dmg( mock.call._package_and_sign_dmg(
self.paths.replace_work( self.paths.replace_work('/$W_1/stable-MOO'), mock.ANY),
'/$W_1/AppProduct-99.0.9999.99-ForCows-MOO'), mock.ANY),
mock.call._package_and_sign_pkg( mock.call._package_and_sign_pkg(
self.paths.replace_work( self.paths.replace_work('/$W_1/stable'), mock.ANY),
'/$W_1/AppProduct-99.0.9999.99-ForDogs-ARF'), mock.ANY),
mock.call._package_and_sign_dmg( mock.call._package_and_sign_dmg(
self.paths.replace_work( self.paths.replace_work('/$W_1/stable-MOOF'), mock.ANY),
'/$W_1/AppProduct-99.0.9999.99-ForDogcows-MOOF'), mock.ANY),
mock.call._package_and_sign_pkg( mock.call._package_and_sign_pkg(
self.paths.replace_work( self.paths.replace_work('/$W_1/stable-MOOF'), mock.ANY),
'/$W_1/AppProduct-99.0.9999.99-ForDogcows-MOOF'), mock.ANY),
mock.call.shutil.rmtree('/$W_1'), mock.call.shutil.rmtree('/$W_1'),
# Finally the installer tools. # Finally the installer tools.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment