Skip to content

Instantly share code, notes, and snippets.

@emidoots
Created January 30, 2019 04:35
Show Gist options
  • Save emidoots/9b346f3ad6a3030c978374aa67415690 to your computer and use it in GitHub Desktop.
Save emidoots/9b346f3ad6a3030c978374aa67415690 to your computer and use it in GitHub Desktop.
// +build ignore
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os"
"path"
"sort"
anchorname "github.com/shurcooL/sanitized_anchor_name"
"github.com/sourcegraph/go-jsonschema/jsonschema"
)
const sitePreamble = `# All site configuration options
This page lists site configuration options for Sourcegraph.
Configure your Sourcegraph instance on the **Configuration** page in the site admin area.
For more information, see ["Configuration overview"](index.md).
`
func main() {
if err := generateDocs(options{
schemaFile: "site.schema.json",
outputFile: "../doc/admin/site_config/all.md",
preamble: sitePreamble,
}); err != nil {
log.Fatal(err)
}
}
type options struct {
schemaFile string
outputFile string
preamble string
}
func generateDocs(opt options) error {
outputFileBase := path.Base(opt.outputFile)
// Decode the schema.
var schema *jsonschema.Schema
f, err := os.Open(opt.schemaFile)
if err != nil {
return err
}
if err := json.NewDecoder(f).Decode(&schema); err != nil {
return err
}
defer f.Close()
// Generate the documentation by walking over every schema entry.
output := &bytes.Buffer{}
if opt.preamble != "" {
output.Write([]byte(opt.preamble))
}
var v jsonschema.Visitor
v = visitorFunc(func(schema *jsonschema.Schema, rel []jsonschema.ReferenceToken) (w jsonschema.Visitor) {
if schema == nil {
return
}
for _, prop := range sortedProperties(schema.Properties) {
if len(rel) == 0 {
fmt.Fprintf(output, "- [%s](%s#%s)\n", prop.name, outputFileBase, anchorname.Create(prop.name))
}
}
return v
})
jsonschema.Walk(v, schema)
return ioutil.WriteFile(opt.outputFile, output.Bytes(), 0777)
}
type visitorFunc func(schema *jsonschema.Schema, rel []jsonschema.ReferenceToken) (w jsonschema.Visitor)
func (v visitorFunc) Visit(schema *jsonschema.Schema, rel []jsonschema.ReferenceToken) (w jsonschema.Visitor) {
return v(schema, rel)
}
// property represents a jsonschema.Schema.Properties and its name in a single structure.
type property struct {
name string
*jsonschema.Schema
}
// sortedProperties returns the given jsonschema.Schema.Properties as a sorted
// list, because its normal type is a map (which has random ordering, and thus
// not suitable for doc generation).
func sortedProperties(m *map[string]*jsonschema.Schema) []property {
if m == nil {
return nil
}
var props []property
for name, schema := range *m {
props = append(props, property{
name: name,
Schema: schema,
})
}
sort.Slice(props, func(i, j int) bool {
return props[i].name < props[j].name
})
return props
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment