-
Notifications
You must be signed in to change notification settings - Fork 9
build: add native custom-gcl installer #201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,118 @@ | ||
| #!/bin/sh | ||
|
|
||
| set -eu | ||
|
|
||
| usage() { | ||
| cat <<'EOF2' | ||
| usage: install-custom-gcl.sh <destination> | ||
|
|
||
| Build a native custom-gcl binary for the current host OS/ARCH using the | ||
| repo-local ll linter plugin and install it at <destination>. | ||
| EOF2 | ||
| } | ||
|
|
||
| if [ "${1:-}" = "" ] || [ "${1:-}" = "-h" ] || [ "${1:-}" = "--help" ]; then | ||
| usage | ||
| exit 1 | ||
| fi | ||
|
|
||
| dest="$1" | ||
|
|
||
| if [ -d "$dest" ]; then | ||
| echo "error: destination cannot be a directory: $dest" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| script_dir=$(CDPATH='' cd -- "$(dirname "$0")" && pwd) | ||
| repo_root=$(CDPATH='' cd -- "$script_dir/.." && pwd) | ||
| tools_dir="$repo_root/tools" | ||
| config_file="$tools_dir/.custom-gcl.yml" | ||
| plugin_dir="$tools_dir/linters" | ||
|
|
||
| if ! command -v go >/dev/null 2>&1; then | ||
| echo "error: go is required to build custom-gcl" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| if ! command -v git >/dev/null 2>&1; then | ||
| echo "error: git is required to build custom-gcl" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| if [ ! -f "$config_file" ]; then | ||
| echo "error: missing config file: $config_file" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| if [ ! -d "$plugin_dir" ]; then | ||
| echo "error: missing plugin module directory: $plugin_dir" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| version=$(sed -n 's/^version:[[:space:]]*//p' "$config_file" | head -n 1) | ||
| plugin_module=$( | ||
| sed -n 's/^[[:space:]]*-[[:space:]]*module:[[:space:]]*//p' \ | ||
| "$config_file" | head -n 1 | tr -d "'\"" | ||
| ) | ||
|
|
||
| if [ -z "$version" ]; then | ||
| echo "error: unable to determine golangci-lint version" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| if [ -z "$plugin_module" ]; then | ||
| echo "error: unable to determine plugin module path" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| tmpdir=$(mktemp -d "${TMPDIR:-/tmp}/custom-gcl.XXXXXX") | ||
| trap 'rm -rf "$tmpdir"' EXIT HUP INT TERM | ||
|
|
||
| repo_dir="$tmpdir/golangci-lint" | ||
| tmp_bin="$tmpdir/custom-gcl" | ||
|
|
||
| echo "Building native custom-gcl ${version} for $(go env GOOS)/$(go env GOARCH)" | ||
| echo "Using plugin module: ${plugin_module}" | ||
|
|
||
| GIT_CONFIG_GLOBAL=/dev/null \ | ||
| GIT_TERMINAL_PROMPT=0 \ | ||
| git clone \ | ||
| --branch "$version" \ | ||
| --single-branch \ | ||
| --depth 1 \ | ||
| -c advice.detachedHead=false \ | ||
| -q \ | ||
| https://github.com/golangci/golangci-lint.git \ | ||
| "$repo_dir" | ||
|
|
||
| cat >"$repo_dir/cmd/golangci-lint/plugins.go" <<EOF2 | ||
| package main | ||
|
|
||
| import ( | ||
| _ "${plugin_module}" | ||
| ) | ||
| EOF2 | ||
|
|
||
| ( | ||
| cd "$repo_dir" | ||
|
|
||
| go mod edit -replace "${plugin_module}=${plugin_dir}" | ||
| go mod tidy | ||
|
|
||
| build_date=$(date -u +"%Y-%m-%dT%H:%M:%SZ") | ||
| ldflags="-s -w -X main.version=${version}-custom-gcl -X main.date=${build_date}" | ||
|
|
||
| export GOFLAGS="${GOFLAGS-}${GOFLAGS:+ }-buildvcs=false" | ||
|
|
||
| CGO_ENABLED=0 go build \ | ||
| -trimpath \ | ||
| -ldflags "$ldflags" \ | ||
| -o "$tmp_bin" \ | ||
| ./cmd/golangci-lint | ||
| ) | ||
|
|
||
| mkdir -p "$(dirname "$dest")" | ||
| mv "$tmp_bin" "$dest" | ||
| chmod +x "$dest" | ||
|
|
||
| echo "Installed native custom-gcl to: $dest" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| #!/bin/sh | ||
|
|
||
| set -eu | ||
|
|
||
| dest="${1:?usage: local-custom-gcl.sh <dest>}" | ||
| script_dir=$(CDPATH='' cd -- "$(dirname "$0")" && pwd) | ||
|
|
||
| mkdir -p "$(dirname "$dest")" | ||
|
|
||
| if command -v custom-gcl >/dev/null 2>&1; then | ||
| ln -sf "$(command -v custom-gcl)" "$dest" | ||
| echo "Using custom-gcl from PATH." | ||
| exit 0 | ||
| fi | ||
|
|
||
| if [ -x "$dest" ]; then | ||
| echo "Using local linter binary: $dest" | ||
| exit 0 | ||
| fi | ||
|
|
||
| if command -v go >/dev/null 2>&1; then | ||
| if "$script_dir/install-custom-gcl.sh" "$dest"; then | ||
| echo "Built native custom-gcl: $dest" | ||
| exit 0 | ||
| fi | ||
|
|
||
| cat >"$dest" <<'EOF2' | ||
| #!/bin/sh | ||
|
|
||
| set -eu | ||
|
|
||
| repo_root=$(CDPATH='' cd -- "$(dirname "$0")/.." && pwd) | ||
| config_file="$repo_root/tools/.custom-gcl.yml" | ||
| gcl_version="" | ||
|
|
||
| if [ -f "$config_file" ]; then | ||
| gcl_version=$(sed -n 's/^version:[[:space:]]*//p' "$config_file" | head -n 1) | ||
| fi | ||
|
|
||
| gcl_version=${gcl_version:-v1.64.5} | ||
|
|
||
| run_golangci() { | ||
| exec go run "github.com/golangci/golangci-lint/cmd/golangci-lint@${gcl_version}" "$@" | ||
| } | ||
|
|
||
| if [ "${1:-}" = "run" ]; then | ||
| shift | ||
|
|
||
| tmpdir="$(mktemp -d "${TMPDIR:-/tmp}/custom-gcl.XXXXXX")" | ||
| cfg="$tmpdir/custom-gcl.yml" | ||
| trap 'rm -rf "$tmpdir"' EXIT | ||
|
|
||
| awk ' | ||
| $0 ~ /^linters-settings:[[:space:]]*$/ { | ||
| in_ls = 1 | ||
| next | ||
| } | ||
| in_ls && $0 ~ /^ custom:[[:space:]]*$/ { | ||
| skip_custom = 1 | ||
| next | ||
| } | ||
| skip_custom && $0 ~ /^ [A-Za-z0-9_-]+:[[:space:]]*$/ { | ||
| skip_custom = 0 | ||
| } | ||
| in_ls && $0 ~ /^[^[:space:]]/ { | ||
| in_ls = 0 | ||
| } | ||
| skip_custom { | ||
| next | ||
| } | ||
| $0 ~ /^[[:space:]]*-[[:space:]]*ll[[:space:]]*$/ { | ||
| sub(/ll/, "lll") | ||
| next | ||
| } | ||
| { | ||
| } | ||
| ' .golangci.yml >"$cfg" | ||
|
|
||
| run_golangci run --config "$cfg" "$@" | ||
| fi | ||
|
|
||
| run_golangci "$@" | ||
| EOF2 | ||
|
Comment on lines
+27
to
+86
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The fallback script hardcodes the cat >"$dest" <<'EOF2'
#!/bin/sh
set -eu
# This script is a fallback. It assumes it is located in tools/ and that
# the repo root is one level up.
repo_root=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd)
config_file="$repo_root/tools/.custom-gcl.yml"
gcl_version=""
if [ -f "$config_file" ]; then
gcl_version=$(sed -n 's/^version:[[:space:]]*//p' "$config_file" | head -n 1)
fi
# Fallback to a known-good version if parsing fails.
gcl_version=${gcl_version:-v1.64.5}
run_golangci() {
exec go run "github.com/golangci/golangci-lint/cmd/golangci-lint@${gcl_version}" "$@"
}
if [ "${1:-}" = "run" ]; then
shift
tmpdir="$(mktemp -d "${TMPDIR:-/tmp}/custom-gcl.XXXXXX")"
cfg="$tmpdir/custom-gcl.yml"
trap 'rm -rf "$tmpdir"' EXIT
awk '
$0 ~ /^linters-settings:[[:space:]]*$/ {
in_ls = 1
print
next
}
in_ls && $0 ~ /^ custom:[[:space:]]*$/ {
skip_custom = 1
next
}
skip_custom && $0 ~ /^ [A-Za-z0-9_-]+:[[:space:]]*$/ {
skip_custom = 0
}
in_ls && $0 ~ /^[^[:space:]]/ {
in_ls = 0
}
skip_custom {
next
}
$0 ~ /^[[:space:]]*-[[:space:]]*ll[[:space:]]*$/ {
sub(/ll/, "lll")
print
next
}
{
print
}
' .golangci.yml >"$cfg"
run_golangci run --config "$cfg" "$@"
fi
run_golangci "$@"
EOF2 |
||
|
|
||
| chmod +x "$dest" | ||
| echo "custom-gcl not found; using golangci-lint v1.64.5 fallback" | ||
| echo "(custom linter plugin 'll' is disabled in local mode)." | ||
| exit 0 | ||
| fi | ||
|
|
||
| echo "error: install go or custom-gcl" >&2 | ||
| exit 1 | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The script doesn't handle the case where the provided destination is an existing directory. If
<destination>is a directory,mvwill place the binary inside it, but the success message will point to the directory itself, which is misleading. Furthermore, subsequent scripts attempting to execute the destination path will fail. You should add a check to ensure the destination is not a directory.