Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add some enhanced launch settings to support more diverse projects #184

Merged
merged 21 commits into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
d6c552d
Add new custom event to trigger tasks
TwitchBronBron Jan 18, 2024
862ee26
support packagePath
TwitchBronBron Jan 18, 2024
1d79a2d
Support using `packagePath` when supplied
TwitchBronBron Jan 19, 2024
a7f7b60
Merge branch 'master' of https://github.com/rokucommunity/roku-debug …
TwitchBronBron Jan 19, 2024
d1a99af
doesHostSupportEcpRendezvousTracking better null handling
TwitchBronBron Jan 19, 2024
3d3ba8e
Better launchConfig sanitization
TwitchBronBron Jan 19, 2024
51f5604
Pass through packageUploadOverrides to roku-deploy
TwitchBronBron Jan 19, 2024
bf76a69
Fix stagingFolderPath reference
TwitchBronBron Jan 19, 2024
1fba681
Fix crash related to outDir and outFile
TwitchBronBron Jan 23, 2024
9c00c18
Merge branch 'master' of https://github.com/rokucommunity/roku-debug …
TwitchBronBron Jan 26, 2024
fe0cd0c
Fix bug in `getFileScheme`
TwitchBronBron Jan 29, 2024
25a3d75
Merge branch 'master' into enhanced-launch
georgejecook Feb 14, 2024
381ccfe
clears cache when manually controlling telnet session
georgejecook Feb 16, 2024
c781939
Support `packageTask`
TwitchBronBron Feb 21, 2024
00b0a63
Sill fixes.
TwitchBronBron Feb 21, 2024
66c7a9a
restore some actions that were disabled during testing
TwitchBronBron Feb 26, 2024
50f9bca
reenable rendezvous tracker
TwitchBronBron Feb 26, 2024
7a503fa
Better detection of missing custom package
TwitchBronBron Feb 26, 2024
4c1e1af
Add `emitChannelPublishedEvent` launch option
TwitchBronBron Feb 27, 2024
ae576e2
[email protected] and fix failing test
TwitchBronBron Mar 1, 2024
4981de7
Merge branch 'master' of https://github.com/rokucommunity/roku-debug …
TwitchBronBron Mar 1, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@
"postman-request": "^2.88.1-postman.32",
"replace-in-file": "^6.3.2",
"replace-last": "^1.2.6",
"roku-deploy": "^3.11.3",
"roku-deploy": "^3.12.0",
"semver": "^7.5.4",
"serialize-error": "^8.1.0",
"smart-buffer": "^4.2.0",
Expand Down
33 changes: 33 additions & 0 deletions src/LaunchConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,39 @@ export interface LaunchConfiguration extends DebugProtocol.LaunchRequestArgument
* @default false
*/
deleteDevChannelBeforeInstall: boolean;

/**
* Task to run instead of roku-deploy to produce the .zip file that will be uploaded to the Roku.
*/
packageTask: string;

/**
* Path to the .zip that will be uploaded to the Roku
*/
packagePath: string;

/**
* Overrides for values used during the roku-deploy zip upload process, like the route and various form data. You probably don't need to change these..
*/
packageUploadOverrides?: {
/**
* The route to use for uploading to the Roku device. Defaults to 'plugin_install'
* @default 'plugin_install'
*/
route: string;

/**
* A dictionary of form fields to be included in the package upload request. Set a value to null to delete from the form
*/
formData: Record<string, any>;
};

/**
* Should the ChannelPublishedEvent be emitted. This is a hack for when certain roku devices become locked up as a result of this event
* being emitted. You probably don't need to set this
* @default true
*/
emitChannelPublishedEvent?: boolean;
}

export interface ComponentLibraryConfiguration {
Expand Down
14 changes: 14 additions & 0 deletions src/RendezvousTracker.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,20 @@ describe('BrightScriptFileUtils ', () => {
rendezvousTracker['deviceInfo'].softwareVersion = '12.0.1';
expect(rendezvousTracker.doesHostSupportEcpRendezvousTracking).to.be.true;
});

it('does not crash when softwareVersion is corrupt or missing', () => {
rendezvousTracker['deviceInfo'].softwareVersion = '';
expect(rendezvousTracker.doesHostSupportEcpRendezvousTracking).to.be.false;

rendezvousTracker['deviceInfo'].softwareVersion = 'notAVersion';
expect(rendezvousTracker.doesHostSupportEcpRendezvousTracking).to.be.false;

rendezvousTracker['deviceInfo'].softwareVersion = undefined;
expect(rendezvousTracker.doesHostSupportEcpRendezvousTracking).to.be.false;

rendezvousTracker['deviceInfo'] = undefined;
expect(rendezvousTracker.doesHostSupportEcpRendezvousTracking).to.be.false;
});
});

describe('on', () => {
Expand Down
6 changes: 5 additions & 1 deletion src/RendezvousTracker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ export class RendezvousTracker {
* Determine if the current Roku device supports the ECP rendezvous tracking feature
*/
public get doesHostSupportEcpRendezvousTracking() {
return semver.gte(this.deviceInfo.softwareVersion, '11.5.0');
let softwareVersion = this.deviceInfo?.softwareVersion;
if (!semver.valid(softwareVersion)) {
softwareVersion = '0.0.0';
}
return semver.gte(softwareVersion, '11.5.0');
}

public logger = logger.createLogger(`[${RendezvousTracker.name}]`);
Expand Down
2 changes: 1 addition & 1 deletion src/adapters/TelnetAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { rokuDeploy } from 'roku-deploy';
import { PrintedObjectParser } from '../PrintedObjectParser';
import type { BSDebugDiagnostic } from '../CompileErrorProcessor';
import { CompileErrorProcessor } from '../CompileErrorProcessor';
import type { RendezvousHistory, RendezvousTracker } from '../RendezvousTracker';
import type { RendezvousTracker } from '../RendezvousTracker';
import type { ChanperfData } from '../ChanperfTracker';
import { ChanperfTracker } from '../ChanperfTracker';
import type { SourceLocation } from '../managers/LocationManager';
Expand Down
105 changes: 97 additions & 8 deletions src/debugSession/BrightScriptDebugSession.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,19 @@ import type { DebugProtocol } from 'vscode-debugprotocol/lib/debugProtocol';
import { DebugSession } from 'vscode-debugadapter';
import { BrightScriptDebugSession } from './BrightScriptDebugSession';
import { fileUtils } from '../FileUtils';
import type { EvaluateContainer, StackFrame, TelnetAdapter } from '../adapters/TelnetAdapter';
import { PrimativeType } from '../adapters/TelnetAdapter';
import { defer } from '../util';
import type { EvaluateContainer, StackFrame } from '../adapters/TelnetAdapter';
import { PrimativeType, TelnetAdapter } from '../adapters/TelnetAdapter';
import { defer, util } from '../util';
import { HighLevelType } from '../interfaces';
import type { LaunchConfiguration } from '../LaunchConfiguration';
import type { SinonStub } from 'sinon';
import { DiagnosticSeverity, util as bscUtil, standardizePath as s } from 'brighterscript';
import { DefaultFiles } from 'roku-deploy';
import { DefaultFiles, rokuDeploy } from 'roku-deploy';
import type { AddProjectParams, ComponentLibraryConstructorParams } from '../managers/ProjectManager';
import { ComponentLibraryProject, Project } from '../managers/ProjectManager';
import { RendezvousTracker } from '../RendezvousTracker';
import { ClientToServerCustomEventName, isCustomRequestEvent } from './Events';
import { EventEmitter } from 'eventemitter3';

const sinon = sinonActual.createSandbox();
const tempDir = s`${__dirname}/../../.tmp`;
Expand Down Expand Up @@ -99,10 +101,10 @@ describe('BrightScriptDebugSession', () => {
}
};
rokuAdapter = {
on: () => {
return () => {
};
},
emitter: new EventEmitter(),
on: TelnetAdapter.prototype.on,
once: TelnetAdapter.prototype.once,
emit: TelnetAdapter.prototype['emit'],
activate: () => Promise.resolve(),
registerSourceLocator: (a, b) => { },
setConsoleOutput: (a) => { },
Expand Down Expand Up @@ -148,6 +150,93 @@ describe('BrightScriptDebugSession', () => {
sinon.restore();
});

it('supports external zipping process', async () => {
//write some project files
fsExtra.outputFileSync(`${rootDir}/source/main.brs`, `
sub main()
print "hello"
end sub
`);
fsExtra.outputFileSync(`${rootDir}/manifest`, '');

const packagePath = s`${tempDir}/custom/app.zip`;

//init the session
session.initializeRequest({} as any, {} as any);

//set a breakpoint in main
await session.setBreakPointsRequest({} as any, {
source: {
path: s`${rootDir}/source/main.brs`
},
breakpoints: [{
line: 2
}]
});

sinon.stub(rokuDeploy, 'getDeviceInfo').returns(Promise.resolve({
developerEnabled: true
}));
sinon.stub(util, 'dnsLookup').callsFake((host) => Promise.resolve(host));

let sendEvent = session.sendEvent.bind(session);
sinon.stub(session, 'sendEvent').callsFake((event) => {
if (isCustomRequestEvent(event)) {
void rokuDeploy.zipFolder(session['launchConfiguration'].stagingDir, packagePath).then(() => {
//pretend we are the client and send a response back
session.emit(ClientToServerCustomEventName.customRequestEventResponse, {
requestId: event.body.requestId
});
});
} else {
//call through
return sendEvent(event);
}
});
sinon.stub(session as any, 'connectRokuAdapter').callsFake(() => {
sinon.stub(session['rokuAdapter'], 'connect').returns(Promise.resolve());
session['rokuAdapter'].connected = true;
return Promise.resolve(session['rokuAdapter']);
});

const publishStub = sinon.stub(session.rokuDeploy, 'publish').callsFake(() => {
//emit the app-ready event
(session['rokuAdapter'] as TelnetAdapter)['emit']('app-ready');

return Promise.resolve({
message: 'success',
results: []
});
});

await session.launchRequest({} as any, {
cwd: tempDir,
//where the source files reside
rootDir: rootDir,
//where roku-debug should put the staged files (and inject breakpoints)
stagingDir: `${stagingDir}/staging`,
//the name of the task that should be run to create the zip (doesn't matter for this test...we're going to intercept it anyway)
packageTask: 'custom-build',
//where the packageTask will be placing the compiled zip
packagePath: packagePath,
packageUploadOverrides: {
route: '1234',
formData: {
one: 'two',
three: null
}
}
} as Partial<LaunchConfiguration> as LaunchConfiguration);

expect(publishStub.getCall(0).args[0].packageUploadOverrides).to.eql({
route: '1234',
formData: {
one: 'two',
three: null
}
});
});

describe('evaluateRequest', () => {
it('resets local var counter on suspend', async () => {
const stub = sinon.stub(session['rokuAdapter'], 'evaluate').callsFake(x => {
Expand Down
Loading