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

Adding support for <product>_EMULATOR_BINARY_PATH for local emualtor dev #6981

Merged
merged 10 commits into from
May 30, 2024
8 changes: 8 additions & 0 deletions src/emulator/download.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,16 @@

tmp.setGracefulCleanup();

export async function downloadEmulator(name: DownloadableEmulators): Promise<void> {

Check warning on line 15 in src/emulator/download.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Missing JSDoc comment
const emulator = downloadableEmulators.getDownloadDetails(name);
if (emulator.localOnly) {
EmulatorLogger.forEmulator(name).logLabeled(
"WARN",
name,
`Env variable override detected, skipping download. Using ${emulator} emulator at ${emulator.binaryPath}`,

Check warning on line 21 in src/emulator/download.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Invalid type "EmulatorDownloadDetails" of template literal expression

Check warning on line 21 in src/emulator/download.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Invalid type "string | undefined" of template literal expression
);
return;
}
EmulatorLogger.forEmulator(name).logLabeled(
"BULLET",
name,
Expand Down Expand Up @@ -43,7 +51,7 @@
removeOldFiles(name, emulator);
}

export async function downloadExtensionVersion(

Check warning on line 54 in src/emulator/download.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Missing JSDoc comment
extensionVersionRef: string,
sourceDownloadUri: string,
targetDir: string,
Expand Down Expand Up @@ -86,7 +94,7 @@
for (const file of files) {
const fullFilePath = path.join(emulator.opts.cacheDir, file);

if (file.indexOf(emulator.opts.namePrefix) < 0) {

Check warning on line 97 in src/emulator/download.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Use 'includes()' method instead
// This file is not related to this emulator, could be a JAR
// from a different emulator or just a random file.
continue;
Expand Down Expand Up @@ -130,7 +138,7 @@
return new Promise((resolve, reject) => {
const hash = crypto.createHash("md5");
const stream = fs.createReadStream(filepath);
stream.on("data", (data: any) => hash.update(data));

Check warning on line 141 in src/emulator/download.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unexpected any. Specify a different type

Check warning on line 141 in src/emulator/download.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe argument of type `any` assigned to a parameter of type `BinaryLike`
stream.on("end", () => {
const checksum = hash.digest("hex");
return checksum === expectedChecksum
Expand Down
21 changes: 17 additions & 4 deletions src/emulator/downloadableEmulators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@
shell: false,
},
pubsub: {
binary: getExecPath(Emulators.PUBSUB)!,

Check warning on line 276 in src/emulator/downloadableEmulators.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Forbidden non-null assertion
args: [],
optionalArgs: ["port", "host"],
joinArgs: true,
Expand All @@ -297,7 +297,7 @@
"service_location",
],
joinArgs: true,
shell: true,
shell: false,
},
};

Expand All @@ -307,7 +307,7 @@
}

/**
* @param name

Check warning on line 310 in src/emulator/downloadableEmulators.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Missing JSDoc @param "name" description
*/
export function getLogFileName(name: string): string {
return `${name}-debug.log`;
Expand All @@ -320,10 +320,9 @@
*/
export function _getCommand(
emulator: DownloadableEmulators,
args: { [s: string]: any },

Check warning on line 323 in src/emulator/downloadableEmulators.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unexpected any. Specify a different type
): DownloadableEmulatorCommand {
const baseCmd = Commands[emulator];

const defaultPort = Constants.getDefaultPort(emulator);
if (!args.port) {
args.port = defaultPort;
Expand Down Expand Up @@ -503,7 +502,21 @@
* @param emulator
*/
export function getDownloadDetails(emulator: DownloadableEmulators): EmulatorDownloadDetails {
return DownloadDetails[emulator];
const details = DownloadDetails[emulator];
const pathOverride = process.env[`${emulator.toUpperCase()}_EMULATOR_BINARY_PATH`];
if (pathOverride) {
const logger = EmulatorLogger.forEmulator(emulator);
logger.logLabeled(
"WARN",
emulator,
`Env variable override detected. Using ${emulator} emulator at ${pathOverride}`,
);
details.downloadPath = pathOverride;
details.binaryPath = pathOverride;
details.localOnly = true;
fs.chmodSync(pathOverride, 0o755);
}
return details;
}

/**
Expand Down Expand Up @@ -579,7 +592,7 @@
},
extraEnv: Partial<NodeJS.ProcessEnv> = {},
): Promise<void> {
const downloadDetails = DownloadDetails[targetName];
const downloadDetails = getDownloadDetails(targetName);
const emulator = get(targetName);
const hasEmulator = fs.existsSync(getExecPath(targetName));
const logger = EmulatorLogger.forEmulator(targetName);
Expand Down
4 changes: 2 additions & 2 deletions src/emulator/storage/rules/runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { downloadEmulator } from "../../download";
import * as fs from "fs-extra";
import {
_getCommand,
DownloadDetails,
getDownloadDetails,
handleEmulatorProcessError,
} from "../../downloadableEmulators";
import { EmulatorRegistry } from "../../registry";
Expand Down Expand Up @@ -124,7 +124,7 @@ export class StorageRulesRuntime {
if (this.alive) {
return;
}
const downloadDetails = DownloadDetails[Emulators.STORAGE];
const downloadDetails = getDownloadDetails(Emulators.STORAGE);
const hasEmulator = fs.existsSync(downloadDetails.downloadPath);

if (!hasEmulator) {
Expand Down
3 changes: 3 additions & 0 deletions src/emulator/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,9 @@ export interface EmulatorDownloadDetails {
// If specified, a path where the runnable binary can be found after downloading and
// unzipping. Otherwise downloadPath will be used.
binaryPath?: string;

// If true, never try to download this emualtor. Set when developing with local versions of an emulator.
localOnly?: boolean;
}

export interface DownloadableEmulatorDetails {
Expand Down
41 changes: 41 additions & 0 deletions src/test/emulators/downloadableEmulators.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { expect } from "chai";
import * as path from "path";
import * as sinon from "sinon";
import * as fs from "fs-extra";

import * as downloadableEmulators from "../../emulator/downloadableEmulators";
import { Emulators } from "../../emulator/types";
Expand All @@ -12,9 +14,48 @@ function checkDownloadPath(name: DownloadableEmulator): void {
}

describe("downloadDetails", () => {
const tempEnvVars: Record<DownloadableEmulator, string> = {
firestore: "",
database: "",
pubsub: "",
};
let chmodStub: sinon.SinonStub;
beforeEach(() => {
chmodStub = sinon.stub(fs, "chmodSync").returns();
tempEnvVars["firestore"] = process.env["FIRESTORE_EMULATOR_BINARY_PATH"] ?? "";
tempEnvVars["database"] = process.env["DATABASE_EMULATOR_BINARY_PATH"] ?? "";
tempEnvVars["pubsub"] = process.env["PUBSUB_EMULATOR_BINARY_PATH"] ?? "";
delete process.env["FIRESTORE_EMULATOR_BINARY_PATH"];
delete process.env["DATABASE_EMULATOR_BINARY_PATH"];
delete process.env["PUBSUB_EMULATOR_BINARY_PATH"];
});

afterEach(() => {
chmodStub.restore();
process.env["FIRESTORE_EMULATOR_BINARY_PATH"] = tempEnvVars["firestore"];
process.env["DATABASE_EMULATOR_BINARY_PATH"] = tempEnvVars["database"];
process.env["PUBSUB_EMULATOR_BINARY_PATH"] = tempEnvVars["pubsub"];
});
it("should match the basename of remoteUrl", () => {
checkDownloadPath(Emulators.FIRESTORE);
checkDownloadPath(Emulators.DATABASE);
checkDownloadPath(Emulators.PUBSUB);
});

it("should apply environment varable overrides", () => {
process.env["FIRESTORE_EMULATOR_BINARY_PATH"] = "my/fake/firestore";
process.env["DATABASE_EMULATOR_BINARY_PATH"] = "my/fake/database";
process.env["PUBSUB_EMULATOR_BINARY_PATH"] = "my/fake/pubsub";

expect(downloadableEmulators.getDownloadDetails(Emulators.FIRESTORE).binaryPath).to.equal(
"my/fake/firestore",
);
expect(downloadableEmulators.getDownloadDetails(Emulators.DATABASE).binaryPath).to.equal(
"my/fake/database",
);
expect(downloadableEmulators.getDownloadDetails(Emulators.PUBSUB).binaryPath).to.equal(
"my/fake/pubsub",
);
expect(chmodStub.callCount).to.equal(3);
});
});
Loading