UNPKG

@adobe/helix-cli

Version:
167 lines (142 loc) 4.93 kB
/* * Copyright 2018 Adobe. All rights reserved. * This file is licensed to you 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 REPRESENTATIONS * OF ANY KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ 'use strict'; const os = require('os'); const path = require('path'); const fse = require('fs-extra'); const chalk = require('chalk'); const shell = require('shelljs'); const glob = require('glob'); const { makeLogger } = require('./log-common'); const ANSI_REGEXP = RegExp([ '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\\u0007)', '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))', ].join('|'), 'g'); function execAsync(cmd) { return new Promise((resolve, reject) => { shell.exec(cmd, (code, stdout, stderr) => { if (code === 0) { resolve(0); } else { reject(stderr); } }); }); } class InitCommand { constructor(logger = makeLogger()) { this._logger = logger; this._name = ''; this._dir = process.cwd(); this._padding = 50; this._type = 'simple'; } withName(name) { this._name = name; return this; } withDirectory(dir) { if (dir) { this._dir = dir; } return this; } withType(type) { this._type = type; return this; } msg(txt) { const dl = txt.length - txt.replace(ANSI_REGEXP, '').length; this._logger.info(txt.padEnd(this._padding + dl, ' ') + chalk.green('[ok]')); } async initGitRepository(dir) { const pwd = shell.pwd(); try { shell.cd(dir); await execAsync('git init -q'); await execAsync('git add -A'); // https://github.com/adobe/helix-cli/issues/280 // bypass pre-commit and commit-msg hooks when doing initial commit (-n,--no-verify) await execAsync('git commit -q -n -m"Initial commit."'); this.msg(chalk.yellow('initializing git repository')); } catch (e) { throw Error(`Unable to initialize git repository: ${e}`); } finally { shell.cd(pwd); } } async run() { if (!this._name) { throw new Error('init needs name.'); } if (!this._dir) { throw new Error('init needs directory.'); } // #181 cover edge case: make sure git is properly configured if (!await fse.pathExists(`${os.homedir()}/.gitconfig`)) { throw new Error(` It seems like Git has not yet been setup on this system. See https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup for more information. `); } this._padding = this._name.length + 45; const projectDir = path.resolve(path.join(this._dir, this._name)); const relPath = path.relative(process.cwd(), projectDir); if (await fse.pathExists(projectDir)) { throw new Error(`cowardly rejecting to re-initialize project: ./${relPath}`); } try { await fse.ensureDir(projectDir); } catch (e) { throw new Error(`Unable to create project directory: ${e}`); } const msgCreating = chalk.yellow('creating'); const msgRelPath = chalk.gray(relPath); this.msg(`${msgCreating} ${msgRelPath}`); const project = { name: this._name, }; function processFile(srcFile, dstFile, filter) { if (filter) { return fse.readFile(srcFile, 'utf8').then((text) => { const result = text.replace(/{{\s*project\.name\s*}}/g, project.name); return fse.outputFile(dstFile, result); }); } return fse.copy(srcFile, dstFile); } const root = path.resolve(__dirname, '..', 'demos', this._type); const jobs = glob.sync('**', { cwd: root, absolute: false, dot: true, nodir: true, }).map((f) => { const srcFile = path.resolve(root, f); const dstName = f === '_gitignore' ? '.gitignore' : f; const dstFile = path.resolve(projectDir, dstName); const filter = f === 'index.md' || f === 'README.md' || f === 'helix-config.yaml'; return processFile(srcFile, dstFile, filter).then(() => { this.msg(`${msgCreating} ${msgRelPath}/${chalk.cyan(f)}`); }); }); await Promise.all(jobs); await this.initGitRepository(projectDir); this._logger.info(chalk` Project {cyan ${this._name}} initialized {green successfully} with a simple example. For more examples, clone or fork one from http://github.com/adobe/project-helix/. Next Step: start the development server and test the generated site with: {grey $ cd ${this._name}} {grey $ hlx up}`); } } module.exports = InitCommand;