11package filesearch
22
33import (
4- "errors"
54 "fmt"
6- iofs "io/fs"
75 "os"
86 "os/exec"
97 "path/filepath"
@@ -12,20 +10,20 @@ import (
1210
1311 "github.com/adrg/xdg"
1412 "github.com/creativeprojects/clog"
13+ "github.com/creativeprojects/resticprofile/constants"
1514 "github.com/creativeprojects/resticprofile/platform"
1615 "github.com/spf13/afero"
1716)
1817
1918var (
20- AppName = "resticprofile"
21-
2219 // configurationExtensions list the possible extensions for the config file
2320 configurationExtensions = []string {
2421 "conf" ,
2522 "yaml" ,
2623 "toml" ,
2724 "json" ,
2825 "hcl" ,
26+ "yml" ,
2927 }
3028
3129 defaultConfigurationLocationsUnix = []string {
4139 }
4240
4341 addConfigurationLocationsDarwin = []string {
44- ".config/" + AppName + "/" ,
42+ ".config/" + constants . ApplicationName + "/" ,
4543 }
4644
4745 defaultConfigurationLocationsWindows = []string {
@@ -69,27 +67,31 @@ var (
6967 }
7068)
7169
72- var fs afero.Fs // we could probably change the implementation to use fs.FS instead
70+ type Finder struct {
71+ fs afero.Fs
72+ }
7373
74- func init () {
75- fs = afero .NewOsFs ()
74+ func NewFinder () Finder {
75+ return Finder {
76+ fs : afero .NewOsFs (), // external packages will always need files from the OS
77+ }
7678}
7779
7880// FindConfigurationFile returns the path of the configuration file
7981// If the file doesn't have an extension, it will search for all possible extensions
80- func FindConfigurationFile (configFile string ) (string , error ) {
82+ func ( f Finder ) FindConfigurationFile (configFile string ) (string , error ) {
8183 found := ""
8284 extension := filepath .Ext (configFile )
8385 displayFile := ""
8486 if extension != "" {
8587 displayFile = fmt .Sprintf ("'%s'" , configFile )
8688 // Search only once through the paths
87- found = findConfigurationFileWithExtension (configFile )
89+ found = f . findConfigurationFileWithExtension (configFile )
8890 } else {
8991 displayFile = fmt .Sprintf ("'%s' with extensions %s" , configFile , strings .Join (configurationExtensions , ", " ))
9092 // Search all extensions one by one
9193 for _ , ext := range configurationExtensions {
92- found = findConfigurationFileWithExtension (configFile + "." + ext )
94+ found = f . findConfigurationFileWithExtension (configFile + "." + ext )
9395 if found != "" {
9496 break
9597 }
@@ -105,9 +107,9 @@ func FindConfigurationFile(configFile string) (string, error) {
105107 strings .Join (getSearchConfigurationLocations (), ", " ))
106108}
107109
108- func findConfigurationFileWithExtension (configFile string ) string {
110+ func ( f Finder ) findConfigurationFileWithExtension (configFile string ) string {
109111 // simple case: try current folder (or rooted path)
110- if fileExists (configFile ) {
112+ if fileExists (f . fs , configFile ) {
111113 return configFile
112114 }
113115
@@ -116,7 +118,7 @@ func findConfigurationFileWithExtension(configFile string) string {
116118
117119 for _ , configPath := range paths {
118120 filename := filepath .Join (configPath , configFile )
119- if fileExists (filename ) {
121+ if fileExists (f . fs , filename ) {
120122 return filename
121123 }
122124 }
@@ -125,7 +127,7 @@ func findConfigurationFileWithExtension(configFile string) string {
125127}
126128
127129// FindConfigurationIncludes finds includes (glob patterns) relative to the configuration file.
128- func FindConfigurationIncludes (configFile string , includes []string ) ([]string , error ) {
130+ func ( f Finder ) FindConfigurationIncludes (configFile string , includes []string ) ([]string , error ) {
129131 if ! filepath .IsAbs (configFile ) {
130132 var err error
131133 if configFile , err = filepath .Abs (configFile ); err != nil {
@@ -150,10 +152,10 @@ func FindConfigurationIncludes(configFile string, includes []string) ([]string,
150152 include = filepath .Join (base , include )
151153 }
152154
153- if fileExists (include ) {
155+ if fileExists (f . fs , include ) {
154156 addFile (include )
155157 } else {
156- if matches , err := afero .Glob (fs , include ); err == nil && matches != nil {
158+ if matches , err := afero .Glob (f . fs , include ); err == nil && matches != nil {
157159 sort .Strings (matches )
158160 for _ , match := range matches {
159161 addFile (match )
@@ -170,14 +172,14 @@ func FindConfigurationIncludes(configFile string, includes []string) ([]string,
170172}
171173
172174// FindResticBinary returns the path of restic executable
173- func FindResticBinary (configLocation string ) (string , error ) {
175+ func ( f Finder ) FindResticBinary (configLocation string ) (string , error ) {
174176 if configLocation != "" {
175177 // Start by the location from the configuration
176178 filename , err := ShellExpand (configLocation )
177179 if err != nil {
178180 clog .Warning (err )
179181 }
180- if filename != "" && fileExists (filename ) {
182+ if filename != "" && fileExists (f . fs , filename ) {
181183 return filename , nil
182184 }
183185 clog .Warningf ("cannot find or read the restic binary specified in the configuration: %q" , configLocation )
@@ -187,7 +189,7 @@ func FindResticBinary(configLocation string) (string, error) {
187189
188190 for _ , configPath := range paths {
189191 filename := filepath .Join (configPath , binaryFile )
190- if fileExists (filename ) {
192+ if fileExists (f . fs , filename ) {
191193 return filename , nil
192194 }
193195 }
@@ -219,9 +221,9 @@ func ShellExpand(filename string) (string, error) {
219221func getSearchConfigurationLocations () []string {
220222 home , _ := os .UserHomeDir ()
221223
222- locations := []string {filepath .Join (xdg .ConfigHome , AppName )}
224+ locations := []string {filepath .Join (xdg .ConfigHome , constants . ApplicationName )}
223225 for _ , configDir := range xdg .ConfigDirs {
224- locations = append (locations , filepath .Join (configDir , AppName ))
226+ locations = append (locations , filepath .Join (configDir , constants . ApplicationName ))
225227 }
226228
227229 if platform .IsWindows () {
@@ -268,9 +270,9 @@ func getResticBinaryName() string {
268270 return resticBinaryUnix
269271}
270272
271- func fileExists (filename string ) bool {
272- _ , err := fs .Stat (filename )
273- return err == nil || errors . Is ( err , iofs . ErrExist )
273+ func fileExists (fs afero. Fs , filename string ) bool {
274+ info , err := fs .Stat (filename )
275+ return err == nil && ! info . IsDir ( )
274276}
275277
276278func addRootToRelativePaths (home string , paths []string ) []string {
0 commit comments