func getReleases() ([]semver.Version, map[string]Version, error) { res, err := http.Get("https://api.github.com/repos/nlf/dhyve-os/releases") if err != nil { return nil, nil, err } defer res.Body.Close() vers := []Version{} decoder := json.NewDecoder(res.Body) err = decoder.Decode(vers) if err != nil { return nil, nil, err } versions := map[string]Version{} rng, err := semver.ParseRange(">= 3.0.0-beta0") if err != nil { return nil, nil, err } svers := []semver.Version{} for _, vers := range versions { v := semver.MustParse(vers.Tag) if rng(v) { versions[vers.Tag] = vers svers = append(svers, v) } } semver.Sort(svers) return svers, versions, nil }
// Load config file that contains the configuration data for the app // instance. Config file should be a valid TOML file that has a bare // minimum data to make it a valid config. Method will panic in case if // there is an error loading the config or interpreting data inside. // Must have the app.name and app.version fields defined correctly. // Refer to implementation code for more details on the loading. func (app *App) loadConfig(name, base string) *toml.TomlTree { const eload = "failed to load TOML config\n %v" const estat = "could not open config file at %v" const ever = "app does not satifsy config version" const eforeign = "config is from different app" var root string = app.RootDirectory // root dir var fileName string = fmt.Sprintf("%s.toml", name) resolved := filepath.Join(root, base, fileName) var clean string = filepath.Clean(resolved) log := app.Journal.WithField("file", clean) log.Info("loading application config file") _, err := os.Stat(clean) // check if file exists if err != nil { panic(fmt.Errorf(estat, clean)) } tree, err := toml.LoadFile(clean) // load config up! if err != nil { panic(fmt.Errorf(eload, err.Error())) } req, ok := tree.Get("app.require").(*toml.TomlTree) if ok && req != nil { // check app requirements var avr string = app.Version.String() name := req.GetDefault("name", app.Name) version := req.GetDefault("version", avr) vr, _ := semver.ParseRange(version.(string)) if vr == nil || !vr(app.Version) { panic(ever) } if name != app.Name { panic(eforeign) } } // assume requirements are satisfied return tree // config tree is ready }
// SemverRangeValidation will validate that the field is in correct, proper semver format. func SemverRangeValidation(v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { if fieldKind != reflect.String { return true } if field.String() == "" { return true } _, err := semver.ParseRange(field.String()) return err == nil }
func NewConstraint(artifactName, rangeString string) (*Constraint, error) { r, err := semver.ParseRange(rangeString) if err != nil { return nil, err } return &Constraint{ ArtifactName: artifactName, RangeString: rangeString, Range: r, }, nil }