// Definition fetcher // // Handles fetching and building ServiceDefinition structs from different // data sources. package service_definition import ( "github.com/goccy/go-yaml" "os" git "spud/git" "strings" ) type DefinitionFetcher struct { Git git.GitClient } func NewDefinitionFetcher() DefinitionFetcher { return DefinitionFetcher{ Git: git.Git{}, } } // Gets a ServiceDefinition from the given location. // // Depending on location prefix, different sources are used: // git+: Clones the target git repository and extracts a service definition from it. // : Uses the location as a filepath to the service definition. func (f DefinitionFetcher) GetDefinition(path string) (ServiceDefinition, error) { if strings.HasPrefix(path, "git+") { return f.getDefinitionFromGit(path) } return f.getDefinitionFromFile(path) } // Clones the target git repository and uses it as a basis to extract // a service definition. func (f DefinitionFetcher) getDefinitionFromGit(path string) (ServiceDefinition, error) { dir, err := os.MkdirTemp("/tmp", "spud-service-") if err != nil { return ServiceDefinition{}, err } if _, err := f.Git.Clone(strings.TrimPrefix(path, "git+"), dir); err != nil { return ServiceDefinition{}, err } return f.getDefinitionFromFile(dir + "/service.yml") } // Extracts a service definition from the given filepath. func (f DefinitionFetcher) getDefinitionFromFile(path string) (ServiceDefinition, error) { var definition ServiceDefinition defData, err := os.ReadFile(path) if err != nil { return ServiceDefinition{}, &FileDoesNotExistError{Message: "Could not find service configuration file", ExpectedPath: path} } if err = yaml.Unmarshal(defData, &definition); err != nil { return ServiceDefinition{}, &InvalidServiceDefinitionError{Path: path} } return definition, nil }