cli: migrate start command to module
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -16,15 +16,16 @@
|
||||
|
||||
import { Command } from 'commander';
|
||||
import { lazy } from '../lib/lazy';
|
||||
import {
|
||||
configOption,
|
||||
registerCommands as registerConfigCommands,
|
||||
} from '../modules/config';
|
||||
import { registerCommands as registerConfigCommands } from '../modules/config';
|
||||
import {
|
||||
registerPackageCommands as registerPackageBuildCommands,
|
||||
registerRepoCommands as registerRepoBuildCommands,
|
||||
registerCommands as registerBuildCommands,
|
||||
} from '../modules/build';
|
||||
import {
|
||||
registerPackageCommands as registerPackageStartCommands,
|
||||
registerRepoCommands as registerRepoStartCommands,
|
||||
} from '../modules/start';
|
||||
import { registerCommands as registerInfoCommands } from '../modules/info';
|
||||
import { registerCommands as registerMigrateCommand } from '../modules/migrate';
|
||||
import {
|
||||
@@ -45,6 +46,7 @@ export function registerRepoCommand(program: Command) {
|
||||
.command('repo [command]')
|
||||
.description('Command that run across an entire Backstage project');
|
||||
|
||||
registerRepoStartCommands(command);
|
||||
registerRepoBuildCommands(command);
|
||||
registerRepoTestCommands(command);
|
||||
registerRepoLintCommands(command);
|
||||
@@ -56,24 +58,7 @@ export function registerScriptCommand(program: Command) {
|
||||
.command('package [command]')
|
||||
.description('Lifecycle scripts for individual packages');
|
||||
|
||||
command
|
||||
.command('start')
|
||||
.description('Start a package for local development')
|
||||
.option(...configOption)
|
||||
.option('--role <name>', 'Run the command with an explicit package role')
|
||||
.option('--check', 'Enable type checking and linting if available')
|
||||
.option('--inspect [host]', 'Enable debugger in Node.js environments')
|
||||
.option(
|
||||
'--inspect-brk [host]',
|
||||
'Enable debugger in Node.js environments, breaking before code starts',
|
||||
)
|
||||
.option(
|
||||
'--require <path...>',
|
||||
'Add a --require argument to the node process',
|
||||
)
|
||||
.option('--link <path>', 'Link an external workspace for module resolution')
|
||||
.action(lazy(() => import('./start'), 'command'));
|
||||
|
||||
registerPackageStartCommands(command);
|
||||
registerPackageBuildCommands(command);
|
||||
registerPackageTestCommands(command);
|
||||
registerMaintenancePackageCommands(command);
|
||||
|
||||
@@ -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 { Command } from 'commander';
|
||||
import { createCliPlugin } from '../../wiring/factory';
|
||||
import { lazy } from '../../lib/lazy';
|
||||
import { configOption } from '../config';
|
||||
|
||||
export const buildPlugin = createCliPlugin({
|
||||
pluginId: 'build',
|
||||
init: async reg => {
|
||||
reg.addCommand({
|
||||
path: ['package', 'start'],
|
||||
description: 'Start a package for local development',
|
||||
execute: async ({ args }) => {
|
||||
const command = new Command();
|
||||
|
||||
const defaultCommand = command
|
||||
.option(...configOption)
|
||||
.option(
|
||||
'--role <name>',
|
||||
'Run the command with an explicit package role',
|
||||
)
|
||||
.option('--check', 'Enable type checking and linting if available')
|
||||
.option('--inspect [host]', 'Enable debugger in Node.js environments')
|
||||
.option(
|
||||
'--inspect-brk [host]',
|
||||
'Enable debugger in Node.js environments, breaking before code starts',
|
||||
)
|
||||
.option(
|
||||
'--require <path...>',
|
||||
'Add a --require argument to the node process',
|
||||
)
|
||||
.option(
|
||||
'--link <path>',
|
||||
'Link an external workspace for module resolution',
|
||||
)
|
||||
.action(lazy(() => import('./commands/package/start'), 'command'));
|
||||
|
||||
await defaultCommand.parseAsync(args, { from: 'user' });
|
||||
},
|
||||
});
|
||||
|
||||
reg.addCommand({
|
||||
path: ['repo', 'start'],
|
||||
description: 'Starts packages in the repo for local development',
|
||||
execute: async () => {
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default buildPlugin;
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2020 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 fs from 'fs-extra';
|
||||
import { OptionValues } from 'commander';
|
||||
import { resolve as resolvePath } from 'node:path';
|
||||
import { PackageRole } from '@backstage/cli-node';
|
||||
import { findRoleFromCommand } from '../../../../../lib/role';
|
||||
import { startBackend, startBackendPlugin } from './startBackend';
|
||||
import { startFrontend } from './startFrontend';
|
||||
import { ForwardedError } from '@backstage/errors';
|
||||
|
||||
export async function command(opts: OptionValues): Promise<void> {
|
||||
const role = await findRoleFromCommand(opts);
|
||||
|
||||
if (opts.link) {
|
||||
const dir = resolvePath(opts.link);
|
||||
if (!fs.pathExistsSync(dir)) {
|
||||
throw new Error(
|
||||
`Invalid workspace link, directory does not exist: ${dir}`,
|
||||
);
|
||||
}
|
||||
const pkgJson = await fs
|
||||
.readJson(resolvePath(dir, 'package.json'))
|
||||
.catch(error => {
|
||||
throw new ForwardedError(
|
||||
'Failed to read package.json in linked workspace',
|
||||
error,
|
||||
);
|
||||
});
|
||||
|
||||
if (!pkgJson.workspaces) {
|
||||
throw new Error(
|
||||
`Invalid workspace link, directory is not a workspace: ${dir}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const options = {
|
||||
configPaths: opts.config as string[],
|
||||
checksEnabled: Boolean(opts.check),
|
||||
linkedWorkspace: opts.link,
|
||||
inspectEnabled: opts.inspect,
|
||||
inspectBrkEnabled: opts.inspectBrk,
|
||||
require: opts.require,
|
||||
};
|
||||
|
||||
switch (role) {
|
||||
case 'backend':
|
||||
return startBackend(options);
|
||||
case 'backend-plugin':
|
||||
case 'backend-plugin-module':
|
||||
case 'node-library':
|
||||
return startBackendPlugin(options);
|
||||
case 'frontend':
|
||||
return startFrontend({
|
||||
...options,
|
||||
entry: 'src/index',
|
||||
verifyVersions: true,
|
||||
});
|
||||
case 'web-library':
|
||||
case 'frontend-plugin':
|
||||
case 'frontend-plugin-module':
|
||||
return startFrontend({ entry: 'dev/index', ...options });
|
||||
case 'frontend-dynamic-container' as PackageRole: // experimental
|
||||
return startFrontend({
|
||||
entry: 'src/index',
|
||||
...options,
|
||||
skipOpenBrowser: true,
|
||||
isModuleFederationRemote: true,
|
||||
});
|
||||
default:
|
||||
throw new Error(
|
||||
`Start command is not supported for package role '${role}'`,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2022 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.
|
||||
*/
|
||||
|
||||
export { command } from './command';
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2020 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 fs from 'fs-extra';
|
||||
import { paths } from '../../../../../lib/paths';
|
||||
import { runBackend } from '../../../../../lib/runner';
|
||||
|
||||
interface StartBackendOptions {
|
||||
checksEnabled: boolean;
|
||||
inspectEnabled: boolean;
|
||||
inspectBrkEnabled: boolean;
|
||||
linkedWorkspace?: string;
|
||||
require?: string;
|
||||
}
|
||||
|
||||
export async function startBackend(options: StartBackendOptions) {
|
||||
const waitForExit = await runBackend({
|
||||
entry: 'src/index',
|
||||
inspectEnabled: options.inspectEnabled,
|
||||
inspectBrkEnabled: options.inspectBrkEnabled,
|
||||
linkedWorkspace: options.linkedWorkspace,
|
||||
require: options.require,
|
||||
});
|
||||
|
||||
await waitForExit();
|
||||
}
|
||||
|
||||
export async function startBackendPlugin(options: StartBackendOptions) {
|
||||
const hasDevIndexEntry = await fs.pathExists(
|
||||
paths.resolveTarget('dev', 'index.ts'),
|
||||
);
|
||||
if (!hasDevIndexEntry) {
|
||||
console.warn(
|
||||
`The 'dev' directory is missing. Please create a proper dev/index.ts in order to start the plugin.`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const waitForExit = await runBackend({
|
||||
entry: 'dev/index',
|
||||
inspectEnabled: options.inspectEnabled,
|
||||
inspectBrkEnabled: options.inspectBrkEnabled,
|
||||
require: options.require,
|
||||
linkedWorkspace: options.linkedWorkspace,
|
||||
});
|
||||
|
||||
await waitForExit();
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2020 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 { readJson } from 'fs-extra';
|
||||
import { resolve as resolvePath } from 'path';
|
||||
import {
|
||||
getModuleFederationOptions,
|
||||
serveBundle,
|
||||
} from '../../../../build/lib/bundler';
|
||||
import { paths } from '../../../../../lib/paths';
|
||||
import { BackstagePackageJson } from '@backstage/cli-node';
|
||||
|
||||
interface StartAppOptions {
|
||||
verifyVersions?: boolean;
|
||||
entry: string;
|
||||
|
||||
checksEnabled: boolean;
|
||||
configPaths: string[];
|
||||
skipOpenBrowser?: boolean;
|
||||
isModuleFederationRemote?: boolean;
|
||||
linkedWorkspace?: string;
|
||||
}
|
||||
|
||||
export async function startFrontend(options: StartAppOptions) {
|
||||
const packageJson = (await readJson(
|
||||
paths.resolveTarget('package.json'),
|
||||
)) as BackstagePackageJson;
|
||||
|
||||
const waitForExit = await serveBundle({
|
||||
entry: options.entry,
|
||||
checksEnabled: options.checksEnabled,
|
||||
configPaths: options.configPaths,
|
||||
verifyVersions: options.verifyVersions,
|
||||
skipOpenBrowser: options.skipOpenBrowser,
|
||||
linkedWorkspace: options.linkedWorkspace,
|
||||
moduleFederation: await getModuleFederationOptions(
|
||||
packageJson,
|
||||
resolvePath(paths.targetDir),
|
||||
options.isModuleFederationRemote,
|
||||
),
|
||||
});
|
||||
|
||||
await waitForExit();
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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 { Command } from 'commander';
|
||||
import { lazy } from '../../lib/lazy';
|
||||
import { configOption } from '../config';
|
||||
|
||||
export function registerRepoCommands(command: Command) {
|
||||
command
|
||||
.command('start')
|
||||
.description('Starts packages in the repo for local development')
|
||||
.action(
|
||||
lazy(
|
||||
async () => ({
|
||||
command: () => {
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
}),
|
||||
'command',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
export function registerPackageCommands(command: Command) {
|
||||
command
|
||||
.command('start')
|
||||
.description('Start a package for local development')
|
||||
.option(...configOption)
|
||||
.option('--role <name>', 'Run the command with an explicit package role')
|
||||
.option('--check', 'Enable type checking and linting if available')
|
||||
.option('--inspect [host]', 'Enable debugger in Node.js environments')
|
||||
.option(
|
||||
'--inspect-brk [host]',
|
||||
'Enable debugger in Node.js environments, breaking before code starts',
|
||||
)
|
||||
.option(
|
||||
'--require <path...>',
|
||||
'Add a --require argument to the node process',
|
||||
)
|
||||
.option('--link <path>', 'Link an external workspace for module resolution')
|
||||
.action(lazy(() => import('./commands/package/start'), 'command'));
|
||||
}
|
||||
Reference in New Issue
Block a user