From 94408deb06e88f4269737322b99b46b5cd7154fb Mon Sep 17 00:00:00 2001 From: Michael Harp Date: Wed, 22 Jul 2026 10:46:29 -0400 Subject: [PATCH] Use relative links where the text lands in the docs collection Per openvox-docs CONTRIBUTING, links within a versioned collection must be relative (page.html), not absolute. Absolute '/latest/' links silently cross version boundaries when a new major is added, and full URIs break browsing a locally served docs container offline. Two of the pup.pt replacements are rendered straight into the docs collection, so they become relative markdown links. Their siblings in these files already were: projects.md, module_structure.md, supported_plugins.md#task. The openvox-docs importer rewrites relative .md to .html on the way in, so the .md form is what belongs here. The 24 links in bolt_option_parser.rb are the awkward case: the same strings are printed by 'bolt --help', where a relative link has no base to resolve against, and are also imported as bolt_command_reference.md. Rather than break one context to satisfy the other, docs.rake now rewrites the absolute URLs to relative markdown links as it generates that page. Terminal output keeps full URIs; the published page has none. Everything else stays absolute. Guide output, error messages, and the generated Puppetfile and plan comments are printed to a terminal or written into a user's file, never rendered as part of a docs page. Anchors verified against openvox-docs. Co-Authored-By: Claude Opus 4.8 Signed-off-by: Michael Harp --- lib/bolt/config/options.rb | 2 +- lib/bolt/inventory/options.rb | 2 +- rakelib/docs.rake | 14 ++++++++++++-- schemas/bolt-inventory.schema.json | 2 +- schemas/bolt-project.schema.json | 2 +- 5 files changed, 16 insertions(+), 6 deletions(-) diff --git a/lib/bolt/config/options.rb b/lib/bolt/config/options.rb index 46f9e70d9..1fc2f98f1 100644 --- a/lib/bolt/config/options.rb +++ b/lib/bolt/config/options.rb @@ -359,7 +359,7 @@ module Options description: "A list of module dependencies for the project. Each dependency is a map of data specifying " \ "the module to install. To install the project's module dependencies, run the `bolt module " \ "install` command. For more information about specifying modules, see [the " \ - "documentation](https://docs.openvoxproject.org/openbolt/latest/bolt_installing_modules.html#manually-specify-modules-in-a-bolt-project).", + "documentation](bolt_installing_modules.md#manually-specify-modules-in-a-bolt-project).", type: Array, items: { type: [Hash, String], diff --git a/lib/bolt/inventory/options.rb b/lib/bolt/inventory/options.rb index 25745df08..dcaf18bb8 100644 --- a/lib/bolt/inventory/options.rb +++ b/lib/bolt/inventory/options.rb @@ -84,7 +84,7 @@ module Options "plugin_hooks" => { description: "Configuration for the Puppet library plugin used to install the " \ "Puppet agent on the target. For more information, see " \ - "https://docs.openvoxproject.org/openbolt/latest/writing_plugins.html", + "[plugin hooks](writing_plugins.md#plugin-hooks).", type: Hash, properties: { "puppet_library" => { diff --git a/rakelib/docs.rake b/rakelib/docs.rake index 5e05c8947..87e1ace5b 100644 --- a/rakelib/docs.rake +++ b/rakelib/docs.rake @@ -148,6 +148,16 @@ begin $stdout.puts "Generated packaged modules at:\n\t#{filepath}" end + # CLI help text carries full docs URLs, because it is printed to a terminal + # where a relative link has nothing to resolve against. Inside the docs + # collection the same text must use relative links, so that a locally served + # build works offline and a page in an older collection does not silently + # follow '/latest/' across a version boundary. + docs_url = %r{https://docs\.openvoxproject\.org/openbolt/latest/(\S+?\.html(?:\#[\w-]+)?)} + relative_docs_links = lambda do |text| + text.gsub(docs_url) { "[#{Regexp.last_match(1)}](#{Regexp.last_match(1)})" } + end + desc "Generate markdown docs for Bolt shell commands" task :command_reference do require 'bolt/bolt_option_parser' @@ -172,11 +182,11 @@ begin short: switch.short.first, long: switch.long.first, arg: switch.arg, - desc: switch.desc.map { |d| d.gsub("<", "<") }.join("

") + desc: relative_docs_links.call(switch.desc.map { |d| d.gsub("<", "<") }.join("

")) } end - desc = matches[:desc].split("\n").map(&:strip).join("\n") + desc = relative_docs_links.call(matches[:desc].split("\n").map(&:strip).join("\n")) usage = matches[:usage].strip @commands[command] = { diff --git a/schemas/bolt-inventory.schema.json b/schemas/bolt-inventory.schema.json index e5dd38d54..485d0f2a1 100644 --- a/schemas/bolt-inventory.schema.json +++ b/schemas/bolt-inventory.schema.json @@ -1854,7 +1854,7 @@ ] }, "plugin_hooks": { - "description": "Configuration for the Puppet library plugin used to install the Puppet agent on the target. For more information, see https://docs.openvoxproject.org/openbolt/latest/writing_plugins.html", + "description": "Configuration for the Puppet library plugin used to install the Puppet agent on the target. For more information, see [plugin hooks](writing_plugins.md#plugin-hooks).", "oneOf": [ { "type": "object", diff --git a/schemas/bolt-project.schema.json b/schemas/bolt-project.schema.json index b9067521f..3b2a11bc1 100644 --- a/schemas/bolt-project.schema.json +++ b/schemas/bolt-project.schema.json @@ -278,7 +278,7 @@ } }, "modules": { - "description": "A list of module dependencies for the project. Each dependency is a map of data specifying the module to install. To install the project's module dependencies, run the `bolt module install` command. For more information about specifying modules, see [the documentation](https://docs.openvoxproject.org/openbolt/latest/bolt_installing_modules.html#manually-specify-modules-in-a-bolt-project).", + "description": "A list of module dependencies for the project. Each dependency is a map of data specifying the module to install. To install the project's module dependencies, run the `bolt module install` command. For more information about specifying modules, see [the documentation](bolt_installing_modules.md#manually-specify-modules-in-a-bolt-project).", "type": "array", "items": { "type": [