From d3970787c8106bb665e81993a07c240e6db32700 Mon Sep 17 00:00:00 2001 From: mailaenderli Date: Wed, 3 Sep 2025 14:17:24 +0000 Subject: [PATCH] feat(build-essential): add build-essential feature --- .github/workflows/ci.yml | 1 + README.md | 1 + build/build.go | 12 +++ features/src/build-essential/NOTES.md | 5 ++ features/src/build-essential/README.md | 25 ++++++ .../build-essential/devcontainer-feature.json | 17 ++++ features/src/build-essential/install.sh | 4 + features/src/build-essential/installer.go | 85 +++++++++++++++++++ features/test/build-essential/install.sh | 7 ++ features/test/build-essential/scenarios.json | 13 +++ .../test/build-essential/test-images.json | 5 ++ 11 files changed, 175 insertions(+) create mode 100644 features/src/build-essential/NOTES.md create mode 100755 features/src/build-essential/README.md create mode 100644 features/src/build-essential/devcontainer-feature.json create mode 100644 features/src/build-essential/install.sh create mode 100644 features/src/build-essential/installer.go create mode 100644 features/test/build-essential/install.sh create mode 100644 features/test/build-essential/scenarios.json create mode 100644 features/test/build-essential/test-images.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b8961ea..1baece9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,6 +16,7 @@ jobs: matrix: feature: [ "browsers", + "build-essential", "docker-out", "git-lfs", "go", diff --git a/README.md b/README.md index 4cc3f2b..9d7b87f 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ Below is a list with included features, click on the link for more details. | Name | Description | | --- | --- | | [browsers](./features/src/browsers/README.md) | A package which installs various browsers. | +| [build-essential](./features/src/build-essential/README.md) | Installs essential build tools (e.g., gcc, g++, make, libc-dev) for compiling C/C++ and | | [docker-out](./features/src/docker-out/README.md) | A feature which installs the Docker client and re-uses the host socket. | | [git-lfs](./features/src/git-lfs/README.md) | A feature which installs Git LFS. | | [go](./features/src/go/README.md) | A feature which installs Go. | diff --git a/build/build.go b/build/build.go index 99f40e6..fec748e 100644 --- a/build/build.go +++ b/build/build.go @@ -21,6 +21,7 @@ import ( var featureList = []string{ "browsers", + "build-essential", "docker-out", "git-lfs", "go", @@ -62,6 +63,17 @@ func init() { return publishFeature("browsers") }) + ////////// build-essential + gotaskr.Task("Feature:build-essential:Package", func() error { + return packageFeature("build-essential") + }) + gotaskr.Task("Feature:build-essential:Test", func() error { + return testFeature("build-essential") + }) + gotaskr.Task("Feature:build-essential:Publish", func() error { + return publishFeature("build-essential") + }) + ////////// docker-out gotaskr.Task("Feature:docker-out:Package", func() error { return packageFeature("docker-out") diff --git a/features/src/build-essential/NOTES.md b/features/src/build-essential/NOTES.md new file mode 100644 index 0000000..c620081 --- /dev/null +++ b/features/src/build-essential/NOTES.md @@ -0,0 +1,5 @@ +## Notes + +### System Compatibility + +Debian, Ubuntu diff --git a/features/src/build-essential/README.md b/features/src/build-essential/README.md new file mode 100755 index 0000000..fe449c7 --- /dev/null +++ b/features/src/build-essential/README.md @@ -0,0 +1,25 @@ +# Build Essential (build-essential) + +A package which installs build essentials like gcc. + +## Example Usage + +```json +"features": { + "ghcr.io/postfinance/devcontainer-features/build-essential:0.1.0": { + "version": "latest" + } +} +``` + +## Options + +| Option | Description | Type | Default Value | Proposals | +|-----|-----|-----|-----|-----| +| version | The version of the build essential package to install. | string | latest | latest, 12.9 | + +## Notes + +### System Compatibility + +Debian, Ubuntu diff --git a/features/src/build-essential/devcontainer-feature.json b/features/src/build-essential/devcontainer-feature.json new file mode 100644 index 0000000..112958f --- /dev/null +++ b/features/src/build-essential/devcontainer-feature.json @@ -0,0 +1,17 @@ +{ + "id": "build-essential", + "version": "0.1.0", + "name": "Build Essential", + "description": "A package which installs build essentials like gcc.", + "options": { + "version": { + "type": "string", + "proposals": [ + "latest", + "12.9" + ], + "default": "latest", + "description": "The version of the build essential package to install." + } + } +} diff --git a/features/src/build-essential/install.sh b/features/src/build-essential/install.sh new file mode 100644 index 0000000..0f53c8a --- /dev/null +++ b/features/src/build-essential/install.sh @@ -0,0 +1,4 @@ +. ./functions.sh + +"./installer_$(detect_arch)" \ + -version="${VERSION:-"latest"}" diff --git a/features/src/build-essential/installer.go b/features/src/build-essential/installer.go new file mode 100644 index 0000000..bc71cfd --- /dev/null +++ b/features/src/build-essential/installer.go @@ -0,0 +1,85 @@ +package main + +import ( + "builder/installer" + "flag" + "fmt" + "os" + "regexp" + "strings" + + "github.com/roemer/gotaskr/execr" + "github.com/roemer/gover" +) + +////////// +// Configuration +////////// + +const packageName = "build-essential" + +var versionOnlyRegex *regexp.Regexp = regexp.MustCompile(`[^\|]*\|\s+([^\|]*)\s+\|.*$`) +var buildEssentialVersionRegex *regexp.Regexp = regexp.MustCompile(`^(?P\d+)\.(?P\d+)`) + +////////// +// Main +////////// + +func main() { + if err := runMain(); err != nil { + fmt.Printf("Error: %v\n", err) + os.Exit(1) + } +} + +func runMain() error { + // Handle the flags + version := flag.String("version", "latest", "The version of build-essential to install.") + flag.Parse() + + // Create and process the feature + feature := installer.NewFeature("Build Essential", true, + &buildEssentialComponent{ + ComponentBase: installer.NewComponentBase(packageName, *version), + }) + return feature.Process() +} + +////////// +// Implementation +////////// + +type buildEssentialComponent struct { + *installer.ComponentBase +} + +func (c *buildEssentialComponent) GetAllVersions() ([]*gover.Version, error) { + if err := execr.Run(true, "apt-get", "update"); err != nil { + return []*gover.Version{}, err + } + + str1, _, err := execr.RunGetOutput(true, "apt-cache", "madison", packageName) + if err != nil { + return []*gover.Version{}, err + } + + allFiles := strings.Split(str1, "\n") + allVersions := []*gover.Version{} + for _, item := range allFiles { + matches := versionOnlyRegex.FindStringSubmatch(item) + if matches == nil { + continue + } + allVersions = append(allVersions, gover.MustParseVersionFromRegex(matches[1], buildEssentialVersionRegex)) + } + + return allVersions, nil +} + +func (c *buildEssentialComponent) InstallVersion(version *gover.Version) error { + if version == gover.EmptyVersion { + return installer.Tools.Apt.InstallDependencies(packageName, "pkg-config", "libpcsclite-dev") + } else { + return installer.Tools.Apt.InstallDependencies(fmt.Sprintf(packageName+"=%s", version.Raw), "pkg-config", "libpcsclite-dev") + } +} diff --git a/features/test/build-essential/install.sh b/features/test/build-essential/install.sh new file mode 100644 index 0000000..11e276f --- /dev/null +++ b/features/test/build-essential/install.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -e + +[[ -f "$(dirname "$0")/../functions.sh" ]] && source "$(dirname "$0")/../functions.sh" +[[ -f "$(dirname "$0")/functions.sh" ]] && source "$(dirname "$0")/functions.sh" + +check_package_installed build-essential diff --git a/features/test/build-essential/scenarios.json b/features/test/build-essential/scenarios.json new file mode 100644 index 0000000..cad1e11 --- /dev/null +++ b/features/test/build-essential/scenarios.json @@ -0,0 +1,13 @@ +{ + "install": { + "build": { + "dockerfile": "Dockerfile", + "options": [ + "--add-host=host.docker.internal:host-gateway" + ] + }, + "features": { + "./build-essential": {} + } + } +} \ No newline at end of file diff --git a/features/test/build-essential/test-images.json b/features/test/build-essential/test-images.json new file mode 100644 index 0000000..4db9a33 --- /dev/null +++ b/features/test/build-essential/test-images.json @@ -0,0 +1,5 @@ +[ + "mcr.microsoft.com/devcontainers/base:debian-11", + "mcr.microsoft.com/devcontainers/base:debian-12", + "mcr.microsoft.com/devcontainers/base:ubuntu-22.04" +] \ No newline at end of file