Skip to content

Commit 59fa61e

Browse files
authored
[FDC] Fix firebase dataconnect:sdk:generate --watch (#9055)
1 parent a0033aa commit 59fa61e

File tree

4 files changed

+64
-54
lines changed

4 files changed

+64
-54
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
- Support auth token JSON in `dataconnect_execute` MPC tool. (#9046)
22
- Fixed the bugs when MCP tools cannot connect to emulator due to CLI version mis-matched. (#9068)
3+
- Fix bug when `firebase dataconnect:sdk:generate --watch` swallow all logs. (#9055)

src/commands/dataconnect-sdk-generate.ts

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import { needProjectId } from "../projectUtils";
77
import { loadAll } from "../dataconnect/load";
88
import { logger } from "../logger";
99
import { getProjectDefaultAccount } from "../auth";
10+
import { logLabeledSuccess } from "../utils";
11+
import { ServiceInfo } from "../dataconnect/types";
1012

1113
type GenerateOptions = Options & { watch?: boolean };
1214

@@ -20,36 +22,41 @@ export const command = new Command("dataconnect:sdk:generate")
2022
const projectId = needProjectId(options);
2123

2224
const serviceInfos = await loadAll(projectId, options.config);
23-
for (const serviceInfo of serviceInfos) {
24-
const configDir = serviceInfo.sourceDirectory;
25-
const hasGeneratables = serviceInfo.connectorInfo.some((c) => {
25+
const serviceInfosWithSDKs = serviceInfos.filter((serviceInfo) =>
26+
serviceInfo.connectorInfo.some((c) => {
2627
return (
2728
c.connectorYaml.generate?.javascriptSdk ||
2829
c.connectorYaml.generate?.kotlinSdk ||
2930
c.connectorYaml.generate?.swiftSdk ||
3031
c.connectorYaml.generate?.dartSdk
3132
);
33+
}),
34+
);
35+
if (!serviceInfosWithSDKs.length) {
36+
logger.warn("No generated SDKs have been declared in connector.yaml files.");
37+
logger.warn(`Run ${clc.bold("firebase init dataconnect:sdk")} to configure a generated SDK.`);
38+
logger.warn(
39+
`See https://firebase.google.com/docs/data-connect/web-sdk for more details of how to configure generated SDKs.`,
40+
);
41+
return;
42+
}
43+
async function generateSDK(serviceInfo: ServiceInfo): Promise<void> {
44+
return DataConnectEmulator.generate({
45+
configDir: serviceInfo.sourceDirectory,
46+
watch: options.watch,
47+
account: getProjectDefaultAccount(options.projectRoot),
3248
});
33-
if (!hasGeneratables) {
34-
logger.warn("No generated SDKs have been declared in connector.yaml files.");
35-
logger.warn(
36-
`Run ${clc.bold("firebase init dataconnect:sdk")} to configure a generated SDK.`,
37-
);
38-
logger.warn(
39-
`See https://firebase.google.com/docs/data-connect/web-sdk for more details of how to configure generated SDKs.`,
40-
);
41-
return;
42-
}
43-
for (const conn of serviceInfo.connectorInfo) {
44-
const account = getProjectDefaultAccount(options.projectRoot);
45-
const output = await DataConnectEmulator.generate({
46-
configDir,
47-
connectorId: conn.connectorYaml.connectorId,
48-
watch: options.watch,
49-
account,
50-
});
51-
logger.info(output);
52-
logger.info(`Generated SDKs for ${conn.connectorYaml.connectorId}`);
49+
}
50+
if (options.watch) {
51+
await Promise.race(serviceInfosWithSDKs.map(generateSDK));
52+
} else {
53+
for (const s of serviceInfosWithSDKs) {
54+
await generateSDK(s);
5355
}
56+
const services = serviceInfosWithSDKs.map((s) => s.dataConnectYaml.serviceId).join(", ");
57+
logLabeledSuccess(
58+
"dataconnect",
59+
`Successfully Generated SDKs for services: ${clc.bold(services)}`,
60+
);
5461
}
5562
});

src/emulator/dataconnectEmulator.ts

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import { BuildResult, requiresVector } from "../dataconnect/types";
2222
import { listenSpecsToString } from "./portUtils";
2323
import { Client, ClientResponse } from "../apiv2";
2424
import { EmulatorRegistry } from "./registry";
25-
import { logger } from "../logger";
2625
import { load } from "../dataconnect/load";
2726
import { Config } from "../config";
2827
import { PostgresServer, TRUNCATE_TABLES_SQL } from "./dataconnect/pgliteServer";
@@ -51,7 +50,6 @@ export interface DataConnectEmulatorArgs {
5150

5251
export interface DataConnectGenerateArgs {
5352
configDir: string;
54-
connectorId: string;
5553
watch?: boolean;
5654
account?: Account;
5755
}
@@ -238,39 +236,44 @@ export class DataConnectEmulator implements EmulatorInstance {
238236
}
239237
}
240238

241-
static async generate(args: DataConnectGenerateArgs): Promise<string> {
239+
static async generate(args: DataConnectGenerateArgs): Promise<void> {
242240
const commandInfo = await downloadIfNecessary(Emulators.DATACONNECT);
243-
const cmd = [
244-
"--logtostderr",
245-
"-v=2",
246-
"generate",
247-
`--config_dir=${args.configDir}`,
248-
`--connector_id=${args.connectorId}`,
249-
];
241+
const cmd = ["--logtostderr", "-v=2", "sdk", "generate", `--config_dir=${args.configDir}`];
250242
if (args.watch) {
251243
cmd.push("--watch");
252244
}
253245
const env = await DataConnectEmulator.getEnv(args.account);
254-
const res = childProcess.spawnSync(commandInfo.binary, cmd, { encoding: "utf-8", env });
255-
if (isIncomaptibleArchError(res.error)) {
256-
throw new FirebaseError(
257-
`Unknown system error when running the Data Connect toolkit. ` +
258-
`You may be able to fix this by installing Rosetta: ` +
259-
`softwareupdate --install-rosetta`,
260-
);
261-
}
262-
logger.info(res.stderr);
263-
if (res.error) {
264-
throw new FirebaseError(`Error starting up Data Connect generate: ${res.error.message}`, {
265-
original: res.error,
266-
});
267-
}
268-
if (res.status !== 0) {
269-
throw new FirebaseError(
270-
`Unable to generate your Data Connect SDKs (exit code ${res.status}): ${res.stderr}`,
271-
);
272-
}
273-
return res.stdout;
246+
return new Promise((resolve, reject) => {
247+
try {
248+
const proc = childProcess.spawn(commandInfo.binary, cmd, { stdio: "inherit", env });
249+
proc.on("close", (code) => {
250+
if (code === 0) {
251+
// Command executed successfully
252+
resolve();
253+
} else {
254+
// Command failed
255+
reject(new Error(`Command failed with exit code ${code}`));
256+
}
257+
});
258+
259+
proc.on("error", (err) => {
260+
// Handle errors like command not found
261+
reject(err);
262+
});
263+
} catch (e: any) {
264+
if (isIncomaptibleArchError(e)) {
265+
reject(
266+
new FirebaseError(
267+
`Unknown system error when running the Data Connect toolkit. ` +
268+
`You may be able to fix this by installing Rosetta: ` +
269+
`softwareupdate --install-rosetta`,
270+
),
271+
);
272+
} else {
273+
reject(e);
274+
}
275+
}
276+
});
274277
}
275278

276279
static async build(args: DataConnectBuildArgs): Promise<BuildResult> {

src/init/features/dataconnect/sdk.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,6 @@ async function actuateWithInfo(setup: Setup, config: Config, info: SdkRequiredIn
202202
const account = getGlobalDefaultAccount();
203203
await DataConnectEmulator.generate({
204204
configDir: connectorInfo.directory,
205-
connectorId: connectorInfo.connectorYaml.connectorId,
206205
account,
207206
});
208207

0 commit comments

Comments
 (0)