diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index b566055bc..8364323d9 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,28 +1,4 @@ { - "image": "mcr.microsoft.com/devcontainers/python:3.11", - "customizations": { - "vscode": { - "extensions": [ - "mads-hartmann.bash-ide-vscode", - "ms-python.python", - "ms-python.vscode-pylance", - "DavidAnson.vscode-markdownlint", - "nefrob.vscode-just-syntax", - "timonwong.shellcheck", - "ms-vscode-remote.remote-containers", - "github.vscode-github-actions" - ] - } - }, - "features": { - "ghcr.io/devcontainers/features/node:1.6.1": {}, - "ghcr.io/devcontainers/features/github-cli:1.0.13": {}, - "ghcr.io/devcontainers/features/docker-in-docker:2.12.0": {}, - "ghcr.io/lukewiwa/features/shellcheck:0.2.3": {}, - "ghcr.io/guiyomh/features/just:0": {}, - "ghcr.io/devcontainers-extra/features/pre-commit:2": {}, - "ghcr.io/devcontainers-extra/features/tmux-homebrew:1": {}, - "ghcr.io/devcontainers-extra/features/act:1": {} - }, + "image": "ghcr.io/devcontainers-extra/features/prebuilt-devcontainer:latest", "postCreateCommand": "/bin/bash -ex ./.devcontainer/setup.sh > postCreateCommand.log" } \ No newline at end of file diff --git a/.github/.devcontainer/devcontainer.json b/.github/.devcontainer/devcontainer.json new file mode 100644 index 000000000..410a0f03e --- /dev/null +++ b/.github/.devcontainer/devcontainer.json @@ -0,0 +1,27 @@ +{ + "image": "mcr.microsoft.com/devcontainers/python:3.11", + "customizations": { + "vscode": { + "extensions": [ + "mads-hartmann.bash-ide-vscode", + "ms-python.python", + "ms-python.vscode-pylance", + "DavidAnson.vscode-markdownlint", + "nefrob.vscode-just-syntax", + "timonwong.shellcheck", + "ms-vscode-remote.remote-containers", + "github.vscode-github-actions" + ] + } + }, + "features": { + "ghcr.io/devcontainers/features/node:1.6.1": {}, + "ghcr.io/devcontainers/features/github-cli:1.0.13": {}, + "ghcr.io/devcontainers/features/docker-in-docker:2.12.0": {}, + "ghcr.io/lukewiwa/features/shellcheck:0.2.3": {}, + "ghcr.io/guiyomh/features/just:0": {}, + "ghcr.io/devcontainers-extra/features/pre-commit:2": {}, + "ghcr.io/devcontainers-extra/features/act:1": {}, + "ghcr.io/devcontainers-extra/features/boilerplate:1": {} + } +} \ No newline at end of file diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 000000000..84ecab5c7 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: koralowiec diff --git a/.github/workflows/archive-feature.yaml b/.github/workflows/archive-feature.yaml new file mode 100644 index 000000000..56cc8c65d --- /dev/null +++ b/.github/workflows/archive-feature.yaml @@ -0,0 +1,48 @@ +name: Archive Feature + +on: + workflow_dispatch: + inputs: + feature_name: + description: 'Name of the feature to archive' + required: true + type: string + +jobs: + archive: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + token: ${{ secrets.ARCHIVE_TOKEN }} + + - name: Install just + uses: extractions/setup-just@v3 + + - name: Create branch for archiving + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git checkout -b archive/${{ inputs.feature_name }} + + - name: Archive feature + run: just archive ${{ inputs.feature_name }} + + - name: Commit changes + run: | + git add -A + git commit -m "chore: archive feature ${{ inputs.feature_name }}" + + - name: Push changes + run: git push origin archive/${{ inputs.feature_name }} + + - name: Create Pull Request + env: + GH_TOKEN: ${{ secrets.ARCHIVE_TOKEN }} + run: | + gh pr create \ + --title "Archive feature: ${{ inputs.feature_name }}" \ + --body "This PR archives the \`${{ inputs.feature_name }}\` feature by moving it to the archive directory." \ + --base main \ + --head archive/${{ inputs.feature_name }} diff --git a/.github/workflows/build-push-prebuilt-devcontainer.yaml b/.github/workflows/build-push-prebuilt-devcontainer.yaml new file mode 100644 index 000000000..4f731c024 --- /dev/null +++ b/.github/workflows/build-push-prebuilt-devcontainer.yaml @@ -0,0 +1,31 @@ +name: Build and Push Prebuilt Devcontainer + +on: + push: + branches: + - main + paths: + - '.github/.devcontainer/**' + workflow_dispatch: {} + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Prebuild dev container image + uses: devcontainers/ci@v0.3 + with: + subFolder: .github + imageName: ghcr.io/${{ github.repository }}/prebuilt-devcontainer + cacheFrom: ghcr.io/${{ github.repository }}/prebuilt-devcontainer + push: always diff --git a/.github/workflows/generate-gh-feature.yml b/.github/workflows/generate-gh-feature.yml new file mode 100644 index 000000000..0b65374ad --- /dev/null +++ b/.github/workflows/generate-gh-feature.yml @@ -0,0 +1,144 @@ +name: Generate Feature from gh-release Template + +on: + workflow_dispatch: + inputs: + ID: + description: 'Feature identifier (e.g., akamai-cli)' + required: true + type: string + Description: + description: 'Feature description' + required: true + type: string + Repository: + description: 'GitHub repository in format "owner/repo" (e.g., akamai/cli)' + required: true + type: string + BinaryNames: + description: 'Binary names (comma-separated if multiple)' + required: true + type: string + BinaryVersionCommands: + description: 'Version check commands (comma-separated if multiple)' + required: false + type: string + default: '--version' + BinaryNonLatestVersions: + description: 'Non-latest versions for testing (comma-separated if multiple)' + required: true + type: string + +jobs: + generate: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + token: ${{ secrets.ARCHIVE_TOKEN }} + + - name: Check if feature already exists + run: | + if [ -d "src/${{ inputs.ID }}" ] || [ -d "test/${{ inputs.ID }}" ]; then + echo "❌ Feature '${{ inputs.ID }}' already exists!" + echo "Please use a different feature ID or remove the existing feature first." + exit 1 + fi + echo "✅ Feature ID is available" + + - name: Validate GitHub repository exists + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + if gh api repos/${{ inputs.Repository }} > /dev/null 2>&1; then + echo "✅ Repository '${{ inputs.Repository }}' exists and is accessible" + else + echo "⚠️ Warning: Could not verify repository '${{ inputs.Repository }}'" + echo "The repository might be private, not exist, or you don't have access to it." + echo "Continuing with feature generation..." + fi + + - name: Download boilerplate + run: | + wget -q https://github.com/gruntwork-io/boilerplate/releases/download/v0.10.1/boilerplate_linux_amd64 + chmod +x boilerplate_linux_amd64 + + - name: Create vars.yml + run: | + cat > vars.yml << 'EOF' + ID: ${{ inputs.ID }} + Description: ${{ inputs.Description }} + Repository: ${{ inputs.Repository }} + BinaryNames: ${{ inputs.BinaryNames }} + BinaryVersionCommands: ${{ inputs.BinaryVersionCommands }} + BinaryNonLatestVersions: ${{ inputs.BinaryNonLatestVersions }} + EOF + echo "📝 Created vars.yml:" + cat vars.yml + + - name: Create branch for new feature + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git checkout -b feature/${{ inputs.ID }}-init + + - name: Generate feature files + run: | + echo "🔧 Generating feature files from templates/gh-release..." + ./boilerplate_linux_amd64 \ + --template-url templates/gh-release/ \ + --output-folder src/${{ inputs.ID }} \ + --var-file vars.yml \ + --non-interactive + + - name: Generate test files + run: | + echo "🧪 Generating test files from templates/test..." + ./boilerplate_linux_amd64 \ + --template-url templates/test/ \ + --output-folder test/${{ inputs.ID }} \ + --var-file vars.yml \ + --non-interactive + + - name: Commit changes + run: | + git add src/ test/ + git commit -m "feat(${{ inputs.ID }}): init + + Generated using boilerplate templates." + + - name: Push changes + run: git push origin feature/${{ inputs.ID }}-init + + - name: Create PR body file + run: | + cat > pr_body.md << 'EOF' + ## New Feature: `${{ inputs.ID }}` + + **Description:** ${{ inputs.Description }} + + **Repository:** [${{ inputs.Repository }}](https://github.com/${{ inputs.Repository }}) + + **Binaries:** `${{ inputs.BinaryNames }}` + + **Version Commands:** `${{ inputs.BinaryVersionCommands }}` + + **Test Versions:** `${{ inputs.BinaryNonLatestVersions }}` + + --- + + This PR was automatically generated using the boilerplate templates. + EOF + echo "📝 PR body content:" + cat pr_body.md + + - name: Create Pull Request + env: + GH_TOKEN: ${{ secrets.ARCHIVE_TOKEN }} + run: | + gh pr create \ + --title "feat(${{ inputs.ID }}): init" \ + --body-file pr_body.md \ + --base main \ + --head feature/${{ inputs.ID }}-init diff --git a/archive/src/airplane-cli/devcontainer-feature.json b/archive/src/airplane-cli/devcontainer-feature.json index 66a51bbb5..5417e66b2 100644 --- a/archive/src/airplane-cli/devcontainer-feature.json +++ b/archive/src/airplane-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "airplane-cli", - "version": "1.0.5", + "version": "1.0.6", "name": "Airplane CLI (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/airplane-cli", "description": "The Airplane CLI, airplane, is the primary way you'll create and deploy new tasks and runbooks. The CLI also provides utility methods for managing API keys, getting/setting configs, and executing tasks/runbooks.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/argo-workflows/README.md b/archive/src/argo-workflows/README.md similarity index 100% rename from src/argo-workflows/README.md rename to archive/src/argo-workflows/README.md diff --git a/src/argo-workflows/devcontainer-feature.json b/archive/src/argo-workflows/devcontainer-feature.json similarity index 96% rename from src/argo-workflows/devcontainer-feature.json rename to archive/src/argo-workflows/devcontainer-feature.json index f59eaa73b..0187f7431 100644 --- a/src/argo-workflows/devcontainer-feature.json +++ b/archive/src/argo-workflows/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "Argo Workflows CLI (via Github Releases)", "id": "argo-workflows", - "version": "1.0.2", + "version": "1.0.3", "description": "Argo Workflows is an open source container-native workflow engine for orchestrating parallel jobs on Kubernetes", "documentationURL": "https://github.com/devcontainers-extra/features/tree/main/src/argo-workflows", "options": { @@ -15,4 +15,4 @@ "description": "Select the Argo Workflows CLI version you would like to install" } } -} \ No newline at end of file +} diff --git a/src/argo-workflows/install.sh b/archive/src/argo-workflows/install.sh similarity index 100% rename from src/argo-workflows/install.sh rename to archive/src/argo-workflows/install.sh diff --git a/archive/src/bitwarden-cli/devcontainer-feature.json b/archive/src/bitwarden-cli/devcontainer-feature.json index 5d53b3f14..39e003016 100644 --- a/archive/src/bitwarden-cli/devcontainer-feature.json +++ b/archive/src/bitwarden-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "bitwarden-cli", - "version": "1.0.2", + "version": "1.0.3", "name": "Bitwarden CLI (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/bitwarden-cli", "description": "The Bitwarden command-line interface (CLI) is a powerful, fully-featured tool for accessing and managing your vault.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/archive/src/cert-manager/devcontainer-feature.json b/archive/src/cert-manager/devcontainer-feature.json index 26f910611..71efb6b03 100644 --- a/archive/src/cert-manager/devcontainer-feature.json +++ b/archive/src/cert-manager/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "cert-manager", - "version": "1.0.2", + "version": "1.0.3", "name": "cert-manager (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/cert-manager", "description": "cert-manager adds certificates and certificate issuers as resource types in Kubernetes clusters, and simplifies the process of obtaining, renewing and using those certificates.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/archive/src/cmctl-asdf/devcontainer-feature.json b/archive/src/cmctl-asdf/devcontainer-feature.json index f77e356e4..601d0ae40 100644 --- a/archive/src/cmctl-asdf/devcontainer-feature.json +++ b/archive/src/cmctl-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "cmctl-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "cmctl (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/cmctl-asdf", "description": "cmctl is a command line tool that can help you manage cert-manager and its resources inside your cluster.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/archive/src/codenotary-cas/devcontainer-feature.json b/archive/src/codenotary-cas/devcontainer-feature.json index dedf5932c..25b91de7c 100644 --- a/archive/src/codenotary-cas/devcontainer-feature.json +++ b/archive/src/codenotary-cas/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "codenotary-cas", - "version": "1.0.9", + "version": "1.0.10", "name": "Codenotary Community Attestation Service (CAS) (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/codenotary-cas", "description": "Community Attestation Service (CAS) can give any digital asset a meaningful, globally-unique, immutable identity that is authentic, verifiable, traceable from anywhere.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/archive/src/croc/devcontainer-feature.json b/archive/src/croc/devcontainer-feature.json index 3afed86a2..0498201f1 100644 --- a/archive/src/croc/devcontainer-feature.json +++ b/archive/src/croc/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "croc", - "version": "1.0.5", + "version": "1.0.6", "name": "croc (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/croc", "description": "croc is a tool that allows any two computers to simply and securely transfer files and folders.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/archive/src/cue-asdf/devcontainer-feature.json b/archive/src/cue-asdf/devcontainer-feature.json index 2e89a1b84..c28db00df 100644 --- a/archive/src/cue-asdf/devcontainer-feature.json +++ b/archive/src/cue-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "cue-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "CUE (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/cue-asdf", "description": "CUE is an open source data constraint language which aims to simplify tasks involving defining and using data.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/archive/src/edge-impulse-cli/devcontainer-feature.json b/archive/src/edge-impulse-cli/devcontainer-feature.json index 13841187c..91814a757 100644 --- a/archive/src/edge-impulse-cli/devcontainer-feature.json +++ b/archive/src/edge-impulse-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "edge-impulse-cli", - "version": "1.0.2", + "version": "1.0.3", "name": "Edge Impulse CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/edge-impulse-cli", "description": "Edge Impulse CLI is used to control local devices, act as a proxy to synchronise data for devices that don't have an internet connection, and to upload and convert local files.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/elasticsearch-asdf/README.md b/archive/src/elasticsearch-asdf/README.md similarity index 100% rename from src/elasticsearch-asdf/README.md rename to archive/src/elasticsearch-asdf/README.md diff --git a/src/elasticsearch-asdf/devcontainer-feature.json b/archive/src/elasticsearch-asdf/devcontainer-feature.json similarity index 95% rename from src/elasticsearch-asdf/devcontainer-feature.json rename to archive/src/elasticsearch-asdf/devcontainer-feature.json index 7ad070706..869531195 100644 --- a/src/elasticsearch-asdf/devcontainer-feature.json +++ b/archive/src/elasticsearch-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "elasticsearch-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "Elasticsearch (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/elasticsearch-asdf", "description": "Elasticsearch is a search engine based on the Lucene library.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/elasticsearch-asdf/install.sh b/archive/src/elasticsearch-asdf/install.sh similarity index 100% rename from src/elasticsearch-asdf/install.sh rename to archive/src/elasticsearch-asdf/install.sh diff --git a/archive/src/boundary-asdf/library_scripts.sh b/archive/src/elasticsearch-asdf/library_scripts.sh similarity index 100% rename from archive/src/boundary-asdf/library_scripts.sh rename to archive/src/elasticsearch-asdf/library_scripts.sh diff --git a/archive/src/elixir-asdf/devcontainer-feature.json b/archive/src/elixir-asdf/devcontainer-feature.json index e9e2efb77..4b5f931bd 100644 --- a/archive/src/elixir-asdf/devcontainer-feature.json +++ b/archive/src/elixir-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "elixir-asdf", - "version": "2.0.19", + "version": "2.0.20", "name": "Elixir (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/elixir-asdf", "description": "Elixir is a functional, concurrent, general-purpose programming language that runs on the BEAM virtual machine which is also used to implement the Erlang programming language.", @@ -26,4 +26,4 @@ "ghcr.io/devcontainers-extra/features/apt-get-packages", "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/archive/src/erlang-asdf/devcontainer-feature.json b/archive/src/erlang-asdf/devcontainer-feature.json index cb2389dfe..ff4966724 100644 --- a/archive/src/erlang-asdf/devcontainer-feature.json +++ b/archive/src/erlang-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "erlang-asdf", - "version": "2.0.18", + "version": "2.0.19", "name": "Erlang (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/erlang-asdf", "description": "Erlang is a general-purpose, concurrent, functional programming language, and a garbage-collected runtime system.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/asdf-package", "ghcr.io/devcontainers-extra/features/apt-get-packages" ] -} \ No newline at end of file +} diff --git a/archive/src/ffmpeg-homebrew/devcontainer-feature.json b/archive/src/ffmpeg-homebrew/devcontainer-feature.json index 799be41fa..f5873a353 100644 --- a/archive/src/ffmpeg-homebrew/devcontainer-feature.json +++ b/archive/src/ffmpeg-homebrew/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ffmpeg-homebrew", - "version": "1.0.19", + "version": "1.0.20", "name": "FFmpeg (via Homebrew)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ffmpeg-homebrew", "description": "FFmpeg is the leading multimedia framework, able to decode, encode, transcode, mux, demux, stream, filter and play pretty much anything that humans and machines have created. It supports the most obscure ancient formats up to the cutting edge. No matter if they were designed by some standards committee, the community or a corporation. It is also highly portable: FFmpeg compiles, runs, and passes our testing infrastructure FATE across Linux, Mac OS X, Microsoft Windows, the BSDs, Solaris, etc. under a wide variety of build environments, machine architectures, and configurations.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/homebrew-package" ] -} \ No newline at end of file +} diff --git a/src/gleam/README.md b/archive/src/gleam/README.md similarity index 100% rename from src/gleam/README.md rename to archive/src/gleam/README.md diff --git a/src/gleam/devcontainer-feature.json b/archive/src/gleam/devcontainer-feature.json similarity index 96% rename from src/gleam/devcontainer-feature.json rename to archive/src/gleam/devcontainer-feature.json index 3a228cccf..20d5426a6 100644 --- a/src/gleam/devcontainer-feature.json +++ b/archive/src/gleam/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "gleam", - "version": "1.0.0", + "version": "1.0.1", "name": "Gleam (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/gleam", "description": "Gleam is a friendly language for building type-safe, scalable systems. (Gleam compiles to Erlang code, so Erlang needs to be installed to run Gleam code.)", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/gleam/install.sh b/archive/src/gleam/install.sh similarity index 100% rename from src/gleam/install.sh rename to archive/src/gleam/install.sh diff --git a/archive/src/age-keygen/library_scripts.sh b/archive/src/gleam/library_scripts.sh similarity index 100% rename from archive/src/age-keygen/library_scripts.sh rename to archive/src/gleam/library_scripts.sh diff --git a/archive/src/homebrew-package/devcontainer-feature.json b/archive/src/homebrew-package/devcontainer-feature.json index c44f415da..933b189ca 100644 --- a/archive/src/homebrew-package/devcontainer-feature.json +++ b/archive/src/homebrew-package/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "Homebrew Package", "id": "homebrew-package", - "version": "1.0.8", + "version": "1.0.9", "description": "Installs a Homebrew package.", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/homebrew-package", "installsAfter": [ @@ -35,4 +35,4 @@ "description": "Additional installation flags. These would be used as extra arguments to the brew command (`brew install @`)" } } -} \ No newline at end of file +} diff --git a/src/istioctl/README.md b/archive/src/istioctl/README.md similarity index 100% rename from src/istioctl/README.md rename to archive/src/istioctl/README.md diff --git a/src/istioctl/devcontainer-feature.json b/archive/src/istioctl/devcontainer-feature.json similarity index 96% rename from src/istioctl/devcontainer-feature.json rename to archive/src/istioctl/devcontainer-feature.json index 1204d9daa..c7eaa663a 100644 --- a/src/istioctl/devcontainer-feature.json +++ b/archive/src/istioctl/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "istioctl", - "version": "1.0.5", + "version": "1.0.6", "name": "Istio CLI (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/istioctl", "description": "The istioctl tool is a configuration command line utility that allows service operators to debug and diagnose their Istio service mesh deployments.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/istioctl/install.sh b/archive/src/istioctl/install.sh similarity index 100% rename from src/istioctl/install.sh rename to archive/src/istioctl/install.sh diff --git a/archive/src/btm/library_scripts.sh b/archive/src/istioctl/library_scripts.sh similarity index 100% rename from archive/src/btm/library_scripts.sh rename to archive/src/istioctl/library_scripts.sh diff --git a/archive/src/ko/devcontainer-feature.json b/archive/src/ko/devcontainer-feature.json index 473194ccd..f69fe3720 100644 --- a/archive/src/ko/devcontainer-feature.json +++ b/archive/src/ko/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ko", - "version": "1.0.9", + "version": "1.0.10", "name": "ko (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ko", "description": "ko is a simple, fast container image builder for Go applications.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/archive/src/kubescape/devcontainer-feature.json b/archive/src/kubescape/devcontainer-feature.json index d6a245cbb..7ad27c128 100644 --- a/archive/src/kubescape/devcontainer-feature.json +++ b/archive/src/kubescape/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "kubescape", - "version": "1.0.5", + "version": "1.0.6", "name": "Kubescape (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/kubescape", "description": "Kubescape is an open-source Kubernetes security platform. It includes risk analysis, security compliance, and misconfiguration scanning. Targeted at the DevSecOps practitioner or platform engineer, it offers an easy-to-use CLI interface, flexible output formats, and automated scanning capabilities. It saves Kubernetes users and admins precious time, effort, and resources.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/archive/src/mage/devcontainer-feature.json b/archive/src/mage/devcontainer-feature.json index 75801a715..cdfe0cfab 100644 --- a/archive/src/mage/devcontainer-feature.json +++ b/archive/src/mage/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "mage", - "version": "1.0.5", + "version": "1.0.6", "name": "Mage (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/mage", "description": "Mage is a make-like build tool using Go. You write plain-old go functions, and Mage automatically uses them as Makefile-like runnable targets.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/archive/src/meson-asdf/devcontainer-feature.json b/archive/src/meson-asdf/devcontainer-feature.json index 503d1129f..30c085526 100644 --- a/archive/src/meson-asdf/devcontainer-feature.json +++ b/archive/src/meson-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "meson-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "Meson (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/meson-asdf", "description": "Meson is an open source build system meant to be both extremely fast, and, even more importantly, as user friendly as possible.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/archive/src/meteor-cli/devcontainer-feature.json b/archive/src/meteor-cli/devcontainer-feature.json index 36d8c3580..9a67a86b6 100644 --- a/archive/src/meteor-cli/devcontainer-feature.json +++ b/archive/src/meteor-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "meteor-cli", - "version": "1.0.2", + "version": "1.0.3", "name": "Meteor CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/meteor-cli", "description": "Meteor is a full-stack JavaScript platform for developing modern web and mobile applications. Meteor includes a key set of technologies for building connected-client reactive applications, a build tool, and a curated set of packages from the Node.js and general JavaScript community.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/archive/src/nushell/devcontainer-feature.json b/archive/src/nushell/devcontainer-feature.json index 12137c3c5..4932679a5 100644 --- a/archive/src/nushell/devcontainer-feature.json +++ b/archive/src/nushell/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "nushell", - "version": "1.0.9", + "version": "1.0.10", "name": "Nushell (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/nushell", "description": "Nushell is a shell with a focus on operating on structured data in the command line.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/archive/src/ory-keto/devcontainer-feature.json b/archive/src/ory-keto/devcontainer-feature.json index 6e0ab8978..9e4adf301 100644 --- a/archive/src/ory-keto/devcontainer-feature.json +++ b/archive/src/ory-keto/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ory-keto", - "version": "1.0.5", + "version": "1.0.6", "name": "Ory Keto (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ory-keto", "description": "Ory Keto is an implementation of 'Zanzibar: Google's Consistent, Global Authorization System'. Ships gRPC, REST APIs, newSQL, and an easy and granular permission language. Supports ACL, RBAC, and other access models.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/archive/src/pip-audit/devcontainer-feature.json b/archive/src/pip-audit/devcontainer-feature.json index c92590b16..a56722e0f 100644 --- a/archive/src/pip-audit/devcontainer-feature.json +++ b/archive/src/pip-audit/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "pip-audit", - "version": "1.0.4", + "version": "1.0.5", "name": "CVE Binary Tool (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/pip-audit", "description": "pip-audit is a tool for scanning Python environments for packages with known vulnerabilities.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/pipx-package/README.md b/archive/src/pipx-package/README.md similarity index 100% rename from src/pipx-package/README.md rename to archive/src/pipx-package/README.md diff --git a/src/pipx-package/devcontainer-feature.json b/archive/src/pipx-package/devcontainer-feature.json similarity index 98% rename from src/pipx-package/devcontainer-feature.json rename to archive/src/pipx-package/devcontainer-feature.json index 5094b1c3b..38256aa12 100644 --- a/src/pipx-package/devcontainer-feature.json +++ b/archive/src/pipx-package/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "Pipx package", "id": "pipx-package", - "version": "1.1.9", + "version": "1.1.10", "description": "Installs a pipx package.", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/pipx-package", "installsAfter": [ @@ -46,4 +46,4 @@ "description": "Force python interpreter to be use (must already exists on the container). If none selected (the default) then python3 will be used (and will be installed in case it does not exists)" } } -} \ No newline at end of file +} diff --git a/src/pipx-package/install.sh b/archive/src/pipx-package/install.sh similarity index 100% rename from src/pipx-package/install.sh rename to archive/src/pipx-package/install.sh diff --git a/archive/src/porter/devcontainer-feature.json b/archive/src/porter/devcontainer-feature.json index d3078aace..fa1dbfc9c 100644 --- a/archive/src/porter/devcontainer-feature.json +++ b/archive/src/porter/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "porter", - "version": "1.0.3", + "version": "1.0.4", "name": "Porter (via porter.sh)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/porter", "description": "Porter enables you to package your application artifact, client tools, configuration and deployment logic together as an installer that you can distribute, and install with a single command.", @@ -98,4 +98,4 @@ "PATH": "/usr/local/porter:${PATH}", "PORTER_HOME": "/usr/local/porter" } -} \ No newline at end of file +} diff --git a/archive/src/postgres-asdf/devcontainer-feature.json b/archive/src/postgres-asdf/devcontainer-feature.json index fc0305f07..4a62e5096 100644 --- a/archive/src/postgres-asdf/devcontainer-feature.json +++ b/archive/src/postgres-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "postgres-asdf", - "version": "1.0.3", + "version": "1.0.4", "name": "PostgreSQL (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/postgres-asdf", "description": "PostgreSQL is a powerful, open source object-relational database system with over 35 years of active development that has earned it a strong reputation for reliability, feature robustness, and performance.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/archive/src/rabbitmq-asdf/devcontainer-feature.json b/archive/src/rabbitmq-asdf/devcontainer-feature.json index 714f8b61b..40188dc2e 100644 --- a/archive/src/rabbitmq-asdf/devcontainer-feature.json +++ b/archive/src/rabbitmq-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "rabbitmq-asdf", - "version": "1.0.4", + "version": "1.0.5", "name": "Rabbitmq (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/kubectl-asdf", "description": "RabbitMQ is a feature rich, multi-protocol messaging and streaming broker.", @@ -25,4 +25,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/archive/src/scala-asdf/devcontainer-feature.json b/archive/src/scala-asdf/devcontainer-feature.json index c83deff17..054f2eb1d 100644 --- a/archive/src/scala-asdf/devcontainer-feature.json +++ b/archive/src/scala-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "scala-asdf", - "version": "2.0.17", + "version": "2.0.18", "name": "scala (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/scala-asdf", "description": "Scala combines object-oriented and functional programming in one concise, high-level language", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/asdf-package", "ghcr.io/devcontainers-extra/features/apt-get-packages" ] -} \ No newline at end of file +} diff --git a/archive/src/serverless/devcontainer-feature.json b/archive/src/serverless/devcontainer-feature.json index 961cb6741..815bcf4fd 100644 --- a/archive/src/serverless/devcontainer-feature.json +++ b/archive/src/serverless/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "serverless", - "version": "2.0.15", + "version": "2.0.16", "name": "Serverless Framework (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/serverless", "description": "Serverless Framework is a widely used open-source IaC tool that allows you to build, and deploy serverless applications on multiple cloud providers.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/archive/src/sqlfmt/devcontainer-feature.json b/archive/src/sqlfmt/devcontainer-feature.json index 0f0af4974..78f667059 100644 --- a/archive/src/sqlfmt/devcontainer-feature.json +++ b/archive/src/sqlfmt/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "sqlfmt", - "version": "1.0.1", + "version": "1.0.2", "name": "sqlfmt (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/sqlfmt", "description": "sqlfmt formats your dbt SQL files so you don't have to.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/archive/src/syncthing/devcontainer-feature.json b/archive/src/syncthing/devcontainer-feature.json index 8bbca02b9..29a8366e7 100644 --- a/archive/src/syncthing/devcontainer-feature.json +++ b/archive/src/syncthing/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "syncthing", - "version": "1.0.2", + "version": "1.0.3", "name": "Syncthing (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/syncthing", "description": "Syncthing is a continuous file synchronization program. It synchronizes files between two or more computers.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/tea/README.md b/archive/src/tea/README.md similarity index 100% rename from src/tea/README.md rename to archive/src/tea/README.md diff --git a/src/tea/devcontainer-feature.json b/archive/src/tea/devcontainer-feature.json similarity index 95% rename from src/tea/devcontainer-feature.json rename to archive/src/tea/devcontainer-feature.json index 20b540e6b..96ee735b9 100644 --- a/src/tea/devcontainer-feature.json +++ b/archive/src/tea/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "tea", - "version": "1.0.9", + "version": "1.0.10", "name": "tea (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/tea", "description": "tea is the next-generation, cross-platform package manager from the creator of brew.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/tea/install.sh b/archive/src/tea/install.sh similarity index 100% rename from src/tea/install.sh rename to archive/src/tea/install.sh diff --git a/src/gleam/library_scripts.sh b/archive/src/tea/library_scripts.sh similarity index 100% rename from src/gleam/library_scripts.sh rename to archive/src/tea/library_scripts.sh diff --git a/archive/src/trivy/devcontainer-feature.json b/archive/src/trivy/devcontainer-feature.json index d930267a2..10b384ed4 100644 --- a/archive/src/trivy/devcontainer-feature.json +++ b/archive/src/trivy/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "trivy", - "version": "1.0.9", + "version": "1.0.10", "name": "Trivy (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/trivy", "description": "Trivy is a comprehensive and versatile security scanner. It finds vulnerabilities, misconfigurations, secrets, SBOM in containers, Kubernetes, code repositories, clouds and more.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/archive/src/vertx-sdkman/devcontainer-feature.json b/archive/src/vertx-sdkman/devcontainer-feature.json index 2d0909eb9..2d50425e8 100644 --- a/archive/src/vertx-sdkman/devcontainer-feature.json +++ b/archive/src/vertx-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "vertx-sdkman", - "version": "2.0.16", + "version": "2.0.17", "name": "Vert.x (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/vertx-sdkman", "description": "Vert.x is a tool-kit for building reactive applications on the JVM.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/archive/src/visualvm-sdkman/devcontainer-feature.json b/archive/src/visualvm-sdkman/devcontainer-feature.json index 291662973..5465d324e 100644 --- a/archive/src/visualvm-sdkman/devcontainer-feature.json +++ b/archive/src/visualvm-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "visualvm-sdkman", - "version": "2.0.16", + "version": "2.0.17", "name": "VisualVM (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/visualvm-sdkman", "description": "VisualVM is a tool that provides a visual interface for viewing detailed\ninformation about Java applications while they are running on a Java Virtual\nMachine.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/archive/src/volta/devcontainer-feature.json b/archive/src/volta/devcontainer-feature.json index 10a8a4997..459d58d43 100644 --- a/archive/src/volta/devcontainer-feature.json +++ b/archive/src/volta/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "volta", - "version": "1.0.5", + "version": "1.0.6", "name": "Volta (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/volta", "description": "Volta is a hassle-free way to manage your JavaScript command-line tools.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/archive/src/xplr/devcontainer-feature.json b/archive/src/xplr/devcontainer-feature.json index d4b9b5ad1..8349c98b1 100644 --- a/archive/src/xplr/devcontainer-feature.json +++ b/archive/src/xplr/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "xplr", - "version": "1.0.9", + "version": "1.0.10", "name": "xplr (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/xplr", "description": "xplr is a terminal UI based file explorer that aims to increase our terminal productivity by being a flexible, interactive orchestrator for the ever growing awesome command-line utilities that work with the file-system.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/test/argo-workflows/scenarios.json b/archive/test/argo-workflows/scenarios.json similarity index 100% rename from test/argo-workflows/scenarios.json rename to archive/test/argo-workflows/scenarios.json diff --git a/test/argo-workflows/test.sh b/archive/test/argo-workflows/test.sh similarity index 100% rename from test/argo-workflows/test.sh rename to archive/test/argo-workflows/test.sh diff --git a/archive/test/btm/scenarios.json b/archive/test/btm/scenarios.json deleted file mode 100644 index 56389dc03..000000000 --- a/archive/test/btm/scenarios.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "test_defaults_debian": { - "image": "mcr.microsoft.com/devcontainers/base:debian", - "features": { - "btm": {} - } - } -} \ No newline at end of file diff --git a/test/elasticsearch-asdf/scenarios.json b/archive/test/elasticsearch-asdf/scenarios.json similarity index 100% rename from test/elasticsearch-asdf/scenarios.json rename to archive/test/elasticsearch-asdf/scenarios.json diff --git a/test/elasticsearch-asdf/test.sh b/archive/test/elasticsearch-asdf/test.sh similarity index 100% rename from test/elasticsearch-asdf/test.sh rename to archive/test/elasticsearch-asdf/test.sh diff --git a/test/gleam/scenarios.json b/archive/test/gleam/scenarios.json similarity index 100% rename from test/gleam/scenarios.json rename to archive/test/gleam/scenarios.json diff --git a/test/gleam/test_defaults_debian.sh b/archive/test/gleam/test_defaults_debian.sh similarity index 100% rename from test/gleam/test_defaults_debian.sh rename to archive/test/gleam/test_defaults_debian.sh diff --git a/test/istioctl/scenarios.json b/archive/test/istioctl/scenarios.json similarity index 100% rename from test/istioctl/scenarios.json rename to archive/test/istioctl/scenarios.json diff --git a/test/istioctl/test_defaults_debian.sh b/archive/test/istioctl/test_defaults_debian.sh similarity index 100% rename from test/istioctl/test_defaults_debian.sh rename to archive/test/istioctl/test_defaults_debian.sh diff --git a/test/pipx-package/install_ansible_specific_version.sh b/archive/test/pipx-package/install_ansible_specific_version.sh similarity index 100% rename from test/pipx-package/install_ansible_specific_version.sh rename to archive/test/pipx-package/install_ansible_specific_version.sh diff --git a/test/pipx-package/install_black.sh b/archive/test/pipx-package/install_black.sh similarity index 100% rename from test/pipx-package/install_black.sh rename to archive/test/pipx-package/install_black.sh diff --git a/test/pipx-package/install_black_custom_interpreter.sh b/archive/test/pipx-package/install_black_custom_interpreter.sh similarity index 100% rename from test/pipx-package/install_black_custom_interpreter.sh rename to archive/test/pipx-package/install_black_custom_interpreter.sh diff --git a/test/pipx-package/install_black_debian_bookworm.sh b/archive/test/pipx-package/install_black_debian_bookworm.sh similarity index 100% rename from test/pipx-package/install_black_debian_bookworm.sh rename to archive/test/pipx-package/install_black_debian_bookworm.sh diff --git a/test/pipx-package/install_precommit.sh b/archive/test/pipx-package/install_precommit.sh similarity index 100% rename from test/pipx-package/install_precommit.sh rename to archive/test/pipx-package/install_precommit.sh diff --git a/test/pipx-package/scenarios.json b/archive/test/pipx-package/scenarios.json similarity index 100% rename from test/pipx-package/scenarios.json rename to archive/test/pipx-package/scenarios.json diff --git a/test/tea/scenarios.json b/archive/test/tea/scenarios.json similarity index 100% rename from test/tea/scenarios.json rename to archive/test/tea/scenarios.json diff --git a/test/tea/test_defaults_debian.sh b/archive/test/tea/test_defaults_debian.sh similarity index 100% rename from test/tea/test_defaults_debian.sh rename to archive/test/tea/test_defaults_debian.sh diff --git a/justfile b/justfile index ecc0b557b..50af130e2 100644 --- a/justfile +++ b/justfile @@ -1,5 +1,7 @@ set positional-arguments +sed_inplace := if os() == "macos" { "-i ''" } else { "-i" } + test feature-name: devcontainer features test -f {{feature-name}} --skip-autogenerated @@ -16,7 +18,7 @@ archive feature-name: add feature-name: mkdir -p src/{{feature-name}} test/{{feature-name}} - cp templates/src/* src/{{feature-name}}/ - cp templates/test/* test/{{feature-name}}/ - sed -i "s//{{feature-name}}/g" src/{{feature-name}}/* - sed -i "s//{{feature-name}}/g" test/{{feature-name}}/* \ No newline at end of file + cp templates/bak/src/* src/{{feature-name}}/ + cp templates/bak/test/* test/{{feature-name}}/ + sed {{sed_inplace}} "s//{{feature-name}}/g" src/{{feature-name}}/* + sed {{sed_inplace}} "s//{{feature-name}}/g" test/{{feature-name}}/* diff --git a/src/act-asdf/devcontainer-feature.json b/src/act-asdf/devcontainer-feature.json index 9ec431ee0..60bf686c3 100644 --- a/src/act-asdf/devcontainer-feature.json +++ b/src/act-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "act-asdf", - "version": "2.0.14", + "version": "2.0.15", "name": "act (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/act-asdf", "description": "Act is an open source project that allows you to run your github flow locally.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/act/devcontainer-feature.json b/src/act/devcontainer-feature.json index 25e0c891b..b87373b73 100644 --- a/src/act/devcontainer-feature.json +++ b/src/act/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "act", - "version": "1.0.14", + "version": "1.0.15", "name": "act (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/act", "description": "Act is an open source project that allows you to run your github flow locally.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/actionlint/devcontainer-feature.json b/src/actionlint/devcontainer-feature.json index 4b765b037..b22294ec0 100644 --- a/src/actionlint/devcontainer-feature.json +++ b/src/actionlint/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "actionlint", - "version": "1.0.6", + "version": "1.0.7", "name": "actionlint (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/actionlint", "description": "Static checker for GitHub Actions workflow files.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/actions-runner/devcontainer-feature.json b/src/actions-runner/devcontainer-feature.json index 995a40b34..7cc433ca7 100644 --- a/src/actions-runner/devcontainer-feature.json +++ b/src/actions-runner/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "actions-runner", - "version": "1.0.12", + "version": "1.0.13", "name": "GitHub Actions Runner", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/actions-runner", "description": "The runner is the application that runs a job from a GitHub Actions workflow. It is used by GitHub Actions in the hosted virtual environments, or you can self-host the runner in your own environment.", @@ -26,4 +26,4 @@ "ghcr.io/devcontainers-extra/features/gh-release", "ghcr.io/devcontainers/features/dotnet" ] -} \ No newline at end of file +} diff --git a/src/activemq-sdkman/devcontainer-feature.json b/src/activemq-sdkman/devcontainer-feature.json index 4b14ca02b..af52f3acb 100644 --- a/src/activemq-sdkman/devcontainer-feature.json +++ b/src/activemq-sdkman/devcontainer-feature.json @@ -1,9 +1,9 @@ { "id": "activemq-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "Apache ActiveMQ (Classic) (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/activemq-sdkman", - "description": "Apache ActiveMQ\u00ae is a popular open source, multi-protocol, Java-based message\nbroker. It supports industry standard protocols so users get the benefits of\nclient choices across a broad range of languages and platforms. Connect from\nclients written in JavaScript, C, C++, Python, .Net, and more. Integrate your\nmulti-platform applications using the ubiquitous AMQP protocol. Exchange\nmessages between your web applications using STOMP over websockets. Manage your\nIoT devices using MQTT. Support your existing JMS infrastructure and beyond.\nActiveMQ offers the power and flexibility to support any messaging use-case.", + "description": "Apache ActiveMQ® is a popular open source, multi-protocol, Java-based message\nbroker. It supports industry standard protocols so users get the benefits of\nclient choices across a broad range of languages and platforms. Connect from\nclients written in JavaScript, C, C++, Python, .Net, and more. Integrate your\nmulti-platform applications using the ubiquitous AMQP protocol. Exchange\nmessages between your web applications using STOMP over websockets. Manage your\nIoT devices using MQTT. Support your existing JMS infrastructure and beyond.\nActiveMQ offers the power and flexibility to support any messaging use-case.", "options": { "version": { "default": "latest", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/archive/src/age-keygen/README.md b/src/age-keygen/README.md similarity index 100% rename from archive/src/age-keygen/README.md rename to src/age-keygen/README.md diff --git a/archive/src/age-keygen/devcontainer-feature.json b/src/age-keygen/devcontainer-feature.json similarity index 95% rename from archive/src/age-keygen/devcontainer-feature.json rename to src/age-keygen/devcontainer-feature.json index 4fcc779bd..c12cb7489 100644 --- a/archive/src/age-keygen/devcontainer-feature.json +++ b/src/age-keygen/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "age-keygen", - "version": "1.0.14", + "version": "1.0.17", "name": "age-keygen (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/age-keygen", "description": "age-keygen generate a key pair for use with age.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/archive/src/age-keygen/install.sh b/src/age-keygen/install.sh similarity index 74% rename from archive/src/age-keygen/install.sh rename to src/age-keygen/install.sh index 2a0e98201..4cf15f66c 100755 --- a/archive/src/age-keygen/install.sh +++ b/src/age-keygen/install.sh @@ -1,4 +1,3 @@ - set -e . ./library_scripts.sh @@ -8,16 +7,12 @@ set -e # `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, # and if missing - will download a temporary copy that automatically get deleted at the end # of the script -ensure_nanolayer nanolayer_location "v0.5.4" - +ensure_nanolayer nanolayer_location "v0.5.6" $nanolayer_location \ install \ devcontainer-feature \ - "ghcr.io/devcontainers-extra/features/gh-release:1.0.25" \ - --option repo='filosottile/age' --option binaryNames='age-keygen' --option version="$VERSION" - - + "ghcr.io/devcontainers-extra/features/gh-release:1.0.26" \ + --option repo='filosottile/age' --option binaryNames='age-keygen' --option version="$VERSION" --option assetRegex='.*(.tar.gz)$' echo 'Done!' - diff --git a/src/istioctl/library_scripts.sh b/src/age-keygen/library_scripts.sh similarity index 100% rename from src/istioctl/library_scripts.sh rename to src/age-keygen/library_scripts.sh diff --git a/src/age/devcontainer-feature.json b/src/age/devcontainer-feature.json index 20df4686f..dbada4411 100644 --- a/src/age/devcontainer-feature.json +++ b/src/age/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "age", - "version": "1.0.15", + "version": "1.0.16", "name": "age (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/age", "description": "age is a simple, modern and secure encryption tool (and Go library) with small explicit keys, no config options, and UNIX-style composability.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/akamai-cli/devcontainer-feature.json b/src/akamai-cli/devcontainer-feature.json index 3ade1d378..fe7a70b04 100644 --- a/src/akamai-cli/devcontainer-feature.json +++ b/src/akamai-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "akamai-cli", - "version": "1.0.5", + "version": "1.0.6", "name": "Akamai CLI (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/akamai-cli", "description": "Use Akamai CLI to configure Akamai platform and products directly from the command line. You can install ready-to-use product packages or build your own custom solutions to manage from CLI.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/alertmanager/devcontainer-feature.json b/src/alertmanager/devcontainer-feature.json index 6449693b6..34095a927 100644 --- a/src/alertmanager/devcontainer-feature.json +++ b/src/alertmanager/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "alertmanager", - "version": "1.0.2", + "version": "1.0.3", "name": "Prometheus Alertmanager (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/alertmanager", "description": "The Alertmanager handles alerts sent by client applications such as the Prometheus server.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/alp-asdf/devcontainer-feature.json b/src/alp-asdf/devcontainer-feature.json index 65f88d40e..71e69618d 100644 --- a/src/alp-asdf/devcontainer-feature.json +++ b/src/alp-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "alp-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "alp (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/alp-asdf", "description": "Installs alp", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/amplify-cli/devcontainer-feature.json b/src/amplify-cli/devcontainer-feature.json index 640741ff0..c3731e556 100644 --- a/src/amplify-cli/devcontainer-feature.json +++ b/src/amplify-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "amplify-cli", - "version": "2.0.15", + "version": "2.0.16", "name": "AWS Amplify CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/amplify-cli", "description": "The Amplify Command Line Interface (CLI) is a unified toolchain to create AWS cloud services for your app. Let's go ahead and install the Amplify CLI.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/angular-cli/devcontainer-feature.json b/src/angular-cli/devcontainer-feature.json index 5c2456cfa..ccdf36629 100644 --- a/src/angular-cli/devcontainer-feature.json +++ b/src/angular-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "angular-cli", - "version": "2.0.15", + "version": "2.0.16", "name": "Angular CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/angular-cli", "description": "Angular CLI is a command-line interface tool that you use to initialize, develop, scaffold, and maintain Angular applications directly from a command shell.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/ansible/README.md b/src/ansible/README.md index f899a6023..aa75a4285 100644 --- a/src/ansible/README.md +++ b/src/ansible/README.md @@ -16,6 +16,7 @@ Ansible is a suite of software tools that enables infrastructure as code. | Options Id | Description | Type | Default Value | |-----|-----|-----|-----| | version | Select the version to install. | string | latest | +| injections | Space delimitered list of python packages to inject into the main package env | string | - | diff --git a/src/ansible/devcontainer-feature.json b/src/ansible/devcontainer-feature.json index 0fbf95b14..1456311cf 100644 --- a/src/ansible/devcontainer-feature.json +++ b/src/ansible/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ansible", - "version": "2.0.17", + "version": "2.1.2", "name": "Ansible (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ansible", "description": "Ansible is a suite of software tools that enables infrastructure as code.", @@ -12,6 +12,15 @@ "latest" ], "type": "string" + }, + "injections": { + "default": "", + "description": "Space delimitered list of python packages to inject into the ansible package env", + "proposals": [ + "hcloud", + "hcloud requests" + ], + "type": "string" } }, "installsAfter": [ diff --git a/src/ansible/install.sh b/src/ansible/install.sh index 17cae471e..e14f62074 100755 --- a/src/ansible/install.sh +++ b/src/ansible/install.sh @@ -1,3 +1,5 @@ +#!/usr/bin/env bash + set -e . ./library_scripts.sh @@ -13,6 +15,6 @@ $nanolayer_location \ install \ devcontainer-feature \ "ghcr.io/devcontainers-extra/features/pipx-package:1.1.9" \ - --option package='ansible-core' --option injections='ansible' --option version="$VERSION" + --option package='ansible-core' --option injections="ansible $INJECTIONS" --option version="$VERSION" --option includeDeps="true" echo 'Done!' diff --git a/src/ant-sdkman/devcontainer-feature.json b/src/ant-sdkman/devcontainer-feature.json index 763a0c04a..8db2bb8c7 100644 --- a/src/ant-sdkman/devcontainer-feature.json +++ b/src/ant-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ant-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "Ant (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ant-sdkman", "description": "Apache Ant is a Java library and command-line tool whose mission is to drive\nprocesses described in build files as targets and extension points dependent\nupon each other. The main known usage of Ant is the build of Java applications.\nAnt supplies a number of built-in tasks allowing to compile, assemble, test and\nrun Java applications. Ant can also be used effectively to build non Java\napplications, for instance C or C++ applications. More generally, Ant can be\nused to pilot any type of process which can be described in terms of targets and\ntasks.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/apko/devcontainer-feature.json b/src/apko/devcontainer-feature.json index ef7b6f89d..45df744a0 100644 --- a/src/apko/devcontainer-feature.json +++ b/src/apko/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "apko", - "version": "1.0.9", + "version": "1.0.10", "name": "apko (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/apko", "description": "apko is an apk-based OCI image builder", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/apt-get-packages/devcontainer-feature.json b/src/apt-get-packages/devcontainer-feature.json index 07a47b305..7867c9403 100644 --- a/src/apt-get-packages/devcontainer-feature.json +++ b/src/apt-get-packages/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "apt-get-packages", - "version": "1.0.7", + "version": "1.0.8", "name": "apt-get packages (for Debian/Ubuntu)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/apt-get-packages", "description": "apt-get is a command line tool for interacting with the Advanced Package Tool (APT) library (a package management system for Linux distributions).", @@ -40,4 +40,4 @@ } }, "installsAfter": [] -} \ No newline at end of file +} diff --git a/src/apt-packages/devcontainer-feature.json b/src/apt-packages/devcontainer-feature.json index c47af11d8..541ca8d71 100644 --- a/src/apt-packages/devcontainer-feature.json +++ b/src/apt-packages/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "apt-packages", - "version": "1.0.5", + "version": "1.0.6", "name": "apt packages (for Debian/Ubuntu)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/apt-packages", "description": "Advanced package tool, or APT, is a free-software user interface that works with core libraries to handle the installation and removal of software on Debian and Debian-based Linux distributions.", @@ -40,4 +40,4 @@ } }, "installsAfter": [] -} \ No newline at end of file +} diff --git a/src/archon/devcontainer-feature.json b/src/archon/devcontainer-feature.json new file mode 100644 index 000000000..7fdedbb3f --- /dev/null +++ b/src/archon/devcontainer-feature.json @@ -0,0 +1,18 @@ +{ + "id": "archon", + "version": "1.0.0", + "name": "archon (via Github Releases)", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/archon", + "description": "The first open-source harness builder for AI coding. Make AI coding deterministic and repeatable.", + "options": { + "version": { + "default": "latest", + "description": "Select the version to install.", + "proposals": [ + "latest" + ], + "type": "string" + } + }, + "installsAfter": [] +} diff --git a/src/archon/install.sh b/src/archon/install.sh new file mode 100755 index 000000000..94ce02311 --- /dev/null +++ b/src/archon/install.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +set -e + +source ./library_scripts.sh + +# nanolayer is a cli utility which keeps container layers as small as possible +# source code: https://github.com/devcontainers-extra/nanolayer +# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, +# and if missing - will download a temporary copy that automatically get deleted at the end +# of the script +ensure_nanolayer nanolayer_location "v0.5.6" + +# Example nanolayer installation via devcontainer-feature +$nanolayer_location \ + install \ + devcontainer-feature \ + "ghcr.io/devcontainers-extra/features/gh-release:1" \ + --option repo='coleam00/Archon' --option binaryNames='archon' --option version="$VERSION" + +echo 'Done!' diff --git a/templates/src/library_scripts.sh b/src/archon/library_scripts.sh similarity index 100% rename from templates/src/library_scripts.sh rename to src/archon/library_scripts.sh diff --git a/src/argo-cd/devcontainer-feature.json b/src/argo-cd/devcontainer-feature.json index e4f4bfd5b..b04d1ff56 100644 --- a/src/argo-cd/devcontainer-feature.json +++ b/src/argo-cd/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "ArgoCD CLI (via Github Releases)", "id": "argo-cd", - "version": "1.0.2", + "version": "1.1.0", "description": "Declarative GitOps CD for Kubernetes", "documentationURL": "https://github.com/devcontainers-extra/features/tree/main/src/argo-cd", "options": { @@ -15,4 +15,4 @@ "description": "Select the Argo CD CLI version you would like to install" } } -} \ No newline at end of file +} diff --git a/src/argo-cd/install.sh b/src/argo-cd/install.sh index 59af15f26..738b1b4d6 100755 --- a/src/argo-cd/install.sh +++ b/src/argo-cd/install.sh @@ -1,87 +1,22 @@ #!/usr/bin/env bash -ARGOCD_VERSION="${VERSION:-"latest"}" - set -e -# Clean up -rm -rf /var/lib/apt/lists/* - -architecture="$(uname -m)" -case ${architecture} in -x86_64) architecture="amd64" ;; -aarch64 | armv8*) architecture="arm64" ;; -aarch32 | armv7* | armvhf*) architecture="arm" ;; -i?86) architecture="386" ;; -*) - echo "(!) Architecture ${architecture} unsupported" - exit 1 - ;; -esac - -if [ "$(id -u)" -ne 0 ]; then - echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' - exit 1 -fi - -# Checks if packages are installed and installs them if not -check_packages() { - if ! dpkg -s "$@" >/dev/null 2>&1; then - if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then - echo "Running apt-get update..." - apt-get update -y - fi - apt-get -y install --no-install-recommends "$@" - fi -} - -# Figure out correct version of a three part version number is not passed -find_version_from_git_tags() { - local variable_name=$1 - local requested_version=${!variable_name} - if [ "${requested_version}" = "none" ]; then return; fi - local repository=$2 - local prefix=${3:-"tags/v"} - local separator=${4:-"."} - local last_part_optional=${5:-"false"} - if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then - local escaped_separator=${separator//./\\.} - local last_part - if [ "${last_part_optional}" = "true" ]; then - last_part="(${escaped_separator}[0-9]+)?" - else - last_part="${escaped_separator}[0-9]+" - fi - local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$" - local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)" - if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then - declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" - else - set +e - declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")" - set -e - fi - fi - if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" >/dev/null 2>&1; then - echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 - exit 1 - fi - echo "${variable_name}=${!variable_name}" -} - -# make sure we have curl -check_packages ca-certificates curl - -# make sure version is available -find_version_from_git_tags ARGOCD_VERSION 'https://github.com/argoproj/argo-cd' +source ./library_scripts.sh -# download and install binary -ARGOCD_FILENAME=argocd-linux-${architecture} -curl -sSL https://github.com/argoproj/argo-cd/releases/download/v${ARGOCD_VERSION}/${ARGOCD_FILENAME} -o argocd-linux -install -m 555 argocd-linux /usr/local/bin/argocd -rm argocd-linux +# nanolayer is a cli utility which keeps container layers as small as possible +# source code: https://github.com/devcontainers-extra/nanolayer +# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, +# and if missing - will download a temporary copy that automatically get deleted at the end +# of the script +ensure_nanolayer nanolayer_location "v0.5.6" -# Clean up -rm -rf /var/lib/apt/lists/* +# Example nanolayer installation via devcontainer-feature +$nanolayer_location \ + install \ + devcontainer-feature \ + "ghcr.io/devcontainers-extra/features/gh-release:1" \ + --option repo='argoproj/argo-cd' --option binaryNames='argocd' \ + --option version="$VERSION" --option releaseTagRegex='^(?!.*(alpha|beta|rc)).*$' -echo "Done!" +echo 'Done!' diff --git a/src/argo-cd/library_scripts.sh b/src/argo-cd/library_scripts.sh new file mode 100644 index 000000000..f6d0760d7 --- /dev/null +++ b/src/argo-cd/library_scripts.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash + +clean_download() { + # The purpose of this function is to download a file with minimal impact on container layer size + # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a + # temporary manner, and making sure to + # 1. uninstall the downloader at the return of the function + # 2. revert back any changes to the package installer database/cache (for example apt-get lists) + # The above steps will minimize the leftovers being created while installing the downloader + # Supported distros: + # debian/ubuntu/alpine + + url=$1 + output_location=$2 + tempdir=$(mktemp -d) + downloader_installed="" + + function _apt_get_install() { + tempdir=$1 + + # copy current state of apt list - in order to revert back later (minimize contianer layer size) + cp -p -R /var/lib/apt/lists $tempdir + apt-get update -y + apt-get -y install --no-install-recommends wget ca-certificates + } + + function _apt_get_cleanup() { + tempdir=$1 + + echo "removing wget" + apt-get -y purge wget --auto-remove + + echo "revert back apt lists" + rm -rf /var/lib/apt/lists/* + rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists + } + + function _apk_install() { + tempdir=$1 + # copy current state of apk cache - in order to revert back later (minimize contianer layer size) + cp -p -R /var/cache/apk $tempdir + + apk add --no-cache wget + } + + function _apk_cleanup() { + tempdir=$1 + + echo "removing wget" + apk del wget + } + # try to use either wget or curl if one of them already installer + if type curl >/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + # in case none of them is installed, install wget temporarly + if [ -z $downloader ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_install $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_install $tempdir + else + echo "distro not supported" + exit 1 + fi + downloader="wget" + downloader_installed="true" + fi + + if [ $downloader = "wget" ]; then + wget -q $url -O $output_location + else + curl -sfL $url -o $output_location + fi + + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi + +} + +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + # normalize version + if ! [[ $required_version == v* ]]; then + required_version=v$required_version + fi + + local nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ]; then + nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" + fi + + # make sure its of the required version + if ! [[ -z "${nanolayer_location}" ]]; then + local current_version + current_version=$($nanolayer_location --version) + if ! [[ $current_version == v* ]]; then + current_version=v$current_version + fi + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [[ -z "${nanolayer_location}" ]]; then + + if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up() { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + if [ -x "/sbin/apk" ]; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + nanolayer_location=$tmp_dir/nanolayer + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + declare -g ${variable_name}=$nanolayer_location + +} diff --git a/src/asciidoctorj-sdkman/devcontainer-feature.json b/src/asciidoctorj-sdkman/devcontainer-feature.json index 2b041a989..45152f934 100644 --- a/src/asciidoctorj-sdkman/devcontainer-feature.json +++ b/src/asciidoctorj-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "asciidoctorj-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "AsciidoctorJ (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/asciidoctorj-sdkman", "description": "AsciidoctorJ is the official library for running Asciidoctor on the JVM. Using\nAsciidoctorJ, you can convert AsciiDoc content or analyze the structure of a\nparsed AsciiDoc document from Java and other JVM languages.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/asdf-package/devcontainer-feature.json b/src/asdf-package/devcontainer-feature.json index 3d2fe6537..f54b41ab7 100644 --- a/src/asdf-package/devcontainer-feature.json +++ b/src/asdf-package/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "asdf package", "id": "asdf-package", - "version": "1.0.9", + "version": "1.0.10", "description": "Installs an asdf package.", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/asdf-package", "installsAfter": [ @@ -43,4 +43,4 @@ "description": "this will be used as argument for 'asdf latest ' command. If none given the default asdf of '[0-9]' will be used." } } -} \ No newline at end of file +} diff --git a/src/assemblyscript/devcontainer-feature.json b/src/assemblyscript/devcontainer-feature.json index faf97ed1b..6979410b0 100644 --- a/src/assemblyscript/devcontainer-feature.json +++ b/src/assemblyscript/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "assemblyscript", - "version": "2.0.15", + "version": "2.0.16", "name": "AssemblyScript (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/assemblyscript", "description": "AssemblyScript compiles a variant of TypeScript to WebAssembly using Binaryen.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/atlantis/devcontainer-feature.json b/src/atlantis/devcontainer-feature.json index 588b5c368..41bdc185c 100644 --- a/src/atlantis/devcontainer-feature.json +++ b/src/atlantis/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "atlantis", - "version": "1.0.5", + "version": "1.0.6", "name": "Atlantis (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/atlantis", "description": "Atlantis is a self-hosted golang application that listens for Terraform pull request events via webhooks.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/atmos/devcontainer-feature.json b/src/atmos/devcontainer-feature.json index 596a752d9..ee4f8d2e0 100644 --- a/src/atmos/devcontainer-feature.json +++ b/src/atmos/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "atmos", - "version": "1.0.5", + "version": "1.0.6", "name": "Atmos (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/atmos", "description": "Atmos is a workflow automation tool. Atmos is lets you take a complex workflow and turn it into a parameterized CLI. You can then run the CLI anywhere, such as locally or in CI/CD.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/auditjs/devcontainer-feature.json b/src/auditjs/devcontainer-feature.json index 2b046d826..4d22f58f0 100644 --- a/src/auditjs/devcontainer-feature.json +++ b/src/auditjs/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "auditjs", - "version": "1.0.5", + "version": "1.0.6", "name": "AuditJS (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/auditjs", "description": "AuditJS audits an NPM package.json file to identify known vulnerabilities.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/autoenv/devcontainer-feature.json b/src/autoenv/devcontainer-feature.json index 12ea1dcc4..efc3b1f29 100644 --- a/src/autoenv/devcontainer-feature.json +++ b/src/autoenv/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "autoenv", - "version": "1.0.5", + "version": "1.0.6", "name": "Autoenv (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/autoenv", "description": "Autoenv is a tool which automatically reads and setups configuration from a . env file when you cd to a directory.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/aws-cdk/devcontainer-feature.json b/src/aws-cdk/devcontainer-feature.json index 8c5d78fa4..731b81cae 100644 --- a/src/aws-cdk/devcontainer-feature.json +++ b/src/aws-cdk/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "aws-cdk", - "version": "2.0.15", + "version": "2.0.16", "name": "AWS Cloud Development Kit (AWS CDK) (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/aws-cdk", "description": "AWS CDK is an open-source software development framework to define cloud infrastructure in code and provision it through AWS CloudFormation.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/aws-eb-cli/devcontainer-feature.json b/src/aws-eb-cli/devcontainer-feature.json index a31a6bb80..7dfb1eb8d 100644 --- a/src/aws-eb-cli/devcontainer-feature.json +++ b/src/aws-eb-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "aws-eb-cli", - "version": "1.0.16", + "version": "1.0.17", "name": "aws-eb-cli (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/aws-eb-cli", "description": "AWS Elastic Beanstalk CLI.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/aztfexport/devcontainer-feature.json b/src/aztfexport/devcontainer-feature.json index 20840a2e6..8091ff92d 100644 --- a/src/aztfexport/devcontainer-feature.json +++ b/src/aztfexport/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "aztfexport", - "version": "1.0.5", + "version": "1.0.6", "name": "aztfexport (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/aztfexport", "description": "aztfexport is a tool to bring existing Azure resources under Terraform's management.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/azure-apiops/devcontainer-feature.json b/src/azure-apiops/devcontainer-feature.json index 8c7092753..7b10efd12 100644 --- a/src/azure-apiops/devcontainer-feature.json +++ b/src/azure-apiops/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "azure-apiops", - "version": "1.0.1", + "version": "1.0.2", "name": "Azure Apiops (Extractor and Publisher) (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/azure-apiops", "description": "APIOps applies the concepts of GitOps and DevOps to API deployment. By using practices from these two methodologies, APIOps can enable everyone involved in the lifecycle of API design, development, and deployment with self-service and automated tools to ensure the quality of the specifications and APIs that theyre building.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/ballerina-sdkman/devcontainer-feature.json b/src/ballerina-sdkman/devcontainer-feature.json index 1ea009dd9..a32e6d9c6 100644 --- a/src/ballerina-sdkman/devcontainer-feature.json +++ b/src/ballerina-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ballerina-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "Ballerina (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ballerina-sdkman", "description": "Open source programming language and platform for cloud-era application\nprogrammers to easily write software that just works.", @@ -38,4 +38,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/bandit/devcontainer-feature.json b/src/bandit/devcontainer-feature.json index c75e687ae..f0420ad05 100644 --- a/src/bandit/devcontainer-feature.json +++ b/src/bandit/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "bandit", - "version": "2.0.17", + "version": "2.0.18", "name": "Bandit (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/bandit", "description": "Bandit is a tool designed to find common security issues in Python code.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/bartib/devcontainer-feature.json b/src/bartib/devcontainer-feature.json index 85ba35c60..7e9ba98fe 100644 --- a/src/bartib/devcontainer-feature.json +++ b/src/bartib/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "bartib", - "version": "1.0.9", + "version": "1.0.10", "name": "Bartib (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/bartib", "description": "Bartib is a simple timetracker for the command line. It saves a log of all tracked activities as a plaintext file and allows you to create flexible reports.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/bash-command/devcontainer-feature.json b/src/bash-command/devcontainer-feature.json index 36f7cc582..0cee929aa 100644 --- a/src/bash-command/devcontainer-feature.json +++ b/src/bash-command/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "Bash Command", "id": "bash-command", - "version": "1.0.0", + "version": "1.0.1", "description": "Executes a bash command", "documentationURL": "https://github.com/devcontainers-extra/features/tree/main/src/bash-command", "options": { @@ -14,4 +14,4 @@ "description": "command to be executed (will be forwarded as is to a 'bash -c ' line)" } } -} \ No newline at end of file +} diff --git a/src/bazel-compile-commands/README.md b/src/bazel-compile-commands/README.md new file mode 100644 index 000000000..dcb9da00c --- /dev/null +++ b/src/bazel-compile-commands/README.md @@ -0,0 +1,42 @@ +# bazel-compile-commands (via Github Releases) (bazel-compile-commands) + +Generates `compile_commands.json` from Bazel builds, enabling accurate code intelligence (go-to-definition, cross-references, diagnostics) in editors that support the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/). + +## Example Usage + +```json +"features": { + "ghcr.io/devcontainers-extra/features/bazel-compile-commands:1": {} +} +``` + +## Options + +| Options Id | Description | Type | Default Value | +| ---------- | -------------------------------------------------------------------------------------------------------------------------------- | ------ | ------------- | +| version | Version to install. Accepts `latest`, a numeric version like `0.22.4`, or the full release tag `bazel-compile-commands-v0.22.4`. | string | latest | + +## Install behaviour + +The feature selects the best available package for the current environment: + +| Environment | Package used | +| -------------------- | ------------------------------- | +| Ubuntu Noble (24.04) | Native `.deb` via `apt-get` | +| Other Linux | Generic `.zip` (amd64 or arm64) | +| macOS | Universal `.zip` | + +## Pairing with Bazel + +This feature pairs naturally with [`ghcr.io/devcontainers-community/features/bazel:1`](https://github.com/devcontainers-community/features-bazel), which installs Bazelisk and Buildifier. When both are present in `devcontainer.json`, the Bazel feature is installed first. + +```json +"features": { + "ghcr.io/devcontainers-community/features/bazel:1": {}, + "ghcr.io/devcontainers-extra/features/bazel-compile-commands:1": {} +} +``` + +--- + +_Note: This file was auto-generated from the [devcontainer-feature.json](devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/bazel-compile-commands/devcontainer-feature.json b/src/bazel-compile-commands/devcontainer-feature.json new file mode 100644 index 000000000..7d1963345 --- /dev/null +++ b/src/bazel-compile-commands/devcontainer-feature.json @@ -0,0 +1,21 @@ +{ + "id": "bazel-compile-commands", + "version": "1.0.0", + "name": "bazel-compile-commands (via Github Releases)", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/bazel-compile-commands", + "description": "Generates compile_commands.json from Bazel builds.", + "options": { + "version": { + "default": "latest", + "description": "Version to install. Accepts 'latest' or a numeric version like '0.22.4'.", + "proposals": [ + "latest", + "0.22.4" + ], + "type": "string" + } + }, + "installsAfter": [ + "ghcr.io/devcontainers-community/features/bazel" + ] +} diff --git a/src/bazel-compile-commands/install.sh b/src/bazel-compile-commands/install.sh new file mode 100755 index 000000000..de53af507 --- /dev/null +++ b/src/bazel-compile-commands/install.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +set -e + +. ./library_scripts.sh + +# nanolayer is a cli utility which keeps container layers as small as possible +# source code: https://github.com/devcontainers-extra/nanolayer +# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, +# and if missing - will download a temporary copy that automatically get deleted at the end +# of the script +ensure_nanolayer nanolayer_location "v0.5.6" + +# Upstream tags use a non-standard "bazel-compile-commands-v" format. Normalise +# any plain version (e.g. "0.22.4" or "v0.22.4") so nanolayer can match it exactly. +if [[ "${VERSION}" != "latest" && "${VERSION}" != bazel-compile-commands-* ]]; then + VERSION="bazel-compile-commands-v${VERSION#v}" +fi + +$nanolayer_location \ + install \ + devcontainer-feature \ + "ghcr.io/devcontainers-extra/features/gh-release:1" \ + --option repo='kiron1/bazel-compile-commands' \ + --option binaryNames='bazel-compile-commands' \ + --option version="$VERSION" \ + --option assetRegex='linux_' \ + --option releaseTagRegex='bazel-compile-commands-v' + +echo 'Done!' diff --git a/src/bazel-compile-commands/library_scripts.sh b/src/bazel-compile-commands/library_scripts.sh new file mode 100644 index 000000000..f6d0760d7 --- /dev/null +++ b/src/bazel-compile-commands/library_scripts.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash + +clean_download() { + # The purpose of this function is to download a file with minimal impact on container layer size + # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a + # temporary manner, and making sure to + # 1. uninstall the downloader at the return of the function + # 2. revert back any changes to the package installer database/cache (for example apt-get lists) + # The above steps will minimize the leftovers being created while installing the downloader + # Supported distros: + # debian/ubuntu/alpine + + url=$1 + output_location=$2 + tempdir=$(mktemp -d) + downloader_installed="" + + function _apt_get_install() { + tempdir=$1 + + # copy current state of apt list - in order to revert back later (minimize contianer layer size) + cp -p -R /var/lib/apt/lists $tempdir + apt-get update -y + apt-get -y install --no-install-recommends wget ca-certificates + } + + function _apt_get_cleanup() { + tempdir=$1 + + echo "removing wget" + apt-get -y purge wget --auto-remove + + echo "revert back apt lists" + rm -rf /var/lib/apt/lists/* + rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists + } + + function _apk_install() { + tempdir=$1 + # copy current state of apk cache - in order to revert back later (minimize contianer layer size) + cp -p -R /var/cache/apk $tempdir + + apk add --no-cache wget + } + + function _apk_cleanup() { + tempdir=$1 + + echo "removing wget" + apk del wget + } + # try to use either wget or curl if one of them already installer + if type curl >/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + # in case none of them is installed, install wget temporarly + if [ -z $downloader ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_install $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_install $tempdir + else + echo "distro not supported" + exit 1 + fi + downloader="wget" + downloader_installed="true" + fi + + if [ $downloader = "wget" ]; then + wget -q $url -O $output_location + else + curl -sfL $url -o $output_location + fi + + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi + +} + +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + # normalize version + if ! [[ $required_version == v* ]]; then + required_version=v$required_version + fi + + local nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ]; then + nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" + fi + + # make sure its of the required version + if ! [[ -z "${nanolayer_location}" ]]; then + local current_version + current_version=$($nanolayer_location --version) + if ! [[ $current_version == v* ]]; then + current_version=v$current_version + fi + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [[ -z "${nanolayer_location}" ]]; then + + if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up() { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + if [ -x "/sbin/apk" ]; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + nanolayer_location=$tmp_dir/nanolayer + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + declare -g ${variable_name}=$nanolayer_location + +} diff --git a/src/beehive/devcontainer-feature.json b/src/beehive/devcontainer-feature.json index da4e80a1a..456094b00 100644 --- a/src/beehive/devcontainer-feature.json +++ b/src/beehive/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "beehive", - "version": "1.0.14", + "version": "1.0.15", "name": "Beehive (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/beehive", "description": "Beehive is an event and agent system, which allows you to create your own agents that perform automated tasks triggered by events and filters.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/bikeshed/devcontainer-feature.json b/src/bikeshed/devcontainer-feature.json index 7a856c1a3..3e7d7803a 100644 --- a/src/bikeshed/devcontainer-feature.json +++ b/src/bikeshed/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "bikeshed", - "version": "2.0.17", + "version": "2.0.18", "name": "Bikeshed (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/bikeshed", "description": "A preprocessor for anyone writing specifications that converts source files into actual specs.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/bin/devcontainer-feature.json b/src/bin/devcontainer-feature.json index f526a2c40..560c108fb 100644 --- a/src/bin/devcontainer-feature.json +++ b/src/bin/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "bin", - "version": "1.0.14", + "version": "1.0.15", "name": "bin (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/bin", "description": "bin is an effortless binary manager. It manages binary files downloaded from different sources.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/black/devcontainer-feature.json b/src/black/devcontainer-feature.json index 477a36d08..cf985a678 100644 --- a/src/black/devcontainer-feature.json +++ b/src/black/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "black", - "version": "2.0.17", + "version": "2.0.18", "name": "Black (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/black", "description": "Black is an uncompromising Python code formatter.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/blackbox-exporter/devcontainer-feature.json b/src/blackbox-exporter/devcontainer-feature.json index 3fbc69f8e..b4257cf6d 100644 --- a/src/blackbox-exporter/devcontainer-feature.json +++ b/src/blackbox-exporter/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "blackbox-exporter", - "version": "1.0.2", + "version": "1.0.3", "name": "Prometheus Blackbox Exporter (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/blackbox-exporter", "description": "The blackbox exporter allows blackbox probing of endpoints over HTTP, HTTPS, DNS, TCP, ICMP and gRPC.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/boilerplate/devcontainer-feature.json b/src/boilerplate/devcontainer-feature.json new file mode 100644 index 000000000..78b2f99a2 --- /dev/null +++ b/src/boilerplate/devcontainer-feature.json @@ -0,0 +1,18 @@ +{ + "id": "boilerplate", + "version": "1.0.0", + "name": "boilerplate (via Github Releases)", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/boilerplate", + "description": "A tool for generating files and folders (boilerplate) from a set of templates", + "options": { + "version": { + "default": "latest", + "description": "Select the version to install.", + "proposals": [ + "latest" + ], + "type": "string" + } + }, + "installsAfter": [] +} diff --git a/src/boilerplate/install.sh b/src/boilerplate/install.sh new file mode 100755 index 000000000..bedab30bb --- /dev/null +++ b/src/boilerplate/install.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +set -e + +source ./library_scripts.sh + +# nanolayer is a cli utility which keeps container layers as small as possible +# source code: https://github.com/devcontainers-extra/nanolayer +# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, +# and if missing - will download a temporary copy that automatically get deleted at the end +# of the script +ensure_nanolayer nanolayer_location "v0.5.6" + +# Example nanolayer installation via devcontainer-feature +$nanolayer_location \ + install \ + devcontainer-feature \ + "ghcr.io/devcontainers-extra/features/gh-release:1" \ + --option repo='gruntwork-io/boilerplate' --option binaryNames='boilerplate' --option version="$VERSION" + +echo 'Done!' diff --git a/src/boilerplate/library_scripts.sh b/src/boilerplate/library_scripts.sh new file mode 100644 index 000000000..f6d0760d7 --- /dev/null +++ b/src/boilerplate/library_scripts.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash + +clean_download() { + # The purpose of this function is to download a file with minimal impact on container layer size + # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a + # temporary manner, and making sure to + # 1. uninstall the downloader at the return of the function + # 2. revert back any changes to the package installer database/cache (for example apt-get lists) + # The above steps will minimize the leftovers being created while installing the downloader + # Supported distros: + # debian/ubuntu/alpine + + url=$1 + output_location=$2 + tempdir=$(mktemp -d) + downloader_installed="" + + function _apt_get_install() { + tempdir=$1 + + # copy current state of apt list - in order to revert back later (minimize contianer layer size) + cp -p -R /var/lib/apt/lists $tempdir + apt-get update -y + apt-get -y install --no-install-recommends wget ca-certificates + } + + function _apt_get_cleanup() { + tempdir=$1 + + echo "removing wget" + apt-get -y purge wget --auto-remove + + echo "revert back apt lists" + rm -rf /var/lib/apt/lists/* + rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists + } + + function _apk_install() { + tempdir=$1 + # copy current state of apk cache - in order to revert back later (minimize contianer layer size) + cp -p -R /var/cache/apk $tempdir + + apk add --no-cache wget + } + + function _apk_cleanup() { + tempdir=$1 + + echo "removing wget" + apk del wget + } + # try to use either wget or curl if one of them already installer + if type curl >/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + # in case none of them is installed, install wget temporarly + if [ -z $downloader ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_install $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_install $tempdir + else + echo "distro not supported" + exit 1 + fi + downloader="wget" + downloader_installed="true" + fi + + if [ $downloader = "wget" ]; then + wget -q $url -O $output_location + else + curl -sfL $url -o $output_location + fi + + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi + +} + +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + # normalize version + if ! [[ $required_version == v* ]]; then + required_version=v$required_version + fi + + local nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ]; then + nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" + fi + + # make sure its of the required version + if ! [[ -z "${nanolayer_location}" ]]; then + local current_version + current_version=$($nanolayer_location --version) + if ! [[ $current_version == v* ]]; then + current_version=v$current_version + fi + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [[ -z "${nanolayer_location}" ]]; then + + if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up() { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + if [ -x "/sbin/apk" ]; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + nanolayer_location=$tmp_dir/nanolayer + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + declare -g ${variable_name}=$nanolayer_location + +} diff --git a/src/bomber/devcontainer-feature.json b/src/bomber/devcontainer-feature.json index 3b2ce5d3d..46f9cb76b 100644 --- a/src/bomber/devcontainer-feature.json +++ b/src/bomber/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "bomber", - "version": "1.0.9", + "version": "1.0.10", "name": "bomber (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/bomber", "description": "bomber is an application that scans SBOMs for security vulnerabilities.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/archive/src/boundary-asdf/README.md b/src/boundary-asdf/README.md similarity index 100% rename from archive/src/boundary-asdf/README.md rename to src/boundary-asdf/README.md diff --git a/archive/src/boundary-asdf/devcontainer-feature.json b/src/boundary-asdf/devcontainer-feature.json similarity index 95% rename from archive/src/boundary-asdf/devcontainer-feature.json rename to src/boundary-asdf/devcontainer-feature.json index eef2fd62a..128052bc6 100644 --- a/archive/src/boundary-asdf/devcontainer-feature.json +++ b/src/boundary-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "boundary-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "boundary (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/boundary-asdf", "description": "Installs boundary", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/archive/src/boundary-asdf/install.sh b/src/boundary-asdf/install.sh similarity index 100% rename from archive/src/boundary-asdf/install.sh rename to src/boundary-asdf/install.sh diff --git a/src/elasticsearch-asdf/library_scripts.sh b/src/boundary-asdf/library_scripts.sh similarity index 100% rename from src/elasticsearch-asdf/library_scripts.sh rename to src/boundary-asdf/library_scripts.sh diff --git a/src/bower/devcontainer-feature.json b/src/bower/devcontainer-feature.json index 17a6a2aae..72d1b2387 100644 --- a/src/bower/devcontainer-feature.json +++ b/src/bower/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "bower", - "version": "1.0.2", + "version": "1.0.3", "name": "Bower (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/bower", "description": "Bower offers a generic, unopinionated solution to the problem of front-end package management, while exposing the package dependency model via an API that can be consumed by a more opinionated build stack.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/bpipe-sdkman/devcontainer-feature.json b/src/bpipe-sdkman/devcontainer-feature.json index a2d77fca7..475cb3216 100644 --- a/src/bpipe-sdkman/devcontainer-feature.json +++ b/src/bpipe-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "bpipe-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "Bpipe (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/bpipe-sdkman", "description": "Bpipe is a framework for running computational pipelines and workflows", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/brownie/devcontainer-feature.json b/src/brownie/devcontainer-feature.json old mode 100755 new mode 100644 index 68cfd4842..7b379c50e --- a/src/brownie/devcontainer-feature.json +++ b/src/brownie/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "brownie", - "version": "2.0.17", + "version": "2.0.18", "name": "Brownie (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/brownie", "description": "Brownie is a Python-based development and testing framework for smart contracts targeting the Ethereum Virtual Machine.", @@ -25,4 +25,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/pipx-package" ] -} \ No newline at end of file +} diff --git a/src/browserify/devcontainer-feature.json b/src/browserify/devcontainer-feature.json index 2d3d00fcd..9c6674860 100644 --- a/src/browserify/devcontainer-feature.json +++ b/src/browserify/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "browserify", - "version": "2.0.15", + "version": "2.0.16", "name": "Browserify (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/browserify", "description": "Browserify lets you require('modules') in the browser by bundling up all of your dependencies.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/archive/src/btm/README.md b/src/btm/README.md similarity index 100% rename from archive/src/btm/README.md rename to src/btm/README.md diff --git a/archive/src/btm/devcontainer-feature.json b/src/btm/devcontainer-feature.json similarity index 95% rename from archive/src/btm/devcontainer-feature.json rename to src/btm/devcontainer-feature.json index df4fe0d2b..e384107bd 100644 --- a/archive/src/btm/devcontainer-feature.json +++ b/src/btm/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "btm", - "version": "1.0.15", + "version": "1.0.17", "name": "bottom (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/btm", "description": "bottom is a customizable cross-platform graphical process/system monitor for the terminal.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/btm/install.sh b/src/btm/install.sh new file mode 100755 index 000000000..b6cc158ad --- /dev/null +++ b/src/btm/install.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash + +set -e + +source ./library_scripts.sh + +# nanolayer is a cli utility which keeps container layers as small as possible +# source code: https://github.com/devcontainers-extra/nanolayer +# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, +# and if missing - will download a temporary copy that automatically get deleted at the end +# of the script +ensure_nanolayer nanolayer_location "v0.5.6" + +# Detect C library type +if [ -f "/lib/ld-musl-x86_64.so.1" ] || [ -f "/lib/ld-musl-aarch64.so.1" ]; then + clib_type=musl +else + clib_type=gnu +fi + +# Detect architecture +architecture="$(uname -m)" +case $architecture in + arm64) + arch="aarch64" + ;; + armv7) + clib_type="${clib_type}eabihf" + ;; + *) + arch="$architecture" + ;; +esac +asset_regex="^bottom_${arch}-unknown-linux-${clib_type}\\.tar\\.gz$" + +# Exclude nightly prereleases, only match semantic version tags +release_tag_regex="^(?!.*nightly)[0-9]+\\.[0-9]+\\.[0-9]+$" + +$nanolayer_location \ + install \ + devcontainer-feature \ + "ghcr.io/devcontainers-extra/features/gh-release:1.0.26" \ + --option repo='ClementTsang/bottom' --option binaryNames='btm' --option version="$VERSION" --option assetRegex="$asset_regex" --option releaseTagRegex="$release_tag_regex" + + + +echo 'Done!' + diff --git a/src/btm/library_scripts.sh b/src/btm/library_scripts.sh new file mode 100644 index 000000000..f6d0760d7 --- /dev/null +++ b/src/btm/library_scripts.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash + +clean_download() { + # The purpose of this function is to download a file with minimal impact on container layer size + # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a + # temporary manner, and making sure to + # 1. uninstall the downloader at the return of the function + # 2. revert back any changes to the package installer database/cache (for example apt-get lists) + # The above steps will minimize the leftovers being created while installing the downloader + # Supported distros: + # debian/ubuntu/alpine + + url=$1 + output_location=$2 + tempdir=$(mktemp -d) + downloader_installed="" + + function _apt_get_install() { + tempdir=$1 + + # copy current state of apt list - in order to revert back later (minimize contianer layer size) + cp -p -R /var/lib/apt/lists $tempdir + apt-get update -y + apt-get -y install --no-install-recommends wget ca-certificates + } + + function _apt_get_cleanup() { + tempdir=$1 + + echo "removing wget" + apt-get -y purge wget --auto-remove + + echo "revert back apt lists" + rm -rf /var/lib/apt/lists/* + rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists + } + + function _apk_install() { + tempdir=$1 + # copy current state of apk cache - in order to revert back later (minimize contianer layer size) + cp -p -R /var/cache/apk $tempdir + + apk add --no-cache wget + } + + function _apk_cleanup() { + tempdir=$1 + + echo "removing wget" + apk del wget + } + # try to use either wget or curl if one of them already installer + if type curl >/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + # in case none of them is installed, install wget temporarly + if [ -z $downloader ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_install $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_install $tempdir + else + echo "distro not supported" + exit 1 + fi + downloader="wget" + downloader_installed="true" + fi + + if [ $downloader = "wget" ]; then + wget -q $url -O $output_location + else + curl -sfL $url -o $output_location + fi + + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi + +} + +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + # normalize version + if ! [[ $required_version == v* ]]; then + required_version=v$required_version + fi + + local nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ]; then + nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" + fi + + # make sure its of the required version + if ! [[ -z "${nanolayer_location}" ]]; then + local current_version + current_version=$($nanolayer_location --version) + if ! [[ $current_version == v* ]]; then + current_version=v$current_version + fi + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [[ -z "${nanolayer_location}" ]]; then + + if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up() { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + if [ -x "/sbin/apk" ]; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + nanolayer_location=$tmp_dir/nanolayer + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + declare -g ${variable_name}=$nanolayer_location + +} diff --git a/src/btop-homebrew/devcontainer-feature.json b/src/btop-homebrew/devcontainer-feature.json index 4f8e1fce7..b809fdd25 100644 --- a/src/btop-homebrew/devcontainer-feature.json +++ b/src/btop-homebrew/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "btop-homebrew", - "version": "1.0.20", + "version": "1.0.21", "name": "btop (via Homebrew)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/btop-homebrew", "description": "btop is a resource monitor that shows usage and stats for processor, memory, disks, network and processes.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/homebrew-package" ] -} \ No newline at end of file +} diff --git a/src/btrace-sdkman/devcontainer-feature.json b/src/btrace-sdkman/devcontainer-feature.json index 3aeab5b40..054915b8a 100644 --- a/src/btrace-sdkman/devcontainer-feature.json +++ b/src/btrace-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "btrace-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "BTrace (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/btrace-sdkman", "description": "BTrace is a safe, dynamic tracing tool for the Java platform. BTrace can be used\nto dynamically trace a running Java program (similar to DTrace for OpenSolaris\napplications and OS). BTrace dynamically instruments the classes of the target\napplication to inject bytecode tracing code.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/budibase-cli/devcontainer-feature.json b/src/budibase-cli/devcontainer-feature.json index fd570a7c2..a2f1a0f70 100644 --- a/src/budibase-cli/devcontainer-feature.json +++ b/src/budibase-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "budibase-cli", - "version": "1.0.2", + "version": "1.0.3", "name": "Budibase CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/budibase-cli", "description": "The Budibase CLI tool can be used to create a new Budibase installation, to manage an existing installation, make backups or update a Budibase installation to a new version.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/buku/devcontainer-feature.json b/src/buku/devcontainer-feature.json index c201cfdc0..714b4b77d 100644 --- a/src/buku/devcontainer-feature.json +++ b/src/buku/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "buku", - "version": "1.0.4", + "version": "1.0.5", "name": "buku (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/buku", "description": "buku is a powerful bookmark manager and a personal textual mini-web.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/bun-package/NOTES.md b/src/bun-package/NOTES.md new file mode 100644 index 000000000..c6f27b0c8 --- /dev/null +++ b/src/bun-package/NOTES.md @@ -0,0 +1,71 @@ +# Additional Notes + +- Requires Bun to be installed (e.g., via the `bun` feature). +- Exports `BUN_INSTALL=/usr/local` to ensure global binaries land in `/usr/local/bin`. +- Useful for installing tools distributed as Bun packages (e.g., `@vercel/turbo`). +- Accepts both bare names and `npm:`-prefixed names; Bun defaults to npm registry, so `npm:` is optional. + +## Behavior + +- Requires root to install globally to `/usr/local` (matches other package helper features). +- Skip-if-installed: + - For `version: "latest"` (or empty), skips when the package is already present in `bun pm -l`. + - For pinned installs (e.g., `"version": "1.2.3"`), skips only when the exact `@` is already installed. +- For non-npm specs (git / URL / GitHub shorthand), use `nameHint` if the name shown by `bun pm -l` differs from your install spec. + +## Usage Examples + +Default latest: + +```json +"features": { + "ghcr.io/devcontainers-extra/features/bun-package:1": { + "package": "@vercel/turbo" + } +} +``` + +Pinned version: + +```json +"features": { + "ghcr.io/devcontainers-extra/features/bun-package:1": { + "package": "@vercel/turbo", + "version": "2.5.6" + } +} +``` + +## Non-npm sources + +- Supports any spec Bun accepts in `bun add`, including git URLs (e.g., `git+https://...`), GitHub shorthand (e.g., `github:user/repo`), and tarball URLs. +- For non-npm sources, the name shown in `bun pm -l` may not match the install spec. Use the optional `nameHint` option to tell the feature which name to look for when deciding to skip. + +### Non-NPM Usage Examples + +```json +"features": { + "ghcr.io/devcontainers-extra/features/bun:1": {}, + "ghcr.io/devcontainers-extra/features/bun-package:1": { + "package": "git+https://github.com/user/tool.git", + "nameHint": "tool" + } +} +``` + +```json +"features": { + "ghcr.io/devcontainers-extra/features/bun:1": {}, + "ghcr.io/devcontainers-extra/features/bun-package:1": { + "package": "github:user/repo", + "nameHint": "repo" + } +} +``` + +Note: Private registries (e.g., GitHub Packages, Artifactory) may require registry / auth setup via `.npmrc` or Bun config in the container. + +## Support + +- Distros: `Debian` / `Ubuntu` and `Alpine` +- Architectures: `x86_64` and `arm64` diff --git a/src/bun-package/README.md b/src/bun-package/README.md new file mode 100644 index 000000000..a071845d5 --- /dev/null +++ b/src/bun-package/README.md @@ -0,0 +1,26 @@ +# Bun package (bun-package) + +Installs a Bun package globally using Bun. Ensures system-wide bin availability. + +## Example Usage + +```json +"features": { + "ghcr.io/devcontainers-extra/features/bun-package:1": { + "package": "@vercel/turbo", + "version": "latest" + } +} +``` + +## Options + +| Options Id | Description | Type | Default Value | +|-----|-----|-----|-----| +| package | Select the Bun package to install globally. | string | | +| version | Select the version of the Bun package to install. | string | latest | +| nameHint | Optional: name to use for skip checks (useful for git / URL / non-npm sources). | string | | + +--- + +_Note: This file was auto-generated from the [devcontainer-feature.json](devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/bun-package/devcontainer-feature.json b/src/bun-package/devcontainer-feature.json new file mode 100644 index 000000000..61fe44f00 --- /dev/null +++ b/src/bun-package/devcontainer-feature.json @@ -0,0 +1,30 @@ +{ + "id": "bun-package", + "version": "1.0.0", + "name": "Bun package", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/bun-package", + "description": "Installs a Bun package globally using Bun.", + "options": { + "package": { + "default": "", + "description": "Select the Bun package to install globally.", + "type": "string" + }, + "version": { + "default": "latest", + "description": "Select the version of the Bun package to install.", + "proposals": [ + "latest" + ], + "type": "string" + }, + "nameHint": { + "default": "", + "description": "Optional: name to use for skip install checks (useful for git / URL / non-npm sources).", + "type": "string" + } + }, + "installsAfter": [ + "ghcr.io/devcontainers-extra/features/bun" + ] +} diff --git a/src/bun-package/install.sh b/src/bun-package/install.sh new file mode 100644 index 000000000..fb44ad95a --- /dev/null +++ b/src/bun-package/install.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env bash + +set -e + +PACKAGE=${PACKAGE:-""} +VERSION=${VERSION:-"latest"} +NAMEHINT=${NAMEHINT:-""} + +if [ -z "$PACKAGE" ]; then + echo "'package' option is empty, skipping" + exit 0 +fi + +# Require root (global install to /usr/local) +if [ "$(id -u)" -ne 0 ]; then + echo -e 'Script must be run as\n root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' + exit 1 +fi + +# Ensure bun exists +if ! command -v bun >/dev/null 2>&1; then + echo "Bun is required. Ensure a Bun feature (bun) ran before this feature." + exit 1 +fi + +# Ensure global binaries land in /usr/local/bin +export BUN_INSTALL="/usr/local" + +# Normalize optional npm: prefix; Bun defaults to npm registry +base_pkg="$PACKAGE" +if [[ "$base_pkg" == npm:* ]]; then + base_pkg="${base_pkg#npm:}" +fi + +# Name used for skip checks (helps for git / URL / non-npm registry installs) +skip_name="$base_pkg" +if [ -n "$NAMEHINT" ]; then + skip_name="$NAMEHINT" +fi + +# Resolve list command (prefer global). Bun uses 'pm ls'. If unavailable, skip detection. +list_cmd="" +if bun pm ls -g >/dev/null 2>&1; then + list_cmd="bun pm ls -g" +elif bun pm ls >/dev/null 2>&1; then + list_cmd="bun pm ls" +fi + +# Skip when already present +if [ -n "$list_cmd" ]; then + if [ "$VERSION" = "latest" ] || [ -z "$VERSION" ]; then + if $list_cmd | grep -q "$skip_name"; then + echo "$skip_name already exists - skipping installation" + exit 0 + fi + else + # For pinned versions, skip only if exact version already installed + if $list_cmd | grep -q "${skip_name}@${VERSION}"; then + echo "$skip_name@${VERSION} already exists - skipping installation" + exit 0 + fi + fi +fi + +# Compose installation spec +pkg="$base_pkg" +if [ "$VERSION" != "latest" ] && [ -n "$VERSION" ]; then + pkg="$base_pkg@$VERSION" +fi + +# Install globally via Bun with basic retries to handle transient registry errors (e.g., 5xx) +max_attempts=4 +attempt=1 +while true; do + if bun add --global "$pkg"; then + break + fi + exit_code=$? + if [ "$attempt" -ge "$max_attempts" ]; then + echo "bun add failed after ${attempt} attempts (exit code $exit_code)" + exit "$exit_code" + fi + sleep_seconds=$(( attempt * attempt )) + echo "bun add failed (exit code $exit_code). Retrying in ${sleep_seconds}s... (${attempt}/${max_attempts})" + sleep "$sleep_seconds" + attempt=$(( attempt + 1 )) +done + +echo 'Done!' diff --git a/src/bun/NOTES.md b/src/bun/NOTES.md new file mode 100644 index 000000000..f11dbb560 --- /dev/null +++ b/src/bun/NOTES.md @@ -0,0 +1,74 @@ +# Additional Notes + +- Bun Website: [https://bun.com/](https://bun.com/) +- Bun GitHub: [https://github.com/oven-sh/bun](https://github.com/oven-sh/bun) + +## Install Method + +This feature installs Bun via the repository's `gh-release` helper, which downloads the correct release asset for the current platform and architecture and places the `bun` binary in `/usr/local/bin`. This follows the repo’s best practices for reproducibility and small image layers. + +## bunx shim + +Bun supports executing binaries with `bun x `. Some environments/tools expect a `bunx` executable. To provide a consistent experience, this feature adds a small shim at `/usr/local/bin/bunx` that forwards to `bun x`. If the upstream release reliably includes a `bunx` binary in the future, the shim can be removed without breaking users. + +## Usage Examples + +Default (latest): + +```json +"features": { + "ghcr.io/devcontainers-extra/features/bun:1": {} +} +``` + +Pin a specific version: + +```json +"features": { + "ghcr.io/devcontainers-extra/features/bun:1": { + "version": "1.1.38" + } +} +``` + +## Support + +- Distros: `Debian` / `Ubuntu` and `Alpine` +- Architectures: `x86_64` and `arm64` (based on available Bun releases) + +## Tests + +This feature is tested against various Distros: + +- `Ubuntu` (glibc) +- `Debian` (glibc) +- `Alpine` (musl) +- `Debian` with a pinned version of Bun + +*Note: Only architectures with actual Bun release assets are supported (x86_64 and arm64).* * + +## Architecture and Asset Selection + +This feature automatically selects the correct Bun release asset based on the detected architecture and libc: + +- **x86_64**: Uses "baseline" builds for optimal CPU compatibility (e.g., `bun-linux-x64-baseline.zip`) +- **arm64**: Uses standard builds since "baseline" variants are not published for ARM64 (e.g., `bun-linux-aarch64.zip`) + +The installation includes robust fallback logic: + +- Primary: Preferred asset pattern for the detected architecture/libc combination +- Fallback: Alternative patterns if the primary asset is not found +- Error handling: Clear error messages if no suitable asset is available + +This approach ensures compatibility across different platforms while gracefully handling potential future changes to Bun's release asset naming. + +## Considerations / Future Enhancements + +- Coexistence with Node.js: this feature only installs `bun` and a `bunx` shim and does not modify Node.js. +- PATH/profile: installation to `/usr/local/bin` avoids profile changes. +- Asset regex patterns: the fallback chain ensures compatibility even if Bun changes their release asset naming conventions. + +## Debugging + +- To enable additional debug logs during installation, set the environment variable `BUN_FEATURE_DEBUG=1`. +- Diagnostic logs from detection functions are emitted to stderr to keep return values clean. diff --git a/src/bun/README.md b/src/bun/README.md new file mode 100644 index 000000000..c7fea1b7c --- /dev/null +++ b/src/bun/README.md @@ -0,0 +1,23 @@ +# Bun (via Github Releases) (bun) + +Installs the Bun JavaScript runtime and package manager via GitHub Releases using the gh-release helper. + +## Example Usage + +```json +"features": { + "ghcr.io/devcontainers-extra/features/bun:1": {} +} +``` + +## Options + +| Options Id | Description | Type | Default Value | +|-----|-----|-----|-----| +| Options Id | Description | Type | Default Value | +|-----|-----|-----|-----| +| version | Select the version to install. | string | latest | + +--- + +_Note: This file was auto-generated from the [devcontainer-feature.json](devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/bun/devcontainer-feature.json b/src/bun/devcontainer-feature.json new file mode 100644 index 000000000..9d61213a0 --- /dev/null +++ b/src/bun/devcontainer-feature.json @@ -0,0 +1,20 @@ +{ + "id": "bun", + "version": "1.1.0", + "name": "Bun", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/bun", + "description": "Bun is an all-in-one toolkit for JavaScript and TypeScript apps.", + "options": { + "version": { + "default": "latest", + "description": "Select the version to install.", + "proposals": [ + "latest" + ], + "type": "string" + } + }, + "installsAfter": [ + "ghcr.io/devcontainers-extra/features/gh-release" + ] +} diff --git a/src/bun/install.sh b/src/bun/install.sh new file mode 100755 index 000000000..00921233b --- /dev/null +++ b/src/bun/install.sh @@ -0,0 +1,251 @@ +#!/usr/bin/env bash + +set -e + +source ./library_scripts.sh + +echo "Starting Bun installation" + +# nanolayer is a cli utility which keeps container layers as small as possible +# source code: https://github.com/devcontainers-extra/nanolayer +# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, +# and if missing - will download a temporary copy that automatically get deleted at the end +# of the script +echo "Ensuring nanolayer is available" +# Initialize variable to suppress shellcheck warning (assigned by ensure_nanolayer function) +nanolayer_location="" +ensure_nanolayer nanolayer_location "v0.5.6" + +# Canonicalize VERSION for Bun's tag scheme when pinning +canonicalize_version() { + local version="$1" + + if [ "$version" = "latest" ] || [ -z "$version" ]; then + echo "latest" + return 0 + fi + + # Remove any leading/trailing whitespace + version="$(echo "$version" | xargs)" + + # Already in correct format + if [[ "$version" =~ ^bun-v[0-9]+\.[0-9]+\.[0-9]+ ]]; then + echo "$version" + return 0 + fi + + # Remove 'bun-' prefix if present + if [[ "$version" =~ ^bun- ]]; then + version="${version#bun-}" + fi + + # Handle versions starting with 'v' + if [[ "$version" =~ ^v[0-9]+\.[0-9]+\.[0-9]+ ]]; then + echo "bun-$version" + return 0 + fi + + # Handle plain version numbers + if [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+ ]]; then + echo "bun-v$version" + return 0 + fi + + # Invalid version format + echo "WARNING: Invalid version format: '$version'. Using 'latest' instead." >&2 + echo "latest" +} + +# shellcheck disable=SC2153 +# VERSION is provided by the devcontainer features framework +version_for_release="$(canonicalize_version "$VERSION")" +echo "Using Bun version: $version_for_release" + +# Figure out arch and libc to disambiguate Bun's multiple Linux assets +detect_arch() { + local arch + arch="$(uname -m)" + + case "$arch" in + x86_64|amd64) + echo "x64" + ;; + aarch64|arm64) + echo "aarch64" + ;; + *) + # Log warning for unsupported architectures + echo "WARNING: Architecture '$arch' is not supported by Bun" >&2 + echo "WARNING: Bun only supports x64 and aarch64 architectures" >&2 + echo "WARNING: Available assets can be found at: https://github.com/oven-sh/bun/releases" >&2 + echo "$arch" + ;; + esac +} + +echo "Detecting system architecture" +if ! arch_segment="$(detect_arch)"; then + echo "ERROR: Failed to detect architecture" >&2 + exit 1 +fi + +# Detect musl vs glibc (robust detection across multiple distros) +detect_libc() { + # Method 1: Check for apk (Alpine) + if [ -x "/sbin/apk" ]; then + echo "-musl" + return 0 + fi + + # Method 2: Check ldd output for musl + if command -v ldd >/dev/null 2>&1; then + if ldd --version 2>&1 | grep -qi musl; then + echo "-musl" + return 0 + fi + fi + + # Method 3: Check for musl library files + if [ -f "/lib/ld-musl-x86_64.so.1" ] || [ -f "/lib/ld-musl-aarch64.so.1" ]; then + echo "-musl" + return 0 + fi + + # Method 4: Check /proc/mounts for musl + if grep -qi musl /proc/mounts 2>/dev/null; then + echo "-musl" + return 0 + fi + + # Default to glibc + echo "" +} + +echo "Detecting libc implementation" +if ! libc_suffix="$(detect_libc)"; then + echo "ERROR: Failed to detect libc implementation" >&2 + exit 1 +fi + +# Build asset regex based on architecture and libc +# - x64: Use baseline builds for widest CPU compatibility +# - aarch64: Use non-baseline builds since baseline doesn't exist for ARM64 +if [ "$arch_segment" = "x64" ]; then + # For x64, try baseline first, then fallback to non-baseline + asset_regex="^bun-linux-x64${libc_suffix}-baseline\\.zip$" +else + # For aarch64, use non-baseline since baseline doesn't exist + asset_regex="^bun-linux-aarch64${libc_suffix}\\.zip$" +fi + +# Bun tags are of the form 'bun-vX.Y.Z'; constrain tag discovery accordingly +release_tag_regex="^bun-v" + +# Try multiple asset regex patterns for robust fallback support +# Build the ordered list of asset regex patterns. +# For x64, we prefer "baseline" first for widest CPU compatibility across +# older/varied machines, then fall back to non-baseline. For aarch64, Bun does +# not publish baseline variants, so we use standard builds. +build_asset_patterns() { + local arch="$1" + local libc="$2" + + case "$arch" in + x64) + if [ "$libc" = "-musl" ]; then + echo "^bun-linux-x64-musl-baseline\\.zip$" + echo "^bun-linux-x64-musl\\.zip$" + else + echo "^bun-linux-x64-baseline\\.zip$" + echo "^bun-linux-x64\\.zip$" + fi + return 0 + ;; + aarch64) + if [ "$libc" = "-musl" ]; then + echo "^bun-linux-aarch64-musl\\.zip$" + else + echo "^bun-linux-aarch64\\.zip$" + fi + return 0 + ;; + *) + echo "ERROR: Unsupported architecture '$arch'" >&2 + echo "ERROR: Bun only supports x64 and aarch64 architectures" >&2 + echo "ERROR: Available assets can be found at: https://github.com/oven-sh/bun/releases" >&2 + return 1 + ;; + esac +} + +# Build asset patterns for current architecture +if ! asset_patterns_output=$(build_asset_patterns "$arch_segment" "$libc_suffix"); then + echo "ERROR: Failed to build asset patterns for arch=$arch_segment, libc_suffix=$libc_suffix" >&2 + exit 1 +fi + +# Convert to array - use a more reliable method +# Split by newlines and create array +asset_patterns=() +while IFS= read -r line; do + if [ -n "$line" ]; then + asset_patterns+=("$line") + fi +done <<< "$asset_patterns_output" + +# Verify we have asset patterns +if [ ${#asset_patterns[@]} -eq 0 ]; then + echo "ERROR: No asset patterns generated for arch=$arch_segment, libc_suffix=$libc_suffix" >&2 + echo "ERROR: asset_patterns_output was: '$asset_patterns_output'" >&2 + exit 1 +fi + +# Try each asset pattern until one succeeds +install_bun() { + if [ ${#asset_patterns[@]} -eq 0 ]; then + echo "ERROR: install_bun: No asset patterns provided!" >&2 + return 1 + fi + + for asset_regex in "${asset_patterns[@]}"; do + if $nanolayer_location \ + install \ + devcontainer-feature \ + "ghcr.io/devcontainers-extra/features/gh-release:1" \ + --option repo='oven-sh/bun' \ + --option binaryNames='bun' \ + --option version="$version_for_release" \ + --option assetRegex="$asset_regex" \ + --option releaseTagRegex="$release_tag_regex" 2>&1; then + return 0 + fi + done + + echo "ERROR: Failed to install Bun. No asset patterns matched." >&2 + echo "ERROR: Troubleshooting information:" >&2 + echo "ERROR: - Architecture: $arch_segment" >&2 + echo "ERROR: - Libc suffix: ${libc_suffix:-(none/glibc)}" >&2 + echo "ERROR: - Version: $version_for_release" >&2 + echo "ERROR: - Asset patterns tried: ${asset_patterns[*]}" >&2 + echo "ERROR: Check https://github.com/oven-sh/bun/releases for available assets" >&2 + return 1 +} + +# Attempt installation +if ! install_bun; then + echo "ERROR: install_bun function failed" >&2 + exit 1 +fi + +echo "Bun installation process completed" + +# Provide a convenient bunx shim +if [ -x "/usr/local/bin/bun" ] && ! [ -x "/usr/local/bin/bunx" ]; then + cat >/usr/local/bin/bunx <<'EOF' +#!/usr/bin/env bash +exec bun x "$@" +EOF + chmod +x /usr/local/bin/bunx +fi + +echo "Bun installation completed successfully" diff --git a/src/bun/library_scripts.sh b/src/bun/library_scripts.sh new file mode 100644 index 000000000..f6d0760d7 --- /dev/null +++ b/src/bun/library_scripts.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash + +clean_download() { + # The purpose of this function is to download a file with minimal impact on container layer size + # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a + # temporary manner, and making sure to + # 1. uninstall the downloader at the return of the function + # 2. revert back any changes to the package installer database/cache (for example apt-get lists) + # The above steps will minimize the leftovers being created while installing the downloader + # Supported distros: + # debian/ubuntu/alpine + + url=$1 + output_location=$2 + tempdir=$(mktemp -d) + downloader_installed="" + + function _apt_get_install() { + tempdir=$1 + + # copy current state of apt list - in order to revert back later (minimize contianer layer size) + cp -p -R /var/lib/apt/lists $tempdir + apt-get update -y + apt-get -y install --no-install-recommends wget ca-certificates + } + + function _apt_get_cleanup() { + tempdir=$1 + + echo "removing wget" + apt-get -y purge wget --auto-remove + + echo "revert back apt lists" + rm -rf /var/lib/apt/lists/* + rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists + } + + function _apk_install() { + tempdir=$1 + # copy current state of apk cache - in order to revert back later (minimize contianer layer size) + cp -p -R /var/cache/apk $tempdir + + apk add --no-cache wget + } + + function _apk_cleanup() { + tempdir=$1 + + echo "removing wget" + apk del wget + } + # try to use either wget or curl if one of them already installer + if type curl >/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + # in case none of them is installed, install wget temporarly + if [ -z $downloader ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_install $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_install $tempdir + else + echo "distro not supported" + exit 1 + fi + downloader="wget" + downloader_installed="true" + fi + + if [ $downloader = "wget" ]; then + wget -q $url -O $output_location + else + curl -sfL $url -o $output_location + fi + + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi + +} + +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + # normalize version + if ! [[ $required_version == v* ]]; then + required_version=v$required_version + fi + + local nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ]; then + nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" + fi + + # make sure its of the required version + if ! [[ -z "${nanolayer_location}" ]]; then + local current_version + current_version=$($nanolayer_location --version) + if ! [[ $current_version == v* ]]; then + current_version=v$current_version + fi + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [[ -z "${nanolayer_location}" ]]; then + + if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up() { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + if [ -x "/sbin/apk" ]; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + nanolayer_location=$tmp_dir/nanolayer + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + declare -g ${variable_name}=$nanolayer_location + +} diff --git a/src/caddy/devcontainer-feature.json b/src/caddy/devcontainer-feature.json index 9e2fcead4..be9dd4712 100644 --- a/src/caddy/devcontainer-feature.json +++ b/src/caddy/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "caddy", - "version": "1.0.9", + "version": "1.0.11", "name": "Caddy (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/caddy", "description": "Caddy is a powerful, enterprise-ready, open source web server with automatic HTTPS.", @@ -29,4 +29,4 @@ "ghcr.io/devcontainers/features/go", "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/caddy/install.sh b/src/caddy/install.sh index d5d7f9357..fd47c6175 100755 --- a/src/caddy/install.sh +++ b/src/caddy/install.sh @@ -8,13 +8,13 @@ set -e # `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, # and if missing - will download a temporary copy that automatically get deleted at the end # of the script -ensure_nanolayer nanolayer_location "v0.5.4" +ensure_nanolayer nanolayer_location "v0.5.6" $nanolayer_location \ install \ devcontainer-feature \ - "ghcr.io/devcontainers/features/go:1.1.3" \ + "ghcr.io/devcontainers/features/go:1.3.4" \ --option version="$GOLANGVERSION" @@ -22,7 +22,7 @@ $nanolayer_location \ $nanolayer_location \ install \ devcontainer-feature \ - "ghcr.io/devcontainers-extra/features/gh-release:1.0.25" \ + "ghcr.io/devcontainers-extra/features/gh-release:1.0.26" \ --option repo='caddyserver/caddy' --option binaryNames='caddy' --option version="$VERSION" diff --git a/src/ccache-asdf/devcontainer-feature.json b/src/ccache-asdf/devcontainer-feature.json index 886bdea51..767aaf7be 100644 --- a/src/ccache-asdf/devcontainer-feature.json +++ b/src/ccache-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ccache-asdf", - "version": "2.0.17", + "version": "2.0.18", "name": "Ccache (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ccache-asdf", "description": "Ccache is a compiler cache. It speeds up recompilation by caching previous compilations and detecting when the same compilation is being done again.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/asdf-package", "ghcr.io/devcontainers-extra/features/apt-get-packages" ] -} \ No newline at end of file +} diff --git a/src/checkov/devcontainer-feature.json b/src/checkov/devcontainer-feature.json index 09372ccb9..94363c3b5 100644 --- a/src/checkov/devcontainer-feature.json +++ b/src/checkov/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "checkov", - "version": "1.0.16", + "version": "1.0.17", "name": "Checkov (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/checkov", "description": "Checkov is a static code analysis tool for infrastructure as code (IaC) and also a software composition analysis (SCA) tool for images and open source packages.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/chezscheme-asdf/devcontainer-feature.json b/src/chezscheme-asdf/devcontainer-feature.json index 358352a91..25d48a5ac 100644 --- a/src/chezscheme-asdf/devcontainer-feature.json +++ b/src/chezscheme-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "chezscheme-asdf", - "version": "2.0.17", + "version": "2.0.18", "name": "chezscheme (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/chezscheme-asdf", "description": "Chez Scheme is both a programming language and an implementation of that language, with supporting tools and documentation.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/asdf-package", "ghcr.io/devcontainers-extra/features/apt-get-packages" ] -} \ No newline at end of file +} diff --git a/src/chisel/devcontainer-feature.json b/src/chisel/devcontainer-feature.json index 88e6b7e02..b81504f0d 100644 --- a/src/chisel/devcontainer-feature.json +++ b/src/chisel/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "chisel", - "version": "1.0.3", + "version": "1.0.4", "name": "Chisel (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/chisel", "description": "Chisel is a fast TCP/UDP tunnel, transported over HTTP, secured via SSH.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/circleci-cli/devcontainer-feature.json b/src/circleci-cli/devcontainer-feature.json index f3bb63ae0..c4200d939 100644 --- a/src/circleci-cli/devcontainer-feature.json +++ b/src/circleci-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "circleci-cli", - "version": "1.0.7", + "version": "1.0.8", "name": "CircleCI CLI (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/circleci-cli", "description": "The CircleCI command line interface (CLI) tool enables developers to build, validate, and test their pipeline jobs in their local development environments.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/claude-code/README.md b/src/claude-code/README.md new file mode 100644 index 000000000..321958cd2 --- /dev/null +++ b/src/claude-code/README.md @@ -0,0 +1,30 @@ + +# claude-code (via npm) (claude-code) + +Claude Code is an agentic coding tool that lives in your terminal + +## Example Usage + +```json +"features": { + "ghcr.io/devcontainers-extra/features/claude-code:1": {} +} +``` + +## Options + +| Options Id | Description | Type | Default Value | +|-----|-----|-----|-----| +| version | Select the version to install. | string | latest | + +## Customizations + +### VS Code Extensions + +- `anthropic.claude-code` + + + +--- + +_Note: This file was auto-generated from the [devcontainer-feature.json](devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/claude-code/bootstrap.sh b/src/claude-code/bootstrap.sh new file mode 100644 index 000000000..375daea51 --- /dev/null +++ b/src/claude-code/bootstrap.sh @@ -0,0 +1,158 @@ +#!/bin/bash + +set -e + +# Parse command line arguments +TARGET="$1" # Optional target parameter + +# Validate target if provided +if [[ -n "$TARGET" ]] && [[ ! "$TARGET" =~ ^(stable|latest|[0-9]+\.[0-9]+\.[0-9]+(-[^[:space:]]+)?)$ ]]; then + echo "Usage: $0 [stable|latest|VERSION]" >&2 + exit 1 +fi + +DOWNLOAD_BASE_URL="https://downloads.claude.ai/claude-code-releases" +DOWNLOAD_DIR="$HOME/.claude/downloads" + +# Check for required dependencies +DOWNLOADER="" +if command -v curl >/dev/null 2>&1; then + DOWNLOADER="curl" +elif command -v wget >/dev/null 2>&1; then + DOWNLOADER="wget" +else + echo "Either curl or wget is required but neither is installed" >&2 + exit 1 +fi + +# Check if jq is available (optional) +HAS_JQ=false +if command -v jq >/dev/null 2>&1; then + HAS_JQ=true +fi + +# Download function that works with both curl and wget +download_file() { + local url="$1" + local output="$2" + + if [ "$DOWNLOADER" = "curl" ]; then + if [ -n "$output" ]; then + curl -fsSL -o "$output" "$url" + else + curl -fsSL "$url" + fi + elif [ "$DOWNLOADER" = "wget" ]; then + if [ -n "$output" ]; then + wget -q -O "$output" "$url" + else + wget -q -O - "$url" + fi + else + return 1 + fi +} + +# Simple JSON parser for extracting checksum when jq is not available +get_checksum_from_manifest() { + local json="$1" + local platform="$2" + + # Normalize JSON to single line and extract checksum + json=$(echo "$json" | tr -d '\n\r\t' | sed 's/ \+/ /g') + + # Extract checksum for platform using bash regex + if [[ $json =~ \"$platform\"[^}]*\"checksum\"[[:space:]]*:[[:space:]]*\"([a-f0-9]{64})\" ]]; then + echo "${BASH_REMATCH[1]}" + return 0 + fi + + return 1 +} + +# Detect platform +case "$(uname -s)" in + Darwin) os="darwin" ;; + Linux) os="linux" ;; + MINGW*|MSYS*|CYGWIN*) echo "Windows is not supported by this script. See https://code.claude.com/docs for installation options." >&2; exit 1 ;; + *) echo "Unsupported operating system: $(uname -s). See https://code.claude.com/docs for supported platforms." >&2; exit 1 ;; +esac + +case "$(uname -m)" in + x86_64|amd64) arch="x64" ;; + arm64|aarch64) arch="arm64" ;; + *) echo "Unsupported architecture: $(uname -m)" >&2; exit 1 ;; +esac + +# Detect Rosetta 2 on macOS: if the shell is running as x64 under Rosetta on an ARM Mac, +# download the native arm64 binary instead of the x64 one +if [ "$os" = "darwin" ] && [ "$arch" = "x64" ]; then + if [ "$(sysctl -n sysctl.proc_translated 2>/dev/null)" = "1" ]; then + arch="arm64" + fi +fi + +# Check for musl on Linux and adjust platform accordingly +if [ "$os" = "linux" ]; then + if [ -f /lib/libc.musl-x86_64.so.1 ] || [ -f /lib/libc.musl-aarch64.so.1 ] || ldd /bin/ls 2>&1 | grep -q musl; then + platform="linux-${arch}-musl" + else + platform="linux-${arch}" + fi +else + platform="${os}-${arch}" +fi +mkdir -p "$DOWNLOAD_DIR" + +# Always download latest version (which has the most up-to-date installer) +version=$(download_file "$DOWNLOAD_BASE_URL/latest") + +# Download manifest and extract checksum +manifest_json=$(download_file "$DOWNLOAD_BASE_URL/$version/manifest.json") + +# Use jq if available, otherwise fall back to pure bash parsing +if [ "$HAS_JQ" = true ]; then + checksum=$(echo "$manifest_json" | jq -r ".platforms[\"$platform\"].checksum // empty") +else + checksum=$(get_checksum_from_manifest "$manifest_json" "$platform") +fi + +# Validate checksum format (SHA256 = 64 hex characters) +if [ -z "$checksum" ] || [[ ! "$checksum" =~ ^[a-f0-9]{64}$ ]]; then + echo "Platform $platform not found in manifest" >&2 + exit 1 +fi + +# Download and verify +binary_path="$DOWNLOAD_DIR/claude-$version-$platform" +if ! download_file "$DOWNLOAD_BASE_URL/$version/$platform/claude" "$binary_path"; then + echo "Download failed" >&2 + rm -f "$binary_path" + exit 1 +fi + +# Pick the right checksum tool +if [ "$os" = "darwin" ]; then + actual=$(shasum -a 256 "$binary_path" | cut -d' ' -f1) +else + actual=$(sha256sum "$binary_path" | cut -d' ' -f1) +fi + +if [ "$actual" != "$checksum" ]; then + echo "Checksum verification failed" >&2 + rm -f "$binary_path" + exit 1 +fi + +chmod +x "$binary_path" + +# Run claude install to set up launcher and shell integration +echo "Setting up Claude Code..." +"$binary_path" install ${TARGET:+"$TARGET"} + +# Clean up downloaded file +rm -f "$binary_path" + +echo "" +echo "✅ Installation complete!" +echo "" diff --git a/src/claude-code/devcontainer-feature.json b/src/claude-code/devcontainer-feature.json new file mode 100644 index 000000000..d0288726e --- /dev/null +++ b/src/claude-code/devcontainer-feature.json @@ -0,0 +1,25 @@ +{ + "id": "claude-code", + "version": "2.0.3", + "name": "claude-code", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/claude-code", + "description": "Claude Code is an agentic coding tool that lives in your terminal", + "options": { + "version": { + "default": "latest", + "description": "Select the version to install.", + "proposals": [ + "latest" + ], + "type": "string" + } + }, + "customizations": { + "vscode": { + "extensions": [ + "anthropic.claude-code" + ] + } + }, + "installsAfter": [] +} diff --git a/src/claude-code/install.sh b/src/claude-code/install.sh new file mode 100644 index 000000000..e31ac039d --- /dev/null +++ b/src/claude-code/install.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +set -e + +# Make sure that variable _REMOTE_USER_HOME is properly set +if [ -z "$_REMOTE_USER_HOME" ]; then + # shellcheck disable=2016 # this is intentional as the expansion should happen in the context of the new session + _REMOTE_USER_HOME="$(su - "$_REMOTE_USER" -c 'echo "$HOME"')" + export _REMOTE_USER_HOME +fi + +# Install via Anthropic's recommended method +# Script downloaded from them: +# https://storage.googleapis.com/claude-code-dist-86c565f3-f756-42ad-8dfa-d59b1c096819/claude-code-releases/bootstrap.sh + +# Resolve the absolute path before su changes the working directory +BOOTSTRAP_SCRIPT="$(pwd)/bootstrap.sh" + +# Run as the devcontainer user so that ~/.claude/, ~/.local/bin/claude, and +# ~/.local/share/claude/ are owned by the right user, not root. +su - "$_REMOTE_USER" </dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + # in case none of them is installed, install wget temporarly + if [ -z $downloader ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_install $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_install $tempdir + else + echo "distro not supported" + exit 1 + fi + downloader="wget" + downloader_installed="true" + fi + + if [ $downloader = "wget" ]; then + wget -q $url -O $output_location + else + curl -sfL $url -o $output_location + fi + + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi + +} + +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + # normalize version + if ! [[ $required_version == v* ]]; then + required_version=v$required_version + fi + + local nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ]; then + nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" + fi + + # make sure its of the required version + if ! [[ -z "${nanolayer_location}" ]]; then + local current_version + current_version=$($nanolayer_location --version) + if ! [[ $current_version == v* ]]; then + current_version=v$current_version + fi + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [[ -z "${nanolayer_location}" ]]; then + + if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up() { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + if [ -x "/sbin/apk" ]; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + nanolayer_location=$tmp_dir/nanolayer + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + declare -g ${variable_name}=$nanolayer_location + +} diff --git a/src/codefresh-cli/devcontainer-feature.json b/src/codefresh-cli/devcontainer-feature.json index f0d46c4ce..38a0d3d6f 100644 --- a/src/codefresh-cli/devcontainer-feature.json +++ b/src/codefresh-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "codefresh-cli", - "version": "1.0.7", + "version": "1.0.8", "name": "Codefresh CLI (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/codefresh-cli", "description": "Codefresh CLI provides a full and flexible interface to interact with Codefresh.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/codename-goose-cli/README.md b/src/codename-goose-cli/README.md new file mode 100644 index 000000000..6a55ae821 --- /dev/null +++ b/src/codename-goose-cli/README.md @@ -0,0 +1,24 @@ + +# codename goose CLI (via Github Releases) (codename-goose-cli) + +An open source, extensible AI agent that goes beyond code suggestions - install, execute, edit, and test with any LLM + +## Example Usage + +```json +"features": { + "ghcr.io/devcontainers-extra/features/codename-goose-cli:1": {} +} +``` + +## Options + +| Options Id | Description | Type | Default Value | +|-----|-----|-----|-----| +| version | Select the version to install. | string | stable | + + + +--- + +_Note: This file was auto-generated from the [devcontainer-feature.json](devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/codename-goose-cli/devcontainer-feature.json b/src/codename-goose-cli/devcontainer-feature.json new file mode 100644 index 000000000..ce976a22f --- /dev/null +++ b/src/codename-goose-cli/devcontainer-feature.json @@ -0,0 +1,17 @@ +{ + "id": "codename-goose-cli", + "version": "1.0.0", + "name": "codename-goose-cli", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/codename-goose-cli", + "description": "An open source, extensible AI agent that goes beyond code suggestions - install, execute, edit, and test with any LLM", + "options": { + "version": { + "default": "stable", + "description": "Select the version to install.", + "proposals": [ + "stable" + ], + "type": "string" + } + } +} \ No newline at end of file diff --git a/src/codename-goose-cli/install.sh b/src/codename-goose-cli/install.sh new file mode 100755 index 000000000..aa090996d --- /dev/null +++ b/src/codename-goose-cli/install.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +set -e + +source ./library_scripts.sh + +# nanolayer is a cli utility which keeps container layers as small as possible +# source code: https://github.com/devcontainers-extra/nanolayer +# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, +# and if missing - will download a temporary copy that automatically get deleted at the end +# of the script +ensure_nanolayer nanolayer_location "v0.5.6" + +echo "Installing goose $VERSION" + +$nanolayer_location \ + install \ + devcontainer-feature \ + "ghcr.io/devcontainers-extra/features/gh-release:1.0.26" \ + --option repo='block/goose' --option binaryNames='goose' --option version="$VERSION" + +$nanolayer_location \ + install \ + apt-get \ + libxcb1 + +echo 'Done!' diff --git a/src/codename-goose-cli/library_scripts.sh b/src/codename-goose-cli/library_scripts.sh new file mode 100644 index 000000000..f6d0760d7 --- /dev/null +++ b/src/codename-goose-cli/library_scripts.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash + +clean_download() { + # The purpose of this function is to download a file with minimal impact on container layer size + # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a + # temporary manner, and making sure to + # 1. uninstall the downloader at the return of the function + # 2. revert back any changes to the package installer database/cache (for example apt-get lists) + # The above steps will minimize the leftovers being created while installing the downloader + # Supported distros: + # debian/ubuntu/alpine + + url=$1 + output_location=$2 + tempdir=$(mktemp -d) + downloader_installed="" + + function _apt_get_install() { + tempdir=$1 + + # copy current state of apt list - in order to revert back later (minimize contianer layer size) + cp -p -R /var/lib/apt/lists $tempdir + apt-get update -y + apt-get -y install --no-install-recommends wget ca-certificates + } + + function _apt_get_cleanup() { + tempdir=$1 + + echo "removing wget" + apt-get -y purge wget --auto-remove + + echo "revert back apt lists" + rm -rf /var/lib/apt/lists/* + rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists + } + + function _apk_install() { + tempdir=$1 + # copy current state of apk cache - in order to revert back later (minimize contianer layer size) + cp -p -R /var/cache/apk $tempdir + + apk add --no-cache wget + } + + function _apk_cleanup() { + tempdir=$1 + + echo "removing wget" + apk del wget + } + # try to use either wget or curl if one of them already installer + if type curl >/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + # in case none of them is installed, install wget temporarly + if [ -z $downloader ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_install $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_install $tempdir + else + echo "distro not supported" + exit 1 + fi + downloader="wget" + downloader_installed="true" + fi + + if [ $downloader = "wget" ]; then + wget -q $url -O $output_location + else + curl -sfL $url -o $output_location + fi + + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi + +} + +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + # normalize version + if ! [[ $required_version == v* ]]; then + required_version=v$required_version + fi + + local nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ]; then + nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" + fi + + # make sure its of the required version + if ! [[ -z "${nanolayer_location}" ]]; then + local current_version + current_version=$($nanolayer_location --version) + if ! [[ $current_version == v* ]]; then + current_version=v$current_version + fi + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [[ -z "${nanolayer_location}" ]]; then + + if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up() { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + if [ -x "/sbin/apk" ]; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + nanolayer_location=$tmp_dir/nanolayer + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + declare -g ${variable_name}=$nanolayer_location + +} diff --git a/src/composer/devcontainer-feature.json b/src/composer/devcontainer-feature.json index f182240dd..584e227ff 100644 --- a/src/composer/devcontainer-feature.json +++ b/src/composer/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "composer", - "version": "1.0.0", + "version": "1.0.1", "name": "Composer (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/composer", "description": "Composer is an open source dependency management tool for PHP.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/concurnas-sdkman/devcontainer-feature.json b/src/concurnas-sdkman/devcontainer-feature.json index d008a3e40..cead6a3a9 100644 --- a/src/concurnas-sdkman/devcontainer-feature.json +++ b/src/concurnas-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "concurnas-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "Concurnas (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/concurnas-sdkman", "description": "Concurnas is an open source JVM programming language designed for building\nreliable, scalable, high performance concurrent, distributed and parallel\nsystems.", @@ -38,4 +38,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/connor-sdkman/devcontainer-feature.json b/src/connor-sdkman/devcontainer-feature.json index 080e7d195..2af5b7395 100644 --- a/src/connor-sdkman/devcontainer-feature.json +++ b/src/connor-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "connor-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "ConnOR (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/connor-sdkman", "description": "ConnOR, short for ConnectOffsetReset, is a commandline tool for resetting Kafka\nConnect source connector offsets.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/consul-asdf/devcontainer-feature.json b/src/consul-asdf/devcontainer-feature.json index 63afd39e1..87403950f 100644 --- a/src/consul-asdf/devcontainer-feature.json +++ b/src/consul-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "consul-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "consul (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/consul-asdf", "description": "Consul is a service networking solution to automate network configurations, discover services, and enable secure connectivity across any cloud or runtime.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/consul-exporter/devcontainer-feature.json b/src/consul-exporter/devcontainer-feature.json index c4dd28585..59f166af9 100644 --- a/src/consul-exporter/devcontainer-feature.json +++ b/src/consul-exporter/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "consul-exporter", - "version": "1.0.2", + "version": "1.0.3", "name": "Prometheus Consul Exporter (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/consul-exporter", "description": "Prometheus exporter for Consul metrics.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/cookiecutter/devcontainer-feature.json b/src/cookiecutter/devcontainer-feature.json index 12e8c6a0b..9bb11c176 100644 --- a/src/cookiecutter/devcontainer-feature.json +++ b/src/cookiecutter/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "cookiecutter", - "version": "2.0.17", + "version": "2.0.18", "name": "Cookiecutter (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/cookiecutter", "description": "Cookiecutter creates projects from project templates.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/copier/devcontainer-feature.json b/src/copier/devcontainer-feature.json index dcf4c7d30..c88a3904b 100644 --- a/src/copier/devcontainer-feature.json +++ b/src/copier/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "copier", - "version": "7.0.14", + "version": "7.0.15", "name": "copier (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/copier", "description": "copier creates projects from project templates.", @@ -23,4 +23,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/corepack/devcontainer-feature.json b/src/corepack/devcontainer-feature.json index 5adf2a71d..7ae6f7b7d 100644 --- a/src/corepack/devcontainer-feature.json +++ b/src/corepack/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "corepack", - "version": "1.0.1", + "version": "1.0.2", "name": "Corepack (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/corepack", "description": "Corepack is a zero-runtime-dependency Node.js script that acts as a bridge between Node.js projects and the package managers they are intended to be used with during development.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/cosign/devcontainer-feature.json b/src/cosign/devcontainer-feature.json index 668f2b0bb..83457d814 100644 --- a/src/cosign/devcontainer-feature.json +++ b/src/cosign/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "cosign", - "version": "1.0.9", + "version": "1.0.10", "name": "Cosign (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/cosign", "description": "Cosign is a command line utility that can sign and verify software artifact, such as container images and blobs.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/coverage-py/devcontainer-feature.json b/src/coverage-py/devcontainer-feature.json index 4b0e83b15..8e609e1dc 100644 --- a/src/coverage-py/devcontainer-feature.json +++ b/src/coverage-py/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "coverage-py", - "version": "2.0.17", + "version": "2.0.18", "name": "Coverage.py (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/coverage-py", "description": "Coverage.py is a tool for measuring code coverage of Python programs.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/crystal-asdf/devcontainer-feature.json b/src/crystal-asdf/devcontainer-feature.json index 6514022be..9485bb663 100644 --- a/src/crystal-asdf/devcontainer-feature.json +++ b/src/crystal-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "crystal-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "Crystal (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/crystal-asdf", "description": "Crystal is a general-purpose, object-oriented programming language", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/cuba-sdkman/devcontainer-feature.json b/src/cuba-sdkman/devcontainer-feature.json index 8b8d5bd2d..9e7a56830 100644 --- a/src/cuba-sdkman/devcontainer-feature.json +++ b/src/cuba-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "cuba-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "CUBA CLI (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/cuba-sdkman", "description": "CUBA CLI is an open source command line utility that enables you to easily\ncreate projects based on CUBA Platform", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/curl-apt-get/devcontainer-feature.json b/src/curl-apt-get/devcontainer-feature.json index 2daf32fd1..71eecc332 100644 --- a/src/curl-apt-get/devcontainer-feature.json +++ b/src/curl-apt-get/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "curl-apt-get", - "version": "1.0.17", + "version": "1.0.18", "name": "cURL (via apt-get)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/curl-apt-get", "description": "cURL is a computer software project providing a library and command-line tool for transferring data using various network protocols.", @@ -8,4 +8,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/apt-get-packages" ] -} \ No newline at end of file +} diff --git a/src/curl-homebrew/devcontainer-feature.json b/src/curl-homebrew/devcontainer-feature.json index edb44a30b..4b384f682 100644 --- a/src/curl-homebrew/devcontainer-feature.json +++ b/src/curl-homebrew/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "curl-homebrew", - "version": "1.0.20", + "version": "1.0.21", "name": "cURL (via Homebrew)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/curl-homebrew", "description": "cURL is a computer software project providing a library and command-line tool for transferring data using various network protocols.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/homebrew-package" ] -} \ No newline at end of file +} diff --git a/src/cve-bin-tool/devcontainer-feature.json b/src/cve-bin-tool/devcontainer-feature.json index 43022c8e9..f79956b0e 100644 --- a/src/cve-bin-tool/devcontainer-feature.json +++ b/src/cve-bin-tool/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "cve-bin-tool", - "version": "1.0.4", + "version": "1.0.5", "name": "CVE Binary Tool (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/cve-bin-tool", "description": "The CVE Binary Tool is a free, open source tool to help you find known vulnerabilities in software, using data from the National Vulnerability Database (NVD) list of Common Vulnerabilities and Exposures (CVEs).", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/cxf-sdkman/devcontainer-feature.json b/src/cxf-sdkman/devcontainer-feature.json index 6fef6f379..8fb938321 100644 --- a/src/cxf-sdkman/devcontainer-feature.json +++ b/src/cxf-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "cxf-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "CXF (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/cxf-sdkman", "description": "Apache CXF is an open source services framework. CXF helps you build and develop\nservices using frontend programming APIs, like JAX-WS and JAX-RS. These services\ncan speak a variety of protocols such as SOAP, XML/HTTP, RESTful HTTP, or CORBA\nand work over a variety of transports such as HTTP, JMS or JBI.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/cyclonedx-cli/devcontainer-feature.json b/src/cyclonedx-cli/devcontainer-feature.json index 7220b2c8e..310277265 100644 --- a/src/cyclonedx-cli/devcontainer-feature.json +++ b/src/cyclonedx-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "cyclonedx-cli", - "version": "1.0.9", + "version": "1.0.10", "name": "CycloneDX CLI (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/cyclonedx-cli", "description": "CycloneDX CLI is a utility with many functions to view, convert, and perform operations on SBOMs.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/cyclonedx-python/devcontainer-feature.json b/src/cyclonedx-python/devcontainer-feature.json index 85ef918e6..9d8a069c9 100644 --- a/src/cyclonedx-python/devcontainer-feature.json +++ b/src/cyclonedx-python/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "cyclonedx-python", - "version": "1.0.4", + "version": "1.0.5", "name": "CycloneDX Python (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/cyclonedx-python", "description": "CycloneDX Python creates CycloneDX Software Bill of Materials (SBOM) from Python projects and environments.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/cz-cli/devcontainer-feature.json b/src/cz-cli/devcontainer-feature.json index 8b415b21d..25e9d733e 100644 --- a/src/cz-cli/devcontainer-feature.json +++ b/src/cz-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "cz-cli", - "version": "1.0.1", + "version": "1.0.2", "name": "Commitizen CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/cz-cli", "description": "Commitizen is release management tool designed for teams. Commitizen assumes your team uses a standard way of commiting rules and from that foundation, it can bump your project's version, create the changelog, and update files.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/d/devcontainer-feature.json b/src/d/devcontainer-feature.json index 25ffc78bf..8a56d67df 100644 --- a/src/d/devcontainer-feature.json +++ b/src/d/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "D (via dlang.org)", "id": "d", - "version": "1.0.2", + "version": "1.0.3", "description": "D is a general-purpose programming language with static typing, systems-level access, and C-like syntax.", "documentationURL": "https://github.com/devcontainers-extra/features/tree/main/src/d", "options": { @@ -24,4 +24,4 @@ "description": "Select the compiler version you would like to install" } } -} \ No newline at end of file +} diff --git a/src/dart/devcontainer-feature.json b/src/dart/devcontainer-feature.json new file mode 100644 index 000000000..878009f44 --- /dev/null +++ b/src/dart/devcontainer-feature.json @@ -0,0 +1,20 @@ +{ + "id": "dart", + "version": "1.0.0", + "name": "dart (via asdf)", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/dart", + "description": "Dart is an approachable, portable, and productive programming language for high-quality apps on any platform", + "options": { + "version": { + "default": "latest", + "description": "Select the version to install.", + "proposals": [ + "latest" + ], + "type": "string" + } + }, + "installsAfter": [ + "ghcr.io/devcontainers-extra/features/asdf-package" + ] +} \ No newline at end of file diff --git a/archive/src/btm/install.sh b/src/dart/install.sh similarity index 61% rename from archive/src/btm/install.sh rename to src/dart/install.sh index 56871f3ba..b19da22a7 100755 --- a/archive/src/btm/install.sh +++ b/src/dart/install.sh @@ -1,23 +1,21 @@ +#!/usr/bin/env bash set -e -. ./library_scripts.sh +source ./library_scripts.sh # nanolayer is a cli utility which keeps container layers as small as possible # source code: https://github.com/devcontainers-extra/nanolayer # `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, # and if missing - will download a temporary copy that automatically get deleted at the end # of the script -ensure_nanolayer nanolayer_location "v0.5.4" - +ensure_nanolayer nanolayer_location "v0.5.6" +# Example nanolayer installation via devcontainer-feature $nanolayer_location \ install \ devcontainer-feature \ - "ghcr.io/devcontainers-extra/features/gh-release:1.0.25" \ - --option repo='ClementTsang/bottom' --option binaryNames='btm' --option version="$VERSION" --option assetRegex='^(?!.*(2-17))' - - + "ghcr.io/devcontainers-extra/features/asdf-package:1.0.10" \ + --option plugin='dart' --option version="$VERSION" echo 'Done!' - diff --git a/src/dart/library_scripts.sh b/src/dart/library_scripts.sh new file mode 100644 index 000000000..f6d0760d7 --- /dev/null +++ b/src/dart/library_scripts.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash + +clean_download() { + # The purpose of this function is to download a file with minimal impact on container layer size + # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a + # temporary manner, and making sure to + # 1. uninstall the downloader at the return of the function + # 2. revert back any changes to the package installer database/cache (for example apt-get lists) + # The above steps will minimize the leftovers being created while installing the downloader + # Supported distros: + # debian/ubuntu/alpine + + url=$1 + output_location=$2 + tempdir=$(mktemp -d) + downloader_installed="" + + function _apt_get_install() { + tempdir=$1 + + # copy current state of apt list - in order to revert back later (minimize contianer layer size) + cp -p -R /var/lib/apt/lists $tempdir + apt-get update -y + apt-get -y install --no-install-recommends wget ca-certificates + } + + function _apt_get_cleanup() { + tempdir=$1 + + echo "removing wget" + apt-get -y purge wget --auto-remove + + echo "revert back apt lists" + rm -rf /var/lib/apt/lists/* + rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists + } + + function _apk_install() { + tempdir=$1 + # copy current state of apk cache - in order to revert back later (minimize contianer layer size) + cp -p -R /var/cache/apk $tempdir + + apk add --no-cache wget + } + + function _apk_cleanup() { + tempdir=$1 + + echo "removing wget" + apk del wget + } + # try to use either wget or curl if one of them already installer + if type curl >/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + # in case none of them is installed, install wget temporarly + if [ -z $downloader ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_install $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_install $tempdir + else + echo "distro not supported" + exit 1 + fi + downloader="wget" + downloader_installed="true" + fi + + if [ $downloader = "wget" ]; then + wget -q $url -O $output_location + else + curl -sfL $url -o $output_location + fi + + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi + +} + +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + # normalize version + if ! [[ $required_version == v* ]]; then + required_version=v$required_version + fi + + local nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ]; then + nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" + fi + + # make sure its of the required version + if ! [[ -z "${nanolayer_location}" ]]; then + local current_version + current_version=$($nanolayer_location --version) + if ! [[ $current_version == v* ]]; then + current_version=v$current_version + fi + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [[ -z "${nanolayer_location}" ]]; then + + if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up() { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + if [ -x "/sbin/apk" ]; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + nanolayer_location=$tmp_dir/nanolayer + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + declare -g ${variable_name}=$nanolayer_location + +} diff --git a/src/dasel-asdf/devcontainer-feature.json b/src/dasel-asdf/devcontainer-feature.json index ad03d9870..ca30d53ec 100644 --- a/src/dasel-asdf/devcontainer-feature.json +++ b/src/dasel-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "dasel-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "Dasel (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/dasel-asdf", "description": "Dasel (short for data-selector) allows you to query and modify data structures using selector strings.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/dashlane-cli/devcontainer-feature.json b/src/dashlane-cli/devcontainer-feature.json index 6fc92129b..047b6d873 100644 --- a/src/dashlane-cli/devcontainer-feature.json +++ b/src/dashlane-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "dashlane-cli", - "version": "1.0.14", + "version": "1.0.15", "name": "Dashlane CLI (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/dashlane-cli", "description": "Dashlane Command Line Interface allows you to get your passwords, otp and secure notes right from your terminal.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/datadog-ci-cli/devcontainer-feature.json b/src/datadog-ci-cli/devcontainer-feature.json index 957c2ccee..f0ee7febd 100644 --- a/src/datadog-ci-cli/devcontainer-feature.json +++ b/src/datadog-ci-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "datadog-ci-cli", - "version": "1.0.7", + "version": "1.0.8", "name": "Datadog CI CLI (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/datadog-ci-cli", "description": "Execute commands with Datadog from within your Continuous Integration/Continuous Deployment scripts to perform end-to-end tests of your application before applying your changes or deploying. datadog-ci allows you to run Continuous Testing tests and wait for the results.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/datasette/devcontainer-feature.json b/src/datasette/devcontainer-feature.json index 823b6cd64..0c95b2b64 100644 --- a/src/datasette/devcontainer-feature.json +++ b/src/datasette/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "datasette", - "version": "2.0.17", + "version": "2.0.18", "name": "Datasette (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/datasette", "description": "Datasette is a tool for exploring and publishing data and is aimed at data journalists, museum curators, archivists, local governments, scientists and researchers.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/dbt-coverage/devcontainer-feature.json b/src/dbt-coverage/devcontainer-feature.json index 2d8218de9..26208bab5 100644 --- a/src/dbt-coverage/devcontainer-feature.json +++ b/src/dbt-coverage/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "dbt-coverage", - "version": "1.0.1", + "version": "1.0.2", "name": "dbt-coverage (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/dbt-coverage", "description": "dbt-coverage is a one-stop-shop for docs and test coverage of dbt projects.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/ddgr-apt-get/devcontainer-feature.json b/src/ddgr-apt-get/devcontainer-feature.json index ea11aa6bd..6affcd880 100644 --- a/src/ddgr-apt-get/devcontainer-feature.json +++ b/src/ddgr-apt-get/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ddgr-apt-get", - "version": "1.0.16", + "version": "1.0.17", "name": "ddgr (via apt-get)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ddgr-apt-get", "description": "ddgr is a cmdline utility to search DuckDuckGo from the terminal.", @@ -8,4 +8,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/apt-get-packages" ] -} \ No newline at end of file +} diff --git a/src/ddgr-homebrew/devcontainer-feature.json b/src/ddgr-homebrew/devcontainer-feature.json index 55bd99ccd..2b7e4b86a 100644 --- a/src/ddgr-homebrew/devcontainer-feature.json +++ b/src/ddgr-homebrew/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ddgr-homebrew", - "version": "1.0.20", + "version": "1.0.21", "name": "ddgr (via Homebrew)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ddgr-homebrew", "description": "ddgr is a cmdline utility to search DuckDuckGo from the terminal.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/homebrew-package" ] -} \ No newline at end of file +} diff --git a/src/deno-asdf/devcontainer-feature.json b/src/deno-asdf/devcontainer-feature.json index e0bf5b16a..2548891cc 100644 --- a/src/deno-asdf/devcontainer-feature.json +++ b/src/deno-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "deno-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "Deno (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/deno-asdf", "description": "Deno is a simple, modern runtime for JavaScript and TypeScript that uses V8 and is built in Rust.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/deno/devcontainer-feature.json b/src/deno/devcontainer-feature.json index a6ede0bbb..c6b5bd4fe 100644 --- a/src/deno/devcontainer-feature.json +++ b/src/deno/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "Deno (via Github Releases)", "id": "deno", - "version": "1.0.2", + "version": "1.0.4", "description": "Deno is a simple, modern runtime for JavaScript and TypeScript that uses V8 and is built in Rust.", "documentationURL": "https://github.com/devcontainers-extra/features/tree/main/src/deno", "options": { @@ -15,4 +15,4 @@ "description": "Select the Deno version you would like to install" } } -} \ No newline at end of file +} diff --git a/src/deno/install.sh b/src/deno/install.sh index e9f96854e..d06bee329 100755 --- a/src/deno/install.sh +++ b/src/deno/install.sh @@ -18,10 +18,7 @@ else case $(uname -sm) in "Darwin x86_64") target="x86_64-apple-darwin" ;; "Darwin arm64") target="aarch64-apple-darwin" ;; - "Linux aarch64") - echo "Error: Official Deno builds for Linux aarch64 are not available. (https://github.com/denoland/deno/issues/1846)" 1>&2 - exit 1 - ;; + "Linux aarch64") target='aarch64-unknown-linux-gnu' ;; *) target="x86_64-unknown-linux-gnu" ;; esac fi diff --git a/src/devcontainers-cli/devcontainer-feature.json b/src/devcontainers-cli/devcontainer-feature.json index f02641900..ba853d39e 100644 --- a/src/devcontainers-cli/devcontainer-feature.json +++ b/src/devcontainers-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "devcontainers-cli", - "version": "1.0.0", + "version": "1.0.1", "name": "devcontainers CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/devcontainers-cli", "description": "The devcontainers CLI, which configures devcontainers from devcontainer.json. Requires the Docker client and access to a Docker engine socket (e.g. by mounting the host's Docker socket into the container)", @@ -19,4 +19,4 @@ "ghcr.io/devcontainers/features/node", "ghcr.io/devcontainers/features/docker-outside-of-docker" ] -} \ No newline at end of file +} diff --git a/src/digitalocean-cli/devcontainer-feature.json b/src/digitalocean-cli/devcontainer-feature.json index 72b532c6b..f5741fb16 100644 --- a/src/digitalocean-cli/devcontainer-feature.json +++ b/src/digitalocean-cli/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "DigitalOcean CLI (via Github Releases)", "id": "digitalocean-cli", - "version": "1.0.3", + "version": "1.0.4", "description": "DigitalOcean CLI allows you to interact with the DigitalOcean API via the command line", "documentationURL": "https://github.com/devcontainers-extra/features/tree/main/src/digitalocean-cli", "options": { @@ -15,4 +15,4 @@ "description": "Select the DigitalOcean CLI version you would like to install" } } -} \ No newline at end of file +} diff --git a/src/direnv-asdf/devcontainer-feature.json b/src/direnv-asdf/devcontainer-feature.json index 3f762be2e..81ae9908b 100644 --- a/src/direnv-asdf/devcontainer-feature.json +++ b/src/direnv-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "direnv-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "direnv (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/direnv-asdf", "description": "direnv is an extension for your shell. It augments existing shells with a new feature that can load and unload environment variables depending on the current directory.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/direnv/devcontainer-feature.json b/src/direnv/devcontainer-feature.json index ad636a933..22061a77a 100644 --- a/src/direnv/devcontainer-feature.json +++ b/src/direnv/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "direnv", - "version": "1.0.2", + "version": "1.0.3", "name": "Direnv (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/direnv", "description": "direnv is an extension for your shell. It augments existing shells with a new feature that can load and unload environment variables depending on the current directory.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/dive/devcontainer-feature.json b/src/dive/devcontainer-feature.json index f20dafb35..d27b9d85c 100644 --- a/src/dive/devcontainer-feature.json +++ b/src/dive/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "dive", - "version": "1.0.14", + "version": "1.0.15", "name": "Dive (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/dive", "description": "Dive is a tool for exploring a docker image, layer contents, and discovering ways to shrink the size of your Docker/OCI image.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/dnote/devcontainer-feature.json b/src/dnote/devcontainer-feature.json index 75ba4c4c7..3f092fc14 100644 --- a/src/dnote/devcontainer-feature.json +++ b/src/dnote/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "dnote", - "version": "1.0.9", + "version": "1.0.10", "name": "Dnote (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/dnote", "description": "Dnote is a simple command line notebook for programmers. It keeps you focused by providing a way of effortlessly capturing and retrieving information without leaving your terminal. It also offers a seamless multi-device sync.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/doctoolchain-sdkman/devcontainer-feature.json b/src/doctoolchain-sdkman/devcontainer-feature.json index c854f6648..a3b427905 100644 --- a/src/doctoolchain-sdkman/devcontainer-feature.json +++ b/src/doctoolchain-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "doctoolchain-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "docToolchain (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/doctoolchain-sdkman", "description": "docToolchain is an implementation of the docs-as-code approach for software\narchitecture plus some additional automation. The basis of docToolchain is the\nphilosophy that software documentation should be treated in the same way as code\ntogether with the arc42 template for software architecture.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/dprint-asdf/devcontainer-feature.json b/src/dprint-asdf/devcontainer-feature.json index c58a7aac0..363e005f0 100644 --- a/src/dprint-asdf/devcontainer-feature.json +++ b/src/dprint-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "dprint-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "dprint (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/dprint-asdf", "description": "dprint is a pluggable and configurable code formatting platform written in Rust.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/driftctl/devcontainer-feature.json b/src/driftctl/devcontainer-feature.json index a938c38cd..4cbd8fbd9 100644 --- a/src/driftctl/devcontainer-feature.json +++ b/src/driftctl/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "driftctl", - "version": "1.0.5", + "version": "1.0.6", "name": "driftctl (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/driftctl", "description": "driftctl detect, track and alert on infrastructure drift.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/drone-cli/devcontainer-feature.json b/src/drone-cli/devcontainer-feature.json index f1f2fa7eb..da5e9c0f8 100644 --- a/src/drone-cli/devcontainer-feature.json +++ b/src/drone-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "drone-cli", - "version": "1.0.7", + "version": "1.0.8", "name": "Drone CLI (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/drone-cli", "description": "Drone CLI is a command line client for the Drone continuous integration server.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/dua/devcontainer-feature.json b/src/dua/devcontainer-feature.json index e2f6cf688..c82ef824d 100644 --- a/src/dua/devcontainer-feature.json +++ b/src/dua/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "dua", - "version": "1.0.14", + "version": "1.0.15", "name": "dua (Disk Usage Analyzer) (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/dua", "description": "dua (Disk Usage Analyzer) is a tool to conveniently learn about the usage of disk space of a given directory. It's parallel by default and will max out your SSD, providing relevant information as fast as possible. Optionally delete superfluous data, and do so more quickly than rm.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/duf/devcontainer-feature.json b/src/duf/devcontainer-feature.json index 24366d0f6..923dd34cf 100644 --- a/src/duf/devcontainer-feature.json +++ b/src/duf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "duf", - "version": "1.0.14", + "version": "1.0.15", "name": "duf (Disk Usage/Free Utility) (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/duf", "description": "duf is a better 'df' alternative.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/dufs/devcontainer-feature.json b/src/dufs/devcontainer-feature.json index 296b8b5f9..2dc394859 100644 --- a/src/dufs/devcontainer-feature.json +++ b/src/dufs/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "dufs", - "version": "1.0.14", + "version": "1.0.15", "name": "Dufs (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/dufs", "description": "Dufs is a distinctive utility file server that supports static serving, uploading, searching, accessing control, webdav and more.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/eas-cli/devcontainer-feature.json b/src/eas-cli/devcontainer-feature.json index 7f65a8416..746cf5115 100644 --- a/src/eas-cli/devcontainer-feature.json +++ b/src/eas-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "eas-cli", - "version": "1.0.10", + "version": "1.0.11", "name": "EAS CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/eas-cli", "description": "EAS CLI is the command line app you will use to interact with EAS services from your terminal.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/eget/devcontainer-feature.json b/src/eget/devcontainer-feature.json index 2d4cea602..1d18c1a90 100644 --- a/src/eget/devcontainer-feature.json +++ b/src/eget/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "eget", - "version": "1.0.14", + "version": "1.0.15", "name": "Eget (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/eget", "description": "Eget easily install prebuilt binaries from GitHub.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/elm-asdf/devcontainer-feature.json b/src/elm-asdf/devcontainer-feature.json index 339f64b9f..548eaee3a 100644 --- a/src/elm-asdf/devcontainer-feature.json +++ b/src/elm-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "elm-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "Elm (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/elm-asdf", "description": "Elm is a domain-specific programming language for declaratively creating web browser-based graphical user interfaces.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/ember-cli/devcontainer-feature.json b/src/ember-cli/devcontainer-feature.json index 6e0d71513..acff9f116 100644 --- a/src/ember-cli/devcontainer-feature.json +++ b/src/ember-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ember-cli", - "version": "1.0.2", + "version": "1.0.3", "name": "Ember CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ember-cli", "description": "The Ember CLI (command line interface) is the official way to create, build, test, and serve the files that make up an Ember app or addon.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/envoy/devcontainer-feature.json b/src/envoy/devcontainer-feature.json index 7ef48445e..2962008fe 100644 --- a/src/envoy/devcontainer-feature.json +++ b/src/envoy/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "envoy", - "version": "1.0.5", + "version": "1.0.6", "name": "Envoy (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/envoy", "description": "Envoy is an L7 proxy and communication bus designed for large modern service oriented architectures.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/epinio/devcontainer-feature.json b/src/epinio/devcontainer-feature.json index 364bffe76..4e1197247 100644 --- a/src/epinio/devcontainer-feature.json +++ b/src/epinio/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "epinio", - "version": "1.0.0", + "version": "1.0.1", "name": "Epinio (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/epinio", "description": "Epinio is an opinionated platform that runs on Kubernetes to take you from Code to URL in one step.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/etcd/devcontainer-feature.json b/src/etcd/devcontainer-feature.json index 60d2ca3fb..1e2ddc707 100644 --- a/src/etcd/devcontainer-feature.json +++ b/src/etcd/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "etcd", - "version": "1.0.11", + "version": "1.0.12", "name": "etcd (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/etcd", "description": "etcd is a distributed reliable key-value store for the most critical data of a distributed system.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/exa/README.md b/src/exa/README.md index 051c5e167..2ad2af9a0 100644 --- a/src/exa/README.md +++ b/src/exa/README.md @@ -1,8 +1,9 @@ - # exa (via Github Releases) (exa) exa is a modern replacement for ls. +Note: exa is no longer maintained. Use eza instead. + ## Example Usage ```json @@ -16,9 +17,3 @@ exa is a modern replacement for ls. | Options Id | Description | Type | Default Value | |-----|-----|-----|-----| | version | Select the version to install. | string | latest | - - - ---- - -_Note: This file was auto-generated from the [devcontainer-feature.json](devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/exa/devcontainer-feature.json b/src/exa/devcontainer-feature.json index 3a0f0868f..8afc437db 100644 --- a/src/exa/devcontainer-feature.json +++ b/src/exa/devcontainer-feature.json @@ -1,9 +1,9 @@ { "id": "exa", - "version": "1.0.14", + "version": "1.0.16", "name": "exa (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/exa", - "description": "exa is a modern replacement for ls.", + "description": "exa is a modern replacement for ls. No longer maintained; use eza instead", "options": { "version": { "default": "latest", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/exercism-cli/devcontainer-feature.json b/src/exercism-cli/devcontainer-feature.json index 28d6eda49..51aa1ba7b 100644 --- a/src/exercism-cli/devcontainer-feature.json +++ b/src/exercism-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "exercism-cli", - "version": "1.0.6", + "version": "1.0.7", "name": "Exercism CLI (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/exercism-cli", "description": "Exercism CLI is the link between the Exercism website and your local work environment. It lets you download exercises and submit your solution to the site.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/expo-cli/devcontainer-feature.json b/src/expo-cli/devcontainer-feature.json index 45e0edb74..243fcb714 100644 --- a/src/expo-cli/devcontainer-feature.json +++ b/src/expo-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "expo-cli", - "version": "1.0.10", + "version": "1.0.11", "name": "Expo CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/expo-cli", "description": "The Expo CLI is a command-line tool that is the primary interface between a developer and other Expo tools.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/express-generator/devcontainer-feature.json b/src/express-generator/devcontainer-feature.json index 42f2037f5..c26ca56bc 100644 --- a/src/express-generator/devcontainer-feature.json +++ b/src/express-generator/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "express-generator", - "version": "2.0.15", + "version": "2.0.16", "name": "Express Application Generator (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/express-generator", "description": "Express Application Generator is a handy tool for creating skeleton Express web apps.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/eza/README.md b/src/eza/README.md new file mode 100644 index 000000000..24d1a9242 --- /dev/null +++ b/src/eza/README.md @@ -0,0 +1,17 @@ +# eza (via Github Releases) (eza) + +eza is a modern replacement for ls. + +## Example Usage + +```json +"features": { + "ghcr.io/devcontainers-extra/features/eza:1": {} +} +``` + +## Options + +| Options Id | Description | Type | Default Value | +|-----|-----|-----|-----| +| version | Select the version to install. | string | latest | diff --git a/src/eza/devcontainer-feature.json b/src/eza/devcontainer-feature.json new file mode 100644 index 000000000..690c13d8b --- /dev/null +++ b/src/eza/devcontainer-feature.json @@ -0,0 +1,20 @@ +{ + "id": "eza", + "version": "1.0.0", + "name": "eza (via GitHub Releases)", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/eza", + "description": "eza is a modern replacement for ls.", + "options": { + "version": { + "default": "latest", + "description": "Select the version to install.", + "proposals": [ + "latest" + ], + "type": "string" + } + }, + "installsAfter": [ + "ghcr.io/devcontainers-extra/features/gh-release" + ] +} diff --git a/src/eza/install.sh b/src/eza/install.sh new file mode 100755 index 000000000..9b348cc10 --- /dev/null +++ b/src/eza/install.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +set -e + +source ./library_scripts.sh + +# nanolayer is a cli utility which keeps container layers as small as possible +# source code: https://github.com/devcontainers-extra/nanolayer +# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, +# and if missing - will download a temporary copy that automatically get deleted at the end +# of the script +ensure_nanolayer nanolayer_location "v0.5.6" + +# Example nanolayer installation via devcontainer-feature +$nanolayer_location \ + install \ + devcontainer-feature \ + "ghcr.io/devcontainers-extra/features/gh-release:1" \ + --option repo='eza-community/eza' --option binaryNames='eza' --option version="$VERSION" \ + --option assetRegex='.*(\.tar\.gz)$' + +echo 'Done!' diff --git a/src/eza/library_scripts.sh b/src/eza/library_scripts.sh new file mode 100644 index 000000000..f6d0760d7 --- /dev/null +++ b/src/eza/library_scripts.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash + +clean_download() { + # The purpose of this function is to download a file with minimal impact on container layer size + # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a + # temporary manner, and making sure to + # 1. uninstall the downloader at the return of the function + # 2. revert back any changes to the package installer database/cache (for example apt-get lists) + # The above steps will minimize the leftovers being created while installing the downloader + # Supported distros: + # debian/ubuntu/alpine + + url=$1 + output_location=$2 + tempdir=$(mktemp -d) + downloader_installed="" + + function _apt_get_install() { + tempdir=$1 + + # copy current state of apt list - in order to revert back later (minimize contianer layer size) + cp -p -R /var/lib/apt/lists $tempdir + apt-get update -y + apt-get -y install --no-install-recommends wget ca-certificates + } + + function _apt_get_cleanup() { + tempdir=$1 + + echo "removing wget" + apt-get -y purge wget --auto-remove + + echo "revert back apt lists" + rm -rf /var/lib/apt/lists/* + rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists + } + + function _apk_install() { + tempdir=$1 + # copy current state of apk cache - in order to revert back later (minimize contianer layer size) + cp -p -R /var/cache/apk $tempdir + + apk add --no-cache wget + } + + function _apk_cleanup() { + tempdir=$1 + + echo "removing wget" + apk del wget + } + # try to use either wget or curl if one of them already installer + if type curl >/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + # in case none of them is installed, install wget temporarly + if [ -z $downloader ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_install $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_install $tempdir + else + echo "distro not supported" + exit 1 + fi + downloader="wget" + downloader_installed="true" + fi + + if [ $downloader = "wget" ]; then + wget -q $url -O $output_location + else + curl -sfL $url -o $output_location + fi + + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi + +} + +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + # normalize version + if ! [[ $required_version == v* ]]; then + required_version=v$required_version + fi + + local nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ]; then + nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" + fi + + # make sure its of the required version + if ! [[ -z "${nanolayer_location}" ]]; then + local current_version + current_version=$($nanolayer_location --version) + if ! [[ $current_version == v* ]]; then + current_version=v$current_version + fi + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [[ -z "${nanolayer_location}" ]]; then + + if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up() { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + if [ -x "/sbin/apk" ]; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + nanolayer_location=$tmp_dir/nanolayer + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + declare -g ${variable_name}=$nanolayer_location + +} diff --git a/src/fd/devcontainer-feature.json b/src/fd/devcontainer-feature.json index a1e4979db..39583adb5 100644 --- a/src/fd/devcontainer-feature.json +++ b/src/fd/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "fd", - "version": "1.0.14", + "version": "1.0.15", "name": "fd (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/fd", "description": "fd is a simple, fast and user-friendly alternative to 'find'.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/ffmpeg-apt-get/devcontainer-feature.json b/src/ffmpeg-apt-get/devcontainer-feature.json index fc7f7b57b..ac5895d04 100644 --- a/src/ffmpeg-apt-get/devcontainer-feature.json +++ b/src/ffmpeg-apt-get/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ffmpeg-apt-get", - "version": "1.0.16", + "version": "1.0.17", "name": "FFmpeg (via apt-get)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ffmpeg-apt-get", "description": "FFmpeg is the leading multimedia framework, able to decode, encode, transcode, mux, demux, stream, filter and play pretty much anything that humans and machines have created. It supports the most obscure ancient formats up to the cutting edge. No matter if they were designed by some standards committee, the community or a corporation. It is also highly portable: FFmpeg compiles, runs, and passes our testing infrastructure FATE across Linux, Mac OS X, Microsoft Windows, the BSDs, Solaris, etc. under a wide variety of build environments, machine architectures, and configurations.", @@ -8,4 +8,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/apt-get-packages" ] -} \ No newline at end of file +} diff --git a/src/firebase-cli/devcontainer-feature.json b/src/firebase-cli/devcontainer-feature.json index 18be4db00..fdc2afdb6 100644 --- a/src/firebase-cli/devcontainer-feature.json +++ b/src/firebase-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "firebase-cli", - "version": "2.0.15", + "version": "2.0.16", "name": "Firebase CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/firebase-cli", "description": "The Firebase CLI (GitHub) provides a variety of tools for managing, viewing, and deploying to Firebase projects.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/fish-apt-get/devcontainer-feature.json b/src/fish-apt-get/devcontainer-feature.json index 0e66a42d1..a5f643109 100644 --- a/src/fish-apt-get/devcontainer-feature.json +++ b/src/fish-apt-get/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "fish-apt-get", - "version": "1.0.4", + "version": "1.0.5", "name": "fish (via apt-get)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/fish-apt-get", "description": "fish is a smart and user-friendly command line shell for macOS, Linux, and the rest of the family. fish includes features like syntax highlighting, autosuggest-as-you-type, and fancy tab completions that just work, with no configuration required.", @@ -8,4 +8,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/apt-get-packages" ] -} \ No newline at end of file +} diff --git a/src/fkill/devcontainer-feature.json b/src/fkill/devcontainer-feature.json index 71cc627fa..57a140bfe 100644 --- a/src/fkill/devcontainer-feature.json +++ b/src/fkill/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "fkill", - "version": "2.0.15", + "version": "2.0.16", "name": "fkill (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/fkill", "description": "fkill fabulously kill processes. Cross-platform.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/flake8/devcontainer-feature.json b/src/flake8/devcontainer-feature.json index 6ba6fb9d2..aced7ee2a 100644 --- a/src/flake8/devcontainer-feature.json +++ b/src/flake8/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "flake8", - "version": "2.0.17", + "version": "2.0.18", "name": "Flake8 (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/flake8", "description": "Flake8 is a python tool that glues together pycodestyle, pyflakes, mccabe, and third-party plugins.", @@ -27,4 +27,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/flink-sdkman/devcontainer-feature.json b/src/flink-sdkman/devcontainer-feature.json index 3180f9ee2..07be00756 100644 --- a/src/flink-sdkman/devcontainer-feature.json +++ b/src/flink-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "flink-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "Flink (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/flink-sdkman", "description": "Apache Flink is an open-source, unified stream-processing and batch-processing\nframework.It's a distributed processing engine for stateful computations over\nunbounded and bounded data streams.It has been designed to run in all common\ncluster environments, perform computations at in-memory speed and at any scale.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/flit/devcontainer-feature.json b/src/flit/devcontainer-feature.json index c3791ce7f..c6f38ebbf 100644 --- a/src/flit/devcontainer-feature.json +++ b/src/flit/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "flit", - "version": "2.0.17", + "version": "2.0.18", "name": "Flit (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/flit", "description": "Flit is a simple way to put Python packages and modules on PyPI.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/former2-cli/devcontainer-feature.json b/src/former2-cli/devcontainer-feature.json index 3d4c4111e..327576c94 100644 --- a/src/former2-cli/devcontainer-feature.json +++ b/src/former2-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "former2-cli", - "version": "1.0.2", + "version": "1.0.3", "name": "Former2 CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/former2-cli", "description": "The Former2 CLI allows you to use the former2.com tool directly from your command line.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/fossil-apt-get/devcontainer-feature.json b/src/fossil-apt-get/devcontainer-feature.json index 674ee9d51..4943c7e63 100644 --- a/src/fossil-apt-get/devcontainer-feature.json +++ b/src/fossil-apt-get/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "fossil-apt-get", - "version": "1.0.16", + "version": "1.0.17", "name": "Fossil (via apt-get)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/fossil-apt-get", "description": "Fossil is a simple, high-reliability, distributed software configuration management system. It is capable of performing distributed version control, bug tracking, wiki services, and blogging.", @@ -8,4 +8,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/apt-get-packages" ] -} \ No newline at end of file +} diff --git a/src/fossil-homebrew/devcontainer-feature.json b/src/fossil-homebrew/devcontainer-feature.json index 0f63e090d..c8805884c 100644 --- a/src/fossil-homebrew/devcontainer-feature.json +++ b/src/fossil-homebrew/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "fossil-homebrew", - "version": "1.0.20", + "version": "1.0.21", "name": "Fossil (via Homebrew)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/fossil-homebrew", "description": "Fossil is a simple, high-reliability, distributed software configuration management system. It is capable of performing distributed version control, bug tracking, wiki services, and blogging.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/homebrew-package" ] -} \ No newline at end of file +} diff --git a/src/fulcio/devcontainer-feature.json b/src/fulcio/devcontainer-feature.json index 2fd2832b2..601d40aa8 100644 --- a/src/fulcio/devcontainer-feature.json +++ b/src/fulcio/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "fulcio", - "version": "1.0.9", + "version": "1.0.10", "name": "Fulcio (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/fulcio", "description": "Fulcio is a free-to-use certificate authority for issuing code signing certificates for an OpenID Connect (OIDC) identity, such as email address.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/fzf/devcontainer-feature.json b/src/fzf/devcontainer-feature.json index 3e460d9a4..f736d0e5c 100644 --- a/src/fzf/devcontainer-feature.json +++ b/src/fzf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "fzf", - "version": "1.0.14", + "version": "1.0.15", "name": "fzf (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/fzf", "description": "fzf is a general-purpose command-line fuzzy finder.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/gaiden-sdkman/devcontainer-feature.json b/src/gaiden-sdkman/devcontainer-feature.json index 60b3b7529..de2d6860c 100644 --- a/src/gaiden-sdkman/devcontainer-feature.json +++ b/src/gaiden-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "gaiden-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "Gaiden (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/gaiden-sdkman", "description": "Gaiden is a tool that makes it easy to create documentation with Markdown.", @@ -44,4 +44,4 @@ "containerEnv": { "JDK_JAVA_OPTIONS": "--add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.time=ALL-UNNAMED" } -} \ No newline at end of file +} diff --git a/src/ganache/devcontainer-feature.json b/src/ganache/devcontainer-feature.json index c4ee510a5..3c6c76e2f 100644 --- a/src/ganache/devcontainer-feature.json +++ b/src/ganache/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ganache", - "version": "1.0.2", + "version": "1.0.3", "name": "Ganache (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ganache", "description": "Ganache is an Ethereum simulator that makes developing Ethereum applications faster, easier, and safer. It includes all popular RPC functions and features (like events) and can be run deterministically to make development a breeze.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/gdbgui/devcontainer-feature.json b/src/gdbgui/devcontainer-feature.json index b5e56c0cf..59be9076e 100644 --- a/src/gdbgui/devcontainer-feature.json +++ b/src/gdbgui/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "gdbgui", - "version": "2.0.17", + "version": "2.0.18", "name": "gdbgui (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/gdbgui", "description": "gdbgui is a browser-based frontend to gdb (gnu debugger).", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/gh-cli/devcontainer-feature.json b/src/gh-cli/devcontainer-feature.json index 1fde748b7..cc7d62078 100644 --- a/src/gh-cli/devcontainer-feature.json +++ b/src/gh-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "gh-cli", - "version": "1.0.12", + "version": "1.0.13", "name": "GitHub CLI (via GitHub Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/gh-cli", "description": "GitHub CLI is a command-line interface to GitHub for use in your terminal or your scripts.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/gh-release/devcontainer-feature.json b/src/gh-release/devcontainer-feature.json index 16d0e986b..eb79edb2c 100644 --- a/src/gh-release/devcontainer-feature.json +++ b/src/gh-release/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "gh-release", - "version": "1.0.25", + "version": "1.0.26", "name": "Github Release", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/gh-release", "description": "Github Release feature will download, extract and add to path a release binary from a given repo", @@ -77,4 +77,4 @@ } }, "installsAfter": [] -} \ No newline at end of file +} diff --git a/src/git-lfs/devcontainer-feature.json b/src/git-lfs/devcontainer-feature.json index 144240907..cb1ee0b04 100644 --- a/src/git-lfs/devcontainer-feature.json +++ b/src/git-lfs/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "git-lfs", - "version": "1.0.2", + "version": "1.0.3", "name": "Git LFS (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/git-lfs", "description": "Git LFS is a command line extension and specification for managing large files with Git.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/gitmux/devcontainer-feature.json b/src/gitmux/devcontainer-feature.json index f4ffc3bcd..89930995a 100644 --- a/src/gitmux/devcontainer-feature.json +++ b/src/gitmux/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "gitmux", - "version": "1.0.9", + "version": "1.0.10", "name": "Gitmux (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/gitmux", "description": "Gitmux shows git status in your tmux status bar.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/gitomatic/devcontainer-feature.json b/src/gitomatic/devcontainer-feature.json index 1639835fb..a6b46fd11 100644 --- a/src/gitomatic/devcontainer-feature.json +++ b/src/gitomatic/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "gitomatic", - "version": "1.0.14", + "version": "1.0.15", "name": "git-o-matic (gitomatic) (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/gitomatic", "description": "gitomatic is a tool to monitor git repositories and automatically pull & push changes.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/gitsign-credential-cache/devcontainer-feature.json b/src/gitsign-credential-cache/devcontainer-feature.json index c9355bc1e..a3a13c7db 100644 --- a/src/gitsign-credential-cache/devcontainer-feature.json +++ b/src/gitsign-credential-cache/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "gitsign-credential-cache", - "version": "1.0.9", + "version": "1.0.10", "name": "gitsign-credential-cache (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/gitsign-credential-cache", "description": "gitsign-credential-cache is a optional helper binary that allows users to cache signing credentials.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/gitsign/devcontainer-feature.json b/src/gitsign/devcontainer-feature.json index cd42c9512..c129d63cd 100644 --- a/src/gitsign/devcontainer-feature.json +++ b/src/gitsign/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "gitsign", - "version": "1.0.9", + "version": "1.0.10", "name": "Gitsign (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/gitsign", "description": "Gitsign implements keyless Sigstore to sign Git commits with a valid OpenID Connect identity.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/gitty/devcontainer-feature.json b/src/gitty/devcontainer-feature.json index b51431b7e..c10cd1e46 100644 --- a/src/gitty/devcontainer-feature.json +++ b/src/gitty/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "gitty", - "version": "1.0.14", + "version": "1.0.15", "name": "gitty (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/gitty", "description": "gitty is a smart little CLI helper for git projects, that shows you all the relevant issues, pull requests and changes at a quick glance, right on the command-line.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/glances/devcontainer-feature.json b/src/glances/devcontainer-feature.json index bbd4ad3d6..2b0b362d6 100644 --- a/src/glances/devcontainer-feature.json +++ b/src/glances/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "glances", - "version": "2.0.17", + "version": "2.0.18", "name": "Glances (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/glances", "description": "Glances is a cross-platform monitoring tool which aims to present a large amount of monitoring information through a curses or Web based interface.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/go-task/devcontainer-feature.json b/src/go-task/devcontainer-feature.json index ad59ea4b5..39ca4a1ab 100644 --- a/src/go-task/devcontainer-feature.json +++ b/src/go-task/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "go-task", - "version": "1.0.5", + "version": "1.0.6", "name": "Task (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/go-task", "description": "Task is a task runner / build tool that aims to be simpler and easier to use than, for example, GNU Make.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/gofumpt/devcontainer-feature.json b/src/gofumpt/devcontainer-feature.json new file mode 100644 index 000000000..b7ab1991a --- /dev/null +++ b/src/gofumpt/devcontainer-feature.json @@ -0,0 +1,18 @@ +{ + "id": "gofumpt", + "version": "1.0.0", + "name": "gofumpt (via Github Releases)", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/gofumpt", + "description": "A stricter gofmt", + "options": { + "version": { + "default": "latest", + "description": "Select the version to install.", + "proposals": [ + "latest" + ], + "type": "string" + } + }, + "installsAfter": [] +} diff --git a/src/gofumpt/install.sh b/src/gofumpt/install.sh new file mode 100755 index 000000000..757067be9 --- /dev/null +++ b/src/gofumpt/install.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +set -e + +source ./library_scripts.sh + +# nanolayer is a cli utility which keeps container layers as small as possible +# source code: https://github.com/devcontainers-extra/nanolayer +# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, +# and if missing - will download a temporary copy that automatically get deleted at the end +# of the script +ensure_nanolayer nanolayer_location "v0.5.6" + +# Example nanolayer installation via devcontainer-feature +$nanolayer_location \ + install \ + devcontainer-feature \ + "ghcr.io/devcontainers-extra/features/gh-release:1" \ + --option repo='mvdan/gofumpt' --option binaryNames='gofumpt' --option version="$VERSION" + +echo 'Done!' diff --git a/src/gofumpt/library_scripts.sh b/src/gofumpt/library_scripts.sh new file mode 100644 index 000000000..f6d0760d7 --- /dev/null +++ b/src/gofumpt/library_scripts.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash + +clean_download() { + # The purpose of this function is to download a file with minimal impact on container layer size + # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a + # temporary manner, and making sure to + # 1. uninstall the downloader at the return of the function + # 2. revert back any changes to the package installer database/cache (for example apt-get lists) + # The above steps will minimize the leftovers being created while installing the downloader + # Supported distros: + # debian/ubuntu/alpine + + url=$1 + output_location=$2 + tempdir=$(mktemp -d) + downloader_installed="" + + function _apt_get_install() { + tempdir=$1 + + # copy current state of apt list - in order to revert back later (minimize contianer layer size) + cp -p -R /var/lib/apt/lists $tempdir + apt-get update -y + apt-get -y install --no-install-recommends wget ca-certificates + } + + function _apt_get_cleanup() { + tempdir=$1 + + echo "removing wget" + apt-get -y purge wget --auto-remove + + echo "revert back apt lists" + rm -rf /var/lib/apt/lists/* + rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists + } + + function _apk_install() { + tempdir=$1 + # copy current state of apk cache - in order to revert back later (minimize contianer layer size) + cp -p -R /var/cache/apk $tempdir + + apk add --no-cache wget + } + + function _apk_cleanup() { + tempdir=$1 + + echo "removing wget" + apk del wget + } + # try to use either wget or curl if one of them already installer + if type curl >/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + # in case none of them is installed, install wget temporarly + if [ -z $downloader ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_install $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_install $tempdir + else + echo "distro not supported" + exit 1 + fi + downloader="wget" + downloader_installed="true" + fi + + if [ $downloader = "wget" ]; then + wget -q $url -O $output_location + else + curl -sfL $url -o $output_location + fi + + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi + +} + +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + # normalize version + if ! [[ $required_version == v* ]]; then + required_version=v$required_version + fi + + local nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ]; then + nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" + fi + + # make sure its of the required version + if ! [[ -z "${nanolayer_location}" ]]; then + local current_version + current_version=$($nanolayer_location --version) + if ! [[ $current_version == v* ]]; then + current_version=v$current_version + fi + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [[ -z "${nanolayer_location}" ]]; then + + if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up() { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + if [ -x "/sbin/apk" ]; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + nanolayer_location=$tmp_dir/nanolayer + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + declare -g ${variable_name}=$nanolayer_location + +} diff --git a/src/golangci-lint/devcontainer-feature.json b/src/golangci-lint/devcontainer-feature.json new file mode 100644 index 000000000..da686f2d9 --- /dev/null +++ b/src/golangci-lint/devcontainer-feature.json @@ -0,0 +1,18 @@ +{ + "id": "golangci-lint", + "version": "1.0.0", + "name": "golangci-lint (via Github Releases)", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/golangci-lint", + "description": "Fast linters runner for Go", + "options": { + "version": { + "default": "latest", + "description": "Select the version to install.", + "proposals": [ + "latest" + ], + "type": "string" + } + }, + "installsAfter": [] +} diff --git a/src/golangci-lint/install.sh b/src/golangci-lint/install.sh new file mode 100755 index 000000000..e88801f01 --- /dev/null +++ b/src/golangci-lint/install.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +set -e + +source ./library_scripts.sh + +# nanolayer is a cli utility which keeps container layers as small as possible +# source code: https://github.com/devcontainers-extra/nanolayer +# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, +# and if missing - will download a temporary copy that automatically get deleted at the end +# of the script +ensure_nanolayer nanolayer_location "v0.5.6" + +# Example nanolayer installation via devcontainer-feature +$nanolayer_location \ + install \ + devcontainer-feature \ + "ghcr.io/devcontainers-extra/features/gh-release:1" \ + --option repo='golangci/golangci-lint' --option binaryNames='golangci-lint' --option version="$VERSION" + +echo 'Done!' diff --git a/src/golangci-lint/library_scripts.sh b/src/golangci-lint/library_scripts.sh new file mode 100644 index 000000000..f6d0760d7 --- /dev/null +++ b/src/golangci-lint/library_scripts.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash + +clean_download() { + # The purpose of this function is to download a file with minimal impact on container layer size + # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a + # temporary manner, and making sure to + # 1. uninstall the downloader at the return of the function + # 2. revert back any changes to the package installer database/cache (for example apt-get lists) + # The above steps will minimize the leftovers being created while installing the downloader + # Supported distros: + # debian/ubuntu/alpine + + url=$1 + output_location=$2 + tempdir=$(mktemp -d) + downloader_installed="" + + function _apt_get_install() { + tempdir=$1 + + # copy current state of apt list - in order to revert back later (minimize contianer layer size) + cp -p -R /var/lib/apt/lists $tempdir + apt-get update -y + apt-get -y install --no-install-recommends wget ca-certificates + } + + function _apt_get_cleanup() { + tempdir=$1 + + echo "removing wget" + apt-get -y purge wget --auto-remove + + echo "revert back apt lists" + rm -rf /var/lib/apt/lists/* + rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists + } + + function _apk_install() { + tempdir=$1 + # copy current state of apk cache - in order to revert back later (minimize contianer layer size) + cp -p -R /var/cache/apk $tempdir + + apk add --no-cache wget + } + + function _apk_cleanup() { + tempdir=$1 + + echo "removing wget" + apk del wget + } + # try to use either wget or curl if one of them already installer + if type curl >/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + # in case none of them is installed, install wget temporarly + if [ -z $downloader ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_install $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_install $tempdir + else + echo "distro not supported" + exit 1 + fi + downloader="wget" + downloader_installed="true" + fi + + if [ $downloader = "wget" ]; then + wget -q $url -O $output_location + else + curl -sfL $url -o $output_location + fi + + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi + +} + +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + # normalize version + if ! [[ $required_version == v* ]]; then + required_version=v$required_version + fi + + local nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ]; then + nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" + fi + + # make sure its of the required version + if ! [[ -z "${nanolayer_location}" ]]; then + local current_version + current_version=$($nanolayer_location --version) + if ! [[ $current_version == v* ]]; then + current_version=v$current_version + fi + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [[ -z "${nanolayer_location}" ]]; then + + if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up() { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + if [ -x "/sbin/apk" ]; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + nanolayer_location=$tmp_dir/nanolayer + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + declare -g ${variable_name}=$nanolayer_location + +} diff --git a/src/graalvm-asdf/devcontainer-feature.json b/src/graalvm-asdf/devcontainer-feature.json index e29e08b7f..439f47a23 100644 --- a/src/graalvm-asdf/devcontainer-feature.json +++ b/src/graalvm-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "graalvm-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "GraalVM (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/graalvm-asdf", "description": "GraalVM is a high-performance JDK designed to accelerate Java application performance while consuming fewer resources.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/gradle-sdkman/devcontainer-feature.json b/src/gradle-sdkman/devcontainer-feature.json index e389c5a82..05a736fab 100644 --- a/src/gradle-sdkman/devcontainer-feature.json +++ b/src/gradle-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "gradle-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "Gradle (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/gradle-sdkman", "description": "Gradle is a build automation tool that builds upon the concepts of Apache Ant\nand Apache Maven and introduces a Groovy-based domain-specific language (DSL)\ninstead of the more traditional XML form of declaring the project configuration.\nGradle uses a directed acyclic graph (DAG) to determine the order in which tasks\ncan be run.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/gradleprofiler-sdkman/devcontainer-feature.json b/src/gradleprofiler-sdkman/devcontainer-feature.json index 71bdfabff..bbd1c2ccb 100644 --- a/src/gradleprofiler-sdkman/devcontainer-feature.json +++ b/src/gradleprofiler-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "gradleprofiler-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "Gradle profiler (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/gradleprofiler-sdkman", "description": "A tool for gathering profiling and benchmarking information for Gradle builds", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/grails-sdkman/devcontainer-feature.json b/src/grails-sdkman/devcontainer-feature.json index c4f0832ce..8baff6e5f 100644 --- a/src/grails-sdkman/devcontainer-feature.json +++ b/src/grails-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "grails-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "Grails (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/grails-sdkman", "description": "Grails is a powerful web framework, for the Java platform aimed at multiplying\ndevelopers productivity thanks to a Convention-over-Configuration, sensible\ndefaults and opinionated APIs. It integrates smoothly with the JVM, allowing you\nto be immediately productive whilst providing powerful features, including\nintegrated ORM, Domain-Specific Languages, runtime and compile-time\nmeta-programming and Asynchronous programming.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/graphite-cli/README.md b/src/graphite-cli/README.md new file mode 100644 index 000000000..b026de67f --- /dev/null +++ b/src/graphite-cli/README.md @@ -0,0 +1,24 @@ + +# Graphite CLI (via npm) (graphite-cli) + +The Graphite command-line interface (CLI) is the CLI utility for working with stacked branches in graphite. + +## Example Usage + +```json +"features": { + "ghcr.io/devcontainers-extra/features/graphite-cli:1": {} +} +``` + +## Options + +| Options Id | Description | Type | Default Value | +|-----|-----|-----|-----| +| version | Select the version of Graphite CLI to install. | string | stsable | + + + +--- + +_Note: This file was auto-generated from the [devcontainer-feature.json](devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/graphite-cli/devcontainer-feature.json b/src/graphite-cli/devcontainer-feature.json new file mode 100644 index 000000000..bbc9af2a6 --- /dev/null +++ b/src/graphite-cli/devcontainer-feature.json @@ -0,0 +1,28 @@ +{ + "id": "graphite-cli", + "version": "1.0.0", + "name": "Graphite.dev CLI (via npm)", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/graphite-cli", + "description": "The Graphite.dev command-line interface (CLI) is the CLI utility for working with stacked branches in graphite.", + "options": { + "version": { + "default": "stable", + "description": "Select the version to install.", + "proposals": [ + "stable" + ], + "type": "string" + } + }, + "customizations": { + "vscode": { + "extensions": [ + "graphite.gti-vscode" + ] + } + }, + "installsAfter": [ + "ghcr.io/devcontainers-extra/features/npm-package", + "ghcr.io/devcontainers/features/node" + ] +} \ No newline at end of file diff --git a/src/graphite-cli/install.sh b/src/graphite-cli/install.sh new file mode 100755 index 000000000..753a89e22 --- /dev/null +++ b/src/graphite-cli/install.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +set -e + +source ./library_scripts.sh + +# nanolayer is a cli utility which keeps container layers as small as possible +# source code: https://github.com/devcontainers-extra/nanolayer +# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, +# and if missing - will download a temporary copy that automatically get deleted at the end +# of the script +ensure_nanolayer nanolayer_location "v0.5.6" + +# Example nanolayer installation via devcontainer-feature +$nanolayer_location \ + install \ + devcontainer-feature \ + "ghcr.io/devcontainers-extra/features/npm-package:1" \ + --option package='@withgraphite/graphite-cli' --option version="$VERSION" + +echo 'Done!' diff --git a/src/graphite-cli/library_scripts.sh b/src/graphite-cli/library_scripts.sh new file mode 100644 index 000000000..f6d0760d7 --- /dev/null +++ b/src/graphite-cli/library_scripts.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash + +clean_download() { + # The purpose of this function is to download a file with minimal impact on container layer size + # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a + # temporary manner, and making sure to + # 1. uninstall the downloader at the return of the function + # 2. revert back any changes to the package installer database/cache (for example apt-get lists) + # The above steps will minimize the leftovers being created while installing the downloader + # Supported distros: + # debian/ubuntu/alpine + + url=$1 + output_location=$2 + tempdir=$(mktemp -d) + downloader_installed="" + + function _apt_get_install() { + tempdir=$1 + + # copy current state of apt list - in order to revert back later (minimize contianer layer size) + cp -p -R /var/lib/apt/lists $tempdir + apt-get update -y + apt-get -y install --no-install-recommends wget ca-certificates + } + + function _apt_get_cleanup() { + tempdir=$1 + + echo "removing wget" + apt-get -y purge wget --auto-remove + + echo "revert back apt lists" + rm -rf /var/lib/apt/lists/* + rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists + } + + function _apk_install() { + tempdir=$1 + # copy current state of apk cache - in order to revert back later (minimize contianer layer size) + cp -p -R /var/cache/apk $tempdir + + apk add --no-cache wget + } + + function _apk_cleanup() { + tempdir=$1 + + echo "removing wget" + apk del wget + } + # try to use either wget or curl if one of them already installer + if type curl >/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + # in case none of them is installed, install wget temporarly + if [ -z $downloader ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_install $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_install $tempdir + else + echo "distro not supported" + exit 1 + fi + downloader="wget" + downloader_installed="true" + fi + + if [ $downloader = "wget" ]; then + wget -q $url -O $output_location + else + curl -sfL $url -o $output_location + fi + + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi + +} + +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + # normalize version + if ! [[ $required_version == v* ]]; then + required_version=v$required_version + fi + + local nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ]; then + nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" + fi + + # make sure its of the required version + if ! [[ -z "${nanolayer_location}" ]]; then + local current_version + current_version=$($nanolayer_location --version) + if ! [[ $current_version == v* ]]; then + current_version=v$current_version + fi + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [[ -z "${nanolayer_location}" ]]; then + + if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up() { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + if [ -x "/sbin/apk" ]; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + nanolayer_location=$tmp_dir/nanolayer + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + declare -g ${variable_name}=$nanolayer_location + +} diff --git a/src/graphite-exporter/devcontainer-feature.json b/src/graphite-exporter/devcontainer-feature.json index afb45195d..a4d07f340 100644 --- a/src/graphite-exporter/devcontainer-feature.json +++ b/src/graphite-exporter/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "graphite-exporter", - "version": "1.0.2", + "version": "1.0.3", "name": "Prometheus Graphite Exporter (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/graphite-exporter", "description": "An exporter for metrics exported in the Graphite plaintext protocol.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/groovy-sdkman/devcontainer-feature.json b/src/groovy-sdkman/devcontainer-feature.json index fff3980d4..6f0ae7a6c 100644 --- a/src/groovy-sdkman/devcontainer-feature.json +++ b/src/groovy-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "groovy-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "Groovy (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/groovy-sdkman", "description": "Groovy is a powerful, optionally typed and dynamic language, with static-typing\nand static compilation capabilities, for the Java platform aimed at multiplying\ndevelopers' productivity thanks to a concise, familiar and easy to learn syntax.\nIt integrates smoothly with any Java program, and immediately delivers to your\napplication powerful features, including scripting capabilities, Domain-Specific\nLanguage authoring, runtime and compile-time meta-programming and functional\nprogramming.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/groovyserv-sdkman/devcontainer-feature.json b/src/groovyserv-sdkman/devcontainer-feature.json index f7224657d..1aa0230c4 100644 --- a/src/groovyserv-sdkman/devcontainer-feature.json +++ b/src/groovyserv-sdkman/devcontainer-feature.json @@ -1,9 +1,9 @@ { "id": "groovyserv-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "GroovyServ (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/groovyserv-sdkman", - "description": "GroovyServ reduces startup time of the JVM for runnning Groovy significantly. It\ndepends on your environments, but in most cases, it\u2019s 10 to 20 times faster than\nregular Groovy.", + "description": "GroovyServ reduces startup time of the JVM for runnning Groovy significantly. It\ndepends on your environments, but in most cases, it’s 10 to 20 times faster than\nregular Groovy.", "options": { "version": { "default": "latest", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/grpcurl-asdf/devcontainer-feature.json b/src/grpcurl-asdf/devcontainer-feature.json index e549e593a..522862930 100644 --- a/src/grpcurl-asdf/devcontainer-feature.json +++ b/src/grpcurl-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "grpcurl-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "gRPCurl (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/grpcurl-asdf", "description": "gRPCurl is a command-line tool that lets you interact with gRPC servers.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/grype/devcontainer-feature.json b/src/grype/devcontainer-feature.json index 79f6bc4cc..f79124de9 100644 --- a/src/grype/devcontainer-feature.json +++ b/src/grype/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "grype", - "version": "1.0.9", + "version": "1.0.10", "name": "Grype (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/grype", "description": "Grype is a vulnerability scanner for container images and filesystems.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/gulp-cli/devcontainer-feature.json b/src/gulp-cli/devcontainer-feature.json index 7a566acab..c509c72ac 100644 --- a/src/gulp-cli/devcontainer-feature.json +++ b/src/gulp-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "gulp-cli", - "version": "2.0.15", + "version": "2.0.16", "name": "Gulp CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/gulp-cli", "description": "Gulp CLI is Command Line Utility for Gulp", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/hadoop-sdkman/devcontainer-feature.json b/src/hadoop-sdkman/devcontainer-feature.json index a642bb0ab..6c4b7a77a 100644 --- a/src/hadoop-sdkman/devcontainer-feature.json +++ b/src/hadoop-sdkman/devcontainer-feature.json @@ -1,9 +1,9 @@ { "id": "hadoop-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "hadoop (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/hadoop-sdkman", - "description": "Apache\u2122 Hadoop\u00ae project develops open-source software for reliable, scalable,\ndistributed computing.It's a framework that allows for the distributed\nprocessing of large data sets across clusters of computersusing simple\nprogramming models.It is designed to scale up from single servers to thousands\nof machines, each offering local computation and storage.", + "description": "Apache™ Hadoop® project develops open-source software for reliable, scalable,\ndistributed computing.It's a framework that allows for the distributed\nprocessing of large data sets across clusters of computersusing simple\nprogramming models.It is designed to scale up from single servers to thousands\nof machines, each offering local computation and storage.", "options": { "version": { "default": "latest", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/haskell/devcontainer-feature.json b/src/haskell/devcontainer-feature.json index 50c3e3139..856b1e6ff 100644 --- a/src/haskell/devcontainer-feature.json +++ b/src/haskell/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "Haskell (via ghcup)", "id": "haskell", - "version": "2.2.2", + "version": "2.2.3", "description": "Installs Haskell. An advanced, purely functional programming language", "documentationURL": "https://github.com/devcontainers-extra/features/tree/main/src/haskell", "options": { diff --git a/src/hatch/devcontainer-feature.json b/src/hatch/devcontainer-feature.json index e17e313bc..ec5488805 100644 --- a/src/hatch/devcontainer-feature.json +++ b/src/hatch/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "hatch", - "version": "2.0.17", + "version": "2.0.18", "name": "Hatch (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/hatch", "description": "Hatch is a modern, extensible Python project manager.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/haxe-asdf/devcontainer-feature.json b/src/haxe-asdf/devcontainer-feature.json index 7a2047097..1234c0fcb 100644 --- a/src/haxe-asdf/devcontainer-feature.json +++ b/src/haxe-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "haxe-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "Haxe (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/haxe-asdf", "description": "Haxe is an open source high-level cross-platform programming language and compiler.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/heroku-cli/devcontainer-feature.json b/src/heroku-cli/devcontainer-feature.json index c63257f1a..4c7b3abab 100644 --- a/src/heroku-cli/devcontainer-feature.json +++ b/src/heroku-cli/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "Heroku CLI (via cli-assets.heroku.com)", "id": "heroku-cli", - "version": "1.0.3", + "version": "1.0.5", "description": "Heroku CLI allows you to interact with the Heroku API via the command line (version 8 and above)", "documentationURL": "https://github.com/devcontainers-extra/features/tree/main/src/heroku-cli", "options": { @@ -15,4 +15,4 @@ "description": "Select the Heroku CLI version you would like to install" } } -} \ No newline at end of file +} diff --git a/src/heroku-cli/install.sh b/src/heroku-cli/install.sh index 7e715f56f..9700864f1 100755 --- a/src/heroku-cli/install.sh +++ b/src/heroku-cli/install.sh @@ -20,10 +20,10 @@ rm -rf /var/lib/apt/lists/* ARCH="$(uname -m)" if [ "$ARCH" == "x86_64" ]; then ARCH=x64 +elif [[ "$ARCH" == "aarch64" || "$ARCH" == "arm64" ]]; then + ARCH=arm64 elif [[ "$ARCH" == aarch* ]]; then ARCH=arm -elif [[ "$ARCH" == "arm64" ]]; then - ARCH=arm64 else echo -e "unsupported arch: $ARCH" exit 1 diff --git a/src/hotel/devcontainer-feature.json b/src/hotel/devcontainer-feature.json index 8a5475b33..1fee5f3da 100644 --- a/src/hotel/devcontainer-feature.json +++ b/src/hotel/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "hotel", - "version": "1.0.3", + "version": "1.0.4", "name": "hotel (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/hotel", "description": "hotel is a simple process manager for developers. Start apps from your browser and access them using local domains.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/how2/devcontainer-feature.json b/src/how2/devcontainer-feature.json index 33088fb1a..a522cacc7 100644 --- a/src/how2/devcontainer-feature.json +++ b/src/how2/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "how2", - "version": "1.0.9", + "version": "1.0.10", "name": "how2 (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/how2", "description": "how2 finds the simplest way to do something in a unix shell. It's like man, but you can query it in natural language. It uses a mix of AI code-completion and StackOverflow search.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/http-server/devcontainer-feature.json b/src/http-server/devcontainer-feature.json index 4e8c34ec2..7b6665d0b 100644 --- a/src/http-server/devcontainer-feature.json +++ b/src/http-server/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "http-server", - "version": "1.0.3", + "version": "1.0.4", "name": "http-server (by http-party) (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/http-server", "description": "http-server is a simple, zero-configuration command-line static HTTP server. It is powerful enough for production usage, but it's simple and hackable enough to be used for testing, local development and learning.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/http4k-sdkman/devcontainer-feature.json b/src/http4k-sdkman/devcontainer-feature.json index 6a7ba5778..ca964da10 100644 --- a/src/http4k-sdkman/devcontainer-feature.json +++ b/src/http4k-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "http4k-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "http4k (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/http4k-sdkman", "description": "http4k is the Functional toolkit for building HTTP applications in Kotlin", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/hyperfine/devcontainer-feature.json b/src/hyperfine/devcontainer-feature.json index 3dcf374e9..aa6a137a2 100644 --- a/src/hyperfine/devcontainer-feature.json +++ b/src/hyperfine/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "hyperfine", - "version": "1.0.14", + "version": "1.0.15", "name": "hyperfine (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/hyperfine", "description": "hyperfine is a command-line benchmarking tool.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/immuadmin-fips/devcontainer-feature.json b/src/immuadmin-fips/devcontainer-feature.json index 355600160..95c081f06 100644 --- a/src/immuadmin-fips/devcontainer-feature.json +++ b/src/immuadmin-fips/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "immuadmin-fips", - "version": "1.0.9", + "version": "1.0.10", "name": "immuadmin (FIPS) (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/immuadmin-fips", "description": "immuadmin is the admin CLI for immudb and immugw. You can install and manage the service installation for both components and get statistics as well as runtime information.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/immuadmin/devcontainer-feature.json b/src/immuadmin/devcontainer-feature.json index 2231df3d8..a7fe998dd 100644 --- a/src/immuadmin/devcontainer-feature.json +++ b/src/immuadmin/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "immuadmin", - "version": "1.0.9", + "version": "1.0.10", "name": "immuadmin (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/immuadmin", "description": "immuadmin is the admin CLI for immudb and immugw. You can install and manage the service installation for both components and get statistics as well as runtime information.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/immuclient-fips/devcontainer-feature.json b/src/immuclient-fips/devcontainer-feature.json index f59afc2ba..767638a9d 100644 --- a/src/immuclient-fips/devcontainer-feature.json +++ b/src/immuclient-fips/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "immuclient-fips", - "version": "1.0.9", + "version": "1.0.10", "name": "immuclient (FIPS) (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/immuclient-fips", "description": "immuclient is a CLI client for immudb - the lightweight, high-speed immutable database for systems and applications.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/immuclient/devcontainer-feature.json b/src/immuclient/devcontainer-feature.json index 9c5023efe..59810f79b 100644 --- a/src/immuclient/devcontainer-feature.json +++ b/src/immuclient/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "immuclient", - "version": "1.0.9", + "version": "1.0.10", "name": "immuclient (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/immuclient", "description": "immuclient is a CLI client for immudb - the lightweight, high-speed immutable database for systems and applications.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/immudb-fips/devcontainer-feature.json b/src/immudb-fips/devcontainer-feature.json index 3a09c52a4..ec0e497f0 100644 --- a/src/immudb-fips/devcontainer-feature.json +++ b/src/immudb-fips/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "immudb-fips", - "version": "1.0.9", + "version": "1.0.10", "name": "immudb (FIPS) (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/immudb-fips", "description": "immudb is an immutable database based on zero trust, SQL and Key-Value, tamperproof, data change history.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/immudb/devcontainer-feature.json b/src/immudb/devcontainer-feature.json index 47437c4fc..5d4b72850 100644 --- a/src/immudb/devcontainer-feature.json +++ b/src/immudb/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "immudb", - "version": "1.0.9", + "version": "1.0.10", "name": "immudb (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/immudb", "description": "immudb is an immutable database based on zero trust, SQL and Key-Value, tamperproof, data change history.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/infisical/README.md b/src/infisical/README.md new file mode 100644 index 000000000..eebb50384 --- /dev/null +++ b/src/infisical/README.md @@ -0,0 +1,27 @@ +# infisical (via Github Releases) (infisical) + +Infisical is an OSS tool for secret management. + +## Example Usage + +```json +"features": { + "ghcr.io/devcontainers-extra/features/infisical:1": {} +} +``` + +## Options + +| Options Id | Description | Type | Default Value | +| ---------- | ------------------------------ | ------ | ------------- | +| version | Select the version to install. | string | latest | + +## Customizations + +### VS Code Extensions + +- `infisical.vscode-infisical` + +--- + +_Note: This file was auto-generated from the [devcontainer-feature.json](devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/infisical/devcontainer-feature.json b/src/infisical/devcontainer-feature.json new file mode 100644 index 000000000..2eab61e83 --- /dev/null +++ b/src/infisical/devcontainer-feature.json @@ -0,0 +1,17 @@ +{ + "id": "infisical", + "version": "1.0.0", + "name": "infisical (via Github Releases)", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/infisical", + "description": "The official Infisical CLI: Inject secrets into applications and manage your Infisical infrastructure.", + "options": { + "version": { + "default": "latest", + "description": "Select the version to install.", + "proposals": ["latest"], + "type": "string" + } + }, + "installsAfter": [] +} + diff --git a/src/infisical/install.sh b/src/infisical/install.sh new file mode 100755 index 000000000..768859afb --- /dev/null +++ b/src/infisical/install.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +set -e + +source ./library_scripts.sh + +# nanolayer is a cli utility which keeps container layers as small as possible +# source code: https://github.com/devcontainers-extra/nanolayer +# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, +# and if missing - will download a temporary copy that automatically get deleted at the end +# of the script +ensure_nanolayer nanolayer_location "v0.5.6" + +# Example nanolayer installation via devcontainer-feature +$nanolayer_location \ + install \ + devcontainer-feature \ + "ghcr.io/devcontainers-extra/features/gh-release:1" \ + --option repo='infisical/cli' --option binaryNames='infisical' --option version="$VERSION" + +echo 'Done!' diff --git a/src/infisical/library_scripts.sh b/src/infisical/library_scripts.sh new file mode 100644 index 000000000..f6d0760d7 --- /dev/null +++ b/src/infisical/library_scripts.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash + +clean_download() { + # The purpose of this function is to download a file with minimal impact on container layer size + # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a + # temporary manner, and making sure to + # 1. uninstall the downloader at the return of the function + # 2. revert back any changes to the package installer database/cache (for example apt-get lists) + # The above steps will minimize the leftovers being created while installing the downloader + # Supported distros: + # debian/ubuntu/alpine + + url=$1 + output_location=$2 + tempdir=$(mktemp -d) + downloader_installed="" + + function _apt_get_install() { + tempdir=$1 + + # copy current state of apt list - in order to revert back later (minimize contianer layer size) + cp -p -R /var/lib/apt/lists $tempdir + apt-get update -y + apt-get -y install --no-install-recommends wget ca-certificates + } + + function _apt_get_cleanup() { + tempdir=$1 + + echo "removing wget" + apt-get -y purge wget --auto-remove + + echo "revert back apt lists" + rm -rf /var/lib/apt/lists/* + rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists + } + + function _apk_install() { + tempdir=$1 + # copy current state of apk cache - in order to revert back later (minimize contianer layer size) + cp -p -R /var/cache/apk $tempdir + + apk add --no-cache wget + } + + function _apk_cleanup() { + tempdir=$1 + + echo "removing wget" + apk del wget + } + # try to use either wget or curl if one of them already installer + if type curl >/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + # in case none of them is installed, install wget temporarly + if [ -z $downloader ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_install $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_install $tempdir + else + echo "distro not supported" + exit 1 + fi + downloader="wget" + downloader_installed="true" + fi + + if [ $downloader = "wget" ]; then + wget -q $url -O $output_location + else + curl -sfL $url -o $output_location + fi + + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi + +} + +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + # normalize version + if ! [[ $required_version == v* ]]; then + required_version=v$required_version + fi + + local nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ]; then + nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" + fi + + # make sure its of the required version + if ! [[ -z "${nanolayer_location}" ]]; then + local current_version + current_version=$($nanolayer_location --version) + if ! [[ $current_version == v* ]]; then + current_version=v$current_version + fi + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [[ -z "${nanolayer_location}" ]]; then + + if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up() { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + if [ -x "/sbin/apk" ]; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + nanolayer_location=$tmp_dir/nanolayer + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + declare -g ${variable_name}=$nanolayer_location + +} diff --git a/src/infracost/devcontainer-feature.json b/src/infracost/devcontainer-feature.json index d1383fc63..36f606286 100644 --- a/src/infracost/devcontainer-feature.json +++ b/src/infracost/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "infracost", - "version": "1.0.5", + "version": "1.0.6", "name": "Infracost (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/infracost", "description": "Infracost shows cloud cost estimates for Terraform. It lets engineers see a cost breakdown and understand costs before making changes, either in the terminal, VS Code or pull requests.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/infrastructor-sdkman/devcontainer-feature.json b/src/infrastructor-sdkman/devcontainer-feature.json index eaf80e2b2..f78d15db2 100644 --- a/src/infrastructor-sdkman/devcontainer-feature.json +++ b/src/infrastructor-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "infrastructor-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "Infrastructor (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/infrastructor-sdkman", "description": "Infrastructor is an open source server provisioning tool written in Groovy", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/invoke/devcontainer-feature.json b/src/invoke/devcontainer-feature.json index 2dcbeb514..d567863ed 100644 --- a/src/invoke/devcontainer-feature.json +++ b/src/invoke/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "invoke", - "version": "1.0.3", + "version": "1.0.4", "name": "Invoke (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/invoke", "description": "Invoke is a Python (2.7 and 3.4+) library for managing shell-oriented subprocesses and organizing executable Python code into CLI-invokable tasks. It draws inspiration from various sources (make/rake, Fabric 1.x, etc) to arrive at a powerful & clean feature set.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/ionic-cli/devcontainer-feature.json b/src/ionic-cli/devcontainer-feature.json index 480a06903..a1ba72af0 100644 --- a/src/ionic-cli/devcontainer-feature.json +++ b/src/ionic-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ionic-cli", - "version": "2.0.15", + "version": "2.0.16", "name": "Ionic CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ionic-cli", "description": "The Ionic command-line interface (CLI) is the go-to tool for developing Ionic apps.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/isort/devcontainer-feature.json b/src/isort/devcontainer-feature.json index 7aac7ad91..928e3f569 100644 --- a/src/isort/devcontainer-feature.json +++ b/src/isort/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "isort", - "version": "2.0.17", + "version": "2.0.18", "name": "isort (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/isort", "description": "isort is a Python utility / library to sort imports alphabetically, and automatically separated into sections and by type.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/jake/devcontainer-feature.json b/src/jake/devcontainer-feature.json index 7f4aa046c..65b94ee75 100644 --- a/src/jake/devcontainer-feature.json +++ b/src/jake/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "jake", - "version": "1.0.4", + "version": "1.0.5", "name": "jake (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/jake", "description": "jake is a tool to check your Python environments for vulnerable Open Source packages with OSS Index or Sonatype Nexus Lifecycle.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/jbake-sdkman/devcontainer-feature.json b/src/jbake-sdkman/devcontainer-feature.json index 29d00f9f2..8f5801323 100644 --- a/src/jbake-sdkman/devcontainer-feature.json +++ b/src/jbake-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "jbake-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "JBake (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/jbake-sdkman", "description": "JBake is a Java based, open source, static site/blog generator for developers\nand designers.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/jbang-sdkman/devcontainer-feature.json b/src/jbang-sdkman/devcontainer-feature.json index f8cded77b..ee74be4cd 100644 --- a/src/jbang-sdkman/devcontainer-feature.json +++ b/src/jbang-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "jbang-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "JBang (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/jbang-sdkman", "description": "JBang makes it easy to use Java for scripting. It lets you use a single file for\ncode and dependency management and allows you to run it directly.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/jenkinsx-cli/devcontainer-feature.json b/src/jenkinsx-cli/devcontainer-feature.json index 922920077..8f75c26d2 100644 --- a/src/jenkinsx-cli/devcontainer-feature.json +++ b/src/jenkinsx-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "jenkinsx-cli", - "version": "1.0.7", + "version": "1.0.8", "name": "Jenkins X CLI (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/jenkinsx-cli", "description": "Jenkins X CLI is the modular command line CLI for Jenkins X 3.x", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/jest/devcontainer-feature.json b/src/jest/devcontainer-feature.json index 8bafcac6b..d2b8974a2 100644 --- a/src/jest/devcontainer-feature.json +++ b/src/jest/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "jest", - "version": "2.0.15", + "version": "2.0.16", "name": "Jest (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/jest", "description": "Jest is a delightful JavaScript Testing Framework with a focus on simplicity", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/jfrog-cli-homebrew/devcontainer-feature.json b/src/jfrog-cli-homebrew/devcontainer-feature.json index a6c74021f..adbaca1e8 100644 --- a/src/jfrog-cli-homebrew/devcontainer-feature.json +++ b/src/jfrog-cli-homebrew/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "jfrog-cli-homebrew", - "version": "1.0.14", + "version": "1.0.15", "name": "JFrog CLI (via Homebrew)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/jfrog-cli-homebrew", "description": "JFrog CLI is a compact and smart client that provides a simple interface that automates access to JFrog products simplifying your automation scripts making them more readable and easier to maintain.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/homebrew-package" ] -} \ No newline at end of file +} diff --git a/src/jfrog-cli-npm/devcontainer-feature.json b/src/jfrog-cli-npm/devcontainer-feature.json index 2daf2d9c9..e401e1590 100644 --- a/src/jfrog-cli-npm/devcontainer-feature.json +++ b/src/jfrog-cli-npm/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "jfrog-cli-npm", - "version": "1.0.9", + "version": "1.0.10", "name": "JFrog CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/jfrog-cli-npm", "description": "JFrog CLI is a compact and smart client that provides a simple interface that automates access to JFrog products simplifying your automation scripts making them more readable and easier to maintain.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/jfrog-cli/devcontainer-feature.json b/src/jfrog-cli/devcontainer-feature.json index 29ce691e8..9b15630c2 100644 --- a/src/jfrog-cli/devcontainer-feature.json +++ b/src/jfrog-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "jfrog-cli", - "version": "1.0.8", + "version": "1.0.9", "name": "JFrog CLI (via jfrog.io)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/jfrog-cli", "description": "JFrog CLI is a compact and smart client that provides a simple interface that automates access to JFrog products simplifying your automation scripts making them more readable and easier to maintain.", @@ -8,4 +8,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/curl-apt-get" ] -} \ No newline at end of file +} diff --git a/src/jira-cli/devcontainer-feature.json b/src/jira-cli/devcontainer-feature.json index 9ee5d85c0..30a7977f8 100644 --- a/src/jira-cli/devcontainer-feature.json +++ b/src/jira-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "jira-cli", - "version": "1.0.7", + "version": "1.0.8", "name": "Jira CLI (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/jira-cli", "description": "Jira CLI is an interactive command line tool for Atlassian Jira that will help you avoid Jira UI to some extent. This tool may not be able to do everything, but it has all the essential features required to improve your day-to-day workflow with Jira.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/jmc-sdkman/devcontainer-feature.json b/src/jmc-sdkman/devcontainer-feature.json index b704c5414..c674390ae 100644 --- a/src/jmc-sdkman/devcontainer-feature.json +++ b/src/jmc-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "jmc-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "JDK Mission Control (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/jmc-sdkman", "description": "Java Flight Recorder and JDK Mission Control together create a complete tool\nchain to continuously collect low level and detailed runtime information\nenabling after-the-fact incident analysis. JDK Mission Control is an advanced\nset of tools that enables efficient and detailed analysis of the extensive of\ndata collected by Java Flight Recorder. The tool chain enables developers and\nadministrators to collect and analyze data from Java applications running\nlocally or deployed in production environments.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/jmeter-sdkman/devcontainer-feature.json b/src/jmeter-sdkman/devcontainer-feature.json index b69e51701..0148c65d2 100644 --- a/src/jmeter-sdkman/devcontainer-feature.json +++ b/src/jmeter-sdkman/devcontainer-feature.json @@ -1,9 +1,9 @@ { "id": "jmeter-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "Apache JMeter (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/jmeter-sdkman", - "description": "The Apache JMeter\u2122 application is open source software, a 100% pure Java\napplication designed to load test functional behavior and measure performance.\nIt was originally designed for testing Web Applications but has since expanded\nto other test functions.", + "description": "The Apache JMeter™ application is open source software, a 100% pure Java\napplication designed to load test functional behavior and measure performance.\nIt was originally designed for testing Web Applications but has since expanded\nto other test functions.", "options": { "version": { "default": "latest", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/joern-sdkman/devcontainer-feature.json b/src/joern-sdkman/devcontainer-feature.json index 46e282dca..461dbeac7 100644 --- a/src/joern-sdkman/devcontainer-feature.json +++ b/src/joern-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "joern-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "Joern (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/joern-sdkman", "description": "Joern is a platform for analyzing source code, bytecode, and binary executables.\nIt generates code property graphs (CPGs), a graph representation of code for\ncross-language code analysis. Code property graphs are stored in a custom graph\ndatabase. This allows code to be mined using search queries formulated in a\nScala-based domain-specific query language. Joern is developed with the goal of\nproviding a useful tool for vulnerability discovery and research in static\nprogram analysis.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/jreleaser-sdkman/devcontainer-feature.json b/src/jreleaser-sdkman/devcontainer-feature.json index 3fdab4cbe..d9b2b6cb8 100644 --- a/src/jreleaser-sdkman/devcontainer-feature.json +++ b/src/jreleaser-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "jreleaser-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "JReleaser (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/jreleaser-sdkman", "description": "JReleaser is a release automation tool for Java projects. Its goal is to\nsimplify creating releases and publishing artifacts to multiple package managers\nwhile providing customizable options.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/jrnl/devcontainer-feature.json b/src/jrnl/devcontainer-feature.json index 190b5619f..8c20698f0 100644 --- a/src/jrnl/devcontainer-feature.json +++ b/src/jrnl/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "jrnl", - "version": "2.0.17", + "version": "2.0.18", "name": "jrnl (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/jrnl", "description": "jrnl is a simple journal application for the command line.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/jshint/devcontainer-feature.json b/src/jshint/devcontainer-feature.json index cc86d3722..570426cc4 100644 --- a/src/jshint/devcontainer-feature.json +++ b/src/jshint/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "jshint", - "version": "2.0.15", + "version": "2.0.16", "name": "JSHint (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/jshint", "description": "JSHint is a tool that helps to detect errors and potential problems in your JavaScript code.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/jsii-diff/devcontainer-feature.json b/src/jsii-diff/devcontainer-feature.json index c3c1af407..7e167f505 100644 --- a/src/jsii-diff/devcontainer-feature.json +++ b/src/jsii-diff/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "jsii-diff", - "version": "1.0.2", + "version": "1.0.3", "name": "jsii-diff (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/jsii-diff", "description": "jsii-diff compares two jsii assemblies for compatibility.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/jsii-pacmak/devcontainer-feature.json b/src/jsii-pacmak/devcontainer-feature.json index af2eace4a..b25731433 100644 --- a/src/jsii-pacmak/devcontainer-feature.json +++ b/src/jsii-pacmak/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "jsii-pacmak", - "version": "1.0.2", + "version": "1.0.3", "name": "jsii-pacmak (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/jsii-pacmak", "description": "jsii-pacmak generates ready-to-publish language-specific packages for jsii modules, part of the jsii project.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/jsii-rosetta/devcontainer-feature.json b/src/jsii-rosetta/devcontainer-feature.json index 907b7448a..bf6462bfa 100644 --- a/src/jsii-rosetta/devcontainer-feature.json +++ b/src/jsii-rosetta/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "jsii-rosetta", - "version": "1.0.2", + "version": "1.0.3", "name": "jsii-rosetta (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/jsii-rosetta", "description": "jsii-rosetta is a utility to transcribe example code snippets from TypeScript to other jsii languages.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/jsii/devcontainer-feature.json b/src/jsii/devcontainer-feature.json index 8e190deed..ef5d6f6aa 100644 --- a/src/jsii/devcontainer-feature.json +++ b/src/jsii/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "jsii", - "version": "1.0.2", + "version": "1.0.3", "name": "jsii compiler (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/jsii", "description": "jsii allows code in any language to naturally interact with JavaScript classes. It is the technology that enables the AWS Cloud Development Kit to deliver polyglot libraries from a single codebase!", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/json-server/devcontainer-feature.json b/src/json-server/devcontainer-feature.json index 445c82f4d..5d97c3906 100644 --- a/src/json-server/devcontainer-feature.json +++ b/src/json-server/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "json-server", - "version": "1.0.3", + "version": "1.0.4", "name": "JSON Server (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/json-server", "description": "Get a full fake REST API with zero coding in less than 30 seconds.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/k2tf/devcontainer-feature.json b/src/k2tf/devcontainer-feature.json index 17046318f..89b4bfce6 100644 --- a/src/k2tf/devcontainer-feature.json +++ b/src/k2tf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "k2tf", - "version": "1.0.5", + "version": "1.0.6", "name": "k2tf (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/k2tf", "description": "k2tf is a tool for converting Kubernetes API Objects (in YAML format) into HashiCorp's Terraform configuration language.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/k6/devcontainer-feature.json b/src/k6/devcontainer-feature.json index bc19922c7..b16e5d40d 100644 --- a/src/k6/devcontainer-feature.json +++ b/src/k6/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "k6", - "version": "1.0.2", + "version": "1.0.3", "name": "k6 (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/k6", "description": "k6 is an open-source load testing tool that makes performance testing easy and productive for engineering teams.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/karaf-sdkman/devcontainer-feature.json b/src/karaf-sdkman/devcontainer-feature.json index af0619973..bea6cb31a 100644 --- a/src/karaf-sdkman/devcontainer-feature.json +++ b/src/karaf-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "karaf-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "Karaf (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/karaf-sdkman", "description": "Apache Karaf is a polymorphic, lightweight, powerful, and enterprise ready\napplications runtime. It provides all the ecosystem and bootstrapping options\nyou need for your applications. It runs on premise or on cloud. By polymorphic,\nit means that Karaf can host any kind of applications: WAR, OSGi, Spring, and\nmuch more.", @@ -38,4 +38,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/keepercommander/devcontainer-feature.json b/src/keepercommander/devcontainer-feature.json index 19928ac76..3e708b063 100644 --- a/src/keepercommander/devcontainer-feature.json +++ b/src/keepercommander/devcontainer-feature.json @@ -1,9 +1,9 @@ { "id": "keepercommander", - "version": "1.0.4", + "version": "1.0.5", "name": "Keeper Commander (Keeper CLI) (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/keepercommander", - "description": "Keeper Commander is a command-line and SDK interface to Keeper\u00ae Password Manager. Commander can be used to access and control your Keeper vault, perform administrative functions (such as end-user onboarding and data import/export), launch remote sessions, rotate passwords, eliminate hardcoded passwords and more.", + "description": "Keeper Commander is a command-line and SDK interface to Keeper® Password Manager. Commander can be used to access and control your Keeper vault, perform administrative functions (such as end-user onboarding and data import/export), launch remote sessions, rotate passwords, eliminate hardcoded passwords and more.", "options": { "version": { "default": "latest", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/ki-sdkman/devcontainer-feature.json b/src/ki-sdkman/devcontainer-feature.json index d8fe5fa8d..73818cb98 100644 --- a/src/ki-sdkman/devcontainer-feature.json +++ b/src/ki-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ki-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "ki (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ki-sdkman", "description": "An extensible implementation of the Kotlin REPL with a rich set of features\nincluding autocomplete, syntax highlighting, type inference and maven\ndependencies.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/kind/devcontainer-feature.json b/src/kind/devcontainer-feature.json index 1e416869d..91b4b88cc 100644 --- a/src/kind/devcontainer-feature.json +++ b/src/kind/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "kind", - "version": "1.0.14", + "version": "1.0.15", "name": "kind (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/kind", "description": "kind is a tool for running local Kubernetes clusters using Docker container 'nodes'. kind was primarily designed for testing Kubernetes itself, but may be used for local development or CI.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/kobweb-sdkman/devcontainer-feature.json b/src/kobweb-sdkman/devcontainer-feature.json index e060ce697..12a26bf84 100644 --- a/src/kobweb-sdkman/devcontainer-feature.json +++ b/src/kobweb-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "kobweb-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "Kobweb (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/kobweb-sdkman", "description": "Kobweb is an opinionated Kotlin web framework built on top of Compose for Web.\nThe CLI provides commands to help setup and manage your project.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/kops/devcontainer-feature.json b/src/kops/devcontainer-feature.json index 66a1b0608..2cd7780a0 100644 --- a/src/kops/devcontainer-feature.json +++ b/src/kops/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "kops", - "version": "1.0.2", + "version": "1.0.3", "name": "kOps (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/kops", "description": "Kubernetes Operations (kOps) - Production Grade k8s Installation, Upgrades and Management.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/kotlin-sdkman/devcontainer-feature.json b/src/kotlin-sdkman/devcontainer-feature.json index 045a8af6c..b480fcbeb 100644 --- a/src/kotlin-sdkman/devcontainer-feature.json +++ b/src/kotlin-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "kotlin-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "Kotlin (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/kotlin-sdkman", "description": "Kotlin is a statically-typed programming language that runs on the Java Virtual\nMachine and can also be compiled to JavaScript source code.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/kscript-sdkman/devcontainer-feature.json b/src/kscript-sdkman/devcontainer-feature.json index 0c8e06e8f..3078d6d57 100644 --- a/src/kscript-sdkman/devcontainer-feature.json +++ b/src/kscript-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "kscript-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "kscript (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/kscript-sdkman", "description": "Enhanced scripting support for Kotlin on *nix-based systems. kscript provides an\neasy-to-use, very flexible, and almost zero-overhead solution to write\nself-contained mini-applications with Kotlin.", @@ -49,4 +49,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/kubeclarity-cli/devcontainer-feature.json b/src/kubeclarity-cli/devcontainer-feature.json index b8bca2608..6e2281bd1 100644 --- a/src/kubeclarity-cli/devcontainer-feature.json +++ b/src/kubeclarity-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "kubeclarity-cli", - "version": "1.0.9", + "version": "1.0.10", "name": "KubeClarity CLI (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/kubeclarity-cli", "description": "KubeClarity is a tool for detection and management of Software Bill Of Materials (SBOM) and vulnerabilities of container images and filesystems. KubeClarity CLI can be run locally and especially useful for CI/CD pipelines. It allows to analyze images and directories to generate SBOM, and scan it for vulnerabilities.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/kubectl-asdf/devcontainer-feature.json b/src/kubectl-asdf/devcontainer-feature.json index f14415ef7..b30f77a8b 100644 --- a/src/kubectl-asdf/devcontainer-feature.json +++ b/src/kubectl-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "kubectl-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "Kubectl (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/kubectl-asdf", "description": "Installs Kubectl", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/kubectx-kubens/devcontainer-feature.json b/src/kubectx-kubens/devcontainer-feature.json index b886962c1..3e0da49e2 100644 --- a/src/kubectx-kubens/devcontainer-feature.json +++ b/src/kubectx-kubens/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "kubectx-kubens", - "version": "1.0.5", + "version": "1.0.6", "name": "Kubectx and Kubens (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/kubectx-kubens", "description": "kubectx is a tool to switch between contexts (clusters) on kubectl faster. kubens is a tool to switch between Kubernetes namespaces (and configure them for kubectl) easily.", @@ -18,4 +18,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/kubie/devcontainer-feature.json b/src/kubie/devcontainer-feature.json index db5036714..a5ee53883 100644 --- a/src/kubie/devcontainer-feature.json +++ b/src/kubie/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "Kubie (via Github Releases)", "id": "kubie", - "version": "1.0.3", + "version": "1.0.4", "description": "Kubie offers kubernetes context switching, namespace switching and prompt modification in a way that makes each shell independent from others", "documentationURL": "https://github.com/devcontainers-extra/features/tree/main/src/kubie", "options": { @@ -15,4 +15,4 @@ "description": "Select the Kubie version you would like to install" } } -} \ No newline at end of file +} diff --git a/src/kyverno-cli/devcontainer-feature.json b/src/kyverno-cli/devcontainer-feature.json index 383682562..285f6d57a 100644 --- a/src/kyverno-cli/devcontainer-feature.json +++ b/src/kyverno-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "kyverno-cli", - "version": "1.0.9", + "version": "1.0.10", "name": "Kyverno CLI (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/kyverno-cli", "description": "Kyverno is a policy engine designed for Kubernetes. The Kyverno Command Line Interface (CLI) is designed to validate and test policy behavior to resources prior to adding them to a cluster.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/lastpass-cli-homebrew/devcontainer-feature.json b/src/lastpass-cli-homebrew/devcontainer-feature.json index 42bc8428a..cb217b8c0 100644 --- a/src/lastpass-cli-homebrew/devcontainer-feature.json +++ b/src/lastpass-cli-homebrew/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "lastpass-cli-homebrew", - "version": "1.0.7", + "version": "1.0.8", "name": "LastPass CLI (via Homebrew)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/lastpass-cli-homebrew", "description": "The LastPass command line application is an open source project that allows you to create, edit, and retrieve passwords in your online LastPass vault.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/homebrew-package" ] -} \ No newline at end of file +} diff --git a/src/layrry-sdkman/devcontainer-feature.json b/src/layrry-sdkman/devcontainer-feature.json index a6b7a2c22..48f1eb7d0 100644 --- a/src/layrry-sdkman/devcontainer-feature.json +++ b/src/layrry-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "layrry-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "Layrry (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/layrry-sdkman", "description": "Layrry - A Launcher and API for Modularized Java Applications. It allows to\nassemble modularized applications based on Maven artifact coordinates of the\n(modular) JARs to include. Layrry utilizes the Java Module System's notion of\nmodule layers, allowing multiple versions of one module to be used within an\napplication at the same time, as well as dynamically adding and removing modules\nat application runtime.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/lean-asdf/devcontainer-feature.json b/src/lean-asdf/devcontainer-feature.json index 51c6f7ca6..92f102dcf 100644 --- a/src/lean-asdf/devcontainer-feature.json +++ b/src/lean-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "lean-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "Lean (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/lean-asdf", "description": "Lean is a functional programming language that makes it easy to write correct and maintainable code.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/lefthook-asdf/devcontainer-feature.json b/src/lefthook-asdf/devcontainer-feature.json index cfea9616d..e9295135d 100644 --- a/src/lefthook-asdf/devcontainer-feature.json +++ b/src/lefthook-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "lefthook-asdf", - "version": "1.0.2", + "version": "1.0.3", "name": "Lefthook (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/lefthook-asdf", "description": "Lefthook is the fastest polyglot Git hooks manager out there.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/leiningen-sdkman/devcontainer-feature.json b/src/leiningen-sdkman/devcontainer-feature.json index b0b8608ce..0c090f619 100644 --- a/src/leiningen-sdkman/devcontainer-feature.json +++ b/src/leiningen-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "leiningen-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "Leiningen (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/leiningen-sdkman", "description": "Leiningen is the easiest way to use Clojure. With a focus on project automation\nand declarative configuration, it gets out of your way and lets you focus on\nyour code.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/lektor/devcontainer-feature.json b/src/lektor/devcontainer-feature.json index 31f78d2ff..9bcc56bbc 100644 --- a/src/lektor/devcontainer-feature.json +++ b/src/lektor/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "lektor", - "version": "2.0.17", + "version": "2.0.18", "name": "Lektor (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/lektor", "description": "Lektor is a static website generator.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/lerna-npm/devcontainer-feature.json b/src/lerna-npm/devcontainer-feature.json index ddffd63a7..46adf00ad 100644 --- a/src/lerna-npm/devcontainer-feature.json +++ b/src/lerna-npm/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "lerna-npm", - "version": "1.0.10", + "version": "1.0.11", "name": "Lerna (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/lerna-npm", "description": "Lerna is a fast modern build system for managing and publishing multiple JavaScript/TypeScript packages from the same repository.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/less/devcontainer-feature.json b/src/less/devcontainer-feature.json index 4e9a03c6f..1ccc2a606 100644 --- a/src/less/devcontainer-feature.json +++ b/src/less/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "less", - "version": "2.0.15", + "version": "2.0.16", "name": "Less (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/less", "description": "Less is a backwards-compatible language extension for CSS", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/levant-asdf/devcontainer-feature.json b/src/levant-asdf/devcontainer-feature.json index 91d04b8fd..521342473 100644 --- a/src/levant-asdf/devcontainer-feature.json +++ b/src/levant-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "levant-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "levant (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/levant-asdf", "description": "Levant is an open source templating and deployment tool for HashiCorp Nomad jobs", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/lighthouse-cli/devcontainer-feature.json b/src/lighthouse-cli/devcontainer-feature.json index d93dd1412..8f91889af 100644 --- a/src/lighthouse-cli/devcontainer-feature.json +++ b/src/lighthouse-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "lighthouse-cli", - "version": "1.0.3", + "version": "1.0.4", "name": "Lighthouse CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/lighthouse-cli", "description": "Lighthouse CLI provides the most flexibility in how Lighthouse runs can be configured and reported. Users who want more advanced usage, or want to run Lighthouse in an automated fashion should use the Node CLI.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/linkerd2-cli-edge/devcontainer-feature.json b/src/linkerd2-cli-edge/devcontainer-feature.json index 423138692..930f892f5 100644 --- a/src/linkerd2-cli-edge/devcontainer-feature.json +++ b/src/linkerd2-cli-edge/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "linkerd2-cli-edge", - "version": "1.0.2", + "version": "1.0.3", "name": "Linkerd CLI (Edge) (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/linkerd2-cli-edge", "description": "The Linkerd CLI is the primary way to interact with Linkerd. It can install the control plane to your cluster, add the proxy to your service and provide detailed metrics for how your service is performing.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/linkerd2-cli-stable/devcontainer-feature.json b/src/linkerd2-cli-stable/devcontainer-feature.json index 6e2eef86c..14b916944 100644 --- a/src/linkerd2-cli-stable/devcontainer-feature.json +++ b/src/linkerd2-cli-stable/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "linkerd2-cli-stable", - "version": "1.0.2", + "version": "1.0.3", "name": "Linkerd CLI (Stable) (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/linkerd2-cli-stable", "description": "The Linkerd CLI is the primary way to interact with Linkerd. It can install the control plane to your cluster, add the proxy to your service and provide detailed metrics for how your service is performing.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/linode-cli/devcontainer-feature.json b/src/linode-cli/devcontainer-feature.json index ba13df904..e17e8a1ec 100644 --- a/src/linode-cli/devcontainer-feature.json +++ b/src/linode-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "linode-cli", - "version": "1.0.2", + "version": "1.0.3", "name": "Linode CLI (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/linode-cli", "description": "Access the entire Linode platform from the command line, easily adding, removing, or modifing services.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/lite-server/devcontainer-feature.json b/src/lite-server/devcontainer-feature.json index 545df036d..bdf122d66 100644 --- a/src/lite-server/devcontainer-feature.json +++ b/src/lite-server/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "lite-server", - "version": "1.0.3", + "version": "1.0.4", "name": "lite-server (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/lite-server", "description": "lite-server is a lightweight development only node server that serves a web app, opens it in the browser, refreshes when html or javascript change, injects CSS changes using sockets, and has a fallback page when a route is not found.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/live-server/devcontainer-feature.json b/src/live-server/devcontainer-feature.json index 0408100da..3bf39d917 100644 --- a/src/live-server/devcontainer-feature.json +++ b/src/live-server/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "live-server", - "version": "1.0.3", + "version": "1.0.4", "name": "Live Server (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/live-server", "description": "Live Server is a little development server with live reload capability. Use it for hacking your HTML/JavaScript/CSS files, but not for deploying the final site.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/localstack/devcontainer-feature.json b/src/localstack/devcontainer-feature.json index 9e18a2921..4a36f2dc8 100644 --- a/src/localstack/devcontainer-feature.json +++ b/src/localstack/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "localstack", - "version": "2.0.22", + "version": "2.0.23", "name": "Localstack (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/localstack", "description": "Localstack is a fully functional local AWS cloud stack.", @@ -28,4 +28,4 @@ } ], "privileged": true -} \ No newline at end of file +} diff --git a/src/localtunnel-npm/devcontainer-feature.json b/src/localtunnel-npm/devcontainer-feature.json index 4bef49b71..e3d544d73 100644 --- a/src/localtunnel-npm/devcontainer-feature.json +++ b/src/localtunnel-npm/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "localtunnel-npm", - "version": "1.0.10", + "version": "1.0.11", "name": "Localtunnel (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/localtunnel-npm", "description": "Localtunnel allows you to easily share a web service on your local development machine without messing with DNS and firewall settings.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/mackup/devcontainer-feature.json b/src/mackup/devcontainer-feature.json index 51ba2cc31..2b99a3385 100644 --- a/src/mackup/devcontainer-feature.json +++ b/src/mackup/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "mackup", - "version": "1.0.4", + "version": "1.0.5", "name": "Mackup (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/mackup", "description": "Mackup keeps your application settings in sync (OS X/Linux).", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/markdownlint-cli/devcontainer-feature.json b/src/markdownlint-cli/devcontainer-feature.json index 46b9a1cf6..a819f41d5 100644 --- a/src/markdownlint-cli/devcontainer-feature.json +++ b/src/markdownlint-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "markdownlint-cli", - "version": "1.0.1", + "version": "1.0.2", "name": "markdownlint-cli (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/markdownlint-cli", "description": "Command Line interface for MarkdownLint", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/markdownlint-cli2/devcontainer-feature.json b/src/markdownlint-cli2/devcontainer-feature.json index 350817a24..d5adac8bc 100644 --- a/src/markdownlint-cli2/devcontainer-feature.json +++ b/src/markdownlint-cli2/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "markdownlint-cli2", - "version": "1.0.1", + "version": "1.0.2", "name": "markdownlint-cli2 (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/markdownlint-cli2", "description": "A fast, flexible, configuration-based command-line interface for linting Markdown/CommonMark files with the markdownlint library.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/maven-sdkman/devcontainer-feature.json b/src/maven-sdkman/devcontainer-feature.json index fb9e84606..4f905b873 100644 --- a/src/maven-sdkman/devcontainer-feature.json +++ b/src/maven-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "maven-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "Maven (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/maven-sdkman", "description": "Apache Maven is a software project management and comprehension tool. Based on\nthe concept of a project object model (POM), Maven can manage a project's build,\nreporting and documentation from a central piece of information.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/meltano/devcontainer-feature.json b/src/meltano/devcontainer-feature.json index 33a752970..47eca4b6a 100644 --- a/src/meltano/devcontainer-feature.json +++ b/src/meltano/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "meltano", - "version": "2.0.17", + "version": "2.0.18", "name": "Meltano ELT (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/meltano", "description": "Meltano lets you extract and load data with a software development-inspired approach that that delivers flexibility and limitless collaboration.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/memcached-exporter/devcontainer-feature.json b/src/memcached-exporter/devcontainer-feature.json index 5788b64f2..6ed32d6ec 100644 --- a/src/memcached-exporter/devcontainer-feature.json +++ b/src/memcached-exporter/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "memcached-exporter", - "version": "1.0.2", + "version": "1.0.3", "name": "Prometheus Memcached Exporter (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/memcached-exporter", "description": "The memcached exporter exports metrics from a memcached server for consumption by Prometheus.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/micro/devcontainer-feature.json b/src/micro/devcontainer-feature.json index 7fb9870c4..c103e6daf 100644 --- a/src/micro/devcontainer-feature.json +++ b/src/micro/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "micro", - "version": "1.0.6", + "version": "1.0.7", "name": "micro (via apt-get)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/micro", "description": "micro is a terminal-based text editor that aims to be easy to use and intuitive, while also taking advantage of the capabilities of modern terminals.", @@ -8,4 +8,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/apt-get-packages" ] -} \ No newline at end of file +} diff --git a/src/micronaut-sdkman/devcontainer-feature.json b/src/micronaut-sdkman/devcontainer-feature.json index 691329e46..1b6a03f29 100644 --- a/src/micronaut-sdkman/devcontainer-feature.json +++ b/src/micronaut-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "micronaut-sdkman", - "version": "2.0.16", + "version": "2.0.17", "name": "Micronaut (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/micronaut-sdkman", "description": "Micronaut is an open source microservice framework for the JVM", @@ -42,4 +42,4 @@ "ghcr.io/devcontainers/features/java", "ghcr.io/devcontainers-extra/features/bash-command" ] -} \ No newline at end of file +} diff --git a/src/mitmproxy/devcontainer-feature.json b/src/mitmproxy/devcontainer-feature.json index 1dbea0b16..780e5d7d3 100644 --- a/src/mitmproxy/devcontainer-feature.json +++ b/src/mitmproxy/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "mitmproxy", - "version": "2.0.17", + "version": "2.0.18", "name": "mitmproxy (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/mitmproxy", "description": "mitmproxy is an interactive TLS-capable intercepting HTTP proxy for penetration testers and software developers", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/mkcert/devcontainer-feature.json b/src/mkcert/devcontainer-feature.json index f865be3db..8d7984d40 100644 --- a/src/mkcert/devcontainer-feature.json +++ b/src/mkcert/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "mkcert", - "version": "1.0.14", + "version": "1.0.15", "name": "mkcert (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/mkcert", "description": "mkcert is a simple tool for making locally-trusted development certificates.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/mkdocs/devcontainer-feature.json b/src/mkdocs/devcontainer-feature.json index 2802ec5a0..c1a017ad3 100644 --- a/src/mkdocs/devcontainer-feature.json +++ b/src/mkdocs/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "mkdocs", - "version": "2.0.18", + "version": "2.0.19", "name": "MkDocs (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/mkdocs", "description": "MkDocs is a fast, simple and downright gorgeous static site generator that's geared towards building project documentation.", @@ -26,5 +26,7 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ], - "containerEnv" : {"TZ": "UTC"} -} \ No newline at end of file + "containerEnv": { + "TZ": "UTC" + } +} diff --git a/src/mlocate-apt-get/devcontainer-feature.json b/src/mlocate-apt-get/devcontainer-feature.json index 4d393e0b5..96906c146 100644 --- a/src/mlocate-apt-get/devcontainer-feature.json +++ b/src/mlocate-apt-get/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "mlocate-apt-get", - "version": "1.0.16", + "version": "1.0.17", "name": "mlocate (via apt-get)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/mlocate-apt-get", "description": "mlocate is a locate/updatedb implementation used for quick lookup of file names.", @@ -8,4 +8,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/apt-get-packages" ] -} \ No newline at end of file +} diff --git a/src/mocha/devcontainer-feature.json b/src/mocha/devcontainer-feature.json index c7399ac1f..232e6423e 100644 --- a/src/mocha/devcontainer-feature.json +++ b/src/mocha/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "mocha", - "version": "2.0.15", + "version": "2.0.16", "name": "Mocha (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/mocha", "description": "Mocha is a feature-rich JavaScript test framework running on Node.js and in the browser, making asynchronous testing simple and fun.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/mongodb-atlas-cli-homebrew/devcontainer-feature.json b/src/mongodb-atlas-cli-homebrew/devcontainer-feature.json index 28cdb9fde..a66bcf520 100644 --- a/src/mongodb-atlas-cli-homebrew/devcontainer-feature.json +++ b/src/mongodb-atlas-cli-homebrew/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "mongodb-atlas-cli-homebrew", - "version": "1.0.14", + "version": "1.0.15", "name": "MongoDB Atlas CLI (via Homebrew)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/mongodb-atlas-cli-homebrew", "description": "The Atlas CLI is a command line interface built specifically for MongoDB Atlas.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/homebrew-package" ] -} \ No newline at end of file +} diff --git a/src/mongosh-homebrew/devcontainer-feature.json b/src/mongosh-homebrew/devcontainer-feature.json index 241689914..8787e4230 100644 --- a/src/mongosh-homebrew/devcontainer-feature.json +++ b/src/mongosh-homebrew/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "mongosh-homebrew", - "version": "1.0.20", + "version": "1.0.21", "name": "MongoDB Shell (via Homebrew)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/mongosh-homebrew", "description": "MongoDB Shell to connect, configure, query, and work with your MongoDB database.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/homebrew-package" ] -} \ No newline at end of file +} diff --git a/src/mosh-apt-get/devcontainer-feature.json b/src/mosh-apt-get/devcontainer-feature.json index 623126672..573945563 100644 --- a/src/mosh-apt-get/devcontainer-feature.json +++ b/src/mosh-apt-get/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "mosh-apt-get", - "version": "1.0.16", + "version": "1.0.17", "name": "Mosh (via apt-get)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/mosh-apt-get", "description": "Mosh is a remote terminal application that allows roaming, supports intermittent connectivity, and provides intelligent local echo and line editing of user keystrokes.", @@ -8,4 +8,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/apt-get-packages" ] -} \ No newline at end of file +} diff --git a/src/mosh-homebrew/devcontainer-feature.json b/src/mosh-homebrew/devcontainer-feature.json index df89e5b28..0b1b4616d 100644 --- a/src/mosh-homebrew/devcontainer-feature.json +++ b/src/mosh-homebrew/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "mosh-homebrew", - "version": "1.0.20", + "version": "1.0.21", "name": "Mosh (via Homebrew)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/mosh-homebrew", "description": "Mosh is a remote terminal application that allows roaming, supports intermittent connectivity, and provides intelligent local echo and line editing of user keystrokes.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/homebrew-package" ] -} \ No newline at end of file +} diff --git a/src/mulefd-sdkman/devcontainer-feature.json b/src/mulefd-sdkman/devcontainer-feature.json index ddc0726f3..866041baa 100644 --- a/src/mulefd-sdkman/devcontainer-feature.json +++ b/src/mulefd-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "mulefd-sdkman", - "version": "2.0.16", + "version": "2.0.17", "name": "Mule Flow Diagrams (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/mulefd-sdkman", "description": "Mule Flow Diagrams is an open source tool that lets you generate flow dependency\ngraph and diagrams for your Mule configurations.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/mvnd-sdkman/devcontainer-feature.json b/src/mvnd-sdkman/devcontainer-feature.json index e307eb9c0..9db7b437b 100644 --- a/src/mvnd-sdkman/devcontainer-feature.json +++ b/src/mvnd-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "mvnd-sdkman", - "version": "2.0.16", + "version": "2.0.17", "name": "Maven Daemon (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/mvnd-sdkman", "description": "The mvnd project aims to provide a daemon infrastructure for maven based builds.\nIt borrows techniques from Gradle and Takari to provide a simple and efficient\nsystem.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/mybatis-sdkman/devcontainer-feature.json b/src/mybatis-sdkman/devcontainer-feature.json index 343e0863d..9ba33ae4b 100644 --- a/src/mybatis-sdkman/devcontainer-feature.json +++ b/src/mybatis-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "mybatis-sdkman", - "version": "2.0.16", + "version": "2.0.17", "name": "MyBatis Migrations (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/mybatis-sdkman", "description": "The MyBatis Schema Migration System (or MyBatis Migrations for short) seeks to\nprovide database migrations for any database (new or existing) and make the\ncurrent status of the database easily accessible and comprehensible. Installing\nthis candidate provides the migrate command for managing database migrations", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/mypy/devcontainer-feature.json b/src/mypy/devcontainer-feature.json index 27959e707..486d8e505 100644 --- a/src/mypy/devcontainer-feature.json +++ b/src/mypy/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "mypy", - "version": "2.0.17", + "version": "2.0.18", "name": "Mypy (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/mypy", "description": "Mypy is a static type checker for Python.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/mysql-homebrew/devcontainer-feature.json b/src/mysql-homebrew/devcontainer-feature.json index e9ab0375d..b82632a62 100644 --- a/src/mysql-homebrew/devcontainer-feature.json +++ b/src/mysql-homebrew/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "mysql-homebrew", - "version": "1.0.20", + "version": "1.0.21", "name": "MySQL (via Homebrew)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/mysql-homebrew", "description": "MySQL is an open-source relational database management system (RDBMS)", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/homebrew-package" ] -} \ No newline at end of file +} diff --git a/src/mysqld-exporter/devcontainer-feature.json b/src/mysqld-exporter/devcontainer-feature.json index c90031cc6..01e89f131 100644 --- a/src/mysqld-exporter/devcontainer-feature.json +++ b/src/mysqld-exporter/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "mysqld-exporter", - "version": "1.0.2", + "version": "1.0.3", "name": "Prometheus MySQL Exporter (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/mysqld-exporter", "description": "Prometheus exporter for MySQL server metrics.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/n8n/devcontainer-feature.json b/src/n8n/devcontainer-feature.json index 49fab17c1..8c277aed3 100644 --- a/src/n8n/devcontainer-feature.json +++ b/src/n8n/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "n8n", - "version": "1.0.2", + "version": "1.0.3", "name": "n8n (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/n8n", "description": "n8n is a free and source-available fair-code licensed workflow automation tool.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/nancy/devcontainer-feature.json b/src/nancy/devcontainer-feature.json index 0fe6caf60..48b82c818 100644 --- a/src/nancy/devcontainer-feature.json +++ b/src/nancy/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "nancy", - "version": "1.0.9", + "version": "1.0.10", "name": "Nancy (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/nancy", "description": "Nancy is a tool to check for vulnerabilities in your Golang dependencies, powered by Sonatype OSS Index.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/navi/devcontainer-feature.json b/src/navi/devcontainer-feature.json index b0606a099..b2912c4a6 100644 --- a/src/navi/devcontainer-feature.json +++ b/src/navi/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "navi", - "version": "1.0.9", + "version": "1.0.10", "name": "navi (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/navi", "description": "navi is an interactive cheatsheet tool for the command-line. navi allows you to browse through cheatsheets (that you may write yourself or download from maintainers) and execute commands. Suggested values for arguments are dynamically displayed in a list.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/ncdu/devcontainer-feature.json b/src/ncdu/devcontainer-feature.json index a6fdd7b95..2650b3675 100644 --- a/src/ncdu/devcontainer-feature.json +++ b/src/ncdu/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ncdu", - "version": "1.0.6", + "version": "1.0.7", "name": "ncdu (via apt-get)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ncdu", "description": "ncdu (NCurses Disk Usage) is a disk utility for Unix systems.", @@ -8,4 +8,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/apt-get-packages" ] -} \ No newline at end of file +} diff --git a/src/neko-asdf/devcontainer-feature.json b/src/neko-asdf/devcontainer-feature.json index dc3948e14..e9a2edb87 100644 --- a/src/neko-asdf/devcontainer-feature.json +++ b/src/neko-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "neko-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "Neko Virtual Machine (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/neko-asdf", "description": "Installs Neko Virtual Machine", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/neo4jmigrations-sdkman/devcontainer-feature.json b/src/neo4jmigrations-sdkman/devcontainer-feature.json index c85effa5a..2bd4d331f 100644 --- a/src/neo4jmigrations-sdkman/devcontainer-feature.json +++ b/src/neo4jmigrations-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "neo4jmigrations-sdkman", - "version": "2.0.16", + "version": "2.0.17", "name": "Neo4j-Migrations (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/neo4jmigrations-sdkman", "description": "Neo4j-Migrations is a database migration and refactoring tool that allows\nrunning Cypher scripts and programmatic refactorings in a controlled and\nrepeatable fashion against one or more Neo4j database.", @@ -42,4 +42,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/neofetch/devcontainer-feature.json b/src/neofetch/devcontainer-feature.json index e3316f875..50b173c65 100644 --- a/src/neofetch/devcontainer-feature.json +++ b/src/neofetch/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "neofetch", - "version": "1.0.6", + "version": "1.0.7", "name": "Neofetch (via apt-get)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/neofetch", "description": "Neofetch displays information about your operating system, software and hardware in an aesthetic and visually pleasing way.", @@ -8,4 +8,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/apt-get-packages" ] -} \ No newline at end of file +} diff --git a/src/neovim-apt-get/devcontainer-feature.json b/src/neovim-apt-get/devcontainer-feature.json index 01197f997..3bb93f75b 100644 --- a/src/neovim-apt-get/devcontainer-feature.json +++ b/src/neovim-apt-get/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "neovim-apt-get", - "version": "1.0.19", + "version": "1.0.20", "name": "Neovim (via apt-get)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/neovim-apt-get", "description": "Neovim is a fork of Vim focused on modern code and features, rather than running in legacy environments.", @@ -8,4 +8,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/apt-get-packages" ] -} \ No newline at end of file +} diff --git a/src/neovim-homebrew/devcontainer-feature.json b/src/neovim-homebrew/devcontainer-feature.json index 7b8bfc4e6..19cd37136 100644 --- a/src/neovim-homebrew/devcontainer-feature.json +++ b/src/neovim-homebrew/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "neovim-homebrew", - "version": "1.0.20", + "version": "1.0.21", "name": "Neovim (via Homebrew)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/neovim-homebrew", "description": "Neovim is a fork of Vim focused on modern code and features, rather than running in legacy environments.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/homebrew-package" ] -} \ No newline at end of file +} diff --git a/src/nestjs-cli/devcontainer-feature.json b/src/nestjs-cli/devcontainer-feature.json index 0a810d0a9..debb613b4 100644 --- a/src/nestjs-cli/devcontainer-feature.json +++ b/src/nestjs-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "nestjs-cli", - "version": "2.0.15", + "version": "2.0.16", "name": "NestJS CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/nestjs-cli", "description": "Nestjs is a progressive Node.js framework for building efficient, reliable and scalable server-side applications.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/netdata/devcontainer-feature.json b/src/netdata/devcontainer-feature.json index 0d97a0adc..a2ce41ee2 100644 --- a/src/netdata/devcontainer-feature.json +++ b/src/netdata/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "netdata", - "version": "1.0.10", + "version": "1.0.11", "name": "Netdata (via my-netdata.io)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/netdata", "description": "Netdata is a distributed, real-time, performance and health monitoring platform for systems, hardware, containers and applications, collecting thousands of useful metrics with zero configuration needed.", @@ -8,4 +8,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/curl-apt-get" ] -} \ No newline at end of file +} diff --git a/src/netlify-cli/devcontainer-feature.json b/src/netlify-cli/devcontainer-feature.json index 659fa33e5..bbec743a7 100644 --- a/src/netlify-cli/devcontainer-feature.json +++ b/src/netlify-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "netlify-cli", - "version": "1.0.3", + "version": "1.0.4", "name": "Netlify CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/netlify-cli", "description": "Netlify CLI lets you configure continuous deployment straight from the command line. You can use Netlify CLI to run a local development server that you can share with others, run a local build and plugins, and deploy your site.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/nim-asdf/devcontainer-feature.json b/src/nim-asdf/devcontainer-feature.json index 5d72e27d9..a93752342 100644 --- a/src/nim-asdf/devcontainer-feature.json +++ b/src/nim-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "nim-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "Nim (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/nim-asdf", "description": "Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/ninja-asdf/devcontainer-feature.json b/src/ninja-asdf/devcontainer-feature.json index b51f6eef6..9d59d66e8 100644 --- a/src/ninja-asdf/devcontainer-feature.json +++ b/src/ninja-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ninja-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "Ninja (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ninja-asdf", "description": "Ninja is a small build system with a focus on speed.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/nmap-apt-get/devcontainer-feature.json b/src/nmap-apt-get/devcontainer-feature.json index 96460bf39..71757075d 100644 --- a/src/nmap-apt-get/devcontainer-feature.json +++ b/src/nmap-apt-get/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "nmap-apt-get", - "version": "1.0.16", + "version": "1.0.17", "name": "Nmap (via apt-get)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/nmap-apt-get", "description": "Nmap (Network Mapper) is a free and open source utility for network discovery and security auditing.", @@ -8,4 +8,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/apt-get-packages" ] -} \ No newline at end of file +} diff --git a/src/nmap-homebrew/devcontainer-feature.json b/src/nmap-homebrew/devcontainer-feature.json index 1dfd05531..c1e0439ee 100644 --- a/src/nmap-homebrew/devcontainer-feature.json +++ b/src/nmap-homebrew/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "nmap-homebrew", - "version": "1.0.20", + "version": "1.0.21", "name": "Nmap (via Homebrew)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/nmap-homebrew", "description": "Nmap (Network Mapper) is a free and open source utility for network discovery and security auditing.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/homebrew-package" ] -} \ No newline at end of file +} diff --git a/src/nnn-apt-get/devcontainer-feature.json b/src/nnn-apt-get/devcontainer-feature.json index 04571ce30..67e925175 100644 --- a/src/nnn-apt-get/devcontainer-feature.json +++ b/src/nnn-apt-get/devcontainer-feature.json @@ -1,11 +1,11 @@ { "id": "nnn-apt-get", - "version": "1.0.16", - "name": "nnn (n\u00b3) (via apt-get)", + "version": "1.0.17", + "name": "nnn (n³) (via apt-get)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/nnn-apt-get", "description": "nnn is a free and open-source file manager which provides a text-based user interface to provide file managing functionalities for Unix-like systems.", "options": {}, "installsAfter": [ "ghcr.io/devcontainers-extra/features/apt-get-packages" ] -} \ No newline at end of file +} diff --git a/src/nnn-homebrew/devcontainer-feature.json b/src/nnn-homebrew/devcontainer-feature.json index 31b862a1a..dccc13b7d 100644 --- a/src/nnn-homebrew/devcontainer-feature.json +++ b/src/nnn-homebrew/devcontainer-feature.json @@ -1,13 +1,13 @@ { "id": "nnn-homebrew", - "version": "1.0.20", - "name": "nnn (n\u00b3) (via Homebrew)", + "version": "1.0.21", + "name": "nnn (n³) (via Homebrew)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/nnn-homebrew", "description": "nnn is a free and open-source file manager which provides a text-based user interface to provide file managing functionalities for Unix-like systems.", "options": { "version": { "default": "latest", - "description": "Select the version of nnn (n\u00b3) to install.", + "description": "Select the version of nnn (n³) to install.", "proposals": [ "latest" ], @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/homebrew-package" ] -} \ No newline at end of file +} diff --git a/src/node-asdf/devcontainer-feature.json b/src/node-asdf/devcontainer-feature.json index 8f2e41f86..7a55faf28 100644 --- a/src/node-asdf/devcontainer-feature.json +++ b/src/node-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "node-asdf", - "version": "0.0.1", + "version": "0.0.2", "name": "Node.js (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/node-asdf", "description": "Installs Node.js via asdf.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/node-exporter/devcontainer-feature.json b/src/node-exporter/devcontainer-feature.json index 56f660c9a..19744c1b5 100644 --- a/src/node-exporter/devcontainer-feature.json +++ b/src/node-exporter/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "node-exporter", - "version": "1.0.2", + "version": "1.0.3", "name": "Prometheus Node Exporter (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/node-exporter", "description": "Prometheus exporter for hardware and OS metrics exposed by *NIX kernels, written in Go with pluggable metric collectors.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/nomad-asdf/devcontainer-feature.json b/src/nomad-asdf/devcontainer-feature.json index 11ff329ae..6fce3146c 100644 --- a/src/nomad-asdf/devcontainer-feature.json +++ b/src/nomad-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "nomad-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "Nomad (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/nomad-asdf", "description": "Nomad is an easy-to-use, flexible, and performant workload orchestrator that can deploy a mix of microservice, batch, containerized, and non-containerized applications.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/nox/devcontainer-feature.json b/src/nox/devcontainer-feature.json index cc2029afc..8fce8e205 100644 --- a/src/nox/devcontainer-feature.json +++ b/src/nox/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "nox", - "version": "2.0.17", + "version": "2.0.18", "name": "nox (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/nox", "description": "nox is a command-line tool that automates testing in multiple Python environments.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/npm-package/devcontainer-feature.json b/src/npm-package/devcontainer-feature.json index c00f57ff9..5dd2b55d2 100644 --- a/src/npm-package/devcontainer-feature.json +++ b/src/npm-package/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "NPM package", "id": "npm-package", - "version": "1.0.3", + "version": "1.0.4", "description": "Installs an npm package globally.", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/npm-package", "installsAfter": [ @@ -27,4 +27,4 @@ "description": "Select the version of the npm package to install." } } -} \ No newline at end of file +} diff --git a/src/npm-packages/devcontainer-feature.json b/src/npm-packages/devcontainer-feature.json index 7c38a762f..2981e9c8f 100644 --- a/src/npm-packages/devcontainer-feature.json +++ b/src/npm-packages/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "npm-packages", - "version": "1.0.0", + "version": "1.0.1", "name": "npm-packages", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/npm-packages", "description": "", diff --git a/src/npm-packages/install.sh b/src/npm-packages/install.sh index 6600bad1d..e444d2e70 100755 --- a/src/npm-packages/install.sh +++ b/src/npm-packages/install.sh @@ -16,13 +16,16 @@ IFS=',' read -ra PACKAGE_ARRAY <<<"$PACKAGES" # Iterate through each package for package in "${PACKAGE_ARRAY[@]}"; do - # Check if package contains version - if [[ $package == *@* ]]; then - # Split package into name and version - name=${package%@*} - version=${package#*@} + # Use regex to match valid npm package identifier + # unscoped, unscoped@version, @scoped, @scoped@version + if [[ $package =~ ^(@?[^@]+?)(@(.+?))?$ ]]; then + name="${BASH_REMATCH[1]}" + version="${BASH_REMATCH[3]}" + # Bash doesn't have non-capturing groups so @version portion can + # only be made optional inside a group, then a nested group captures + # the version number itself. else - # Package without version + # Fallback for any invalid package identifiers name=$package version="" fi diff --git a/src/nx-npm/devcontainer-feature.json b/src/nx-npm/devcontainer-feature.json index cb2d47bbe..6ae055b6b 100644 --- a/src/nx-npm/devcontainer-feature.json +++ b/src/nx-npm/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "nx-npm", - "version": "1.0.10", + "version": "1.0.11", "name": "nx (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/nx-npm", "description": "Nx is a smart, fast and extensible build system with first class monorepo support and powerful integrations.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/ocaml-asdf/devcontainer-feature.json b/src/ocaml-asdf/devcontainer-feature.json index dc893f735..25510a1eb 100644 --- a/src/ocaml-asdf/devcontainer-feature.json +++ b/src/ocaml-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ocaml-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "OCaml (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ocaml-asdf", "description": "OCaml is a general-purpose, industrial-strength programming language with an emphasis on expressiveness and safety.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/ocaml-opam/devcontainer-feature.json b/src/ocaml-opam/devcontainer-feature.json new file mode 100644 index 000000000..d63230d44 --- /dev/null +++ b/src/ocaml-opam/devcontainer-feature.json @@ -0,0 +1,42 @@ +{ + "id": "ocaml-opam", + "version": "1.1.0", + "name": "OCaml (via opam)", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ocaml-opam", + "description": "Installation of OCaml that includes a package manager and the compiler itself. Also install some platform tools like a build system, support for your editor, and a few other important ones.", + "options": { + "version": { + "default": "latest", + "description": "Select the OCaml version to install.", + "proposals": [ + "latest", + "5.3.0", + "4.14.2" + ], + "type": "string" + }, + "installPlatformTools": { + "default": true, + "description": "Install some of the OCaml Platform tools? (UTop, Dune, OCaml-LSP, odoc, OCamlFormat)", + "type": "boolean" + }, + "additionalPackages": { + "default": "", + "description": "Enter additional package, separated by spaces.", + "proposals": [ + "base core_kernel ounit qcheck" + ], + "type": "string" + } + }, + "customizations": { + "vscode": { + "extensions": [ + "ocamllabs.ocaml-platform" + ] + } + }, + "installsAfter": [ + "ghcr.io/devcontainers-extra/features/gh-release" + ] +} diff --git a/src/ocaml-opam/install.sh b/src/ocaml-opam/install.sh new file mode 100755 index 000000000..57d0425e0 --- /dev/null +++ b/src/ocaml-opam/install.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +set -e + +source ./library_scripts.sh + +# nanolayer is a cli utility which keeps container layers as small as possible +# source code: https://github.com/devcontainers-extra/nanolayer +# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, +# and if missing - will download a temporary copy that automatically get deleted at the end +# of the script +ensure_nanolayer nanolayer_location "v0.5.6" + +# Example nanolayer installation via devcontainer-feature +$nanolayer_location \ + install \ + devcontainer-feature \ + "ghcr.io/devcontainers-extra/features/gh-release:1.0.25" \ + --option repo='ocaml/opam' --option binaryNames='opam' --option version="latest" --option releaseTagRegex='^(?!.*(alpha|beta|rc)).*$' + + +# Initialise opam +flags=() +if [ "$VERSION" != "latest" ]; then + flags+=(--compiler="$VERSION") +fi +su "$_REMOTE_USER" -c "opam init --disable-sandboxing --shell-setup -y ${flags[*]}" + +# Install packages +packages=() +if [ "$INSTALLPLATFORMTOOLS" = "true" ]; then + packages+=(ocaml-lsp-server odoc ocamlformat utop) +fi +IFS=" " read -r -a additionalPackages <<<"$ADDITIONALPACKAGES" +packages+=("${additionalPackages[@]}") +if [ ${#packages[@]} -ne 0 ]; then + su "$_REMOTE_USER" -c "opam install ${packages[*]} -y" +fi + + +echo 'Done!' diff --git a/src/ocaml-opam/library_scripts.sh b/src/ocaml-opam/library_scripts.sh new file mode 100644 index 000000000..f6d0760d7 --- /dev/null +++ b/src/ocaml-opam/library_scripts.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash + +clean_download() { + # The purpose of this function is to download a file with minimal impact on container layer size + # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a + # temporary manner, and making sure to + # 1. uninstall the downloader at the return of the function + # 2. revert back any changes to the package installer database/cache (for example apt-get lists) + # The above steps will minimize the leftovers being created while installing the downloader + # Supported distros: + # debian/ubuntu/alpine + + url=$1 + output_location=$2 + tempdir=$(mktemp -d) + downloader_installed="" + + function _apt_get_install() { + tempdir=$1 + + # copy current state of apt list - in order to revert back later (minimize contianer layer size) + cp -p -R /var/lib/apt/lists $tempdir + apt-get update -y + apt-get -y install --no-install-recommends wget ca-certificates + } + + function _apt_get_cleanup() { + tempdir=$1 + + echo "removing wget" + apt-get -y purge wget --auto-remove + + echo "revert back apt lists" + rm -rf /var/lib/apt/lists/* + rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists + } + + function _apk_install() { + tempdir=$1 + # copy current state of apk cache - in order to revert back later (minimize contianer layer size) + cp -p -R /var/cache/apk $tempdir + + apk add --no-cache wget + } + + function _apk_cleanup() { + tempdir=$1 + + echo "removing wget" + apk del wget + } + # try to use either wget or curl if one of them already installer + if type curl >/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + # in case none of them is installed, install wget temporarly + if [ -z $downloader ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_install $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_install $tempdir + else + echo "distro not supported" + exit 1 + fi + downloader="wget" + downloader_installed="true" + fi + + if [ $downloader = "wget" ]; then + wget -q $url -O $output_location + else + curl -sfL $url -o $output_location + fi + + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi + +} + +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + # normalize version + if ! [[ $required_version == v* ]]; then + required_version=v$required_version + fi + + local nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ]; then + nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" + fi + + # make sure its of the required version + if ! [[ -z "${nanolayer_location}" ]]; then + local current_version + current_version=$($nanolayer_location --version) + if ! [[ $current_version == v* ]]; then + current_version=v$current_version + fi + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [[ -z "${nanolayer_location}" ]]; then + + if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up() { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + if [ -x "/sbin/apk" ]; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + nanolayer_location=$tmp_dir/nanolayer + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + declare -g ${variable_name}=$nanolayer_location + +} diff --git a/src/oclif/devcontainer-feature.json b/src/oclif/devcontainer-feature.json index ad4c02607..e622ace3e 100644 --- a/src/oclif/devcontainer-feature.json +++ b/src/oclif/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "oclif", - "version": "1.0.2", + "version": "1.0.3", "name": "oclif generator (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/oclif", "description": "The oclif generator creates a CLI project in TypeScript to get you started quickly. It requires very few runtime dependencies and has extremely minimal overhead.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/opa/devcontainer-feature.json b/src/opa/devcontainer-feature.json index fa965aef9..9c6bfa55a 100644 --- a/src/opa/devcontainer-feature.json +++ b/src/opa/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "opa", - "version": "1.0.5", + "version": "1.0.6", "name": "Open Policy Agent (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/opa", "description": "Open Policy Agent (OPA) is an open source, general-purpose policy engine that enables unified, context-aware policy enforcement across the entire stack.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/opam-asdf/devcontainer-feature.json b/src/opam-asdf/devcontainer-feature.json index f23da3898..20fc9d693 100644 --- a/src/opam-asdf/devcontainer-feature.json +++ b/src/opam-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "opam-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "Opam (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/opam-asdf", "description": "opam is a source-based package manager for OCaml.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/opencode/devcontainer-feature.json b/src/opencode/devcontainer-feature.json new file mode 100644 index 000000000..bbcfa16b8 --- /dev/null +++ b/src/opencode/devcontainer-feature.json @@ -0,0 +1,18 @@ +{ + "id": "opencode", + "version": "1.0.0", + "name": "opencode (via Github Releases)", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/opencode", + "description": "The open source coding agent.", + "options": { + "version": { + "default": "latest", + "description": "Select the version to install.", + "proposals": [ + "latest" + ], + "type": "string" + } + }, + "installsAfter": [] +} diff --git a/src/opencode/install.sh b/src/opencode/install.sh new file mode 100755 index 000000000..c47309c16 --- /dev/null +++ b/src/opencode/install.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +set -e + +source ./library_scripts.sh + +# nanolayer is a cli utility which keeps container layers as small as possible +# source code: https://github.com/devcontainers-extra/nanolayer +# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, +# and if missing - will download a temporary copy that automatically get deleted at the end +# of the script +ensure_nanolayer nanolayer_location "v0.5.6" + +# Example nanolayer installation via devcontainer-feature +$nanolayer_location \ + install \ + devcontainer-feature \ + "ghcr.io/devcontainers-extra/features/gh-release:1" \ + --option repo='sst/opencode' --option binaryNames='opencode' --option version="$VERSION" \ + --option assetRegex='^(?!.*baseline).*$' + +echo 'Done!' diff --git a/src/opencode/library_scripts.sh b/src/opencode/library_scripts.sh new file mode 100644 index 000000000..f6d0760d7 --- /dev/null +++ b/src/opencode/library_scripts.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash + +clean_download() { + # The purpose of this function is to download a file with minimal impact on container layer size + # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a + # temporary manner, and making sure to + # 1. uninstall the downloader at the return of the function + # 2. revert back any changes to the package installer database/cache (for example apt-get lists) + # The above steps will minimize the leftovers being created while installing the downloader + # Supported distros: + # debian/ubuntu/alpine + + url=$1 + output_location=$2 + tempdir=$(mktemp -d) + downloader_installed="" + + function _apt_get_install() { + tempdir=$1 + + # copy current state of apt list - in order to revert back later (minimize contianer layer size) + cp -p -R /var/lib/apt/lists $tempdir + apt-get update -y + apt-get -y install --no-install-recommends wget ca-certificates + } + + function _apt_get_cleanup() { + tempdir=$1 + + echo "removing wget" + apt-get -y purge wget --auto-remove + + echo "revert back apt lists" + rm -rf /var/lib/apt/lists/* + rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists + } + + function _apk_install() { + tempdir=$1 + # copy current state of apk cache - in order to revert back later (minimize contianer layer size) + cp -p -R /var/cache/apk $tempdir + + apk add --no-cache wget + } + + function _apk_cleanup() { + tempdir=$1 + + echo "removing wget" + apk del wget + } + # try to use either wget or curl if one of them already installer + if type curl >/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + # in case none of them is installed, install wget temporarly + if [ -z $downloader ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_install $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_install $tempdir + else + echo "distro not supported" + exit 1 + fi + downloader="wget" + downloader_installed="true" + fi + + if [ $downloader = "wget" ]; then + wget -q $url -O $output_location + else + curl -sfL $url -o $output_location + fi + + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi + +} + +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + # normalize version + if ! [[ $required_version == v* ]]; then + required_version=v$required_version + fi + + local nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ]; then + nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" + fi + + # make sure its of the required version + if ! [[ -z "${nanolayer_location}" ]]; then + local current_version + current_version=$($nanolayer_location --version) + if ! [[ $current_version == v* ]]; then + current_version=v$current_version + fi + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [[ -z "${nanolayer_location}" ]]; then + + if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up() { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + if [ -x "/sbin/apk" ]; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + nanolayer_location=$tmp_dir/nanolayer + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + declare -g ${variable_name}=$nanolayer_location + +} diff --git a/src/opengrep/devcontainer-feature.json b/src/opengrep/devcontainer-feature.json new file mode 100644 index 000000000..594ddc49c --- /dev/null +++ b/src/opengrep/devcontainer-feature.json @@ -0,0 +1,18 @@ +{ + "id": "opengrep", + "version": "1.0.0", + "name": "opengrep (via Github Releases)", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/opengrep", + "description": "Static code analysis engine to find security issues in code.", + "options": { + "version": { + "default": "latest", + "description": "Select the version to install.", + "proposals": [ + "latest" + ], + "type": "string" + } + }, + "installsAfter": [] +} diff --git a/src/opengrep/install.sh b/src/opengrep/install.sh new file mode 100755 index 000000000..9b7efc1e1 --- /dev/null +++ b/src/opengrep/install.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +set -e + +source ./library_scripts.sh + +# nanolayer is a cli utility which keeps container layers as small as possible +# source code: https://github.com/devcontainers-extra/nanolayer +# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, +# and if missing - will download a temporary copy that automatically get deleted at the end +# of the script +ensure_nanolayer nanolayer_location "v0.5.6" + +# Example nanolayer installation via devcontainer-feature +$nanolayer_location \ + install \ + devcontainer-feature \ + "ghcr.io/devcontainers-extra/features/gh-release:1" \ + --option repo='opengrep/opengrep' --option binaryNames='opengrep' --option version="$VERSION" --option assetRegex='opengrep_manylinux_[^.]*$' + +echo 'Done!' diff --git a/src/opengrep/library_scripts.sh b/src/opengrep/library_scripts.sh new file mode 100644 index 000000000..f6d0760d7 --- /dev/null +++ b/src/opengrep/library_scripts.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash + +clean_download() { + # The purpose of this function is to download a file with minimal impact on container layer size + # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a + # temporary manner, and making sure to + # 1. uninstall the downloader at the return of the function + # 2. revert back any changes to the package installer database/cache (for example apt-get lists) + # The above steps will minimize the leftovers being created while installing the downloader + # Supported distros: + # debian/ubuntu/alpine + + url=$1 + output_location=$2 + tempdir=$(mktemp -d) + downloader_installed="" + + function _apt_get_install() { + tempdir=$1 + + # copy current state of apt list - in order to revert back later (minimize contianer layer size) + cp -p -R /var/lib/apt/lists $tempdir + apt-get update -y + apt-get -y install --no-install-recommends wget ca-certificates + } + + function _apt_get_cleanup() { + tempdir=$1 + + echo "removing wget" + apt-get -y purge wget --auto-remove + + echo "revert back apt lists" + rm -rf /var/lib/apt/lists/* + rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists + } + + function _apk_install() { + tempdir=$1 + # copy current state of apk cache - in order to revert back later (minimize contianer layer size) + cp -p -R /var/cache/apk $tempdir + + apk add --no-cache wget + } + + function _apk_cleanup() { + tempdir=$1 + + echo "removing wget" + apk del wget + } + # try to use either wget or curl if one of them already installer + if type curl >/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + # in case none of them is installed, install wget temporarly + if [ -z $downloader ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_install $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_install $tempdir + else + echo "distro not supported" + exit 1 + fi + downloader="wget" + downloader_installed="true" + fi + + if [ $downloader = "wget" ]; then + wget -q $url -O $output_location + else + curl -sfL $url -o $output_location + fi + + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi + +} + +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + # normalize version + if ! [[ $required_version == v* ]]; then + required_version=v$required_version + fi + + local nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ]; then + nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" + fi + + # make sure its of the required version + if ! [[ -z "${nanolayer_location}" ]]; then + local current_version + current_version=$($nanolayer_location --version) + if ! [[ $current_version == v* ]]; then + current_version=v$current_version + fi + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [[ -z "${nanolayer_location}" ]]; then + + if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up() { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + if [ -x "/sbin/apk" ]; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + nanolayer_location=$tmp_dir/nanolayer + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + declare -g ${variable_name}=$nanolayer_location + +} diff --git a/src/opentofu/README.md b/src/opentofu/README.md new file mode 100644 index 000000000..7feb44295 --- /dev/null +++ b/src/opentofu/README.md @@ -0,0 +1,30 @@ + +# opentofu (via Github Releases) (opentofu) + +OpenTofu is an OSS tool for building, changing, and versioning infrastructure safely and efficiently. + +## Example Usage + +```json +"features": { + "ghcr.io/devcontainers-extra/features/opentofu:1": {} +} +``` + +## Options + +| Options Id | Description | Type | Default Value | +|-----|-----|-----|-----| +| version | Select the version to install. | string | latest | + +## Customizations + +### VS Code Extensions + +- `opentofu.vscode-opentofu` + + + +--- + +_Note: This file was auto-generated from the [devcontainer-feature.json](devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/opentofu/devcontainer-feature.json b/src/opentofu/devcontainer-feature.json new file mode 100644 index 000000000..606e1834f --- /dev/null +++ b/src/opentofu/devcontainer-feature.json @@ -0,0 +1,25 @@ +{ + "id": "opentofu", + "version": "1.0.0", + "name": "opentofu (via Github Releases)", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/opentofu", + "description": "OpenTofu is an OSS tool for building, changing, and versioning infrastructure safely and efficiently.", + "options": { + "version": { + "default": "latest", + "description": "Select the version to install.", + "proposals": [ + "latest" + ], + "type": "string" + } + }, + "customizations": { + "vscode": { + "extensions": [ + "opentofu.vscode-opentofu" + ] + } + }, + "installsAfter": [] +} diff --git a/src/opentofu/install.sh b/src/opentofu/install.sh new file mode 100644 index 000000000..ac563f603 --- /dev/null +++ b/src/opentofu/install.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +set -e + +source ./library_scripts.sh + +# nanolayer is a cli utility which keeps container layers as small as possible +# source code: https://github.com/devcontainers-extra/nanolayer +# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, +# and if missing - will download a temporary copy that automatically get deleted at the end +# of the script +ensure_nanolayer nanolayer_location "v0.5.6" + +# Example nanolayer installation via devcontainer-feature +$nanolayer_location \ + install \ + devcontainer-feature \ + "ghcr.io/devcontainers-extra/features/gh-release:1" \ + --option repo='opentofu/opentofu' --option binaryNames='tofu' --option version="$VERSION" \ + --option assetRegex='^.*\.tar\.gz$' + +echo 'Done!' diff --git a/src/opentofu/library_scripts.sh b/src/opentofu/library_scripts.sh new file mode 100644 index 000000000..f6d0760d7 --- /dev/null +++ b/src/opentofu/library_scripts.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash + +clean_download() { + # The purpose of this function is to download a file with minimal impact on container layer size + # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a + # temporary manner, and making sure to + # 1. uninstall the downloader at the return of the function + # 2. revert back any changes to the package installer database/cache (for example apt-get lists) + # The above steps will minimize the leftovers being created while installing the downloader + # Supported distros: + # debian/ubuntu/alpine + + url=$1 + output_location=$2 + tempdir=$(mktemp -d) + downloader_installed="" + + function _apt_get_install() { + tempdir=$1 + + # copy current state of apt list - in order to revert back later (minimize contianer layer size) + cp -p -R /var/lib/apt/lists $tempdir + apt-get update -y + apt-get -y install --no-install-recommends wget ca-certificates + } + + function _apt_get_cleanup() { + tempdir=$1 + + echo "removing wget" + apt-get -y purge wget --auto-remove + + echo "revert back apt lists" + rm -rf /var/lib/apt/lists/* + rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists + } + + function _apk_install() { + tempdir=$1 + # copy current state of apk cache - in order to revert back later (minimize contianer layer size) + cp -p -R /var/cache/apk $tempdir + + apk add --no-cache wget + } + + function _apk_cleanup() { + tempdir=$1 + + echo "removing wget" + apk del wget + } + # try to use either wget or curl if one of them already installer + if type curl >/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + # in case none of them is installed, install wget temporarly + if [ -z $downloader ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_install $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_install $tempdir + else + echo "distro not supported" + exit 1 + fi + downloader="wget" + downloader_installed="true" + fi + + if [ $downloader = "wget" ]; then + wget -q $url -O $output_location + else + curl -sfL $url -o $output_location + fi + + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi + +} + +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + # normalize version + if ! [[ $required_version == v* ]]; then + required_version=v$required_version + fi + + local nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ]; then + nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" + fi + + # make sure its of the required version + if ! [[ -z "${nanolayer_location}" ]]; then + local current_version + current_version=$($nanolayer_location --version) + if ! [[ $current_version == v* ]]; then + current_version=v$current_version + fi + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [[ -z "${nanolayer_location}" ]]; then + + if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up() { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + if [ -x "/sbin/apk" ]; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + nanolayer_location=$tmp_dir/nanolayer + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + declare -g ${variable_name}=$nanolayer_location + +} diff --git a/src/ory-cli/devcontainer-feature.json b/src/ory-cli/devcontainer-feature.json index 24d76b10a..3aea6a85f 100644 --- a/src/ory-cli/devcontainer-feature.json +++ b/src/ory-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ory-cli", - "version": "1.0.5", + "version": "1.0.6", "name": "Ory CLI (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ory-cli", "description": "Ory CLI is a convenient and easy-to-use tool that helps you manage and configure The Ory Network.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/ory-hydra/devcontainer-feature.json b/src/ory-hydra/devcontainer-feature.json index c257bf9d8..b11ad70b6 100644 --- a/src/ory-hydra/devcontainer-feature.json +++ b/src/ory-hydra/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ory-hydra", - "version": "1.0.5", + "version": "1.0.6", "name": "Ory Hydra (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ory-hydra", "description": "Ory Hydra is a hardened, OpenID Certified OAuth 2.0 Server and OpenID Connect Provider optimized for low-latency, high throughput, and low resource consumption.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/ory-kratos/devcontainer-feature.json b/src/ory-kratos/devcontainer-feature.json index 78f47acef..48a91f9a6 100644 --- a/src/ory-kratos/devcontainer-feature.json +++ b/src/ory-kratos/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ory-kratos", - "version": "1.0.5", + "version": "1.0.6", "name": "Ory Kratos (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ory-kratos", "description": "Ory Kratos is the developer-friendly, security-hardened and battle-test Identity, User Management and Authentication system for the Cloud.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/ory-oathkeeper/devcontainer-feature.json b/src/ory-oathkeeper/devcontainer-feature.json index fb8a029e2..de7168c32 100644 --- a/src/ory-oathkeeper/devcontainer-feature.json +++ b/src/ory-oathkeeper/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ory-oathkeeper", - "version": "1.0.5", + "version": "1.0.6", "name": "Ory Oathkeeper (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ory-oathkeeper", "description": "ORY Oathkeeper is an Identity & Access Proxy (IAP) and Access Control Decision API that authorizes HTTP requests based on sets of Access Rules.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/outagedeck/README.md b/src/outagedeck/README.md new file mode 100644 index 000000000..5c0bbadc3 --- /dev/null +++ b/src/outagedeck/README.md @@ -0,0 +1,34 @@ +# OutageDeck CLI (via GitHub Releases) (outagedeck) + +Check the live status of 170+ cloud and SaaS providers from a terminal or CI +script. OutageDeck normalizes each vendor's official status feed; it does not +replace synthetic monitoring. + +## Example usage + +```json +"features": { + "ghcr.io/devcontainers-extra/features/outagedeck:1": {} +} +``` + +Then query one or more provider slugs: + +```bash +outagedeck status aws cloudflare github openai +``` + +For structured CI output and a nonzero exit code when a provider is down: + +```bash +outagedeck status --json --fail-on=outage aws github openai +``` + +Find more examples in the [OutageDeck CLI repository](https://github.com/outagedeck/cli) +or review the [API documentation](https://outagedeck.com/developers/api?utm_source=devcontainers-extra&utm_medium=feature&utm_campaign=devcontainer_feature). + +## Options + +| Options Id | Description | Type | Default Value | +|------------|----------------------------------------------|--------|---------------| +| version | Select the OutageDeck CLI version to install. | string | latest | diff --git a/src/outagedeck/devcontainer-feature.json b/src/outagedeck/devcontainer-feature.json new file mode 100644 index 000000000..c8d1c231a --- /dev/null +++ b/src/outagedeck/devcontainer-feature.json @@ -0,0 +1,21 @@ +{ + "id": "outagedeck", + "version": "1.0.0", + "name": "OutageDeck CLI (via GitHub Releases)", + "documentationURL": "https://github.com/devcontainers-extra/features/tree/main/src/outagedeck", + "description": "Check the live status of cloud and SaaS providers from a terminal or CI script.", + "options": { + "version": { + "default": "latest", + "description": "Select the OutageDeck CLI version to install.", + "proposals": [ + "latest", + "0.1.0" + ], + "type": "string" + } + }, + "installsAfter": [ + "ghcr.io/devcontainers-extra/features/gh-release" + ] +} diff --git a/src/outagedeck/install.sh b/src/outagedeck/install.sh new file mode 100755 index 000000000..fd472f850 --- /dev/null +++ b/src/outagedeck/install.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +set -e + +source ./library_scripts.sh + +# nanolayer is a CLI utility which keeps container layers as small as possible. +# Source: https://github.com/devcontainers-extra/nanolayer +ensure_nanolayer nanolayer_location "v0.5.6" + +"$nanolayer_location" \ + install \ + devcontainer-feature \ + "ghcr.io/devcontainers-extra/features/gh-release:1" \ + --option repo='outagedeck/cli' \ + --option binaryNames='outagedeck' \ + --option version="$VERSION" + +echo 'Done!' diff --git a/src/outagedeck/library_scripts.sh b/src/outagedeck/library_scripts.sh new file mode 100755 index 000000000..98e0da825 --- /dev/null +++ b/src/outagedeck/library_scripts.sh @@ -0,0 +1,131 @@ +#!/usr/bin/env bash + +clean_download() { + local url=$1 + local output_location=$2 + local tempdir + tempdir=$(mktemp -d) + local downloader_installed="" + + _apt_get_install() { + local apt_tempdir=$1 + cp -p -R /var/lib/apt/lists "$apt_tempdir" + apt-get update -y + apt-get -y install --no-install-recommends wget ca-certificates + } + + _apt_get_cleanup() { + local apt_tempdir=$1 + apt-get -y purge wget --auto-remove + rm -rf /var/lib/apt/lists/* + rm -r /var/lib/apt/lists + mv "$apt_tempdir/lists" /var/lib/apt/lists + } + + _apk_install() { + local apk_tempdir=$1 + cp -p -R /var/cache/apk "$apk_tempdir" + apk add --no-cache wget + } + + _apk_cleanup() { + apk del wget + } + + local downloader + if type curl >/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + if [ -z "$downloader" ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_install "$tempdir" + elif [ -x "/sbin/apk" ]; then + _apk_install "$tempdir" + else + echo "distro not supported" + exit 1 + fi + downloader="wget" + downloader_installed="true" + fi + + if [ "$downloader" = "wget" ]; then + wget -q "$url" -O "$output_location" + else + curl -sfL "$url" -o "$output_location" + fi + + if [ -n "$downloader_installed" ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_cleanup "$tempdir" + elif [ -x "/sbin/apk" ]; then + _apk_cleanup + fi + fi +} + +ensure_nanolayer() { + local variable_name=$1 + local required_version=$2 + + if [[ $required_version != v* ]]; then + required_version="v$required_version" + fi + + local resolved_nanolayer="" + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION:-}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION:-}" ]]; then + if type nanolayer >/dev/null 2>&1; then + resolved_nanolayer=nanolayer + fi + elif [[ -f "$NANOLAYER_CLI_LOCATION" && -x "$NANOLAYER_CLI_LOCATION" ]]; then + resolved_nanolayer=$NANOLAYER_CLI_LOCATION + fi + + if [[ -n "$resolved_nanolayer" ]]; then + local current_version + current_version=$($resolved_nanolayer --version) + if [[ $current_version != v* ]]; then + current_version="v$current_version" + fi + if [[ $current_version != "$required_version" ]]; then + resolved_nanolayer="" + fi + fi + fi + + if [[ -z "$resolved_nanolayer" ]]; then + if [[ "$(uname -sm)" != "Linux x86_64" && "$(uname -sm)" != "Linux aarch64" ]]; then + echo "No nanolayer binary for $(uname -sm)" + exit 1 + fi + + local nanolayer_tempdir + nanolayer_tempdir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + clean_up() { + local exit_code=$? + rm -rf "$nanolayer_tempdir" + exit "$exit_code" + } + trap clean_up EXIT + + local clib_type=gnu + if [ -x "/sbin/apk" ]; then + clib_type=musl + fi + local tar_filename="nanolayer-$(uname -m)-unknown-linux-$clib_type.tgz" + clean_download \ + "https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename" \ + "$nanolayer_tempdir/$tar_filename" + tar xfz "$nanolayer_tempdir/$tar_filename" -C "$nanolayer_tempdir" + chmod a+x "$nanolayer_tempdir/nanolayer" + resolved_nanolayer="$nanolayer_tempdir/nanolayer" + fi + + declare -g "$variable_name=$resolved_nanolayer" +} diff --git a/src/packer-asdf/devcontainer-feature.json b/src/packer-asdf/devcontainer-feature.json index 3150e319d..a6c0f6b79 100644 --- a/src/packer-asdf/devcontainer-feature.json +++ b/src/packer-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "packer-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "Packer (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/packer-asdf", "description": "Packer is a free and open source tool for creating golden images for multiple platforms from a single source configuration.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/pandoc/devcontainer-feature.json b/src/pandoc/devcontainer-feature.json index a0e66b138..117d33b9c 100644 --- a/src/pandoc/devcontainer-feature.json +++ b/src/pandoc/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "pandoc", - "version": "1.0.14", + "version": "1.0.15", "name": "Pandoc (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/pandoc", "description": "Pandoc is a Haskell library for converting from one markup format to another, and a command-line tool that uses this library.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/pass-apt-get/devcontainer-feature.json b/src/pass-apt-get/devcontainer-feature.json index e1d96b332..336c33288 100644 --- a/src/pass-apt-get/devcontainer-feature.json +++ b/src/pass-apt-get/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "pass-apt-get", - "version": "1.0.4", + "version": "1.0.5", "name": "pass (password-store) (via apt-get)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/pass-apt-get", "description": "pass is a very simple password store that encrypts passwords using gpg and places the encrypted password in a directory.", @@ -8,4 +8,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/apt-get-packages" ] -} \ No newline at end of file +} diff --git a/src/pdm/devcontainer-feature.json b/src/pdm/devcontainer-feature.json index 9445f7639..4f40c42e1 100644 --- a/src/pdm/devcontainer-feature.json +++ b/src/pdm/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "pdm", - "version": "2.0.17", + "version": "2.0.18", "name": "PDM (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/pdm", "description": "PDM is a modern Python package and dependency manager supporting the latest PEP standards.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/peco-asdf/devcontainer-feature.json b/src/peco-asdf/devcontainer-feature.json index a8f964805..8f60c7f8c 100644 --- a/src/peco-asdf/devcontainer-feature.json +++ b/src/peco-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "peco-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "peco (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/peco-asdf", "description": "peco is simplistic interactive filtering tool.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/perl-asdf/devcontainer-feature.json b/src/perl-asdf/devcontainer-feature.json index 9007fe472..007cd41ce 100644 --- a/src/perl-asdf/devcontainer-feature.json +++ b/src/perl-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "perl-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "Perl (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/perl-asdf", "description": "Perl is a general-purpose, interpreted, dynamic programming language.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/pierrot-sdkman/devcontainer-feature.json b/src/pierrot-sdkman/devcontainer-feature.json index a764a7a7d..002782c76 100644 --- a/src/pierrot-sdkman/devcontainer-feature.json +++ b/src/pierrot-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "pierrot-sdkman", - "version": "2.0.16", + "version": "2.0.17", "name": "Pierrot (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/pierrot-sdkman", "description": "Pierrot helps you to manage many GitHub repositories with a single command.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/pipenv/devcontainer-feature.json b/src/pipenv/devcontainer-feature.json index b04cc7469..f99a5eebc 100644 --- a/src/pipenv/devcontainer-feature.json +++ b/src/pipenv/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "pipenv", - "version": "2.0.17", + "version": "2.0.18", "name": "Pipenv (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/pipenv", "description": "Pipenv automatically creates and manages a virtualenv for your projects.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/pnpm/devcontainer-feature.json b/src/pnpm/devcontainer-feature.json index 21033922a..4ff7fea59 100644 --- a/src/pnpm/devcontainer-feature.json +++ b/src/pnpm/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "pnpm", - "version": "2.0.4", + "version": "2.0.5", "name": "Pnpm (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/pnpm", "description": "Pnpm is a fast and disk space efficient package manager.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/podman-homebrew/devcontainer-feature.json b/src/podman-homebrew/devcontainer-feature.json index 2ca15951f..ed670cc08 100644 --- a/src/podman-homebrew/devcontainer-feature.json +++ b/src/podman-homebrew/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "podman-homebrew", - "version": "1.0.20", + "version": "1.0.21", "name": "Podman (via Homebrew)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/podman-homebrew", "description": "Podman is a tool for managing containers and images, volumes mounted into those containers, and pods made from groups of containers.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/homebrew-package" ] -} \ No newline at end of file +} diff --git a/src/poetry/devcontainer-feature.json b/src/poetry/devcontainer-feature.json index 04e176393..8cb9aaf5b 100644 --- a/src/poetry/devcontainer-feature.json +++ b/src/poetry/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "poetry", - "version": "2.0.17", + "version": "2.0.18", "name": "Poetry (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/poetry", "description": "Poetry is a tool for dependency management and packaging in Python.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/pomchecker-sdkman/devcontainer-feature.json b/src/pomchecker-sdkman/devcontainer-feature.json index da4acdd55..cbc9fb32f 100644 --- a/src/pomchecker-sdkman/devcontainer-feature.json +++ b/src/pomchecker-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "pomchecker-sdkman", - "version": "2.0.16", + "version": "2.0.17", "name": "Pomchecker (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/pomchecker-sdkman", "description": "Pomchecker - Checks that POM files comply with the minimum rules required for\npublication to Maven Central. It can also check if a POM is a valid BOM file.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/poppler-utils-apt-get/devcontainer-feature.json b/src/poppler-utils-apt-get/devcontainer-feature.json index 0be4ad7c9..15d63214c 100644 --- a/src/poppler-utils-apt-get/devcontainer-feature.json +++ b/src/poppler-utils-apt-get/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "poppler-utils-apt-get", - "version": "1.0.0", + "version": "1.0.1", "name": "poppler-utils (pdftotext, pdftoppm, pdftops, pdfattach, pdfdetach, pdffonts, pdfimages, pdfinfo, pdfseparate, pdftocairo, pdftohtml, pdfunite) (via apt-get)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/curl-apt-get", "description": "poppler-utils is a collection of command-line utilities built on Poppler's library API, to manage PDF and extract contents: \npdfattach - add a new embedded file (attachment) to an existing PDF \npdfdetach - extract embedded documents from a PDF \npdffonts - lists the fonts used in a PDF \npdfimages - extract all embedded images at native resolution from a PDF \npdfinfo - list all information of a PDF \npdfseparate - extract single pages from a PDF \npdftocairo - convert single pages from a PDF to vector or bitmap formats using cairo \npdftohtml - convert PDF to HTML format retaining formatting \npdftoppm - convert a PDF page to a bitmap \npdftops - convert PDF to printable PS format \npdftotext - extract all text from PDF \npdfunite - merges several PDFs.", @@ -8,4 +8,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/apt-get-packages" ] -} \ No newline at end of file +} diff --git a/src/powerbi-visuals-tools/devcontainer-feature.json b/src/powerbi-visuals-tools/devcontainer-feature.json index 21a7e205e..9dac2e345 100644 --- a/src/powerbi-visuals-tools/devcontainer-feature.json +++ b/src/powerbi-visuals-tools/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "powerbi-visuals-tools", - "version": "2.0.15", + "version": "2.0.16", "name": "PowerBI Visual Tools (pbiviz) (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/powerbi-visuals-tools", "description": "PowerBI Visual Tools Contains tools for building/packaging Power BI visuals", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/powershell/devcontainer-feature.json b/src/powershell/devcontainer-feature.json index a37ee1fe3..1add1f730 100644 --- a/src/powershell/devcontainer-feature.json +++ b/src/powershell/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "powershell", - "version": "1.0.13", + "version": "1.0.14", "name": "PowerShell (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/powershell", "description": "PowerShell is a cross-platform (Windows, Linux, and macOS) automation and configuration tool/framework that works well with your existing tools and is optimized for dealing with structured data (e.g. JSON, CSV, XML, etc.), REST APIs, and object models. It includes a command-line shell, an associated scripting language and a framework for processing cmdlets.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/pre-commit/devcontainer-feature.json b/src/pre-commit/devcontainer-feature.json index 49d01b70c..780a7c161 100644 --- a/src/pre-commit/devcontainer-feature.json +++ b/src/pre-commit/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "pre-commit", - "version": "2.0.17", + "version": "2.0.18", "name": "Pre-Commit (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/pre-commit", "description": "Pre-Commit is a framework for managing and maintaining multi-language pre-commit hooks.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/prek/README.md b/src/prek/README.md new file mode 100644 index 000000000..5d9d6127d --- /dev/null +++ b/src/prek/README.md @@ -0,0 +1,38 @@ +# prek (via Github Releases) + +prek is a faster, dependency-free alternative to pre-commit, re-engineered in Rust. + +## Example Usage + +```json +"features": { + "ghcr.io/devcontainers-extra/features/prek:1": {} +} +``` + +## Options + +| Options Id | Description | Type | Default Value | +|-----|-----|-----|-----| +| version | Select the version to install. | string | latest | + +## About prek + +[prek](https://github.com/j178/prek) is a reimagined version of pre-commit, built in Rust. It is designed to be a faster, dependency-free and drop-in alternative, while also providing some additional long-requested features. + +### Key Features + +- A single binary with no dependencies, does not require Python or any other runtime +- Multiple times faster than `pre-commit` and takes up half the disk space +- Fully compatible with the original pre-commit configurations and hooks +- Built-in support for monorepos (workspace mode) +- Integration with uv for managing Python virtual environments and dependencies +- Built-in Rust-native implementation of some common hooks + +## Installation + +This feature installs prek from GitHub releases based on your system architecture (x86_64 or aarch64) and C library type (glibc or musl). + +--- + +_Note: This file was auto-generated from the [devcontainer-feature.json](devcontainer-feature.json)._ diff --git a/src/prek/devcontainer-feature.json b/src/prek/devcontainer-feature.json new file mode 100644 index 000000000..876381d01 --- /dev/null +++ b/src/prek/devcontainer-feature.json @@ -0,0 +1,20 @@ +{ + "id": "prek", + "version": "1.0.0", + "name": "prek (via Github Releases)", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/prek", + "description": "prek is a faster, dependency-free alternative to pre-commit, re-engineered in Rust.", + "options": { + "version": { + "default": "latest", + "description": "Select the version to install.", + "proposals": [ + "latest" + ], + "type": "string" + } + }, + "installsAfter": [ + "ghcr.io/devcontainers-extra/features/gh-release" + ] +} diff --git a/src/prek/install.sh b/src/prek/install.sh new file mode 100755 index 000000000..5d4c435b6 --- /dev/null +++ b/src/prek/install.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +set -e + +source ./library_scripts.sh + +# nanolayer is a cli utility which keeps container layers as small as possible +# source code: https://github.com/devcontainers-extra/nanolayer +# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, +# and if missing - will download a temporary copy that automatically get deleted at the end +# of the script +ensure_nanolayer nanolayer_location "v0.5.6" + +# Detect C library type (musl for Alpine, gnu for Debian/Ubuntu) +if [ -f "/lib/ld-musl-x86_64.so.1" ] || [ -f "/lib/ld-musl-aarch64.so.1" ]; then + clib_type=musl +else + clib_type=gnu +fi + +# Detect architecture +architecture="$(uname -m)" +case $architecture in + x86_64) + arch="x86_64" + ;; + aarch64) + arch="aarch64" + ;; + *) + echo "(!) Architecture ${architecture} is not supported" + exit 1 + ;; +esac + +# Build asset regex to match prek release binaries +# Example: prek-x86_64-unknown-linux-gnu.tar.gz +asset_regex="^prek-${arch}-unknown-linux-${clib_type}\\.tar\\.gz$" + +$nanolayer_location \ + install \ + devcontainer-feature \ + "ghcr.io/devcontainers-extra/features/gh-release:1.0.26" \ + --option repo='j178/prek' \ + --option binaryNames='prek' \ + --option version="$VERSION" \ + --option assetRegex="$asset_regex" + +echo 'Done!' diff --git a/src/tea/library_scripts.sh b/src/prek/library_scripts.sh similarity index 99% rename from src/tea/library_scripts.sh rename to src/prek/library_scripts.sh index 9e1072eca..08abda9c9 100644 --- a/src/tea/library_scripts.sh +++ b/src/prek/library_scripts.sh @@ -1,5 +1,3 @@ - - clean_download() { # The purpose of this function is to download a file with minimal impact on container layer size # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a @@ -169,4 +167,3 @@ ensure_nanolayer() { } - diff --git a/src/prettier/devcontainer-feature.json b/src/prettier/devcontainer-feature.json index b97ed1b63..4894f99db 100644 --- a/src/prettier/devcontainer-feature.json +++ b/src/prettier/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "prettier", - "version": "1.0.1", + "version": "1.0.2", "name": "Prettier (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/prettier", "description": "Prettier is an opinionated code formatter.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/prisma/devcontainer-feature.json b/src/prisma/devcontainer-feature.json index f6baa7a92..75d6efa1d 100644 --- a/src/prisma/devcontainer-feature.json +++ b/src/prisma/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "prisma", - "version": "2.0.15", + "version": "2.0.16", "name": "Prisma CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/prisma", "description": "Prisma is a next-generation ORM for Node.js & TypeScript | PostgreSQL, MySQL, MariaDB, SQL Server, SQLite, MongoDB and CockroachDB.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/projen/devcontainer-feature.json b/src/projen/devcontainer-feature.json index c923ac7f3..1a56da57e 100644 --- a/src/projen/devcontainer-feature.json +++ b/src/projen/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "projen", - "version": "1.0.2", + "version": "1.0.3", "name": "projen (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/projen", "description": "projen synthesizes project configuration files such as package.json, tsconfig.json, .gitignore, GitHub Workflows, eslint, jest, etc from a well-typed definition written in JavaScript.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/prometheus/devcontainer-feature.json b/src/prometheus/devcontainer-feature.json index ef739bfff..4978d01ef 100644 --- a/src/prometheus/devcontainer-feature.json +++ b/src/prometheus/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "prometheus", - "version": "1.0.2", + "version": "1.0.3", "name": "Prometheus (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/prometheus", "description": "Prometheus, a Cloud Native Computing Foundation project, is a systems and service monitoring system. It collects metrics from configured targets at given intervals, evaluates rule expressions, displays the results, and can trigger alerts when specified conditions are observed.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/promlens/devcontainer-feature.json b/src/promlens/devcontainer-feature.json index b3abe021a..174b1578d 100644 --- a/src/promlens/devcontainer-feature.json +++ b/src/promlens/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "promlens", - "version": "1.0.2", + "version": "1.0.3", "name": "PromLens (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/promlens", "description": "PromLens is a web-based PromQL query builder, analyzer, and visualizer.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/protoc-asdf/devcontainer-feature.json b/src/protoc-asdf/devcontainer-feature.json index 0a1c0686f..b8bdbab53 100644 --- a/src/protoc-asdf/devcontainer-feature.json +++ b/src/protoc-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "protoc-asdf", - "version": "1.0.6", + "version": "1.0.7", "name": "protoc (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/protoc-asdf", "description": "protoc is the protocol buffer compiler", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/protoc/devcontainer-feature.json b/src/protoc/devcontainer-feature.json index 1c22a46ce..b1ba6ba39 100644 --- a/src/protoc/devcontainer-feature.json +++ b/src/protoc/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "protoc", - "version": "1.0.2", + "version": "1.0.3", "name": "Protocol Buffer (Protobuf) Compiler (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/protoc", "description": "A compiler for protocol buffer definition files.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/pulumi/devcontainer-feature.json b/src/pulumi/devcontainer-feature.json index 9e9d6ec3e..018d4d948 100644 --- a/src/pulumi/devcontainer-feature.json +++ b/src/pulumi/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "Pulumi (via get.pulumi.com)", "id": "pulumi", - "version": "1.2.3", + "version": "1.2.4", "description": "Pulumi is a modern infrastructure as code platform", "documentationURL": "https://github.com/devcontainers-extra/features/tree/main/src/pulumi", "options": { @@ -20,4 +20,4 @@ "description": "Add pulumi command-line completion to bash" } } -} \ No newline at end of file +} diff --git a/src/pushgateway/devcontainer-feature.json b/src/pushgateway/devcontainer-feature.json index 7d5c3cb69..1bf54410b 100644 --- a/src/pushgateway/devcontainer-feature.json +++ b/src/pushgateway/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "pushgateway", - "version": "1.0.2", + "version": "1.0.3", "name": "Prometheus Pushgateway (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/pushgateway", "description": "The Prometheus Pushgateway exists to allow ephemeral and batch jobs to expose their metrics to Prometheus. Since these kinds of jobs may not exist long enough to be scraped, they can instead push their metrics to a Pushgateway. The Pushgateway then exposes these metrics to Prometheus.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/pyinfra/devcontainer-feature.json b/src/pyinfra/devcontainer-feature.json index ac1ce60ae..9ca351337 100644 --- a/src/pyinfra/devcontainer-feature.json +++ b/src/pyinfra/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "pyinfra", - "version": "2.0.17", + "version": "2.0.18", "name": "pyinfra (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/pyinfra", "description": "pyinfra is a Python alternative to Ansible where you don't write your deployment in YAML file, but in Python.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/pylint/devcontainer-feature.json b/src/pylint/devcontainer-feature.json index 1c8fe4f51..0df96a2a7 100644 --- a/src/pylint/devcontainer-feature.json +++ b/src/pylint/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "pylint", - "version": "2.0.17", + "version": "2.0.18", "name": "Pylint (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/pylint", "description": "Pylint is a static code analyser for Python 2 or 3.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/pyoxidizer/devcontainer-feature.json b/src/pyoxidizer/devcontainer-feature.json index e1f38dc8d..2c24c1000 100644 --- a/src/pyoxidizer/devcontainer-feature.json +++ b/src/pyoxidizer/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "pyoxidizer", - "version": "1.0.5", + "version": "1.0.6", "name": "PyOxidizer (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/pyoxidizer", "description": "PyOxidizer is a modern Python application packaging and distribution tool.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/pyscaffold/devcontainer-feature.json b/src/pyscaffold/devcontainer-feature.json index d4b3d3b35..6101923e5 100644 --- a/src/pyscaffold/devcontainer-feature.json +++ b/src/pyscaffold/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "pyscaffold", - "version": "2.0.17", + "version": "2.0.18", "name": "PyScaffold (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/pyscaffold", "description": "PyScaffold is a python project template generator with batteries included.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/qrcode/devcontainer-feature.json b/src/qrcode/devcontainer-feature.json index ed1aee942..f6aa7eea3 100644 --- a/src/qrcode/devcontainer-feature.json +++ b/src/qrcode/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "qrcode", - "version": "2.0.17", + "version": "2.0.18", "name": "qrcode (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/qrcode", "description": "qrcode is a command line QR-Code generator.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/quarkus-sdkman/devcontainer-feature.json b/src/quarkus-sdkman/devcontainer-feature.json index 6c8eb9ad6..ee49ff9c7 100644 --- a/src/quarkus-sdkman/devcontainer-feature.json +++ b/src/quarkus-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "quarkus-sdkman", - "version": "2.0.16", + "version": "2.0.17", "name": "Quarkus CLI (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/quarkus-sdkman", "description": "Quarkus is a Kubernetes Native Java framework tailored for OpenJDK HotSpot and\nGraalVM, crafted from best-of-breed Java libraries and standards.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/quasar-cli/devcontainer-feature.json b/src/quasar-cli/devcontainer-feature.json index a5dde9256..47b3ba59d 100644 --- a/src/quasar-cli/devcontainer-feature.json +++ b/src/quasar-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "quasar-cli", - "version": "2.0.15", + "version": "2.0.16", "name": "Quasar CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/quasar-cli", "description": "Quasar is an MIT licensed open-source Vue.js based framework, which allows you as a web developer to quickly create responsive websites/apps in many flavours.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/raku-asdf/devcontainer-feature.json b/src/raku-asdf/devcontainer-feature.json index ffe147874..9c947fb96 100644 --- a/src/raku-asdf/devcontainer-feature.json +++ b/src/raku-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "raku-asdf", - "version": "1.0.17", + "version": "1.0.18", "name": "Raku (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/raku-asdf", "description": "Raku is a general-purpose, interpreted, dynamic programming language.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/apt-get-packages", "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/rclone/devcontainer-feature.json b/src/rclone/devcontainer-feature.json index fcb9fcd32..486cab29c 100644 --- a/src/rclone/devcontainer-feature.json +++ b/src/rclone/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "rclone", - "version": "1.0.14", + "version": "1.0.15", "name": "Rclone (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/rclone", "description": "Rclone ('rsync for cloud storage') is a command-line program to sync files and directories to and from different cloud storage providers.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/redis-homebrew/devcontainer-feature.json b/src/redis-homebrew/devcontainer-feature.json index 3ab873e55..9c2ee0468 100644 --- a/src/redis-homebrew/devcontainer-feature.json +++ b/src/redis-homebrew/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "redis-homebrew", - "version": "1.0.20", + "version": "1.0.21", "name": "Redis (via Homebrew)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/redis-homebrew", "description": "Redis is an in-memory data structure store, used as a distributed, in-memory key-value database, cache and message broker, with optional durability.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/homebrew-package" ] -} \ No newline at end of file +} diff --git a/src/rekor-cli/devcontainer-feature.json b/src/rekor-cli/devcontainer-feature.json index dfff1625f..638cb947c 100644 --- a/src/rekor-cli/devcontainer-feature.json +++ b/src/rekor-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "rekor-cli", - "version": "1.0.9", + "version": "1.0.10", "name": "Rekor CLI (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/rekor-cli", "description": "Rekor provide an immutable, tamper-resistant ledger of metadata generated within a software project supply chain.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/renovate-cli/devcontainer-feature.json b/src/renovate-cli/devcontainer-feature.json index 0673fcde5..b346810f4 100644 --- a/src/renovate-cli/devcontainer-feature.json +++ b/src/renovate-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "renovate-cli", - "version": "2.0.15", + "version": "2.0.16", "name": "Renovate CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/renovate-cli", "description": "Renovate is a universal dependency update tool. Multi-platform and multi-language.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/ripgrep/devcontainer-feature.json b/src/ripgrep/devcontainer-feature.json index 0a101a48e..8e19de2c2 100644 --- a/src/ripgrep/devcontainer-feature.json +++ b/src/ripgrep/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ripgrep", - "version": "1.0.14", + "version": "1.0.15", "name": "ripgrep (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ripgrep", "description": "ripgrep recursively searches directories for a regex pattern while respecting your gitignore.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/rollup/devcontainer-feature.json b/src/rollup/devcontainer-feature.json index fb3830f72..99eadf6d0 100644 --- a/src/rollup/devcontainer-feature.json +++ b/src/rollup/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "rollup", - "version": "2.0.15", + "version": "2.0.16", "name": "rollup.js (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/rollup", "description": "Rollup is a module bundler for JavaScript which compiles small pieces of code into something larger and more complex, such as a library or application.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/ruby-asdf/devcontainer-feature.json b/src/ruby-asdf/devcontainer-feature.json index 2407eaf71..6ca20d1b5 100644 --- a/src/ruby-asdf/devcontainer-feature.json +++ b/src/ruby-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ruby-asdf", - "version": "0.0.1", + "version": "0.0.2", "name": "Ruby (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ruby-asdf", "description": "Installs Ruby via asdf.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/ruff/README.md b/src/ruff/README.md index 6c052cea7..03c1e3fc8 100644 --- a/src/ruff/README.md +++ b/src/ruff/README.md @@ -1,5 +1,5 @@ -# Ruff (via pipx) (ruff) +# Ruff (via Github Releases) Ruff is an extremely fast Python linter, written in Rust. diff --git a/src/ruff/devcontainer-feature.json b/src/ruff/devcontainer-feature.json index 31502280e..dabdc6702 100644 --- a/src/ruff/devcontainer-feature.json +++ b/src/ruff/devcontainer-feature.json @@ -1,7 +1,7 @@ { "id": "ruff", - "version": "1.0.1", - "name": "Ruff (via pipx)", + "version": "2.0.0", + "name": "Ruff (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ruff", "description": "Ruff is an extremely fast Python linter, written in Rust.", "options": { @@ -14,8 +14,12 @@ "type": "string" } }, - "installsAfter": [ - "ghcr.io/devcontainers-extra/features/pipx-package", - "ghcr.io/devcontainers/features/python" - ] -} \ No newline at end of file + "customizations": { + "vscode": { + "extensions": [ + "charliermarsh.ruff" + ] + } + }, + "installsAfter": [] +} diff --git a/src/ruff/install.sh b/src/ruff/install.sh index 1c344caae..87b3ec2af 100755 --- a/src/ruff/install.sh +++ b/src/ruff/install.sh @@ -1,23 +1,21 @@ +#!/usr/bin/env bash set -e -. ./library_scripts.sh +source ./library_scripts.sh # nanolayer is a cli utility which keeps container layers as small as possible # source code: https://github.com/devcontainers-extra/nanolayer # `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, # and if missing - will download a temporary copy that automatically get deleted at the end # of the script -ensure_nanolayer nanolayer_location "v0.5.0" - +ensure_nanolayer nanolayer_location "v0.5.6" +# Example nanolayer installation via devcontainer-feature $nanolayer_location \ install \ devcontainer-feature \ - "ghcr.io/devcontainers-extra/features/pipx-package:1.1.8" \ - --option package='ruff' --option version="$VERSION" - - + "ghcr.io/devcontainers-extra/features/gh-release:1" \ + --option repo='astral-sh/ruff' --option binaryNames='ruff' --option version="$VERSION" echo 'Done!' - diff --git a/src/ruff/library_scripts.sh b/src/ruff/library_scripts.sh index 9e1072eca..f6d0760d7 100644 --- a/src/ruff/library_scripts.sh +++ b/src/ruff/library_scripts.sh @@ -1,4 +1,4 @@ - +#!/usr/bin/env bash clean_download() { # The purpose of this function is to download a file with minimal impact on container layer size @@ -15,7 +15,7 @@ clean_download() { tempdir=$(mktemp -d) downloader_installed="" - _apt_get_install() { + function _apt_get_install() { tempdir=$1 # copy current state of apt list - in order to revert back later (minimize contianer layer size) @@ -24,7 +24,7 @@ clean_download() { apt-get -y install --no-install-recommends wget ca-certificates } - _apt_get_cleanup() { + function _apt_get_cleanup() { tempdir=$1 echo "removing wget" @@ -35,15 +35,15 @@ clean_download() { rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists } - _apk_install() { + function _apk_install() { tempdir=$1 # copy current state of apk cache - in order to revert back later (minimize contianer layer size) cp -p -R /var/cache/apk $tempdir - apk add --no-cache wget + apk add --no-cache wget } - _apk_cleanup() { + function _apk_cleanup() { tempdir=$1 echo "removing wget" @@ -59,10 +59,10 @@ clean_download() { fi # in case none of them is installed, install wget temporarly - if [ -z $downloader ] ; then - if [ -x "/usr/bin/apt-get" ] ; then + if [ -z $downloader ]; then + if [ -x "/usr/bin/apt-get" ]; then _apt_get_install $tempdir - elif [ -x "/sbin/apk" ] ; then + elif [ -x "/sbin/apk" ]; then _apk_install $tempdir else echo "distro not supported" @@ -72,7 +72,7 @@ clean_download() { downloader_installed="true" fi - if [ $downloader = "wget" ] ; then + if [ $downloader = "wget" ]; then wget -q $url -O $output_location else curl -sfL $url -o $output_location @@ -80,10 +80,10 @@ clean_download() { # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because # alpine lack bash, and RETURN is not a valid signal under sh shell - if ! [ -z $downloader_installed ] ; then - if [ -x "/usr/bin/apt-get" ] ; then + if ! [ -z $downloader_installed ]; then + if [ -x "/usr/bin/apt-get" ]; then _apt_get_cleanup $tempdir - elif [ -x "/sbin/apk" ] ; then + elif [ -x "/sbin/apk" ]; then _apk_cleanup $tempdir else echo "distro not supported" @@ -93,56 +93,60 @@ clean_download() { } - ensure_nanolayer() { # Ensure existance of the nanolayer cli program local variable_name=$1 local required_version=$2 + # normalize version + if ! [[ $required_version == v* ]]; then + required_version=v$required_version + fi - local __nanolayer_location="" + local nanolayer_location="" # If possible - try to use an already installed nanolayer - if [ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]; then - if [ -z "${NANOLAYER_CLI_LOCATION}" ]; then + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then if type nanolayer >/dev/null 2>&1; then echo "Found a pre-existing nanolayer in PATH" - __nanolayer_location=nanolayer + nanolayer_location=nanolayer fi - elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ] ; then - __nanolayer_location=${NANOLAYER_CLI_LOCATION} - echo "Found a pre-existing nanolayer which were given in env variable: $__nanolayer_location" + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ]; then + nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" fi # make sure its of the required version - if ! [ -z "${__nanolayer_location}" ]; then + if ! [[ -z "${nanolayer_location}" ]]; then local current_version - current_version=$($__nanolayer_location --version) - + current_version=$($nanolayer_location --version) + if ! [[ $current_version == v* ]]; then + current_version=v$current_version + fi if ! [ $current_version == $required_version ]; then echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" - __nanolayer_location="" + nanolayer_location="" fi fi fi # If not previuse installation found, download it temporarly and delete at the end of the script - if [ -z "${__nanolayer_location}" ]; then + if [[ -z "${nanolayer_location}" ]]; then - if [ "$(uname -sm)" = 'Linux x86_64' ] || [ "$(uname -sm)" = "Linux aarch64" ]; then + if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) - clean_up () { + clean_up() { ARG=$? rm -rf $tmp_dir exit $ARG } trap clean_up EXIT - - if [ -x "/sbin/apk" ] ; then + if [ -x "/sbin/apk" ]; then clib_type=musl else clib_type=gnu @@ -155,8 +159,7 @@ ensure_nanolayer() { tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" chmod a+x $tmp_dir/nanolayer - __nanolayer_location=$tmp_dir/nanolayer - + nanolayer_location=$tmp_dir/nanolayer else echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" @@ -165,8 +168,6 @@ ensure_nanolayer() { fi # Expose outside the resolved location - export ${variable_name}=$__nanolayer_location + declare -g ${variable_name}=$nanolayer_location } - - diff --git a/src/salesforce-cli/devcontainer-feature.json b/src/salesforce-cli/devcontainer-feature.json index cb3c209e4..9349f13c4 100644 --- a/src/salesforce-cli/devcontainer-feature.json +++ b/src/salesforce-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "salesforce-cli", - "version": "1.0.2", + "version": "1.0.3", "name": "Salesforce CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/salesforce-cli", "description": "The Salesforce CLI is a powerful command line interface that simplifies development and build automation when working with your Salesforce org.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/salesforce-sfdx/devcontainer-feature.json b/src/salesforce-sfdx/devcontainer-feature.json index c19f59a6d..10cb0e3be 100644 --- a/src/salesforce-sfdx/devcontainer-feature.json +++ b/src/salesforce-sfdx/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "salesforce-sfdx", - "version": "1.0.2", + "version": "1.0.3", "name": "Salesforce sfdx (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/salesforce-sfdx", "description": "sfdx provide you with the ability to develop and test your apps more easily on Salesforce Platform.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/sanity-cli/devcontainer-feature.json b/src/sanity-cli/devcontainer-feature.json index c0701b0fb..052b63443 100644 --- a/src/sanity-cli/devcontainer-feature.json +++ b/src/sanity-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "sanity-cli", - "version": "1.0.2", + "version": "1.0.3", "name": "Sanity.io CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/sanity-cli", "description": "The sanity Command Line Interface (CLI) is a collection of tools for managing, developing, debugging, and deploying your Sanity Studio projects.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/sap-piper/devcontainer-feature.json b/src/sap-piper/devcontainer-feature.json index fe89b778d..573713268 100644 --- a/src/sap-piper/devcontainer-feature.json +++ b/src/sap-piper/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "sap-piper", - "version": "1.0.9", + "version": "1.0.10", "name": "Project Piper (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/sap-piper", "description": "Piper offers default pipelines to easily implement CI/CD processes integrating SAP systems.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/sbt-sdkman/devcontainer-feature.json b/src/sbt-sdkman/devcontainer-feature.json index b5ea67e07..954000412 100644 --- a/src/sbt-sdkman/devcontainer-feature.json +++ b/src/sbt-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "sbt-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "sbt (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/sbt-sdkman", "description": "SBT is an open source build tool for Scala and Java projects, similar to Java's\nMaven or Ant. Its main features are: native support for compiling Scala code and\nintegrating with many Scala test frameworks; build descriptions written in Scala\nusing a DSL; dependency management using Ivy (which supports Maven-format\nrepositories); continuous compilation, testing, and deployment; integration with\nthe Scala interpreter for rapid iteration and debugging; support for mixed\nJava/Scala projects", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/scala-sdkman/devcontainer-feature.json b/src/scala-sdkman/devcontainer-feature.json index 74347d967..f8db21588 100644 --- a/src/scala-sdkman/devcontainer-feature.json +++ b/src/scala-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "scala-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "Scala (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/scala-sdkman", "description": "Scala is a programming language for general software applications. Scala has\nfull support for functional programming and a very strong static type system.\nThis allows programs written in Scala to be very concise and thus smaller in\nsize than other general-purpose programming languages. Scala source code is\nintended to be compiled to Java bytecode, so that the resulting executable code\nruns on a Java virtual machine. Java libraries may be used directly in Scala\ncode and vice versa. Scala is object-oriented, and uses a curly-brace syntax.\nScala has many features of functional programming languages, including currying,\ntype inference, immutability, lazy evaluation, and pattern matching. It also has\nan advanced type system supporting algebraic data types, covariance and\ncontravariance, higher-order types, and anonymous types. Other features of Scala\ninclude operator overloading, optional parameters, named parameters, raw\nstrings, and no checked exceptions.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/scalacli-sdkman/devcontainer-feature.json b/src/scalacli-sdkman/devcontainer-feature.json index 7dad4212c..debd346f0 100644 --- a/src/scalacli-sdkman/devcontainer-feature.json +++ b/src/scalacli-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "scalacli-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "Scala CLI (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/scalacli-sdkman", "description": "Scala CLI is a command-line tool to interact with the Scala language. It lets\nyou compile, run, test, and package your Scala code (and more!)", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/scancode-toolkit/devcontainer-feature.json b/src/scancode-toolkit/devcontainer-feature.json index c944be1d6..64725a8fe 100644 --- a/src/scancode-toolkit/devcontainer-feature.json +++ b/src/scancode-toolkit/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "scancode-toolkit", - "version": "1.0.4", + "version": "1.0.5", "name": "Scan (SAST) (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/scancode-toolkit", "description": "ScanCode scan code to detect packages and dependencies, licenses, copyrights and more.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/schemacrawler-sdkman/devcontainer-feature.json b/src/schemacrawler-sdkman/devcontainer-feature.json index d2bf59317..965b86adc 100644 --- a/src/schemacrawler-sdkman/devcontainer-feature.json +++ b/src/schemacrawler-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "schemacrawler-sdkman", - "version": "2.0.16", + "version": "2.0.17", "name": "SchemaCrawler (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/schemacrawler-sdkman", "description": "SchemaCrawler is a free database schema discovery and comprehension tool.\nSchemaCrawler has a good mix of useful features for data governance. You can\nsearch for database schema objects using regular expressions, and output the\nschema and data in a readable text format. The output serves for database\ndocumentation, and is designed to be diff-ed against other database schemas.\nSchemaCrawler also generates schema diagrams. You can execute scripts in any\nstandard scripting language against your database. You can find potential schema\ndesign issues with lint.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/sentinel-asdf/devcontainer-feature.json b/src/sentinel-asdf/devcontainer-feature.json index d86403554..c0005afb3 100644 --- a/src/sentinel-asdf/devcontainer-feature.json +++ b/src/sentinel-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "sentinel-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "sentinel (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/sentinel-asdf", "description": "Sentinel is an embeddable policy as code framework to enable fine-grained, logic-based policy decisions that can be extended to source external information to make decisions.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/serf-asdf/devcontainer-feature.json b/src/serf-asdf/devcontainer-feature.json index 5ebb6f8a3..bdbcf0507 100644 --- a/src/serf-asdf/devcontainer-feature.json +++ b/src/serf-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "serf-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "Serf (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/serf-asdf", "description": "Serf is a decentralized solution for cluster membership, failure detection, and orchestration.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/shellcheck/README.md b/src/shellcheck/README.md new file mode 100644 index 000000000..d63c201af --- /dev/null +++ b/src/shellcheck/README.md @@ -0,0 +1,24 @@ + +# shellcheck (via Github Releases) (shellcheck) + + + +## Example Usage + +```json +"features": { + "ghcr.io/devcontainers-extra/features/shellcheck:1": {} +} +``` + +## Options + +| Options Id | Description | Type | Default Value | +|-----|-----|-----|-----| +| version | Select the version to install. | string | latest | + + + +--- + +_Note: This file was auto-generated from the [devcontainer-feature.json](devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/shellcheck/devcontainer-feature.json b/src/shellcheck/devcontainer-feature.json new file mode 100644 index 000000000..821947f9b --- /dev/null +++ b/src/shellcheck/devcontainer-feature.json @@ -0,0 +1,18 @@ +{ + "id": "shellcheck", + "version": "1.1.0", + "name": "shellcheck (via Github Releases)", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/shellcheck", + "description": "", + "options": { + "version": { + "default": "latest", + "description": "Select the version to install.", + "proposals": [ + "latest" + ], + "type": "string" + } + }, + "installsAfter": [] +} diff --git a/src/shellcheck/install.sh b/src/shellcheck/install.sh new file mode 100755 index 000000000..ecc24b3d5 --- /dev/null +++ b/src/shellcheck/install.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +set -e + +source ./library_scripts.sh + +# nanolayer is a cli utility which keeps container layers as small as possible +# source code: https://github.com/devcontainers-extra/nanolayer +# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, +# and if missing - will download a temporary copy that automatically get deleted at the end +# of the script +ensure_nanolayer nanolayer_location "v0.5.6" + +# Example nanolayer installation via devcontainer-feature +$nanolayer_location \ + install \ + devcontainer-feature \ + "ghcr.io/devcontainers-extra/features/gh-release:1" \ + --option repo='koalaman/shellcheck' --option binaryNames='shellcheck' --option version="$VERSION" --option assetRegex='shellcheck-.*.tar.xz$' + +echo 'Done!' diff --git a/src/shellcheck/library_scripts.sh b/src/shellcheck/library_scripts.sh new file mode 100644 index 000000000..f6d0760d7 --- /dev/null +++ b/src/shellcheck/library_scripts.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash + +clean_download() { + # The purpose of this function is to download a file with minimal impact on container layer size + # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a + # temporary manner, and making sure to + # 1. uninstall the downloader at the return of the function + # 2. revert back any changes to the package installer database/cache (for example apt-get lists) + # The above steps will minimize the leftovers being created while installing the downloader + # Supported distros: + # debian/ubuntu/alpine + + url=$1 + output_location=$2 + tempdir=$(mktemp -d) + downloader_installed="" + + function _apt_get_install() { + tempdir=$1 + + # copy current state of apt list - in order to revert back later (minimize contianer layer size) + cp -p -R /var/lib/apt/lists $tempdir + apt-get update -y + apt-get -y install --no-install-recommends wget ca-certificates + } + + function _apt_get_cleanup() { + tempdir=$1 + + echo "removing wget" + apt-get -y purge wget --auto-remove + + echo "revert back apt lists" + rm -rf /var/lib/apt/lists/* + rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists + } + + function _apk_install() { + tempdir=$1 + # copy current state of apk cache - in order to revert back later (minimize contianer layer size) + cp -p -R /var/cache/apk $tempdir + + apk add --no-cache wget + } + + function _apk_cleanup() { + tempdir=$1 + + echo "removing wget" + apk del wget + } + # try to use either wget or curl if one of them already installer + if type curl >/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + # in case none of them is installed, install wget temporarly + if [ -z $downloader ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_install $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_install $tempdir + else + echo "distro not supported" + exit 1 + fi + downloader="wget" + downloader_installed="true" + fi + + if [ $downloader = "wget" ]; then + wget -q $url -O $output_location + else + curl -sfL $url -o $output_location + fi + + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi + +} + +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + # normalize version + if ! [[ $required_version == v* ]]; then + required_version=v$required_version + fi + + local nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ]; then + nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" + fi + + # make sure its of the required version + if ! [[ -z "${nanolayer_location}" ]]; then + local current_version + current_version=$($nanolayer_location --version) + if ! [[ $current_version == v* ]]; then + current_version=v$current_version + fi + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [[ -z "${nanolayer_location}" ]]; then + + if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up() { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + if [ -x "/sbin/apk" ]; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + nanolayer_location=$tmp_dir/nanolayer + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + declare -g ${variable_name}=$nanolayer_location + +} diff --git a/src/shfmt/devcontainer-feature.json b/src/shfmt/devcontainer-feature.json index 0f893123e..b7c632f2d 100644 --- a/src/shfmt/devcontainer-feature.json +++ b/src/shfmt/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "shfmt", - "version": "1.0.1", + "version": "1.0.2", "name": "shfmt (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/shfmt", "description": "Shfmt is a shell parser, formatter, and interpreter.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/shopify-cli/devcontainer-feature.json b/src/shopify-cli/devcontainer-feature.json index 42d567e36..2851385a6 100644 --- a/src/shopify-cli/devcontainer-feature.json +++ b/src/shopify-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "shopify-cli", - "version": "1.0.3", + "version": "1.0.4", "name": "Shopify CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/shopify-cli", "description": "Shopify CLI is a command-line interface tool that helps you build Shopify apps and themes. It quickly generates Shopify apps, themes, and custom storefronts. You can also use it to automate many common development tasks.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/sigstore-python/devcontainer-feature.json b/src/sigstore-python/devcontainer-feature.json index 809e9d446..5f59a2dcc 100644 --- a/src/sigstore-python/devcontainer-feature.json +++ b/src/sigstore-python/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "sigstore-python", - "version": "1.0.4", + "version": "1.0.5", "name": "sigstore-python (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ansible", "description": "sigstore-python is a Python tool for generating and verifying Sigstore signatures. You can use it to sign and verify Python package distributions, or anything else!", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/snyk-cli/devcontainer-feature.json b/src/snyk-cli/devcontainer-feature.json index 4d44ae371..33abfe8bb 100644 --- a/src/snyk-cli/devcontainer-feature.json +++ b/src/snyk-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "snyk-cli", - "version": "1.0.2", + "version": "1.0.3", "name": "Snyk CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/snyk-cli", "description": "Snyk CLI scans and monitors your projects for security vulnerabilities.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/sops/devcontainer-feature.json b/src/sops/devcontainer-feature.json index 5a9000a44..6486bf0de 100644 --- a/src/sops/devcontainer-feature.json +++ b/src/sops/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "sops", - "version": "1.0.14", + "version": "1.0.15", "name": "sops (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/sops", "description": "sops is an editor of encrypted files that supports YAML, JSON, ENV, INI and BINARY formats and encrypts with AWS KMS, GCP KMS, Azure Key Vault, age, and PGP.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/spacectl/devcontainer-feature.json b/src/spacectl/devcontainer-feature.json index d80b60992..cb7d6a54c 100644 --- a/src/spacectl/devcontainer-feature.json +++ b/src/spacectl/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "spacectl", - "version": "1.0.5", + "version": "1.0.6", "name": "Spacelift CLI (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/spacectl", "description": "spacectl is a utility wrapping Spacelift's GraphQL API for easy programmatic access in command-line contexts - either in manual interactive mode (in your local shell), or in a predefined CI pipeline (GitHub actions, CircleCI, Jenkins etc).", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/spark-sdkman/devcontainer-feature.json b/src/spark-sdkman/devcontainer-feature.json index d2bb4c270..d1cf2f438 100644 --- a/src/spark-sdkman/devcontainer-feature.json +++ b/src/spark-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "spark-sdkman", - "version": "2.0.16", + "version": "2.0.17", "name": "Spark (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/spark-sdkman", "description": "Apache Spark is an open-source cluster-computing framework. Spark provides an\ninterface for programming entire clusters with implicit data parallelism and\nfault-tolerance.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/spicedb/devcontainer-feature.json b/src/spicedb/devcontainer-feature.json index 3f8567aa3..97b81a3b9 100644 --- a/src/spicedb/devcontainer-feature.json +++ b/src/spicedb/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "spicedb", - "version": "1.0.5", + "version": "1.0.6", "name": "SpiceDB (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/spicedb", "description": "SpiceDB is an open source, Google Zanzibar-inspired, database system for creating and managing security-critical application permissions.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/springboot-sdkman/devcontainer-feature.json b/src/springboot-sdkman/devcontainer-feature.json index a0469b98f..4688073de 100644 --- a/src/springboot-sdkman/devcontainer-feature.json +++ b/src/springboot-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "springboot-sdkman", - "version": "2.0.16", + "version": "2.0.17", "name": "Spring Boot (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/springboot-sdkman", "description": "Spring Boot takes an opinionated view of building production-ready Spring\napplications. It favors convention over configuration and is designed to get you\nup and running as quickly as possible.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/sqlfluff/devcontainer-feature.json b/src/sqlfluff/devcontainer-feature.json index fc5fbc857..659b9b26a 100644 --- a/src/sqlfluff/devcontainer-feature.json +++ b/src/sqlfluff/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "sqlfluff", - "version": "1.0.2", + "version": "1.0.3", "name": "SqlFluff (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/sqlfluff", "description": "Fluff is an extensible and modular linter designed to help you write good SQL and catch errors and bad SQL before it hits your database.", @@ -27,4 +27,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/squarespace-server/devcontainer-feature.json b/src/squarespace-server/devcontainer-feature.json index d85f6aa9f..8399dc786 100644 --- a/src/squarespace-server/devcontainer-feature.json +++ b/src/squarespace-server/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "squarespace-server", - "version": "1.0.2", + "version": "1.0.3", "name": "Squarespace Local Development Server (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/squarespace-server", "description": "The Squarespace local development server is a command line tool that sets up a test server on your computer, allowing you to see changes to your template before making them live", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/sshoogr-sdkman/devcontainer-feature.json b/src/sshoogr-sdkman/devcontainer-feature.json index 20e6a76e6..3aa3c1de2 100644 --- a/src/sshoogr-sdkman/devcontainer-feature.json +++ b/src/sshoogr-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "sshoogr-sdkman", - "version": "2.0.16", + "version": "2.0.17", "name": "Sshoogr (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/sshoogr-sdkman", "description": "Sshoogr is a Groovy based DSL and command line tool for working with remote\nservers through SSH.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/starship-homebrew/devcontainer-feature.json b/src/starship-homebrew/devcontainer-feature.json index 4d5f86d58..e17204bc3 100644 --- a/src/starship-homebrew/devcontainer-feature.json +++ b/src/starship-homebrew/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "starship-homebrew", - "version": "1.0.20", + "version": "1.0.21", "name": "Starship (via Homebrew)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/starship-homebrew", "description": "Starship is fast and highly customizable cross-shell prompt that can display contextual information.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/homebrew-package" ] -} \ No newline at end of file +} diff --git a/src/starship/devcontainer-feature.json b/src/starship/devcontainer-feature.json index 9bc35bd6e..9078540b3 100644 --- a/src/starship/devcontainer-feature.json +++ b/src/starship/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "starship", - "version": "1.0.9", + "version": "1.0.10", "name": "Starship (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/starship", "description": "Starship is fast and highly customizable cross-shell prompt that can display contextual information.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/statsd-exporter/devcontainer-feature.json b/src/statsd-exporter/devcontainer-feature.json index 62e25f3be..13c446a0c 100644 --- a/src/statsd-exporter/devcontainer-feature.json +++ b/src/statsd-exporter/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "statsd-exporter", - "version": "1.0.2", + "version": "1.0.3", "name": "Prometheus StatsD Exporter (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/statsd-exporter", "description": "The StatsD exporter is a drop-in replacement for StatsD. This exporter translates StatsD metrics to Prometheus metrics via configured mapping rules.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/stew/devcontainer-feature.json b/src/stew/devcontainer-feature.json index dadbc0506..03b198a8f 100644 --- a/src/stew/devcontainer-feature.json +++ b/src/stew/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "stew", - "version": "1.0.14", + "version": "1.0.15", "name": "stew (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/stew", "description": "stew is an independent package manager for compiled binaries.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/supabase-cli/devcontainer-feature.json b/src/supabase-cli/devcontainer-feature.json index 1d5cbd20a..1750fecae 100644 --- a/src/supabase-cli/devcontainer-feature.json +++ b/src/supabase-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "supabase-cli", - "version": "1.0.6", + "version": "1.0.7", "name": "Supabase CLI (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/supabase-cli", "description": "The Supabase CLI provides tools to develop your project locally and deploy to the Supabase Platform. You can also use the CLI to manage your Supabase projects, handle database migrations and CI/CD workflows, and generate types directly from your database schema.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/surge-cli/devcontainer-feature.json b/src/surge-cli/devcontainer-feature.json index de609d72a..ed267be47 100644 --- a/src/surge-cli/devcontainer-feature.json +++ b/src/surge-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "surge-cli", - "version": "1.0.2", + "version": "1.0.3", "name": "Surge CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/surge-cli", "description": "Publish HTML, CSS, and JS for free, without leaving the command line.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/sv2v/devcontainer-feature.json b/src/sv2v/devcontainer-feature.json index c308b321c..7939cffd2 100644 --- a/src/sv2v/devcontainer-feature.json +++ b/src/sv2v/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "sv2v", - "version": "1.0.14", + "version": "1.0.15", "name": "sv2v (SystemVerilog to Verilog) (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/sv2v", "description": "sv2v converts SystemVerilog (IEEE 1800-2017) to Verilog (IEEE 1364-2005), with an emphasis on supporting synthesizable language constructs.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/svu-asdf/devcontainer-feature.json b/src/svu-asdf/devcontainer-feature.json index 806d85d2b..4fc2f8746 100644 --- a/src/svu-asdf/devcontainer-feature.json +++ b/src/svu-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "svu-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "svu (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/svu-asdf", "description": "svu is a tool to manage semantic versions at ease.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/syft/devcontainer-feature.json b/src/syft/devcontainer-feature.json index c3a429345..18480310e 100644 --- a/src/syft/devcontainer-feature.json +++ b/src/syft/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "syft", - "version": "1.0.9", + "version": "1.0.10", "name": "Syft (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/syft", "description": "Syft is A CLI tool and Go library for generating a Software Bill of Materials (SBOM) from container images and filesystems.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/syntaqx-serve/devcontainer-feature.json b/src/syntaqx-serve/devcontainer-feature.json index 8296bb6de..553ab3314 100644 --- a/src/syntaqx-serve/devcontainer-feature.json +++ b/src/syntaqx-serve/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "syntaqx-serve", - "version": "1.0.6", + "version": "1.0.7", "name": "serve (by syntaqx) (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/syntaqx-cli", "description": "serve is a static http server anywhere you need one. It's basically python -m SimpleHTTPServer 8080 written in Go, because who can remember that many letters?", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/tailscale/devcontainer-feature.json b/src/tailscale/devcontainer-feature.json index f05fdb30d..50aa078a9 100644 --- a/src/tailscale/devcontainer-feature.json +++ b/src/tailscale/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "tailscale", - "version": "1.0.11", + "version": "1.0.12", "name": "Tailscale (via tailscale.com)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/tailscale", "description": "Tailscale is a VPN service that makes the devices and applications you own accessible anywhere in the world, securely and effortlessly.", @@ -8,4 +8,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/curl-apt-get" ] -} \ No newline at end of file +} diff --git a/src/talosctl/devcontainer-feature.json b/src/talosctl/devcontainer-feature.json index 25d9c6134..7d7e070c9 100644 --- a/src/talosctl/devcontainer-feature.json +++ b/src/talosctl/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "talosctl", - "version": "1.0.0", + "version": "1.0.1", "name": "talosctl (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/talosctl", "description": "A CLI tool that interfaces with the Talos Linux API.", diff --git a/src/talosctl/install.sh b/src/talosctl/install.sh index 70de85293..fd7dfe95a 100644 --- a/src/talosctl/install.sh +++ b/src/talosctl/install.sh @@ -16,6 +16,10 @@ $nanolayer_location \ install \ devcontainer-feature \ "ghcr.io/devcontainers-extra/features/gh-release:1" \ - --option repo='siderolabs/talos' --option binaryNames='talosctl' --option version="$VERSION" --option releaseTagRegex='^(?!.*(alpha|beta)).*$' + --option repo='siderolabs/talos' \ + --option binaryNames='talosctl' \ + --option assetRegex='^.*(?/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + # in case none of them is installed, install wget temporarly + if [ -z $downloader ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_install $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_install $tempdir + else + echo "distro not supported" + exit 1 + fi + downloader="wget" + downloader_installed="true" + fi + + if [ $downloader = "wget" ]; then + wget -q $url -O $output_location + else + curl -sfL $url -o $output_location + fi + + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi + +} + +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + # normalize version + if ! [[ $required_version == v* ]]; then + required_version=v$required_version + fi + + local nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ]; then + nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" + fi + + # make sure its of the required version + if ! [[ -z "${nanolayer_location}" ]]; then + local current_version + current_version=$($nanolayer_location --version) + if ! [[ $current_version == v* ]]; then + current_version=v$current_version + fi + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [[ -z "${nanolayer_location}" ]]; then + + if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up() { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + if [ -x "/sbin/apk" ]; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + nanolayer_location=$tmp_dir/nanolayer + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + declare -g ${variable_name}=$nanolayer_location + +} diff --git a/src/tfsec/devcontainer-feature.json b/src/tfsec/devcontainer-feature.json index 437785343..396c70b00 100644 --- a/src/tfsec/devcontainer-feature.json +++ b/src/tfsec/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "tfsec", - "version": "1.0.5", + "version": "1.0.6", "name": "tfsec (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/tfsec", "description": "tfsec is a static analysis security scanner for your Terraform code. Designed to run locally and in your CI pipelines, developer-friendly output and fully documented checks mean detection and remediation can take place as quickly and efficiently as possible", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/tfswitch/devcontainer-feature.json b/src/tfswitch/devcontainer-feature.json index a81f149a1..7b1de469d 100644 --- a/src/tfswitch/devcontainer-feature.json +++ b/src/tfswitch/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "tfswitch", - "version": "1.0.10", + "version": "1.0.11", "name": "Terraform Switcher (tfswitch) (via warrensbox/terraform-switcher)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/tfswitch", "description": "The tfswitch command line tool lets you switch between different versions of terraform.", @@ -8,4 +8,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/curl-apt-get" ] -} \ No newline at end of file +} diff --git a/src/tldr/devcontainer-feature.json b/src/tldr/devcontainer-feature.json index 72e6b5bdd..d35cc4616 100644 --- a/src/tldr/devcontainer-feature.json +++ b/src/tldr/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "tldr", - "version": "2.0.15", + "version": "2.0.16", "name": "tldr (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/tldr", "description": "The tldr pages are a community effort to simplify the beloved man pages with practical examples.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/tmate/devcontainer-feature.json b/src/tmate/devcontainer-feature.json index 2add1e47f..ba3bea8ad 100644 --- a/src/tmate/devcontainer-feature.json +++ b/src/tmate/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "tmate", - "version": "1.0.6", + "version": "1.0.7", "name": "tmate (via apt-get)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/tmate", "description": "tmate is a terminal multiplexer with instant terminal sharing. It enables a number of terminals to be created, accessed, and controlled from a single screen and be shared with another mates.", @@ -8,4 +8,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/apt-get-packages" ] -} \ No newline at end of file +} diff --git a/src/tmux-apt-get/devcontainer-feature.json b/src/tmux-apt-get/devcontainer-feature.json index f3c1b2e4d..e365c234f 100644 --- a/src/tmux-apt-get/devcontainer-feature.json +++ b/src/tmux-apt-get/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "tmux-apt-get", - "version": "1.0.16", + "version": "1.0.17", "name": "tmux (via apt-get)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/tmux-apt-get", "description": "tmux is a terminal multiplexer: it enables a number of terminals to be created, accessed, and controlled from a single screen. tmux may be detached from a screen and continue running in the background, then later reattached.", @@ -8,4 +8,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/apt-get-packages" ] -} \ No newline at end of file +} diff --git a/src/tmux-homebrew/devcontainer-feature.json b/src/tmux-homebrew/devcontainer-feature.json index 519b8a849..b96770491 100644 --- a/src/tmux-homebrew/devcontainer-feature.json +++ b/src/tmux-homebrew/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "tmux-homebrew", - "version": "1.0.20", + "version": "1.0.21", "name": "tmux (via Homebrew)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/tmux-homebrew", "description": "tmux is a terminal multiplexer: it enables a number of terminals to be created, accessed, and controlled from a single screen. tmux may be detached from a screen and continue running in the background, then later reattached.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/homebrew-package" ] -} \ No newline at end of file +} diff --git a/src/tomcat-sdkman/devcontainer-feature.json b/src/tomcat-sdkman/devcontainer-feature.json index 6076815d9..6b7363234 100644 --- a/src/tomcat-sdkman/devcontainer-feature.json +++ b/src/tomcat-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "tomcat-sdkman", - "version": "2.0.16", + "version": "2.0.17", "name": "Apache Tomcat (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/tomcat-sdkman", "description": "The Apache Tomcat software is an open source implementation of the Java\nServlet, JavaServer Pages, Java Expression Language and Java WebSocket\ntechnologies.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/tooljet-cli/devcontainer-feature.json b/src/tooljet-cli/devcontainer-feature.json index 4cf59ec30..ace7cc405 100644 --- a/src/tooljet-cli/devcontainer-feature.json +++ b/src/tooljet-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "tooljet-cli", - "version": "1.0.2", + "version": "1.0.3", "name": "ToolJet CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/tooljet-cli", "description": "ToolJet is an open-source low-code framework to build and deploy internal tools quickly with minimal engineering effort.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/toolkit-sdkman/devcontainer-feature.json b/src/toolkit-sdkman/devcontainer-feature.json index e54d6cb0e..88617b39b 100644 --- a/src/toolkit-sdkman/devcontainer-feature.json +++ b/src/toolkit-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "toolkit-sdkman", - "version": "2.0.16", + "version": "2.0.17", "name": "ToolKit (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/toolkit-sdkman", "description": "Toolkit is a client command line tool that supports multiple IoT protocols like\nMQTT and COAP. It provides a command line client tool for IoT development.", @@ -42,4 +42,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/tox/devcontainer-feature.json b/src/tox/devcontainer-feature.json index ba734237c..164a871c3 100644 --- a/src/tox/devcontainer-feature.json +++ b/src/tox/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "tox", - "version": "2.0.17", + "version": "2.0.18", "name": "tox (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/tox", "description": "tox is a generic virtual environment management and test command line tool.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/tridentctl-asdf/devcontainer-feature.json b/src/tridentctl-asdf/devcontainer-feature.json index 96248b958..34b1f2b75 100644 --- a/src/tridentctl-asdf/devcontainer-feature.json +++ b/src/tridentctl-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "tridentctl-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "tridentctl (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/tridentctl-asdf", "description": "Installs tridentctl", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/truffle/devcontainer-feature.json b/src/truffle/devcontainer-feature.json index 31b1f7e2b..30fdc8c7f 100644 --- a/src/truffle/devcontainer-feature.json +++ b/src/truffle/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "truffle", - "version": "1.0.2", + "version": "1.0.3", "name": "Truffle (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/truffle", "description": "Truffle is a development environment, testing framework, and asset pipeline for Ethereum, aiming to make life as an Ethereum developer easier.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/ts-node/devcontainer-feature.json b/src/ts-node/devcontainer-feature.json index fa8726bd0..d46f96f5d 100644 --- a/src/ts-node/devcontainer-feature.json +++ b/src/ts-node/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ts-node", - "version": "1.0.1", + "version": "1.0.2", "name": "ts-node (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ts-node", "description": "ts-node is a TypeScript execution engine and REPL for Node.js. It JIT transforms TypeScript into JavaScript, enabling you to directly execute TypeScript on Node.js without precompiling. ", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/tsx/devcontainer-feature.json b/src/tsx/devcontainer-feature.json index 447437f0f..476a18af8 100644 --- a/src/tsx/devcontainer-feature.json +++ b/src/tsx/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "tsx", - "version": "1.0.1", + "version": "1.0.2", "name": "tsx (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/tsx", "description": "tsx is a CLI command (alternative to node) for seamlessly running TypeScript & ESM, in both commonjs & module package types.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/turborepo-npm/devcontainer-feature.json b/src/turborepo-npm/devcontainer-feature.json index 81e3fc83a..64bfcf997 100644 --- a/src/turborepo-npm/devcontainer-feature.json +++ b/src/turborepo-npm/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "turborepo-npm", - "version": "1.0.11", + "version": "1.0.12", "name": "Turborepo (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/turborepo-npm", "description": "Turborepo is a high-performance build system for JavaScript and TypeScript codebases.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/twine/devcontainer-feature.json b/src/twine/devcontainer-feature.json index 10a59cce9..fbfa3fbc8 100644 --- a/src/twine/devcontainer-feature.json +++ b/src/twine/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "twine", - "version": "2.0.17", + "version": "2.0.18", "name": "Twine (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/twine", "description": "Twine is a utility for publishing Python packages on PyPI.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/ty/devcontainer-feature.json b/src/ty/devcontainer-feature.json new file mode 100644 index 000000000..ba183c261 --- /dev/null +++ b/src/ty/devcontainer-feature.json @@ -0,0 +1,25 @@ +{ + "id": "ty", + "version": "1.0.0", + "name": "ty (via Github Releases)", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ty", + "description": "An extremely fast Python type checker and language server, written in Rust.", + "options": { + "version": { + "default": "latest", + "description": "Select the version to install.", + "proposals": [ + "latest" + ], + "type": "string" + } + }, + "customizations": { + "vscode": { + "extensions": [ + "astral-sh.ty" + ] + } + }, + "installsAfter": [] +} diff --git a/src/ty/install.sh b/src/ty/install.sh new file mode 100755 index 000000000..e417b490c --- /dev/null +++ b/src/ty/install.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +set -e + +source ./library_scripts.sh + +# nanolayer is a cli utility which keeps container layers as small as possible +# source code: https://github.com/devcontainers-extra/nanolayer +# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, +# and if missing - will download a temporary copy that automatically get deleted at the end +# of the script +ensure_nanolayer nanolayer_location "v0.5.6" + +# Example nanolayer installation via devcontainer-feature +$nanolayer_location \ + install \ + devcontainer-feature \ + "ghcr.io/devcontainers-extra/features/gh-release:1" \ + --option repo='astral-sh/ty' --option binaryNames='ty' --option version="$VERSION" + +echo 'Done!' diff --git a/src/ty/library_scripts.sh b/src/ty/library_scripts.sh new file mode 100644 index 000000000..f6d0760d7 --- /dev/null +++ b/src/ty/library_scripts.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash + +clean_download() { + # The purpose of this function is to download a file with minimal impact on container layer size + # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a + # temporary manner, and making sure to + # 1. uninstall the downloader at the return of the function + # 2. revert back any changes to the package installer database/cache (for example apt-get lists) + # The above steps will minimize the leftovers being created while installing the downloader + # Supported distros: + # debian/ubuntu/alpine + + url=$1 + output_location=$2 + tempdir=$(mktemp -d) + downloader_installed="" + + function _apt_get_install() { + tempdir=$1 + + # copy current state of apt list - in order to revert back later (minimize contianer layer size) + cp -p -R /var/lib/apt/lists $tempdir + apt-get update -y + apt-get -y install --no-install-recommends wget ca-certificates + } + + function _apt_get_cleanup() { + tempdir=$1 + + echo "removing wget" + apt-get -y purge wget --auto-remove + + echo "revert back apt lists" + rm -rf /var/lib/apt/lists/* + rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists + } + + function _apk_install() { + tempdir=$1 + # copy current state of apk cache - in order to revert back later (minimize contianer layer size) + cp -p -R /var/cache/apk $tempdir + + apk add --no-cache wget + } + + function _apk_cleanup() { + tempdir=$1 + + echo "removing wget" + apk del wget + } + # try to use either wget or curl if one of them already installer + if type curl >/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + # in case none of them is installed, install wget temporarly + if [ -z $downloader ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_install $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_install $tempdir + else + echo "distro not supported" + exit 1 + fi + downloader="wget" + downloader_installed="true" + fi + + if [ $downloader = "wget" ]; then + wget -q $url -O $output_location + else + curl -sfL $url -o $output_location + fi + + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi + +} + +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + # normalize version + if ! [[ $required_version == v* ]]; then + required_version=v$required_version + fi + + local nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ]; then + nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" + fi + + # make sure its of the required version + if ! [[ -z "${nanolayer_location}" ]]; then + local current_version + current_version=$($nanolayer_location --version) + if ! [[ $current_version == v* ]]; then + current_version=v$current_version + fi + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [[ -z "${nanolayer_location}" ]]; then + + if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up() { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + if [ -x "/sbin/apk" ]; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + nanolayer_location=$tmp_dir/nanolayer + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + declare -g ${variable_name}=$nanolayer_location + +} diff --git a/src/typescript/devcontainer-feature.json b/src/typescript/devcontainer-feature.json index 3d0ce281c..fdd74ec27 100644 --- a/src/typescript/devcontainer-feature.json +++ b/src/typescript/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "typescript", - "version": "2.0.15", + "version": "2.0.16", "name": "TypeScript (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/typescript", "description": "TypeScript is a strongly typed programming language that builds on JavaScript, giving you better tooling at any scale.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/typst/devcontainer-feature.json b/src/typst/devcontainer-feature.json index 5183104f6..874bd40c0 100644 --- a/src/typst/devcontainer-feature.json +++ b/src/typst/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "typst", - "version": "1.0.5", + "version": "1.0.6", "name": "Typst (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/typst", "description": "Typst is a new markup-based typesetting system that is designed to be as powerful as LaTeX while being much easier to learn and use.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/ufmt/devcontainer-feature.json b/src/ufmt/devcontainer-feature.json index 5da98aa98..bed16f2bf 100644 --- a/src/ufmt/devcontainer-feature.json +++ b/src/ufmt/devcontainer-feature.json @@ -1,9 +1,9 @@ { "id": "ufmt", - "version": "1.0.1", + "version": "1.0.2", "name": "ufmt (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/ufmt", - "description": "\u00b5fmt is a safe, atomic code formatter for Python built on top of black and \u00b5sort.", + "description": "µfmt is a safe, atomic code formatter for Python built on top of black and µsort.", "options": { "version": { "default": "latest", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/upx/devcontainer-feature.json b/src/upx/devcontainer-feature.json index 9daf49ba2..67e558678 100644 --- a/src/upx/devcontainer-feature.json +++ b/src/upx/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "upx", - "version": "1.0.14", + "version": "1.0.15", "name": "UPX (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/upx", "description": "UPX is a free, secure, portable, extendable, high-performance executable packer for several executable formats.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/uv-tool/devcontainer-feature.json b/src/uv-tool/devcontainer-feature.json new file mode 100644 index 000000000..2af62076b --- /dev/null +++ b/src/uv-tool/devcontainer-feature.json @@ -0,0 +1,42 @@ +{ + "id": "uv-tool", + "version": "1.0.0", + "name": "Python tool (via uv)", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/uv-tool", + "description": "Installs a Python tool using uv.", + "options": { + "uv_version": { + "default": "latest", + "description": "The version of uv to install. Set to 'latest' to always get the latest version.", + "type": "string" + }, + "package": { + "default": "", + "description": "The package to install commands from.", + "type": "string" + }, + "from": { + "default": "", + "description": "Use the given package to provide the command. By default, the package name is assumed to match the command name.", + "type": "string" + }, + "with": { + "default": "", + "description": "Space-separated list of additional packages to include as dependencies (does not install their executables). Supports version constraints, e.g., 'mkdocs-material mkdocs-minify-plugin>=0.7,<0.8'", + "type": "string" + }, + "with-executables-from": { + "default": "", + "description": "Comma-separated list of packages to include as dependencies and install their executables, e.g., 'ansible-core,ansible-lint'", + "type": "string" + }, + "python": { + "default": "", + "description": "Specify the Python version to use.", + "type": "string" + } + }, + "installsAfter": [ + "ghcr.io/devcontainers-extra/features/uv" + ] +} diff --git a/src/uv-tool/install.sh b/src/uv-tool/install.sh new file mode 100755 index 000000000..0f1782401 --- /dev/null +++ b/src/uv-tool/install.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash + +set -e + +UV_VERSION="${UV_VERSION:-"latest"}" +PACKAGE="${PACKAGE:-""}" +FROM="${FROM:-""}" +WITH="${WITH:-""}" +WITH_EXECUTABLES_FROM="${WITH_EXECUTABLES_FROM:-""}" +PYTHON="${PYTHON:-""}" + +USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" + +# Validate required parameters +if [ -z "${PACKAGE}" ]; then + echo "Error: PACKAGE option is required" + exit 1 +fi + +source ./library_scripts.sh + +# nanolayer is a cli utility which keeps container layers as small as possible +# source code: https://github.com/devcontainers-extra/nanolayer +# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, +# and if missing - will download a temporary copy that automatically get deleted at the end +# of the script +ensure_nanolayer nanolayer_location "v0.5.6" + +$nanolayer_location \ + install \ + devcontainer-feature \ + "ghcr.io/devcontainers-extra/features/uv:1" \ + --option version="$UV_VERSION" + +# Determine the appropriate non-root user +if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then + USERNAME="" + possible_users=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)") + for current_user in "${possible_users[@]}"; do + if id -u "${current_user}" > /dev/null 2>&1; then + USERNAME=${current_user} + break + fi + done + if [ "${USERNAME}" = "" ]; then + USERNAME=root + fi +elif [ "${USERNAME}" = "none" ] || ! id -u "${USERNAME}" > /dev/null 2>&1; then + USERNAME=root +fi + +uv_args=("${PACKAGE}") + +[ -n "${FROM}" ] && uv_args+=(--from "${FROM}") +[ -n "${WITH_EXECUTABLES_FROM}" ] && uv_args+=(--with-executables-from "${WITH_EXECUTABLES_FROM}") +[ -n "${PYTHON}" ] && uv_args+=(--python "${PYTHON}") + +# Convert space-delimited WITH packages to multiple --with flags +if [ -n "${WITH}" ]; then + read -ra with_array <<<"${WITH}" + for pkg in "${with_array[@]}"; do + [ -n "$pkg" ] && uv_args+=(--with "$pkg") + done +fi + +if [ "${USERNAME}" != "root" ] && [ "${USERNAME}" != "" ]; then + echo "Installing ${PACKAGE} for user ${USERNAME}..." + # Export the uv_args array as a properly quoted string + uv_cmd="uv tool install $(printf '%q ' "${uv_args[@]}")" + sudo -u "${USERNAME}" bash -c " + export PATH=\"/home/${USERNAME}/.local/bin:\$PATH\" + ${uv_cmd} + " +else + echo "Installing ${PACKAGE} for root..." + uv tool install "${uv_args[@]}" +fi + +echo 'Done!' diff --git a/src/uv-tool/library_scripts.sh b/src/uv-tool/library_scripts.sh new file mode 100644 index 000000000..f6d0760d7 --- /dev/null +++ b/src/uv-tool/library_scripts.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash + +clean_download() { + # The purpose of this function is to download a file with minimal impact on container layer size + # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a + # temporary manner, and making sure to + # 1. uninstall the downloader at the return of the function + # 2. revert back any changes to the package installer database/cache (for example apt-get lists) + # The above steps will minimize the leftovers being created while installing the downloader + # Supported distros: + # debian/ubuntu/alpine + + url=$1 + output_location=$2 + tempdir=$(mktemp -d) + downloader_installed="" + + function _apt_get_install() { + tempdir=$1 + + # copy current state of apt list - in order to revert back later (minimize contianer layer size) + cp -p -R /var/lib/apt/lists $tempdir + apt-get update -y + apt-get -y install --no-install-recommends wget ca-certificates + } + + function _apt_get_cleanup() { + tempdir=$1 + + echo "removing wget" + apt-get -y purge wget --auto-remove + + echo "revert back apt lists" + rm -rf /var/lib/apt/lists/* + rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists + } + + function _apk_install() { + tempdir=$1 + # copy current state of apk cache - in order to revert back later (minimize contianer layer size) + cp -p -R /var/cache/apk $tempdir + + apk add --no-cache wget + } + + function _apk_cleanup() { + tempdir=$1 + + echo "removing wget" + apk del wget + } + # try to use either wget or curl if one of them already installer + if type curl >/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + # in case none of them is installed, install wget temporarly + if [ -z $downloader ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_install $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_install $tempdir + else + echo "distro not supported" + exit 1 + fi + downloader="wget" + downloader_installed="true" + fi + + if [ $downloader = "wget" ]; then + wget -q $url -O $output_location + else + curl -sfL $url -o $output_location + fi + + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi + +} + +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + # normalize version + if ! [[ $required_version == v* ]]; then + required_version=v$required_version + fi + + local nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ]; then + nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" + fi + + # make sure its of the required version + if ! [[ -z "${nanolayer_location}" ]]; then + local current_version + current_version=$($nanolayer_location --version) + if ! [[ $current_version == v* ]]; then + current_version=v$current_version + fi + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [[ -z "${nanolayer_location}" ]]; then + + if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up() { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + if [ -x "/sbin/apk" ]; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + nanolayer_location=$tmp_dir/nanolayer + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + declare -g ${variable_name}=$nanolayer_location + +} diff --git a/src/uv/devcontainer-feature.json b/src/uv/devcontainer-feature.json new file mode 100644 index 000000000..ce9995d06 --- /dev/null +++ b/src/uv/devcontainer-feature.json @@ -0,0 +1,18 @@ +{ + "id": "uv", + "version": "1.0.2", + "name": "uv (via GitHub Releases)", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/uv", + "description": "An extremely fast Python package and project manager, written in Rust.", + "options": { + "version": { + "default": "latest", + "description": "Select the version to install.", + "proposals": [ + "latest" + ], + "type": "string" + } + }, + "installsAfter": [] +} diff --git a/src/uv/install.sh b/src/uv/install.sh new file mode 100755 index 000000000..a2d76746a --- /dev/null +++ b/src/uv/install.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +set -e + +source ./library_scripts.sh + +# nanolayer is a cli utility which keeps container layers as small as possible +# source code: https://github.com/devcontainers-extra/nanolayer +# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, +# and if missing - will download a temporary copy that automatically get deleted at the end +# of the script +ensure_nanolayer nanolayer_location "v0.5.6" + +# uv uses uv-`uname -m`-unknown-linux-gnu.tar.gz naming, +# the default "arm64" filter for aarch64 would match a 32 bit arm binary instead +arch_segment="" +case "$(uname -m)" in + x86_64) + arch_segment="x86_64" + ;; + aarch64|arm64) + arch_segment="aarch64" + ;; + *) + arch_segment="$(uname -m)" + ;; +esac +asset_regex="^uv-${arch_segment}-unknown-linux-gnu\\.tar\\.gz$" + +# Example nanolayer installation via devcontainer-feature +$nanolayer_location \ + install \ + devcontainer-feature \ + "ghcr.io/devcontainers-extra/features/gh-release:1" \ + --option repo='astral-sh/uv' \ + --option binaryNames='uv,uvx' \ + --option assetRegex="$asset_regex" \ + --option version="$VERSION" \ + --option libName='uv' + +echo 'Done!' diff --git a/src/uv/library_scripts.sh b/src/uv/library_scripts.sh new file mode 100644 index 000000000..f6d0760d7 --- /dev/null +++ b/src/uv/library_scripts.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash + +clean_download() { + # The purpose of this function is to download a file with minimal impact on container layer size + # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a + # temporary manner, and making sure to + # 1. uninstall the downloader at the return of the function + # 2. revert back any changes to the package installer database/cache (for example apt-get lists) + # The above steps will minimize the leftovers being created while installing the downloader + # Supported distros: + # debian/ubuntu/alpine + + url=$1 + output_location=$2 + tempdir=$(mktemp -d) + downloader_installed="" + + function _apt_get_install() { + tempdir=$1 + + # copy current state of apt list - in order to revert back later (minimize contianer layer size) + cp -p -R /var/lib/apt/lists $tempdir + apt-get update -y + apt-get -y install --no-install-recommends wget ca-certificates + } + + function _apt_get_cleanup() { + tempdir=$1 + + echo "removing wget" + apt-get -y purge wget --auto-remove + + echo "revert back apt lists" + rm -rf /var/lib/apt/lists/* + rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists + } + + function _apk_install() { + tempdir=$1 + # copy current state of apk cache - in order to revert back later (minimize contianer layer size) + cp -p -R /var/cache/apk $tempdir + + apk add --no-cache wget + } + + function _apk_cleanup() { + tempdir=$1 + + echo "removing wget" + apk del wget + } + # try to use either wget or curl if one of them already installer + if type curl >/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + # in case none of them is installed, install wget temporarly + if [ -z $downloader ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_install $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_install $tempdir + else + echo "distro not supported" + exit 1 + fi + downloader="wget" + downloader_installed="true" + fi + + if [ $downloader = "wget" ]; then + wget -q $url -O $output_location + else + curl -sfL $url -o $output_location + fi + + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi + +} + +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + # normalize version + if ! [[ $required_version == v* ]]; then + required_version=v$required_version + fi + + local nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ]; then + nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" + fi + + # make sure its of the required version + if ! [[ -z "${nanolayer_location}" ]]; then + local current_version + current_version=$($nanolayer_location --version) + if ! [[ $current_version == v* ]]; then + current_version=v$current_version + fi + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [[ -z "${nanolayer_location}" ]]; then + + if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up() { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + if [ -x "/sbin/apk" ]; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + nanolayer_location=$tmp_dir/nanolayer + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + declare -g ${variable_name}=$nanolayer_location + +} diff --git a/src/vault-asdf/devcontainer-feature.json b/src/vault-asdf/devcontainer-feature.json index 07c3545cb..2f74b8731 100644 --- a/src/vault-asdf/devcontainer-feature.json +++ b/src/vault-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "vault-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "Vault (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/vault-asdf", "description": "Vault secures, stores, and tightly controls access to tokens, passwords, certificates, API keys, and other secrets in modern computing.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/vercel-cli/devcontainer-feature.json b/src/vercel-cli/devcontainer-feature.json index 2cd8308e5..67f1111c3 100644 --- a/src/vercel-cli/devcontainer-feature.json +++ b/src/vercel-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "vercel-cli", - "version": "1.0.3", + "version": "1.0.4", "name": "Vercel CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/vercel-cli", "description": "With Vercel CLI command-line interface (CLI) you can interact with the Vercel platform using a terminal, or through an automated system, enabling you to retrieve logs, manage certificates, replicate your deployment environment locally, manage Domain Name System (DNS) records, and more.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/vercel-ncc/devcontainer-feature.json b/src/vercel-ncc/devcontainer-feature.json index e41c0c43f..82423ca11 100644 --- a/src/vercel-ncc/devcontainer-feature.json +++ b/src/vercel-ncc/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "vercel-ncc", - "version": "1.0.3", + "version": "1.0.4", "name": "ncc (by Vercel) (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/vercel-ncc", "description": "ncc is a simple CLI for compiling a Node.js module into a single file, together with all its dependencies, gcc-style.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/vercel-pkg/devcontainer-feature.json b/src/vercel-pkg/devcontainer-feature.json index 874522d04..f5c3ef141 100644 --- a/src/vercel-pkg/devcontainer-feature.json +++ b/src/vercel-pkg/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "vercel-pkg", - "version": "1.0.3", + "version": "1.0.4", "name": "pkg (by Vercel) (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/vercel-pkg", "description": "This command line interface enables you to package your Node.js project into an executable that can be run even on devices without Node.js installed.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/vercel-release/devcontainer-feature.json b/src/vercel-release/devcontainer-feature.json index 1aa99e7e3..08afd6912 100644 --- a/src/vercel-release/devcontainer-feature.json +++ b/src/vercel-release/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "vercel-release", - "version": "1.0.3", + "version": "1.0.4", "name": "Release (by Vercel) (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/vercel-release", "description": "Release is a command line tool to automatically generate a new GitHub Release and populates it with the changes (commits) made since the last release.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/vercel-serve/devcontainer-feature.json b/src/vercel-serve/devcontainer-feature.json index 7b02e41a5..d8d33b324 100644 --- a/src/vercel-serve/devcontainer-feature.json +++ b/src/vercel-serve/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "vercel-serve", - "version": "1.0.3", + "version": "1.0.4", "name": "serve (by Vercel) (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/vercel-serve", "description": "serve helps you serve a static site, single page application or just a static file (no matter if on your device or on the local network).", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/vscode-cli/devcontainer-feature.json b/src/vscode-cli/devcontainer-feature.json index bd32278f0..21d541a6f 100644 --- a/src/vscode-cli/devcontainer-feature.json +++ b/src/vscode-cli/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "Visual Studio Code CLI", "id": "vscode-cli", - "version": "1.0.1", + "version": "1.0.2", "description": "Visual Studio Code CLI (official Microsoft build), which manages the Visual Studio Code Server and vscode.dev tunnels.", "documentationURL": "https://github.com/devcontainers-extra/features/tree/main/src/vscode-cli", "options": { @@ -14,4 +14,4 @@ "description": "Specify the Visual Studio Code CLI version to install; or \"latest\"; or \"commit:\"" } } -} \ No newline at end of file +} diff --git a/src/vscode-server/devcontainer-feature.json b/src/vscode-server/devcontainer-feature.json index 63366c8cf..742b70ae6 100644 --- a/src/vscode-server/devcontainer-feature.json +++ b/src/vscode-server/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "Visual Studio Code Server", "id": "vscode-server", - "version": "1.0.1", + "version": "1.0.2", "description": "Visual Studio Code Server (official Microsoft build), which hosts Visual Studio Code via HTTP", "documentationURL": "https://github.com/devcontainers-extra/features/tree/main/src/vscode-server", "options": { @@ -14,4 +14,4 @@ "description": "Specify the Visual Studio Code Server version to install; or \"latest\"; or \"commit:\"" } } -} \ No newline at end of file +} diff --git a/src/vtop/devcontainer-feature.json b/src/vtop/devcontainer-feature.json index e95497183..75b014d34 100644 --- a/src/vtop/devcontainer-feature.json +++ b/src/vtop/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "vtop", - "version": "2.0.15", + "version": "2.0.16", "name": "vtop (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/vtop", "description": "vtop is a graphical activity monitor for the command line.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/vue-cli/devcontainer-feature.json b/src/vue-cli/devcontainer-feature.json index 3a2600379..e58cf72a4 100644 --- a/src/vue-cli/devcontainer-feature.json +++ b/src/vue-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "vue-cli", - "version": "2.0.15", + "version": "2.0.16", "name": "Vue CLI (via npm)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/vue-cli", "description": "Vue CLI is a full system for rapid Vue.js development.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/npm-package", "ghcr.io/devcontainers/features/node" ] -} \ No newline at end of file +} diff --git a/src/vulture/devcontainer-feature.json b/src/vulture/devcontainer-feature.json index 6320e66fb..d6a1d6e28 100644 --- a/src/vulture/devcontainer-feature.json +++ b/src/vulture/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "vulture", - "version": "2.0.17", + "version": "2.0.18", "name": "Vulture (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/vulture", "description": "Vulture finds unused code in Python programs.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/w3m-apt-get/devcontainer-feature.json b/src/w3m-apt-get/devcontainer-feature.json index 9c5a95baa..163461bb6 100644 --- a/src/w3m-apt-get/devcontainer-feature.json +++ b/src/w3m-apt-get/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "w3m-apt-get", - "version": "1.0.16", + "version": "1.0.17", "name": "w3m (via apt-get)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/w3m-apt-get", "description": "w3m is a free software/open source text-based web browser and terminal pager.", @@ -8,4 +8,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/apt-get-packages" ] -} \ No newline at end of file +} diff --git a/src/w3m-homebrew/devcontainer-feature.json b/src/w3m-homebrew/devcontainer-feature.json index 0cf27cf5e..1768789eb 100644 --- a/src/w3m-homebrew/devcontainer-feature.json +++ b/src/w3m-homebrew/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "w3m-homebrew", - "version": "1.0.20", + "version": "1.0.21", "name": "w3m (via Homebrew)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/w3m-homebrew", "description": "w3m is a free software/open source text-based web browser and terminal pager.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/homebrew-package" ] -} \ No newline at end of file +} diff --git a/src/waypoint-asdf/devcontainer-feature.json b/src/waypoint-asdf/devcontainer-feature.json index 76d5729e9..da4abe323 100644 --- a/src/waypoint-asdf/devcontainer-feature.json +++ b/src/waypoint-asdf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "waypoint-asdf", - "version": "2.0.15", + "version": "2.0.16", "name": "Waypoint (via asdf)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/waypoint-asdf", "description": "Waypoint is an open source solution that provides a modern workflow for build, deploy, and release across platforms.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/asdf-package" ] -} \ No newline at end of file +} diff --git a/src/webtau-sdkman/devcontainer-feature.json b/src/webtau-sdkman/devcontainer-feature.json index 259fded52..a799be8bf 100644 --- a/src/webtau-sdkman/devcontainer-feature.json +++ b/src/webtau-sdkman/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "webtau-sdkman", - "version": "2.0.15", + "version": "2.0.16", "name": "Webtau (via SDKMAN)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/webtau-sdkman", "description": "Webtau (short for web test automation) is a testing API, command line tool and a\nframework to write unit, integration and end-to-end tests. Tests can span\nmultiple application layers like REST-API, Graph QL, Browser, Database and CLI.\nConsistent set of matchers and testing concepts work across all testing layers.\nUse REPL mode to speed-up tests development. Leverage rich reporting to\nsignificantly cut down failure investigation time.", @@ -41,4 +41,4 @@ "ghcr.io/ebaskoro/devcontainer-features/sdkman", "ghcr.io/devcontainers/features/java" ] -} \ No newline at end of file +} diff --git a/src/wget-apt-get/devcontainer-feature.json b/src/wget-apt-get/devcontainer-feature.json index 3d412623c..f7ed79e51 100644 --- a/src/wget-apt-get/devcontainer-feature.json +++ b/src/wget-apt-get/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "wget-apt-get", - "version": "1.0.16", + "version": "1.0.17", "name": "Wget (via apt-get)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/wget-apt-get", "description": "Wget is a free software package for retrieving files using HTTP, HTTPS, FTP and FTPS, the most widely used Internet protocols.", @@ -8,4 +8,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/apt-get-packages" ] -} \ No newline at end of file +} diff --git a/src/wget-homebrew/devcontainer-feature.json b/src/wget-homebrew/devcontainer-feature.json index 990fe9a03..5da4cbb25 100644 --- a/src/wget-homebrew/devcontainer-feature.json +++ b/src/wget-homebrew/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "wget-homebrew", - "version": "1.0.20", + "version": "1.0.21", "name": "Wget (via Homebrew)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/wget-homebrew", "description": "Wget is a free software package for retrieving files using HTTP, HTTPS, FTP and FTPS, the most widely used Internet protocols.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/homebrew-package" ] -} \ No newline at end of file +} diff --git a/src/wireguard-apt-get/devcontainer-feature.json b/src/wireguard-apt-get/devcontainer-feature.json index bb22c37e1..03d4fab58 100644 --- a/src/wireguard-apt-get/devcontainer-feature.json +++ b/src/wireguard-apt-get/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "wireguard-apt-get", - "version": "1.0.11", + "version": "1.0.12", "name": "WireGuard (via apt-get)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/wireguard-apt-get", "description": "WireGuard is an extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography.", @@ -8,4 +8,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/apt-get-packages" ] -} \ No newline at end of file +} diff --git a/src/worktrunk/devcontainer-feature.json b/src/worktrunk/devcontainer-feature.json new file mode 100644 index 000000000..47811b0f1 --- /dev/null +++ b/src/worktrunk/devcontainer-feature.json @@ -0,0 +1,18 @@ +{ + "id": "worktrunk", + "version": "1.0.0", + "name": "worktrunk (via Github Releases)", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/worktrunk", + "description": "Worktrunk is a CLI for Git worktree management, designed for parallel AI agent workflows", + "options": { + "version": { + "default": "latest", + "description": "Select the version to install.", + "proposals": [ + "latest" + ], + "type": "string" + } + }, + "installsAfter": [] +} diff --git a/src/worktrunk/install.sh b/src/worktrunk/install.sh new file mode 100755 index 000000000..efdd12f8b --- /dev/null +++ b/src/worktrunk/install.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +set -e + +source ./library_scripts.sh + +# nanolayer is a cli utility which keeps container layers as small as possible +# source code: https://github.com/devcontainers-extra/nanolayer +# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, +# and if missing - will download a temporary copy that automatically get deleted at the end +# of the script +ensure_nanolayer nanolayer_location "v0.5.6" + +# Example nanolayer installation via devcontainer-feature +$nanolayer_location \ + install \ + devcontainer-feature \ + "ghcr.io/devcontainers-extra/features/gh-release:1" \ + --option repo='max-sixty/worktrunk' --option binaryNames='wt' --option version="$VERSION" \ + --option assetRegex='worktrunk.*(tar).*' + +echo 'Done!' diff --git a/src/worktrunk/library_scripts.sh b/src/worktrunk/library_scripts.sh new file mode 100644 index 000000000..f6d0760d7 --- /dev/null +++ b/src/worktrunk/library_scripts.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash + +clean_download() { + # The purpose of this function is to download a file with minimal impact on container layer size + # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a + # temporary manner, and making sure to + # 1. uninstall the downloader at the return of the function + # 2. revert back any changes to the package installer database/cache (for example apt-get lists) + # The above steps will minimize the leftovers being created while installing the downloader + # Supported distros: + # debian/ubuntu/alpine + + url=$1 + output_location=$2 + tempdir=$(mktemp -d) + downloader_installed="" + + function _apt_get_install() { + tempdir=$1 + + # copy current state of apt list - in order to revert back later (minimize contianer layer size) + cp -p -R /var/lib/apt/lists $tempdir + apt-get update -y + apt-get -y install --no-install-recommends wget ca-certificates + } + + function _apt_get_cleanup() { + tempdir=$1 + + echo "removing wget" + apt-get -y purge wget --auto-remove + + echo "revert back apt lists" + rm -rf /var/lib/apt/lists/* + rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists + } + + function _apk_install() { + tempdir=$1 + # copy current state of apk cache - in order to revert back later (minimize contianer layer size) + cp -p -R /var/cache/apk $tempdir + + apk add --no-cache wget + } + + function _apk_cleanup() { + tempdir=$1 + + echo "removing wget" + apk del wget + } + # try to use either wget or curl if one of them already installer + if type curl >/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + # in case none of them is installed, install wget temporarly + if [ -z $downloader ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_install $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_install $tempdir + else + echo "distro not supported" + exit 1 + fi + downloader="wget" + downloader_installed="true" + fi + + if [ $downloader = "wget" ]; then + wget -q $url -O $output_location + else + curl -sfL $url -o $output_location + fi + + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi + +} + +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + # normalize version + if ! [[ $required_version == v* ]]; then + required_version=v$required_version + fi + + local nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ]; then + nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" + fi + + # make sure its of the required version + if ! [[ -z "${nanolayer_location}" ]]; then + local current_version + current_version=$($nanolayer_location --version) + if ! [[ $current_version == v* ]]; then + current_version=v$current_version + fi + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [[ -z "${nanolayer_location}" ]]; then + + if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up() { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + if [ -x "/sbin/apk" ]; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + nanolayer_location=$tmp_dir/nanolayer + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + declare -g ${variable_name}=$nanolayer_location + +} diff --git a/src/xmrig/devcontainer-feature.json b/src/xmrig/devcontainer-feature.json index feddd0d0a..b30a494ee 100644 --- a/src/xmrig/devcontainer-feature.json +++ b/src/xmrig/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "xmrig", - "version": "1.0.2", + "version": "1.0.3", "name": "XMRig (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/xmrig", "description": "XMRig is a high performance, open source, cross platform RandomX, KawPow, CryptoNight and GhostRider unified CPU/GPU miner and RandomX benchmark.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/xonsh/devcontainer-feature.json b/src/xonsh/devcontainer-feature.json index 24b2f9402..17de1006a 100644 --- a/src/xonsh/devcontainer-feature.json +++ b/src/xonsh/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "xonsh", - "version": "1.0.4", + "version": "1.0.5", "name": "Xonsh (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/xonsh", "description": "Xonsh is a Python-powered, cross-platform, Unix-gazing shell language and command prompt.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/yamllint/devcontainer-feature.json b/src/yamllint/devcontainer-feature.json index 84f4e789e..acddee42e 100644 --- a/src/yamllint/devcontainer-feature.json +++ b/src/yamllint/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "yamllint", - "version": "2.0.17", + "version": "2.0.18", "name": "yamllint (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/yamllint", "description": "yamllint is a Python utility / library to sort imports alphabetically, and automatically separated into sections and by type.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/yapf/devcontainer-feature.json b/src/yapf/devcontainer-feature.json index 2d4691947..b4d11280c 100644 --- a/src/yapf/devcontainer-feature.json +++ b/src/yapf/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "yapf", - "version": "2.0.17", + "version": "2.0.18", "name": "yapf (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/yapf", "description": "yapf is a formatter for Python files.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/youtube-dl/devcontainer-feature.json b/src/youtube-dl/devcontainer-feature.json index 27b679e4f..a49bf7196 100644 --- a/src/youtube-dl/devcontainer-feature.json +++ b/src/youtube-dl/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "youtube-dl", - "version": "2.0.17", + "version": "2.0.18", "name": "youtube-dl (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/youtube-dl", "description": "youtube-dl is a command-line program to download videos from YouTube.com and other video sites.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/youtubeuploader/devcontainer-feature.json b/src/youtubeuploader/devcontainer-feature.json index 4bd093a5e..15d08cfee 100644 --- a/src/youtubeuploader/devcontainer-feature.json +++ b/src/youtubeuploader/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "youtubeuploader", - "version": "1.0.3", + "version": "1.0.4", "name": "Youtube Uploader (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/youtubeuploader", "description": "Scripted uploads to Youtube.", @@ -17,4 +17,4 @@ "installsAfter": [ "ghcr.io/devcontainers-extra/features/gh-release" ] -} \ No newline at end of file +} diff --git a/src/yt-dlp/devcontainer-feature.json b/src/yt-dlp/devcontainer-feature.json index de65ffaf4..b14b9b842 100644 --- a/src/yt-dlp/devcontainer-feature.json +++ b/src/yt-dlp/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "yt-dlp", - "version": "2.0.17", + "version": "2.0.18", "name": "yt-dlp (via pipx)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/yt-dlp", "description": "yt-dlp is a youtube-dl fork with additional features and fixes.", @@ -18,4 +18,4 @@ "ghcr.io/devcontainers-extra/features/pipx-package", "ghcr.io/devcontainers/features/python" ] -} \ No newline at end of file +} diff --git a/src/zig/devcontainer-feature.json b/src/zig/devcontainer-feature.json index c6bd1303c..aa1215be1 100644 --- a/src/zig/devcontainer-feature.json +++ b/src/zig/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "Zig (via ziglang.org)", "id": "zig", - "version": "1.1.1", + "version": "1.1.2", "description": "Zig is a general-purpose programming language and toolchain for maintaining robust, optimal and reusable software.", "documentationURL": "https://github.com/devcontainers-extra/features/tree/main/src/zig", "options": { @@ -15,4 +15,4 @@ "description": "Select the Zig version you would like to install" } } -} \ No newline at end of file +} diff --git a/src/zsh-plugins/devcontainer-feature.json b/src/zsh-plugins/devcontainer-feature.json index eadd43975..aef1f6adb 100644 --- a/src/zsh-plugins/devcontainer-feature.json +++ b/src/zsh-plugins/devcontainer-feature.json @@ -1,39 +1,39 @@ { - "name": "ZSH Plugins", - "id": "zsh-plugins", - "version": "0.0.4", - "description": "Install (Oh-My-)ZSH plugins", - "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/zsh-plugins", - "installsAfter": [ - "ghcr.io/devcontainers/features/common-utils", - "ghcr.io/devcontainers/features/git" - ], - "options": { - "plugins": { - "type": "string", - "default": "", - "proposals": [ - "ssh-agent npm" - ], - "description": "Space separated list of ZSH plugin names that will be added to .zshrc" - }, - "omzPlugins": { - "type": "string", - "default": "", - "proposals": [ - "https://github.com/zsh-users/zsh-autosuggestions" - ], - "description": "Space separated list of Oh-My-ZSH custom plugin Git URLs that will be cloned" - }, - "username": { - "type": "string", - "default": "", - "proposals": [ - "root", - "node", - "vscode" - ], - "description": "For which user to setup ZSH plugins, by default uses 'remoteUser' or 'containerUser' from config" + "name": "ZSH Plugins", + "id": "zsh-plugins", + "version": "0.0.5", + "description": "Install (Oh-My-)ZSH plugins", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/zsh-plugins", + "installsAfter": [ + "ghcr.io/devcontainers/features/common-utils", + "ghcr.io/devcontainers/features/git" + ], + "options": { + "plugins": { + "type": "string", + "default": "", + "proposals": [ + "ssh-agent npm" + ], + "description": "Space separated list of ZSH plugin names that will be added to .zshrc" + }, + "omzPlugins": { + "type": "string", + "default": "", + "proposals": [ + "https://github.com/zsh-users/zsh-autosuggestions" + ], + "description": "Space separated list of Oh-My-ZSH custom plugin Git URLs that will be cloned" + }, + "username": { + "type": "string", + "default": "", + "proposals": [ + "root", + "node", + "vscode" + ], + "description": "For which user to setup ZSH plugins, by default uses 'remoteUser' or 'containerUser' from config" + } } - } -} \ No newline at end of file +} diff --git a/templates/src/devcontainer-feature.json b/templates/bak/src/devcontainer-feature.json similarity index 100% rename from templates/src/devcontainer-feature.json rename to templates/bak/src/devcontainer-feature.json diff --git a/templates/src/install.sh b/templates/bak/src/install.sh similarity index 100% rename from templates/src/install.sh rename to templates/bak/src/install.sh diff --git a/templates/bak/src/library_scripts.sh b/templates/bak/src/library_scripts.sh new file mode 100644 index 000000000..f6d0760d7 --- /dev/null +++ b/templates/bak/src/library_scripts.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash + +clean_download() { + # The purpose of this function is to download a file with minimal impact on container layer size + # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a + # temporary manner, and making sure to + # 1. uninstall the downloader at the return of the function + # 2. revert back any changes to the package installer database/cache (for example apt-get lists) + # The above steps will minimize the leftovers being created while installing the downloader + # Supported distros: + # debian/ubuntu/alpine + + url=$1 + output_location=$2 + tempdir=$(mktemp -d) + downloader_installed="" + + function _apt_get_install() { + tempdir=$1 + + # copy current state of apt list - in order to revert back later (minimize contianer layer size) + cp -p -R /var/lib/apt/lists $tempdir + apt-get update -y + apt-get -y install --no-install-recommends wget ca-certificates + } + + function _apt_get_cleanup() { + tempdir=$1 + + echo "removing wget" + apt-get -y purge wget --auto-remove + + echo "revert back apt lists" + rm -rf /var/lib/apt/lists/* + rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists + } + + function _apk_install() { + tempdir=$1 + # copy current state of apk cache - in order to revert back later (minimize contianer layer size) + cp -p -R /var/cache/apk $tempdir + + apk add --no-cache wget + } + + function _apk_cleanup() { + tempdir=$1 + + echo "removing wget" + apk del wget + } + # try to use either wget or curl if one of them already installer + if type curl >/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + # in case none of them is installed, install wget temporarly + if [ -z $downloader ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_install $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_install $tempdir + else + echo "distro not supported" + exit 1 + fi + downloader="wget" + downloader_installed="true" + fi + + if [ $downloader = "wget" ]; then + wget -q $url -O $output_location + else + curl -sfL $url -o $output_location + fi + + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi + +} + +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + # normalize version + if ! [[ $required_version == v* ]]; then + required_version=v$required_version + fi + + local nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ]; then + nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" + fi + + # make sure its of the required version + if ! [[ -z "${nanolayer_location}" ]]; then + local current_version + current_version=$($nanolayer_location --version) + if ! [[ $current_version == v* ]]; then + current_version=v$current_version + fi + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [[ -z "${nanolayer_location}" ]]; then + + if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up() { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + if [ -x "/sbin/apk" ]; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + nanolayer_location=$tmp_dir/nanolayer + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + declare -g ${variable_name}=$nanolayer_location + +} diff --git a/templates/bak/test/scenarios.json b/templates/bak/test/scenarios.json new file mode 100644 index 000000000..48ca39c54 --- /dev/null +++ b/templates/bak/test/scenarios.json @@ -0,0 +1,16 @@ +{ + "test_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "": {} + } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "": { + "version": "x.y.z" + } + } + } +} \ No newline at end of file diff --git a/templates/bak/test/test.sh b/templates/bak/test/test.sh new file mode 100755 index 000000000..b2873a73c --- /dev/null +++ b/templates/bak/test/test.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "something is installed" something --version + +reportResults diff --git a/templates/bak/test/test_debian.sh b/templates/bak/test/test_debian.sh new file mode 100755 index 000000000..b2873a73c --- /dev/null +++ b/templates/bak/test/test_debian.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "something is installed" something --version + +reportResults diff --git a/templates/bak/test/test_specific_version.sh b/templates/bak/test/test_specific_version.sh new file mode 100755 index 000000000..e4858fa21 --- /dev/null +++ b/templates/bak/test/test_specific_version.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "something version is equal to x.y.z" sh -c "something --version | grep 'x.y.z'" + +reportResults diff --git a/templates/gh-release/boilerplate.yml b/templates/gh-release/boilerplate.yml new file mode 100644 index 000000000..6f1ba7a9e --- /dev/null +++ b/templates/gh-release/boilerplate.yml @@ -0,0 +1,12 @@ +variables: + - name: ID + description: The unique identifier for the feature (e.g., akamai-cli). + + - name: Description + description: A brief description of the feature. + + - name: Repository + description: The GitHub repository in the format "owner/repo" (e.g., akamai/cli). + + - name: BinaryNames + description: The names of the binaries to install from the release (comma-separated if multiple). diff --git a/templates/gh-release/devcontainer-feature.json b/templates/gh-release/devcontainer-feature.json new file mode 100644 index 000000000..466db7e1e --- /dev/null +++ b/templates/gh-release/devcontainer-feature.json @@ -0,0 +1,18 @@ +{ + "id": "{{.ID}}", + "version": "1.0.0", + "name": "{{.ID}} (via Github Releases)", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/{{.ID}}", + "description": "{{.Description}}", + "options": { + "version": { + "default": "latest", + "description": "Select the version to install.", + "proposals": [ + "latest" + ], + "type": "string" + } + }, + "installsAfter": [] +} diff --git a/templates/gh-release/install.sh b/templates/gh-release/install.sh new file mode 100755 index 000000000..ff1c69aeb --- /dev/null +++ b/templates/gh-release/install.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +set -e + +source ./library_scripts.sh + +# nanolayer is a cli utility which keeps container layers as small as possible +# source code: https://github.com/devcontainers-extra/nanolayer +# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, +# and if missing - will download a temporary copy that automatically get deleted at the end +# of the script +ensure_nanolayer nanolayer_location "v0.5.6" + +# Example nanolayer installation via devcontainer-feature +$nanolayer_location \ + install \ + devcontainer-feature \ + "ghcr.io/devcontainers-extra/features/gh-release:1" \ + --option repo='{{.Repository}}' --option binaryNames='{{.BinaryNames}}' --option version="$VERSION" + +echo 'Done!' diff --git a/templates/gh-release/library_scripts.sh b/templates/gh-release/library_scripts.sh new file mode 100644 index 000000000..f6d0760d7 --- /dev/null +++ b/templates/gh-release/library_scripts.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash + +clean_download() { + # The purpose of this function is to download a file with minimal impact on container layer size + # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a + # temporary manner, and making sure to + # 1. uninstall the downloader at the return of the function + # 2. revert back any changes to the package installer database/cache (for example apt-get lists) + # The above steps will minimize the leftovers being created while installing the downloader + # Supported distros: + # debian/ubuntu/alpine + + url=$1 + output_location=$2 + tempdir=$(mktemp -d) + downloader_installed="" + + function _apt_get_install() { + tempdir=$1 + + # copy current state of apt list - in order to revert back later (minimize contianer layer size) + cp -p -R /var/lib/apt/lists $tempdir + apt-get update -y + apt-get -y install --no-install-recommends wget ca-certificates + } + + function _apt_get_cleanup() { + tempdir=$1 + + echo "removing wget" + apt-get -y purge wget --auto-remove + + echo "revert back apt lists" + rm -rf /var/lib/apt/lists/* + rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists + } + + function _apk_install() { + tempdir=$1 + # copy current state of apk cache - in order to revert back later (minimize contianer layer size) + cp -p -R /var/cache/apk $tempdir + + apk add --no-cache wget + } + + function _apk_cleanup() { + tempdir=$1 + + echo "removing wget" + apk del wget + } + # try to use either wget or curl if one of them already installer + if type curl >/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + # in case none of them is installed, install wget temporarly + if [ -z $downloader ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_install $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_install $tempdir + else + echo "distro not supported" + exit 1 + fi + downloader="wget" + downloader_installed="true" + fi + + if [ $downloader = "wget" ]; then + wget -q $url -O $output_location + else + curl -sfL $url -o $output_location + fi + + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi + +} + +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + # normalize version + if ! [[ $required_version == v* ]]; then + required_version=v$required_version + fi + + local nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ]; then + nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" + fi + + # make sure its of the required version + if ! [[ -z "${nanolayer_location}" ]]; then + local current_version + current_version=$($nanolayer_location --version) + if ! [[ $current_version == v* ]]; then + current_version=v$current_version + fi + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [[ -z "${nanolayer_location}" ]]; then + + if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up() { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + if [ -x "/sbin/apk" ]; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + nanolayer_location=$tmp_dir/nanolayer + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + declare -g ${variable_name}=$nanolayer_location + +} diff --git a/templates/test/boilerplate.yml b/templates/test/boilerplate.yml new file mode 100644 index 000000000..fe68ad94c --- /dev/null +++ b/templates/test/boilerplate.yml @@ -0,0 +1,13 @@ +variables: + - name: ID + description: The unique identifier for the feature (e.g., akamai-cli). + + - name: BinaryNames + description: The names of the binaries to install from the release (comma-separated if multiple). + + - name: BinaryVersionCommands + description: The commands to check the version of the installed binaries (comma-separated if multiple). + default: "--version" + + - name: BinaryNonLatestVersions + description: Specific non-latest versions for test scenarios (comma-separated if multiple). For example, if 1.2.3 is the latest version, you should use 1.2.2 here. diff --git a/templates/test/scenarios.json b/templates/test/scenarios.json index 48ca39c54..283d4b0ab 100644 --- a/templates/test/scenarios.json +++ b/templates/test/scenarios.json @@ -2,15 +2,15 @@ "test_debian": { "image": "mcr.microsoft.com/devcontainers/base:debian", "features": { - "": {} + "{{.ID}}": {} } }, "test_specific_version": { "image": "mcr.microsoft.com/devcontainers/base:debian", "features": { - "": { - "version": "x.y.z" + "{{.ID}}": { + "version": "{{index (splitList "," .BinaryNonLatestVersions) 0}}" } } } -} \ No newline at end of file +} diff --git a/templates/test/test.sh b/templates/test/test.sh index b2873a73c..f5101fa3f 100755 --- a/templates/test/test.sh +++ b/templates/test/test.sh @@ -4,6 +4,17 @@ set -e source dev-container-features-test-lib -check "something is installed" something --version +{{- $binaryNames := splitList "," .BinaryNames}} +{{- $versionCommands := splitList "," .BinaryVersionCommands}} +{{- range $index, $binary := $binaryNames}} +{{- $versionCmd := "--version"}} +{{- if gt (len $versionCommands) 1}} +{{- $versionCmd = index $versionCommands $index}} +{{- else if eq (len $versionCommands) 1}} +{{- $versionCmd = index $versionCommands 0}} +{{- end}} + +check "{{$binary}} is installed" {{$binary}} {{$versionCmd}} +{{- end}} reportResults diff --git a/templates/test/test_debian.sh b/templates/test/test_debian.sh index b2873a73c..f7780a21d 100755 --- a/templates/test/test_debian.sh +++ b/templates/test/test_debian.sh @@ -3,7 +3,17 @@ set -e source dev-container-features-test-lib +{{- $binaryNames := splitList "," .BinaryNames}} +{{- $versionCommands := splitList "," .BinaryVersionCommands}} +{{- range $index, $binary := $binaryNames}} +{{- $versionCmd := "--version"}} +{{- if gt (len $versionCommands) 1}} +{{- $versionCmd = index $versionCommands $index}} +{{- else if eq (len $versionCommands) 1}} +{{- $versionCmd = index $versionCommands 0}} +{{- end}} -check "something is installed" something --version +check "{{$binary}} is installed" {{$binary}} {{$versionCmd}} +{{- end}} reportResults diff --git a/templates/test/test_specific_version.sh b/templates/test/test_specific_version.sh index e4858fa21..0108dac96 100755 --- a/templates/test/test_specific_version.sh +++ b/templates/test/test_specific_version.sh @@ -3,7 +3,19 @@ set -e source dev-container-features-test-lib +{{- $binaryNames := splitList "," .BinaryNames}} +{{- $versionCommands := splitList "," .BinaryVersionCommands}} +{{- $nonLatestVersions := splitList "," .BinaryNonLatestVersions}} +{{- range $index, $binary := $binaryNames}} +{{- $versionCmd := "--version"}} +{{- if gt (len $versionCommands) 1}} +{{- $versionCmd = index $versionCommands $index}} +{{- else if eq (len $versionCommands) 1}} +{{- $versionCmd = index $versionCommands 0}} +{{- end}} +{{- $nonLatestVersion := index $nonLatestVersions $index}} -check "something version is equal to x.y.z" sh -c "something --version | grep 'x.y.z'" +check "{{$binary}} version is equal to {{$nonLatestVersion}}" sh -c "{{$binary}} {{$versionCmd}} | grep '{{$nonLatestVersion}}'" +{{- end}} reportResults diff --git a/archive/test/age-keygen/scenarios.json b/test/age-keygen/scenarios.json similarity index 100% rename from archive/test/age-keygen/scenarios.json rename to test/age-keygen/scenarios.json diff --git a/archive/test/age-keygen/test_defaults_debian.sh b/test/age-keygen/test_defaults_debian.sh similarity index 100% rename from archive/test/age-keygen/test_defaults_debian.sh rename to test/age-keygen/test_defaults_debian.sh diff --git a/test/ansible/scenarios.json b/test/ansible/scenarios.json index fe4ce9d59..f0246a912 100644 --- a/test/ansible/scenarios.json +++ b/test/ansible/scenarios.json @@ -24,5 +24,13 @@ "version": "2.13.0" } } + }, + "test_injections": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "ansible": { + "injections": "hcloud" + } + } } } \ No newline at end of file diff --git a/test/ansible/test_injections.sh b/test/ansible/test_injections.sh new file mode 100644 index 000000000..25d659675 --- /dev/null +++ b/test/ansible/test_injections.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "hcloud package is injected" bash -c "pipx list --include-injected | grep hcloud" + +reportResults diff --git a/test/archon/scenarios.json b/test/archon/scenarios.json new file mode 100644 index 000000000..ab5f5292f --- /dev/null +++ b/test/archon/scenarios.json @@ -0,0 +1,16 @@ +{ + "test_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "archon": {} + } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "archon": { + "version": "0.3.4" + } + } + } +} diff --git a/test/archon/test.sh b/test/archon/test.sh new file mode 100755 index 000000000..2739ca851 --- /dev/null +++ b/test/archon/test.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "archon is installed" archon version + +reportResults diff --git a/test/archon/test_debian.sh b/test/archon/test_debian.sh new file mode 100755 index 000000000..2739ca851 --- /dev/null +++ b/test/archon/test_debian.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "archon is installed" archon version + +reportResults diff --git a/test/archon/test_specific_version.sh b/test/archon/test_specific_version.sh new file mode 100755 index 000000000..68dd898f3 --- /dev/null +++ b/test/archon/test_specific_version.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "archon version is equal to 0.3.4" sh -c "archon version | grep '0.3.4'" + +reportResults diff --git a/test/argo-cd/scenarios.json b/test/argo-cd/scenarios.json index 657eda1cc..bb3f8cb24 100644 --- a/test/argo-cd/scenarios.json +++ b/test/argo-cd/scenarios.json @@ -4,5 +4,13 @@ "features": { "argo-cd": {} } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "argo-cd": { + "version": "2.14.14" + } + } } } \ No newline at end of file diff --git a/test/argo-cd/test_specific_version.sh b/test/argo-cd/test_specific_version.sh new file mode 100755 index 000000000..4bed18f4d --- /dev/null +++ b/test/argo-cd/test_specific_version.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "argocd version is equal to 2.14.14" sh -c "argocd version | grep '2.14.14'" + +reportResults diff --git a/test/bazel-compile-commands/scenarios.json b/test/bazel-compile-commands/scenarios.json new file mode 100644 index 000000000..a893dbd73 --- /dev/null +++ b/test/bazel-compile-commands/scenarios.json @@ -0,0 +1,25 @@ +{ + "test": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-24.04", + "features": { + "ghcr.io/devcontainers-community/features/bazel:1": {}, + "bazel-compile-commands": {} + } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-24.04", + "features": { + "ghcr.io/devcontainers-community/features/bazel:1": {}, + "bazel-compile-commands": { + "version": "0.22.4" + } + } + }, + "test_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "ghcr.io/devcontainers-community/features/bazel:1": {}, + "bazel-compile-commands": {} + } + } +} diff --git a/test/bazel-compile-commands/test.sh b/test/bazel-compile-commands/test.sh new file mode 100755 index 000000000..2b2cfd07a --- /dev/null +++ b/test/bazel-compile-commands/test.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "bazel-compile-commands is installed" bazel-compile-commands --version +check "bazelisk is installed" bazelisk --version + +reportResults diff --git a/test/bazel-compile-commands/test_debian.sh b/test/bazel-compile-commands/test_debian.sh new file mode 100755 index 000000000..2b2cfd07a --- /dev/null +++ b/test/bazel-compile-commands/test_debian.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "bazel-compile-commands is installed" bazel-compile-commands --version +check "bazelisk is installed" bazelisk --version + +reportResults diff --git a/test/bazel-compile-commands/test_specific_version.sh b/test/bazel-compile-commands/test_specific_version.sh new file mode 100644 index 000000000..a42376b83 --- /dev/null +++ b/test/bazel-compile-commands/test_specific_version.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +which bazel-compile-commands +check "bazel-compile-commands version is 0.22.4" sh -c "bazel-compile-commands --version 2>&1 | grep '0.22.4'" +check "bazelisk is installed" bazelisk --version + +reportResults diff --git a/test/boilerplate/scenarios.json b/test/boilerplate/scenarios.json new file mode 100644 index 000000000..facce5d10 --- /dev/null +++ b/test/boilerplate/scenarios.json @@ -0,0 +1,16 @@ +{ + "test_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "boilerplate": {} + } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "boilerplate": { + "version": "0.10.0" + } + } + } +} diff --git a/test/boilerplate/test.sh b/test/boilerplate/test.sh new file mode 100755 index 000000000..c6f6a6404 --- /dev/null +++ b/test/boilerplate/test.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "boilerplate is installed" boilerplate --version + +reportResults diff --git a/test/boilerplate/test_debian.sh b/test/boilerplate/test_debian.sh new file mode 100755 index 000000000..c6f6a6404 --- /dev/null +++ b/test/boilerplate/test_debian.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "boilerplate is installed" boilerplate --version + +reportResults diff --git a/test/boilerplate/test_specific_version.sh b/test/boilerplate/test_specific_version.sh new file mode 100755 index 000000000..fc712fba7 --- /dev/null +++ b/test/boilerplate/test_specific_version.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "boilerplate version is equal to 0.10.0" sh -c "boilerplate --version | grep '0.10.0'" + +reportResults diff --git a/archive/test/boundary-asdf/scenarios.json b/test/boundary-asdf/scenarios.json similarity index 100% rename from archive/test/boundary-asdf/scenarios.json rename to test/boundary-asdf/scenarios.json diff --git a/archive/test/boundary-asdf/test.sh b/test/boundary-asdf/test.sh similarity index 100% rename from archive/test/boundary-asdf/test.sh rename to test/boundary-asdf/test.sh diff --git a/test/btm/scenarios.json b/test/btm/scenarios.json new file mode 100644 index 000000000..88b24d836 --- /dev/null +++ b/test/btm/scenarios.json @@ -0,0 +1,16 @@ +{ + "test_defaults_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "btm": {} + } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "btm": { + "version": "0.11.0" + } + } + } +} \ No newline at end of file diff --git a/archive/test/btm/test_defaults_debian.sh b/test/btm/test_defaults_debian.sh similarity index 100% rename from archive/test/btm/test_defaults_debian.sh rename to test/btm/test_defaults_debian.sh diff --git a/test/btm/test_specific_version.sh b/test/btm/test_specific_version.sh new file mode 100644 index 000000000..2476ea3a8 --- /dev/null +++ b/test/btm/test_specific_version.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "btm version is equal to 0.11.0" sh -c "btm --version | grep '0.11.0'" + +reportResults diff --git a/test/bun-package/scenarios.json b/test/bun-package/scenarios.json new file mode 100644 index 000000000..a9bd26496 --- /dev/null +++ b/test/bun-package/scenarios.json @@ -0,0 +1,62 @@ +{ + "test_install_angular_cli": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "bun": {}, + "bun-package": { + "version": "latest", + "package": "@angular/cli" + } + } + }, + "test_install_typescript": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "bun": {}, + "bun-package": { + "version": "latest", + "package": "typescript" + } + } + }, + "test_ubuntu": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "features": { + "bun": {}, + "bun-package": { + "version": "latest", + "package": "typescript" + } + } + }, + "test_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "bun": {}, + "bun-package": { + "version": "latest", + "package": "typescript" + } + } + }, + "test_alpine": { + "image": "mcr.microsoft.com/devcontainers/base:alpine", + "features": { + "bun": {}, + "bun-package": { + "version": "latest", + "package": "typescript" + } + } + }, + "test_specific_package_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "bun": {}, + "bun-package": { + "version": "5.5.4", + "package": "typescript" + } + } + } +} \ No newline at end of file diff --git a/test/bun-package/test_alpine.sh b/test/bun-package/test_alpine.sh new file mode 100644 index 000000000..1b6760e60 --- /dev/null +++ b/test/bun-package/test_alpine.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "typescript is installed on Alpine (via bun-package)" bunx tsc --version + +reportResults diff --git a/test/bun-package/test_debian.sh b/test/bun-package/test_debian.sh new file mode 100644 index 000000000..64bb96b6b --- /dev/null +++ b/test/bun-package/test_debian.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "typescript is installed on Debian (via bun-package)" bunx tsc --version + +reportResults diff --git a/test/bun-package/test_install_angular_cli.sh b/test/bun-package/test_install_angular_cli.sh new file mode 100644 index 000000000..485a2f8db --- /dev/null +++ b/test/bun-package/test_install_angular_cli.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -e + +source dev-container-features-test-lib + +check "Angular CLI is installed (via bun-package)" bunx ng version + +reportResults diff --git a/test/bun-package/test_install_typescript.sh b/test/bun-package/test_install_typescript.sh new file mode 100644 index 000000000..ddb7dbffc --- /dev/null +++ b/test/bun-package/test_install_typescript.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "typescript is installed (via bun-package)" bunx tsc --version + +reportResults diff --git a/test/bun-package/test_specific_package_version.sh b/test/bun-package/test_specific_package_version.sh new file mode 100644 index 000000000..27ca1be83 --- /dev/null +++ b/test/bun-package/test_specific_package_version.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "typescript version is equal to 5.5.4" sh -c "bunx tsc --version | grep '^Version 5.5.4'" + +reportResults diff --git a/test/bun-package/test_ubuntu.sh b/test/bun-package/test_ubuntu.sh new file mode 100644 index 000000000..614fb6611 --- /dev/null +++ b/test/bun-package/test_ubuntu.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "typescript is installed on Ubuntu (via bun-package)" bunx tsc --version + +reportResults diff --git a/test/bun/scenarios.json b/test/bun/scenarios.json new file mode 100644 index 000000000..241794675 --- /dev/null +++ b/test/bun/scenarios.json @@ -0,0 +1,28 @@ +{ + "test_ubuntu": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "features": { + "bun": {} + } + }, + "test_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "bun": {} + } + }, + "test_alpine": { + "image": "mcr.microsoft.com/devcontainers/base:alpine", + "features": { + "bun": {} + } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "bun": { + "version": "1.2.20" + } + } + } +} \ No newline at end of file diff --git a/test/bun/test.sh b/test/bun/test.sh new file mode 100755 index 000000000..0835be055 --- /dev/null +++ b/test/bun/test.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "bun is installed" bun --version + +reportResults diff --git a/test/bun/test_alpine.sh b/test/bun/test_alpine.sh new file mode 100644 index 000000000..0835be055 --- /dev/null +++ b/test/bun/test_alpine.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "bun is installed" bun --version + +reportResults diff --git a/test/bun/test_debian.sh b/test/bun/test_debian.sh new file mode 100755 index 000000000..0835be055 --- /dev/null +++ b/test/bun/test_debian.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "bun is installed" bun --version + +reportResults diff --git a/test/bun/test_specific_version.sh b/test/bun/test_specific_version.sh new file mode 100755 index 000000000..f32b754a8 --- /dev/null +++ b/test/bun/test_specific_version.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +set -e + +# shellcheck disable=SC1091 +# dev-container-features-test-lib is provided by the test framework at runtime +source dev-container-features-test-lib + +check "bun version is equal to 1.2.20" sh -c "bun --version | grep '^1.2.20'" + +reportResults diff --git a/test/bun/test_ubuntu.sh b/test/bun/test_ubuntu.sh new file mode 100644 index 000000000..0835be055 --- /dev/null +++ b/test/bun/test_ubuntu.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "bun is installed" bun --version + +reportResults diff --git a/test/claude-code/scenarios.json b/test/claude-code/scenarios.json new file mode 100644 index 000000000..6f06352cc --- /dev/null +++ b/test/claude-code/scenarios.json @@ -0,0 +1,16 @@ +{ + "test_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "claude-code": {} + } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "claude-code": { + "version": "2.0.30" + } + } + } +} \ No newline at end of file diff --git a/test/claude-code/test.sh b/test/claude-code/test.sh new file mode 100644 index 000000000..d8c00b08c --- /dev/null +++ b/test/claude-code/test.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "claude is installed" claude --version + +reportResults diff --git a/test/claude-code/test_debian.sh b/test/claude-code/test_debian.sh new file mode 100644 index 000000000..cdaa1733d --- /dev/null +++ b/test/claude-code/test_debian.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "claude is installed" claude --version +check "~/.claude is owned by the current user" test "$(stat -c %u "$HOME/.claude")" = "$(id -u)" +check "~/.local/share/claude is owned by the current user" test "$(stat -c %u "$HOME/.local/share/claude")" = "$(id -u)" + +reportResults diff --git a/test/claude-code/test_specific_version.sh b/test/claude-code/test_specific_version.sh new file mode 100644 index 000000000..5a0b564f2 --- /dev/null +++ b/test/claude-code/test_specific_version.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "claude version is equal to 2.0.30" sh -c "claude --version | grep '2.0.30'" + +reportResults diff --git a/test/codebuddy-code/scenarios.json b/test/codebuddy-code/scenarios.json new file mode 100644 index 000000000..2e9e50421 --- /dev/null +++ b/test/codebuddy-code/scenarios.json @@ -0,0 +1,16 @@ +{ + "test_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "codebuddy-code": {} + } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "codebuddy-code": { + "version": "2.16.0" + } + } + } +} \ No newline at end of file diff --git a/test/codebuddy-code/test.sh b/test/codebuddy-code/test.sh new file mode 100755 index 000000000..89f009cc6 --- /dev/null +++ b/test/codebuddy-code/test.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "CodeBuddy is installed" codebuddy --version + +reportResults diff --git a/test/codebuddy-code/test_debian.sh b/test/codebuddy-code/test_debian.sh new file mode 100755 index 000000000..89f009cc6 --- /dev/null +++ b/test/codebuddy-code/test_debian.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "CodeBuddy is installed" codebuddy --version + +reportResults diff --git a/test/codebuddy-code/test_specific_version.sh b/test/codebuddy-code/test_specific_version.sh new file mode 100755 index 000000000..3f66754bf --- /dev/null +++ b/test/codebuddy-code/test_specific_version.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "CodeBuddy version is equal to 2.16.0" sh -c "codebuddy --version | grep '2.16.0'" + +reportResults diff --git a/test/codename-goose-cli/scenarios.json b/test/codename-goose-cli/scenarios.json new file mode 100644 index 000000000..e77198f34 --- /dev/null +++ b/test/codename-goose-cli/scenarios.json @@ -0,0 +1,16 @@ +{ + "test_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "codename-goose-cli": {} + } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "codename-goose-cli": { + "version": "v1.0.35" + } + } + } +} \ No newline at end of file diff --git a/test/codename-goose-cli/test.sh b/test/codename-goose-cli/test.sh new file mode 100755 index 000000000..aa0fb88c9 --- /dev/null +++ b/test/codename-goose-cli/test.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "goose is installed" goose --version + +reportResults diff --git a/test/codename-goose-cli/test_debian.sh b/test/codename-goose-cli/test_debian.sh new file mode 100755 index 000000000..aa0fb88c9 --- /dev/null +++ b/test/codename-goose-cli/test_debian.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "goose is installed" goose --version + +reportResults diff --git a/test/codename-goose-cli/test_specific_version.sh b/test/codename-goose-cli/test_specific_version.sh new file mode 100755 index 000000000..7b6107818 --- /dev/null +++ b/test/codename-goose-cli/test_specific_version.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "goose version is equal to 1.0.35" sh -c "goose --version | grep '1.0.35'" + +reportResults diff --git a/test/dart/scenarios.json b/test/dart/scenarios.json new file mode 100644 index 000000000..f561c70df --- /dev/null +++ b/test/dart/scenarios.json @@ -0,0 +1,16 @@ +{ + "test_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "dart": {} + } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "dart": { + "version": "3.9.3" + } + } + } +} \ No newline at end of file diff --git a/test/dart/test.sh b/test/dart/test.sh new file mode 100755 index 000000000..1fe0590eb --- /dev/null +++ b/test/dart/test.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "dart is installed" dart --version + +reportResults diff --git a/test/dart/test_debian.sh b/test/dart/test_debian.sh new file mode 100755 index 000000000..8a04fbb07 --- /dev/null +++ b/test/dart/test_debian.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "dart --version" dart --version + +reportResults diff --git a/test/dart/test_specific_version.sh b/test/dart/test_specific_version.sh new file mode 100755 index 000000000..765cf9503 --- /dev/null +++ b/test/dart/test_specific_version.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "dart version is equal to 3.9.3" sh -c "dart --version | grep '3.9.3'" + +reportResults diff --git a/test/eza/scenarios.json b/test/eza/scenarios.json new file mode 100644 index 000000000..11c445a23 --- /dev/null +++ b/test/eza/scenarios.json @@ -0,0 +1,16 @@ +{ + "test_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "eza": {} + } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "eza": { + "version": "0.23.0" + } + } + } +} diff --git a/test/eza/test.sh b/test/eza/test.sh new file mode 100755 index 000000000..0915d023a --- /dev/null +++ b/test/eza/test.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "eza is installed" eza --version + +reportResults diff --git a/test/eza/test_debian.sh b/test/eza/test_debian.sh new file mode 100755 index 000000000..0915d023a --- /dev/null +++ b/test/eza/test_debian.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "eza is installed" eza --version + +reportResults diff --git a/test/eza/test_specific_version.sh b/test/eza/test_specific_version.sh new file mode 100755 index 000000000..cd1b7b650 --- /dev/null +++ b/test/eza/test_specific_version.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "eza version is equal to 0.23.0" sh -c "eza --version | grep '0.23.0'" + +reportResults diff --git a/test/gofumpt/scenarios.json b/test/gofumpt/scenarios.json new file mode 100644 index 000000000..ddb717af8 --- /dev/null +++ b/test/gofumpt/scenarios.json @@ -0,0 +1,16 @@ +{ + "test_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "gofumpt": {} + } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "gofumpt": { + "version": "0.9.1" + } + } + } +} diff --git a/test/gofumpt/test.sh b/test/gofumpt/test.sh new file mode 100755 index 000000000..5b32aea25 --- /dev/null +++ b/test/gofumpt/test.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "gofumpt is installed" gofumpt --version + +reportResults diff --git a/test/gofumpt/test_debian.sh b/test/gofumpt/test_debian.sh new file mode 100755 index 000000000..5b32aea25 --- /dev/null +++ b/test/gofumpt/test_debian.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "gofumpt is installed" gofumpt --version + +reportResults diff --git a/test/gofumpt/test_specific_version.sh b/test/gofumpt/test_specific_version.sh new file mode 100755 index 000000000..cc1d6d3bb --- /dev/null +++ b/test/gofumpt/test_specific_version.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "gofumpt version is equal to 0.9.1" sh -c "gofumpt --version | grep '0.9.1'" + +reportResults diff --git a/test/golangci-lint/scenarios.json b/test/golangci-lint/scenarios.json new file mode 100644 index 000000000..e02c2fb21 --- /dev/null +++ b/test/golangci-lint/scenarios.json @@ -0,0 +1,16 @@ +{ + "test_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "golangci-lint": {} + } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "golangci-lint": { + "version": "2.11.3" + } + } + } +} diff --git a/test/golangci-lint/test.sh b/test/golangci-lint/test.sh new file mode 100755 index 000000000..0308f30a2 --- /dev/null +++ b/test/golangci-lint/test.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "golangci-lint is installed" golangci-lint --version + +reportResults diff --git a/test/golangci-lint/test_debian.sh b/test/golangci-lint/test_debian.sh new file mode 100755 index 000000000..0308f30a2 --- /dev/null +++ b/test/golangci-lint/test_debian.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "golangci-lint is installed" golangci-lint --version + +reportResults diff --git a/test/golangci-lint/test_specific_version.sh b/test/golangci-lint/test_specific_version.sh new file mode 100755 index 000000000..e673274ff --- /dev/null +++ b/test/golangci-lint/test_specific_version.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "golangci-lint version is equal to 2.11.3" sh -c "golangci-lint --version | grep '2.11.3'" + +reportResults diff --git a/test/graphite-cli/scenarios.json b/test/graphite-cli/scenarios.json new file mode 100644 index 000000000..2f13583fc --- /dev/null +++ b/test/graphite-cli/scenarios.json @@ -0,0 +1,8 @@ +{ + "test_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "graphite-cli": {} + } + } +} diff --git a/test/graphite-cli/test_debian.sh b/test/graphite-cli/test_debian.sh new file mode 100755 index 000000000..8dd0f8f1d --- /dev/null +++ b/test/graphite-cli/test_debian.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "gt --help" gt --help + +reportResults diff --git a/test/infisical/scenarios.json b/test/infisical/scenarios.json new file mode 100644 index 000000000..3c0188728 --- /dev/null +++ b/test/infisical/scenarios.json @@ -0,0 +1,16 @@ +{ + "test_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "infisical": {} + } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "infisical": { + "version": "0.43.45" + } + } + } +} diff --git a/test/infisical/test.sh b/test/infisical/test.sh new file mode 100755 index 000000000..e37186ff3 --- /dev/null +++ b/test/infisical/test.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "infisical is installed" infisical --version + +reportResults diff --git a/test/infisical/test_debian.sh b/test/infisical/test_debian.sh new file mode 100755 index 000000000..e37186ff3 --- /dev/null +++ b/test/infisical/test_debian.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "infisical is installed" infisical --version + +reportResults diff --git a/test/infisical/test_specific_version.sh b/test/infisical/test_specific_version.sh new file mode 100755 index 000000000..48f0ce71f --- /dev/null +++ b/test/infisical/test_specific_version.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "infisical version is equal to 0.43.45" sh -c "infisical --version | grep '0.43.45'" + +reportResults diff --git a/test/npm-packages/scenarios.json b/test/npm-packages/scenarios.json index d5363099d..d9581aec6 100644 --- a/test/npm-packages/scenarios.json +++ b/test/npm-packages/scenarios.json @@ -3,7 +3,7 @@ "image": "mcr.microsoft.com/devcontainers/base:debian", "features": { "npm-packages": { - "packages": "eslint@9.20.1,nodemon,prettier@3.5.2" + "packages": "eslint@9.20.1,nodemon,prettier@3.5.2,@angular/cli@19.2.1,@biomejs/biome" } } } diff --git a/test/npm-packages/test_debian_versions.sh b/test/npm-packages/test_debian_versions.sh index 4463caa7e..cb688c17d 100755 --- a/test/npm-packages/test_debian_versions.sh +++ b/test/npm-packages/test_debian_versions.sh @@ -7,5 +7,7 @@ source dev-container-features-test-lib check "eslint version is equal to 9.20.1" bash -c "eslint --version | grep 'v9.20.1'" check "nodemon is installed" nodemon --version check "prettier version is equal to 3.5.2" bash -c "prettier --version | grep '3.5.2'" +check "@angular/cli version is equal to 19.2.1" bash -c "ng --version | grep '19.2.1'" +check "@biomejs/biome is installed" biome --version reportResults diff --git a/test/ocaml-opam/scenarios.json b/test/ocaml-opam/scenarios.json new file mode 100644 index 000000000..7e8af74b2 --- /dev/null +++ b/test/ocaml-opam/scenarios.json @@ -0,0 +1,32 @@ +{ + "test_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "ocaml-opam": {} + } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "ocaml-opam": { + "version": "4.14.2" + } + } + }, + "test_no_platform_tools": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "ocaml-opam": { + "installPlatformTools": false + } + } + }, + "test_additional_packages": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "ocaml-opam": { + "additionalPackages": "ounit2 qcheck-core" + } + } + } +} diff --git a/test/ocaml-opam/test_additional_packages.sh b/test/ocaml-opam/test_additional_packages.sh new file mode 100755 index 000000000..1b3e7e772 --- /dev/null +++ b/test/ocaml-opam/test_additional_packages.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "OUnit is installed" sh -c "opam list | grep ounit" +check "QCheck is installed" sh -c "opam list | grep qcheck" + +reportResults diff --git a/test/ocaml-opam/test_debian.sh b/test/ocaml-opam/test_debian.sh new file mode 100755 index 000000000..8237241c3 --- /dev/null +++ b/test/ocaml-opam/test_debian.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "opam is installed" opam --version +check "OCaml is installed" ocamlc --version +check "UTop is installed" utop -version + +check "no opam warning" sh -c "test $(opam switch 2>&1 | grep --count 'WARNING') -eq 0" + +reportResults diff --git a/test/ocaml-opam/test_no_platform_tools.sh b/test/ocaml-opam/test_no_platform_tools.sh new file mode 100755 index 000000000..69e7b5c19 --- /dev/null +++ b/test/ocaml-opam/test_no_platform_tools.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "no utop" sh -c "! command -v utop" + +reportResults diff --git a/test/ocaml-opam/test_specific_version.sh b/test/ocaml-opam/test_specific_version.sh new file mode 100755 index 000000000..279689b1a --- /dev/null +++ b/test/ocaml-opam/test_specific_version.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "OCaml version is equal to 4.14.2" sh -c "ocamlc --version | grep '4.14.2'" + +reportResults diff --git a/test/opencode/scenarios.json b/test/opencode/scenarios.json new file mode 100644 index 000000000..cfad1a85e --- /dev/null +++ b/test/opencode/scenarios.json @@ -0,0 +1,16 @@ +{ + "test_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "opencode": {} + } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "opencode": { + "version": "1.0.176" + } + } + } +} diff --git a/test/opencode/test.sh b/test/opencode/test.sh new file mode 100755 index 000000000..c10e98aad --- /dev/null +++ b/test/opencode/test.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "opencode is installed" opencode --version + +reportResults diff --git a/test/opencode/test_debian.sh b/test/opencode/test_debian.sh new file mode 100755 index 000000000..c10e98aad --- /dev/null +++ b/test/opencode/test_debian.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "opencode is installed" opencode --version + +reportResults diff --git a/test/opencode/test_specific_version.sh b/test/opencode/test_specific_version.sh new file mode 100755 index 000000000..c374514b2 --- /dev/null +++ b/test/opencode/test_specific_version.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "opencode version is equal to 1.0.176" sh -c "opencode --version | grep '1.0.176'" + +reportResults diff --git a/test/opengrep/scenarios.json b/test/opengrep/scenarios.json new file mode 100644 index 000000000..666eabe99 --- /dev/null +++ b/test/opengrep/scenarios.json @@ -0,0 +1,16 @@ +{ + "test_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "opengrep": {} + } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "opengrep": { + "version": "1.18.0" + } + } + } +} diff --git a/test/opengrep/test.sh b/test/opengrep/test.sh new file mode 100755 index 000000000..54223790c --- /dev/null +++ b/test/opengrep/test.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "opengrep is installed" opengrep --version + +reportResults diff --git a/test/opengrep/test_debian.sh b/test/opengrep/test_debian.sh new file mode 100755 index 000000000..54223790c --- /dev/null +++ b/test/opengrep/test_debian.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "opengrep is installed" opengrep --version + +reportResults diff --git a/test/opengrep/test_specific_version.sh b/test/opengrep/test_specific_version.sh new file mode 100755 index 000000000..d7b816f74 --- /dev/null +++ b/test/opengrep/test_specific_version.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "opengrep version is equal to 1.18.0" sh -c "opengrep --version | grep '1.18.0'" + +reportResults diff --git a/test/opentofu/scenarios.json b/test/opentofu/scenarios.json new file mode 100644 index 000000000..79f90bf6c --- /dev/null +++ b/test/opentofu/scenarios.json @@ -0,0 +1,16 @@ +{ + "test_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "opentofu": {} + } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "opentofu": { + "version": "1.9.4" + } + } + } +} diff --git a/test/opentofu/test.sh b/test/opentofu/test.sh new file mode 100644 index 000000000..e2ee7c632 --- /dev/null +++ b/test/opentofu/test.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "tofu is installed" tofu --version + +reportResults diff --git a/test/opentofu/test_debian.sh b/test/opentofu/test_debian.sh new file mode 100644 index 000000000..e2ee7c632 --- /dev/null +++ b/test/opentofu/test_debian.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "tofu is installed" tofu --version + +reportResults diff --git a/test/opentofu/test_specific_version.sh b/test/opentofu/test_specific_version.sh new file mode 100644 index 000000000..89b61bc2a --- /dev/null +++ b/test/opentofu/test_specific_version.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "tofu version is equal to 1.9.4" sh -c "tofu --version | grep '1.9.4'" + +reportResults diff --git a/test/outagedeck/scenarios.json b/test/outagedeck/scenarios.json new file mode 100644 index 000000000..bb01553fa --- /dev/null +++ b/test/outagedeck/scenarios.json @@ -0,0 +1,16 @@ +{ + "test_default": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "outagedeck": {} + } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "outagedeck": { + "version": "0.1.0" + } + } + } +} diff --git a/test/outagedeck/test.sh b/test/outagedeck/test.sh new file mode 100755 index 000000000..b0120b3d2 --- /dev/null +++ b/test/outagedeck/test.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "outagedeck is installed" outagedeck --version + +reportResults diff --git a/test/outagedeck/test_default.sh b/test/outagedeck/test_default.sh new file mode 100755 index 000000000..2602aad9b --- /dev/null +++ b/test/outagedeck/test_default.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "outagedeck is installed" outagedeck --version +check "outagedeck status command is available" sh -c "outagedeck help | grep 'outagedeck status'" + +reportResults diff --git a/test/outagedeck/test_specific_version.sh b/test/outagedeck/test_specific_version.sh new file mode 100755 index 000000000..d8f1a0491 --- /dev/null +++ b/test/outagedeck/test_specific_version.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "outagedeck version is 0.1.0" sh -c "outagedeck --version | grep '0.1.0'" + +reportResults diff --git a/test/prek/scenarios.json b/test/prek/scenarios.json new file mode 100644 index 000000000..995efe310 --- /dev/null +++ b/test/prek/scenarios.json @@ -0,0 +1,16 @@ +{ + "test_defaults_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "prek": {} + } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "prek": { + "version": "0.3.6" + } + } + } +} diff --git a/test/prek/test_defaults_debian.sh b/test/prek/test_defaults_debian.sh new file mode 100755 index 000000000..2f7b21a34 --- /dev/null +++ b/test/prek/test_defaults_debian.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "prek --version" prek --version + +reportResults diff --git a/test/prek/test_specific_version.sh b/test/prek/test_specific_version.sh new file mode 100755 index 000000000..6fefebb50 --- /dev/null +++ b/test/prek/test_specific_version.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "prek version is equal to 0.3.6" sh -c "prek --version | grep '0.3.6'" + +reportResults diff --git a/test/shellcheck/scenarios.json b/test/shellcheck/scenarios.json new file mode 100644 index 000000000..b5c8b724f --- /dev/null +++ b/test/shellcheck/scenarios.json @@ -0,0 +1,16 @@ +{ + "test_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "shellcheck": {} + } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "shellcheck": { + "version": "0.9.0" + } + } + } +} \ No newline at end of file diff --git a/test/shellcheck/test_debian.sh b/test/shellcheck/test_debian.sh new file mode 100755 index 000000000..e53cdba6b --- /dev/null +++ b/test/shellcheck/test_debian.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "shellcheck is installed" shellcheck --version + +reportResults diff --git a/test/shellcheck/test_specific_version.sh b/test/shellcheck/test_specific_version.sh new file mode 100755 index 000000000..06646101a --- /dev/null +++ b/test/shellcheck/test_specific_version.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "shellcheck version is equal to 0.9.0" sh -c "shellcheck --version | grep '0.9.0'" + +reportResults diff --git a/test/terragrunt/scenarios.json b/test/terragrunt/scenarios.json index 1d1e6cecd..0abc6a801 100644 --- a/test/terragrunt/scenarios.json +++ b/test/terragrunt/scenarios.json @@ -4,5 +4,21 @@ "features": { "terragrunt": {} } + }, + "test_specific_version_before_assets_change": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "terragrunt": { + "version": "0.93.5" + } + } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "terragrunt": { + "version": "0.96.0" + } + } } } \ No newline at end of file diff --git a/test/terragrunt/test_specific_version.sh b/test/terragrunt/test_specific_version.sh new file mode 100755 index 000000000..5580e8094 --- /dev/null +++ b/test/terragrunt/test_specific_version.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "terragrunt --version" terragrunt --version +check "terragrunt version is equal to 0.96.0" sh -c "terragrunt --version | grep '0.96.0'" + +reportResults diff --git a/test/terragrunt/test_specific_version_before_assets_change.sh b/test/terragrunt/test_specific_version_before_assets_change.sh new file mode 100755 index 000000000..8f7a10be4 --- /dev/null +++ b/test/terragrunt/test_specific_version_before_assets_change.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "terragrunt --version" terragrunt --version +check "terragrunt version is equal to 0.93.5" sh -c "terragrunt --version | grep '0.93.5'" + +reportResults diff --git a/test/tflint/scenarios.json b/test/tflint/scenarios.json new file mode 100644 index 000000000..7cb7266ef --- /dev/null +++ b/test/tflint/scenarios.json @@ -0,0 +1,16 @@ +{ + "test_default": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "tflint": {} + } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "tflint": { + "version": "0.62.0" + } + } + } +} \ No newline at end of file diff --git a/test/tflint/test.sh b/test/tflint/test.sh new file mode 100755 index 000000000..70c491bac --- /dev/null +++ b/test/tflint/test.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "something is installed" tflint --version + +reportResults diff --git a/test/tflint/test_default.sh b/test/tflint/test_default.sh new file mode 100755 index 000000000..96f1aaddd --- /dev/null +++ b/test/tflint/test_default.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "tflint is installed" tflint --version + +reportResults diff --git a/test/tflint/test_specific_version.sh b/test/tflint/test_specific_version.sh new file mode 100755 index 000000000..742971673 --- /dev/null +++ b/test/tflint/test_specific_version.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "tflint version is equal to 0.62.0" sh -c "tflint --version | grep '0.62.0'" + +reportResults diff --git a/test/ty/scenarios.json b/test/ty/scenarios.json new file mode 100644 index 000000000..ef48409c0 --- /dev/null +++ b/test/ty/scenarios.json @@ -0,0 +1,16 @@ +{ + "test_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "ty": {} + } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "ty": { + "version": "0.0.10" + } + } + } +} diff --git a/test/ty/test.sh b/test/ty/test.sh new file mode 100755 index 000000000..c433ffc9f --- /dev/null +++ b/test/ty/test.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "ty is installed" ty --version + +reportResults diff --git a/test/ty/test_debian.sh b/test/ty/test_debian.sh new file mode 100755 index 000000000..c433ffc9f --- /dev/null +++ b/test/ty/test_debian.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "ty is installed" ty --version + +reportResults diff --git a/test/ty/test_specific_version.sh b/test/ty/test_specific_version.sh new file mode 100755 index 000000000..5d5af0ad9 --- /dev/null +++ b/test/ty/test_specific_version.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "ty version is equal to 0.0.10" sh -c "ty --version | grep '0.0.10'" + +reportResults diff --git a/test/uv-tool/install_tool_using_from.sh b/test/uv-tool/install_tool_using_from.sh new file mode 100644 index 000000000..1ccff31af --- /dev/null +++ b/test/uv-tool/install_tool_using_from.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "httpie is installed" http --version + +reportResults diff --git a/test/uv-tool/install_tool_using_multiple_with.sh b/test/uv-tool/install_tool_using_multiple_with.sh new file mode 100644 index 000000000..5bc9199a5 --- /dev/null +++ b/test/uv-tool/install_tool_using_multiple_with.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "mkdocs is installed" mkdocs --version +check "mkdocs-material theme is available" sh -c "cd $(uv tool dir)/mkdocs && uv pip list | grep mkdocs-material" +check "mkdocs-minify-plugin is available" sh -c "cd $(uv tool dir)/mkdocs && uv pip list | grep mkdocs-minify-plugin" + +reportResults diff --git a/test/uv-tool/install_tool_using_uv_version.sh b/test/uv-tool/install_tool_using_uv_version.sh new file mode 100644 index 000000000..a29cc784d --- /dev/null +++ b/test/uv-tool/install_tool_using_uv_version.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "uv tool version" sh -c "uv --version | grep 0.9.6" +check "httpie is installed" http --version + +reportResults diff --git a/test/uv-tool/install_tool_using_with.sh b/test/uv-tool/install_tool_using_with.sh new file mode 100644 index 000000000..2c8171f04 --- /dev/null +++ b/test/uv-tool/install_tool_using_with.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "mkdocs-material theme is available" sh -c "cd $(uv tool dir)/mkdocs && uv pip list | grep mkdocs-material" + +reportResults diff --git a/test/uv-tool/install_tool_using_with_executables_from_and_python.sh b/test/uv-tool/install_tool_using_with_executables_from_and_python.sh new file mode 100644 index 000000000..863dabb4f --- /dev/null +++ b/test/uv-tool/install_tool_using_with_executables_from_and_python.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "ansible is installed" ansible --version +check "ansible-core executables are available" ansible-playbook --version +check "ansible-lint is available" ansible-lint --version + +check "ansible uses Python 3.13" sh -c "ansible --version | grep 'python version = 3.13'" + +reportResults diff --git a/test/uv-tool/scenarios.json b/test/uv-tool/scenarios.json new file mode 100644 index 000000000..aa7425c9a --- /dev/null +++ b/test/uv-tool/scenarios.json @@ -0,0 +1,48 @@ +{ + "install_tool_using_uv_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "uv-tool": { + "uv_version": "0.9.6", + "package": "httpie" + } + } + }, + "install_tool_using_from": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "uv-tool": { + "package": "httpie", + "from": "git+https://github.com/httpie/cli" + } + } + }, + "install_tool_using_with": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "uv-tool": { + "package": "mkdocs", + "with": "mkdocs-material" + } + } + }, + "install_tool_using_multiple_with": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "uv-tool": { + "package": "mkdocs", + "with": "mkdocs-material mkdocs-minify-plugin" + } + } + }, + "install_tool_using_with_executables_from_and_python": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "uv-tool": { + "package": "ansible", + "with-executables-from": "ansible-core,ansible-lint", + "python": "3.13" + } + } + } +} diff --git a/test/uv/scenarios.json b/test/uv/scenarios.json new file mode 100644 index 000000000..763dcbc12 --- /dev/null +++ b/test/uv/scenarios.json @@ -0,0 +1,16 @@ +{ + "test_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "uv": {} + } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "uv": { + "version": "0.8.14" + } + } + } +} \ No newline at end of file diff --git a/test/uv/test.sh b/test/uv/test.sh new file mode 100755 index 000000000..0ba98d2f7 --- /dev/null +++ b/test/uv/test.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "uv is installed" uv --version + +reportResults diff --git a/test/uv/test_debian.sh b/test/uv/test_debian.sh new file mode 100755 index 000000000..0ba98d2f7 --- /dev/null +++ b/test/uv/test_debian.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "uv is installed" uv --version + +reportResults diff --git a/test/uv/test_specific_version.sh b/test/uv/test_specific_version.sh new file mode 100755 index 000000000..c5254f79c --- /dev/null +++ b/test/uv/test_specific_version.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "uv version is equal to 0.8.14" sh -c "uv --version | grep '0.8.14'" + +reportResults diff --git a/test/worktrunk/scenarios.json b/test/worktrunk/scenarios.json new file mode 100644 index 000000000..a40ab0053 --- /dev/null +++ b/test/worktrunk/scenarios.json @@ -0,0 +1,16 @@ +{ + "test_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "worktrunk": {} + } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "worktrunk": { + "version": "0.35.2" + } + } + } +} diff --git a/test/worktrunk/test.sh b/test/worktrunk/test.sh new file mode 100755 index 000000000..b04829f67 --- /dev/null +++ b/test/worktrunk/test.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "wt is installed" wt --version + +reportResults diff --git a/test/worktrunk/test_debian.sh b/test/worktrunk/test_debian.sh new file mode 100755 index 000000000..b04829f67 --- /dev/null +++ b/test/worktrunk/test_debian.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "wt is installed" wt --version + +reportResults diff --git a/test/worktrunk/test_specific_version.sh b/test/worktrunk/test_specific_version.sh new file mode 100755 index 000000000..8a47888e5 --- /dev/null +++ b/test/worktrunk/test_specific_version.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "wt version is equal to 0.35.2" sh -c "wt --version 2>&1 | grep '0.35.2'" + +reportResults diff --git a/vars.yml b/vars.yml new file mode 100644 index 000000000..4040ae38c --- /dev/null +++ b/vars.yml @@ -0,0 +1,6 @@ +ID: opencode +Description: The open source coding agent. +Repository: sst/opencode +BinaryNames: opencode +BinaryVersionCommands: --version +BinaryNonLatestVersions: 1.0.179