diff --git a/CHANGELOG.md b/CHANGELOG.md index 985d2c7..20393fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- replace meta-work in database with a databaseMetadata field on all works' metadata. client libraries should be able to generate properly from the resulting, simpler JSON schema. + ## [0.3.1] - 2024-04-13 ### Fixed @@ -26,11 +30,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial release -[Unreleased]: https://github.com/ortfo/db/compare/v0.3.0...HEAD -[0.3.1]: https://github.com/ortfo/db/-/releases/tag/v0.3.1 +[Unreleased]: https://github.com/ortfo/db/compare/v0.3.1...HEAD +[0.3.1]: https://github.com/ortfo/db/compare/v0.3.0...v0.3.1 [0.3.0]: https://github.com/ortfo/db/compare/v0.2.0...v0.3.0 [0.2.0]: https://github.com/ortfo/db/releases/tag/v0.2.0 [//]: # (C3-2-DKAC:GGH:Rortfo/db:Tv{t}) - -[unreleased]: https://github.com/ortfo/db/-/compare/v0.3.1...main diff --git a/build.go b/build.go index 7911636..6571840 100644 --- a/build.go +++ b/build.go @@ -21,12 +21,12 @@ import ( "path" jsoniter "github.com/json-iterator/go" - "github.com/mitchellh/mapstructure" ) type Database map[string]AnalyzedWork type DatabaseMeta struct { + // Partial is true if the database was not fully built. Partial bool } @@ -38,25 +38,15 @@ func (w Database) AsSlice() []AnalyzedWork { return works } -// Works gets the mapping of all works (without the #meta "pseudo-work"). +// Works gets the mapping of all works func (w Database) Works() map[string]AnalyzedWork { - works := make(map[string]AnalyzedWork) - for id, work := range w { - if id == "#meta" { - continue - } - works[id] = work - } - return works + return w } -// WorksSlice gets the slice of all works in the database (without the #meta "pseudo-work") +// WorksSlice gets the slice of all works in the database func (w Database) WorksSlice() []AnalyzedWork { works := make([]AnalyzedWork, 0) - for id, work := range w { - if id == "#meta" { - continue - } + for _, work := range w { works = append(works, work) } return works @@ -108,12 +98,10 @@ func (w Database) GroupWorksByYear() [][]AnalyzedWork { // Meta gets the database meta information func (w Database) Meta() DatabaseMeta { - for id, metaWork := range w { - if id == "#meta" { - return DatabaseMeta{Partial: metaWork.Partial} - } + for _, work := range w { + return work.Metadata.DatabaseMetadata } - panic("no meta work found, database has no meta information (no #meta top-level key found)") + panic("no work in database, cannot get meta information") } // Partial returns true if the database results from a partial build. @@ -416,20 +404,19 @@ func (ctx *RunContext) BuildSome(include string, databaseDirectory string, outpu func (ctx *RunContext) WriteDatabase(works Database, flags Flags, outputFilename string, partial bool) { ctx.LogDebug("Writing database (partial=%v) to %s", partial, outputFilename) - worksWithMetadata := make(map[string]interface{}) - err := mapstructure.Decode(works, &worksWithMetadata) - if err != nil { - ctx.DisplayError("while converting works to map", err) - return + worksWithDatabaseMetadata := make(Database, 0) + for id, work := range works { + work.Metadata.DatabaseMetadata = DatabaseMeta{Partial: partial} + worksWithDatabaseMetadata[id] = work } - worksWithMetadata["#meta"] = struct{ Partial bool }{Partial: partial} + // Compile the database var worksJSON []byte json := jsoniter.ConfigFastest if ctx.Flags.Minified { - worksJSON, _ = json.Marshal(worksWithMetadata) + worksJSON, _ = json.Marshal(worksWithDatabaseMetadata) } else { - worksJSON, _ = json.MarshalIndent(worksWithMetadata, "", " ") + worksJSON, _ = json.MarshalIndent(worksWithDatabaseMetadata, "", " ") } // Output it diff --git a/description.go b/description.go index c5751d0..3b6974c 100644 --- a/description.go +++ b/description.go @@ -195,6 +195,7 @@ type WorkMetadata struct { WIP bool `json:"wip" yaml:",omitempty"` Private bool `json:"private" yaml:",omitempty"` AdditionalMetadata map[string]interface{} `mapstructure:",remain" json:"additionalMetadata" yaml:",omitempty"` + DatabaseMetadata DatabaseMeta `json:"databaseMetadata" ` } func (m WorkMetadata) CreatedAt() time.Time { diff --git a/jsonschema.go b/jsonschema.go index 3296e62..921af67 100644 --- a/jsonschema.go +++ b/jsonschema.go @@ -19,8 +19,12 @@ func setSchemaId(schema *jsonschema.Schema) { schema.ID = jsonschema.ID(fmt.Sprintf("https://raw.githubusercontent.com/ortfo/db/v%s/schemas/%s.schema.json", Version, base)) } -func makeJSONSchema(t any) string { - schema := yamlReflector.Reflect(t) +func makeJSONSchema(t any, yaml bool) string { + selectedReflector := jsonschema.Reflector{} + if yaml { + selectedReflector = yamlReflector + } + schema := selectedReflector.Reflect(t) setSchemaId(schema) out, err := json.MarshalIndent(schema, "", " ") if err != nil { @@ -30,54 +34,21 @@ func makeJSONSchema(t any) string { } func ConfigurationJSONSchema() string { - return makeJSONSchema(&Configuration{}) + return makeJSONSchema(&Configuration{}, true) } func DatabaseJSONSchema() string { - schema := jsonschema.Reflect(&Database{}) - setSchemaId(schema) - - metaWorkProperties := jsonschema.NewProperties() - metaWorkProperties.Set("Partial", &jsonschema.Schema{ - Type: "boolean", - }) - - schema.Definitions["MetaWork"] = &jsonschema.Schema{ - Type: "object", - Properties: metaWorkProperties, - } - - dbWithWorkProperties := jsonschema.NewProperties() - dbWithWorkProperties.Set("#meta", &jsonschema.Schema{ - Ref: "#/$defs/MetaWork", - }) - - schema.Definitions["DatabaseWithMetaWork"] = &jsonschema.Schema{ - Type: "object", - Properties: dbWithWorkProperties, - PatternProperties: map[string]*jsonschema.Schema{ - "^(?!#meta).*$": { - Ref: "#/$defs/AnalyzedWork", - }, - }, - } - schema.Ref = "#/$defs/DatabaseWithMetaWork" - - out, err := json.MarshalIndent(schema, "", " ") - if err != nil { - panic(err) - } - return string(out) + return makeJSONSchema(&Database{}, false) } type tags []Tag func TagsRepositoryJSONSchema() string { - return makeJSONSchema(&tags{}) + return makeJSONSchema(&tags{}, true) } type technologies []Technology func TechnologiesRepositoryJSONSchema() string { - return makeJSONSchema(&technologies{}) + return makeJSONSchema(&technologies{}, true) }