diff --git a/README.md b/README.md index 92d18a8..37467bc 100644 --- a/README.md +++ b/README.md @@ -764,7 +764,8 @@ When you make changes to `myfunction.sql`, include it in your current migration by adding `--!include functions/myfunction.sql` to your `current.sql` (or any `current/*.sql`). This statement doesn't need to be at the top of the file, wherever it is will be replaced by the content of -`migrations/fixtures/functions/myfunction.sql` when the migration is committed. +`migrations/fixtures/functions/myfunction.sql` when the migration is committed +(or compiled using `commit` or `run` commands). ```sql --!include functions/myfunction.sql diff --git a/src/commands/compile.ts b/src/commands/compile.ts index 2516cf5..b9beea4 100644 --- a/src/commands/compile.ts +++ b/src/commands/compile.ts @@ -1,7 +1,7 @@ import * as fsp from "fs/promises"; import { CommandModule } from "yargs"; -import { compilePlaceholders } from "../migration"; +import { compileIncludes, compilePlaceholders } from "../migration"; import { parseSettings, Settings } from "../settings"; import { CommonArgv, getSettings, readStdin } from "./_common"; @@ -11,11 +11,18 @@ interface CompileArgv extends CommonArgv { export async function compile( settings: Settings, - content: string, + rawContents: string, + filename: string | null = null, shadow = false, ): Promise { const parsedSettings = await parseSettings(settings, shadow); - return compilePlaceholders(parsedSettings, content, shadow); + const contents = await compileIncludes( + parsedSettings, + rawContents, + filename ? new Set([filename]) : new Set(), + ); + + return compilePlaceholders(parsedSettings, contents, shadow); } export const compileCommand: CommandModule< @@ -25,7 +32,7 @@ export const compileCommand: CommandModule< command: "compile [file]", aliases: [], describe: `\ -Compiles a SQL file, inserting all the placeholders and returning the result to STDOUT`, +Compiles a SQL file, resolving includes, inserting all the placeholders and returning the result to STDOUT`, builder: { shadow: { type: "boolean", @@ -35,12 +42,15 @@ Compiles a SQL file, inserting all the placeholders and returning the result to }, handler: async (argv) => { const settings = await getSettings({ configFile: argv.config }); - const content = + const { content, filename } = typeof argv.file === "string" - ? await fsp.readFile(argv.file, "utf8") - : await readStdin(); + ? { + filename: argv.file, + content: await fsp.readFile(argv.file, "utf8"), + } + : { filename: null, content: await readStdin() }; - const compiled = await compile(settings, content, argv.shadow); + const compiled = await compile(settings, content, filename, argv.shadow); // eslint-disable-next-line no-console console.log(compiled); diff --git a/src/commands/run.ts b/src/commands/run.ts index 7d963c2..73a4404 100644 --- a/src/commands/run.ts +++ b/src/commands/run.ts @@ -4,7 +4,7 @@ import { CommandModule } from "yargs"; import { DO_NOT_USE_DATABASE_URL } from "../actions"; import { runQueryWithErrorInstrumentation } from "../instrumentation"; -import { compilePlaceholders } from "../migration"; +import { compileIncludes, compilePlaceholders } from "../migration"; import { withClient } from "../pgReal"; import { makeRootDatabaseConnectionString, @@ -19,10 +19,9 @@ interface RunArgv extends CommonArgv { rootDatabase?: boolean; } -// eslint-disable-next-line @typescript-eslint/no-explicit-any export async function run( settings: Settings, - content: string, + rawContents: string, filename: string, { shadow = false, @@ -35,7 +34,12 @@ export async function run( } = {}, ): Promise { const parsedSettings = await parseSettings(settings, shadow); - const sql = compilePlaceholders(parsedSettings, content, shadow); + const contents = await compileIncludes( + parsedSettings, + rawContents, + new Set([filename]), + ); + const sql = compilePlaceholders(parsedSettings, contents, shadow); const baseConnectionString = rootDatabase ? parsedSettings.rootConnectionString : shadow @@ -62,7 +66,7 @@ export const runCommand: CommandModule, RunArgv> = { command: "run [file]", aliases: [], describe: `\ -Compiles a SQL file, inserting all the placeholders, and then runs it against the database. Useful for seeding. If called from an action will automatically run against the same database (via GM_DBURL envvar) unless --shadow or --rootDatabase are supplied.`, +Compiles a SQL file, resolving includes and inserting all the placeholders, and then runs it against the database. Useful for seeding. If called from an action will automatically run against the same database (via GM_DBURL envvar) unless --shadow or --rootDatabase are supplied.`, builder: { shadow: { type: "boolean",