diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 940cd84..208d068 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,6 +10,7 @@ jobs: smoke: name: smoke / ${{ matrix.os }} / ${{ matrix.shell }} runs-on: ${{ matrix.os }} + timeout-minutes: 30 strategy: fail-fast: false matrix: @@ -55,6 +56,7 @@ jobs: suite: name: suite / ${{ matrix.os }} runs-on: ${{ matrix.os }} + timeout-minutes: 45 strategy: fail-fast: false matrix: diff --git a/.gitignore b/.gitignore index aaa9c45..51837ec 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,8 @@ tmp/ scripts/gvm Gemfile.lock .vagrant/ + +# Local-only AI / planning artifacts — do not commit +.cursor/ +docs/plans/ +docs/brainstorms/ diff --git a/ChangeLog b/ChangeLog index b38f228..ba3436e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,12 @@ All notable changes to gvm2 are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/). +## [Unreleased] + +### Fixed + +- Stop duplicating `GOPATH`/`PATH` when creating the `global` pkgset environment (`pkgset-create` and installer `system@global`) (#8). + ## [1.2.0] - 2026-07-14 ### Added diff --git a/binscripts/gvm-installer b/binscripts/gvm-installer index 375b9b1..08910b2 100755 --- a/binscripts/gvm-installer +++ b/binscripts/gvm-installer @@ -41,15 +41,8 @@ export GOPATH; GOPATH="$GVM_DEST/$GVM_NAME/pkgsets/system/global" export PATH; PATH="$GVM_DEST/$GVM_NAME/pkgsets/system/global/bin:$GOROOT/bin:$GVM_ROOT/bin:\$PATH" EOF - # create system@global pkgset + # create system@global pkgset (base system env already embeds global) cp $GVM_DEST/$GVM_NAME/environments/system $GVM_DEST/$GVM_NAME/environments/system@global - # @TODO: This is here for consistency with 'gvm pkgset create' which adds - # some duplicated entries when the pkgset is 'global'. Need to fix it! - cat << EOF >> $GVM_DEST/$GVM_NAME/environments/system@global -export gvm_pkgset_name="global" -export GOPATH; GOPATH="$GVM_DEST/$GVM_NAME/pkgsets/system/global:\$GOPATH" -export PATH; PATH="$GVM_DEST/$GVM_NAME/pkgsets/system/global/bin:\$PATH" -EOF } BRANCH=${1:-master} diff --git a/scripts/ci-smoke.sh b/scripts/ci-smoke.sh index 8cd1e6e..b3938cb 100755 --- a/scripts/ci-smoke.sh +++ b/scripts/ci-smoke.sh @@ -7,10 +7,23 @@ source "$GVM_DEST/gvm/scripts/gvm" echo "GVM_VERSION=${GVM_VERSION:-} HEXDUMP_PATH=${HEXDUMP_PATH:-}" test -n "$GVM_VERSION" test -n "$HEXDUMP_PATH" +# system@global is only created when an existing Go was detected at install time +if [ -f "$GVM_DEST/gvm/environments/system@global" ]; then + if grep -q 'global:$GOPATH' "$GVM_DEST/gvm/environments/system@global"; then + echo "FAIL: system@global has duplicated global GOPATH prefix" >&2 + exit 1 + fi + diff -q "$GVM_DEST/gvm/environments/system" "$GVM_DEST/gvm/environments/system@global" +fi gvm install go1.22.12 -B gvm use go1.22.12 go version | grep -E 'go1\.22\.12' gvm list --porcelain | grep -F 'go1.22.12' +# install creates $go@global via pkgset create; must not duplicate global GOPATH +if grep -q 'global:$GOPATH' "$GVM_DEST/gvm/environments/go1.22.12@global"; then + echo "FAIL: go1.22.12@global has duplicated global GOPATH prefix" >&2 + exit 1 +fi spaced="$GVM_DEST/dir with spaces" mkdir -p "$spaced" cd "$spaced" diff --git a/scripts/install b/scripts/install index 0aecf07..06465eb 100755 --- a/scripts/install +++ b/scripts/install @@ -214,15 +214,31 @@ download_binary() { GO_BINARY_URL="${GO_BINARY_BASE_URL}/${GO_BINARY_FILE}" GO_BINARY_PATH=${GVM_ROOT}/archive/${GO_BINARY_FILE} - if [ ! -f $GO_BINARY_PATH ]; then - curl -s -f -L $GO_BINARY_URL > ${GO_BINARY_PATH} - - if [[ $? -ne 0 ]]; then - display_error "Failed to download binary go" - rm -rf $GO_INSTALL_ROOT - rm -f $GO_BINARY_PATH + if [ ! -f "$GO_BINARY_PATH" ]; then + mkdir -p "${GVM_ROOT}/archive" || { + display_error "Failed to create archive directory" + rm -rf "$GO_INSTALL_ROOT" exit 1 - fi + } + # go.dev occasionally flakes under parallel CI; retry before failing. + _dl_attempt=1 + _dl_max=3 + while [ "${_dl_attempt}" -le "${_dl_max}" ]; do + if curl -sS -f -L --retry 2 --retry-delay 1 \ + -o "${GO_BINARY_PATH}" "${GO_BINARY_URL}"; then + break + fi + rm -f "${GO_BINARY_PATH}" + if [ "${_dl_attempt}" -eq "${_dl_max}" ]; then + display_error "Failed to download binary go" + rm -rf "$GO_INSTALL_ROOT" + exit 1 + fi + display_warning "Binary download failed (attempt ${_dl_attempt}/${_dl_max}); retrying..." + _dl_attempt=$((_dl_attempt + 1)) + sleep "${_dl_attempt}" + done + unset _dl_attempt _dl_max fi tar zxf ${GO_BINARY_PATH} -C $GO_INSTALL_ROOT --strip-components 1 >> "${GVM_ROOT}/logs/go-${GO_NAME}-download-binary" 2>&1 diff --git a/scripts/pkgset-create b/scripts/pkgset-create index 20eea82..5e115e7 100755 --- a/scripts/pkgset-create +++ b/scripts/pkgset-create @@ -33,6 +33,14 @@ mkdir -p "$target_top/pkgsets/$gvm_go_name/$target_set_name" || display_fatal "Could not create packageset folder" cp "$GVM_ROOT/environments/$gvm_go_name" "$target_top/environments/$gvm_go_name@$target_set_name" || display_fatal "Could copy environment" + +# Base Go environments already embed the global pkgset (see scripts/install +# create_enviroment and binscripts/gvm-installer). Copying alone is enough for +# global; re-appending GOPATH/PATH would duplicate those prefixes. +if [ "${target_set_name}" = "global" ]; then + exit 0 +fi + echo "export gvm_pkgset_name=\"$target_set_name_str\"" >> "$target_top/environments/$gvm_go_name@$target_set_name" || display_fatal "Could not extend environment" echo "export GOPATH; GOPATH=\"$add_gopath:\$GOPATH\"" >> "$target_top/environments/$gvm_go_name@$target_set_name" || @@ -40,16 +48,14 @@ echo "export GOPATH; GOPATH=\"$add_gopath:\$GOPATH\"" >> "$target_top/environmen echo "export PATH; PATH=\"$add_path:\$PATH\"" >> "$target_top/environments/$gvm_go_name@$target_set_name" || display_fatal "Could not extend environment" -if [ "${target_set_name}" != "global" ]; then - echo "# Package Set-Specific Overrides" >> "${GVM_ROOT}/environments/${gvm_go_name}@${target_set_name}" - echo "export GVM_OVERLAY_PREFIX; GVM_OVERLAY_PREFIX=\"\${GVM_ROOT}/pkgsets/${gvm_go_name}/${target_set_name}/overlay\"" >> "${GVM_ROOT}/environments/${gvm_go_name}@${target_set_name}" - mkdir -p "${GVM_ROOT}/pkgsets/${gvm_go_name}/${target_set_name}/overlay/"{bin,lib/pkgconfig} - echo "export PATH; PATH=\"${GVM_ROOT}/pkgsets/${gvm_go_name}/${target_set_name}/bin:\${GVM_OVERLAY_PREFIX}/bin:\${PATH}\"" >> "$GVM_ROOT/environments/${gvm_go_name}@${target_set_name}" || - display_fatal "Could not extend environment" - echo "export LD_LIBRARY_PATH; LD_LIBRARY_PATH=\"\${GVM_OVERLAY_PREFIX}/lib:\${LD_LIBRARY_PATH}\"" >> "${GVM_ROOT}/environments/${gvm_go_name}@${target_set_name}" || - display_fatal "Could not extend environment" - echo "export DYLD_LIBRARY_PATH; DYLD_LIBRARY_PATH=\"\${GVM_OVERLAY_PREFIX}/lib:\${DYLD_LIBRARY_PATH}\"" >> "${GVM_ROOT}/environments/${gvm_go_name}@${target_set_name}" || - display_fatal "Could not extend environment" - echo "export PKG_CONFIG_PATH; PKG_CONFIG_PATH=\"\${GVM_OVERLAY_PREFIX}/lib/pkgconfig:\${PKG_CONFIG_PATH}\"" >> "${GVM_ROOT}/environments/${gvm_go_name}@${target_set_name}" || - display_fatal "Could not extend environment" -fi +echo "# Package Set-Specific Overrides" >> "${GVM_ROOT}/environments/${gvm_go_name}@${target_set_name}" +echo "export GVM_OVERLAY_PREFIX; GVM_OVERLAY_PREFIX=\"\${GVM_ROOT}/pkgsets/${gvm_go_name}/${target_set_name}/overlay\"" >> "${GVM_ROOT}/environments/${gvm_go_name}@${target_set_name}" +mkdir -p "${GVM_ROOT}/pkgsets/${gvm_go_name}/${target_set_name}/overlay/"{bin,lib/pkgconfig} +echo "export PATH; PATH=\"${GVM_ROOT}/pkgsets/${gvm_go_name}/${target_set_name}/bin:\${GVM_OVERLAY_PREFIX}/bin:\${PATH}\"" >> "$GVM_ROOT/environments/${gvm_go_name}@${target_set_name}" || + display_fatal "Could not extend environment" +echo "export LD_LIBRARY_PATH; LD_LIBRARY_PATH=\"\${GVM_OVERLAY_PREFIX}/lib:\${LD_LIBRARY_PATH}\"" >> "${GVM_ROOT}/environments/${gvm_go_name}@${target_set_name}" || + display_fatal "Could not extend environment" +echo "export DYLD_LIBRARY_PATH; DYLD_LIBRARY_PATH=\"\${GVM_OVERLAY_PREFIX}/lib:\${DYLD_LIBRARY_PATH}\"" >> "${GVM_ROOT}/environments/${gvm_go_name}@${target_set_name}" || + display_fatal "Could not extend environment" +echo "export PKG_CONFIG_PATH; PKG_CONFIG_PATH=\"\${GVM_OVERLAY_PREFIX}/lib/pkgconfig:\${PKG_CONFIG_PATH}\"" >> "${GVM_ROOT}/environments/${gvm_go_name}@${target_set_name}" || + display_fatal "Could not extend environment" diff --git a/tests/gvm_pkgset_global_comment_test.sh b/tests/gvm_pkgset_global_comment_test.sh new file mode 100644 index 0000000..0f56d4a --- /dev/null +++ b/tests/gvm_pkgset_global_comment_test.sh @@ -0,0 +1,20 @@ +source $GVM_ROOT/scripts/gvm + +## Synthetic Go env whose base file already embeds the global pkgset. +## Note: tf runs each line as its own command — never use multi-line heredocs. +mkdir -p "$GVM_ROOT/gos/duptest" "$GVM_ROOT/pkgsets/duptest" "$GVM_ROOT/environments" +printf '%s\n' 'export GVM_ROOT; GVM_ROOT="'"$GVM_ROOT"'"' 'export gvm_go_name; gvm_go_name="duptest"' 'export gvm_pkgset_name; gvm_pkgset_name="global"' 'export GOPATH; GOPATH="'"$GVM_ROOT"'/pkgsets/duptest/global"' 'export PATH; PATH="'"$GVM_ROOT"'/pkgsets/duptest/global/bin:$PATH"' > "$GVM_ROOT/environments/duptest" + +gvm_go_name=duptest "$GVM_ROOT/scripts/pkgset-create" global # status=0 +test -f "$GVM_ROOT/environments/duptest@global" # status=0 +## @global should be a clean copy — no GOPATH="…/global:$GOPATH" append +grep 'global:$GOPATH' "$GVM_ROOT/environments/duptest@global" # status=1 +diff -q "$GVM_ROOT/environments/duptest" "$GVM_ROOT/environments/duptest@global" # status=0 + +## Non-global pkgsets still prepend paths +gvm_go_name=duptest "$GVM_ROOT/scripts/pkgset-create" myset # status=0 +grep 'pkgsets/duptest/myset:$GOPATH' "$GVM_ROOT/environments/duptest@myset" # status=0 +grep 'Package Set-Specific Overrides' "$GVM_ROOT/environments/duptest@myset" # status=0 + +## Cleanup +rm -rf "$GVM_ROOT/gos/duptest" "$GVM_ROOT/pkgsets/duptest" "$GVM_ROOT/environments/duptest" "$GVM_ROOT/environments/duptest@global" "$GVM_ROOT/environments/duptest@myset"