@@ -10,6 +10,14 @@ import (
1010 "time"
1111
1212 "github.com/subosito/gotenv"
13+
14+ "github.com/snyk/go-application-framework/pkg/utils"
15+ )
16+
17+ // Environment variable names
18+ const (
19+ PathEnvVarName = "PATH"
20+ ShellEnvVarName = "SHELL"
1321)
1422
1523// LoadConfiguredEnvironment updates the environment with local configuration. Precedence as follows:
@@ -24,7 +32,7 @@ func LoadConfiguredEnvironment(customConfigFiles []string, workingDirectory stri
2432 defer func () { _ = gotenv .Apply (strings .NewReader (bashOutput )) }() //nolint:errcheck // we can't do anything with the error
2533
2634 env := gotenv .Parse (strings .NewReader (bashOutput ))
27- specificShell , ok := env ["SHELL" ]
35+ specificShell , ok := env [ShellEnvVarName ]
2836 if ok {
2937 fromSpecificShell := getEnvFromShell (specificShell )
3038 _ = gotenv .Apply (strings .NewReader (fromSpecificShell )) //nolint:errcheck // we can't do anything with the error
@@ -41,7 +49,7 @@ func LoadConfiguredEnvironment(customConfigFiles []string, workingDirectory stri
4149
4250func loadFile (fileName string ) {
4351 // preserve path
44- path := os .Getenv ("PATH" )
52+ previousPath := os .Getenv (PathEnvVarName )
4553
4654 // overwrite existing variables with file config
4755 err := gotenv .OverLoad (fileName )
@@ -50,7 +58,7 @@ func loadFile(fileName string) {
5058 }
5159
5260 // add previous path to the end of the new
53- UpdatePath (path , false )
61+ UpdatePath (previousPath , false )
5462}
5563
5664// guard against command injection
@@ -92,39 +100,38 @@ func getEnvFromShell(shell string) string {
92100 return string (env )
93101}
94102
95- // UpdatePath prepends or appends the extension to the current path. If the entry is already there, it skips it. The
96- // result is set into the process environment with os.Setenv.
103+ // UpdatePath prepends or appends the extension to the current path.
104+ // For append, if the entry is already there, it will not be re-added / moved.
105+ // For prepend, if the entry is already there, it will be correctly re-prioritized to the front.
106+ // The result is set into the process environment with os.Setenv.
97107//
98108// pathExtension string the path component to be added.
99109// prepend bool whether to pre- or append
100110func UpdatePath (pathExtension string , prepend bool ) string {
101- pathVarName := "PATH"
111+ currentPath := os . Getenv ( PathEnvVarName )
102112
103113 if pathExtension == "" {
104- return os . Getenv ( pathVarName )
114+ return currentPath
105115 }
106116
107- currentPath := os .Getenv (pathVarName )
108- currentPathEntries := strings .Split (currentPath , string (os .PathListSeparator ))
109-
110- pathEntries := map [string ]bool {}
111- for _ , entry := range currentPathEntries {
112- pathEntries [entry ] = true
117+ if currentPath == "" {
118+ _ = os .Setenv (PathEnvVarName , pathExtension )
119+ return pathExtension
113120 }
114121
122+ currentPathEntries := strings .Split (currentPath , string (os .PathListSeparator ))
115123 addPathEntries := strings .Split (pathExtension , string (os .PathListSeparator ))
116- var newPathSlice []string
117- for _ , entry := range addPathEntries {
118- if ! pathEntries [entry ] {
119- newPathSlice = append (newPathSlice , entry )
120- }
121- }
122124
123- resultSlice := append (newPathSlice , currentPathEntries ... )
124- if ! prepend {
125- resultSlice = append (currentPathEntries , newPathSlice ... )
125+ var combinedSliceWithDuplicates []string
126+ if prepend {
127+ combinedSliceWithDuplicates = append (addPathEntries , currentPathEntries ... )
128+ } else {
129+ combinedSliceWithDuplicates = append (currentPathEntries , addPathEntries ... )
126130 }
127- newPath := strings .Join (resultSlice , string (os .PathListSeparator ))
128- _ = os .Setenv (pathVarName , newPath )
131+
132+ newPathSlice := utils .Dedupe (combinedSliceWithDuplicates )
133+
134+ newPath := strings .Join (newPathSlice , string (os .PathListSeparator ))
135+ _ = os .Setenv (PathEnvVarName , newPath )
129136 return newPath
130137}
0 commit comments