feat(docsite): optional site_url and site_label link back to the main site
- site.yaml keys site_url and site_label, validated: http(s) URL with a host or a path starting with a single /; a label needs a URL - docs:build and docs:serve flags --site-url and --site-label override them the way --base-url overrides base_url - every page header, the 404 page included, links back with the explicit label, else the URL host, else Home; unset output is unchanged - docs/console/utilities.md documents the keys and flags
This commit is contained in:
@@ -29,6 +29,8 @@ func docsBuildCommand() bonfire.Command {
|
||||
{Name: "src", Description: "Docs source directory (default <root>/docs)"},
|
||||
{Name: "out", Description: "Output directory (default <root>/site)"},
|
||||
{Name: "base-url", Description: "Base URL for site links (overrides site.yaml base_url)"},
|
||||
{Name: "site-url", Description: "Main site URL linked from the docs header (overrides site.yaml site_url)"},
|
||||
{Name: "site-label", Description: "Label of the main site link (overrides site.yaml site_label; default: the URL host, or Home)"},
|
||||
{Name: "check", Description: "Validate the docs and write nothing", Bare: true},
|
||||
},
|
||||
Run: func(ctx context.Context, in bonfire.Input, out bonfire.Output) error {
|
||||
@@ -91,6 +93,8 @@ func docsServeCommand() bonfire.Command {
|
||||
{Name: "root", Description: "Repository root; src= paths and modules/ resolve against it", Default: "."},
|
||||
{Name: "src", Description: "Docs source directory (default <root>/docs)"},
|
||||
{Name: "base-url", Description: "Base URL for site links (overrides site.yaml base_url)"},
|
||||
{Name: "site-url", Description: "Main site URL linked from the docs header (overrides site.yaml site_url)"},
|
||||
{Name: "site-label", Description: "Label of the main site link (overrides site.yaml site_label; default: the URL host, or Home)"},
|
||||
{Name: "addr", Description: "Listen address; must be loopback unless --allow-remote", Default: docsite.DefaultServeAddr},
|
||||
{Name: "allow-remote", Description: "Allow a non-loopback --addr (serves the docs on the network)", Bare: true},
|
||||
},
|
||||
@@ -126,6 +130,8 @@ func docsOptions(in bonfire.Input) docsite.Options {
|
||||
opts.Src, _ = in.Flag("src")
|
||||
opts.Out, _ = in.Flag("out")
|
||||
opts.BaseURL, _ = in.Flag("base-url")
|
||||
opts.SiteURL, _ = in.Flag("site-url")
|
||||
opts.SiteLabel, _ = in.Flag("site-label")
|
||||
return opts
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,40 @@ func TestDocsBuildRealTree(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestDocsBuildSiteFlags checks that --site-url and --site-label reach the
|
||||
// header and that an unsafe --site-url is refused.
|
||||
func TestDocsBuildSiteFlags(t *testing.T) {
|
||||
out := filepath.Join(t.TempDir(), "site")
|
||||
var buf bytes.Buffer
|
||||
root, err := bonfire.NewRoot("summer", toolCommands(), &buf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root.SetArgs([]string{"docs:build", "--root", repoRoot, "--out", out, "--site-url", "/", "--site-label", "example.org"})
|
||||
if err := root.Execute(); err != nil {
|
||||
t.Fatalf("docs:build: %v\n%s", err, buf.String())
|
||||
}
|
||||
index, err := os.ReadFile(filepath.Join(out, "index.html"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, want := range []string{`class="site-link" href="/"`, "example.org"} {
|
||||
if !bytes.Contains(index, []byte(want)) {
|
||||
t.Errorf("index.html lacks %s", want)
|
||||
}
|
||||
}
|
||||
|
||||
buf.Reset()
|
||||
root, err = bonfire.NewRoot("summer", toolCommands(), &buf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root.SetArgs([]string{"docs:build", "--root", repoRoot, "--out", filepath.Join(t.TempDir(), "bad"), "--site-url", "javascript:alert(1)"})
|
||||
if err := root.Execute(); err == nil || !strings.Contains(err.Error(), "--site-url") {
|
||||
t.Fatalf("docs:build --site-url javascript:alert(1): err = %v, want a --site-url error", err)
|
||||
}
|
||||
}
|
||||
|
||||
// requiredPages lists the guide pages the docs must keep. Each content plan
|
||||
// appends the pages it writes.
|
||||
var requiredPages = []string{
|
||||
|
||||
Reference in New Issue
Block a user