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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ Custom features for dev containers used in development of Omoxyz software projec
## Features

- **Lefthook** ([lefthook](./src/lefthook/README.md)) – fast polyglot Git hooks manager to automate code checks, formatting, and tests before commits and pushes.
- **Air** ([go-air](./src/go-air/README.md)) - live reloader for Go apps
- **Protoc** ([protoc](./src/protoc/README.md))
- **Air** ([go-air](./src/go-air/README.md)) - live reloader for Go apps.
- **Protoc** ([protoc](./src/protoc/README.md)) - protocol buffer compiler.
- **Protolint** ([protolint](./src/protolint/README.md)) - linter and fixer to enforce Protocol Buffer style and conventions.

## Usage

Expand Down
Empty file added src/protolint/NOTES.md
Empty file.
20 changes: 20 additions & 0 deletions src/protolint/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "Protolint",
"id": "protolint",
"version": "1.0.0",
"documentationURL": "http://github.com/omoxyz/devcontainer-features/tree/main/src/protolint",
"description": "Install Protolint linter and fixer to enforce Protocol Buffer style and conventions.",
"options": {
"version": {
"default": "latest",
"description": "Select the version to install.",
"proposals": [
"latest"
],
"type": "string"
}
},
"installsAfter": [
"ghcr.io/devcontainers/features/git"
]
}
87 changes: 87 additions & 0 deletions src/protolint/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#!/usr/bin/env bash

if [ "$(id -u)" -ne 0 ]; then
echo -e 'Scripts must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
exit 1
fi

source ./utils.sh

PROTOLINT_VERSION=${VERSION:-"latest"}
GITHUB_REPO=https://github.com/yoheimuta/protolint

# Exit immediately if a command exits with a non-zero status.
set -e

apt_get_update

# Clean up
rm -rf /var/lib/apt/lists/*

export DEBIAN_FRONTEND=noninteractive

get_github_filename() {
local version=$1
local arch=$2
echo "protolint_${version}_linux_${arch}.tar.gz"
}

install_from_github() {
local version_list=$(git ls-remote --tags ${GITHUB_REPO})

# Get 2 latest appropriate versions
versions=($(find_latest_versions $PROTOLINT_VERSION version_list "tags/v"))
if [ $? -eq 1 ]; then
echo "Can't find appropriate version"
exit 1
fi

latest_version=${versions[0]}
prev_version=${versions[1]}

echo "Downloading protolint v${latest_version}...."

check_packages wget

# Get architecture
local arch=$(dpkg --print-architecture)

local filename=$(get_github_filename $latest_version $arch)

set +e

# Create temporary directory
mkdir -p /tmp/protolint
pushd /tmp/protolint

# Download zip file
wget ${GITHUB_REPO}/releases/download/v${latest_version}/${filename}
local exit_code=$?

set -e

if [ "$exit_code" != "0" ]; then
# Handle situation where git tags are ahead of what was is available to actually download
echo "(!) protolint version ${latest_version} failed to download. Attempting to fall back to ${prev_version} to retry..."
filename=$(get_github_filename $prev_version $arch)
wget ${GITHUB_REPO}/releases/download/v${prev_version}/${filename}
fi

tar -xvzf /tmp/protolint/${filename} -C /tmp/protolint

# Install binaries
cp -r /tmp/protolint/protolint /usr/local/bin/protolint
cp -r /tmp/protolint/protoc-gen-protolint /usr/local/bin/protoc-gen-protolint

# Remove temporary directory
popd
rm -rf /tmp/protolint
}

# Install curl, unzip if missing
check_packages curl ca-certificates unzip git

install_from_github

# Clean up
rm -rf /var/lib/apt/lists/*
81 changes: 81 additions & 0 deletions src/protolint/utils.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/usr/bin/env bash

# Refresh the local package index if no package list entries are stored on the system.
apt_get_update() {
if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then
echo "Running apt-get update..."
apt-get update -y
fi
}

# Checks if packages are installed and installs them if not
check_packages() {
for pkg in "$@"; do
# Check if it's a command in PATH
if command -v "$pkg" &> /dev/null; then
echo "[OK] $pkg found in PATH"
continue
fi

# Check if it's a Debian/Ubuntu package installed
if dpkg -s "$pkg" &> /dev/null; then
echo "[OK] $pkg package installed"
continue
fi

# If not found, install package
echo "$pkg not found. Installing..."
apt_get_update
apt-get install -y --no-install-recommends $pkg

done
}

# Find 2 latest versions that appropriate to requested version
find_latest_versions() {
local requested_version=$1
local version_list=${!2}

# Version prefix such as "tags/v"
local prefix_regex=${3:-''}

# Version number part separator such as "." in "1.0.0"
local separator=${4:-"."}
local escaped_separator=${separator//./\\.}

local suffix_regex=${5:-''}

# Format and sort version list
local version_regex="${prefix_regex}\\K[0-9]+(${escaped_separator}[0-9]+){0,2}${suffix_regex}$"
version_list="$(printf "%s\n" "${version_list[@]}" | grep -oP $version_regex| tr -d ' ' | tr $separator '.' | sort -rV)"

if [ "${requested_version}" = "latest" ]; then
echo "$(echo "${version_list}" | head -n 2)"
else
# Try to get latest matching version

set +e
local regex="^"

# Get major version or exit
local major="$(echo "${requested_version}" | grep -oE '^[0-9]+')"
if [ $major != '' ]; then
regex="${regex}${major}"
else
echo "Invalid version \"${requested_version}\". Use \"latest\" or MAJOR[.MINOR][.PATCH]"
return 1
fi

# Get minor number or accept any
local minor="$(echo "${requested_version}" | grep -oP '^[0-9]+\.\K[0-9]+')"
regex="${regex}$([ "$minor" != '' ] && echo "${escaped_separator}${minor}" || echo "(${escaped_separator}[0-9]+)?")"


# Get patch number or accept any
local patch="$(echo "${requested_version}" | grep -oP '^[0-9]+\.[0-9]+\.\K[0-9]+')"
regex="${regex}$([ "$patch" != '' ] && echo "${escaped_separator}${patch}" || echo "(${escaped_separator}[0-9]+)?")"
set -e

echo "$(echo "${version_list}" | grep -E -m 2 "^${regex}$")"
fi
}
8 changes: 8 additions & 0 deletions test/protolint/scenarios.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"test": {
"image": "mcr.microsoft.com/devcontainers/base:debian",
"features": {
"protoc": {}
}
}
}
10 changes: 10 additions & 0 deletions test/protolint/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env bash

set -e

source dev-container-features-test-lib

check "protolint version" protolint version
check "protoc-gen-protolint " protoc-gen-protolint version

reportResults