Skip to content

Commit

Permalink
Revert "Hold back Functions refactor until after I/O" (#3384)
Browse files Browse the repository at this point in the history
* Revert "Revert "Refactor Functions deploy code to use types that aren't literal API structs (#3361)" (#3379)"

This reverts commit e438b26.

* Format fixes

* Fix bug with promptOnce in open command

Co-authored-by: Thomas Bouldin <[email protected]>
  • Loading branch information
joehan and inlined committed May 19, 2021
1 parent 92e1809 commit 33ff495
Show file tree
Hide file tree
Showing 48 changed files with 3,746 additions and 2,037 deletions.
2 changes: 2 additions & 0 deletions src/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,9 @@ var api = {
"FIREBASE_FUNCTIONS_V2_URL",
"https://cloudfunctions.googleapis.com"
),
runOrigin: utils.envOverride("CLOUD_RUN_URL", "https://run.googleapis.com"),
functionsUploadRegion: utils.envOverride("FIREBASE_FUNCTIONS_UPLOAD_REGION", "us-central1"),
functionsDefaultRegion: utils.envOverride("FIREBASE_FUNCTIONS_DEFAULT_REGION", "us-central1"),
cloudschedulerOrigin: utils.envOverride(
"FIREBASE_CLOUDSCHEDULER_URL",
"https://cloudscheduler.googleapis.com"
Expand Down
55 changes: 27 additions & 28 deletions src/commands/functions-delete.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { Command } from "../command";
import * as clc from "cli-color";
import * as cloudfunctions from "../gcp/cloudfunctions";
import * as functionsConfig from "../functionsConfig";
import { deleteFunctions } from "../functionsDelete";
import * as getProjectId from "../getProjectId";
import * as helper from "../functionsDeployHelper";
import { promptOnce } from "../prompt";
import * as helper from "../deploy/functions/functionsDeployHelper";
import { requirePermissions } from "../requirePermissions";
import * as utils from "../utils";
import * as args from "../deploy/functions/args";
import * as backend from "../deploy/functions/backend";

export default new Command("functions:delete [filters...]")
.description("delete one or more Cloud Functions by name or group name.")
Expand All @@ -18,50 +19,48 @@ export default new Command("functions:delete [filters...]")
)
.option("-f, --force", "No confirmation. Otherwise, a confirmation prompt will appear.")
.before(requirePermissions, ["cloudfunctions.functions.list", "cloudfunctions.functions.delete"])
.action(async (filters, options) => {
.action(async (filters: string[], options: { force: boolean; region?: string }) => {
if (!filters.length) {
return utils.reject("Must supply at least function or group name.");
}

const projectId = getProjectId(options);
const context = {
projectId: getProjectId(options),
} as args.Context;

// Dot notation can be used to indicate function inside of a group
const filterChunks = filters.map((filter: string) => {
return filter.split(".");
});
const config = await functionsConfig.getFirebaseConfig(options);
const [config, existingBackend] = await Promise.all([
functionsConfig.getFirebaseConfig(options),
backend.existingBackend(context),
]);
await backend.checkAvailability(context, /* want=*/ backend.empty());
const appEngineLocation = functionsConfig.getAppEngineLocation(config);
const res = await cloudfunctions.listAllFunctions(projectId);
if (res.unreachable) {
utils.logLabeledWarning(
"functions",
`Unable to reach the following Cloud Functions regions:\n${res.unreachable.join(
"\n"
)}\nCloud Functions in these regions will not be deleted.`
);
}
const functionsToDelete = res.functions.filter((fn) => {
const regionMatches = options.region ? helper.getRegion(fn.name) === options.region : true;
const nameMatches = helper.functionMatchesAnyGroup(fn.name, filterChunks);

const functionsToDelete = existingBackend.cloudFunctions.filter((fn) => {
const regionMatches = options.region ? fn.region === options.region : true;
const nameMatches = helper.functionMatchesAnyGroup(fn, filterChunks);
return regionMatches && nameMatches;
});
if (functionsToDelete.length === 0) {
return utils.reject(
`The specified filters do not match any existing functions in project ${clc.bold(
projectId
context.projectId
)}.`,
{ exit: 1 }
);
}

const scheduledFnNamesToDelete = functionsToDelete
.filter((fn) => {
return fn.labels?.["deployment-scheduled"] === "true";
})
.map((fn) => fn.name);
const fnNamesToDelete = functionsToDelete.map((fn) => fn.name);
const schedulesToDelete = existingBackend.schedules.filter((schedule) => {
functionsToDelete.some(backend.sameFunctionName(schedule.targetService));
});
const topicsToDelete = existingBackend.topics.filter((topic) => {
functionsToDelete.some(backend.sameFunctionName(topic.targetService));
});

const deleteList = fnNamesToDelete
const deleteList = functionsToDelete
.map((func) => {
return "\t" + helper.getFunctionLabel(func);
})
Expand All @@ -82,9 +81,9 @@ export default new Command("functions:delete [filters...]")
return utils.reject("Command aborted.", { exit: 1 });
}
return await deleteFunctions(
fnNamesToDelete,
scheduledFnNamesToDelete,
projectId,
functionsToDelete,
schedulesToDelete,
topicsToDelete,
appEngineLocation
);
});
26 changes: 10 additions & 16 deletions src/commands/hosting-channel-create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,23 +38,17 @@ export default new Command("hosting:channel:create [channelId]")
expireTTL = calculateChannelExpireTTL(options.expires);
}

if (!channelId) {
if (options.nonInteractive) {
throw new FirebaseError(
`"channelId" argument must be provided in a non-interactive environment`
);
}
channelId = await promptOnce(
{
type: "input",
message: "Please provide a URL-friendly name for the channel:",
validate: (s) => s.length > 0,
} // Prevents an empty string from being submitted!
);
}
if (!channelId) {
throw new FirebaseError(`"channelId" must not be empty`);
if (channelId) {
options.channelId = channelId;
}
channelId = await promptOnce(
{
type: "input",
message: "Please provide a URL-friendly name for the channel:",
validate: (s) => s.length > 0,
},
options
);

channelId = normalizeName(channelId);

Expand Down
31 changes: 11 additions & 20 deletions src/deploy/functions/args.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
// These types should proably be in a root deploy.ts, but we can only boil the ocean one bit at a time.

import { ReadStream } from "fs";
import * as gcf from "../../gcp/cloudfunctions";
import * as deploymentPlanner from "./deploymentPlanner";

import * as backend from "./backend";
import * as gcfV2 from "../../gcp/cloudfunctionsv2";

// These types should proably be in a root deploy.ts, but we can only boil the ocean one bit at a time.

// Payload holds the output types of what we're building.
export interface Payload {
functions?: {
byRegion: deploymentPlanner.RegionMap;
triggers: deploymentPlanner.CloudFunctionTrigger[];
backend: backend.Backend;
};
}

Expand All @@ -26,8 +26,8 @@ export interface Options {
config: {
// Note: it might be worth defining overloads for config values we use in
// deploy/functions.
get(key: string, defaultValue?: any): any;
set(key: string, value: any): void;
get(key: string, defaultValue?: unknown): unknown;
set(key: string, value: unknown): void;
has(key: string): boolean;
path(pathName: string): string;

Expand All @@ -44,12 +44,6 @@ export interface Options {
force: boolean;
}

export interface FunctionsSource {
file: string;
stream: ReadStream;
size: number;
}

// Context holds cached values of what we've looked up in handling this request.
// For non-trivial values, use helper functions that cache automatically and/or hide implementation
// details.
Expand All @@ -58,17 +52,14 @@ export interface Context {
filters: string[][];

// Filled in the "prepare" phase.
functionsSource?: FunctionsSource;
// TODO: replace with backend.Runtime once it is committed.
runtimeChoice?: gcf.Runtime;
functionsSource?: string;
runtimeChoice?: backend.Runtime;
runtimeConfigEnabled?: boolean;
firebaseConfig?: FirebaseConfig;

// Filled in the "deploy" phase.
uploadUrl?: string;

// TOOD: move to caching function w/ helper
existingFunctions?: gcf.CloudFunction[];
storageSource?: gcfV2.StorageSource;
}

export interface FirebaseConfig {
Expand Down

0 comments on commit 33ff495

Please sign in to comment.