コード例 #1
0
def test_setup_environment_content_x86(tmp_work_path, monkeypatch,
                                       machine_platform, distro):
    snapcraft_project = Project()
    snapcraft_project._snap_meta = Snap(name="test-snap", base=distro[0])

    monkeypatch.setattr(platform, "machine", lambda: machine_platform[0])

    recorded_files = dict()

    @contextlib.contextmanager
    def fake_namedtempfile(*, suffix: str, **kwargs):
        # Usage hides the file basename in the suffix.
        tmp_path = os.path.join("tmpfile")
        with open(tmp_path, "wb") as f_write:
            yield f_write
        with open(tmp_path, "r") as f_read:
            recorded_files[suffix] = f_read.read()

    monkeypatch.setattr(tempfile, "NamedTemporaryFile", fake_namedtempfile)

    provider = ProviderImpl(project=snapcraft_project, echoer=Mock())
    provider._setup_environment()

    assert recorded_files == {
        ".bashrc":
        '#!/bin/bash\nexport PS1="\\h \\$(/bin/_snapcraft_prompt)# "\n',
        "00-snapcraft":
        'Apt::Install-Recommends "false";\n',
        "_snapcraft_prompt":
        dedent("""\
            #!/bin/bash
            if [[ "$PWD" =~ ^$HOME.* ]]; then
                path="${PWD/#$HOME/\\ ..}"
                if [[ "$path" == " .." ]]; then
                    ps1=""
                else
                    ps1="$path"
                fi
            else
                ps1="$PWD"
            fi
            echo -n $ps1
            """),
        "default.sources":
        dedent(f"""\
                Types: deb
                URIs: {machine_platform[1]["main"]}
                Suites: {distro[1]} {distro[1]}-updates
                Components: main multiverse restricted universe
            """),
        "default-security.sources":
        dedent(f"""\
                Types: deb
                URIs: {machine_platform[1]["security"]}
                Suites: {distro[1]}-security
                Components: main multiverse restricted universe
            """),
        "sources.list":
        "",
    }
コード例 #2
0
ファイル: _sanity_checks.py プロジェクト: snapcore/snapcraft
def conduct_project_sanity_check(project: Project, **kwargs) -> None:
    """Sanity check the project itself before continuing.

    The checks done here are meant to be light, and not rely on the build environment.
    """
    # The snapcraft.yaml should be valid even without extensions applied
    # This here check is mostly for backwards compatibility with the
    # rest of the code base.
    if project.info is not None:
        project.info.validate_raw_snapcraft()

    if project._get_build_base() == "core":
        raise errors.UnsupportedBaseError(base="core")

    snap_dir_path = os.path.join(project._get_snapcraft_assets_dir())
    if os.path.isdir(snap_dir_path):
        # TODO: move this check to the ProjectInfo class.
        _check_snap_dir(snap_dir_path)

    if (
        project._get_build_base() in ["core20"]
        and kwargs.get("target_arch") is not None
        and not os.getenv("SNAPCRAFT_ENABLE_EXPERIMENTAL_TARGET_ARCH")
    ):
        raise SnapcraftEnvironmentError(
            "*EXPERIMENTAL* '--target-arch' configured, but not enabled. "
            "Enable with '--enable-experimental-target-arch' flag."
        )

    # Icon should refer to project file, verify it exists.
    icon = project.info.get_raw_snapcraft().get("icon")
    if icon and not os.path.exists(icon):
        raise SnapcraftEnvironmentError(f"Specified icon {icon!r} does not exist.")
コード例 #3
0
ファイル: __init__.py プロジェクト: snapcore/snapcraft
def get_project(base: str = "core20") -> Project:
    project = Project()
    project._snap_meta = Snap(name="project-name",
                              base=base,
                              version="1.0",
                              confinement="strict")
    return project
コード例 #4
0
def get_project(*, is_managed_host: bool = False, **kwargs):
    # We need to do this here until we can get_snapcraft_yaml as part of Project.
    if is_managed_host:
        try:
            os.chdir(os.path.expanduser(os.path.join("~", "project")))
        except FileNotFoundError:
            # No project found (fresh environment).
            raise errors.ProjectNotFoundError()

    snapcraft_yaml_file_path = get_snapcraft_yaml()

    # This method may be called from a click.Command with no parent.
    ctx = click.get_current_context()
    if ctx.parent is not None:
        for key, value in ctx.parent.params.items():
            if not kwargs.get(key):
                kwargs[key] = value

    project = Project(
        debug=kwargs.pop("debug", False),
        target_deb_arch=kwargs.pop("target_arch", None),
        snapcraft_yaml_file_path=snapcraft_yaml_file_path,
        is_managed_host=is_managed_host,
    )

    # Validate yaml info from schema prior to consumption.
    if project.info is not None:
        project.info.validate_raw_snapcraft()

        # TODO: this should be automatic on get_project().
        # This is not the complete meta parsed by the project loader.
        project._snap_meta = Snap.from_dict(project.info.get_raw_snapcraft())

    return project
コード例 #5
0
def project(monkeypatch, tmp_work_path, request):
    """Return project variants for core and core18"""
    monkeypatch.setattr(Project, "parallel_build_count", 2)

    snapcraft_project = Project()
    snapcraft_project._snap_meta = Snap(name="test-snap",
                                        base="core18",
                                        confinement="strict")
    return snapcraft_project
コード例 #6
0
    def test_pull_is_dirty_if_target_arch_changes(
        self,
        mock_install_build_snaps,
        mock_install_build_packages,
        mock_enable_cross_compilation,
    ):
        # Set the option to error on dirty/outdated steps
        with snapcraft_legacy.config.CLIConfig() as cli_config:
            cli_config.set_outdated_step_action(
                snapcraft_legacy.config.OutdatedStepAction.ERROR)

        mock_install_build_packages.return_value = []
        project_config = self.make_snapcraft_project(
            textwrap.dedent("""\
                parts:
                  part1:
                    plugin: nil
                """))

        project = Project(
            snapcraft_yaml_file_path=self.snapcraft_yaml_file_path,
            target_deb_arch="amd64",
        )
        project_config = project_loader.load_config(project)
        # Pull it with amd64
        lifecycle.execute(steps.PULL, project_config)

        # Reset logging since we only care about the following
        self.fake_logger = fixtures.FakeLogger(level=logging.INFO)
        self.useFixture(self.fake_logger)

        project = Project(
            snapcraft_yaml_file_path=self.snapcraft_yaml_file_path,
            target_deb_arch="armhf",
        )
        project_config = project_loader.load_config(project)
        # Pull it again with armhf. Should catch that the part needs to be
        # re-pulled due to the change in target architecture and raise an
        # error.
        raised = self.assertRaises(errors.StepOutdatedError, lifecycle.execute,
                                   steps.PULL, project_config)

        self.assertThat(self.fake_logger.output,
                        Contains("Setting target machine to 'armhf'"))

        self.assertThat(raised.step, Equals(steps.PULL))
        self.assertThat(raised.part, Equals("part1"))
        self.assertThat(
            raised.report,
            Equals("The 'deb_arch' project option appears to have changed.\n"),
        )
コード例 #7
0
ファイル: test_maven.py プロジェクト: snapcore/snapcraft
    def test_use_invalid_openjdk_version_fails(self, base, version, expected_message):
        class Options:
            maven_options = []
            maven_targets = [""]
            maven_version = maven._DEFAULT_MAVEN_VERSION
            maven_version_checksum = maven._DEFAULT_MAVEN_CHECKSUM
            maven_openjdk_version = version

        project = Project()
        project._snap_meta = Snap(name="test-snap", base=base, confinement="strict")

        with pytest.raises(maven.UnsupportedJDKVersionError) as error:
            maven.MavenPlugin("test-part", Options(), project)
            assert str(error) == expected_message
コード例 #8
0
ファイル: test_waf.py プロジェクト: snapcore/snapcraft
def test_cross_compile(monkeypatch, deb_arch):
    monkeypatch.setattr(Project, "is_cross_compiling", True)

    class Options:
        configflags = []

    project = Project(target_deb_arch=deb_arch)
    project._snap_meta = meta.snap.Snap(name="test-snap", base="core18")

    plugin = waf.WafPlugin("test-part", Options(), project)
    plugin.enable_cross_compilation()

    env = plugin.env(plugin.sourcedir)
    assert f"CC={project.arch_triplet}-gcc" in env
    assert f"CXX={project.arch_triplet}-g++" in env
コード例 #9
0
ファイル: test_ant.py プロジェクト: snapcore/snapcraft
    def test_use_invalid_openjdk_version_fails(self, base, version, expected_message):
        class Options:
            ant_properties = {}
            ant_build_targets = None
            ant_channel = None
            ant_version = "1.10.5"
            ant_version_checksum = "sha512/a7f1e0cec9d5ed1b3ab6cddbb9364f127305a997bbc88ecd734f9ef142ec0332375e01ace3592759bb5c3307cd9c1ac0a78a30053f304c7030ea459498e4ce4e"
            ant_openjdk_version = version

        project = Project()
        project._snap_meta = Snap(name="test-snap", base=base, confinement="strict")

        with pytest.raises(ant.UnsupportedJDKVersionError) as error:
            ant.AntPlugin("test-part", Options(), project)
            assert str(error) == expected_message
コード例 #10
0
ファイル: test_maven.py プロジェクト: snapcore/snapcraft
def maven_plugin(tmp_work_path, request):
    """Return an instance of MavenPlugin setup with different bases and java versions."""
    java_version, base = request.param

    class Options:
        maven_options = []
        maven_targets = [""]
        maven_version = maven._DEFAULT_MAVEN_VERSION
        maven_version_checksum = maven._DEFAULT_MAVEN_CHECKSUM
        maven_openjdk_version = java_version

    project = Project()
    project._snap_meta = Snap(name="test-snap", base=base, confinement="strict")

    return maven.MavenPlugin("test-part", Options(), project)
コード例 #11
0
def project(snapcraft_yaml_path, request):
    """Return a project in host and managed-host modes."""
    snapcraft_project = Project(
        is_managed_host=request.param,
        snapcraft_yaml_file_path=snapcraft_yaml_path.as_posix(),
    )
    return snapcraft_project
コード例 #12
0
    def setUp(self):
        super().setUp()

        self.project = Project()
        self.project._snap_meta = Snap(name="test-snap",
                                       base="core18",
                                       confinement="strict")
コード例 #13
0
def get_project_config(snapcraft_yaml_content):
    snapcraft_yaml_path = pathlib.Path("snapcraft.yaml")
    with snapcraft_yaml_path.open("w") as snapcraft_yaml_file:
        print(snapcraft_yaml_content, file=snapcraft_yaml_file)

    project = Project(snapcraft_yaml_file_path=snapcraft_yaml_path.as_posix())
    return project_loader.load_config(project)
コード例 #14
0
ファイル: _config.py プロジェクト: snapcore/snapcraft
    def __init__(self, project: project.Project) -> None:
        self.build_snaps: Set[str] = set()
        self.project = project

        # raw_snapcraft_yaml is read only, create a new copy
        snapcraft_yaml = apply_extensions(project.info.get_raw_snapcraft())

        self.validator = Validator(snapcraft_yaml)
        self.validator.validate()

        snapcraft_yaml = self._expand_filesets(snapcraft_yaml)

        self.data = self._expand_env(snapcraft_yaml)

        self.data["architectures"] = _process_architectures(
            self.data.get("architectures"), project.deb_arch)

        self._ensure_no_duplicate_app_aliases()

        self._global_grammar_processor = grammar_processing.GlobalGrammarProcessor(
            properties=self.data,
            arch=project.host_deb_arch,
            target_arch=project.target_arch,
        )

        # XXX: Resetting snap_meta due to above mangling of data.
        # Convergence to operating on snap_meta will remove this requirement...
        project._snap_meta = Snap.from_dict(self.data)

        self.parts = PartsConfig(parts=self.data,
                                 project=project,
                                 validator=self.validator)
コード例 #15
0
    def test_use_invalid_openjdk_version_fails(self, base, version,
                                               expected_message):
        class Options:
            gradle_options = []
            gradle_output_dir = "build/libs"
            gradle_version = gradle._DEFAULT_GRADLE_VERSION
            gradle_version_checksum = gradle._DEFAULT_GRADLE_CHECKSUM
            gradle_openjdk_version = version

        project = Project()
        project._snap_meta = Snap(name="test-snap",
                                  base=base,
                                  confinement="strict")

        with pytest.raises(gradle.UnsupportedJDKVersionError) as error:
            gradle.GradlePlugin("test-part", Options(), project)
            assert str(error) == expected_message
コード例 #16
0
ファイル: test_ant.py プロジェクト: snapcore/snapcraft
def ant_plugin(tmp_work_path, request):
    """Return an instance of AntPlugin setup with different bases and java versions."""
    java_version, base = request.param

    class Options:
        ant_properties = {}
        ant_build_targets = None
        ant_channel = None
        ant_version = "1.10.5"
        ant_version_checksum = "sha512/a7f1e0cec9d5ed1b3ab6cddbb9364f127305a997bbc88ecd734f9ef142ec0332375e01ace3592759bb5c3307cd9c1ac0a78a30053f304c7030ea459498e4ce4e"
        ant_openjdk_version = java_version
        ant_buildfile = None

    project = Project()
    project._snap_meta = Snap(name="test-snap", base=base, confinement="strict")

    return ant.AntPlugin("test-part", Options(), project)
コード例 #17
0
ファイル: test_project.py プロジェクト: snapcore/snapcraft
def test_project_with_arguments():
    project = Project(target_deb_arch="armhf", debug=True)

    assert project.deb_arch == "armhf"
    assert project.debug is True

    # This is a backwards compatibility check
    assert project.info is None
コード例 #18
0
def gradle_plugin(tmp_path, request):
    """Return an instance of GradlePlugin setup with different bases and java versions."""
    java_version, base = request.param

    class Options:
        gradle_options = []
        gradle_output_dir = "build/libs"
        gradle_version = gradle._DEFAULT_GRADLE_VERSION
        gradle_version_checksum = gradle._DEFAULT_GRADLE_CHECKSUM
        gradle_openjdk_version = java_version

    os.chdir(tmp_path)
    project = Project()
    project._snap_meta = Snap(name="test-snap",
                              base=base,
                              confinement="strict")

    return gradle.GradlePlugin("test-part", Options(), project)
コード例 #19
0
ファイル: _plugin_loader.py プロジェクト: snapcore/snapcraft
def load_plugin(
    plugin_name: str,
    part_name: str,
    project: Project,
    properties,
    part_schema,
    definitions_schema,
) -> plugins.v1.PluginV1:
    local_plugins_dir = project._get_local_plugins_dir()
    if local_plugins_dir is not None:
        plugin_class = _get_local_plugin_class(
            plugin_name=plugin_name, local_plugins_dir=local_plugins_dir
        )
    if plugin_class is None:
        plugin_class = plugins.get_plugin_for_base(
            plugin_name, build_base=project._get_build_base()
        )

    if issubclass(plugin_class, plugins.v2.PluginV2):
        plugin_schema = plugin_class.get_schema()
        options = _make_options(
            part_name, part_schema, definitions_schema, properties, plugin_schema
        )
        plugin = plugin_class(part_name=part_name, options=options)
    else:
        plugin_schema = plugin_class.schema()
        _validate_pull_and_build_properties(
            plugin_name, plugin_class, part_schema, definitions_schema
        )
        options = _make_options(
            part_name, part_schema, definitions_schema, properties, plugin_schema
        )
        plugin = plugin_class(part_name, options, project)

        if project.is_cross_compiling:
            logger.debug(
                "Setting {!r} as the compilation target for {!r}".format(
                    project.deb_arch, plugin_name
                )
            )
            plugin.enable_cross_compilation()

    return plugin
コード例 #20
0
ファイル: test_parts.py プロジェクト: snapcore/snapcraft
    def make_snapcraft_project(self, parts):
        snapcraft_yaml = fixture_setup.SnapcraftYaml(self.path)
        snapcraft_yaml.update_part("part1", dict(plugin="nil"))
        for part_name, part in parts:
            snapcraft_yaml.update_part(part_name, part)
        self.useFixture(snapcraft_yaml)

        project = Project(
            snapcraft_yaml_file_path=snapcraft_yaml.snapcraft_yaml_file_path)
        return project_loader.load_config(project)
コード例 #21
0
    def _get_snap_packaging(self, **yaml_args):
        if "parts" not in yaml_args:
            yaml_args["parts"] = dict(part1=dict(plugin="nil"))

        snapcraft_yaml = fixture_setup.SnapcraftYaml(self.path, **yaml_args)
        self.useFixture(snapcraft_yaml)

        project = Project(
            snapcraft_yaml_file_path=snapcraft_yaml.snapcraft_yaml_file_path)
        config = load_config(project)

        return _SnapPackaging(project_config=config, extracted_metadata=None)
コード例 #22
0
def test_cross_compile(monkeypatch, tmp_work_path, mock_run, deb_arch,
                       go_arch):
    monkeypatch.setattr(Project, "is_cross_compiling", True)

    class Options:
        source = ""
        go_packages = ["github.com/gotools/vet"]
        go_importpath = ""
        go_buildtags = ""
        go_channel = ""

    project = Project(target_deb_arch=deb_arch)
    project._snap_meta = meta.snap.Snap(name="test-snap", base="core18")

    plugin = go.GoPlugin("test-part", Options(), project)

    os.makedirs(plugin.sourcedir)

    plugin.pull()

    assert mock_run.call_count == 1

    for call_args in mock_run.call_args_list:
        env = call_args[1]["env"]
        assert "CC" in env
        assert env["CC"] == f"{project.arch_triplet}-gcc"

        assert "CXX" in env
        assert env["CXX"] == f"{project.arch_triplet}-g++"

        assert "CGO_ENABLED" in env
        assert env["CGO_ENABLED"] == "1"

        assert "GOARCH" in env
        assert env["GOARCH"] == go_arch

        if deb_arch == "armhf":
            assert "GOARM" in env
            assert env["GOARM"] == "7"
コード例 #23
0
    def test_non_prime_and_no_version(self):
        snapcraft_yaml = fixture_setup.SnapcraftYaml(self.path, version=None)
        snapcraft_yaml.data["adopt-info"] = "test-part"
        snapcraft_yaml.update_part(
            "test-part",
            {
                "plugin": "nil",
                "override-build": "snapcraftctl set-version 1.0"
            },
        )
        self.useFixture(snapcraft_yaml)

        project = Project(
            snapcraft_yaml_file_path=snapcraft_yaml.snapcraft_yaml_file_path)
        project_config = project_loader.load_config(project)

        # This should not fail
        lifecycle.execute(steps.PULL, project_config)
コード例 #24
0
ファイル: test_project.py プロジェクト: snapcore/snapcraft
def test_project_with_snapcraft_yaml_file_path_carries_info(tmp_work_path):
    snapcraft_yaml_path = pathlib.Path("snapcraft.yaml")
    with snapcraft_yaml_path.open("w") as snapcraft_yaml_file:
        print(
            dedent("""\
            name: foo
            version: "1"
            summary: bar
            description: baz
            confinement: strict

            parts:
              part1:
                plugin: go
            """),
            file=snapcraft_yaml_file,
        )

    project = Project(snapcraft_yaml_file_path=snapcraft_yaml_path.as_posix())

    # Only 1 value is enough
    assert project.info.name == "foo"
コード例 #25
0
def test_icon(tmp_work_path):
    snapcraft_yaml_path = tmp_work_path / "snap/snapcraft.yaml"
    snapcraft_yaml_path.parent.mkdir(parents=True)
    with snapcraft_yaml_path.open("w") as snapcraft_file:
        print(
            dedent("""\
            name: project-name
            base: core18
            version: "1.0"
            summary: sanity checks
            description: sanity checks
            grade: stable
            confinement: strict
            icon: foo.png

            parts:
              nil:
                plugin: nil
            """),
            file=snapcraft_file,
        )

    project = Project(
        is_managed_host=False,
        snapcraft_yaml_file_path=snapcraft_yaml_path.as_posix(),
    )

    # Test without icon raises error
    with pytest.raises(snapcraft_legacy.internal.errors.
                       SnapcraftEnvironmentError) as exc_info:
        conduct_project_sanity_check(project)

    assert exc_info.value.get_brief(
    ) == "Specified icon 'foo.png' does not exist."

    # Test with icon passes.
    (tmp_work_path / "foo.png").touch()
    conduct_project_sanity_check(project)
コード例 #26
0
ファイル: test_project.py プロジェクト: snapcore/snapcraft
def test_project_local_plugin_location(tmp_work_path, location):
    snapcraft_yaml_path = tmp_work_path / pathlib.Path(location)
    snapcraft_yaml_path.parent.mkdir(parents=True)
    with snapcraft_yaml_path.open("w") as snapcraft_yaml_file:
        print(
            dedent("""\
            name: foo
            version: "1"
            summary: bar
            description: baz
            confinement: strict

            parts:
              part1:
                plugin: go
            """),
            file=snapcraft_yaml_file,
        )

    project = Project(snapcraft_yaml_file_path=snapcraft_yaml_path.as_posix())

    expected_plugins_dir = snapcraft_yaml_path.parent / "plugins"
    assert project.local_plugins_dir == expected_plugins_dir.as_posix()
コード例 #27
0
 def __init__(self):
     self.project = Project()
     self.project._snap_meta = Snap(
         name="project-name", base="core20", version="1.0", confinement="strict"
     )
     self.parts = Parts()
コード例 #28
0
ファイル: test_flutter.py プロジェクト: snapcore/snapcraft
def test_unsupported_base_raises(flutter_options):
    project = Project()
    project._snap_meta = Snap(name="test-snap", base="bad-base", confinement="strict")

    with pytest.raises(errors.PluginBaseError):
        flutter.FlutterPlugin("test-part", flutter_options, project)
コード例 #29
0
 def load_project_and_worktree(self):
     """(Re)load project and worktree."""
     self._project = Project(snapcraft_yaml_file_path=self._snapcraft_yaml.
                             snapcraft_yaml_file_path)
     self._project._project_dir = self._source.path
     self._wt = WorkTree(self._dest.path, self._project)
コード例 #30
0
    def setUp(self):
        super().setUp()

        self.useFixture(fixtures.FakeLogger(level=logging.ERROR))

        temp_cwd = fixture_setup.TempCWD()
        self.useFixture(temp_cwd)

        snapcraft_yaml = fixture_setup.SnapcraftYaml(
            temp_cwd.path,
            base="core18",
            parts={"test-part": {
                "plugin": "nil"
            }})
        self.useFixture(snapcraft_yaml)

        project = Project(
            snapcraft_yaml_file_path=snapcraft_yaml.snapcraft_yaml_file_path)

        self.global_state_filepath = project._get_global_state_file_path()

        self.project_config = project_loader.load_config(project)

        self.useFixture(
            fixtures.MockPatchObject(self.project_config,
                                     "get_build_snaps",
                                     return_value={"core18"}))

        self.useFixture(
            fixtures.MockPatch(
                "snapcraft_legacy.internal.lifecycle._runner._Executor.run"))

        self.useFixture(
            fixtures.MockPatch(
                "snapcraft_legacy.internal.repo.snaps.install_snaps"))

        # Avoid unnecessary calls to info.
        channel_map = []
        for arch in ("amd64", "i386", "s390x", "arm64", "armhf", "ppc64el"):
            channel_map.append({
                "channel": {
                    "architecture": arch,
                    "name": "stable",
                    "released-at": "2019-10-15T13:54:06.800280+00:00",
                    "risk": "stable",
                    "track": "latest",
                },
                "confinement": "strict",
                "download": {
                    "deltas": [],
                    "sha3-384":
                    "64d232d6bfa65be14d7f8d84e952d4e372e12021e2c3dbaf70cf2af5e78bf51c4baf9c9107dd6db815064636b781bda6",
                    "size":
                    57151488,
                    "url":
                    "https://api.snapcraft.io/api/v1/snaps/download/CSO04Jhav2yK0uz97cr0ipQRyqg0qQL6_1223.snap",
                },
                "revision": 1223,
            })
        info = {
            "channel-map": channel_map,
            "default-track": None,
            "name": "core18",
            "snap": {
                "name": "core18",
                "publisher": {
                    "display-name": "Canonical",
                    "id": "canonical",
                    "username": "******",
                    "validation": "verified",
                },
                "snap-id": "CSO04Jhav2yK0uz97cr0ipQRyqg0qQL6",
            },
            "snap-id": "CSO04Jhav2yK0uz97cr0ipQRyqg0qQL6",
        }
        self.fake_storeapi_get_info = fixtures.MockPatch(
            "snapcraft_legacy.storeapi._snap_api.SnapAPI.get_info",
            return_value=SnapInfo(info),
        )
        self.useFixture(self.fake_storeapi_get_info)