Skip to content

Commit

Permalink
catch schema commands up to main branch
Browse files Browse the repository at this point in the history
this implements changes in the flags for all schema commands as well
large changes in functionality for `schema diff` and `schema status`.
  • Loading branch information
echo-bravo-yahoo committed Oct 29, 2024
1 parent d8e148c commit 3199c26
Show file tree
Hide file tree
Showing 15 changed files with 546 additions and 143 deletions.
2 changes: 1 addition & 1 deletion src/commands/schema/abandon.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ function buildAbandonCommand(yargs) {
input: {
description: "Prompt for user input (e.g., confirmations)",
default: true,
type: "boolean"
type: "boolean",
},
...commonQueryOptions,
})
Expand Down
2 changes: 1 addition & 1 deletion src/commands/schema/commit.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ function buildCommitCommand(yargs) {
input: {
description: "Prompt for user input (e.g., confirmations)",
default: true,
type: "boolean"
type: "boolean",
},
...commonQueryOptions,
})
Expand Down
109 changes: 93 additions & 16 deletions src/commands/schema/diff.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,124 @@ import { container } from "../../cli.mjs";
import { commonQueryOptions } from "../../lib/command-helpers.mjs";
import { reformatFSL } from "../../lib/schema.mjs";

/**
* @returns string[]
*/
function parseTarget(argv) {
if (!argv.active && !argv.staged) {
return ["staged", "local"];
}

if (argv.active && argv.staged) {
throw new Error("Cannot specify both --active and --staged");
}

if (argv.active) {
return ["active", "local"];
} else if (argv.staged) {
return ["active", "staged"];
} else {
throw new Error("Invalid target. Expected: active or staged");
}
}

async function doDiff(argv) {
const [source, target] = parseTarget(argv);
const diffKind = argv.text ? "textual" : "semantic";

const gatherFSL = container.resolve("gatherFSL");
const logger = container.resolve("logger");
const makeFaunaRequest = container.resolve("makeFaunaRequest");

const files = reformatFSL(await gatherFSL(argv.dir));

const params = new URLSearchParams({ force: "true" });
const params = new URLSearchParams({});
if (argv.color) params.set("color", "ansi");
params.set("staged", argv.staged);
if (target === "staged") params.set("diff", diffKind);

const response = await makeFaunaRequest({
const { version, status, diff } = await makeFaunaRequest({
baseUrl: argv.url,
path: new URL(`/schema/1/validate?${params}`, argv.url).href,
path: "/schema/1/staged/status",
params,
secret: argv.secret,
body: files,
method: "POST",
method: "GET",
});

const bold = argv.color ? chalk.bold : (str) => str;
const description = argv.staged ? "remote, staged" : "remote, active";
logger.stdout(
`Differences between the ${bold("local")} schema and the ${bold(
description,
)} schema:`,
);
logger.stdout(response.diff ? response.diff : "No schema differences");
if (target === "staged") {
logger.stdout(
`Differences from the ${chalk.bold("remote, active")} schema to the ${chalk.bold("remote, staged")} schema:`,
);
if (status === "none") {
logger.stdout("There is no staged schema present.");
} else {
logger.stdout(diff ? diff : "No schema differences.");
}
} else {
const params = new URLSearchParams({
diff: diffKind,
staged: String(source === "staged"),
});
if (argv.color) params.set("color", "ansi");
if (version) {
params.set("version", version);
} else {
params.set("force", "true");
}

const { diff } = await makeFaunaRequest({
baseUrl: argv.url,
path: "/schema/1/validate",
params,
secret: argv.secret,
body: files,
method: "POST",
});

if (status === "none") {
logger.stdout(
`Differences from the ${chalk.bold("remote")} schema to the ${chalk.bold("local")} schema:`,
);
} else if (source === "active") {
logger.stdout(
`Differences from the ${chalk.bold("remote, active")} schema to the ${chalk.bold("local")} schema:`,
);
} else {
logger.stdout(
`Differences from the ${chalk.bold("remote, staged")} schema to the ${chalk.bold("local")} schema:`,
);
}
logger.stdout(diff ? diff : "No schema differences.");
}
}

function buildDiffCommand(yargs) {
return yargs
.options({
staged: {
description:
"Compare the local schema to the staged schema instead of the active schema.",
"Show the diff between the active and staged schema, instead of the local schema.",
default: false,
type: "boolean",
},
text: {
description: "Display the text diff instead of the semantic diff.",
default: false,
type: "boolean",
},
active: {
description:
"Show the diff against the active schema instead of the staged schema.",
default: false,
type: "boolean",
},
...commonQueryOptions,
})
.example([["$0 schema diff"], ["$0 schema diff --dir schemas/myschema"]])
.example([
["$0 schema diff"],
["$0 schema diff --dir schemas/myschema"],
["$0 schema diff --staged"],
["$0 schema diff --active --text"],
])
.version(false)
.help("help", "show help");
}
Expand Down
31 changes: 17 additions & 14 deletions src/commands/schema/pull.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,38 @@

import { container } from "../../cli.mjs";
import { commonQueryOptions } from "../../lib/command-helpers.mjs";
import { makeFaunaRequest } from "../../lib/db.mjs";

async function doPull(argv) {
const logger = container.resolve("logger");
const gatherFSL = container.resolve("gatherFSL");
const confirm = container.resolve("confirm");
const getSchemaFiles = container.resolve("getSchemaFiles");
const getStagedSchemaStatus = container.resolve("getStagedSchemaStatus");

// fetch the list of remote FSL files
const filesResponse = await getSchemaFiles({
secret: argv.secret,
const filesResponse = await makeFaunaRequest({
baseUrl: argv.url,
path: "/schema/1/files",
method: "GET",
secret: argv.secret,
});

// check if there's a staged schema
const statusResponse = await getStagedSchemaStatus({
params: { version: filesResponse.version },
const statusResponse = await makeFaunaRequest({
baseUrl: argv.url,
path: "/schema/1/staged/status",
params: new URLSearchParams({ version: filesResponse.version }),
method: "GET",
secret: argv.secret,
});

// if there's a staged schema, require the --staged flag.
// getting unstaged FSL while staged FSL exists is not yet
// if there's a staged schema, cannot use the --active flag.
// getting active FSL while staged FSL exists is not yet
// implemented at the service level.
if (statusResponse.status !== "none" && !argv.staged) {
if (statusResponse.status !== "none" && argv.active) {
throw new Error(
"There is a staged schema change. Use --staged to pull it.",
"There is a staged schema change. Remove the --active flag to pull it.",
);
} else if (statusResponse.status === "none" && argv.staged) {
} else if (statusResponse.status === "none" && !argv.active) {
throw new Error("There are no staged schema changes to pull.");
}

Expand Down Expand Up @@ -117,16 +120,16 @@ function buildPullCommand(yargs) {
type: "boolean",
default: false,
},
staged: {
description: "Pulls staged schema instead of the active schema",
active: {
description: "Pulls the active schema instead of the staged schema",
type: "boolean",
default: false,
},
...commonQueryOptions,
})
.example([
["$0 schema pull"],
["$0 schema pull --staged"],
["$0 schema pull --active"],
["$0 schema pull --delete"],
])
.version(false)
Expand Down
21 changes: 12 additions & 9 deletions src/commands/schema/push.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ async function doPush(argv) {
if (!argv.input) {
const params = new URLSearchParams({
force: "true",
staged: argv.staged ? "true" : "false",
staged: argv.active ? "false" : "true",
});

await makeFaunaRequest({
baseUrl: argv.url,
path: `/schema/1/update?${params}`,
path: "/schema/1/update",
params,
body: fsl,
secret: argv.secret,
method: "POST",
Expand All @@ -29,13 +30,14 @@ async function doPush(argv) {
// need to pass the last known schema version through.
const params = new URLSearchParams({
force: "true",
staged: argv.staged ? "true" : "false",
staged: argv.active ? "false" : "true",
});
if (argv.color) params.set("color", "ansi");

const response = await makeFaunaRequest({
baseUrl: argv.url,
path: `/schema/1/validate?${params}`,
path: "/schema/1/validate",
params,
body: fsl,
secret: argv.secret,
method: "POST",
Expand All @@ -58,12 +60,13 @@ async function doPush(argv) {
if (confirmed) {
const params = new URLSearchParams({
version: response.version,
staged: argv.staged ? "true" : "false",
staged: argv.active ? "false" : "true",
});

await makeFaunaRequest({
baseUrl: argv.url,
path: `/schema/1/update?${params}`,
path: "/schema/1/update",
params,
body: fsl,
secret: argv.secret,
method: "POST",
Expand All @@ -80,9 +83,9 @@ function buildPushCommand(yargs) {
input: {
description: "Prompt for user input (e.g., confirmations)",
default: true,
type: "boolean"
type: "boolean",
},
staged: {
active: {
description:
"Stages the schema change instead of applying it immediately",
type: "boolean",
Expand All @@ -93,7 +96,7 @@ function buildPushCommand(yargs) {
.example([
["$0 schema push"],
["$0 schema push --dir schemas/myschema"],
["$0 schema push --staged"],
["$0 schema push --active"],
])
.version(false)
.help("help", "show help");
Expand Down
47 changes: 43 additions & 4 deletions src/commands/schema/status.mjs
Original file line number Diff line number Diff line change
@@ -1,23 +1,62 @@
//@ts-check

import chalk from "chalk";

import { container } from "../../cli.mjs";
import { commonQueryOptions } from "../../lib/command-helpers.mjs";
import { reformatFSL } from "../../lib/schema.mjs";

async function doStatus(argv) {
const logger = container.resolve("logger");
const makeFaunaRequest = container.resolve("makeFaunaRequest");

const params = new URLSearchParams({ diff: "true" });
let params = new URLSearchParams({ diff: "summary" });
if (argv.color) params.set("color", "ansi");
const gatherFSL = container.resolve("gatherFSL");
const fsl = reformatFSL(await gatherFSL(argv.dir));

const response = await makeFaunaRequest({
const statusResponse = await makeFaunaRequest({
baseUrl: argv.url,
path: `/schema/1/staged/status?${params}`,
path: "/schema/1/staged/status",
params,
secret: argv.secret,
method: "GET",
});

logger.stdout(response.diff);
params = new URLSearchParams({
diff: "summary",
staged: "true",
version: statusResponse.version,
});
const validationResponse = await makeFaunaRequest({
baseUrl: argv.url,
path: "/schema/1/validate",
params,
secret: argv.secret,
method: "POST",
body: fsl,
});

logger.stdout(`Staged changes: ${chalk.bold(statusResponse.status)}`);
if (statusResponse.pending_summary !== "") {
logger.stdout(statusResponse.pending_summary);
}
if (statusResponse.diff) {
logger.stdout("Staged changes:\n");
logger.stdout(statusResponse.diff.split("\n").join("\n "));
}

if (validationResponse.error) {
logger.stdout(`Local changes:`);
throw new Error(validationResponse.error.message);
} else if (validationResponse.diff === "") {
logger.stdout(`Local changes: ${chalk.bold("none")}\n`);
} else {
logger.stdout(`Local changes:\n`);
logger.stdout(` ${validationResponse.diff.split("\n").join("\n ")}`);
logger.stdout("(use `fauna schema diff` to display local changes)");
logger.stdout("(use `fauna schema push` to stage local changes)");
}
}

function buildStatusCommand(yargs) {
Expand Down
Loading

0 comments on commit 3199c26

Please sign in to comment.