package versioning import ( "fmt" "io/ioutil" "os" "strings" "github.com/ghodss/yaml" "github.com/pkg/errors" ) // YAMLDescriptor holds the unique identifier combination for an artifact type YAMLDescriptor struct { GroupID string ArtifactID string Version string } // YAMLfile defines an artifact using a yaml file for versioning type YAMLfile struct { path string content map[string]interface{} versionField string artifactIDField string readFile func(string) ([]byte, error) writeFile func(string, []byte, os.FileMode) error } func (y *YAMLfile) init() { if len(y.versionField) == 0 { y.versionField = "version" } if len(y.artifactIDField) == 0 { y.artifactIDField = "ID" } if y.readFile == nil { y.readFile = ioutil.ReadFile } if y.writeFile == nil { y.writeFile = ioutil.WriteFile } } func (y *YAMLfile) readContent() error { y.init() if y.content != nil { return nil } content, err := y.readFile(y.path) if err != nil { return errors.Wrapf(err, "failed to read file '%v'", y.path) } err = yaml.Unmarshal(content, &y.content) if err != nil { return errors.Wrapf(err, "failed to read yaml content of file '%v'", y.content) } return nil } func (y *YAMLfile) readField(key string) (string, error) { err := y.readContent() if err != nil { return "", errors.Wrapf(err, "failed to get key %s", key) } return strings.TrimSpace(fmt.Sprint(y.content[key])), nil } // VersioningScheme returns the relevant versioning scheme func (y *YAMLfile) VersioningScheme() string { return "semver2" } // GetArtifactID returns the current ID of the artifact func (y *YAMLfile) GetArtifactID() (string, error) { y.init() return y.readField(y.artifactIDField) } // GetVersion returns the current version of the artifact with a YAML-based build descriptor func (y *YAMLfile) GetVersion() (string, error) { y.init() return y.readField(y.versionField) } // SetVersion updates the version of the artifact with a YAML-based build descriptor func (y *YAMLfile) SetVersion(version string) error { err := y.readContent() if err != nil { return errors.Wrapf(err, "failed to set version") } y.content[y.versionField] = version content, err := yaml.Marshal(y.content) if err != nil { return errors.Wrapf(err, "failed to create yaml content for '%v'", y.path) } err = y.writeFile(y.path, content, 0700) if err != nil { return errors.Wrapf(err, "failed to write file '%v'", y.path) } return nil } // GetCoordinates returns the coordinates func (y *YAMLfile) GetCoordinates() (Coordinates, error) { result := Coordinates{} var err error result.ArtifactID, err = y.GetArtifactID() if err != nil { return result, err } result.Version, err = y.GetVersion() if err != nil { return result, err } return result, nil }