diff --git a/.github/workflows/create-package.yml b/.github/workflows/create-package.yml new file mode 100644 index 00000000..4f130832 --- /dev/null +++ b/.github/workflows/create-package.yml @@ -0,0 +1,57 @@ +name: create-package +on: + pull_request: + types: [labeled, unlabeled, synchronize] +jobs: + create-package: + runs-on: ubuntu-latest + if: contains(github.event.pull_request.labels.*.name, 'create-package') + env: + GH_TOKEN: ${{ github.token }} + steps: + - uses: actions/checkout@master + - uses: actions/setup-node@master + with: + node-version: "14.19.0" + # Get a bot token so the bot's name shows up on all our actions + - name: Get Token From roku-ci-token Application + uses: tibdex/github-app-token@v1 + id: generate-token + with: + app_id: ${{ secrets.BOT_APP_ID }} + private_key: ${{ secrets.BOT_PRIVATE_KEY }} + - run: echo "TOKEN=${{ steps.generate-token.outputs.token }}" >> $GITHUB_ENV + - name: Compute variables + run: | + CURRENT_VERSION=$(grep -o '\"version\": *\"[^\"]*\"' package.json | awk -F'\"' '{print $4}') + SANITIZED_BRANCH_NAME=$(echo "$GITHUB_HEAD_REF" | sed 's/[^0-9a-zA-Z-]/-/g') + BUILD_VERSION="$CURRENT_VERSION-$SANITIZED_BRANCH_NAME.$(date +%Y%m%d%H%M%S)" + NPM_PACKAGE_NAME=$(grep -o '\"name\": *\"[^\"]*\"' package.json | awk -F'\"' '{print $4}') + ARTIFACT_NAME=$(echo "$NPM_PACKAGE_NAME-$BUILD_VERSION.tgz" | tr '/' '-') + ARTIFACT_URL="${{ github.server_url }}/${{ github.repository }}/releases/download/v0.0.0-packages/${ARTIFACT_NAME}" + + echo "BUILD_VERSION=$BUILD_VERSION" >> $GITHUB_ENV + echo "ARTIFACT_URL=$ARTIFACT_URL" >> $GITHUB_ENV + + - run: npm ci + - run: npm version "$BUILD_VERSION" --no-git-tag-version + - run: npm pack + + # create the release if not exist + - run: gh release create v0.0.0-packages --latest=false --prerelease --notes "catchall release for temp packages" -R ${{ github.repository }} + continue-on-error: true + + # upload this artifact to the "packages" github release + - run: gh release upload v0.0.0-packages *.tgz -R ${{ github.repository }} + + - name: Fetch build artifact + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + return github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: "Hey there! I just built a new temporary npm package based on ${{ github.event.pull_request.head.sha }}. You can download it [here](${{ env.ARTIFACT_URL }}) or install it by running the following command: \n```bash\nnpm install ${{ env.ARTIFACT_URL }}\n```" + }); diff --git a/CHANGELOG.md b/CHANGELOG.md index dee7908e..60714e9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## [0.21.1](https://github.com/rokucommunity/roku-debug/compare/v0.21.0...v0.21.1) - 2024-01-16 +### Changed + - upgrade to [brighterscript@0.65.17](https://github.com/rokucommunity/brighterscript/blob/master/CHANGELOG.md#06517---2024-01-16). Notable changes since 0.65.16: + - adds support for libpkg prefix ([brighterscript#1017](https://github.com/rokucommunity/brighterscript/pull/1017)) + - Assign .program to the builder BEFORE calling afterProgram ([brighterscript#1011](https://github.com/rokucommunity/brighterscript/pull/1011)) + + + +## [0.21.0](https://github.com/rokucommunity/roku-debug/compare/v0.20.15...v0.21.0) - 2024-01-10 +### Added + - Add cli flag to run dap as standalone process ([#173](https://github.com/rokucommunity/roku-debug/pull/173)) + - Expose `controlPort` launch option for overriding the debug protocol port ([#182](https://github.com/rokucommunity/roku-debug/pull/182)) + + + ## [0.20.15](https://github.com/rokucommunity/roku-debug/compare/v0.20.14...v0.20.15) - 2024-01-08 ### Changed - Display a modal message when the we fail to upload a package to the device ([#178](https://github.com/rokucommunity/roku-debug/pull/178)) diff --git a/README.md b/README.md index ffc34fc8..246f1787 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,20 @@ A [Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol/) [![license](https://img.shields.io/github/license/rokucommunity/roku-debug.svg)](LICENSE) [![Slack](https://img.shields.io/badge/Slack-RokuCommunity-4A154B?logo=slack)](https://join.slack.com/t/rokudevelopers/shared_invite/zt-4vw7rg6v-NH46oY7hTktpRIBM_zGvwA) +## Usage +This project can be integrated with any IDE that supports the debug-adapter-protocol. + +**Known integrations:** +- [BrightScript Language extension for VSCode](https://github.com/rokucommunity/vscode-brightscript-language) +- [nvim-dap extension for Neovim](https://github.com/mfussenegger/nvim-dap/wiki/Debug-Adapter-installation#brightscript) + +## DAP instructions +To run the language server standalone, you simply need to: +- install nodejs and make sure npx is on your path +- install this project (`npm install roku-debug`) +- run the project in dap mode (`npx roku-debug --dap`) + + ## Contributors [![](https://sourcerer.io/fame/TwitchBronBron/rokucommunity/roku-debug/images/0)](https://sourcerer.io/fame/TwitchBronBron/rokucommunity/roku-debug/links/0)[![](https://sourcerer.io/fame/TwitchBronBron/rokucommunity/roku-debug/images/1)](https://sourcerer.io/fame/TwitchBronBron/rokucommunity/roku-debug/links/1)[![](https://sourcerer.io/fame/TwitchBronBron/rokucommunity/roku-debug/images/2)](https://sourcerer.io/fame/TwitchBronBron/rokucommunity/roku-debug/links/2)[![](https://sourcerer.io/fame/TwitchBronBron/rokucommunity/roku-debug/images/3)](https://sourcerer.io/fame/TwitchBronBron/rokucommunity/roku-debug/links/3)[![](https://sourcerer.io/fame/TwitchBronBron/rokucommunity/roku-debug/images/4)](https://sourcerer.io/fame/TwitchBronBron/rokucommunity/roku-debug/links/4)[![](https://sourcerer.io/fame/TwitchBronBron/rokucommunity/roku-debug/images/5)](https://sourcerer.io/fame/TwitchBronBron/rokucommunity/roku-debug/links/5)[![](https://sourcerer.io/fame/TwitchBronBron/rokucommunity/roku-debug/images/6)](https://sourcerer.io/fame/TwitchBronBron/rokucommunity/roku-debug/links/6)[![](https://sourcerer.io/fame/TwitchBronBron/rokucommunity/roku-debug/images/7)](https://sourcerer.io/fame/TwitchBronBron/rokucommunity/roku-debug/links/7) diff --git a/package-lock.json b/package-lock.json index 737efa83..e7be050f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,17 @@ { "name": "roku-debug", - "version": "0.20.15", + "version": "0.21.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "roku-debug", - "version": "0.20.15", + "version": "0.21.1", "license": "MIT", "dependencies": { "@rokucommunity/logger": "^0.3.3", "@types/request": "^2.48.8", - "brighterscript": "^0.65.16", + "brighterscript": "^0.65.17", "dateformat": "^4.6.3", "debounce": "^1.2.1", "eol": "^0.9.1", @@ -20,6 +20,7 @@ "find-in-files": "^0.5.0", "fs-extra": "^10.0.0", "natural-orderby": "^2.0.3", + "portfinder": "^1.0.32", "postman-request": "^2.88.1-postman.32", "replace-in-file": "^6.3.2", "replace-last": "^1.2.6", @@ -34,6 +35,9 @@ "vscode-languageserver": "^6.1.1", "xml2js": "^0.5.0" }, + "bin": { + "roku-debug": "dist/cli.js" + }, "devDependencies": { "@types/chai": "^4.2.22", "@types/dateformat": "~3", @@ -61,7 +65,6 @@ "mocha": "^9.1.3", "nyc": "^15.1.0", "p-defer": "^4.0.0", - "portfinder": "^1.0.32", "rimraf": "^3.0.2", "rmfr": "^2.0.0", "rxjs": "^7.4.0", @@ -1271,7 +1274,6 @@ "version": "2.6.4", "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", - "dev": true, "dependencies": { "lodash": "^4.17.14" } @@ -1370,9 +1372,9 @@ } }, "node_modules/brighterscript": { - "version": "0.65.16", - "resolved": "https://registry.npmjs.org/brighterscript/-/brighterscript-0.65.16.tgz", - "integrity": "sha512-2RJMF8itkrPXtZ92JkJf3emvzcCl5ETXGVyPsdO/hMKbUGinEGMRFG07FR0bzjRotbALzsozGE/Hjzw412Sjww==", + "version": "0.65.17", + "resolved": "https://registry.npmjs.org/brighterscript/-/brighterscript-0.65.17.tgz", + "integrity": "sha512-c86jJYXwInV5ETnuE13VgyT8i+cTimabUPknImF51LQ1/gUDdrPL8d7NKcx+K8QBZLCW1ozkj/k6qttfEQnZRw==", "dependencies": { "@rokucommunity/bslib": "^0.1.1", "@xml-tools/parser": "^1.0.7", @@ -4054,8 +4056,7 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/nanoid": { "version": "3.3.1", @@ -4474,7 +4475,6 @@ "version": "1.0.32", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==", - "dev": true, "dependencies": { "async": "^2.6.4", "debug": "^3.2.7", @@ -4488,7 +4488,6 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, "dependencies": { "ms": "^2.1.1" } @@ -4497,7 +4496,6 @@ "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, "dependencies": { "minimist": "^1.2.6" }, @@ -6862,7 +6860,6 @@ "version": "2.6.4", "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", - "dev": true, "requires": { "lodash": "^4.17.14" } @@ -6938,9 +6935,9 @@ } }, "brighterscript": { - "version": "0.65.16", - "resolved": "https://registry.npmjs.org/brighterscript/-/brighterscript-0.65.16.tgz", - "integrity": "sha512-2RJMF8itkrPXtZ92JkJf3emvzcCl5ETXGVyPsdO/hMKbUGinEGMRFG07FR0bzjRotbALzsozGE/Hjzw412Sjww==", + "version": "0.65.17", + "resolved": "https://registry.npmjs.org/brighterscript/-/brighterscript-0.65.17.tgz", + "integrity": "sha512-c86jJYXwInV5ETnuE13VgyT8i+cTimabUPknImF51LQ1/gUDdrPL8d7NKcx+K8QBZLCW1ozkj/k6qttfEQnZRw==", "requires": { "@rokucommunity/bslib": "^0.1.1", "@xml-tools/parser": "^1.0.7", @@ -8961,8 +8958,7 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "nanoid": { "version": "3.3.1", @@ -9282,7 +9278,6 @@ "version": "1.0.32", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==", - "dev": true, "requires": { "async": "^2.6.4", "debug": "^3.2.7", @@ -9293,7 +9288,6 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, "requires": { "ms": "^2.1.1" } @@ -9302,7 +9296,6 @@ "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, "requires": { "minimist": "^1.2.6" } diff --git a/package.json b/package.json index 58fa05d6..5599378b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "roku-debug", - "version": "0.20.15", + "version": "0.21.1", "description": "Debug adapter for Roku application development using Node.js", "main": "dist/index.js", "scripts": { @@ -18,6 +18,9 @@ "type": "git", "url": "https://github.com/rokucommunity/roku-debug" }, + "bin": { + "roku-debug": "dist/cli.js" + }, "author": "RokuCommunity", "license": "MIT", "mocha": { @@ -84,7 +87,6 @@ "mocha": "^9.1.3", "nyc": "^15.1.0", "p-defer": "^4.0.0", - "portfinder": "^1.0.32", "rimraf": "^3.0.2", "rmfr": "^2.0.0", "rxjs": "^7.4.0", @@ -96,7 +98,7 @@ "dependencies": { "@rokucommunity/logger": "^0.3.3", "@types/request": "^2.48.8", - "brighterscript": "^0.65.16", + "brighterscript": "^0.65.17", "dateformat": "^4.6.3", "debounce": "^1.2.1", "eol": "^0.9.1", @@ -105,6 +107,7 @@ "find-in-files": "^0.5.0", "fs-extra": "^10.0.0", "natural-orderby": "^2.0.3", + "portfinder": "^1.0.32", "postman-request": "^2.88.1-postman.32", "replace-in-file": "^6.3.2", "replace-last": "^1.2.6", diff --git a/src/LaunchConfiguration.ts b/src/LaunchConfiguration.ts index fd5e2c5a..05d7d0b3 100644 --- a/src/LaunchConfiguration.ts +++ b/src/LaunchConfiguration.ts @@ -47,7 +47,9 @@ export interface LaunchConfiguration extends DebugProtocol.LaunchRequestArgument bsConst?: Record; /** - * Port to access component libraries. + * Port used to use when spinning up a web server to host component libraries. This runs on the developer machine and does not correspond to a port on the Roku device. + * Defaults to 8080 + * @default 8080 */ componentLibrariesPort: number; @@ -223,6 +225,7 @@ export interface LaunchConfiguration extends DebugProtocol.LaunchRequestArgument * The port that should be used when installing the package. Defaults to 80. * This is mainly useful for things like emulators that use alternate ports, * or when publishing through some type of port forwarding configuration. + * @default 80 */ packagePort?: number; @@ -230,20 +233,43 @@ export interface LaunchConfiguration extends DebugProtocol.LaunchRequestArgument * The port used to send remote control commands (like home press, back, etc.). Defaults to 8060. * This is mainly useful for things like emulators that use alternate ports, * or when sending commands through some type of port forwarding. + * @default 8060 */ remotePort?: number; /** - * The brightscript console port. In telnet mode this is the port used for the telnet connection. In debug protocol mode, this is used to obtain compile errors from the device. + * The port that should be used to send SceneGraph debug commands. Defaults to 8080. + * @default 8080 + */ + sceneGraphDebugCommandsPort: number; + + /** + * Port used to connect to and control a debug protocol session. + * This is mainly useful for things like emulators that use alternate ports, + * or when connecting to the debug protocol through some type of port forwarding. Defaults to 8081. + * @default 8081 + */ + controlPort: number; + + /** + * The brightscript console port. In telnet mode this is the port used for the primary telnet connection. In debug protocol mode, this is used to obtain compile errors from the device. Defaults to 8085. + * @default 8085 */ brightScriptConsolePort?: number; /** * The path used for the staging folder of roku-deploy * This should generally be set to "${cwd}/.roku-deploy-staging", but that's ultimately up to the debug client. + * @deprecated use `stagingDir` instead */ stagingFolderPath?: string; + /** + * Path used for the staging folder where files are written right before being packaged. This folder will contain any roku-debug related sourcemaps, + * as well as having breakpoints injected into source code + */ + stagingDir?: string; + /** * What level of debug server's internal logging should be performed in the debug session */ @@ -266,12 +292,6 @@ export interface LaunchConfiguration extends DebugProtocol.LaunchRequestArgument * @default false */ deleteDevChannelBeforeInstall: boolean; - - /** - * sceneGraphDebugCommandsPort - * The port that should be used to send SceneGraph debug commands. Defaults to 8080. - */ - sceneGraphDebugCommandsPort: number; } export interface ComponentLibraryConfiguration { diff --git a/src/cli.ts b/src/cli.ts new file mode 100644 index 00000000..7aa33ba3 --- /dev/null +++ b/src/cli.ts @@ -0,0 +1,17 @@ +#!/usr/bin/env node +import * as yargs from 'yargs'; +import { BrightScriptDebugSession } from './debugSession/BrightScriptDebugSession'; + +let options = yargs + .usage('$0', 'BrighterScript, a superset of Roku\'s BrightScript language') + .help('help', 'View help information about this tool.') + .option('dap', { type: 'boolean', defaultDescription: 'false', description: 'Run roku-debug as a standalone debug-adapter-protocol process, communicating over STDIO' }) + .parseSync(); + +(function main() { + if (options.dap) { + BrightScriptDebugSession.run(BrightScriptDebugSession); + } else { + throw new Error('Not supported'); + } +}()); diff --git a/src/debugSession/BrightScriptDebugSession.spec.ts b/src/debugSession/BrightScriptDebugSession.spec.ts index c69f9382..395b0a3a 100644 --- a/src/debugSession/BrightScriptDebugSession.spec.ts +++ b/src/debugSession/BrightScriptDebugSession.spec.ts @@ -64,7 +64,7 @@ describe('BrightScriptDebugSession', () => { launchConfiguration = { rootDir: rootDir, outDir: outDir, - stagingFolderPath: stagingDir, + stagingDir: stagingDir, files: DefaultFiles } as any; session['launchConfiguration'] = launchConfiguration; @@ -658,7 +658,7 @@ describe('BrightScriptDebugSession', () => { it('registers the entry breakpoint when stopOnEntry is enabled', async () => { (session as any).launchConfiguration = { stopOnEntry: true }; session.projectManager.mainProject = { - stagingFolderPath: stagingDir + stagingDir: stagingDir }; let stub = sinon.stub(session.projectManager, 'registerEntryBreakpoint').returns(Promise.resolve()); await session.handleEntryBreakpoint(); @@ -677,10 +677,10 @@ describe('BrightScriptDebugSession', () => { it('erases all staging folders when configured to do so', async () => { let stub = sinon.stub(fsExtra, 'removeSync').returns(null); session.projectManager.mainProject = { - stagingFolderPath: 'stagingPathA' + stagingDir: 'stagingPathA' }; session.projectManager.componentLibraryProjects.push({ - stagingFolderPath: 'stagingPathB' + stagingDir: 'stagingPathB' }); (session as any).launchConfiguration = { retainStagingFolder: false @@ -830,7 +830,7 @@ describe('BrightScriptDebugSession', () => { session.projectManager.componentLibraryProjects.push( new ComponentLibraryProject({ rootDir: complib1Dir, - stagingFolderPath: stagingDir, + stagingDir: stagingDir, outDir: outDir, libraryIndex: 1 } as Partial as any) diff --git a/src/debugSession/BrightScriptDebugSession.ts b/src/debugSession/BrightScriptDebugSession.ts index 5b610e45..8c038d60 100644 --- a/src/debugSession/BrightScriptDebugSession.ts +++ b/src/debugSession/BrightScriptDebugSession.ts @@ -217,13 +217,29 @@ export class BrightScriptDebugSession extends BaseDebugSession { public deviceInfo: DeviceInfo; + /** + * Set defaults and standardize values for all of the LaunchConfiguration values + * @param config + * @returns + */ + private normalizeLaunchConfig(config: LaunchConfiguration) { + config.componentLibrariesPort ??= 8080; + config.packagePort ??= 80; + config.remotePort ??= 8060; + config.sceneGraphDebugCommandsPort ??= 8080; + config.controlPort ??= 8081; + config.brightScriptConsolePort ??= 8085; + config.stagingDir ??= config.stagingFolderPath; + return config; + } + public async launchRequest(response: DebugProtocol.LaunchResponse, config: LaunchConfiguration) { this.logger.log('[launchRequest] begin'); //send the response right away so the UI immediately shows the debugger toolbar this.sendResponse(response); - this.launchConfiguration = config; + this.launchConfiguration = this.normalizeLaunchConfig(config); //set the logLevel provided by the launch config if (this.launchConfiguration.logLevel) { @@ -267,7 +283,11 @@ export class BrightScriptDebugSession extends BaseDebugSession { ]); this.logger.log(`Packaging projects took: ${(util.formatTime(Date.now() - start))}`); - util.log(`Connecting to Roku via ${this.enableDebugProtocol ? 'the BrightScript debug protocol' : 'telnet'} at ${this.launchConfiguration.host}`); + if (this.enableDebugProtocol) { + util.log(`Connecting to Roku via the BrightScript debug protocol at ${this.launchConfiguration.host}:${this.launchConfiguration.controlPort}`); + } else { + util.log(`Connecting to Roku via telnet at ${this.launchConfiguration.host}:${this.launchConfiguration.brightScriptConsolePort}`); + } await this.initRendezvousTracking(); @@ -600,7 +620,7 @@ export class BrightScriptDebugSession extends BaseDebugSession { raleTrackerTaskFileLocation: this.launchConfiguration.raleTrackerTaskFileLocation, injectRdbOnDeviceComponent: this.launchConfiguration.injectRdbOnDeviceComponent, rdbFilesBasePath: this.launchConfiguration.rdbFilesBasePath, - stagingFolderPath: this.launchConfiguration.stagingFolderPath + stagingDir: this.launchConfiguration.stagingDir }); util.log('Moving selected files to staging area'); @@ -1411,7 +1431,7 @@ export class BrightScriptDebugSession extends BaseDebugSession { if (!this.enableDebugProtocol) { this.entryBreakpointWasHandled = true; if (this.launchConfiguration.stopOnEntry || this.launchConfiguration.deepLinkUrl) { - await this.projectManager.registerEntryBreakpoint(this.projectManager.mainProject.stagingFolderPath); + await this.projectManager.registerEntryBreakpoint(this.projectManager.mainProject.stagingDir); } } } @@ -1440,14 +1460,14 @@ export class BrightScriptDebugSession extends BaseDebugSession { //if configured, delete the staging directory if (!this.launchConfiguration.retainStagingFolder) { - const stagingFolders = this.projectManager?.getStagingFolderPaths() ?? []; - this.logger.info('deleting staging folders', stagingFolders); - for (let stagingFolderPath of stagingFolders) { + const stagingDirs = this.projectManager?.getStagingDirs() ?? []; + this.logger.info('deleting staging folders', stagingDirs); + for (let stagingDir of stagingDirs) { try { - fsExtra.removeSync(stagingFolderPath); + fsExtra.removeSync(stagingDir); } catch (e) { this.logger.error(e); - util.log(`Error removing staging directory '${stagingFolderPath}': ${JSON.stringify(e)}`); + util.log(`Error removing staging directory '${stagingDir}': ${JSON.stringify(e)}`); } } } diff --git a/src/managers/BreakpointManager.spec.ts b/src/managers/BreakpointManager.spec.ts index 746a611b..715e5ca0 100644 --- a/src/managers/BreakpointManager.spec.ts +++ b/src/managers/BreakpointManager.spec.ts @@ -388,7 +388,7 @@ describe('BreakpointManager', () => { await bpManager.writeBreakpointsForProject(new Project({ rootDir: rootDir, outDir: outDir, - stagingFolderPath: stagingDir + stagingDir: stagingDir })); //it wrote the breakpoint in the correct location @@ -429,7 +429,7 @@ describe('BreakpointManager', () => { rootDir: rootDir, outDir: s`${cwd}/out`, sourceDirs: [sourceDir1], - stagingFolderPath: stagingDir + stagingDir: stagingDir }) ); @@ -467,7 +467,7 @@ describe('BreakpointManager', () => { rootDir: rootDir, outDir: s`${cwd}/out`, sourceDirs: [sourceDir1, sourceDir2], - stagingFolderPath: stagingDir + stagingDir: stagingDir }) ); @@ -510,7 +510,7 @@ describe('BreakpointManager', () => { rootDir: rootDir, outDir: s`${cwd}/out`, sourceDirs: [sourceDir1, sourceDir2], - stagingFolderPath: stagingDir + stagingDir: stagingDir }) ); @@ -552,7 +552,7 @@ describe('BreakpointManager', () => { rootDir: rootDir, outDir: s`${cwd}/out`, sourceDirs: [sourceDir1, sourceDir2], - stagingFolderPath: stagingDir + stagingDir: stagingDir }) ); @@ -609,7 +609,7 @@ describe('BreakpointManager', () => { ], rootDir: s`${tmpDir}/dist`, outDir: s`${tmpDir}/out`, - stagingFolderPath: stagingDir + stagingDir: stagingDir })); //the breakpoints should be placed in the proper locations @@ -714,7 +714,7 @@ describe('BreakpointManager', () => { files: [ 'source/main.brs' ], - stagingFolderPath: stagingDir, + stagingDir: stagingDir, outDir: outDir, rootDir: rootDir })); @@ -726,7 +726,7 @@ describe('BreakpointManager', () => { lineNumber: 2, fileMappings: [], rootDir: rootDir, - stagingFolderPath: stagingDir, + stagingDir: stagingDir, enableSourceMaps: true }); @@ -775,7 +775,7 @@ describe('BreakpointManager', () => { files: [ 'source/main.brs' ], - stagingFolderPath: stagingDir, + stagingDir: stagingDir, outDir: outDir, rootDir: rootDir })); @@ -813,7 +813,7 @@ describe('BreakpointManager', () => { dest: '' } ], - stagingFolderPath: stagingDir, + stagingDir: stagingDir, outDir: outDir, rootDir: rootDir }); diff --git a/src/managers/BreakpointManager.ts b/src/managers/BreakpointManager.ts index 5d261d59..1087afcd 100644 --- a/src/managers/BreakpointManager.ts +++ b/src/managers/BreakpointManager.ts @@ -368,7 +368,7 @@ export class BreakpointManager { ...project?.sourceDirs ?? [], project.rootDir ], - project.stagingFolderPath, + project.stagingDir, project.fileMappings ); @@ -376,7 +376,7 @@ export class BreakpointManager { let relativeStagingPath = fileUtils.replaceCaseInsensitive( stagingLocation.filePath, fileUtils.standardizePath( - fileUtils.removeTrailingSlash(project.stagingFolderPath) + '/' + fileUtils.removeTrailingSlash(project.stagingDir) + '/' ), '' ); @@ -384,7 +384,7 @@ export class BreakpointManager { //replace staging folder path with nothing (so we can build a pkg path) .replaceCaseInsensitive( s`${stagingLocation.filePath}`, - s`${project.stagingFolderPath}`, + s`${project.stagingDir}`, '' ) //force to unix path separators diff --git a/src/managers/LocationManager.spec.ts b/src/managers/LocationManager.spec.ts index 8387a665..ca2294ac 100644 --- a/src/managers/LocationManager.spec.ts +++ b/src/managers/LocationManager.spec.ts @@ -52,7 +52,7 @@ describe('LocationManager', () => { let location = await locationManager.getSourceLocation({ stagingFilePath: stagingFilePath, - stagingFolderPath: stagingDir, + stagingDir: stagingDir, fileMappings: [], rootDir: rootDir, lineNumber: 1, @@ -76,7 +76,7 @@ describe('LocationManager', () => { let location = await locationManager.getSourceLocation({ stagingFilePath: s`${stagingDir}/lib1.brs`, - stagingFolderPath: stagingDir, + stagingDir: stagingDir, fileMappings: [{ src: s`${rootDir}/lib1.brs`, dest: s`${stagingDir}/lib1.brs` @@ -116,7 +116,7 @@ describe('LocationManager', () => { let location = await locationManager.getSourceLocation({ stagingFilePath: stagingFilePath, - stagingFolderPath: stagingDir, + stagingDir: stagingDir, fileMappings: [], rootDir: rootDir, lineNumber: 3, @@ -142,7 +142,7 @@ describe('LocationManager', () => { let location = await locationManager.getSourceLocation({ stagingFilePath: s`${stagingDir}/lib1.brs`, - stagingFolderPath: stagingDir, + stagingDir: stagingDir, fileMappings: [{ src: s`${sourceDirs[0]}/lib1.brs`, dest: '/lib1.brs' @@ -169,7 +169,7 @@ describe('LocationManager', () => { let location = await locationManager.getSourceLocation({ stagingFilePath: s`${stagingDir}/lib1.brs`, - stagingFolderPath: stagingDir, + stagingDir: stagingDir, fileMappings: [{ src: s`${sourceDirs[1]}/lib1.brs`, dest: '/lib1.brs' @@ -195,7 +195,7 @@ describe('LocationManager', () => { let location = await locationManager.getSourceLocation({ stagingFilePath: s`${stagingDir}/lib1.brs`, - stagingFolderPath: stagingDir, + stagingDir: stagingDir, fileMappings: [{ src: s`${sourceDirs[2]}/lib1.brs`, dest: '/lib1.brs' diff --git a/src/managers/LocationManager.ts b/src/managers/LocationManager.ts index 91a712ec..e0433898 100644 --- a/src/managers/LocationManager.ts +++ b/src/managers/LocationManager.ts @@ -18,7 +18,7 @@ export class LocationManager { */ public async getSourceLocation(options: GetSourceLocationOptions): Promise { let rootDir = s`${options.rootDir}`; - let stagingFolderPath = s`${options.stagingFolderPath}`; + let stagingDir = s`${options.stagingDir}`; let currentFilePath = s`${options.stagingFilePath}`; let sourceDirs = options.sourceDirs ? options.sourceDirs.map(x => s`${x}`) : []; //throw out any sourceDirs pointing the rootDir @@ -62,7 +62,7 @@ export class LocationManager { //if we have sourceDirs, rootDir is the project's OUTPUT folder, so skip looking for files there, and //instead walk backwards through sourceDirs until we find the file we want if (sourceDirs.length > 0) { - let relativeFilePath = fileUtils.getRelativePath(stagingFolderPath, currentFilePath); + let relativeFilePath = fileUtils.getRelativePath(stagingDir, currentFilePath); let sourceDirsFilePath = await fileUtils.findFirstRelativeFile(relativeFilePath, sourceDirs); //if we found a file in one of the sourceDirs, use that if (sourceDirsFilePath) { @@ -104,18 +104,18 @@ export class LocationManager { sourceLineNumber: number, sourceColumnIndex: number, sourceDirs: string[], - stagingFolderPath: string, + stagingDir: string, fileMappings: Array<{ src: string; dest: string }> ): Promise<{ type: 'fileMap' | 'sourceDirs' | 'sourceMap'; locations: SourceLocation[] }> { sourceFilePath = s`${sourceFilePath}`; sourceDirs = sourceDirs.map(x => s`${x}`); - stagingFolderPath = s`${stagingFolderPath}`; + stagingDir = s`${stagingDir}`; //look through the sourcemaps in the staging folder for any instances of this source location let locations = await this.sourceMapManager.getGeneratedLocations( glob.sync('**/*.map', { - cwd: stagingFolderPath, + cwd: stagingDir, absolute: true }), { @@ -141,7 +141,7 @@ export class LocationManager { let parentFolderPath = fileUtils.findFirstParent(sourceFilePath, sourceDirs); if (parentFolderPath) { let relativeFilePath = fileUtils.replaceCaseInsensitive(sourceFilePath, parentFolderPath, ''); - let stagingFilePathAbsolute = path.join(stagingFolderPath, relativeFilePath); + let stagingFilePathAbsolute = path.join(stagingDir, relativeFilePath); return { type: 'sourceDirs', locations: [{ @@ -180,7 +180,7 @@ export interface GetSourceLocationOptions { /** * The absolute path to the staging folder */ - stagingFolderPath: string; + stagingDir: string; /** * The absolute path to the file in the staging folder diff --git a/src/managers/ProjectManager.spec.ts b/src/managers/ProjectManager.spec.ts index e86b92ee..cf1c4d44 100644 --- a/src/managers/ProjectManager.spec.ts +++ b/src/managers/ProjectManager.spec.ts @@ -19,9 +19,9 @@ let cwd = fileUtils.standardizePath(process.cwd()); let tempPath = s`${cwd}/.tmp`; let rootDir = s`${tempPath}/rootDir`; let outDir = s`${tempPath}/outDir`; -let stagingFolderPath = s`${outDir}/stagingDir`; +let stagingDir = s`${outDir}/stagingDir`; let compLibOutDir = s`${outDir}/component-libraries`; -let compLibStagingFolderPath = s`${rootDir}/component-libraries/CompLibA`; +let compLibstagingDir = s`${rootDir}/component-libraries/CompLibA`; beforeEach(() => { fsExtra.ensureDirSync(tempPath); @@ -44,10 +44,10 @@ describe('ProjectManager', () => { manager = new ProjectManager(breakpointManager, locationManager); manager.mainProject = { - stagingFolderPath: stagingFolderPath + stagingDir: stagingDir }; manager.componentLibraryProjects.push({ - stagingFolderPath: compLibStagingFolderPath, + stagingDir: compLibstagingDir, libraryIndex: 1, outDir: compLibOutDir }); @@ -173,7 +173,7 @@ describe('ProjectManager', () => { expect( await manager.getStagingFileInfo('pkg:/source/main.brs') ).to.include({ - absolutePath: s`${stagingFolderPath}/source/main.brs`, + absolutePath: s`${stagingDir}/source/main.brs`, //the relative path should not include a leading slash relativePath: s`source/main.brs` }); @@ -182,13 +182,13 @@ describe('ProjectManager', () => { it(`searches for partial files in main project when '...' is encountered`, async () => { let stub = sinon.stub(fileUtils, 'findPartialFileInDirectory').callsFake((partialFilePath, directoryPath) => { expect(partialFilePath).to.equal('...ource/main.brs'); - expect(directoryPath).to.equal(manager.mainProject.stagingFolderPath); + expect(directoryPath).to.equal(manager.mainProject.stagingDir); return Promise.resolve(`source/main.brs`); }); expect( (await manager.getStagingFileInfo('...ource/main.brs')).absolutePath ).to.equal( - s`${stagingFolderPath}/source/main.brs` + s`${stagingDir}/source/main.brs` ); expect(stub.called).to.be.true; }); @@ -197,20 +197,20 @@ describe('ProjectManager', () => { expect( (await manager.getStagingFileInfo('pkg:/source/main__lib1.brs')).absolutePath ).to.equal( - s`${compLibStagingFolderPath}/source/main__lib1.brs` + s`${compLibstagingDir}/source/main__lib1.brs` ); }); it(`detects partial paths to component library filenames`, async () => { let stub = sinon.stub(fileUtils, 'findPartialFileInDirectory').callsFake((partialFilePath, directoryPath) => { expect(partialFilePath).to.equal('...ource/main__lib1.brs'); - expect(directoryPath).to.equal(manager.componentLibraryProjects[0].stagingFolderPath); + expect(directoryPath).to.equal(manager.componentLibraryProjects[0].stagingDir); return Promise.resolve(`source/main__lib1.brs`); }); let info = await manager.getStagingFileInfo('...ource/main__lib1.brs'); expect(info).to.deep.include({ relativePath: s`source/main__lib1.brs`, - absolutePath: s`${compLibStagingFolderPath}/source/main__lib1.brs` + absolutePath: s`${compLibstagingDir}/source/main__lib1.brs` }); expect(info.project).to.include({ outDir: compLibOutDir @@ -224,7 +224,7 @@ describe('ProjectManager', () => { it(`does not crash when file is missing`, async () => { manager.mainProject.fileMappings = []; let sourceLocation = await manager.getSourceLocation('pkg:/source/file-we-dont-know-about.brs', 1); - expect(n(sourceLocation.filePath)).to.equal(n(`${stagingFolderPath}/source/file-we-dont-know-about.brs`)); + expect(n(sourceLocation.filePath)).to.equal(n(`${stagingDir}/source/file-we-dont-know-about.brs`)); }); it('handles truncated paths', async () => { @@ -241,13 +241,13 @@ describe('ProjectManager', () => { 'source/file2.brs' ])); manager.mainProject.rootDir = rootDir; - manager.mainProject.stagingFolderPath = stagingFolderPath; + manager.mainProject.stagingDir = stagingDir; manager.mainProject.fileMappings = [{ src: s`${rootDir}/source/file1.brs`, - dest: s`${stagingFolderPath}/source/file1.brs` + dest: s`${stagingDir}/source/file1.brs` }, { src: s`${rootDir}/source/file2.brs`, - dest: s`${stagingFolderPath}/source/file2.brs` + dest: s`${stagingDir}/source/file2.brs` }]; let sourceLocation = await manager.getSourceLocation('...rce/file1.brs', 1); @@ -268,13 +268,13 @@ describe('ProjectManager', () => { } }); manager.mainProject.rootDir = rootDir; - manager.mainProject.stagingFolderPath = stagingFolderPath; + manager.mainProject.stagingDir = stagingDir; manager.mainProject.fileMappings = [{ src: s`${rootDir}/source/file1.brs`, - dest: s`${stagingFolderPath}/source/file1.brs` + dest: s`${stagingDir}/source/file1.brs` }, { src: s`${rootDir}/source/file2.brs`, - dest: s`${stagingFolderPath}/source/file2.brs` + dest: s`${stagingDir}/source/file2.brs` }]; let sourceLocation = await manager.getSourceLocation('pkg:source/file1.brs', 1); @@ -304,7 +304,7 @@ describe('Project', () => { injectRdbOnDeviceComponent: true, rdbFilesBasePath: rdbFilesBasePath, sourceDirs: [s`${cwd}/source1`], - stagingFolderPath: stagingFolderPath, + stagingDir: stagingDir, raleTrackerTaskFileLocation: 'z' }); }); @@ -320,7 +320,7 @@ describe('Project', () => { expect(project.injectRaleTrackerTask).to.equal(true); expect(project.outDir).to.eql(outDir); expect(project.sourceDirs).to.eql([s`${cwd}/source1`]); - expect(project.stagingFolderPath).to.eql(stagingFolderPath); + expect(project.stagingDir).to.eql(stagingDir); expect(project.raleTrackerTaskFileLocation).to.eql('z'); expect(project.injectRdbOnDeviceComponent).to.equal(true); expect(project.rdbFilesBasePath).to.eql(rdbFilesBasePath); @@ -336,17 +336,17 @@ describe('Project', () => { project.raleTrackerTaskFileLocation = undefined; project.rootDir = rootDir; project.outDir = outDir; - project.stagingFolderPath = stagingFolderPath; + project.stagingDir = stagingDir; fsExtra.ensureDirSync(project.rootDir); fsExtra.ensureDirSync(project.outDir); - fsExtra.ensureDirSync(project.stagingFolderPath); + fsExtra.ensureDirSync(project.stagingDir); fsExtra.writeFileSync(s`${project.rootDir}/manifest`, 'bs_const=b=true'); project.files = [ 'manifest' ]; await project.stage(); - expect(fsExtra.pathExistsSync(`${stagingFolderPath}/manifest`)).to.be.true; + expect(fsExtra.pathExistsSync(`${stagingDir}/manifest`)).to.be.true; }); }); @@ -443,7 +443,7 @@ describe('Project', () => { let filePath = s`${folder}/main.${fileExt}`; fsExtra.writeFileSync(filePath, fileContents); - project.stagingFolderPath = folder; + project.stagingDir = folder; project.injectRaleTrackerTask = true; //these file contents don't actually matter project.raleTrackerTaskFileLocation = raleTrackerTaskFileLocation; @@ -456,7 +456,7 @@ describe('Project', () => { fsExtra.ensureDirSync(tempPath); fsExtra.writeFileSync(`${tempPath}/RALE.xml`, 'test contents'); await doTest(`sub main()\nend sub`, `sub main()\nend sub`); - expect(fsExtra.pathExistsSync(s`${project.stagingFolderPath}/components/TrackerTask.xml`), 'TrackerTask.xml was not copied to staging').to.be.true; + expect(fsExtra.pathExistsSync(s`${project.stagingDir}/components/TrackerTask.xml`), 'TrackerTask.xml was not copied to staging').to.be.true; }); it('works for inline comments brs files', async () => { @@ -556,7 +556,7 @@ describe('Project', () => { let filePath = s`${folder}/main.${fileExt}`; fsExtra.writeFileSync(filePath, fileContents); - project.stagingFolderPath = folder; + project.stagingDir = folder; project.injectRdbOnDeviceComponent = injectRdbOnDeviceComponent; project.rdbFilesBasePath = rdbFilesBasePath; await project.copyAndTransformRDB(); @@ -567,8 +567,8 @@ describe('Project', () => { it('copies the RDB files', async () => { fsExtra.ensureDirSync(tempPath); await doTest(`sub main()\nend sub`, `sub main()\nend sub`); - expect(fsExtra.pathExistsSync(s`${project.stagingFolderPath}/${sourceFileRelativePath}`), `${sourceFileRelativePath} was not copied to staging`).to.be.true; - expect(fsExtra.pathExistsSync(s`${project.stagingFolderPath}/${componentsFileRelativePath}`), `${componentsFileRelativePath} was not copied to staging`).to.be.true; + expect(fsExtra.pathExistsSync(s`${project.stagingDir}/${sourceFileRelativePath}`), `${sourceFileRelativePath} was not copied to staging`).to.be.true; + expect(fsExtra.pathExistsSync(s`${project.stagingDir}/${componentsFileRelativePath}`), `${componentsFileRelativePath} was not copied to staging`).to.be.true; }); it('works for inline comments brs files', async () => { @@ -587,8 +587,8 @@ describe('Project', () => { // let brsSample = `\nsub main()\n screen.show\n ' ${Project.RDB_ODC_ENTRY}\nend sub`; // project.injectRdbOnDeviceComponent = false // await doTest(brsSample, brsSample, 'brs', false); - // expect(fsExtra.pathExistsSync(s`${project.stagingFolderPath}/${sourceFileRelativePath}`), `${sourceFileRelativePath} should not have been copied to staging`).to.be.false; - // expect(fsExtra.pathExistsSync(s`${project.stagingFolderPath}/${componentsFileRelativePath}`), `${componentsFileRelativePath} should not have been copied to staging`).to.be.false; + // expect(fsExtra.pathExistsSync(s`${project.stagingDir}/${sourceFileRelativePath}`), `${sourceFileRelativePath} should not have been copied to staging`).to.be.false; + // expect(fsExtra.pathExistsSync(s`${project.stagingDir}/${componentsFileRelativePath}`), `${componentsFileRelativePath} should not have been copied to staging`).to.be.false; // }); it('works for in line comments in xml files', async () => { @@ -652,9 +652,9 @@ describe('Project', () => { describe('zipPackage', () => { it('excludes sourcemaps', async () => { - fsExtra.outputFileSync(`${project.stagingFolderPath}/manifest`, '#stuff'); - fsExtra.outputFileSync(`${project.stagingFolderPath}/source/main.brs`, 'sub main() : end sub'); - fsExtra.outputFileSync(`${project.stagingFolderPath}/source/main.brs.map`, '{}'); + fsExtra.outputFileSync(`${project.stagingDir}/manifest`, '#stuff'); + fsExtra.outputFileSync(`${project.stagingDir}/source/main.brs`, 'sub main() : end sub'); + fsExtra.outputFileSync(`${project.stagingDir}/source/main.brs.map`, '{}'); await project.zipPackage({ retainStagingFolder: true }); const zipPath = path.join( project.outDir, @@ -680,7 +680,7 @@ describe('ComponentLibraryProject', () => { bsConst: { b: true }, injectRaleTrackerTask: true, sourceDirs: [s`${tempPath}/source1`], - stagingFolderPath: s`${outDir}/complib1-staging`, + stagingDir: s`${outDir}/complib1-staging`, raleTrackerTaskFileLocation: 'z', libraryIndex: 0, outFile: 'PrettyComponent.zip' @@ -700,8 +700,8 @@ describe('ComponentLibraryProject', () => { it('adds postfix if path is 1) pkg:/ or 2) relative - no spaces in url', async () => { let project = new ComponentLibraryProject(params); project.fileMappings = []; - fsExtra.outputFileSync(`${params.stagingFolderPath}/source/main.brs`, ''); - fsExtra.outputFileSync(`${params.stagingFolderPath}/components/Component1.xml`, ` + fsExtra.outputFileSync(`${params.stagingDir}/source/main.brs`, ''); + fsExtra.outputFileSync(`${params.stagingDir}/components/Component1.xml`, `