Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
8 changes: 8 additions & 0 deletions src/ambient.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ declare global {
type: 'open-template',
listener: (name: string, editorValues: EditorValues) => void,
): void;
addEventListener(
type: 'register-local-version',
listener: (info: {
name: string;
path: string;
version: string;
}) => void,
): void;
addEventListener(
type: 'saved-local-fiddle',
listener: (filePath: string) => void,
Expand Down
2 changes: 2 additions & 0 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export type FileTransformOperation = 'dotfiles' | 'forge';
export enum VersionSource {
remote = 'remote',
local = 'local',
pullRequest = 'pull-request',
}

export enum GistActionType {
Expand Down Expand Up @@ -186,6 +187,7 @@ export type FiddleEvent =
| 'open-template'
| 'package-fiddle'
| 'redo-in-editor'
| 'register-local-version'
| 'run-fiddle'
| 'save-fiddle-gist'
| 'saved-local-fiddle'
Expand Down
1 change: 1 addition & 0 deletions src/ipc-events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export enum IpcEvents {
SHOW_WELCOME_TOUR = 'SHOW_WELCOME_TOUR',
CLEAR_CONSOLE = 'CLEAR_CONSOLE',
LOAD_LOCAL_VERSION_FOLDER = 'LOAD_LOCAL_VERSION_FOLDER',
REGISTER_LOCAL_VERSION_FOLDER = 'REGISTER_LOCAL_VERSION_FOLDER',
BISECT_COMMANDS_TOGGLE = 'BISECT_COMMANDS_TOGGLE',
BEFORE_QUIT = 'BEFORE_QUIT',
CONFIRM_QUIT = 'CONFIRM_QUIT',
Expand Down
11 changes: 1 addition & 10 deletions src/main/dialogs.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import * as path from 'node:path';

import { Installer } from '@electron/fiddle-core';
import { BrowserWindow, dialog } from 'electron';
import * as fs from 'fs-extra';

import { ipcMainManager } from './ipc';
import { isValidElectronPath } from './utils/local-version';
import { SelectedLocalVersion } from '../interfaces';
import { IpcEvents } from '../ipc-events';

Expand All @@ -31,14 +30,6 @@ function makeLocalName(folderPath: string): string {
return `${leader} - ${buildType}`;
}

/**
* Verifies if the local electron path is valid
*/
function isValidElectronPath(folderPath: string): boolean {
const execPath = Installer.getExecPath(folderPath);
return fs.existsSync(execPath);
}

/**
* Listens to IPC events related to dialogs and message boxes
*/
Expand Down
33 changes: 33 additions & 0 deletions src/main/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { app } from 'electron';
import { openFiddle } from './files';
import { ipcMainManager } from './ipc';
import { isDevMode } from './utils/devmode';
import { isValidElectronPath } from './utils/local-version';
import { getOrCreateMainWindow } from './windows';
import { IpcEvents } from '../ipc-events';

Expand Down Expand Up @@ -65,6 +66,38 @@ const handlePotentialProtocolLaunch = (url: string) => {
return;
}
break;
// electron-fiddle://register-local-version/?name={name}&path={path}&version={version}
case 'register-local-version': {
if (pathParts.length === 1) {
const name = parsed.searchParams.get('name');
const localPath = parsed.searchParams.get('path');
const version = parsed.searchParams.get('version');

if (!(name && localPath && version)) {
console.debug('register-local-version: Missing params');
return;
}

if (!isValidElectronPath(localPath)) {
console.debug(`register-local-version: Invalid path ${localPath}`);
return;
}

const toAdd = {
name,
path: localPath,
version,
};

console.debug('register-local-version: Registering version', toAdd);

ipcMainManager.send(IpcEvents.REGISTER_LOCAL_VERSION_FOLDER, [toAdd]);
} else {
// Invalid
return;
}
break;
}
default:
return;
}
Expand Down
11 changes: 11 additions & 0 deletions src/main/utils/local-version.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as fs from 'fs';

import { Installer } from '@electron/fiddle-core';

/**
* Verifies if the local electron path is valid
*/
export function isValidElectronPath(folderPath: string): boolean {
const execPath = Installer.getExecPath(folderPath);
return fs.existsSync(execPath);
}
1 change: 1 addition & 0 deletions src/preload/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const channelMapping: Record<FiddleEvent, IpcEvents> = {
'open-settings': IpcEvents.OPEN_SETTINGS,
'open-template': IpcEvents.FS_OPEN_TEMPLATE,
'package-fiddle': IpcEvents.FIDDLE_PACKAGE,
'register-local-version': IpcEvents.REGISTER_LOCAL_VERSION_FOLDER,
'redo-in-editor': IpcEvents.REDO_IN_EDITOR,
'run-fiddle': IpcEvents.FIDDLE_RUN,
'saved-local-fiddle': IpcEvents.SAVED_LOCAL_FIDDLE,
Expand Down
18 changes: 18 additions & 0 deletions src/renderer/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
PACKAGE_NAME,
PackageJsonOptions,
SetFiddleOptions,
Version,
} from '../interfaces';
import { defaultDark, defaultLight } from '../themes-defaults';

Expand Down Expand Up @@ -137,6 +138,7 @@ export class App {
this.setupTitleListeners();
this.setupUnloadListeners();
this.setupTypeListeners();
this.setupProtocolListeners();

window.ElectronFiddle.sendReady();

Expand Down Expand Up @@ -310,4 +312,20 @@ export class App {
};
});
}

public setupProtocolListeners() {
window.ElectronFiddle.addEventListener(
'register-local-version',
({ name, path, version }) => {
const toAdd: Version = {
localPath: path,
version,
name,
};

this.state.addLocalVersion(toAdd);
this.state.setVersion(version);
},
);
}
}
10 changes: 8 additions & 2 deletions src/renderer/versions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,16 @@ export function getElectronVersions(): Array<RunnableVersion> {
export function addLocalVersion(input: Version): Array<Version> {
const versions = getLocalVersions();

if (!versions.find((v) => v.localPath === input.localPath)) {
versions.push(input);
// Replace existing local version if it exists
const existingVersionIndex = versions.findIndex(
(v) => v.localPath === input.localPath,
);
if (existingVersionIndex > -1) {
versions.splice(existingVersionIndex, 1);
}

versions.push(input);

saveLocalVersions(versions);

return versions;
Expand Down
64 changes: 64 additions & 0 deletions tests/main/protocol-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/

import * as fs from 'node:fs';
import * as path from 'node:path';

import { app } from 'electron';
import { mocked } from 'jest-mock';
Expand All @@ -13,11 +14,16 @@ import {
listenForProtocolHandler,
setupProtocolHandler,
} from '../../src/main/protocol';
import { isValidElectronPath } from '../../src/main/utils/local-version';
import { getOrCreateMainWindow, mainIsReady } from '../../src/main/windows';
import { overridePlatform, resetPlatform } from '../utils';

jest.mock('node:fs');

jest.mock('../../src/main/utils/local-version', () => ({
isValidElectronPath: jest.fn(),
}));

describe('protocol', () => {
const oldArgv = [...process.argv];

Expand Down Expand Up @@ -192,5 +198,63 @@ describe('protocol', () => {
await new Promise(process.nextTick);
expect(mainWindow.focus).toHaveBeenCalled();
});

it('handles registering local version url', () => {
mocked(isValidElectronPath).mockReturnValueOnce(true);

overridePlatform('darwin');
listenForProtocolHandler();

const handler = mocked(app.on).mock.calls[0][1];
const url = new URL('electron-fiddle://register-local-version/');
const params = {
name: 'test',
path: path.resolve(__dirname),
version: '35.0.0-local',
};
const keys = Object.keys(params) as Array<keyof typeof params>;
keys.forEach((k) => {
url.searchParams.append(k, params[k]);
});
handler({}, url.href);

expect(ipcMainManager.send).toHaveBeenCalledWith(
IpcEvents.REGISTER_LOCAL_VERSION_FOLDER,
[params],
);
});

it('handles registering local version without valid path', () => {
mocked(isValidElectronPath).mockReturnValueOnce(false);

overridePlatform('darwin');
listenForProtocolHandler();

const handler = mocked(app.on).mock.calls[0][1];
const url = new URL('electron-fiddle://register-local-version/');
const params = {
name: 'test',
path: path.resolve(__dirname),
version: '35.0.0-local',
};
const keys = Object.keys(params) as Array<keyof typeof params>;
keys.forEach((k) => {
url.searchParams.append(k, params[k]);
});
handler({}, url.href);

expect(ipcMainManager.send).not.toHaveBeenCalled();
});

it('handles registering local version with missing params', () => {
overridePlatform('darwin');
listenForProtocolHandler();

const handler = mocked(app.on).mock.calls[0][1];
const url = new URL('electron-fiddle://register-local-version/');
handler({}, url.href);

expect(ipcMainManager.send).not.toHaveBeenCalled();
});
});
});
30 changes: 30 additions & 0 deletions tests/renderer/app-spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,36 @@ describe('App component', () => {
});
});

describe('setupProtocolListeners()', () => {
it('handles registering new versions', () => {
const addEventListenerMock = window.ElectronFiddle
.addEventListener as any;
addEventListenerMock.mockClear();

app.setupProtocolListeners();

expect(addEventListenerMock).toHaveBeenCalledWith(
'register-local-version',
expect.anything(),
);

const callback = addEventListenerMock.mock.calls[0][1];
const addVersion = {
name: 'new-version',
path: '/version/build/path',
version: '123.0.0-local',
};
callback(addVersion);

expect(app.state.addLocalVersion).toHaveBeenCalledWith({
name: addVersion.name,
localPath: addVersion.path,
version: addVersion.version,
});
expect(app.state.setVersion).toHaveBeenCalledWith(addVersion.version);
});
});

describe('prompting to confirm replacing an unsaved fiddle', () => {
// make a second fiddle that differs from the first
const editorValues = createEditorValues();
Expand Down