Skip to content

Commit

Permalink
Always re-inject the chalice runtime into the zip file
Browse files Browse the repository at this point in the history
This ensures more seamless upgrades when new functionality is
added to the runtime (such as Response classes).
  • Loading branch information
jamesls committed Feb 22, 2017
1 parent 48d69a0 commit 11ccb27
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 10 deletions.
15 changes: 7 additions & 8 deletions chalice/deployer.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,21 +476,20 @@ def inject_latest_app(self, deployment_package_filename, project_dir):
with zipfile.ZipFile(deployment_package_filename, 'r') as inzip:
with zipfile.ZipFile(tmpzip, 'w') as outzip:
for el in inzip.infolist():
if self._is_chalice_app_file(el.filename):
if self._needs_latest_version(el.filename):
continue
else:
contents = inzip.read(el.filename)
outzip.writestr(el, contents)
# Then at the end, add back the app.py.
app_py = os.path.join(project_dir, 'app.py')
assert os.path.isfile(app_py), app_py
outzip.write(app_py, 'app.py')
self._add_chalice_lib_if_needed(project_dir, outzip)
# Then at the end, add back the app.py, chalicelib,
# and runtime files.
self._add_app_files(outzip, project_dir)
shutil.move(tmpzip, deployment_package_filename)

def _is_chalice_app_file(self, filename):
def _needs_latest_version(self, filename):
# type: (str) -> bool
return filename == 'app.py' or filename.startswith('chalicelib/')
return filename == 'app.py' or filename.startswith(
('chalicelib/', 'chalice/'))

def _add_chalice_lib_if_needed(self, project_dir, zip):
# type: (str, zipfile.ZipFile) -> None
Expand Down
35 changes: 33 additions & 2 deletions tests/functional/test_deployer.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ def test_app_injection_still_compresses_file(tmpdir, chalice_deployer):
new_size = os.path.getsize(name)
# The new_size won't be exactly the same as the original,
# we just want to make sure it wasn't converted to
# ZIP_STORED.
assert abs(original_size - new_size) < 10
# ZIP_STORED, so there's a 5% tolerance.
assert new_size < (original_size * 1.05)


def test_no_error_message_printed_on_empty_reqs_file(tmpdir,
Expand Down Expand Up @@ -176,3 +176,34 @@ def test_zip_filename_changes_on_vendor_update(tmpdir, chalice_deployer):
extra_package.join('__init__.py').write('# v2')
second = chalice_deployer.deployment_package_filename(str(appdir))
assert first != second


def test_chalice_runtime_injected_on_change(tmpdir, chalice_deployer):
appdir = _create_app_structure(tmpdir)
name = chalice_deployer.create_deployment_package(str(appdir))
# We're verifying that we always inject the chalice runtime
# but we can't actually modify the runtime in this repo, so
# instead we'll modify the deployment package and change the
# runtime.
# We'll then verify when we inject the latest app the runtime
# has been re-added. This should give us enough confidence
# that the runtime is always being inserted.
_remove_runtime_from_deployment_package(name)
with zipfile.ZipFile(name) as z:
assert 'chalice/app.py' not in z.namelist()
chalice_deployer.inject_latest_app(name, str(appdir))
with zipfile.ZipFile(name) as z:
assert 'chalice/app.py' in z.namelist()


def _remove_runtime_from_deployment_package(filename):
new_filename = os.path.join(os.path.dirname(filename), 'new.zip')
with zipfile.ZipFile(filename, 'r') as original:
with zipfile.ZipFile (new_filename, 'w',
compression=zipfile.ZIP_DEFLATED) as z:
for item in original.infolist():
if item.filename.startswith('chalice/'):
continue
contents = original.read(item.filename)
z.writestr(item, contents)
os.rename(new_filename, filename)

0 comments on commit 11ccb27

Please sign in to comment.