Skip to content

Commit

Permalink
Use 'default' alias if there are multiple aliases (#7804)
Browse files Browse the repository at this point in the history
* Default to default

* Use "default" alias project when there are multiple listed

* no only
  • Loading branch information
joehan authored Oct 7, 2024
1 parent 1085394 commit bfc3fd4
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
- Added emulator support for SDK defined extensions.
- Fixed various trigger handling issues in the Functions emualtor, including an issue where Eventarc functions would not be emulated correctly after a reload.
- Added support for generating Dart SDKs for Data Connect connectors.
- Commands now correctly default to 'default' alias when there is more than one alias listed. (#7624)
33 changes: 33 additions & 0 deletions src/command.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { expect } from "chai";
import * as sinon from "sinon";
import * as rc from "./rc";
import * as nock from "nock";

import { Command, validateProjectId } from "./command";
Expand Down Expand Up @@ -30,6 +32,18 @@ describe("Command", () => {
});

describe("runner", () => {
let rcStub: sinon.SinonStub;
beforeEach(() => {
rcStub = sinon
.stub(rc, "loadRC")
.returns(new rc.RC(undefined, { projects: { default: "default-project" } }));
});

afterEach(() => {
rcStub.restore();
nock.cleanAll();
});

it("should work when no arguments are passed and options", async () => {
const run = command
.action((options) => {
Expand Down Expand Up @@ -126,6 +140,25 @@ describe("Command", () => {
project: "resolved-project",
});
});

it("should use the 'default' alias if no project is passed", async () => {
const run = command
.action((options) => {
return {
project: options.project,
projectNumber: options.projectNumber,
projectId: options.projectId,
};
})
.runner();

const result = await run({});
expect(result).to.deep.eq({
projectId: "default-project",
projectNumber: undefined,
project: "default-project",
});
});
});
});

Expand Down
21 changes: 15 additions & 6 deletions src/command.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as clc from "colorette";
import { CommanderStatic } from "commander";
import { first, last, get, size, head, keys, values } from "lodash";
import { first, last, size, head, keys, values } from "lodash";

import { FirebaseError } from "./error";
import { getInheritedOption, setupLoggers, withTimeout } from "./utils";
Expand All @@ -12,6 +12,7 @@ import { trackEmulator, trackGA4 } from "./track";
import { selectAccount, setActiveAccount } from "./auth";
import { getFirebaseProject } from "./management/projects";
import { requireAuth } from "./requireAuth";
import { Options } from "./options";

// eslint-disable-next-line @typescript-eslint/no-explicit-any
type ActionFunction = (...args: any[]) => any;
Expand Down Expand Up @@ -334,25 +335,33 @@ export class Command {
* @param options the command options object.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
private applyRC(options: any): void {
private applyRC(options: Options): void {
const rc = loadRC(options);
options.rc = rc;

options.project =
options.project || (configstore.get("activeProjects") || {})[options.projectRoot];
const activeProject = options.projectRoot
? (configstore.get("activeProjects") ?? {})[options.projectRoot]
: undefined;
options.project = options.project ?? activeProject;
// support deprecated "firebase" key in firebase.json
if (options.config && !options.project) {
options.project = options.config.defaults.project;
}

const aliases = rc.projects;
const rcProject = get(aliases, options.project);
const rcProject = options.project ? aliases[options.project] : undefined;
if (rcProject) {
// Look up aliases
options.projectAlias = options.project;
options.project = rcProject;
} else if (!options.project && size(aliases) === 1) {
// If there's only a single alias, use that.
// This seems to be how we originally implemented default project - keeping this behavior to avoid breaking any unusual set ups.
options.projectAlias = head(keys(aliases));
options.project = head(values(aliases));
} else if (!options.project && aliases["default"]) {
// If there's an alias named 'default', default to that.
options.projectAlias = "default";
options.project = aliases["default"];
}
}

Expand Down

0 comments on commit bfc3fd4

Please sign in to comment.