Skip to content

Commit

Permalink
feat: clean command
Browse files Browse the repository at this point in the history
  • Loading branch information
NathanFlurry committed Mar 7, 2024
1 parent ed717cd commit 0767dd5
Show file tree
Hide file tree
Showing 9 changed files with 177 additions and 143 deletions.
7 changes: 7 additions & 0 deletions src/build/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { migrateDev } from "../migrate/dev.ts";
import { compileModuleTypeHelper } from "./gen.ts";
import { migrateDeploy } from "../migrate/deploy.ts";
import { ensurePostgresRunning } from "../utils/postgres_daemon.ts";
import { generateClient } from "../migrate/generate.ts";

/**
* Which format to use for building.
Expand Down Expand Up @@ -257,12 +258,18 @@ async function buildSteps(
// Do not alter migrations, only deploy them
await migrateDeploy(project, [module]);
}

// Generate client
await generateClient(project, [module]);
},
});

// Run one migration at a time since Prisma is interactive
await waitForBuildPromises(buildState);
}

// Wait for promise since we can't run multiple `migrateDev` commands at once
await waitForBuildPromises(buildState);
}

buildStep(buildState, {
Expand Down
12 changes: 12 additions & 0 deletions src/cli/commands/clean.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Command } from "../deps.ts";
import { GlobalOpts, initProject } from "../common.ts";
import { cleanProject } from "../../project/project.ts";

export const cleanCommand = new Command<GlobalOpts>()
.description("Removes all build artifacts")
.action(
async (opts) => {
const project = await initProject(opts);
await cleanProject(project);
},
);
4 changes: 3 additions & 1 deletion src/cli/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { createCommand } from "./commands/create.ts";
import { lintCommand } from "./commands/lint.ts";
import { formatCommand } from "./commands/format.ts";
import { initCommand } from "./commands/init.ts";
import { cleanCommand } from "./commands/clean.ts";

const command = new Command();
command.action(() => command.showHelp())
Expand All @@ -21,11 +22,12 @@ command.action(() => command.showHelp())
.command("create", createCommand)
.command("start", startCommand)
.command("test", testCommand)
.command("db", dbCommand)
.command("database, db", dbCommand)
.command("sdk", sdkCommand)
.command("format, fmt", formatCommand)
.command("lint", lintCommand)
.command("build", buildCommand)
.command("clean", cleanCommand)
.command("help", new HelpCommand().global())
.command("completions", new CompletionsCommand())
.error((error, cmd) => {
Expand Down
2 changes: 2 additions & 0 deletions src/migrate/deploy.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Deploys SQL migrations. See `dev.ts` to generate migrations.
//
// Wrapper around `prisma migrate deploy`

import { Module, Project } from "../project/mod.ts";
Expand Down
148 changes: 11 additions & 137 deletions src/migrate/dev.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
// Generates SQL migrations & generates client library.
// Generates & deploys SQL migrations. See `deploy.ts` to only deploy migrations.
//
// Wrapper around `prisma migrate dev`

import { copy, exists, resolve } from "../deps.ts";
import { buildPrismaPackage } from "./build_prisma_esm.ts";
import { assert, copy, exists, resolve } from "../deps.ts";
import { Module, Project } from "../project/mod.ts";
import { forEachPrismaSchema } from "./mod.ts";

Expand All @@ -16,10 +15,12 @@ export async function migrateDev(
modules: Module[],
opts: MigrateDevOpts,
) {
assert(modules.every(m => ("local" in m.registry.config)), "Only local modules can run migrateDev because it generates migration files");

await forEachPrismaSchema(
project,
modules,
async ({ databaseUrl, module, tempDir, generatedClientDir }) => {
async ({ databaseUrl, module, tempDir }) => {
// Generate migrations & client
const status = await new Deno.Command("deno", {
args: [
Expand All @@ -28,6 +29,7 @@ export async function migrateDev(
"npm:prisma@5.9.1",
"migrate",
"dev",
"--skip-generate",
...(opts.createOnly ? ["--create-only"] : []),
],
cwd: tempDir,
Expand All @@ -36,149 +38,21 @@ export async function migrateDev(
stderr: "inherit",
env: {
DATABASE_URL: databaseUrl,
PRISMA_CLIENT_FORCE_WASM: "true",
},
}).output();
if (!status.success) {
throw new Error("Failed to generate migrations");
}

if (!opts.createOnly) {
// Specify the path to the library & binary types
await (async () => {
for (
const filename of [
"index.d.ts",
"default.d.ts",
"wasm.d.ts",
"edge.d.ts",
]
) {
const filePath = resolve(generatedClientDir, filename);
let content = await Deno.readTextFile(filePath);
const replaceLineA =
`import * as runtime from './runtime/library.js'`;
const replaceLineB =
`import * as runtime from './runtime/binary.js'`;
content = content
.replace(
replaceLineA,
`// @deno-types="./runtime/library.d.ts"\n${replaceLineA}`,
)
.replace(
replaceLineB,
`// @deno-types="./runtime/binary.d.ts"\n${replaceLineB}`,
)
.replace(/from '.\/default'/g, `from './default.d.ts'`);
await Deno.writeTextFile(filePath, content);
}
})();

// Compile the ESM library
buildPrismaPackage(
generatedClientDir,
resolve(generatedClientDir, "esm.js"),
);
}

// Copy back migrations dir
//
// Copy for both `path` (that we'll use later in this script) and
// `sourcePath` (which is the original module's source)
const tempMigrationsDir = resolve(tempDir, "migrations");
const migrationsDir = resolve(module.path, "db", "migrations");
if (await exists(tempMigrationsDir)) {
await copy(tempMigrationsDir, migrationsDir, { overwrite: true });
await copy(tempMigrationsDir, resolve(module.path, "db", "migrations"), { overwrite: true });
await copy(tempMigrationsDir, resolve(module.sourcePath, "db", "migrations"), { overwrite: true });
}
},
);
}

// export async function __TEMP__migrateDev(
// project: Project,
// module: Module,
// opts: MigrateDevOpts,
// ) {
// const databaseUrl = "postgres://username:password@localhost:5432/database";
// // Setup database
// const defaultDatabaseUrl = Deno.env.get("DATABASE_URL") ??
// "postgres://postgres:password@localhost:5432/postgres";

// // Create dirs
// const tempDir = await Deno.makeTempDir();
// const dbDir = resolve(module.path, "db");
// const generatedClientDir = resolve(
// module.path,
// "_gen",
// "prisma",
// );

// // Copy db
// await copy(dbDir, tempDir, { overwrite: true });

// // Generate migrations & client
// console.log("Generating migrations");
// const status = await new Deno.Command("deno", {
// args: [
// "run",
// "-A",
// "npm:prisma@5.9.1",
// "migrate",
// "dev",
// ...(opts.createOnly ? ["--create-only"] : []),
// ],
// cwd: tempDir,
// stdin: "inherit",
// stdout: "inherit",
// stderr: "inherit",
// env: {
// DATABASE_URL: databaseUrl,
// PRISMA_CLIENT_FORCE_WASM: "true",
// },
// }).output();
// if (!status.success) {
// throw new Error("Failed to generate migrations");
// }

// if (!opts.createOnly) {
// // Specify the path to the library & binary types
// await (async () => {
// for (
// const filename of [
// "index.d.ts",
// "default.d.ts",
// "wasm.d.ts",
// "edge.d.ts",
// ]
// ) {
// const filePath = resolve(generatedClientDir, filename);
// let content = await Deno.readTextFile(filePath);
// const replaceLineA = `import * as runtime from './runtime/library.js'`;
// const replaceLineB = `import * as runtime from './runtime/binary.js'`;
// content = content
// .replace(
// replaceLineA,
// `// @deno-types="./runtime/library.d.ts"\n${replaceLineA}`,
// )
// .replace(
// replaceLineB,
// `// @deno-types="./runtime/binary.d.ts"\n${replaceLineB}`,
// )
// .replace(/from '.\/default'/g, `from './default.d.ts'`);
// await Deno.writeTextFile(filePath, content);
// }
// })();

// // Compile the ESM library
// console.log("Compiling ESM library");
// buildPrismaPackage(
// generatedClientDir,
// resolve(generatedClientDir, "esm.js"),
// );
// }

// // Copy back migrations dir
// console.log("Copying migrations back");
// const tempMigrationsDir = resolve(tempDir, "migrations");
// const migrationsDir = resolve(module.path, "db", "migrations");
// if (await exists(tempMigrationsDir)) {
// await copy(tempMigrationsDir, migrationsDir, { overwrite: true });
// }
// }
72 changes: 72 additions & 0 deletions src/migrate/generate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Generates Prisma client libraries.
//
// Wrapper around `prisma generate`

import { resolve } from "../deps.ts";
import { buildPrismaPackage } from "./build_prisma_esm.ts";
import { Module, Project } from "../project/mod.ts";
import { forEachPrismaSchema } from "./mod.ts";

export async function generateClient(
project: Project,
modules: Module[],
) {
await forEachPrismaSchema(
project,
modules,
async ({ databaseUrl, tempDir, generatedClientDir }) => {
// Generate migrations & client
const status = await new Deno.Command("deno", {
args: [
"run",
"-A",
"npm:prisma@5.9.1",
"generate",
],
cwd: tempDir,
stdin: "inherit",
stdout: "inherit",
stderr: "inherit",
env: {
DATABASE_URL: databaseUrl,
PRISMA_CLIENT_FORCE_WASM: "true",
},
}).output();
if (!status.success) {
throw new Error("Failed to generate migrations");
}

// Specify the path to the library & binary types
for (
const filename of [
"index.d.ts",
"default.d.ts",
"wasm.d.ts",
"edge.d.ts",
]
) {
const filePath = resolve(generatedClientDir, filename);
let content = await Deno.readTextFile(filePath);
const replaceLineA = `import * as runtime from './runtime/library.js'`;
const replaceLineB = `import * as runtime from './runtime/binary.js'`;
content = content
.replace(
replaceLineA,
`// @deno-types="./runtime/library.d.ts"\n${replaceLineA}`,
)
.replace(
replaceLineB,
`// @deno-types="./runtime/binary.d.ts"\n${replaceLineB}`,
)
.replace(/from '.\/default'/g, `from './default.d.ts'`);
await Deno.writeTextFile(filePath, content);
}

// Compile the ESM library
await buildPrismaPackage(
generatedClientDir,
resolve(generatedClientDir, "esm.js"),
);
},
);
}
16 changes: 16 additions & 0 deletions src/project/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,21 @@ import { Project } from "./project.ts";
import { Registry } from "./registry.ts";

export interface Module {
/**
* The path to the module in the project's _gen directory.
*
* This path can be modified and will be discarded on the next codegen.
*/
path: string;

/**
* The path to the module's source code.
*
* This path almost never be modified (including _gen), except for
* exclusions where auto-generating code (e.g. prisma migrate dev).
*/
sourcePath: string;

name: string;
config: ModuleConfig;
registry: Registry,
Expand All @@ -21,6 +35,7 @@ export interface ModuleDatabase {

export async function loadModule(
modulePath: string,
sourcePath: string,
name: string,
registry: Registry,
): Promise<Module> {
Expand Down Expand Up @@ -80,6 +95,7 @@ export async function loadModule(

return {
path: modulePath,
sourcePath,
name,
config,
registry,
Expand Down
Loading

0 comments on commit 0767dd5

Please sign in to comment.