Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
28 changes: 25 additions & 3 deletions src/firebase_studio/migrate.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,16 @@
});

describe("extractMetadata", () => {
let readFileStub: sinon.SinonStub;
beforeEach(() => {
sandbox.stub(fs, "readFile").callsFake(async (p: any) => {
readFileStub = sandbox.stub(fs, "readFile").callsFake(async (p: any) => {

Check warning on line 27 in src/firebase_studio/migrate.spec.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unexpected any. Specify a different type
const pStr = p.toString();

Check warning on line 28 in src/firebase_studio/migrate.spec.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe call of an `any` typed value

Check warning on line 28 in src/firebase_studio/migrate.spec.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe member access .toString on an `any` value

Check warning on line 28 in src/firebase_studio/migrate.spec.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe assignment of an `any` value
if (pStr.endsWith("metadata.json")) {
if (pStr.endsWith("metadata.json") || pStr.endsWith("studio.json")) {

Check warning on line 29 in src/firebase_studio/migrate.spec.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe call of an `any` typed value

Check warning on line 29 in src/firebase_studio/migrate.spec.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe member access .endsWith on an `any` value

Check warning on line 29 in src/firebase_studio/migrate.spec.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe call of an `any` typed value

Check warning on line 29 in src/firebase_studio/migrate.spec.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe member access .endsWith on an `any` value
return JSON.stringify({ projectId: "original-project" });
}
if (pStr.endsWith(".firebaserc")) {

Check warning on line 32 in src/firebase_studio/migrate.spec.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe call of an `any` typed value

Check warning on line 32 in src/firebase_studio/migrate.spec.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe member access .endsWith on an `any` value
throw Object.assign(new Error("File not found"), { code: "ENOENT" });
}
if (pStr.endsWith("blueprint.md")) {
return "# **App Name**: Test App";
}
Expand All @@ -40,7 +44,25 @@
expect(result.projectId).to.equal("override-project");
});

it("should fallback to metadata.json if no override is provided", async () => {
it("should use firebaserc project if override is not provided", async () => {
readFileStub.callsFake(async (p: any) => {
const pStr = p.toString();
if (pStr.endsWith("metadata.json") || pStr.endsWith("studio.json")) {
return JSON.stringify({ projectId: "original-project" });
}
if (pStr.endsWith(".firebaserc")) {
return JSON.stringify({ projects: { default: "firebaserc-project" } });
}
if (pStr.endsWith("blueprint.md")) {
return "# **App Name**: Test App";
}
return "";
});
const result = await extractMetadata(testRoot);
expect(result.projectId).to.equal("firebaserc-project");
});

it("should fallback to metadata.json/studio.json if no override or firebaserc is provided", async () => {
const result = await extractMetadata(testRoot);
expect(result.projectId).to.equal("original-project");
});
Expand Down
21 changes: 17 additions & 4 deletions src/firebase_studio/migrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,16 +179,29 @@ export async function extractMetadata(

logger.debug(`overrideProjectId ${overrideProjectId}`);
logger.debug(`metadata.projectId ${metadata.projectId}`);
let projectId = overrideProjectId || metadata.projectId;
if (!projectId) {
let projectId: string | undefined;
let projectIdSource = "";

if (overrideProjectId) {
projectId = overrideProjectId;
projectIdSource = "--project flag";
} else {
// try to get project ID from .firebaserc
try {
const firebasercContent = await fs.readFile(path.join(rootPath, ".firebaserc"), "utf8");
const firebaserc = JSON.parse(firebasercContent) as { projects?: { default?: string } };
projectId = firebaserc.projects?.default;
if (firebaserc.projects?.default) {
projectId = firebaserc.projects.default;
projectIdSource = ".firebaserc";
}
} catch (err: unknown) {
logger.debug(`Could not read .firebaserc at ${rootPath}: ${err}`);
}

if (!projectId && metadata.projectId) {
projectId = metadata.projectId;
projectIdSource = "studio.json";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The projectIdSource is hardcoded to "studio.json" here. However, the extractMetadata function (lines 201-209) attempts to read metadata.json first, and then studio.json. If studio.json is not found or is invalid, metadata.projectId would originate from metadata.json. To provide more accurate logging, consider dynamically determining whether the projectId came from metadata.json or studio.json.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good suggestion.

}
}

if (projectId) {
Expand All @@ -197,7 +210,7 @@ export async function extractMetadata(
exit: 1,
});
}
logger.info(`✅ Using Firebase Project: ${projectId}`);
logger.info(`✅ Using Firebase Project: ${projectId} (source: ${projectIdSource})`);
} else {
logger.debug(
`❌ Failed to determine the Firebase Project ID. You can set a project later by setting the '--project' flag.`,
Expand Down
Loading