if err != nil {
return "", err
}
- base := ".netrc"
+
+ // Prioritize _netrc on Windows for compatibility.
if runtime.GOOS == "windows" {
- base = "_netrc"
+ legacyPath := filepath.Join(dir, "_netrc")
+ _, err := os.Stat(legacyPath)
+ if err == nil {
+ return legacyPath, nil
+ }
+ if !os.IsNotExist(err) {
+ return "", err
+ }
+
}
- return filepath.Join(dir, base), nil
+ // Use the .netrc file (fall back to it if we're on Windows).
+ return filepath.Join(dir, ".netrc"), nil
}
var readNetrc = sync.OnceValues(func() ([]netrcLine, error) {
--- /dev/null
+# This test ensures .netrc and _netrc are both supported on windows.
+# See golang.org/issue/66832
+
+[!GOOS:windows] skip
+[short] skip
+
+env GOPROXY=direct
+env GOSUMDB=off
+mkdir $WORK\home
+env USERPROFILE=$WORK\home
+
+# Make sure _netrc works.
+cp netrc_file $WORK\home\_netrc
+cp go.mod.orig go.mod
+go mod tidy
+go list all
+stdout vcs-test.golang.org/auth/or401
+stdout vcs-test.golang.org/auth/or404
+rm $WORK\home\_netrc
+
+# Without credentials, downloading a module from a path that requires HTTPS
+# basic auth should fail.
+cp go.mod.orig go.mod
+! go mod tidy
+stderr '^\tserver response: ACCESS DENIED, buddy$'
+stderr '^\tserver response: File\? What file\?$'
+
+# Make sure .netrc works as a fallback.
+cp netrc_file $WORK\home\.netrc
+cp go.mod.orig go.mod
+go mod tidy
+go list all
+stdout vcs-test.golang.org/auth/or401
+stdout vcs-test.golang.org/auth/or404
+
+-- go.mod.orig --
+module private.example.com
+-- main.go --
+package useprivate
+
+import (
+ _ "vcs-test.golang.org/auth/or401"
+ _ "vcs-test.golang.org/auth/or404"
+)
+-- netrc_file --
+machine vcs-test.golang.org
+ login aladdin
+ password opensesame