From 69a1217d8436cdb0e32d45951c9d7e744fdf8ecf Mon Sep 17 00:00:00 2001 From: henryfauna <90654917+henryfauna@users.noreply.github.com> Date: Wed, 11 Dec 2024 09:23:19 -0800 Subject: [PATCH] Handle No Local Schema Files (#505) * handle no local schema on * appease linter * address comments * fix tests * Update test/schema/status.mjs Co-authored-by: James Rodewig --------- Co-authored-by: James Rodewig --- src/commands/schema/status.mjs | 69 +++++++++++++++++----------- test/schema/status.mjs | 82 ++++++++++++++++++++++++++++------ 2 files changed, 111 insertions(+), 40 deletions(-) diff --git a/src/commands/schema/status.mjs b/src/commands/schema/status.mjs index 3c1cd970..ad166883 100644 --- a/src/commands/schema/status.mjs +++ b/src/commands/schema/status.mjs @@ -1,6 +1,7 @@ //@ts-check import chalk from "chalk"; +import path from "path"; import { container } from "../../cli.mjs"; import { @@ -15,34 +16,40 @@ async function doStatus(argv) { const logger = container.resolve("logger"); const makeFaunaRequest = container.resolve("makeFaunaRequest"); - let params = new URLSearchParams({ diff: "summary" }); const secret = await getSecret(); + const absoluteDirPath = path.resolve(argv.dir); const gatherFSL = container.resolve("gatherFSL"); - const fsl = reformatFSL(await gatherFSL(argv.dir)); + const fslFiles = await gatherFSL(argv.dir); + const hasLocalSchema = fslFiles.length > 0; + const fsl = reformatFSL(fslFiles); + const statusParams = new URLSearchParams({ format: "summary" }); const statusResponse = await makeFaunaRequest({ argv, path: "/schema/1/staged/status", - params, + params: statusParams, method: "GET", secret, }); - params = new URLSearchParams({ - diff: "summary", - staged: "true", - version: statusResponse.version, - }); - - const validationResponse = await makeFaunaRequest({ - argv, - path: "/schema/1/diff", - params, - method: "POST", - body: fsl, - secret, - }); + let diffResponse = null; + if (hasLocalSchema) { + const diffParams = new URLSearchParams({ + staged: "true", + format: "summary", + version: statusResponse.version, + }); + diffResponse = await makeFaunaRequest({ + argv, + path: "/schema/1/diff", + params: diffParams, + method: "POST", + body: fsl, + secret, + }); + } + // Output the status response logger.stdout(`Staged changes: ${chalk.bold(statusResponse.status)}`); if (statusResponse.pending_summary !== "") { logger.stdout(statusResponse.pending_summary); @@ -52,17 +59,27 @@ async function doStatus(argv) { logger.stdout(statusResponse.diff.split("\n").join("\n ")); } - if (validationResponse.error) { - logger.stdout(`Local changes:`); - throw new CommandError(validationResponse.error.message); - } else if (validationResponse.diff === "") { + // Output the diff response + if (!hasLocalSchema) { + logger.stdout( + `Local changes: ${chalk.bold(`no schema files found in '${absoluteDirPath}'`)}\n`, + ); + return; + } + + if (diffResponse.error) { + throw new CommandError(diffResponse.error.message); + } + + if (diffResponse.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)"); + return; } + + logger.stdout(`Local changes:\n`); + logger.stdout(` ${diffResponse.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) { diff --git a/test/schema/status.mjs b/test/schema/status.mjs index fbee9d1f..d3912923 100644 --- a/test/schema/status.mjs +++ b/test/schema/status.mjs @@ -2,13 +2,22 @@ import { expect } from "chai"; import chalk from "chalk"; +import sinon from "sinon"; import { run } from "../../src/cli.mjs"; import { setupTestContainer as setupContainer } from "../../src/config/setup-test-container.mjs"; +import { reformatFSL } from "../../src/lib/schema.mjs"; import { buildUrl, commonFetchParams, f } from "../helpers.mjs"; describe("schema status", function () { - let container, fetch, logger; + let container, fetch, logger, gatherFSL; + + let fsl = [ + { + name: "collections.fsl", + content: "collection Customer {\n name: String\n email: String\n}\n", + }, + ]; let summaryDiff = "\x1B[1;34m* Adding collection `NewCollection`\x1B[0m to collections.fsl:2:1\n" + @@ -66,9 +75,51 @@ describe("schema status", function () { container = setupContainer(); fetch = container.resolve("fetch"); logger = container.resolve("logger"); + gatherFSL = container.resolve("gatherFSL"); + }); + + it("notifies the user when no local schema is found", async function () { + gatherFSL.resolves([]); + fetch.onCall(0).resolves( + f({ + version: 0, + status: "none", + diff: "Staged schema: none", + pending_summary: "", + }), + ); + fetch.onCall(1).resolves( + f({ + version: 0, + diff: "", + }), + ); + + await run(`schema status --secret "secret"`, container); + + expect(fetch).to.have.been.calledWith( + buildUrl("/schema/1/staged/status", { format: "summary", color: "ansi" }), + commonFetchParams, + ); + expect(fetch).not.to.have.been.calledWith( + buildUrl("/schema/1/validate", { + format: "summary", + staged: "true", + version: "0", + color: "ansi", + }), + { ...commonFetchParams, method: "POST", body: new FormData() }, + ); + expect(logger.stdout).to.have.been.calledWith( + `Staged changes: ${chalk.bold("none")}`, + ); + expect(logger.stdout).to.have.been.calledWith( + sinon.match(/^Local changes: .*no schema files found in.*\n$/), + ); }); it("fetches the current status when there are no changes", async function () { + gatherFSL.resolves(fsl); fetch.onCall(0).resolves( f({ version: 0, @@ -88,17 +139,17 @@ describe("schema status", function () { await run(`schema status --secret "secret"`, container); expect(fetch).to.have.been.calledWith( - buildUrl("/schema/1/staged/status", { diff: "summary", color: "ansi" }), + buildUrl("/schema/1/staged/status", { format: "summary", color: "ansi" }), commonFetchParams, ); expect(fetch).to.have.been.calledWith( buildUrl("/schema/1/diff", { - diff: "summary", + format: "summary", staged: "true", version: "0", color: "ansi", }), - { ...commonFetchParams, method: "POST", body: new FormData() }, + { ...commonFetchParams, method: "POST", body: reformatFSL(fsl) }, ); expect(logger.stdout).to.have.been.calledWith( `Staged changes: ${chalk.bold("none")}`, @@ -109,6 +160,7 @@ describe("schema status", function () { }); it("fetches the current status when there are only local changes", async function () { + gatherFSL.resolves(fsl); fetch.onCall(0).resolves( f({ version: 0, @@ -131,17 +183,17 @@ describe("schema status", function () { await run(`schema status --secret "secret"`, container); expect(fetch).to.have.been.calledWith( - buildUrl("/schema/1/staged/status", { diff: "summary", color: "ansi" }), + buildUrl("/schema/1/staged/status", { format: "summary", color: "ansi" }), commonFetchParams, ); expect(fetch).to.have.been.calledWith( buildUrl("/schema/1/diff", { - diff: "summary", + format: "summary", staged: "true", version: "0", color: "ansi", }), - { ...commonFetchParams, method: "POST", body: new FormData() }, + { ...commonFetchParams, method: "POST", body: reformatFSL(fsl) }, ); expect(logger.stdout).to.have.been.calledWith( `Staged changes: ${chalk.bold("none")}`, @@ -160,6 +212,7 @@ describe("schema status", function () { }); it("fetches the current status when there are only staged changes", async function () { + gatherFSL.resolves(fsl); fetch.onCall(0).resolves( f({ version: 0, @@ -179,18 +232,18 @@ describe("schema status", function () { await run(`schema status --secret "secret"`, container); expect(fetch).to.have.been.calledWith( - buildUrl("/schema/1/staged/status", { diff: "summary", color: "ansi" }), + buildUrl("/schema/1/staged/status", { format: "summary", color: "ansi" }), commonFetchParams, ); expect(fetch).to.have.been.calledWith( buildUrl("/schema/1/diff", { - diff: "summary", + format: "summary", staged: "true", version: "0", color: "ansi", }), - { ...commonFetchParams, method: "POST", body: new FormData() }, + { ...commonFetchParams, method: "POST", body: reformatFSL(fsl) }, ); expect(logger.stdout).to.have.been.calledWith( `Staged changes: ${chalk.bold("ready")}`, @@ -205,6 +258,7 @@ describe("schema status", function () { }); it("fetches the current status when there are both local and staged changes", async function () { + gatherFSL.resolves(fsl); fetch.onCall(0).resolves( f({ version: 0, @@ -226,17 +280,17 @@ describe("schema status", function () { await run(`schema status --secret "secret"`, container); expect(fetch).to.have.been.calledWith( - buildUrl("/schema/1/staged/status", { diff: "summary", color: "ansi" }), + buildUrl("/schema/1/staged/status", { format: "summary", color: "ansi" }), commonFetchParams, ); expect(fetch).to.have.been.calledWith( buildUrl("/schema/1/diff", { - diff: "summary", + format: "summary", staged: "true", version: "0", color: "ansi", }), - { ...commonFetchParams, method: "POST", body: new FormData() }, + { ...commonFetchParams, method: "POST", body: reformatFSL(fsl) }, ); expect(logger.stdout).to.have.been.calledWith( `Staged changes: ${chalk.bold("ready")}`, @@ -270,7 +324,7 @@ describe("schema status", function () { await run(`schema status --no-color --secret "secret"`, container); expect(fetch).to.have.been.calledWith( - buildUrl("/schema/1/staged/status", { diff: "summary" }), + buildUrl("/schema/1/staged/status", { format: "summary" }), commonFetchParams, ); expect(logger.stderr).not.to.have.been.called;