Skip to content

Commit

Permalink
Use project config in schema commands (#253)
Browse files Browse the repository at this point in the history
* Add gitignore for test output

* Use project config path as a fallacbk from --dir
  • Loading branch information
macmv authored Sep 27, 2023
1 parent 34ab4d9 commit 8ded068
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 45 deletions.
11 changes: 2 additions & 9 deletions src/commands/schema/diff.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,14 @@
const SchemaCommand = require("../../lib/schema-command.js").default;
const fetch = require("node-fetch");
const { Flags } = require("@oclif/core");

class DiffSchemaCommand extends SchemaCommand {
static flags = {
...SchemaCommand.flags,
// NB: Required as a flag because it will become optional eventually,
// once project configuration is implemented.
dir: Flags.string({
required: true,
description: "The directory of .fsl files to push",
}),
};

async run() {
const fps = this.gather(this.flags.dir);
const files = this.read(this.flags.dir, fps);
const fps = this.gather();
const files = this.read(fps);
try {
const { urlbase, secret } = await this.fetchsetup();
const res = await fetch(`${urlbase}/schema/1/validate?force=true`, {
Expand Down
16 changes: 4 additions & 12 deletions src/commands/schema/pull.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,6 @@ class PullSchemaCommand extends SchemaCommand {
"Delete .fsl files in the target directory that are not part of the database schema",
default: false,
}),
// NB: Required as a flag because it will become optional eventually,
// once project configuration is implemented.
dir: Flags.string({
required: true,
description: "The target directory",
}),
};

async confirm() {
Expand All @@ -37,8 +31,6 @@ class PullSchemaCommand extends SchemaCommand {
async run() {
const { urlbase, secret } = await this.fetchsetup();

const dir = this.flags.dir;

try {
// Gather remote schema files to download.
const filesres = await fetch(`${urlbase}/schema/1/files`, {
Expand All @@ -56,7 +48,7 @@ class PullSchemaCommand extends SchemaCommand {
.sort();

// Gather local .fsl files to overwrite or delete.
const existing = this.gather(dir);
const existing = this.gather();

// Summarize file changes.
const adds = [];
Expand Down Expand Up @@ -92,7 +84,7 @@ class PullSchemaCommand extends SchemaCommand {
if (this.flags.delete) {
// Delete extra .fsl files.
for (const deleteme of deletes) {
fs.unlinkSync(path.join(dir, deleteme));
fs.unlinkSync(path.join(this.dir, deleteme));
}
}

Expand All @@ -106,7 +98,7 @@ class PullSchemaCommand extends SchemaCommand {
if (filejson.error) {
this.error(filejson.error.message);
}
const fp = path.join(dir, filename);
const fp = path.join(this.dir, filename);
fs.mkdirSync(path.dirname(fp), { recursive: true });
fs.writeFileSync(fp, filejson.content);
}
Expand All @@ -122,6 +114,6 @@ class PullSchemaCommand extends SchemaCommand {
PullSchemaCommand.description =
"Pull a database schema's .fsl files into a directory";

PullSchemaCommand.examples = ["$ fauna schema pull --dir schemas/myschema"];
PullSchemaCommand.examples = ["$ fauna schema pull"];

module.exports = PullSchemaCommand;
10 changes: 2 additions & 8 deletions src/commands/schema/push.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,6 @@ class PushSchemaCommand extends SchemaCommand {
description: "Push the change without a diff or schema version check",
default: false,
}),
// NB: Required as a flag because it will become optional eventually,
// once project configuration is implemented.
dir: Flags.string({
required: true,
description: "The directory of .fsl files to push",
}),
};

async confirm() {
Expand All @@ -32,8 +26,8 @@ class PushSchemaCommand extends SchemaCommand {
}

async run() {
const fps = this.gather(this.flags.dir);
const files = this.read(this.flags.dir, fps);
const fps = this.gather();
const files = this.read(fps);
try {
const { urlbase, secret } = await this.fetchsetup();
if (this.flags.force) {
Expand Down
4 changes: 3 additions & 1 deletion src/commands/shell.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ class ShellCommand extends EvalCommand {
// we don't want to allow people to call some of the default commands
// from the node repl
const entries = Object.entries(this.repl.commands);
this.repl.commands = Object.fromEntries(entries.filter(([k, _]) => !["load", "save"].includes(k)));
this.repl.commands = Object.fromEntries(
entries.filter(([k, _]) => !["load", "save"].includes(k))
);

this.commands.forEach(({ cmd, ...cmdOptions }) =>
this.repl.defineCommand(cmd, cmdOptions)
Expand Down
8 changes: 8 additions & 0 deletions src/lib/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ export class Config {
export type ShellOpts = {
flags?: { [key: string]: any };
rootConfig?: { [key: string]: any };
projectPath?: string;
projectConfig?: { [key: string]: any };
};

Expand All @@ -124,6 +125,8 @@ export class ShellConfig {
//
// If this is unset, `validate` will fail.
endpoint: Endpoint | undefined;
// The path to the project config.
projectPath: string | undefined;

static read(flags: any) {
const rootConfig = ini.parse(readFileOpt(getRootConfigPath()));
Expand All @@ -135,6 +138,10 @@ export class ShellConfig {
return new ShellConfig({
flags,
rootConfig,
projectPath:
projectConfigPath !== undefined
? path.dirname(projectConfigPath)
: undefined,
projectConfig,
});
}
Expand All @@ -145,6 +152,7 @@ export class ShellConfig {
this.rootConfig = new RootConfig(
new Config("config key", opts.rootConfig ?? {})
);
this.projectPath = opts.projectPath;
this.projectConfig = opts.projectConfig
? new ProjectConfig(new Config("config key", opts.projectConfig))
: undefined;
Expand Down
15 changes: 12 additions & 3 deletions src/lib/fauna-command.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ class FaunaCommand extends Command {
async withClient(f, dbScope, role) {
let connectionOptions;
try {
connectionOptions = this.shellConfig.lookupEndpoint({ scope: dbScope, role });
connectionOptions = this.shellConfig.lookupEndpoint({
scope: dbScope,
role,
});

const { hostname, port, protocol } = new URL(connectionOptions.url);

Expand Down Expand Up @@ -95,7 +98,10 @@ class FaunaCommand extends Command {
// construct v4 client
let connectionOptions;
try {
connectionOptions = this.shellConfig.lookupEndpoint({ scope: dbScope, role });
connectionOptions = this.shellConfig.lookupEndpoint({
scope: dbScope,
role,
});

const { hostname, port, protocol } = new URL(connectionOptions.url);

Expand Down Expand Up @@ -130,7 +136,10 @@ class FaunaCommand extends Command {
// construct v10 client
let connectionOptions;
try {
connectionOptions = this.shellConfig.lookupEndpoint({ scope: dbScope, role });
connectionOptions = this.shellConfig.lookupEndpoint({
scope: dbScope,
role,
});
const client = new FaunaClient(
connectionOptions.url,
connectionOptions.secret,
Expand Down
49 changes: 38 additions & 11 deletions src/lib/schema-command.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
import FaunaCommand from "./fauna-command";
import { readFileSync, readdirSync, statSync } from "fs";
import { join } from "path";
import * as fs from "fs";
import * as path from "path";
import FormData from "form-data";
import { Flags } from "@oclif/core";

class SchemaCommand extends FaunaCommand {
static flags = (() => {
// Remove flags that don't make sense.
const { graphqlHost, graphqlPort, ...rest } = FaunaCommand.flags;
return rest;
return {
dir: Flags.string({
description:
"The directory of .fsl files to push. Defaults to the directory of `.fauna-project`",
required: false,
}),
...rest,
};
})();

async fetchsetup() {
Expand All @@ -21,6 +29,25 @@ class SchemaCommand extends FaunaCommand {
};
}

/**
* @type {string}
*/
dir;

async init() {
await super.init();

if (this.flags.dir !== undefined) {
this.dir = this.flags.dir;
} else if (this.shellConfig.projectPath !== undefined) {
this.dir = this.shellConfig.projectPath;
} else {
this.error(
"No project found. Create a project with `fauna project init`."
);
}
}

// Helper to construct form data for a collection of files, as
// returned by `gather`.
body(files) {
Expand All @@ -34,13 +61,13 @@ class SchemaCommand extends FaunaCommand {
// Reads the files using their relative-to-`basedir` paths and returns their
// contents paired with the relative path.
// Fails if the total size of the files is too large.
read(basedir, relpaths) {
read(relpaths) {
const FILESIZE_LIMIT_BYTES = 32 * 1024 * 1024;
const curr = [];
var totalsize = 0;
for (const relp of relpaths) {
const fp = join(basedir, relp);
const content = readFileSync(fp);
const fp = path.join(this.dir, relp);
const content = fs.readFileSync(fp);
totalsize += content.length;
if (totalsize > FILESIZE_LIMIT_BYTES) {
this.error(
Expand All @@ -55,15 +82,15 @@ class SchemaCommand extends FaunaCommand {
// Gathers all FSL files in the directory rooted at `basedir` and returns a
// list of relative paths.
// Fails if there are too many files.
gather(basedir) {
gather() {
const FILE_LIMIT = 256;
const go = (rel, curr) => {
const names = readdirSync(join(basedir, rel));
const names = fs.readdirSync(path.join(this.dir, rel));
const subdirs = [];
for (const n of names) {
const fp = join(basedir, rel, n);
const relp = join(rel, n);
const isDir = statSync(fp).isDirectory();
const fp = path.join(this.dir, rel, n);
const relp = path.join(rel, n);
const isDir = fs.statSync(fp).isDirectory();
if (n.endsWith(".fsl") && !isDir) {
curr.push(relp);
}
Expand Down
3 changes: 2 additions & 1 deletion test/lib/fauna-import-writer.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const expect = require("expect");
const getFaunaImportWriter = require("../../src/lib/fauna-import-writer").default;
const getFaunaImportWriter =
require("../../src/lib/fauna-import-writer").default;
const jestMock = require("jest-mock");
const sizeof = require("object-sizeof");
const { UnavailableError, FaunaHTTPError } = require("faunadb").errors;
Expand Down
1 change: 1 addition & 0 deletions test/testdata/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
roles/

0 comments on commit 8ded068

Please sign in to comment.