mirror of
https://github.com/TECHNOFAB11/docsonnet.git
synced 2026-02-02 07:35:11 +01:00
feat: inline package declaration
Docsonnet packages previously used to be declared in a `main.docsonnet`. Because this file basically always contains the same, it is kinda redundant. To avoid that, the information from there has been inlined into the main Jsonnet file, while the parser logic will become part of the Go application, as embedded Jsonnet.
This commit is contained in:
parent
a63ddd1061
commit
5fbee517fe
4 changed files with 91 additions and 83 deletions
|
|
@ -1,8 +1 @@
|
||||||
local d = import './main.libsonnet';
|
(import "../load.libsonnet").package(import "./main.libsonnet")
|
||||||
|
|
||||||
d.new('d', url='github.com/jsonnet-libs/docsonnet/doc-util')
|
|
||||||
+ d.withAPI(import './main.libsonnet')
|
|
||||||
+ d.withHelp(|||
|
|
||||||
`doc-util` provides a Jsonnet interface for `docsonnet`,
|
|
||||||
a Jsonnet API doc generator that uses structured data instead of comments.
|
|
||||||
|||)
|
|
||||||
|
|
|
||||||
|
|
@ -1,114 +1,71 @@
|
||||||
local _internal = {
|
|
||||||
// clean removes the hash from the key
|
|
||||||
clean(str): std.strReplace(str, '#', ''),
|
|
||||||
|
|
||||||
include(api, key):
|
|
||||||
// include docsonnet fields
|
|
||||||
if std.startsWith(key, '#') then true
|
|
||||||
|
|
||||||
// non-docsonnet object, might have nested docsonnet
|
|
||||||
else if std.isObject(api[key]) then
|
|
||||||
// skip if has docsonnet counterpart
|
|
||||||
(if std.objectHasAll(api, '#' + key) then false else true)
|
|
||||||
|
|
||||||
// some other field, skip it
|
|
||||||
else false,
|
|
||||||
|
|
||||||
// ds deals with docsonnet fields. Also checks for nested objects for
|
|
||||||
//docsonnet ones
|
|
||||||
ds(api, key):
|
|
||||||
local cleaned = self.clean(key);
|
|
||||||
if std.objectHasAll(api[key], 'object') && std.objectHasAll(api, cleaned) then
|
|
||||||
api[key] + $.object.withFields($.filter(api[cleaned]))
|
|
||||||
else
|
|
||||||
api[key],
|
|
||||||
|
|
||||||
// filter returns only docsonnet related objects from the api
|
|
||||||
filter(api): {
|
|
||||||
[self.clean(key)]:
|
|
||||||
// include all docsonnet
|
|
||||||
if std.startsWith(key, '#') then
|
|
||||||
$.ds(api, key)
|
|
||||||
// create docsonnet objects from regular ones
|
|
||||||
else if std.isObject(api[key]) then
|
|
||||||
$.obj('', $.filter(api[key]))
|
|
||||||
|
|
||||||
for key in std.objectFields(api)
|
|
||||||
if self.include(api, key)
|
|
||||||
},
|
|
||||||
|
|
||||||
fromMain(main): self.filter(main),
|
|
||||||
};
|
|
||||||
|
|
||||||
{
|
{
|
||||||
local internal = self + _internal,
|
|
||||||
local d = self,
|
local d = self,
|
||||||
|
|
||||||
'#new': d.fn('`new` initiates the api documentation model, taking the `name` and import `url` of your project', [d.arg('name', d.T.string), d.arg('url', d.T.string)]),
|
'#': d.pkg(
|
||||||
new(name, url):: {
|
name='d',
|
||||||
|
url='github.com/sh0rez/docsonnet/doc-util',
|
||||||
|
help=|||
|
||||||
|
`doc-util` provides a Jsonnet interface for `docsonnet`,
|
||||||
|
a Jsonnet API doc generator that uses structured data instead of comments.
|
||||||
|
|||
|
||||||
|
),
|
||||||
|
|
||||||
|
package:: {
|
||||||
|
'#new':: d.fn('new creates a new package with given `name`, `import` URL and `help` text', [d.arg('name', d.T.string), d.arg('url', d.T.string), d.arg('help', d.T.string)]),
|
||||||
|
new(name, url, help):: {
|
||||||
name: name,
|
name: name,
|
||||||
'import': url,
|
'import': url,
|
||||||
},
|
|
||||||
|
|
||||||
'#withAPI': d.fn('`withAPI` automatically builds the docsonnet model from your public API. The `main` parameter is usually set to `import "./main.libsonnet"`.', [d.arg('main', d.T.object)]),
|
|
||||||
withAPI(main):: {
|
|
||||||
api: internal.fromMain(main),
|
|
||||||
},
|
|
||||||
|
|
||||||
'#withFields': d.fn('`withFields` allows to manually specify the docsonnet model. Usually `withAPI` is the better alternative', [d.arg('fields', d.T.object)]),
|
|
||||||
withFields(fields):: {
|
|
||||||
api: fields,
|
|
||||||
},
|
|
||||||
|
|
||||||
"#withHelp": d.fn("`withHelp` sets the main description text, displayed right under the package's name", [d.arg("help", d.T.string)]),
|
|
||||||
withHelp(help):: {
|
|
||||||
help: help,
|
help: help,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
|
||||||
"#object": d.obj("Utilities for documenting Jsonnet objects (`{ }`)."),
|
'#pkg':: self.package['#new'] + d.func.withHelp('`new` is a shorthand for `package.new`'),
|
||||||
|
pkg:: self.package.new,
|
||||||
|
|
||||||
|
'#object': d.obj('Utilities for documenting Jsonnet objects (`{ }`).'),
|
||||||
object:: {
|
object:: {
|
||||||
"#new": d.fn("new creates a new object, optionally with description and fields", [d.arg("help", d.T.string), d.arg("fields", d.T.object)]),
|
'#new': d.fn('new creates a new object, optionally with description and fields', [d.arg('help', d.T.string), d.arg('fields', d.T.object)]),
|
||||||
new(help='', fields={}):: { object: {
|
new(help='', fields={}):: { object: {
|
||||||
help: help,
|
help: help,
|
||||||
fields: fields,
|
fields: fields,
|
||||||
} },
|
} },
|
||||||
|
|
||||||
"#withFields": d.fn("The `withFields` modifier overrides the fields property of an already created object", [d.arg("fields", d.T.object)]),
|
'#withFields': d.fn('The `withFields` modifier overrides the fields property of an already created object', [d.arg('fields', d.T.object)]),
|
||||||
withFields(fields):: { object+: {
|
withFields(fields):: { object+: {
|
||||||
fields: fields,
|
fields: fields,
|
||||||
} },
|
} },
|
||||||
},
|
},
|
||||||
|
|
||||||
"#obj": self.object["#new"] + d.func.withHelp("`obj` is a shorthand for `object.new`"),
|
'#obj': self.object['#new'] + d.func.withHelp('`obj` is a shorthand for `object.new`'),
|
||||||
obj:: self.object.new,
|
obj:: self.object.new,
|
||||||
|
|
||||||
"#func": d.obj("Utilities for documenting Jsonnet methods (functions of objects)"),
|
'#func': d.obj('Utilities for documenting Jsonnet methods (functions of objects)'),
|
||||||
func:: {
|
func:: {
|
||||||
"#new": d.fn("new creates a new function, optionally with description and arguments", [d.arg("help", d.T.string), d.arg("args", d.T.array)]),
|
'#new': d.fn('new creates a new function, optionally with description and arguments', [d.arg('help', d.T.string), d.arg('args', d.T.array)]),
|
||||||
new(help='', args=[]):: { 'function': {
|
new(help='', args=[]):: { 'function': {
|
||||||
help: help,
|
help: help,
|
||||||
args: args,
|
args: args,
|
||||||
} },
|
} },
|
||||||
|
|
||||||
"#withHelp": d.fn("The `withHelp` modifier overrides the help text of that function", [d.arg("help", d.T.string)]),
|
'#withHelp': d.fn('The `withHelp` modifier overrides the help text of that function', [d.arg('help', d.T.string)]),
|
||||||
withHelp(help):: {'function'+: {
|
withHelp(help):: { 'function'+: {
|
||||||
help: help,
|
help: help,
|
||||||
}}
|
} },
|
||||||
},
|
},
|
||||||
|
|
||||||
"#fn": self.func["#new"] + d.func.withHelp("`fn` is a shorthand for `func.new`"),
|
'#fn': self.func['#new'] + d.func.withHelp('`fn` is a shorthand for `func.new`'),
|
||||||
fn:: self.func.new,
|
fn:: self.func.new,
|
||||||
|
|
||||||
"#argument": d.obj("Utilities for creating function arguments"),
|
'#argument': d.obj('Utilities for creating function arguments'),
|
||||||
argument:: {
|
argument:: {
|
||||||
"#new": d.fn("new creates a new function argument, taking the name, the type and optionally a default value", [d.arg("name", d.T.string), d.arg("type", d.T.string), d.arg("default", d.T.any)]),
|
'#new': d.fn('new creates a new function argument, taking the name, the type and optionally a default value', [d.arg('name', d.T.string), d.arg('type', d.T.string), d.arg('default', d.T.any)]),
|
||||||
new(name, type, default=null): {
|
new(name, type, default=null): {
|
||||||
name: name,
|
name: name,
|
||||||
type: type,
|
type: type,
|
||||||
default: default,
|
default: default,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"#arg": self.argument["#new"] + self.func.withHelp("`arg` is a shorthand for `argument.new`"),
|
'#arg': self.argument['#new'] + self.func.withHelp('`arg` is a shorthand for `argument.new`'),
|
||||||
arg:: self.argument.new,
|
arg:: self.argument.new,
|
||||||
|
|
||||||
// T contains constants for the Jsonnet types
|
// T contains constants for the Jsonnet types
|
||||||
|
|
|
||||||
58
load.libsonnet
Normal file
58
load.libsonnet
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
{
|
||||||
|
// reshape converts the Jsonnet structure to the one used by docsonnet:
|
||||||
|
// - put fields into an `api` key
|
||||||
|
// - put subpackages into `sub` key
|
||||||
|
reshape(pkg)::
|
||||||
|
local aux(old, key) =
|
||||||
|
if key == '#' then
|
||||||
|
old
|
||||||
|
else if std.objectHas(pkg[key], '#') then
|
||||||
|
old { sub+: { [key]: $.package(pkg[key]) } }
|
||||||
|
else
|
||||||
|
old { api+: { [key]: pkg[key] } };
|
||||||
|
|
||||||
|
std.foldl(aux, std.objectFields(pkg), {})
|
||||||
|
+ pkg['#'],
|
||||||
|
|
||||||
|
// fillObjects creates docsonnet objects from Jsonnet ones,
|
||||||
|
// also filling those that have been specified explicitely
|
||||||
|
fillObjects(api)::
|
||||||
|
local aux(old, key) =
|
||||||
|
if std.startsWith(key, '#') then
|
||||||
|
old { [key]: api[key] }
|
||||||
|
else if std.isObject(api[key]) && std.length(std.objectFields(api[key])) > 0 then
|
||||||
|
old { ['#' + key]+: { object+: {
|
||||||
|
fields: api[key],
|
||||||
|
} } }
|
||||||
|
else old;
|
||||||
|
|
||||||
|
std.foldl(aux, std.objectFields(api), {}),
|
||||||
|
|
||||||
|
// clean removes all hashes from field names
|
||||||
|
clean(api):: {
|
||||||
|
[std.lstripChars(key, '#')]:
|
||||||
|
if std.isObject(api[key]) then $.clean(api[key])
|
||||||
|
else api[key]
|
||||||
|
for key in std.objectFields(api)
|
||||||
|
},
|
||||||
|
|
||||||
|
cleanNonObj(api):: {
|
||||||
|
[key]:
|
||||||
|
if std.startsWith(key, "#") then api[key]
|
||||||
|
else if std.isObject(api[key]) then $.cleanNonObj(api[key])
|
||||||
|
else api[key]
|
||||||
|
for key in std.objectFieldsAll(api)
|
||||||
|
if std.isObject(api[key])
|
||||||
|
},
|
||||||
|
|
||||||
|
// package loads docsonnet from a Jsonnet package
|
||||||
|
package(pkg)::
|
||||||
|
local cleaned = self.cleanNonObj(pkg);
|
||||||
|
local reshaped = self.reshape(cleaned);
|
||||||
|
local filled =
|
||||||
|
if std.objectHas(reshaped, 'api')
|
||||||
|
then reshaped { api: $.fillObjects(reshaped.api) }
|
||||||
|
else reshaped;
|
||||||
|
self.clean(filled),
|
||||||
|
// reshaped,
|
||||||
|
}
|
||||||
|
|
@ -13,7 +13,7 @@ import (
|
||||||
var indexTmpl = strings.Replace(`
|
var indexTmpl = strings.Replace(`
|
||||||
# package {{.Name}}
|
# package {{.Name}}
|
||||||
´´´jsonnet
|
´´´jsonnet
|
||||||
local {{.Name}} = import {{.Import}}
|
local {{.Name}} = import "{{.Import}}"
|
||||||
´´´
|
´´´
|
||||||
|
|
||||||
{{.Help}}
|
{{.Help}}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue