Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -148,5 +148,5 @@
}
]
},
"generated_at": "2026-04-02T13:54:15Z"
"generated_at": "2026-04-02T15:07:10Z"
}
3 changes: 1 addition & 2 deletions continuous_delivery_scripts/plugins/GOLAND.MD
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,4 @@ The plugin leverages [goreleaser](https://goreleaser.com/) to package and releas
Therefore, a `.goreleaser.yml` file must be present in the go source directory i.e. where the mod file lies.

## Documentation
The plugin uses [golds](https://github.com/go101/golds) to generate the code reference documentation.
It currently uses version 0.4.1 as later versions comprise [an issue](https://github.com/go101/golds/issues/26)
The plugin uses [doc2go](https://abhinav.github.io/doc2go) to generate the code reference documentation.
103 changes: 72 additions & 31 deletions continuous_delivery_scripts/plugins/golang.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@

import logging
import os
import shutil
from pathlib import Path
from subprocess import check_call
from typing import TYPE_CHECKING, Optional, List, Dict
from subprocess import check_call, check_output
from typing import TYPE_CHECKING, Optional, List, Dict, MutableMapping

from continuous_delivery_scripts.utils.configuration import (
configuration,
Expand Down Expand Up @@ -37,14 +38,11 @@
GO_MOD_ON_VALUE = "on"


def _generate_golds_command_list(output_directory: Path, module: str) -> List[str]:
def _generate_doc2go_command_list(output_directory: Path, module: str) -> List[str]:
return [
"golds",
"-gen",
"-wdpkgs-listing=solo",
"-only-list-exporteds",
f"-dir={str(output_directory)}",
"-nouses",
"doc2go",
"-out",
str(output_directory),
f"{module}",
]

Expand All @@ -66,12 +64,12 @@ def _generate_goreleaser_check_command_list() -> List[str]:
]


def _install_golds_command_list() -> List[str]:
def _install_doc2go_command_list() -> List[str]:
return [
"go",
"install",
"go101.org/golds@main",
] # FIXME change version to latest when https://github.com/go101/golds/issues/26 is fixed
"go.abhg.dev/doc2go@latest",
]


def _install_syft_command_list() -> List[str]:
Expand All @@ -82,29 +80,63 @@ def _install_goreleaser_command_list() -> List[str]:
return ["go", "install", "github.com/goreleaser/goreleaser/v2@latest"]


def _call_golds(output_directory: Path, module: str) -> None:
"""Calls Golds for generating the docs."""
logger.info("Installing Golds if missing.")
def _ensure_go_tool_installed(
tool_name: str,
version_command: List[str],
install_command: List[str],
env: MutableMapping[str, str],
) -> None:
"""Ensure a Go-based tool is available on PATH before use."""
tool_path = shutil.which(tool_name)
if tool_path:
try:
check_output(version_command, env=env)
logger.info("Using %s from PATH: %s", tool_name, tool_path)
return
except Exception as exception:
logger.warning("Could not use %s from PATH: %s", tool_name, exception)

logger.info("Installing %s with go install.", tool_name)
check_call(install_command, env=env)


def _call_doc2go(output_directory: Path, module: str) -> None:
"""Call doc2go for generating the docs."""
env = os.environ
env[ENVVAR_GO_MOD] = GO_MOD_ON_VALUE
check_call(_install_golds_command_list(), env=env)
logger.info("Creating Code documentation.")
logger.info(f"Running Golds over [{module}] in [{SRC_DIR}].")
# check_call(_generate_golds_command_list(output_directory, module), cwd=str(SRC_DIR), env=env)
# FIXME
logger.warning(
"Currently not running golds because there is an issue with latest versions: "
+ "https://github.com/go101/golds/issues/26"
_ensure_go_tool_installed(
tool_name="doc2go",
version_command=["doc2go", "-version"],
install_command=_install_doc2go_command_list(),
env=env,
)
logger.info("Creating Code documentation.")
logger.info("Running doc2go over [%s] in [%s].", module, SRC_DIR)
# FIXME enable doc2go when fully tested
# check_call(
# _generate_doc2go_command_list(output_directory, module),
# cwd=str(SRC_DIR),
# env=env,
# )
logger.warning("Currently not running doc2go")


def _call_goreleaser_check(version: str) -> None:
"""Calls go releaser check to verify configuration."""
logger.info("Installing GoReleaser if missing.")
env = os.environ
env[ENVVAR_GO_MOD] = GO_MOD_ON_VALUE
check_call(_install_syft_command_list(), env=env)
check_call(_install_goreleaser_command_list(), env=env)
_ensure_go_tool_installed(
tool_name="syft",
version_command=["syft", "--version"],
install_command=_install_syft_command_list(),
env=env,
)
_ensure_go_tool_installed(
tool_name="goreleaser",
version_command=["goreleaser", "--version"],
install_command=_install_goreleaser_command_list(),
env=env,
)
logger.info("Checking GoReleaser configuration.")
env[ENVVAR_GORELEASER_CUSTOMISED_TAG] = version
env[ENVVAR_GORELEASER_GIT_TOKEN] = configuration.get_value(ConfigurationVariable.GIT_TOKEN)
Expand Down Expand Up @@ -136,7 +168,7 @@ class Go(BaseLanguage):

def get_related_language(self) -> str:
"""Gets the related language."""
return get_language_from_file_name(__file__)
return str(get_language_from_file_name(__file__))

def get_version_tag(self, version: str) -> str:
"""Gets tag based on version."""
Expand All @@ -161,7 +193,7 @@ def check_credentials(self) -> None:
def generate_code_documentation(self, output_directory: Path, module_to_document: str) -> None:
"""Generates the code documentation."""
super().generate_code_documentation(output_directory, module_to_document)
_call_golds(output_directory, "./...")
_call_doc2go(output_directory, module_to_document if module_to_document else "./...")

def can_add_licence_headers(self) -> bool:
"""States that licence headers can be added."""
Expand Down Expand Up @@ -189,11 +221,20 @@ def tag_release(self, git: GitWrapper, version: str, shortcuts: Dict[str, bool])

def _call_goreleaser_release(self, version: str) -> None:
"""Calls go releaser release to upload packages."""
logger.info("Installing GoReleaser if missing.")
env = os.environ
env[ENVVAR_GO_MOD] = GO_MOD_ON_VALUE
check_call(_install_syft_command_list(), env=env)
check_call(_install_goreleaser_command_list(), env=env)
_ensure_go_tool_installed(
tool_name="syft",
version_command=["syft", "--version"],
install_command=_install_syft_command_list(),
env=env,
)
_ensure_go_tool_installed(
tool_name="goreleaser",
version_command=["goreleaser", "--version"],
install_command=_install_goreleaser_command_list(),
env=env,
)
tag = self.get_version_tag(version)
# The tag of the release must be retrieved
# See https://github.com/goreleaser/goreleaser/discussions/1426
Expand Down
1 change: 1 addition & 0 deletions news/20260402160607.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:zap: `[GOLANG]` Check whether tools are already installed before attempting to installing it from scratch using `go install`
Loading