Exemple #1
0
def test_pack_snap_output_file_output_directory_non_existant(mocker, new_dir):
    """Output to a non-existent directory."""
    mock_run = mocker.patch("subprocess.run")
    output_directory = new_dir / "output"
    assert not output_directory.exists()

    pack.pack_snap(new_dir, output=output_directory / "test.snap")

    assert mock_run.mock_calls[:2] == [
        call(
            ["snap", "pack", "--check-skeleton", new_dir],
            capture_output=True,
            check=True,
            universal_newlines=True,
        ),
        call(
            [
                "snap",
                "pack",
                "--filename",
                "test.snap",
                new_dir,
                (new_dir / "output"),
            ],
            capture_output=True,
            check=True,
            universal_newlines=True,
        ),
    ]
Exemple #2
0
def test_pack_snap_error(mocker, new_dir):
    mocker.patch("subprocess.run", side_effect=subprocess.CalledProcessError(42, "cmd"))
    with pytest.raises(errors.SnapcraftError) as raised:
        pack.pack_snap(new_dir, output=str(new_dir))

    assert str(raised.value) == (
        "Cannot pack snap file: Command 'cmd' returned non-zero exit status 42."
    )
Exemple #3
0
 def run(self, parsed_args):
     """Run the command."""
     if parsed_args.directory:
         snap_filename = pack.pack_snap(parsed_args.directory,
                                        output=parsed_args.output)
         emit.message(f"Created snap package {snap_filename}")
     else:
         super().run(parsed_args)
Exemple #4
0
def test_pack_snap(mocker, new_dir):
    mock_run = mocker.patch("subprocess.run")
    pack.pack_snap(new_dir, output=None)
    assert mock_run.mock_calls[:2] == [
        call(
            ["snap", "pack", "--check-skeleton", new_dir],
            capture_output=True,
            check=True,
            universal_newlines=True,
        ),
        call(
            ["snap", "pack", new_dir, new_dir],
            capture_output=True,
            check=True,
            universal_newlines=True,
        ),
    ]
Exemple #5
0
def test_pack_snap_output_file_output_directory_cwd(mocker, new_dir):
    """Output to a filename in the current working directory."""
    mock_run = mocker.patch("subprocess.run")
    pack.pack_snap(new_dir, output=f"{new_dir}/test.snap")
    assert mock_run.mock_calls[:2] == [
        call(
            ["snap", "pack", "--check-skeleton", new_dir],
            capture_output=True,
            check=True,
            universal_newlines=True,
        ),
        call(
            ["snap", "pack", "--filename", "test.snap", new_dir, new_dir],
            capture_output=True,
            check=True,
            universal_newlines=True,
        ),
    ]
Exemple #6
0
def test_pack_snap_compression(mocker, new_dir):
    """Compression should be passed to snap pack."""
    mock_run = mocker.patch("subprocess.run")
    pack.pack_snap(new_dir, output=None, compression="zz")
    assert mock_run.mock_calls[:2] == [
        call(
            ["snap", "pack", "--check-skeleton", new_dir],
            capture_output=True,
            check=True,
            universal_newlines=True,
        ),
        call(
            ["snap", "pack", "--compression", "zz", new_dir, new_dir],
            capture_output=True,
            check=True,
            universal_newlines=True,
        ),
    ]
Exemple #7
0
def test_pack_snap_compression_none(mocker, new_dir):
    """No compression uses snap default."""
    mock_run = mocker.patch("subprocess.run")
    pack.pack_snap(new_dir, output=None, compression=None)
    assert mock_run.mock_calls[:2] == [
        call(
            ["snap", "pack", "--check-skeleton", new_dir],
            capture_output=True,
            check=True,
            universal_newlines=True,
        ),
        call(
            ["snap", "pack", new_dir, new_dir],
            capture_output=True,
            check=True,
            universal_newlines=True,
        ),
    ]
Exemple #8
0
def test_pack_snap_output_directory_cwd_no_filename(mocker, new_dir):
    """Output to the current working directory when no filename is specified."""
    mock_run = mocker.patch("subprocess.run")
    pack.pack_snap(new_dir, output=str(new_dir))
    assert mock_run.mock_calls[:2] == [
        call(
            ["snap", "pack", "--check-skeleton", new_dir],
            capture_output=True,
            check=True,
            universal_newlines=True,
        ),
        call(
            ["snap", "pack", new_dir, new_dir],
            capture_output=True,
            check=True,
            universal_newlines=True,
        ),
    ]
Exemple #9
0
def test_pack_snap_file_name_missing_parameters(mocker, new_dir, parameters):
    """If name, version, and target architecture are not all specified, then use
    snap's default naming convention."""
    mock_run = mocker.patch("subprocess.run")
    pack.pack_snap(new_dir, output=None, **parameters)
    assert mock_run.mock_calls[:2] == [
        call(
            ["snap", "pack", "--check-skeleton", new_dir],
            capture_output=True,
            check=True,
            universal_newlines=True,
        ),
        call(
            ["snap", "pack", new_dir, new_dir],
            capture_output=True,
            check=True,
            universal_newlines=True,
        ),
    ]
Exemple #10
0
def test_pack_snap_output_file_output_directory_existing_no_filename(mocker, new_dir):
    """Outputs to an existing directory when no filename is specified."""
    mock_run = mocker.patch("subprocess.run")
    output_directory = new_dir / "output"
    output_directory.mkdir()
    assert output_directory.is_dir()

    pack.pack_snap(new_dir, output=output_directory)

    assert mock_run.mock_calls[:2] == [
        call(
            ["snap", "pack", "--check-skeleton", new_dir],
            capture_output=True,
            check=True,
            universal_newlines=True,
        ),
        call(
            ["snap", "pack", new_dir, output_directory],
            capture_output=True,
            check=True,
            universal_newlines=True,
        ),
    ]
Exemple #11
0
def test_pack_snap_use_output_name_over_name_version_arch(mocker, new_dir):
    """Output filename takes priority over name, version, and target_arch parameters."""
    mock_run = mocker.patch("subprocess.run")
    pack.pack_snap(
        new_dir,
        output="test.snap",
        name="hello",
        version="1.0",
        target_arch="armhf",
    )
    assert mock_run.mock_calls[:2] == [
        call(
            ["snap", "pack", "--check-skeleton", new_dir],
            capture_output=True,
            check=True,
            universal_newlines=True,
        ),
        call(
            ["snap", "pack", "--filename", "test.snap", new_dir, new_dir],
            capture_output=True,
            check=True,
            universal_newlines=True,
        ),
    ]
Exemple #12
0
def test_pack_snap_file_name_valid(mocker, new_dir):
    """Passing name, version, and target_arch should produce a valid file name."""
    mock_run = mocker.patch("subprocess.run")
    pack.pack_snap(
        new_dir,
        output=None,
        name="hello",
        version="1.0",
        target_arch="armhf",
    )
    assert mock_run.mock_calls[:2] == [
        call(
            ["snap", "pack", "--check-skeleton", new_dir],
            capture_output=True,
            check=True,
            universal_newlines=True,
        ),
        call(
            ["snap", "pack", "--filename", "hello_1.0_armhf.snap", new_dir, new_dir],
            capture_output=True,
            check=True,
            universal_newlines=True,
        ),
    ]
Exemple #13
0
def _run_command(
    command_name: str,
    *,
    project: Project,
    parse_info: Dict[str, List[str]],
    assets_dir: Path,
    start_time: datetime,
    parallel_build_count: int,
    parsed_args: "argparse.Namespace",
) -> None:
    managed_mode = utils.is_managed_mode()
    part_names = getattr(parsed_args, "parts", None)

    if not managed_mode:
        run_project_checks(project, assets_dir=assets_dir)

        if command_name == "snap":
            emit.progress(
                "The 'snap' command is deprecated, use 'pack' instead.",
                permanent=True,
            )

    if parsed_args.use_lxd and providers.get_platform_default_provider(
    ) == "lxd":
        emit.progress("LXD is used by default on this platform.",
                      permanent=True)

    if (not managed_mode and not parsed_args.destructive_mode
            and not os.getenv("SNAPCRAFT_BUILD_ENVIRONMENT") == "host"):
        if command_name == "clean" and not part_names:
            _clean_provider(project, parsed_args)
        else:
            _run_in_provider(project, command_name, parsed_args)
        return

    if managed_mode:
        work_dir = utils.get_managed_environment_home_path()
        project_dir = utils.get_managed_environment_project_path()
    else:
        work_dir = Path.cwd()
        project_dir = Path.cwd()

    step_name = "prime" if command_name in ("pack", "snap") else command_name

    lifecycle = PartsLifecycle(
        project.parts,
        work_dir=work_dir,
        assets_dir=assets_dir,
        base=project.get_effective_base(),
        package_repositories=project.package_repositories,
        parallel_build_count=parallel_build_count,
        part_names=part_names,
        adopt_info=project.adopt_info,
        project_name=project.name,
        parse_info=parse_info,
        project_vars={
            "version": project.version or "",
            "grade": project.grade or "",
        },
        extra_build_snaps=project.get_extra_build_snaps(),
    )

    if command_name == "clean":
        lifecycle.clean(part_names=part_names)
        return

    lifecycle.run(
        step_name,
        debug=parsed_args.debug,
        shell=getattr(parsed_args, "shell", False),
        shell_after=getattr(parsed_args, "shell_after", False),
    )

    # Extract metadata and generate snap.yaml
    project_vars = lifecycle.project_vars
    if step_name == "prime" and not part_names:
        emit.progress("Extracting and updating metadata...")
        metadata_list = lifecycle.extract_metadata()
        update_project_metadata(
            project,
            project_vars=project_vars,
            metadata_list=metadata_list,
            assets_dir=assets_dir,
            prime_dir=lifecycle.prime_dir,
        )

        emit.progress("Copying snap assets...")
        setup_assets(
            project,
            assets_dir=assets_dir,
            project_dir=project_dir,
            prime_dir=lifecycle.prime_dir,
        )

        emit.progress("Generating snap metadata...")
        snap_yaml.write(
            project,
            lifecycle.prime_dir,
            arch=lifecycle.target_arch,
            arch_triplet=lifecycle.target_arch_triplet,
        )
        emit.progress("Generated snap metadata", permanent=True)

        if parsed_args.enable_manifest:
            _generate_manifest(
                project,
                lifecycle=lifecycle,
                start_time=start_time,
                parsed_args=parsed_args,
            )

    if command_name in ("pack", "snap"):
        snap_filename = pack.pack_snap(
            lifecycle.prime_dir,
            output=parsed_args.output,
            compression=project.compression,
            name=project.name,
            version=process_version(project.version),
            target_arch=lifecycle.target_arch,
        )
        emit.message(f"Created snap package {snap_filename}")
Exemple #14
0
def _run_command(
    command_name: str,
    *,
    project: Project,
    parse_info: Dict[str, List[str]],
    assets_dir: Path,
    start_time: datetime,
    parallel_build_count: int,
    parsed_args: "argparse.Namespace",
) -> None:
    managed_mode = utils.is_managed_mode()
    part_names = getattr(parsed_args, "parts", None)

    if not managed_mode:
        run_project_checks(project, assets_dir=assets_dir)

        if command_name == "snap":
            emit.progress(
                "The 'snap' command is deprecated, use 'pack' instead.",
                permanent=True,
            )

    if parsed_args.use_lxd and providers.get_platform_default_provider(
    ) == "lxd":
        emit.progress("LXD is used by default on this platform.",
                      permanent=True)

    if (not managed_mode and not parsed_args.destructive_mode
            and not os.getenv("SNAPCRAFT_BUILD_ENVIRONMENT") == "host"):
        if command_name == "clean" and not part_names:
            _clean_provider(project, parsed_args)
        else:
            _run_in_provider(project, command_name, parsed_args)
        return

    if managed_mode:
        work_dir = utils.get_managed_environment_home_path()
        project_dir = utils.get_managed_environment_project_path()
    else:
        work_dir = project_dir = Path.cwd()

    step_name = "prime" if command_name in ("pack", "snap") else command_name

    lifecycle = PartsLifecycle(
        project.parts,
        work_dir=work_dir,
        assets_dir=assets_dir,
        base=project.get_effective_base(),
        package_repositories=project.package_repositories,
        parallel_build_count=parallel_build_count,
        part_names=part_names,
        adopt_info=project.adopt_info,
        project_name=project.name,
        parse_info=parse_info,
        project_vars={
            "version": project.version or "",
            "grade": project.grade or "",
        },
        extra_build_snaps=project.get_extra_build_snaps(),
        target_arch=project.get_build_for(),
    )

    if command_name == "clean":
        lifecycle.clean(part_names=part_names)
        return

    lifecycle.run(
        step_name,
        debug=parsed_args.debug,
        shell=getattr(parsed_args, "shell", False),
        shell_after=getattr(parsed_args, "shell_after", False),
    )

    # Extract metadata and generate snap.yaml
    if step_name == "prime" and not part_names:
        _generate_metadata(
            project=project,
            lifecycle=lifecycle,
            project_dir=project_dir,
            assets_dir=assets_dir,
            start_time=start_time,
            parsed_args=parsed_args,
        )

    if command_name in ("pack", "snap"):
        issues = linters.run_linters(lifecycle.prime_dir, lint=project.lint)
        status = linters.report(issues, intermediate=True)

        # In case of linter errors, stop execution and return the error code.
        if status in (LinterStatus.ERRORS, LinterStatus.FATAL):
            raise errors.LinterError("Linter errors found", exit_code=status)

        snap_filename = pack.pack_snap(
            lifecycle.prime_dir,
            output=parsed_args.output,
            compression=project.compression,
            name=project.name,
            version=process_version(project.version),
            target_arch=project.get_build_for(),
        )
        emit.message(f"Created snap package {snap_filename}")