← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~jugmac00/lpcraft:add-golang-plugin into lpcraft:main

 

Jürgen Gmach has proposed merging ~jugmac00/lpcraft:add-golang-plugin into lpcraft:main.

Commit message:
Add Golang plugin

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~jugmac00/lpcraft/+git/lpcraft/+merge/427068
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~jugmac00/lpcraft:add-golang-plugin into lpcraft:main.
diff --git a/NEWS.rst b/NEWS.rst
index 924486c..3c3b4d6 100644
--- a/NEWS.rst
+++ b/NEWS.rst
@@ -2,6 +2,11 @@
 Version history
 ===============
 
+0.0.21 (unreleased)
+===================
+
+- Add Golang plugin.
+
 0.0.20 (2022-07-15)
 ===================
 
diff --git a/lpcraft/plugin/tests/test_plugins.py b/lpcraft/plugin/tests/test_plugins.py
index 5b28fd7..8e43fb4 100644
--- a/lpcraft/plugin/tests/test_plugins.py
+++ b/lpcraft/plugin/tests/test_plugins.py
@@ -961,3 +961,129 @@ class TestPlugins(CommandBaseTestCase):
         )
 
         self.assertEqual(0, result.exit_code)
+
+    @patch("lpcraft.commands.run.get_provider")
+    @patch("lpcraft.commands.run.get_host_architecture", return_value="amd64")
+    def test_golang_plugin(
+        self, mock_get_host_architecture, mock_get_provider
+    ):
+        launcher = Mock(spec=launch)
+        provider = makeLXDProvider(lxd_launcher=launcher)
+        mock_get_provider.return_value = provider
+        execute_run = launcher.return_value.execute_run
+        execute_run.return_value = subprocess.CompletedProcess([], 0)
+        config = dedent(
+            """
+            pipeline:
+                - build
+
+            jobs:
+                build:
+                    plugin: golang
+                    golang-version: "1.17"
+                    series: focal
+                    architectures: amd64
+                    packages: [file, git]
+                    run: go build -x examples/go-top.go
+            """
+        )
+        Path(".launchpad.yaml").write_text(config)
+
+        self.run_command("run")
+        self.assertEqual(
+            [
+                call(
+                    ["apt", "update"],
+                    cwd=PosixPath("/root/lpcraft/project"),
+                    env={},
+                    stdout=ANY,
+                    stderr=ANY,
+                ),
+                call(
+                    ["apt", "install", "-y", "golang-1.17", "file", "git"],
+                    cwd=PosixPath("/root/lpcraft/project"),
+                    env={},
+                    stdout=ANY,
+                    stderr=ANY,
+                ),
+                call(
+                    [
+                        "bash",
+                        "--noprofile",
+                        "--norc",
+                        "-ec",
+                        "\nexport PATH=/usr/lib/go-1.17/bin/:$PATH\ngo build -x examples/go-top.go",  # noqa: E501
+                    ],
+                    cwd=PosixPath("/root/lpcraft/project"),
+                    env={},
+                    stdout=ANY,
+                    stderr=ANY,
+                ),
+            ],
+            execute_run.call_args_list,
+        )
+
+    @patch("lpcraft.commands.run.get_provider")
+    @patch("lpcraft.commands.run.get_host_architecture", return_value="amd64")
+    def test_golang_plugin_with_different_version(
+        self, mock_get_host_architecture, mock_get_provider
+    ):
+        # XXX 2022-07-19 - jugmac00
+        # If we ever quit using test classes, this test could be easily
+        # merged with the one before using `pytest.mark.parametrize`.
+        launcher = Mock(spec=launch)
+        provider = makeLXDProvider(lxd_launcher=launcher)
+        mock_get_provider.return_value = provider
+        execute_run = launcher.return_value.execute_run
+        execute_run.return_value = subprocess.CompletedProcess([], 0)
+        # we test a different version, additionally it was provided as float
+        # but that is ok - it will be converted to a str
+        config = dedent(
+            """
+            pipeline:
+                - build
+            jobs:
+                build:
+                    plugin: golang
+                    golang-version: 1.18
+                    series: focal
+                    architectures: amd64
+                    packages: [file, git]
+                    run: go build -x examples/go-top.go
+            """
+        )
+        Path(".launchpad.yaml").write_text(config)
+
+        self.run_command("run")
+        self.assertEqual(
+            [
+                call(
+                    ["apt", "update"],
+                    cwd=PosixPath("/root/lpcraft/project"),
+                    env={},
+                    stdout=ANY,
+                    stderr=ANY,
+                ),
+                call(
+                    ["apt", "install", "-y", "golang-1.18", "file", "git"],
+                    cwd=PosixPath("/root/lpcraft/project"),
+                    env={},
+                    stdout=ANY,
+                    stderr=ANY,
+                ),
+                call(
+                    [
+                        "bash",
+                        "--noprofile",
+                        "--norc",
+                        "-ec",
+                        "\nexport PATH=/usr/lib/go-1.18/bin/:$PATH\ngo build -x examples/go-top.go",  # noqa: E501
+                    ],
+                    cwd=PosixPath("/root/lpcraft/project"),
+                    env={},
+                    stdout=ANY,
+                    stderr=ANY,
+                ),
+            ],
+            execute_run.call_args_list,
+        )
diff --git a/lpcraft/plugins/plugins.py b/lpcraft/plugins/plugins.py
index 833c461..cc4ed11 100644
--- a/lpcraft/plugins/plugins.py
+++ b/lpcraft/plugins/plugins.py
@@ -8,6 +8,7 @@ __all__ = [
     "PyProjectBuildPlugin",
     "MiniCondaPlugin",
     "CondaBuildPlugin",
+    "GolangPlugin",
 ]
 
 import textwrap
@@ -399,3 +400,56 @@ class CondaBuildPlugin(MiniCondaPlugin):
             {build_command}{conda_channels}{configs} {self.build_target}
             {run_command}"""
         )
+
+
+@register(name="golang")
+class GolangPlugin(BasePlugin):
+    """Installs the required `golang` version.
+
+    Usage:
+        In `.launchpad.yaml`, create the following structure:
+
+        .. code-block:: yaml
+
+            pipeline:
+                - build
+
+            jobs:
+                build:
+                    plugin: golang
+                    golang-version: "1.17"
+                    series: focal
+                    architectures: amd64
+                    packages: [file, git]
+                    run: go build -x examples/go-top.go
+
+    Please note that the requested golang version needs to be available either
+    in the standard or in a provided additional repository.
+    """
+
+    class Config(BaseConfig):
+        golang_version: StrictStr
+
+        @pydantic.validator("golang_version", pre=True)
+        def validate_golang_version(cls, v: str | float | int) -> str:
+            return str(v)
+
+    INTERPOLATES_RUN_COMMAND = True
+
+    def get_plugin_config(self) -> "GolangPlugin.Config":
+        return cast(GolangPlugin.Config, self.config.plugin_config)
+
+    @hookimpl  # type: ignore
+    def lpcraft_install_packages(self) -> list[str]:
+        version = self.get_plugin_config().golang_version
+        return [f"golang-{version}"]
+
+    @hookimpl  # type: ignore
+    def lpcraft_execute_run(self) -> str:
+        version = self.get_plugin_config().golang_version
+        run_command = self.config.run or ""
+        return textwrap.dedent(
+            f"""
+            export PATH=/usr/lib/go-{version}/bin/:$PATH
+            {run_command}"""
+        )
diff --git a/setup.cfg b/setup.cfg
index 620de17..76d03ce 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,6 +1,6 @@
 [metadata]
 name = lpcraft
-version = 0.0.20
+version = 0.0.21.dev0
 description = Runner for Launchpad CI jobs
 long_description = file: README.rst
 long_description_content_type = text/x-rst

Follow ups