From f14df56222a1ed754b0608ad66e4aa2aaa48c213 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 30 Dec 2024 13:24:31 +0100 Subject: [PATCH] cli: experimental support for using embedded-postgres as dev DB Signed-off-by: Patrik Oldsberg Made-with: Cursor --- .changeset/thin-elephants-joke.md | 5 + packages/cli-module-build/package.json | 2 + .../src/lib/runner/runBackend.ts | 12 +++ .../src/lib/runner/startEmbeddedDb.ts | 67 +++++++++++++ packages/cli-module-build/src/types.d.ts | 20 ++++ yarn.lock | 95 ++++++++++++++++++- 6 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 .changeset/thin-elephants-joke.md create mode 100644 packages/cli-module-build/src/lib/runner/startEmbeddedDb.ts create mode 100644 packages/cli-module-build/src/types.d.ts diff --git a/.changeset/thin-elephants-joke.md b/.changeset/thin-elephants-joke.md new file mode 100644 index 0000000000..e64940551b --- /dev/null +++ b/.changeset/thin-elephants-joke.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +The `package start` command now supports an experimental `EXPERIMENTAL_DEV_DB` env flag that can be set to enable the use of `embedded-postgres` as the database for local development, rather than SQLite. For this to work the desired version of the `embedded-postgres` package must be installed in your project, typically as a `devDependency`. diff --git a/packages/cli-module-build/package.json b/packages/cli-module-build/package.json index 605df9a542..ce64c5268f 100644 --- a/packages/cli-module-build/package.json +++ b/packages/cli-module-build/package.json @@ -65,6 +65,7 @@ "cross-spawn": "^7.0.3", "css-loader": "^6.5.1", "ctrlc-windows": "^2.1.0", + "embedded-postgres": "^17.2.0-beta.15", "esbuild-loader": "^4.0.0", "eslint-rspack-plugin": "^4.2.1", "eslint-webpack-plugin": "^4.2.0", @@ -77,6 +78,7 @@ "node-stdlib-browser": "^1.3.1", "npm-packlist": "^5.0.0", "p-queue": "^6.6.2", + "portfinder": "^1.0.32", "postcss": "^8.1.0", "postcss-import": "^16.1.0", "process": "^0.11.10", diff --git a/packages/cli-module-build/src/lib/runner/runBackend.ts b/packages/cli-module-build/src/lib/runner/runBackend.ts index 86c249e8be..4c64c5154e 100644 --- a/packages/cli-module-build/src/lib/runner/runBackend.ts +++ b/packages/cli-module-build/src/lib/runner/runBackend.ts @@ -24,6 +24,7 @@ import { isAbsolute as isAbsolutePath } from 'node:path'; import { targetPaths } from '@backstage/cli-common'; import spawn from 'cross-spawn'; +import { startEmbeddedDb } from './startEmbeddedDb'; const loaderArgs = [ '--enable-source-maps', @@ -57,6 +58,16 @@ export async function runBackend(options: RunBackendOptions) { const server = new IpcServer(); ServerDataStore.bind(server); + const extraEnv: Record = {}; + + if (process.env.EXPERIMENTAL_DEV_DB) { + const db = await startEmbeddedDb(); + extraEnv.APP_CONFIG_backend_database = JSON.stringify({ + client: 'pg', + connection: db.connection, + }); + } + let exiting = false; let firstStart = true; let child: ChildProcess | undefined; @@ -134,6 +145,7 @@ export async function runBackend(options: RunBackendOptions) { cwd: options.targetDir, env: { ...process.env, + ...extraEnv, BACKSTAGE_CLI_LINKED_WORKSPACE: options.linkedWorkspace, BACKSTAGE_CLI_CHANNEL: '1', ESBK_TSCONFIG_PATH: targetPaths.resolveRoot('tsconfig.json'), diff --git a/packages/cli-module-build/src/lib/runner/startEmbeddedDb.ts b/packages/cli-module-build/src/lib/runner/startEmbeddedDb.ts new file mode 100644 index 0000000000..85de29cda2 --- /dev/null +++ b/packages/cli-module-build/src/lib/runner/startEmbeddedDb.ts @@ -0,0 +1,67 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import os from 'node:os'; +import fs from 'fs-extra'; +import { resolve as resolvePath } from 'path'; +import { getPortPromise } from 'portfinder'; + +export async function startEmbeddedDb() { + const { default: EmbeddedPostgres } = await import('embedded-postgres').catch( + error => { + throw new Error( + `Failed to load peer dependency 'embedded-postgres' for generating SQL reports. ` + + `It must be installed as an explicit dependency in your project. Caused by; ${error}`, + ); + }, + ); + + const host = 'localhost'; + const user = 'postgres'; + const password = 'password'; + const port = await getPortPromise(); + const tmpDir = await fs.mkdtemp( + resolvePath(os.tmpdir(), 'backstage-dev-db-'), + ); + const pg = new EmbeddedPostgres({ + databaseDir: tmpDir, + user, + password, + port, + persistent: false, + onError(_messageOrError) {}, + onLog(_message) {}, + }); + + // Create the cluster config files + await pg.initialise(); + + // Start the server + await pg.start(); + + return { + connection: { + host, + user, + password, + port, + }, + async close() { + await pg.stop(); + await fs.rmdir(tmpDir, { recursive: true, maxRetries: 3 }); + }, + }; +} diff --git a/packages/cli-module-build/src/types.d.ts b/packages/cli-module-build/src/types.d.ts new file mode 100644 index 0000000000..2e30114f10 --- /dev/null +++ b/packages/cli-module-build/src/types.d.ts @@ -0,0 +1,20 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// It's missing a types entry point, but has types in dist +declare module 'embedded-postgres' { + export { default } from 'embedded-postgres/dist/index'; +} diff --git a/yarn.lock b/yarn.lock index 13b51ed309..35bca1fb75 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2900,6 +2900,7 @@ __metadata: cross-spawn: "npm:^7.0.3" css-loader: "npm:^6.5.1" ctrlc-windows: "npm:^2.1.0" + embedded-postgres: "npm:^17.2.0-beta.15" esbuild-loader: "npm:^4.0.0" eslint-rspack-plugin: "npm:^4.2.1" eslint-webpack-plugin: "npm:^4.2.0" @@ -2912,6 +2913,7 @@ __metadata: node-stdlib-browser: "npm:^1.3.1" npm-packlist: "npm:^5.0.0" p-queue: "npm:^6.6.2" + portfinder: "npm:^1.0.32" postcss: "npm:^8.1.0" postcss-import: "npm:^16.1.0" process: "npm:^0.11.10" @@ -8557,6 +8559,62 @@ __metadata: languageName: node linkType: hard +"@embedded-postgres/darwin-arm64@npm:^17.2.0-beta.15": + version: 17.2.0-beta.15 + resolution: "@embedded-postgres/darwin-arm64@npm:17.2.0-beta.15" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@embedded-postgres/darwin-x64@npm:^17.2.0-beta.15": + version: 17.2.0-beta.15 + resolution: "@embedded-postgres/darwin-x64@npm:17.2.0-beta.15" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@embedded-postgres/linux-arm64@npm:^17.2.0-beta.15": + version: 17.2.0-beta.15 + resolution: "@embedded-postgres/linux-arm64@npm:17.2.0-beta.15" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"@embedded-postgres/linux-arm@npm:^17.2.0-beta.15": + version: 17.2.0-beta.15 + resolution: "@embedded-postgres/linux-arm@npm:17.2.0-beta.15" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@embedded-postgres/linux-ia32@npm:^17.2.0-beta.15": + version: 17.2.0-beta.15 + resolution: "@embedded-postgres/linux-ia32@npm:17.2.0-beta.15" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + +"@embedded-postgres/linux-ppc64@npm:^17.2.0-beta.15": + version: 17.2.0-beta.15 + resolution: "@embedded-postgres/linux-ppc64@npm:17.2.0-beta.15" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"@embedded-postgres/linux-x64@npm:^17.2.0-beta.15": + version: 17.2.0-beta.15 + resolution: "@embedded-postgres/linux-x64@npm:17.2.0-beta.15" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@embedded-postgres/windows-x64@npm:^17.2.0-beta.15": + version: 17.2.0-beta.15 + resolution: "@embedded-postgres/windows-x64@npm:17.2.0-beta.15" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@emnapi/core@npm:^1.4.3, @emnapi/core@npm:^1.5.0, @emnapi/core@npm:^1.7.1": version: 1.7.1 resolution: "@emnapi/core@npm:1.7.1" @@ -29366,6 +29424,41 @@ __metadata: languageName: node linkType: hard +"embedded-postgres@npm:^17.2.0-beta.15": + version: 17.2.0-beta.15 + resolution: "embedded-postgres@npm:17.2.0-beta.15" + dependencies: + "@embedded-postgres/darwin-arm64": "npm:^17.2.0-beta.15" + "@embedded-postgres/darwin-x64": "npm:^17.2.0-beta.15" + "@embedded-postgres/linux-arm": "npm:^17.2.0-beta.15" + "@embedded-postgres/linux-arm64": "npm:^17.2.0-beta.15" + "@embedded-postgres/linux-ia32": "npm:^17.2.0-beta.15" + "@embedded-postgres/linux-ppc64": "npm:^17.2.0-beta.15" + "@embedded-postgres/linux-x64": "npm:^17.2.0-beta.15" + "@embedded-postgres/windows-x64": "npm:^17.2.0-beta.15" + async-exit-hook: "npm:^2.0.1" + pg: "npm:^8.7.3" + dependenciesMeta: + "@embedded-postgres/darwin-arm64": + optional: true + "@embedded-postgres/darwin-x64": + optional: true + "@embedded-postgres/linux-arm": + optional: true + "@embedded-postgres/linux-arm64": + optional: true + "@embedded-postgres/linux-ia32": + optional: true + "@embedded-postgres/linux-ppc64": + optional: true + "@embedded-postgres/linux-x64": + optional: true + "@embedded-postgres/windows-x64": + optional: true + checksum: 10/bba9ba0f584bbfba854c60932eafc62c4338e8231793f1c7c3cc4e066895877c606c68b7f5b07ec005de4c7506e81f70bf1cd27d74bf5719c7be334272294ce4 + languageName: node + linkType: hard + "emittery@npm:^0.13.1": version: 0.13.1 resolution: "emittery@npm:0.13.1" @@ -41558,7 +41651,7 @@ __metadata: languageName: node linkType: hard -"pg@npm:^8.11.3, pg@npm:^8.9.0": +"pg@npm:^8.11.3, pg@npm:^8.7.3, pg@npm:^8.9.0": version: 8.20.0 resolution: "pg@npm:8.20.0" dependencies: