Merge pull request #7439 from cmpadden/create-app-path-option

Support optional [path] argument in create-app command-line utility
This commit is contained in:
Patrik Oldsberg
2021-10-28 13:17:47 +02:00
committed by GitHub
3 changed files with 61 additions and 27 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/create-app': patch
---
Support optional path argument when generating a project using `create-app`
+49 -24
View File
@@ -27,7 +27,7 @@ import { Task, templatingTask } from './lib/tasks';
const exec = promisify(execCb);
async function checkExists(rootDir: string, name: string) {
async function checkAppExists(rootDir: string, name: string) {
await Task.forItem('checking', name, async () => {
const destination = resolvePath(rootDir, name);
@@ -40,6 +40,17 @@ async function checkExists(rootDir: string, name: string) {
});
}
async function checkPathExists(path: string) {
await Task.forItem('checking', path, async () => {
try {
await fs.mkdirs(path);
} catch (error) {
// will fail if a file already exists at given `path`
throw new Error(`Failed to create app directory: ${error.message}`);
}
});
}
async function createTemporaryAppFolder(tempDir: string) {
await Task.forItem('creating', 'temporary directory', async () => {
try {
@@ -50,12 +61,6 @@ async function createTemporaryAppFolder(tempDir: string) {
});
}
async function cleanUp(tempDir: string) {
await Task.forItem('remove', 'temporary directory', async () => {
await fs.remove(tempDir);
});
}
async function buildApp(appDir: string) {
const runCmd = async (cmd: string) => {
await Task.forItem('executing', cmd, async () => {
@@ -75,11 +80,17 @@ async function buildApp(appDir: string) {
async function moveApp(tempDir: string, destination: string, id: string) {
await Task.forItem('moving', id, async () => {
await fs.move(tempDir, destination).catch(error => {
throw new Error(
`Failed to move app from ${tempDir} to ${destination}: ${error.message}`,
);
});
await fs
.move(tempDir, destination)
.catch(error => {
throw new Error(
`Failed to move app from ${tempDir} to ${destination}: ${error.message}`,
);
})
.finally(() => {
// remove temporary files on both success and failure
fs.removeSync(tempDir);
});
});
}
@@ -117,23 +128,40 @@ export default async (cmd: Command): Promise<void> => {
const templateDir = paths.resolveOwn('templates/default-app');
const tempDir = resolvePath(os.tmpdir(), answers.name);
const appDir = resolvePath(paths.targetDir, answers.name);
// Use `--path` argument as applicaiton directory when specified, otherwise
// create a directory using `answers.name`
const appDir = cmd.path
? resolvePath(paths.targetDir, cmd.path)
: resolvePath(paths.targetDir, answers.name);
Task.log();
Task.log('Creating the app...');
try {
Task.section('Checking if the directory is available');
await checkExists(paths.targetDir, answers.name);
if (cmd.path) {
// Template directly to specified path
Task.section('Creating a temporary app directory');
await createTemporaryAppFolder(tempDir);
Task.section('Checking that supplied path exists');
await checkPathExists(appDir);
Task.section('Preparing files');
await templatingTask(templateDir, tempDir, answers);
Task.section('Preparing files');
await templatingTask(templateDir, cmd.path, answers);
} else {
// Template to temporary location, and then move files
Task.section('Moving to final location');
await moveApp(tempDir, appDir, answers.name);
Task.section('Checking if the directory is available');
await checkAppExists(paths.targetDir, answers.name);
Task.section('Creating a temporary app directory');
await createTemporaryAppFolder(tempDir);
Task.section('Preparing files');
await templatingTask(templateDir, tempDir, answers);
Task.section('Moving to final location');
await moveApp(tempDir, appDir, answers.name);
}
if (!cmd.skipInstall) {
Task.section('Building the app');
@@ -157,10 +185,7 @@ export default async (cmd: Command): Promise<void> => {
Task.error(String(error));
Task.log('It seems that something went wrong when creating the app 🤔');
Task.log('We are going to clean up, and then you can try again.');
Task.section('Cleanup');
await cleanUp(tempDir);
Task.error('🔥 Failed to create app!');
Task.exit(1);
}
+7 -3
View File
@@ -26,10 +26,14 @@ import { version } from '../package.json';
import createApp from './createApp';
const main = (argv: string[]) => {
program.name('backstage-create-app').version(version);
program
.description('Creates a new app in a new directory')
.name('backstage-create-app')
.version(version)
.description('Creates a new app in a new directory or specified path')
.option(
'--path [directory]',
'Location to store the app defaulting to a new folder with the app name',
)
.option(
'--skip-install',
'Skip the install and builds steps after creating the app',