mirror of
https://github.com/strapi/strapi.git
synced 2025-07-18 14:32:56 +00:00

Create starter CLI Add spaces option Extract project basename Add starter shortcut Refactor git init commit Replace concurrently with npm-run-all Move fetch repo function to dedicated file Allow shortcut to accept external org repo Fix package config & readme Fix versions Add task prefixes Update readme [Starter CLI] error handling (#9600) * Display error message + help for missing arguments * Add cleaner error messages * Bump commander from v6.1.0 to v7.1.0 * Capture and log errors from commander * Simplify cli argument errors * Provide more human readable error messages * Replace throw with console log * Add logger Add starter tracking Add wrapper for tracking keys Update root config Keep template in scope root fix strapi config Fix open frontend Remove open-cli Update for rename frontend->starter update description Update tracking Fix tests fix e2e tests Make sure packageJsonStrapi does not override unwanted keys & make it optional to avoid errors simplify metadata strapi Allow stater or frontend folder for smooth migration of existing starters Udpate dep Handle error
171 lines
4.7 KiB
JavaScript
171 lines
4.7 KiB
JavaScript
'use strict';
|
|
|
|
const { resolve, join, basename } = require('path');
|
|
const os = require('os');
|
|
const fse = require('fs-extra');
|
|
|
|
const ora = require('ora');
|
|
const ciEnv = require('ci-info');
|
|
const chalk = require('chalk');
|
|
|
|
const generateNewApp = require('strapi-generate-new');
|
|
|
|
const hasYarn = require('./has-yarn');
|
|
const { runInstall, runApp, initGit } = require('./child-process');
|
|
const { getRepoInfo, downloadGithubRepo } = require('./fetch-github');
|
|
const logger = require('./logger');
|
|
const stopProcess = require('./stop-process');
|
|
|
|
/**
|
|
* @param {string} filePath Path to starter.json file
|
|
*/
|
|
function readStarterJson(filePath, starterUrl) {
|
|
try {
|
|
const data = fse.readFileSync(filePath);
|
|
return JSON.parse(data);
|
|
} catch (err) {
|
|
stopProcess(`Could not find ${chalk.yellow('starter.json')} in ${chalk.yellow(starterUrl)}`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {string} rootPath Path to the project directory
|
|
* @param {string} projectName Name of the project
|
|
*/
|
|
async function initPackageJson(rootPath, projectName) {
|
|
const packageManager = hasYarn ? 'yarn --cwd' : 'npm run --prefix';
|
|
|
|
try {
|
|
await fse.writeJson(
|
|
join(rootPath, 'package.json'),
|
|
{
|
|
name: projectName,
|
|
private: true,
|
|
version: '0.0.0',
|
|
scripts: {
|
|
'develop:backend': `${packageManager} backend develop`,
|
|
'develop:frontend': `wait-on http://localhost:1337/admin && ${packageManager} frontend develop`,
|
|
develop: 'FORCE_COLOR=1 npm-run-all -l -p develop:*',
|
|
},
|
|
devDependencies: {
|
|
'npm-run-all': '4.1.5',
|
|
'wait-on': '5.2.1',
|
|
},
|
|
},
|
|
{
|
|
spaces: 2,
|
|
}
|
|
);
|
|
} catch (err) {
|
|
stopProcess(`Failed to create ${chalk.yellow(`package.json`)} in ${chalk.yellow(rootPath)}`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {string} path The directory path for install
|
|
*/
|
|
async function installWithLogs(path) {
|
|
const installPrefix = chalk.yellow('Installing dependencies:');
|
|
const loader = ora(installPrefix).start();
|
|
const logInstall = (chunk = '') => {
|
|
loader.text = `${installPrefix} ${chunk
|
|
.toString()
|
|
.split('\n')
|
|
.join(' ')}`;
|
|
};
|
|
|
|
const runner = runInstall(path);
|
|
runner.stdout.on('data', logInstall);
|
|
runner.stderr.on('data', logInstall);
|
|
|
|
await runner;
|
|
|
|
loader.stop();
|
|
console.log(`Dependencies installed ${chalk.green('successfully')}.`);
|
|
}
|
|
|
|
/**
|
|
* @param {object} projectArgs projectName and starterUrl for the project
|
|
* @param {object} program Commands for generating new application
|
|
*/
|
|
module.exports = async function buildStarter(projectArgs, program) {
|
|
const { projectName, starterUrl } = projectArgs;
|
|
|
|
// Create temporary directory for starter
|
|
const tmpDir = await fse.mkdtemp(join(os.tmpdir(), 'strapi-'));
|
|
|
|
// Fetch repo info
|
|
const { full_name } = await getRepoInfo(starterUrl);
|
|
|
|
// Download repo inside tmp dir
|
|
await downloadGithubRepo(starterUrl, tmpDir);
|
|
|
|
const starterJson = readStarterJson(join(tmpDir, 'starter.json'), starterUrl);
|
|
|
|
// Project directory
|
|
const rootPath = resolve(projectName);
|
|
const projectBasename = basename(rootPath);
|
|
|
|
try {
|
|
await fse.ensureDir(rootPath);
|
|
} catch (error) {
|
|
stopProcess(`Failed to create ${chalk.yellow(rootPath)}: ${error.message}`);
|
|
}
|
|
|
|
// Copy the downloaded frontend folder to the project folder
|
|
const frontendPath = join(rootPath, 'frontend');
|
|
|
|
const starterDir = (await fse.pathExists(join(tmpDir, 'starter'))) ? 'starter' : 'frontend';
|
|
|
|
try {
|
|
await fse.copy(join(tmpDir, starterDir), frontendPath, {
|
|
overwrite: true,
|
|
recursive: true,
|
|
});
|
|
} catch (error) {
|
|
stopProcess(`Failed to create ${chalk.yellow(frontendPath)}: ${error.message}`);
|
|
}
|
|
|
|
// Delete temporary directory
|
|
await fse.remove(tmpDir);
|
|
|
|
console.log(`Creating Strapi starter frontend at ${chalk.yellow(frontendPath)}.`);
|
|
|
|
// Install frontend dependencies
|
|
console.log(`Installing ${chalk.yellow(full_name)} starter`);
|
|
|
|
await installWithLogs(frontendPath);
|
|
|
|
const fullUrl = `https://github.com/${full_name}`;
|
|
// Set command options for Strapi app
|
|
const generateStrapiAppOptions = {
|
|
...program,
|
|
starter: fullUrl,
|
|
template: starterJson.template,
|
|
run: false,
|
|
};
|
|
|
|
// Create strapi app using the template
|
|
await generateNewApp(join(rootPath, 'backend'), generateStrapiAppOptions);
|
|
|
|
// Setup monorepo
|
|
initPackageJson(rootPath, projectBasename);
|
|
|
|
// Add gitignore
|
|
try {
|
|
const gitignore = join(__dirname, '..', 'resources', 'gitignore');
|
|
await fse.copy(gitignore, join(rootPath, '.gitignore'));
|
|
} catch (err) {
|
|
logger.warn(`Failed to create file: ${chalk.yellow('.gitignore')}`);
|
|
}
|
|
|
|
await installWithLogs(rootPath);
|
|
|
|
if (!ciEnv.isCI) {
|
|
await initGit(rootPath);
|
|
}
|
|
|
|
console.log(chalk.green('Starting the app'));
|
|
await runApp(rootPath);
|
|
};
|