Skip to content

Commit

Permalink
progress
Browse files Browse the repository at this point in the history
  • Loading branch information
mathu97 committed Nov 14, 2024
1 parent 7bcaa24 commit d61e180
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 75 deletions.
23 changes: 5 additions & 18 deletions src/emulator/apphosting/serve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@

import { isIPv4 } from "net";
import { checkListenable } from "../portUtils";
import { PackageManager, discoverPackageManager } from "./utils";
import { detectStartCommand } from "./utils";
import { DEFAULT_HOST, DEFAULT_PORTS } from "../constants";
import { spawnWithCommandString, wrapSpawn } from "../../init/spawn";
import { spawnWithCommandString } from "../../init/spawn";
import { logger } from "./utils";
import { Emulators } from "../types";
import { getLocalAppHostingConfiguration } from "./config";
import { FirebaseError } from "../../error";

interface StartOptions {
startCommand?: string;
Expand Down Expand Up @@ -61,21 +60,9 @@ async function serve(port: number, startCommand?: string): Promise<void> {
return;
}

let packageManager: PackageManager = "npm";
try {
packageManager = await discoverPackageManager(rootDir);
} catch (e) {
throw new FirebaseError(
"Failed to detect your project's package manager, consider manually setting the start command with the `startCommandOverride` config. ",
);
}

logger.logLabeled(
"BULLET",
Emulators.APPHOSTING,
`starting app with: '${packageManager} run dev'`,
);
await wrapSpawn(packageManager, ["run", "dev"], rootDir, environmentVariablesToInject);
const detectedStartCommand = await detectStartCommand(rootDir);
logger.logLabeled("BULLET", Emulators.APPHOSTING, `starting app with: '${detectStartCommand}`);

Check warning on line 64 in src/emulator/apphosting/serve.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Invalid type "(rootDir: string) => Promise<string>" of template literal expression
await spawnWithCommandString(detectedStartCommand, rootDir, environmentVariablesToInject);
}

function availablePort(host: string, port: number): Promise<boolean> {
Expand Down
15 changes: 14 additions & 1 deletion src/emulator/apphosting/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export type PackageManager = "npm" | "yarn" | "pnpm";
* @param rootdir project's root directory
* @returns PackageManager

Check warning on line 17 in src/emulator/apphosting/utils.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Invalid JSDoc tag (preference). Replace "returns" JSDoc tag with "return"
*/
export async function discoverPackageManager(rootdir: string): Promise<PackageManager> {
async function detectPackageManager(rootdir: string): Promise<PackageManager> {
if (await pathExists(join(rootdir, "pnpm-lock.yaml"))) {
return "pnpm";
}
Expand All @@ -31,3 +31,16 @@ export async function discoverPackageManager(rootdir: string): Promise<PackageMa

throw new FirebaseError("Unsupported package manager");
}

export async function detectStartCommand(rootDir: string) {

Check warning on line 35 in src/emulator/apphosting/utils.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Missing return type on function

Check warning on line 35 in src/emulator/apphosting/utils.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Missing JSDoc comment
let packageManager: PackageManager = "npm";
try {
packageManager = await detectPackageManager(rootDir);
} catch (e) {
throw new FirebaseError(
"Failed to detect your project's package manager, consider manually setting the start command with the `startCommandOverride` config. ",
);
}

return `${packageManager} run dev`;
}
82 changes: 32 additions & 50 deletions src/emulator/initEmulators.ts
Original file line number Diff line number Diff line change
@@ -1,69 +1,51 @@
// specific initialization steps for an emulator

import { promptOnce } from "../prompt";
import { detectStartCommand } from "./apphosting/utils";
import { EmulatorLogger } from "./emulatorLogger";
import { Emulators } from "./types";

export const AdditionalInitFns: {
[e in Emulators]: () => Promise<Record<string, string> | null>;
} = {
apphosting: async () => {
// Auto-detect package manager and set startCommandOverride
type InitFn = () => Promise<Record<string, string> | null>;
type AdditionalInitFnsType = Partial<Record<Emulators, InitFn>>;

export const AdditionalInitFns: AdditionalInitFnsType = {
[Emulators.APPHOSTING]: async () => {
const additionalConfigs = new Map<string, string>();
const logger = EmulatorLogger.forEmulator(Emulators.APPHOSTING);
logger.log("BULLET", "Initializing App Hosting Emulator");

// get root directory
const rootDirectory = await promptOnce({
name: "rootDir",
type: "input",
default: "./",
message: "Specify your app's root directory relative to your repository",
});
additionalConfigs.set("rootDirectory", rootDirectory);

// Auto-detect package manager and set startCommandOverride
// TODO: don't use cwd, instead try to find project root
const backendRoot = process.cwd();
try {
const startCommand = await detectStartCommand(backendRoot);
additionalConfigs.set("startCommandOverride", startCommand);
} catch (e) {
logger.log(
"WARN",
"failed to auto-detect your project's start command, consider manually setting the start command by setting the startCommandOverride config",
);
}

return {
rootDirectory,
};
// prompt for apphosting yaml to export
},
auth: async () => {
return null;
},
hub: async () => {
return null;
},
functions: async () => {
return null;
},
firestore: async () => {
return null;
},
database: async () => {
return null;
},
hosting: async () => {
return null;
},
pubsub: async () => {
return null;
},
ui: async () => {
return null;
},
logging: async () => {
return null;
},
storage: async () => {
return null;
},
extensions: async () => {
return null;
},
eventarc: async () => {
return null;
},
dataconnect: async () => {
return null;
},
tasks: async () => {
return null;

return mapToObject(additionalConfigs);
},
};

function mapToObject(map: Map<string, string>): Record<string, string> {
let newObject: Record<string, string> = {};

Check failure on line 46 in src/emulator/initEmulators.ts

View workflow job for this annotation

GitHub Actions / lint (20)

'newObject' is never reassigned. Use 'const' instead

Check failure on line 46 in src/emulator/initEmulators.ts

View workflow job for this annotation

GitHub Actions / unit (18)

'newObject' is never reassigned. Use 'const' instead

Check failure on line 46 in src/emulator/initEmulators.ts

View workflow job for this annotation

GitHub Actions / unit (18)

'newObject' is never reassigned. Use 'const' instead
for (let [key, value] of map) {

Check failure on line 47 in src/emulator/initEmulators.ts

View workflow job for this annotation

GitHub Actions / lint (20)

'key' is never reassigned. Use 'const' instead

Check failure on line 47 in src/emulator/initEmulators.ts

View workflow job for this annotation

GitHub Actions / lint (20)

'value' is never reassigned. Use 'const' instead

Check failure on line 47 in src/emulator/initEmulators.ts

View workflow job for this annotation

GitHub Actions / unit (18)

'key' is never reassigned. Use 'const' instead

Check failure on line 47 in src/emulator/initEmulators.ts

View workflow job for this annotation

GitHub Actions / unit (18)

'value' is never reassigned. Use 'const' instead

Check failure on line 47 in src/emulator/initEmulators.ts

View workflow job for this annotation

GitHub Actions / unit (18)

'key' is never reassigned. Use 'const' instead

Check failure on line 47 in src/emulator/initEmulators.ts

View workflow job for this annotation

GitHub Actions / unit (18)

'value' is never reassigned. Use 'const' instead
newObject[key] = value;
}
return newObject;
}
15 changes: 9 additions & 6 deletions src/init/features/emulators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,15 @@ export async function doSetup(setup: Setup, config: any) {
}

//TODO: Can add some logic here where each emulator can run their own inits

Check failure on line 58 in src/init/features/emulators.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Expected space or tab after '//' in comment

Check failure on line 58 in src/init/features/emulators.ts

View workflow job for this annotation

GitHub Actions / unit (18)

Expected space or tab after '//' in comment

Check failure on line 58 in src/init/features/emulators.ts

View workflow job for this annotation

GitHub Actions / unit (18)

Expected space or tab after '//' in comment
const additionalOptions = await AdditionalInitFns[selected]();
if (additionalOptions) {
setup.config.emulators[selected] = {
...setup.config.emulators[selected],
...additionalOptions,
};
const additionalInitFn = AdditionalInitFns[selected];
if (additionalInitFn) {
const additionalOptions = await additionalInitFn();
if (additionalOptions) {
setup.config.emulators[selected] = {
...setup.config.emulators[selected],
...additionalOptions,
};
}
}
}

Expand Down

0 comments on commit d61e180

Please sign in to comment.