@@ -103,25 +103,42 @@ Examples:
103103 RunE : runExec ,
104104}
105105
106+ func deduplicatePathString (pathStr string ) string {
107+ parts := strings .Split (pathStr , string (os .PathListSeparator ))
108+ var result []string
109+ seen := make (map [string ]bool )
110+ for _ , p := range parts {
111+ if p == "" {
112+ continue
113+ }
114+ // On Windows, paths are case-insensitive, so we use lower case for deduplication.
115+ key := p
116+ if runtime .GOOS == "windows" {
117+ key = strings .ToLower (p )
118+ }
119+ if ! seen [key ] {
120+ seen [key ] = true
121+ result = append (result , p )
122+ }
123+ }
124+ return strings .Join (result , string (os .PathListSeparator ))
125+ }
126+
106127// mergeEnvMaps merges src into dst. PATH values are combined additively so
107128// that each tool's bin directory is prepended in order.
108129func mergeEnvMaps (dst , src map [string ]string ) {
109130 for k , v := range src {
110131 if k == "PATH" {
111132 if dst ["PATH" ] != "" {
112- dst ["PATH" ] = v + string (os .PathListSeparator ) + dst ["PATH" ]
133+ dst ["PATH" ] = deduplicatePathString ( v + string (os .PathListSeparator ) + dst ["PATH" ])
113134 } else {
114- dst ["PATH" ] = v
135+ dst ["PATH" ] = deduplicatePathString ( v )
115136 }
116137 } else if k == "NODE_PATH" {
117138 if dst ["NODE_PATH" ] != "" {
118- // Avoid duplicates
119- sep := string (os .PathListSeparator )
120- if ! strings .Contains (dst ["NODE_PATH" ]+ sep , v + sep ) {
121- dst ["NODE_PATH" ] = dst ["NODE_PATH" ] + sep + v
122- }
139+ dst ["NODE_PATH" ] = deduplicatePathString (dst ["NODE_PATH" ] + string (os .PathListSeparator ) + v )
123140 } else {
124- dst ["NODE_PATH" ] = v
141+ dst ["NODE_PATH" ] = deduplicatePathString ( v )
125142 }
126143 } else {
127144 dst [k ] = v
@@ -137,16 +154,16 @@ func applyEnvMap(envMap map[string]string) {
137154 if k == "PATH" && v != "" {
138155 existing := os .Getenv ("PATH" )
139156 if existing != "" {
140- os .Setenv (k , v + string (os .PathListSeparator )+ existing )
157+ os .Setenv (k , deduplicatePathString ( v + string (os .PathListSeparator )+ existing ) )
141158 } else {
142- os .Setenv (k , v )
159+ os .Setenv (k , deduplicatePathString ( v ) )
143160 }
144161 } else if k == "NODE_PATH" && v != "" {
145162 existing := os .Getenv ("NODE_PATH" )
146163 if existing != "" {
147- os .Setenv (k , existing + string (os .PathListSeparator )+ v )
164+ os .Setenv (k , deduplicatePathString ( existing + string (os .PathListSeparator )+ v ) )
148165 } else {
149- os .Setenv (k , v )
166+ os .Setenv (k , deduplicatePathString ( v ) )
150167 }
151168 } else if v != "" {
152169 os .Setenv (k , v )
0 commit comments