diff --git a/.gitignore b/.gitignore index fcb84729..76b8d244 100644 --- a/.gitignore +++ b/.gitignore @@ -34,4 +34,6 @@ actions/badges/ tests_coverage/ .jekyll-cache/ /.sisyphus -/.opencode \ No newline at end of file +/.opencode +/.pi +/.pp \ No newline at end of file diff --git a/docs/_data/sidebars/_cli.yml b/docs/_data/sidebars/_cli.yml index d910cf24..c50e7a9a 100644 --- a/docs/_data/sidebars/_cli.yml +++ b/docs/_data/sidebars/_cli.yml @@ -41,3 +41,9 @@ cli: &cli - title: trdl bin-path url: /reference/cli/trdl_bin_path.html + + - title: Other commands + f: + + - title: trdl version + url: /reference/cli/trdl_version.html diff --git a/docs/_data/sidebars/reference.yml b/docs/_data/sidebars/reference.yml index 8485d8eb..a2bbcd1e 100644 --- a/docs/_data/sidebars/reference.yml +++ b/docs/_data/sidebars/reference.yml @@ -47,6 +47,12 @@ cli: &cli - title: trdl bin-path url: /reference/cli/trdl_bin_path.html + - title: Other commands + f: + + - title: trdl version + url: /reference/cli/trdl_version.html + # This file is generated by the github.com/werf/trdl/server/pkg/gendocs # DO NOT EDIT! diff --git a/docs/_includes/reference/vault_plugin/configure/build/mac_signing_identity.md b/docs/_includes/reference/vault_plugin/configure/build/mac_signing_identity.md index 46f229d0..f0cc4592 100644 --- a/docs/_includes/reference/vault_plugin/configure/build/mac_signing_identity.md +++ b/docs/_includes/reference/vault_plugin/configure/build/mac_signing_identity.md @@ -1,4 +1,4 @@ -Add or update build signing credentials. +Add or update build signing credentials for macOS builds. ## Add or update mac signing credentials diff --git a/docs/_includes/reference/vault_plugin/configure/git_credential.md b/docs/_includes/reference/vault_plugin/configure/git_credential.md index e9c0fcd7..57e3ec95 100644 --- a/docs/_includes/reference/vault_plugin/configure/git_credential.md +++ b/docs/_includes/reference/vault_plugin/configure/git_credential.md @@ -1,4 +1,4 @@ -Configure Git credentials. +Configure Git credentials to perform clone operation. ## Configure Git credentials diff --git a/docs/_includes/reference/vault_plugin/configure/last_published_git_commit.md b/docs/_includes/reference/vault_plugin/configure/last_published_git_commit.md index 6ab2124e..5b5b06ce 100644 --- a/docs/_includes/reference/vault_plugin/configure/last_published_git_commit.md +++ b/docs/_includes/reference/vault_plugin/configure/last_published_git_commit.md @@ -1,4 +1,4 @@ -Read or delete the last published Git commit. +This endpoint allows reading or deleting the last published Git commit recorded by the plugin. ## Get the last published Git commit diff --git a/docs/_includes/reference/vault_plugin/configure/trusted_pgp_public_key.md b/docs/_includes/reference/vault_plugin/configure/trusted_pgp_public_key.md index c06b93e7..f3c0c751 100644 --- a/docs/_includes/reference/vault_plugin/configure/trusted_pgp_public_key.md +++ b/docs/_includes/reference/vault_plugin/configure/trusted_pgp_public_key.md @@ -1,4 +1,4 @@ -Configure trusted PGP public keys. +Configure trusted PGP public keys to check git repository commit signatures. ## Add a trusted PGP public key diff --git a/docs/_includes/reference/vault_plugin/publish.md b/docs/_includes/reference/vault_plugin/publish.md index 90dbb617..26486aca 100644 --- a/docs/_includes/reference/vault_plugin/publish.md +++ b/docs/_includes/reference/vault_plugin/publish.md @@ -1,4 +1,4 @@ -Publish release channels. +Publish release channels based on trdl_channels.yaml configuration in the git repository. ## Publish release channels diff --git a/docs/_includes/reference/vault_plugin/release.md b/docs/_includes/reference/vault_plugin/release.md index c7f7b7b3..532c88c8 100644 --- a/docs/_includes/reference/vault_plugin/release.md +++ b/docs/_includes/reference/vault_plugin/release.md @@ -1,4 +1,4 @@ -Perform a release. +Perform a release for the specified git tag. ## Perform a release diff --git a/docs/pages_en/reference/cli/overview.md b/docs/pages_en/reference/cli/overview.md index 17639738..255f90f0 100644 --- a/docs/pages_en/reference/cli/overview.md +++ b/docs/pages_en/reference/cli/overview.md @@ -18,3 +18,6 @@ Advanced commands: - [trdl exec]({{ "/reference/cli/trdl_exec.html" | true_relative_url }}) — {% include /reference/cli/trdl_exec.short.md %}. - [trdl dir-path]({{ "/reference/cli/trdl_dir_path.html" | true_relative_url }}) — {% include /reference/cli/trdl_dir_path.short.md %}. - [trdl bin-path]({{ "/reference/cli/trdl_bin_path.html" | true_relative_url }}) — {% include /reference/cli/trdl_bin_path.short.md %}. + +Other commands: + - [trdl version]({{ "/reference/cli/trdl_version.html" | true_relative_url }}) — {% include /reference/cli/trdl_version.short.md %}. diff --git a/docs/pages_en/reference/cli/trdl_version.md b/docs/pages_en/reference/cli/trdl_version.md new file mode 100644 index 00000000..215f50fc --- /dev/null +++ b/docs/pages_en/reference/cli/trdl_version.md @@ -0,0 +1,6 @@ +--- +title: trdl version +permalink: reference/cli/trdl_version.html +--- + +{% include /reference/cli/trdl_version.md %} diff --git a/server/pkg/gendocs/templates.go b/server/pkg/gendocs/templates.go index faaeb911..87bf4ad1 100644 --- a/server/pkg/gendocs/templates.go +++ b/server/pkg/gendocs/templates.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" "path/filepath" + "regexp" "sort" "strings" "text/template" @@ -11,6 +12,11 @@ import ( "github.com/hashicorp/vault/sdk/framework" ) +var ( + helpWhitespaceRe = regexp.MustCompile(`\s+`) + openAPIParamRe = regexp.MustCompile(`\{[^/]+}`) +) + type MethodExampleTemplateData struct { Description string Path string @@ -178,16 +184,23 @@ func NewBackendTemplateData(backendDoc *framework.OASDocument, frameworkBackendR pathName := FormatPathName(rawPathName) pathDesc := backendDoc.Paths[rawPathName] - // FIXME: pathDesc.Description is actually a HelpSynopsis, where is HelpDescription? + // Vault only exposes the route HelpSynopsis in the OpenAPI document (pathDesc.Description). + // Use the full HelpDescription for the route page heading when available and keep the + // synopsis for the short description shown in the overview. + synopsis := pathDesc.Description + descriptionSource := synopsis + if fullDesc := routeHelpDescription(frameworkBackendRef, rawPathName); fullDesc != "" { + descriptionSource = fullDesc + } - descParts := strings.SplitN(pathDesc.Description, " ", 2) + descParts := strings.SplitN(descriptionSource, " ", 2) descParts[0] = strings.Title(descParts[0]) description := strings.Join(descParts, " ") description = strings.TrimSuffix(description, ".") + "." path := &PathTemplateData{ Name: pathName, - Synopsis: strings.ToLower(pathDesc.Description), + Synopsis: strings.ToLower(synopsis), Description: description, } @@ -224,6 +237,23 @@ func NewBackendTemplateData(backendDoc *framework.OASDocument, frameworkBackendR return backendTemplateData, nil } +func normalizeHelpString(s string) string { + return strings.TrimSpace(helpWhitespaceRe.ReplaceAllString(s, " ")) +} + +func routeHelpDescription(b *framework.Backend, rawPathName string) string { + if b == nil { + return "" + } + + pathName := strings.TrimPrefix(openAPIParamRe.ReplaceAllString(rawPathName, "x"), "/") + if p := b.Route(pathName); p != nil { + return normalizeHelpString(p.HelpDescription) + } + + return "" +} + func FormatPathPatternAsFilesystemMarkdownPath(pattern string) (string, error) { // fmt.Printf("INPUT PATTERN: %q\n", pattern) if pattern == "/" { diff --git a/server/pkg/gendocs/templates_test.go b/server/pkg/gendocs/templates_test.go new file mode 100644 index 00000000..d0cf6b17 --- /dev/null +++ b/server/pkg/gendocs/templates_test.go @@ -0,0 +1,153 @@ +package gendocs + +import ( + "testing" + + "github.com/hashicorp/vault/sdk/framework" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// newTestBackend builds a minimal framework.Backend whose routes carry the given +// synopsis/description pairs, so NewBackendTemplateData can resolve descriptions +// by route path via the public Route API. +func newTestBackend(paths []*framework.Path) *framework.Backend { + return &framework.Backend{ + Help: "Test backend help", + BackendType: 0, + Paths: paths, + } +} + +// oasDoc mirrors what Vault exposes at the OpenAPI path level: only the route +// HelpSynopsis ends up in OASPathItem.Description. +func oasDoc(pathSynopsis map[string]string) *framework.OASDocument { + doc := framework.NewOASDocument("test") + for path, synopsis := range pathSynopsis { + doc.Paths[path] = &framework.OASPathItem{ + Description: synopsis, + Get: &framework.OASOperation{}, + } + } + return doc +} + +func pathByName(data *BackendTemplateData, name string) *PathTemplateData { + for _, p := range data.Paths { + if p.Name == name { + return p + } + } + return nil +} + +func TestNewBackendTemplateData_UsesHelpDescriptionForHeading(t *testing.T) { + backend := newTestBackend([]*framework.Path{ + { + Pattern: "configure/git_credential/?$", + HelpSynopsis: "Configure Git credentials", + HelpDescription: "Configure Git credentials to perform clone operation", + }, + }) + doc := oasDoc(map[string]string{ + "/configure/git_credential": "Configure Git credentials", + }) + + data, err := NewBackendTemplateData(doc, backend, nil) + require.NoError(t, err) + + p := pathByName(data, "/configure/git_credential") + require.NotNil(t, p) + + // Full-page heading uses HelpDescription. + assert.Equal(t, "Configure Git credentials to perform clone operation.", p.Description) + // Overview line keeps the short synopsis (lower-cased). + assert.Equal(t, "configure git credentials", p.Synopsis) +} + +func TestNewBackendTemplateData_FallsBackToSynopsisWhenNoDescription(t *testing.T) { + backend := newTestBackend([]*framework.Path{ + { + Pattern: "configure/pgp_signing_key$", + HelpSynopsis: "Configure a PGP key for signing release artifacts", + // No HelpDescription. + }, + }) + doc := oasDoc(map[string]string{ + "/configure/pgp_signing_key": "Configure a PGP key for signing release artifacts", + }) + + data, err := NewBackendTemplateData(doc, backend, nil) + require.NoError(t, err) + + p := pathByName(data, "/configure/pgp_signing_key") + require.NotNil(t, p) + + assert.Equal(t, "Configure a PGP key for signing release artifacts.", p.Description) + assert.Equal(t, "configure a pgp key for signing release artifacts", p.Synopsis) +} + +func TestNewBackendTemplateData_DuplicateSynopsisRoutesGetOwnDescription(t *testing.T) { + // Two routes deliberately share an identical HelpSynopsis. Matching by route + // path (not synopsis string) must give each its own HelpDescription. + backend := newTestBackend([]*framework.Path{ + { + Pattern: "alpha$", + HelpSynopsis: "Manage thing", + HelpDescription: "Manage thing alpha in detail", + }, + { + Pattern: "beta$", + HelpSynopsis: "Manage thing", + HelpDescription: "Manage thing beta in detail", + }, + }) + doc := oasDoc(map[string]string{ + "/alpha": "Manage thing", + "/beta": "Manage thing", + }) + + data, err := NewBackendTemplateData(doc, backend, nil) + require.NoError(t, err) + + alpha := pathByName(data, "/alpha") + beta := pathByName(data, "/beta") + require.NotNil(t, alpha) + require.NotNil(t, beta) + + assert.Equal(t, "Manage thing alpha in detail.", alpha.Description) + assert.Equal(t, "Manage thing beta in detail.", beta.Description) +} + +func TestNewBackendTemplateData_ParametrizedRouteResolves(t *testing.T) { + backend := newTestBackend([]*framework.Path{ + { + Pattern: "configure/trusted_pgp_public_key/" + framework.GenericNameRegex("name") + "$", + HelpSynopsis: "Read or delete the configured trusted PGP public key", + HelpDescription: "Read or delete the configured trusted PGP public key in full", + }, + }) + doc := oasDoc(map[string]string{ + "/configure/trusted_pgp_public_key/{name}": "Read or delete the configured trusted PGP public key", + }) + + data, err := NewBackendTemplateData(doc, backend, nil) + require.NoError(t, err) + + p := pathByName(data, "/configure/trusted_pgp_public_key/:name") + require.NotNil(t, p) + + assert.Equal(t, "Read or delete the configured trusted PGP public key in full.", p.Description) +} + +func TestNormalizeHelpString(t *testing.T) { + cases := map[string]string{ + " hello world ": "hello world", + "a\n\tb": "a b", + "single": "single", + "": "", + } + for in, want := range cases { + assert.Equal(t, want, normalizeHelpString(in)) + } +}