diff --git a/package.json b/package.json index 1d90447..759aa8f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chimp-cli", - "version": "1.0.0", + "version": "2.0.0", "description": "Purpose Chimp cli will make your life easier to edit your chimp recipes This cli will allow you to use your own IDE to edit your recipe. It will also allow you use others tools (sass / js bundle and so on) It includes a live reload tool", "main": "src/index.js", "bin": { @@ -26,7 +26,7 @@ "devDependencies": {}, "homepage": "https://github.com/sunny-fr/chimp-cli", "repository": { - "type" : "git", - "url" : "https://github.com/sunny-fr/chimp-cli" + "type": "git", + "url": "https://github.com/sunny-fr/chimp-cli" } } diff --git a/src/index.js b/src/index.js index 58ba47f..a35b253 100755 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,7 @@ #!/usr/bin/env node const chalk = require('chalk') -const cliSelect = require('cli-select'); +const cliSelect = require('cli-select') const showWelcomeMessage = require('./messages/welcome') const cli = () => { @@ -10,21 +10,31 @@ const cli = () => { const deploy = () => require('./deploy') const watch = () => require('./watch') + const simple = () => require('./templates/simple') + const rollup = () => require('./templates/rollup') const dispatch = (task) => { - if (task === 'deploy') { - return deploy() - } - if (task === 'watch') { - return watch() - } - if (args.length < 1) { - console.log('') - console.log('') - console.log('no available command for ' + task) - console.log('') - console.log('') + switch (task) { + case 'deploy': { + return deploy() + } + case 'watch': { + return watch() + } + case 'generate simple template': { + return simple() + } + case 'generate rollup template': { + return rollup() + } + default: { + console.log('') + console.log('') + console.log('no available command for ' + task) + console.log('') + console.log('') + } } @@ -37,17 +47,17 @@ const cli = () => { console.log('What do you want to do ?') console.log('') cliSelect({ - values: ['watch', 'deploy'], + values: ['watch', 'deploy', 'generate simple template', 'generate rollup template'], valueRenderer: (value, selected) => { if (selected) { - return chalk.underline(value); + return chalk.underline(value) } - return value; + return value }, }).then((response) => { - dispatch(response.value) - }); + dispatch(response.value) + }) return } @@ -56,8 +66,6 @@ const cli = () => { dispatch(args[0]) - - } cli() diff --git a/src/messages/success.js b/src/messages/success.js index ba5c85c..af834ee 100644 --- a/src/messages/success.js +++ b/src/messages/success.js @@ -2,14 +2,14 @@ const boxen = require('boxen') const chalk = require("chalk"); -const greeting = chalk.white.bold('ITS DONE !!') +const greeting = chalk.white(' 🐵 \n It\'s done! \n Happy Coding!') const boxenOptions = { padding: 1, margin: 1, borderStyle: 'round', - borderColor: 'yellow', - backgroundColor: '#555555' + borderColor: '#18acff', + backgroundColor: '#555555', } const showSuccessMessage = () => console.log(boxen(greeting, boxenOptions)) diff --git a/src/messages/welcome.js b/src/messages/welcome.js index 9e90f59..12d05da 100644 --- a/src/messages/welcome.js +++ b/src/messages/welcome.js @@ -1,14 +1,14 @@ const boxen = require('boxen') const chalk = require("chalk"); -const greeting = chalk.white.bold(' 🐵 Welcome chimp cli 🐵️ ') +const greeting = chalk.white(' 🐵 \n chimp cli welcome! \n https://chimp.fr') const boxenOptions = { padding: 1, margin: 1, borderStyle: 'round', borderColor: '#18acff', - backgroundColor: '#555555' + backgroundColor: '#555555', } const showWelcomeMessage = () => console.log(boxen(greeting, boxenOptions)) diff --git a/src/templates/rollup.js b/src/templates/rollup.js new file mode 100644 index 0000000..878babd --- /dev/null +++ b/src/templates/rollup.js @@ -0,0 +1,66 @@ +const config = require('../config') +const {configExistAndValid} = require('../core/management') +const Generate = require('../utils/Generate') +const path = require('path') +const fs = require('fs') +const chalk = require('chalk') +const execSync = require('child_process').execSync +const showSuccess = require('../messages/success') + + +function start() { + configExistAndValid({config}) + .then(chimpConfig => { + let packagePath = path.dirname(require.resolve('./rollup/.chimp-cfg')); + + + console.log('') + console.log('') + console.log(chalk.green(' Generating Files for Rollup + Sass Template... ')) + console.log('') + console.log('') + + + new Generate({ + templatePath: packagePath, + targetPath: process.cwd(), + chimpConfig + }).build().then(() => { + fs.unlinkSync(process.cwd() + '/.chimp-config') + fs.renameSync('.chimp-cfg', '.chimp-config') + + console.log('') + console.log('') + console.log(chalk.green(' Installing dependencies ')) + console.log(chalk.green(' running npm install for you ')) + console.log(chalk.green(' ')) + console.log(chalk.green(' please wait... ')) + console.log('') + console.log('') + + execSync('npm install',{stdio:[0,1,2]}) + + console.log('') + console.log('') + + showSuccess() + + console.log('') + console.log('') + console.log(chalk.green(' You can now run again : chimp ')) + console.log(chalk.green(' and choose the option of watching or deploying ')) + console.log(chalk.green(' you recipe ! ')) + console.log('') + console.log('') + + + + }) + }) + .catch(e => { + console.log('Main error') + console.log(e) + }) +} + +start() \ No newline at end of file diff --git a/src/templates/rollup/.gitignore b/src/templates/rollup/.gitignore new file mode 100755 index 0000000..7ff6fc8 --- /dev/null +++ b/src/templates/rollup/.gitignore @@ -0,0 +1,18 @@ +.DS_Store + +# IDE Files +#------------------------- +.idea* + + +## Sublime Text cache files +*.tmlanguage.cache +*.tmPreferences.cache +*.stTheme.cache +*.sublime-workspace +*.sublime-project +package-lock.json + +build +node_modules +.chimp-cfg \ No newline at end of file diff --git a/src/templates/rollup/package.json b/src/templates/rollup/package.json new file mode 100644 index 0000000..dafdfa4 --- /dev/null +++ b/src/templates/rollup/package.json @@ -0,0 +1,30 @@ +{ + "name": "{recipe-slug}", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "start": "chimp", + "chimp:watch": "chimp watch", + "chimp:deploy": "chimp deploy", + "rollup:bundle": "rollup -c ./rollup.config.js", + "rollup:watch": "rollup -c ./rollup.config.js -w", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "@babel/core": "^7.10.0", + "animate.css": "^4.1.0", + "rollup": "^2.6.1", + "rollup-plugin-commonjs": "^10.1.0", + "rollup-plugin-peer-deps-external": "^2.2.2", + "rollup-plugin-sass": "^1.2.2" + }, + "devDependencies": { + "rollup-plugin-babel": "^4.4.0", + "rollup-plugin-node-resolve": "^5.2.0", + "rollup-plugin-postcss": "^3.1.1", + "rollup-plugin-terser": "^6.1.0" + } +} diff --git a/src/templates/rollup/rollup.config.js b/src/templates/rollup/rollup.config.js new file mode 100644 index 0000000..a0abbad --- /dev/null +++ b/src/templates/rollup/rollup.config.js @@ -0,0 +1,37 @@ +import babel from 'rollup-plugin-babel'; +import resolve from 'rollup-plugin-node-resolve'; +import commonjs from 'rollup-plugin-commonjs'; +import postcss from 'rollup-plugin-postcss'; +import peerDepsExternal from 'rollup-plugin-peer-deps-external'; +import {terser} from 'rollup-plugin-terser' + +export default { + input: './src/main.js', + + output: [ + { + name: 'comlib', + sourcemap: false, + file: './build/bundle.js', + format: 'umd', + globals: { react: 'React' }, + }, + ], + + plugins: [ + peerDepsExternal(), + postcss({ + output: './build/bundle.css', + extract: true, + modules: true, + use: ['sass'], + minimize: true + }), + babel({ exclude: 'node_modules/**' }), + resolve(), + commonjs(), + terser() + ], + + external: ['react', 'react-dom'], +}; \ No newline at end of file diff --git a/src/templates/rollup/src/index.js b/src/templates/rollup/src/index.js new file mode 100644 index 0000000..23e9b3c --- /dev/null +++ b/src/templates/rollup/src/index.js @@ -0,0 +1,7 @@ +import styles from './style.scss' + +function main() { + console.log('hello world') +} + +main() \ No newline at end of file diff --git a/src/templates/rollup/src/style.scss b/src/templates/rollup/src/style.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/templates/simple.js b/src/templates/simple.js new file mode 100644 index 0000000..9c19af9 --- /dev/null +++ b/src/templates/simple.js @@ -0,0 +1,47 @@ +const config = require('../config') +const {configExistAndValid} = require('../core/management') +const Generate = require('../utils/Generate') +const path = require('path') +const fs = require('fs') +const chalk = require('chalk') + +function start() { + configExistAndValid({config}) + .then(chimpConfig => { + let packagePath = path.dirname(require.resolve('./simple/.chimp-cfg')); + + + console.log('') + console.log('') + console.log(chalk.green(' Generating Files for Simple Template... ')) + console.log('') + console.log('') + + + new Generate({ + templatePath: packagePath, + targetPath: process.cwd(), + chimpConfig + }).build().then(() => { + fs.unlinkSync(process.cwd() + '/.chimp-config') + fs.renameSync('.chimp-cfg', '.chimp-config') + + console.log('') + console.log('') + console.log(chalk.green(' --- I T \' S D O N E ---' )) + console.log(chalk.green(' happy coding !')) + console.log(chalk.green('')) + console.log(chalk.green(' You can now run again : chimp ')) + console.log(chalk.green(' and choose the option of watching or deploying ')) + console.log(chalk.green(' you recipe ! ')) + console.log('') + console.log('') + }) + }) + .catch(e => { + console.log('Main error') + console.log(e) + }) +} + +start() \ No newline at end of file diff --git a/src/templates/simple/.gitignore b/src/templates/simple/.gitignore new file mode 100755 index 0000000..7ff6fc8 --- /dev/null +++ b/src/templates/simple/.gitignore @@ -0,0 +1,18 @@ +.DS_Store + +# IDE Files +#------------------------- +.idea* + + +## Sublime Text cache files +*.tmlanguage.cache +*.tmPreferences.cache +*.stTheme.cache +*.sublime-workspace +*.sublime-project +package-lock.json + +build +node_modules +.chimp-cfg \ No newline at end of file diff --git a/src/templates/simple/src/script.js b/src/templates/simple/src/script.js new file mode 100644 index 0000000..e69de29 diff --git a/src/templates/simple/src/style.css b/src/templates/simple/src/style.css new file mode 100644 index 0000000..e69de29 diff --git a/src/utils/Generate.js b/src/utils/Generate.js new file mode 100644 index 0000000..378b8be --- /dev/null +++ b/src/utils/Generate.js @@ -0,0 +1,63 @@ +const fs = require('fs') +const path = require('path') +const chalk = require('chalk') +const {interpolate} = require('../utils/utils') + + +function log(str) { + console.log(chalk.yellow(str)) +} + +class Generate { + constructor({templatePath = './',targetPath ='./', chimpConfig }) { + this.templatePath = templatePath + this.targetPath = targetPath + this.chimpConfig = chimpConfig || {} + } + + getFileContents(file) { + return fs.readFileSync(file, {encoding: 'utf8'}) + } + + getStructure(root) { + return new Promise(function (resolve, reject) { + const structure = {} + function walkSync(currentDirPath) { + fs.readdirSync(currentDirPath).forEach(function (name) { + const filePath = path.join(currentDirPath, name); + const stat = fs.statSync(filePath); + if (stat.isFile()) { + structure[filePath] = {type: 'file', path: filePath} + } else if (stat.isDirectory()) { + structure[filePath] = {type: 'directory', path: filePath} + walkSync(filePath); + } + }); + } + + walkSync(root) + resolve(structure) + }) + } + + build() { + const root = this.templatePath + const base = this.targetPath + '/' + return this.getStructure(root).then(structure => { + Object.keys(structure).forEach( prop=>{ + const item = structure[prop] + if (item.type === 'directory') { + fs.mkdirSync(base + item.path.substr(root.length + 1)) + log(' | ' + item.path.substr(root.length + 1)) + } else if (item.type === 'file') { + const fullPath = base + item.path.substr(root.length + 1) + const contents = this.getFileContents(item.path) + fs.writeFileSync(fullPath, interpolate(contents, this.chimpConfig)) + log(' | -- ' + item.path.substr(root.length + 1)) + } + }, ) + }) + } +} + +module.exports = Generate \ No newline at end of file diff --git a/src/utils/utils.js b/src/utils/utils.js index 8cba74d..a8da8d5 100644 --- a/src/utils/utils.js +++ b/src/utils/utils.js @@ -1,9 +1,4 @@ const fs = require('fs') -//const path = require('path') - -//const inquirer = require('inquirer') - - function templatize(s, d) { for (let p in d) @@ -38,11 +33,42 @@ const omit = (props, prop) => { } +const cleanParams = function (str) { + return str.replace(/({[A-z0-9_\-]+})/g, '') +} + +const interpolate = function (str, params) { + const keys = Object.keys(params); + // if no string is given we generate one ( params = {foo:'bar', baz:'wth'} will generate {foo}:{baz}) + // it will provide a unique id for models + const stringToDecorate = str || keys.sort().map(v => '{' + v + '}').join(':') + // it will turn path/to/{id} to path/to/123 + const result = keys.reduce((prev, current) => { + const elm_val = params[current] + // skip functions + if (typeof elm_val === 'function') return prev + + if (Array.isArray(elm_val)) { + return prev.replace( + new RegExp('{' + current + '}', 'g'), + '[' + elm_val.map(item => typeof item === 'object' ? interpolate(null, item) : item).join('|') + ']' + ) + } + if (typeof elm_val === 'undefined') return prev + return prev.replace(new RegExp('{' + current + '}', 'g'), elm_val) + }, stringToDecorate) + // if params are missing we remove them + // path/to/123/{anotherId} => path/to/123/ + return cleanParams(result) +} + + module.exports = { getFileContents, writeFileContent, createDirectory, templatize, + interpolate, fileExists, omit } \ No newline at end of file