docs: generate docs for bake standard library functions
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
This commit is contained in:
@@ -132,6 +132,7 @@ var stdlibFunctions = []funcDef{
|
||||
// value in a list.
|
||||
func indexOfFunc() function.Function {
|
||||
return function.New(&function.Spec{
|
||||
Description: `Finds the element index for a given value in a list.`,
|
||||
Params: []function.Parameter{
|
||||
{
|
||||
Name: "list",
|
||||
@@ -177,6 +178,7 @@ func indexOfFunc() function.Function {
|
||||
// basenameFunc constructs a function that returns the last element of a path.
|
||||
func basenameFunc() function.Function {
|
||||
return function.New(&function.Spec{
|
||||
Description: `Returns the last element of a path.`,
|
||||
Params: []function.Parameter{
|
||||
{
|
||||
Name: "path",
|
||||
@@ -194,6 +196,7 @@ func basenameFunc() function.Function {
|
||||
// dirnameFunc constructs a function that returns the directory of a path.
|
||||
func dirnameFunc() function.Function {
|
||||
return function.New(&function.Spec{
|
||||
Description: `Returns the directory of a path.`,
|
||||
Params: []function.Parameter{
|
||||
{
|
||||
Name: "path",
|
||||
@@ -212,6 +215,7 @@ func dirnameFunc() function.Function {
|
||||
// leaving only characters that are valid for a Bake target name.
|
||||
func sanitizeFunc() function.Function {
|
||||
return function.New(&function.Spec{
|
||||
Description: `Replaces all non-alphanumeric characters with a underscore, leaving only characters that are valid for a Bake target name.`,
|
||||
Params: []function.Parameter{
|
||||
{
|
||||
Name: "name",
|
||||
@@ -240,8 +244,9 @@ func sanitizeFunc() function.Function {
|
||||
// This function was imported from terraform's datetime utilities.
|
||||
func timestampFunc() function.Function {
|
||||
return function.New(&function.Spec{
|
||||
Params: []function.Parameter{},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Description: `Returns a string representation of the current date and time.`,
|
||||
Params: []function.Parameter{},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||
return cty.StringVal(time.Now().UTC().Format(time.RFC3339)), nil
|
||||
},
|
||||
|
||||
@@ -1399,8 +1399,7 @@ $ docker buildx bake
|
||||
|
||||
## Function
|
||||
|
||||
A [set of general-purpose functions][bake_stdlib]
|
||||
provided by [go-cty][go-cty]
|
||||
A [set of general-purpose functions][bake_stdlib] provided by [go-cty][go-cty]
|
||||
are available for use in HCL files:
|
||||
|
||||
```hcl
|
||||
@@ -1440,7 +1439,7 @@ target "webapp-dev" {
|
||||
|
||||
[add-host]: https://docs.docker.com/reference/cli/docker/buildx/build/#add-host
|
||||
[attestations]: https://docs.docker.com/build/attestations/
|
||||
[bake_stdlib]: https://github.com/docker/buildx/blob/master/bake/hclparser/stdlib.go
|
||||
[bake_stdlib]: https://github.com/docker/buildx/blob/master/docs/bake-stdlib.md
|
||||
[build-arg]: https://docs.docker.com/reference/cli/docker/image/build/#build-arg
|
||||
[build-context]: https://docs.docker.com/reference/cli/docker/buildx/build/#build-context
|
||||
[cache-backends]: https://docs.docker.com/build/cache/backends/
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
---
|
||||
title: Bake standard library functions
|
||||
---
|
||||
|
||||
<!---MARKER_STDLIB_START-->
|
||||
|
||||
| Name | Description |
|
||||
|:-------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `absolute` | If the given number is negative then returns its positive equivalent, or otherwise returns the given number unchanged. |
|
||||
| [`add`](#add) | Returns the sum of the two given numbers. |
|
||||
| `and` | Applies the logical AND operation to the given boolean values. |
|
||||
| `base64decode` | |
|
||||
| `base64encode` | |
|
||||
| `basename` | Returns the last element of a path. |
|
||||
| `bcrypt` | |
|
||||
| `byteslen` | Returns the total number of bytes in the given buffer. |
|
||||
| `bytesslice` | Extracts a subslice from the given buffer. |
|
||||
| `can` | |
|
||||
| `ceil` | Returns the smallest whole number that is greater than or equal to the given value. |
|
||||
| `chomp` | Removes one or more newline characters from the end of the given string. |
|
||||
| `chunklist` | Splits a single list into multiple lists where each has at most the given number of elements. |
|
||||
| `cidrhost` | |
|
||||
| `cidrnetmask` | |
|
||||
| `cidrsubnet` | |
|
||||
| `cidrsubnets` | |
|
||||
| `coalesce` | Returns the first of the given arguments that isn't null, or raises an error if there are no non-null arguments. |
|
||||
| `coalescelist` | Returns the first of the given sequences that has a length greater than zero. |
|
||||
| `compact` | Removes all empty string elements from the given list of strings. |
|
||||
| `concat` | Concatenates together all of the given lists or tuples into a single sequence, preserving the input order. |
|
||||
| `contains` | Returns true if the given value is a value in the given list, tuple, or set, or false otherwise. |
|
||||
| `convert` | |
|
||||
| `csvdecode` | Parses the given string as Comma Separated Values (as defined by RFC 4180) and returns a map of objects representing the table of data, using the first row as a header row to define the object attributes. |
|
||||
| `dirname` | Returns the directory of a path. |
|
||||
| `distinct` | Removes any duplicate values from the given list, preserving the order of remaining elements. |
|
||||
| `divide` | Divides the first given number by the second. |
|
||||
| `element` | Returns the element with the given index from the given list or tuple, applying the modulo operation to the given index if it's greater than the number of elements. |
|
||||
| `equal` | Returns true if the two given values are equal, or false otherwise. |
|
||||
| `flatten` | Transforms a list, set, or tuple value into a tuple by replacing any given elements that are themselves sequences with a flattened tuple of all of the nested elements concatenated together. |
|
||||
| `floor` | Returns the greatest whole number that is less than or equal to the given value. |
|
||||
| `format` | Constructs a string by applying formatting verbs to a series of arguments, using a similar syntax to the C function \"printf\". |
|
||||
| `formatdate` | Formats a timestamp given in RFC 3339 syntax into another timestamp in some other machine-oriented time syntax, as described in the format string. |
|
||||
| `formatlist` | Constructs a list of strings by applying formatting verbs to a series of arguments, using a similar syntax to the C function \"printf\". |
|
||||
| `greaterthan` | Returns true if and only if the second number is greater than the first. |
|
||||
| `greaterthanorequalto` | Returns true if and only if the second number is greater than or equal to the first. |
|
||||
| `hasindex` | Returns true if if the given collection can be indexed with the given key without producing an error, or false otherwise. |
|
||||
| `indent` | Adds a given number of spaces after each newline character in the given string. |
|
||||
| `index` | Returns the element with the given key from the given collection, or raises an error if there is no such element. |
|
||||
| `indexof` | Finds the element index for a given value in a list. |
|
||||
| `int` | Discards any fractional portion of the given number. |
|
||||
| `join` | Concatenates together the elements of all given lists with a delimiter, producing a single string. |
|
||||
| `jsondecode` | Parses the given string as JSON and returns a value corresponding to what the JSON document describes. |
|
||||
| `jsonencode` | Returns a string containing a JSON representation of the given value. |
|
||||
| `keys` | Returns a list of the keys of the given map in lexicographical order. |
|
||||
| `length` | Returns the number of elements in the given collection. |
|
||||
| `lessthan` | Returns true if and only if the second number is less than the first. |
|
||||
| `lessthanorequalto` | Returns true if and only if the second number is less than or equal to the first. |
|
||||
| `log` | Returns the logarithm of the given number in the given base. |
|
||||
| `lookup` | Returns the value of the element with the given key from the given map, or returns the default value if there is no such element. |
|
||||
| `lower` | Returns the given string with all Unicode letters translated to their lowercase equivalents. |
|
||||
| `max` | Returns the numerically greatest of all of the given numbers. |
|
||||
| `md5` | |
|
||||
| `merge` | Merges all of the elements from the given maps into a single map, or the attributes from given objects into a single object. |
|
||||
| `min` | Returns the numerically smallest of all of the given numbers. |
|
||||
| `modulo` | Divides the first given number by the second and then returns the remainder. |
|
||||
| `multiply` | Returns the product of the two given numbers. |
|
||||
| `negate` | Multiplies the given number by -1. |
|
||||
| `not` | Applies the logical NOT operation to the given boolean value. |
|
||||
| `notequal` | Returns false if the two given values are equal, or true otherwise. |
|
||||
| `or` | Applies the logical OR operation to the given boolean values. |
|
||||
| `parseint` | Parses the given string as a number of the given base, or raises an error if the string contains invalid characters. |
|
||||
| `pow` | Returns the given number raised to the given power (exponentiation). |
|
||||
| `range` | Returns a list of numbers spread evenly over a particular range. |
|
||||
| `regex` | Applies the given regular expression pattern to the given string and returns information about a single match, or raises an error if there is no match. |
|
||||
| `regex_replace` | Applies the given regular expression pattern to the given string and replaces all matches with the given replacement string. |
|
||||
| `regexall` | Applies the given regular expression pattern to the given string and returns a list of information about all non-overlapping matches, or an empty list if there are no matches. |
|
||||
| `replace` | Replaces all instances of the given substring in the given string with the given replacement string. |
|
||||
| `reverse` | Returns the given string with all of its Unicode characters in reverse order. |
|
||||
| `reverselist` | Returns the given list with its elements in reverse order. |
|
||||
| `rsadecrypt` | |
|
||||
| `sanitize` | Replaces all non-alphanumeric characters with a underscore, leaving only characters that are valid for a Bake target name. |
|
||||
| `sethaselement` | Returns true if the given set contains the given element, or false otherwise. |
|
||||
| `setintersection` | Returns the intersection of all given sets. |
|
||||
| `setproduct` | Calculates the cartesian product of two or more sets. |
|
||||
| `setsubtract` | Returns the relative complement of the two given sets. |
|
||||
| `setsymmetricdifference` | Returns the symmetric difference of the two given sets. |
|
||||
| `setunion` | Returns the union of all given sets. |
|
||||
| `sha1` | |
|
||||
| `sha256` | |
|
||||
| `sha512` | |
|
||||
| `signum` | Returns 0 if the given number is zero, 1 if the given number is positive, or -1 if the given number is negative. |
|
||||
| `slice` | Extracts a subslice of the given list or tuple value. |
|
||||
| `sort` | Applies a lexicographic sort to the elements of the given list. |
|
||||
| `split` | Produces a list of one or more strings by splitting the given string at all instances of a given separator substring. |
|
||||
| `strlen` | Returns the number of Unicode characters (technically: grapheme clusters) in the given string. |
|
||||
| `substr` | Extracts a substring from the given string. |
|
||||
| `subtract` | Returns the difference between the two given numbers. |
|
||||
| `timeadd` | Adds the duration represented by the given duration string to the given RFC 3339 timestamp string, returning another RFC 3339 timestamp. |
|
||||
| `timestamp` | Returns a string representation of the current date and time. |
|
||||
| `title` | Replaces one letter after each non-letter and non-digit character with its uppercase equivalent. |
|
||||
| `trim` | Removes consecutive sequences of characters in "cutset" from the start and end of the given string. |
|
||||
| `trimprefix` | Removes the given prefix from the start of the given string, if present. |
|
||||
| `trimspace` | Removes any consecutive space characters (as defined by Unicode) from the start and end of the given string. |
|
||||
| `trimsuffix` | Removes the given suffix from the start of the given string, if present. |
|
||||
| `try` | |
|
||||
| `upper` | Returns the given string with all Unicode letters translated to their uppercase equivalents. |
|
||||
| `urlencode` | |
|
||||
| `uuidv4` | |
|
||||
| `uuidv5` | |
|
||||
| `values` | Returns the values of elements of a given map, or the values of attributes of a given object, in lexicographic order by key or attribute name. |
|
||||
| `zipmap` | Constructs a map from a list of keys and a corresponding list of values, which must both be of the same length. |
|
||||
|
||||
|
||||
<!---MARKER_STDLIB_END-->
|
||||
|
||||
## Examples
|
||||
|
||||
### <a name="add"></a> `add`
|
||||
|
||||
```hcl
|
||||
# docker-bake.hcl
|
||||
target "webapp-dev" {
|
||||
dockerfile = "Dockerfile.webapp"
|
||||
tags = ["docker.io/username/webapp:latest"]
|
||||
args = {
|
||||
buildno = "${add(123, 1)}"
|
||||
}
|
||||
}
|
||||
```
|
||||
+89
-2
@@ -1,10 +1,15 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/docker/buildx/bake/hclparser"
|
||||
"github.com/docker/buildx/commands"
|
||||
clidocstool "github.com/docker/cli-docs-tool"
|
||||
"github.com/docker/cli/cli/command"
|
||||
@@ -21,10 +26,14 @@ import (
|
||||
)
|
||||
|
||||
const defaultSourcePath = "docs/reference/"
|
||||
const defaultBakeStdlibSourcePath = "docs/bake-stdlib.md"
|
||||
|
||||
var adjustSep = regexp.MustCompile(`\|:---(\s+)`)
|
||||
|
||||
type options struct {
|
||||
source string
|
||||
formats []string
|
||||
source string
|
||||
bakeSource string
|
||||
formats []string
|
||||
}
|
||||
|
||||
// fixUpExperimentalCLI trims the " (EXPERIMENTAL)" suffix from the CLI output,
|
||||
@@ -79,6 +88,9 @@ func gen(opts *options) error {
|
||||
if err = c.GenMarkdownTree(cmd); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = generateBakeStdlibDocs(opts.bakeSource); err != nil {
|
||||
return errors.Wrap(err, "generating bake stdlib docs")
|
||||
}
|
||||
case "yaml":
|
||||
// fix up is needed only for yaml (used for generating docs.docker.com contents)
|
||||
fixUpExperimentalCLI(cmd)
|
||||
@@ -97,6 +109,7 @@ func run() error {
|
||||
opts := &options{}
|
||||
flags := pflag.NewFlagSet(os.Args[0], pflag.ContinueOnError)
|
||||
flags.StringVar(&opts.source, "source", defaultSourcePath, "Docs source folder")
|
||||
flags.StringVar(&opts.bakeSource, "bake-stdlib-source", defaultBakeStdlibSourcePath, "Bake stdlib source file")
|
||||
flags.StringSliceVar(&opts.formats, "formats", []string{}, "Format (md, yaml)")
|
||||
if err := flags.Parse(os.Args[1:]); err != nil {
|
||||
return err
|
||||
@@ -113,3 +126,77 @@ func main() {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func generateBakeStdlibDocs(filename string) error {
|
||||
log.Printf("INFO: Generating Markdown for %q", filename)
|
||||
dt, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
currentContent := string(dt)
|
||||
|
||||
start := strings.Index(currentContent, "<!---MARKER_STDLIB_START-->")
|
||||
end := strings.Index(currentContent, "<!---MARKER_STDLIB_END-->")
|
||||
if start == -1 {
|
||||
return errors.Errorf("no start marker in %s", filename)
|
||||
}
|
||||
if end == -1 {
|
||||
return errors.Errorf("no end marker in %s", filename)
|
||||
}
|
||||
|
||||
table := newMdTable("Name", "Description")
|
||||
names := make([]string, 0, len(hclparser.Stdlib()))
|
||||
for name := range hclparser.Stdlib() {
|
||||
names = append(names, name)
|
||||
}
|
||||
sort.Strings(names)
|
||||
for _, name := range names {
|
||||
fn := hclparser.Stdlib()[name]
|
||||
fname := fmt.Sprintf("`%s`", name)
|
||||
if strings.Contains(currentContent, "<a name=\""+name+"\"></a>") {
|
||||
fname = fmt.Sprintf("[`%s`](#%s)", name, name)
|
||||
}
|
||||
table.AddRow(fname, fn.Description())
|
||||
}
|
||||
|
||||
newContent := currentContent[:start] + "<!---MARKER_STDLIB_START-->\n\n" + table.String() + "\n" + currentContent[end:]
|
||||
return os.WriteFile(filename, []byte(newContent), 0644)
|
||||
}
|
||||
|
||||
type mdTable struct {
|
||||
out *strings.Builder
|
||||
tabWriter *tabwriter.Writer
|
||||
}
|
||||
|
||||
func newMdTable(headers ...string) *mdTable {
|
||||
w := &strings.Builder{}
|
||||
t := &mdTable{
|
||||
out: w,
|
||||
tabWriter: tabwriter.NewWriter(w, 5, 5, 1, ' ', tabwriter.Debug),
|
||||
}
|
||||
t.addHeader(headers...)
|
||||
return t
|
||||
}
|
||||
|
||||
func (t *mdTable) addHeader(cols ...string) {
|
||||
t.AddRow(cols...)
|
||||
_, _ = t.tabWriter.Write([]byte("|" + strings.Repeat(":---\t", len(cols)) + "\n"))
|
||||
}
|
||||
|
||||
func (t *mdTable) AddRow(cols ...string) {
|
||||
for i := range cols {
|
||||
cols[i] = mdEscapePipe(cols[i])
|
||||
}
|
||||
_, _ = t.tabWriter.Write([]byte("| " + strings.Join(cols, "\t ") + "\t\n"))
|
||||
}
|
||||
|
||||
func (t *mdTable) String() string {
|
||||
_ = t.tabWriter.Flush()
|
||||
return adjustSep.ReplaceAllStringFunc(t.out.String()+"\n", func(in string) string {
|
||||
return strings.ReplaceAll(in, " ", "-")
|
||||
})
|
||||
}
|
||||
|
||||
func mdEscapePipe(s string) string {
|
||||
return strings.ReplaceAll(s, `|`, `\|`)
|
||||
}
|
||||
|
||||
@@ -21,9 +21,9 @@ RUN --mount=target=/context \
|
||||
--mount=target=.,type=tmpfs <<EOT
|
||||
set -e
|
||||
rsync -a /context/. .
|
||||
docsgen --formats "$FORMATS" --source "docs/reference"
|
||||
docsgen --formats "$FORMATS" --source "docs/reference" --bake-stdlib-source "docs/bake-stdlib.md"
|
||||
mkdir /out
|
||||
cp -r docs/reference /out
|
||||
cp -r docs/reference docs/bake-stdlib.md /out
|
||||
rm -f /out/reference/*__INTERNAL_SERVE.yaml /out/reference/*__INTERNAL_SERVE.md
|
||||
EOT
|
||||
|
||||
@@ -36,11 +36,11 @@ RUN --mount=target=/context \
|
||||
set -e
|
||||
rsync -a /context/. .
|
||||
git add -A
|
||||
rm -rf docs/reference/*
|
||||
rm -rf docs/reference/* docs/bake-stdlib.md
|
||||
cp -rf /out/* ./docs/
|
||||
if [ -n "$(git status --porcelain -- docs/reference)" ]; then
|
||||
if [ -n "$(git status --porcelain -- docs/reference docs/bake-stdlib.md)" ]; then
|
||||
echo >&2 'ERROR: Docs result differs. Please update with "make docs"'
|
||||
git status --porcelain -- docs/reference
|
||||
git status --porcelain -- docs/reference docs/bake-stdlib.md
|
||||
exit 1
|
||||
fi
|
||||
EOT
|
||||
|
||||
Reference in New Issue
Block a user