Skip to content

Add extends support to BrightScript launch configs #774

Description

@TwitchBronBron

Summary

Add an extends property to the BrightScript debug configuration that lets developers define shared base launch configs in external files, which are then inherited and overridden by the local launch.json. Modeled after brighterscript's bsconfig.json extends concept.

Related: #346

Motivation

Developers working across multiple Roku projects or environments (dev/QA/prod) often have large amounts of duplicated launch config. There's currently no way to extract shared values into a base file and inherit from it.

Behavior

Basic usage

In .vscode/launch.json:

{
    "type": "brightscript",
    "extends": "../shared/roku-launch.json",
    "host": "192.168.1.100"
}

The referenced file is loaded first, then all values from the current config are merged overtop (shallow merge — arrays are fully replaced, not concatenated).

Chaining

Chains are supported: c extends b which extends a. The merge order is a → b → c, with c winning.

Optional extends (? prefix)

Prefix the path with ? to silently skip if the file doesn't exist:

"extends": "?../shared/roku-launch.qa.json"

Without the ?, a missing file throws a descriptive error.

Path resolution

The extends path is resolved relative to the directory containing the config file that declares it. For the root launch.json, that is .vscode/. For extended files, it is relative to that file's own location.

Relative paths in base files

${workspaceFolder} and other VSCode variable substitutions in base files are passed through as-is and resolved downstream by VSCode — no special handling needed. Plain relative paths (e.g. rootDir: "./src") in base files will resolve relative to the workspace folder when consumed, same as any other config value.

Workspace settings

extends will also be available as the brightscript.debug.extends workspace setting (synced automatically by the existing sync-launch-settings script). When used there, relative paths should use ${workspaceFolder} as an anchor since there's no launch.json file to resolve against.

Schema / IntelliSense for base files

  • A dist/launch-schema.json is generated at build time from the existing configurationAttributes.launch.properties in package.json (via a new scripts/generate-launch-schema.ts script).
  • This file is not committed — it's generated as part of npm run build and npm run watch.
  • package.json jsonValidation maps roku-launch*.json./dist/launch-schema.json, providing full IntelliSense for base config files following this naming convention (e.g. roku-launch.json, roku-launch.qa.json, roku-launch-ci.json).

Edge cases & validation

  • Missing required file: throws with the resolved path in the error message
  • Missing optional file (? prefix): silently skipped, launch proceeds normally
  • Circular dependency: detected via ancestor path tracking (case-insensitive on Windows); throws Circular dependency detected: "a.json" => "b.json" => "a.json"
  • JSONC: base files support comments and trailing commas (parsed via jsonc-parser)
  • Array values: child arrays fully replace parent arrays (no concatenation)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions