Skip to content

Commit

Permalink
Add fauna schema pull --active (#392)
Browse files Browse the repository at this point in the history
* Update pull to send the correct requests to core when pulling a staged schema

* Add `--active` flag to pull

* Fix tests
  • Loading branch information
macmv authored Oct 14, 2024
1 parent 6c23ae3 commit 1f71602
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 65 deletions.
51 changes: 26 additions & 25 deletions src/commands/schema/pull.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ export default class PullSchemaCommand extends SchemaCommand {
"Delete .fsl files in the target directory that are not part of the database schema",
default: false,
}),
staged: Flags.boolean({
description: "Pulls staged schema instead of the active schema",
active: Flags.boolean({
description: "Pulls the active schema instead of the staged schema.",
default: false,
}),
};
Expand All @@ -27,36 +27,30 @@ export default class PullSchemaCommand extends SchemaCommand {
const { url, secret } = await this.fetchsetup();

try {
// Gather remote schema files to download.
const filesres = await fetch(new URL("/schema/1/files", url), {
// Check if there's a staged schema, and require `--staged` if there is one.
const statusres = await fetch(new URL(`/schema/1/staged/status`, url), {
method: "GET",
headers: { AUTHORIZATION: `Bearer ${secret}` },
});
const filesjson = await filesres.json();
if (filesjson.error) {
this.error(filesjson.error.message);
}

// Check if there's a staged schema, and require `--staged` if there is one.
const params = new URLSearchParams({
version: filesjson.version,
});
const statusres = await fetch(
new URL(`/schema/1/staged/status?${params}`, url),
{
method: "GET",
headers: { AUTHORIZATION: `Bearer ${secret}` },
}
);
const statusjson = await statusres.json();
if (statusjson.error) {
this.error(statusjson.error.message);
}

if (statusjson.status !== "none" && !this.flags?.staged) {
this.error("There is a staged schema change. Use --staged to pull it.");
} else if (statusjson.status === "none" && this.flags?.staged) {
this.error("There are no staged schema changes to pull.");
let isStagedPull = statusjson.status !== "none" && !this.flags?.active;

// Gather remote schema files to download.
const params = new URLSearchParams({
version: statusjson.version,
staged: isStagedPull ? "true" : "false",
});
const filesres = await fetch(new URL(`/schema/1/files?${params}`, url), {
method: "GET",
headers: { AUTHORIZATION: `Bearer ${secret}` },
});
const filesjson = await filesres.json();
if (filesjson.error) {
this.error(filesjson.error.message);
}

// Sort for consistent order. It's nice for tests.
Expand Down Expand Up @@ -112,8 +106,15 @@ export default class PullSchemaCommand extends SchemaCommand {
}

for (const filename of filenames) {
const params = new URLSearchParams({
version: statusjson.version,
staged: isStagedPull ? "true" : "false",
});
const fileres = await fetch(
new URL(`/schema/1/files/${encodeURIComponent(filename)}`, url),
new URL(
`/schema/1/files/${encodeURIComponent(filename)}?${params}`,
url
),
{
method: "GET",
headers: { AUTHORIZATION: `Bearer ${secret}` },
Expand Down
85 changes: 45 additions & 40 deletions test/commands/schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -330,15 +330,15 @@ describe(`fauna schema pull`, () => {
.persist()
.post("/", matchFqlReq(query.Now()))
.reply(200, new Date())
.get("/schema/1/files")
.get("/schema/1/staged/status")
.reply(200, { status: "none", version: 0 })
.get("/schema/1/files?version=0&staged=false")
.reply(200, pullfiles)
.get("/schema/1/staged/status?version=0")
.reply(200, { status: "none" })
.get("/schema/1/files/functions.fsl")
.get("/schema/1/files/functions.fsl?version=0&staged=false")
.reply(200, functions)
.get("/schema/1/files/main.fsl")
.get("/schema/1/files/main.fsl?version=0&staged=false")
.reply(200, main)
.get("/schema/1/files/roles%2Fmyrole.fsl")
.get("/schema/1/files/roles%2Fmyrole.fsl?version=0&staged=false")
.reply(200, myrole);

// Running the command with options
Expand Down Expand Up @@ -384,71 +384,76 @@ describe(`fauna schema pull`, () => {
});
}

it(`requires --staged when there's a staged schema`, async () => {
it(`runs schema pull with a staged schema`, async () => {
const stubConfirm = sinon.stub(inquirer, "confirm").resolves(true);

nock(getEndpoint(), { allowUnmocked: false })
.persist()
.post("/", matchFqlReq(query.Now()))
.reply(200, new Date())
.get("/schema/1/files")
.get("/schema/1/staged/status")
.reply(200, { status: "ready", version: 0 })
.get("/schema/1/files?version=0&staged=true")
.reply(200, pullfiles)
.get("/schema/1/staged/status?version=0")
.reply(200, { status: "ready" });
.get("/schema/1/staged/status?version=0&staged=true")
.reply(200, { status: "ready" })
.get("/schema/1/files/functions.fsl?version=0&staged=true")
.reply(200, functions)
.get("/schema/1/files/main.fsl?version=0&staged=true")
.reply(200, main)
.get("/schema/1/files/roles%2Fmyrole.fsl?version=0&staged=true")
.reply(200, myrole);

const { error } = await runCommand(
// This should work as normal.
const { stdout } = await runCommand(
withOpts(["schema pull", `--dir=${testdir}`])
);
expect(error?.message).to.equal(
"There is a staged schema change. Use --staged to pull it."
expect(stdout).to.contain("Pull makes the following changes:");
expect(
fs.readFileSync(path.join(testdir, "functions.fsl"), "utf8")
).to.equal(functions.content);
expect(fs.readFileSync(path.join(testdir, "main.fsl"), "utf8")).to.equal(
main.content
);

stubConfirm.restore();
});

it(`disallows --staged when there's no staged schema`, async () => {
const stubConfirm = sinon.stub(inquirer, "confirm").resolves(true);

nock(getEndpoint(), { allowUnmocked: false })
.persist()
.post("/", matchFqlReq(query.Now()))
.reply(200, new Date())
.get("/schema/1/files")
.reply(200, pullfiles)
.get("/schema/1/staged/status?version=0")
.reply(200, { status: "none" });

const { error } = await runCommand(
withOpts(["schema pull", `--dir=${testdir}`, `--staged`])
expect(
fs.readFileSync(path.join(testdir, "roles", "myrole.fsl"), "utf8")
).to.equal(myrole.content);
expect(fs.statSync(path.join(testdir, "no.fsl")).isDirectory()).to.equal(
true
);
expect(error?.message).to.equal(
"There are no staged schema changes to pull."
expect(fs.statSync(path.join(testdir, "nofsl")).isDirectory()).to.equal(
true
);
expect(fs.statSync(path.join(testdir, "main.notfsl")).isFile()).to.equal(
true
);

stubConfirm.restore();
});

it(`runs schema pull --staged`, async () => {
it(`runs schema pull --active with a staged schema`, async () => {
const stubConfirm = sinon.stub(inquirer, "confirm").resolves(true);

nock(getEndpoint(), { allowUnmocked: false })
.persist()
.post("/", matchFqlReq(query.Now()))
.reply(200, new Date())
.get("/schema/1/files")
.get("/schema/1/staged/status")
.reply(200, { status: "ready", version: 0 })
.get("/schema/1/files?version=0&staged=false")
.reply(200, pullfiles)
.get("/schema/1/staged/status?version=0")
.get("/schema/1/staged/status?version=0&staged=false")
.reply(200, { status: "ready" })
.get("/schema/1/files/functions.fsl")
.get("/schema/1/files/functions.fsl?version=0&staged=false")
.reply(200, functions)
.get("/schema/1/files/main.fsl")
.get("/schema/1/files/main.fsl?version=0&staged=false")
.reply(200, main)
.get("/schema/1/files/roles%2Fmyrole.fsl")
.get("/schema/1/files/roles%2Fmyrole.fsl?version=0&staged=false")
.reply(200, myrole);

// This should work as normal.
const { stdout } = await runCommand(
withOpts(["schema pull", `--dir=${testdir}`, `--staged`])
withOpts(["schema pull", `--dir=${testdir}`, `--active`])
);
expect(stdout).to.contain("Pull makes the following changes:");
expect(
Expand Down

0 comments on commit 1f71602

Please sign in to comment.