From a6f1e5c6dc6456adf0a653e2a95ba409927ccb68 Mon Sep 17 00:00:00 2001 From: bblietz Date: Wed, 20 May 2026 11:12:00 -0700 Subject: [PATCH] docs: cleanup Confluence-export link debris + add confluence-html-link lint rule Audit step 4 partial: kills the 11 known `_.html` Confluence-export link artifacts left over from the original Confluence-to-Markdown migration. Each was repointed at the current in-repo doc that supersedes the dead Confluence page. The audit called these "not aliasable" but the human-readable filename prefix maps every target unambiguously. Link rewrites (3 files / 11 edits): docs/DEVELOPER/core-concepts/xml-components/component-initialization-order.md L18 children_1608551.html -> /docs/references/scenegraph/xml-elements/children.md L23 interface_1608549.html -> /docs/references/scenegraph/xml-elements/interface.md L28 script_1608550.html -> /docs/references/scenegraph/xml-elements/script.md L58 PosterGrid_1607203.html -> /docs/references/scenegraph/list-and-grid-nodes/postergrid.md L66 Remote-Control-Events_1607636.html -> ../scenegraph-xml/remote-control-events.md L67 Scene_1607315.html -> /docs/references/scenegraph/scene.md docs/DEVELOPER/core-concepts/xml-components/scenegraph-compilation.md L24 component_1608292.html -> /docs/references/scenegraph/xml-elements/component.md L31 Scene_1607315.html -> /docs/references/scenegraph/scene.md L32 OverhangPanelSetScene_1613108.html -> /docs/references/scenegraph/sliding-panels-nodes/overhangpanelsetscene.md L34 Component-Initialization-Order_1611697.html -> component-initialization-order.md (sibling file) docs/REFERENCES/brightscript/interfaces/ifpath.md L74 https://sdkdocs-archive.staging.web.roku.com/roAssociativeArray_1611481.html -> /docs/references/brightscript/components/roassociativearray.md Path-convention notes: - 9 of 11 use lowercase absolute paths (`/docs/references/...`) matching the proven-working pattern: all 226 working in-repo absolute links in the repo today use the lowercase form, and the renderer resolves them case-insensitively to the uppercase `docs/REFERENCES/` filesystem. - 2 use relative paths (the `Remote Control Events` and `Component Initialization Order` references): both source files are under `docs/DEVELOPER/core-concepts/`, and there are zero working `/docs/developer/...` precedents in the repo, so a sibling-relative path is the safer choice. Filesystem resolution confirmed for both. New lint rule: .github/scripts/docs-lint/rules/links.mjs Rule id: `confluence-html-link` (error) Catches: - Relative or absolute link targets matching `_.html` - External URLs to `sdkdocs-archive.staging.web.roku.com/` Wired into index.mjs RULES array. Verification: $ node .github/scripts/docs-lint/index.mjs ... brightscript-fence-required: 0 confluence-html-link: 0 pipe-no-blank-above: 1 (pre-existing, ifscreen.md) html-blank-between-tags: 2 (pre-existing, ifscreen.md) Out of scope (deferred to follow-up PRs of audit step 4): - 151 broken-prefix in-repo absolute links (`/docs/developer-program/`, `/dev/docs/`, `/docs/specs/`, `/docs/references/`, `/trc-docs/`) - 8 anchor mismatches in DEVELOPER/release-notes/index.md - 55 unique dead/errored external URLs identified by HTTP HEAD pass - 5 misc broken relative paths - 2,855 doc:slug ReadMe-legacy links (Tier-2 future migration) --- .github/scripts/docs-lint/index.mjs | 3 +- .github/scripts/docs-lint/rules/links.mjs | 51 +++++++++++++++++++ .../component-initialization-order.md | 12 ++--- .../xml-components/scenegraph-compilation.md | 8 +-- .../brightscript/interfaces/ifpath.md | 2 +- 5 files changed, 64 insertions(+), 12 deletions(-) create mode 100644 .github/scripts/docs-lint/rules/links.mjs diff --git a/.github/scripts/docs-lint/index.mjs b/.github/scripts/docs-lint/index.mjs index 8bce140b..dd735c43 100644 --- a/.github/scripts/docs-lint/index.mjs +++ b/.github/scripts/docs-lint/index.mjs @@ -22,8 +22,9 @@ import remarkGfm from 'remark-gfm' import { Reporter, printReport } from './lib/report.mjs' import * as tables from './rules/tables.mjs' +import * as links from './rules/links.mjs' -const RULES = [tables] +const RULES = [tables, links] const SYNC_PATHS = [ 'docs/**/*.md', diff --git a/.github/scripts/docs-lint/rules/links.mjs b/.github/scripts/docs-lint/rules/links.mjs new file mode 100644 index 00000000..069c39ed --- /dev/null +++ b/.github/scripts/docs-lint/rules/links.mjs @@ -0,0 +1,51 @@ +/** + * Link rules for docs-lint. + * + * Rules and severity: + * error confluence-html-link + * Link target matches Confluence-export filename pattern + * `_.html` (e.g. `children_1608551.html`). These are + * dead artifacts from the original Confluence-to-Markdown migration. + * Either the link should be repointed at the current in-repo doc, or + * the target should be hosted somewhere that still resolves. + * + * Detects both relative (`children_1608551.html`) and absolute + * (`/.../children_1608551.html`) forms. Also catches external URLs to + * the `sdkdocs-archive.staging.web.roku.com` Confluence-archive host. + */ + +import { visit } from 'unist-util-visit'; + +export const id = 'links'; + +// `_.html` pattern, anywhere in the URL path. Trailing +// `#anchor` is tolerated by the parser; we test against just the path. +const CONFLUENCE_EXPORT_RE = /[^\s/]+_\d+\.html(\?[^#\s]*)?(#\S*)?$/i; +const CONFLUENCE_ARCHIVE_HOST_RE = /^https?:\/\/sdkdocs-archive\.staging\.web\.roku\.com\//i; + +function isConfluenceLink(url) { + if (!url) return false; + if (CONFLUENCE_ARCHIVE_HOST_RE.test(url)) return true; + // Strip query + hash, then test the path portion + const pathPart = url.split('#')[0].split('?')[0]; + // Skip true external URLs (already handled by archive-host check above) + if (/^https?:\/\//i.test(url) && !CONFLUENCE_ARCHIVE_HOST_RE.test(url)) return false; + // mailto / tel / doc:slug -- skip + if (/^(mailto|tel|doc):/i.test(url)) return false; + return CONFLUENCE_EXPORT_RE.test(pathPart); +} + +export function check({ file, mdast, reporter }) { + visit(mdast, (node) => { + if (node.type !== 'link' && node.type !== 'image' && node.type !== 'definition') return; + if (!isConfluenceLink(node.url)) return; + reporter.add({ + file, + line: node.position?.start.line, + col: node.position?.start.column ?? 1, + rule: 'confluence-html-link', + severity: 'error', + message: `Confluence-export link target \`${node.url}\` -- the original Confluence page is gone; repoint at the current in-repo doc`, + }); + }); +} diff --git a/docs/DEVELOPER/core-concepts/xml-components/component-initialization-order.md b/docs/DEVELOPER/core-concepts/xml-components/component-initialization-order.md index 579b4f85..da3ae7e4 100644 --- a/docs/DEVELOPER/core-concepts/xml-components/component-initialization-order.md +++ b/docs/DEVELOPER/core-concepts/xml-components/component-initialization-order.md @@ -15,17 +15,17 @@ next: Instances of components defined in an XML file follow a well-defined initialization order when they are created. -1. The [**\**](children_1608551.html) element nodes defined +1. The [**\**](/docs/references/scenegraph/xml-elements/children.md) element nodes defined in XML markup are created, and their fields are set to their initial values, either to a default value, or to the value specified in the XML markup. -2. The **[\](interface_1608549.html)** element fields of +2. The **[\](/docs/references/scenegraph/xml-elements/interface.md)** element fields of the XML component are created, and their initial values are set, either to a default value, or to the value specified by the `value` attribute. -3. The [**\**](script_1608550.html) element `init()` function +3. The [**\**](/docs/references/scenegraph/xml-elements/script.md) element `init()` function is called, and all initializations contained in the function are performed. @@ -55,7 +55,7 @@ using **`createObject()`** or **`createChild()`**. This means that a component object may not have been completely constructed immediately after those calls. For certain nodes that may rely on dynamically-downloaded content to construct the node, such as -[**PosterGrid**](PosterGrid_1607203.html), subsequent object function +[**PosterGrid**](/docs/references/scenegraph/list-and-grid-nodes/postergrid.md), subsequent object function calls may return an object reference to an unconstructed object. ## Parenting and the Focus Chain @@ -63,8 +63,8 @@ calls may return an object reference to an unconstructed object. For nodes that are defined in the **\** XML markup of the component file, the parent node is set after the node is created, and **`init()`** is called. This has implications for the focus chain (see -[**Remote Control Events**](Remote-Control-Events_1607636.html)), which -must end at a node derived from **[Scene](Scene_1607315.html)**. Until +[**Remote Control Events**](../scenegraph-xml/remote-control-events.md)), which +must end at a node derived from **[Scene](/docs/references/scenegraph/scene.md)**. Until the newly-created node is parented to a node that is either derived from **Scene**, or parented to a node in a focus chain that ends on a node derived from **Scene**, you will not be able to set remote control focus diff --git a/docs/DEVELOPER/core-concepts/xml-components/scenegraph-compilation.md b/docs/DEVELOPER/core-concepts/xml-components/scenegraph-compilation.md index 3663fe6e..6c7e3a3b 100644 --- a/docs/DEVELOPER/core-concepts/xml-components/scenegraph-compilation.md +++ b/docs/DEVELOPER/core-concepts/xml-components/scenegraph-compilation.md @@ -21,17 +21,17 @@ BrightScript files in the `pkg:/components` directory are compiled in the same way as BrightScript files in the `pkg:/source` directory. The SceneGraph component files are compiled by creating a list of component names for the application, based on the `name` attribute of -the [**\**](component_1608292.html) element of each file. +the [**\**](/docs/references/scenegraph/xml-elements/component.md) element of each file. These component names are checked for validity as instances of the components are created in the application. This check is *case-sensitive*: the component name to be created must *exactly* match a name in the component name list, *including* case. The application begins to create instances of SceneGraph components starting with a component extended from a scene node class (either -[**Scene**](Scene_1607315.html) or -[**OverhangPanelSetScene**](OverhangPanelSetScene_1613108.html)). See +[**Scene**](/docs/references/scenegraph/scene.md) or +[**OverhangPanelSetScene**](/docs/references/scenegraph/sliding-panels-nodes/overhangpanelsetscene.md)). See [**Component Initialization -Order**](Component-Initialization-Order_1611697.html) for a description +Order**](component-initialization-order.md) for a description of the process that creates component instances. diff --git a/docs/REFERENCES/brightscript/interfaces/ifpath.md b/docs/REFERENCES/brightscript/interfaces/ifpath.md index c143d9e8..33e79a6c 100644 --- a/docs/REFERENCES/brightscript/interfaces/ifpath.md +++ b/docs/REFERENCES/brightscript/interfaces/ifpath.md @@ -71,7 +71,7 @@ A flag indicating whether the current path is valid. #### Description -Returns an [roAssociativeArray](https://sdkdocs-archive.staging.web.roku.com/roAssociativeArray_1611481.html) containing keys for the parent directories, extensions, and file name in the file path. +Returns an [roAssociativeArray](/docs/references/brightscript/components/roassociativearray.md) containing keys for the parent directories, extensions, and file name in the file path. #### Return Value