package cnf import ( "errors" "os" "path/filepath" ) // ErrUnknownExtension is raised when encountering an unknown extension var ErrUnknownExtension = errors.New("unknown extension format") // ErrUnknownFormat is raised when the format cannot be guessed from the content of the file var ErrUnknownFormat = errors.New("cannot infer format from content") // ErrFileNotExist is raised when required file does not exist var ErrFileNotExist = errors.New("cannot find file") // Load the current file and create the configuration format accordingly func Load(path string) (ConfigurationFormat, error) { // 1. check file if _, err := os.Stat(path); os.IsNotExist(err) { return nil, ErrFileNotExist } // 2. Try to load from extension extension := filepath.Ext(path) if len(extension) > 0 { if confFormat := loadFromExtension(extension); confFormat != nil { // open file file, err := os.Open(path) if err != nil { return nil, err } // parse _, err = confFormat.ReadFrom(file) file.Close() if err == nil { return confFormat, nil } } } // 4. Try to guess from the content confFormat, err := loadFromContent(path) if err != nil { return nil, err } if confFormat == nil { return nil, ErrUnknownFormat } return confFormat, nil } func loadFromExtension(ext string) ConfigurationFormat { // select configuration or fail if not known switch ext { case ".json": return new(json) case ".ini", ".conf": return new(ini) case ".yaml": return new(yaml) case ".nginx": return new(nginx) case ".sh": return new(bash) default: return nil } } func loadFromContent(path string) (ConfigurationFormat, error) { // 3. open file file, err := os.Open(path) if err != nil { return nil, err } defer file.Close() // extensions ordered by strictness of the language's syntax extensions := []string{".json", ".nginx", ".ini", ".yaml", ".sh"} // try to load each available extension for _, ext := range extensions { file.Seek(0, 0) // load parser c := loadFromExtension(ext) if c == nil { continue } // parse _, err := c.ReadFrom(file) if err == nil { return c, nil } } return nil, ErrUnknownFormat }