UNPKG

kitura-cli

Version:
193 lines (161 loc) 7.36 kB
#!/usr/bin/env node const chalk = require('chalk'); const spawnSync = require('child_process').spawnSync; const os = require('os'); const fs = require('fs'); const path = require('path'); const replaceInFile = require('replace-in-file'); const initURL = 'https://github.com/IBM-Swift/generator-swiftserver-projects' const initBranch = 'init' let args = process.argv.slice(2); if (args.length > 0) { if (args.indexOf('--help') > -1) { printHelp(); process.exit(0); } } let currentDirPath = path.resolve("./"); let currentDir = path.basename(currentDirPath); // Replace spaces with hyphens so Xcode project will build. let projName = currentDir.replace(/ /g, "-"); if (projName.charAt(0) === '.') { console.error(chalk.red('Application name cannot start with .: %s')); process.exit(1); } // Make sure directory doesn't contain problem characters. validateDirectoryName(); // Make sure directory is empty. checkCurrentDirIsEmpty(); // Clone repo contents into current directory. cloneProject(initURL, initBranch); // Rename project to match current directory renameProject(); // If '--skip-build' not specified, then build project. if (!(args.includes('--skip-build'))) { buildProject(); } function validateDirectoryName() { var problemChars = /[%:;="<>”|\\\/]/; if (problemChars.test(projName)) { console.error(chalk.red('Error: ') + 'Project directory cannot contain the following characters: %":;=<>”|\\'); process.exit(1); } } function checkCurrentDirIsEmpty() { try { var data = fs.readdirSync('.'); if (data.length !== 0) { console.error(chalk.red('Error: ') + 'Current directory is not empty.'); console.error(chalk.red('Please repeat the command in an empty directory.')); process.exit(1); } } catch (err) { console.error(chalk.red('Error: ') + 'could not create project.'); console.error(err.message); process.exit(err.errno); } } function cloneProject(url, branch) { console.log('Creating project...'); let clone = spawnSync('git', ['clone', '-b', branch, url, '.']); if (clone.status !== 0) { console.error(chalk.red('Error: ') + 'failed to run git clone.'); console.error('Please check your network connection and that you have git installed.'); console.error('Head to https://git-scm.com/downloads for instructions on installing git.'); process.exit(clone.status); } else { console.log(chalk.green('Project created successfully.')); if ((args.includes('--skip-build'))) { console.log('Next steps:'); console.log(''); console.log('Generate your Xcode project:'); console.log(chalk.grey(' $ swift package generate-xcodeproj')); console.log(''); console.log('Or, build your project from the terminal:'); console.log(chalk.grey(' $ swift build')); } } // Remove git remote let git = spawnSync('rm', ['-rf', '.git']); if (git.status !== 0) { console.error(chalk.red('Error: ') + 'failed to remove .git directory.'); process.exit(git.status); } } /* Projects created with kitura init start by cloning a template project, and renaming elements of that project to match the user's chosen project name (determined by the name of their current directory). We perform this renaming for three variants of the project's name: The original name as given, the same name with special characters stripped (as required by SwiftPM), and the stripped name also lowercased (used for example in the name of Docker containers generated by 'kitura build' and 'kitura run'). */ function renameProject() { let projNameLowercase = projName.toLowerCase(); // Ensure project name only contains alphanumeric characters. let projNameClean = projName.replace(/^[^a-zA-Z]*/, '') .replace(/[^a-zA-Z0-9]/g, ''); let projNameCleanLowercase = projNameClean.toLowerCase(); // Name of the project generated by the swiftserver generator. Used as a placeholder to find and replace with the actual project name. let oldProjName = "Generator-Swiftserver-Projects"; // Name of the project directory generated by the swiftserver generator let oldProjNameClean = "GeneratorSwiftserverProjects"; // Value used throughout various files, all of which are inserted by the swiftserver generator // Also the name of the directory within the charts directory let oldProjNameCleanLowercase = "generatorswiftserverprojects" // Rename directories (charts can't contain special characters or uppercase characters). try { fs.renameSync("./chart/" + oldProjNameCleanLowercase, "./chart/" + projNameCleanLowercase); fs.renameSync("./Sources/" + oldProjName, "./Sources/" + projName); } catch (err) { console.error(chalk.red('Error: ') + 'could not rename directories.'); console.error(err.message); process.exit(err.errno); } //Construct a regex expression to replace multiple occurrences of oldProjName const oldProjNameRegex = new RegExp(oldProjName, 'g'); //Construct a regex expression to replace multiple occurances of oldProjNameCleanLowercase const oldProjNameCleanLowercaseRegex = new RegExp(oldProjNameCleanLowercase, 'g'); /* Creates the options for replace-in-file which will look at all files within this directory (and nested directories) replacing all occurances of the Generator-Swiftserver-Projects and generatorswiftserverprojects placeholders that are added by the generator. */ const options = { files: "**", from: [oldProjNameRegex, oldProjNameCleanLowercaseRegex], to: [projName, projNameCleanLowercase] }; replaceInFile.sync(options); } function buildProject() { console.log('Running `swift build` to build project...'); var build = spawnSync('swift', ['build'], { stdio:[0,1,2] }); if (build.status !== 0) { console.error(chalk.red('Failed to complete build.')); process.exit(build.status); } else { console.log('Running `swift package generate-xcodeproj` to generate Xcode Project...'); var xcodeProj = spawnSync('swift', ['package', 'generate-xcodeproj'], { stdio:[0,1,2] }); if (xcodeProj.status !== 0) { console.error(chalk.red('Failed to generate Xcode Project.')); process.exit(xcodeProj.status); } else { console.log(chalk.green('Project built successfully.')); console.log('Next steps:'); console.log(''); console.log('Open your Xcode project:'); console.log(chalk.grey(' $ open ' + projName + '.xcodeproj')); console.log(''); console.log('Or, run your app from the terminal:'); console.log(chalk.grey(' $ swift run')); } } } function printHelp() { console.log(""); console.log(" Usage: kitura init [options]"); console.log(""); console.log(" Scaffold a bare-bones Kitura project."); console.log(""); console.log(" Options:"); console.log(""); console.log(" --help print this help"); console.log(" --skip-build do not build the project"); console.log(""); }