Skip to content

Commit

Permalink
meta: fix management of snap/local (#2502)
Browse files Browse the repository at this point in the history
Do not copy snap/local into the snap, furthermore, improve the copy
logic to work better with embedded directories.

Fixes SNAPCRAFT-J2
Fixes SNAPCRAFT-JB

Signed-off-by: Sergio Schvezov <sergio.schvezov@canonical.com>
  • Loading branch information
sergiusens authored Mar 15, 2019
1 parent 3f7d63c commit e48cd84
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 46 deletions.
53 changes: 13 additions & 40 deletions snapcraft/internal/meta/_snap_packaging.py
Original file line number Diff line number Diff line change
Expand Up @@ -433,44 +433,15 @@ def _record_manifest_and_source_snapcraft_yaml(self):
yaml_utils.dump(annotated_snapcraft, stream=manifest_file)

def write_snap_directory(self) -> None:
# First migrate the snap directory. It will overwrite any conflicting
# files.
for root, directories, files in os.walk(
self._project_config.project._get_snapcraft_assets_dir()
):
with contextlib.suppress(ValueError):
directories.remove(".snapcraft")
with contextlib.suppress(ValueError):
# The snapcraft.yaml is migrated later
files.remove("snapcraft.yaml")

for directory in directories:
source = os.path.relpath(
os.path.join(root, directory),
self._project_config.project._work_dir,
)
# Also build-aux from destination
destination = os.path.join(self._prime_dir, source.lstrip("build-aux/"))
file_utils.create_similar_directory(source, destination)

for file_path in files:
source = os.path.relpath(
os.path.join(root, file_path),
self._project_config.project._work_dir,
)
# Also build-aux from destination
destination = os.path.join(self._prime_dir, source.lstrip("build-aux/"))
with contextlib.suppress(FileNotFoundError):
os.remove(destination)
file_utils.link_or_copy(source, destination)

# Now copy the assets contained within the snap directory directly into
# meta.
for origin in ["gui", "hooks"]:
src_dir = os.path.join(
self._project_config.project._get_snapcraft_assets_dir(), origin
)
dst_dir = os.path.join(self.meta_dir, origin)
snap_assets_dir = self._project_config.project._get_snapcraft_assets_dir()
prime_snap_dir = os.path.join(self._prime_dir, "snap")

snap_dir_iter = itertools.product([prime_snap_dir], ["hooks"])
meta_dir_iter = itertools.product([self._meta_dir], ["hooks", "gui"])

for origin in itertools.chain(snap_dir_iter, meta_dir_iter):
src_dir = os.path.join(snap_assets_dir, origin[1])
dst_dir = os.path.join(origin[0], origin[1])
if os.path.isdir(src_dir):
os.makedirs(dst_dir, exist_ok=True)
for asset in os.listdir(src_dir):
Expand All @@ -482,8 +453,10 @@ def write_snap_directory(self) -> None:

file_utils.link_or_copy(source, destination, follow_symlinks=True)

# Ensure that the hook is executable
if origin == "hooks":
# Ensure that the hook is executable in meta/hooks, this is a moot
# point considering the prior link_or_copy call, but is technically
# correct and allows for this operation to take place only once.
if origin[0] == self._meta_dir and origin[1] == "hooks":
_prepare_hook(destination)

self._record_manifest_and_source_snapcraft_yaml()
Expand Down
37 changes: 31 additions & 6 deletions tests/unit/test_meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -859,13 +859,17 @@ def test_create_meta_with_hook(self):
)

for hook in ("foo", "bar"):
generated_hook_path = os.path.join(self.prime_dir, "meta", "hooks", hook)
self.assertThat(
generated_hook_path,
FileExists(),
"The {!r} hook was not setup correctly".format(hook),
)
meta_dir_hook_path = os.path.join(self.prime_dir, "meta", "hooks", hook)
snap_dir_hook_path = os.path.join(self.prime_dir, "snap", "hooks", hook)

for hook_location in (meta_dir_hook_path, snap_dir_hook_path):
self.assertThat(
hook_location,
FileExists(),
"The {!r} hook was not setup correctly".format(hook),
)

for hook in ("foo", "bar"):
self.assertThat(
y["hooks"],
Contains(hook),
Expand All @@ -885,6 +889,27 @@ def test_create_meta_with_hook(self):
"Expected generated 'bar' hook to not contain 'plugs'",
)

def test_local_is_not_copied_to_snap(self):
project_local_dir = os.path.join(self.snapcraft_assets_dir, "local")
local_file = "file"
local_subdir_file = os.path.join("dir", "file")

os.makedirs(os.path.join(project_local_dir, "dir"))
_create_file(os.path.join(project_local_dir, local_file))
_create_file(os.path.join(project_local_dir, local_subdir_file))

self.generate_meta_yaml(
snapcraft_yaml_file_path=os.path.join(
self.snapcraft_assets_dir, "snapcraft.yaml"
)
)

prime_local_dir = os.path.join(self.prime_dir, "snap", "local")
self.assertThat(os.path.join(prime_local_dir, local_file), Not(FileExists()))
self.assertThat(
os.path.join(prime_local_dir, local_subdir_file), Not(FileExists())
)


class MetadataFromSourceWithIconFileTestCase(CreateMetadataFromSourceBaseTestCase):

Expand Down

0 comments on commit e48cd84

Please sign in to comment.