From d3ddba6e8c930cacc1306c333983854f7c9d3b5a Mon Sep 17 00:00:00 2001 From: huyld Date: Wed, 14 Nov 2018 16:09:04 +0700 Subject: [PATCH 01/22] =?UTF-8?q?chore:=20change=20package=20name=20to=20c?= =?UTF-8?q?ompromise=20`yarn=20create`=20command=20=E2=9A=99=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2baa9e8..f771092 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "gulpset-skeleton", + "name": "create-gulpset-skeleton", "version": "3.1.0", "description": "Gulp based project skeleton with modular tasks.", "main": "gulpfile.js", From 67253f5e3e339d4930483adeb52dd7728a451763 Mon Sep 17 00:00:00 2001 From: huyld Date: Wed, 14 Nov 2018 18:44:24 +0700 Subject: [PATCH 02/22] =?UTF-8?q?chore:=20add=20dependencies=20=E2=9E=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index f771092..a3a3625 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,10 @@ }, "dependencies": { "@fourdigit/sanitize-4d.css": "^7.0.4", - "@fourdigit/scss-utilities": "^1.0.0" + "@fourdigit/scss-utilities": "^1.0.0", + "cross-spawn": "^6.0.5", + "fs-extra": "^7.0.1", + "minimist": "^1.2.0" }, "directories": { "doc": "docs" From 0a6a7df45cf0d3c50b3799cc7f2ec1d8881ae6c1 Mon Sep 17 00:00:00 2001 From: huyld Date: Wed, 14 Nov 2018 18:48:35 +0700 Subject: [PATCH 03/22] =?UTF-8?q?feat(init):=20add=20initialization=20scri?= =?UTF-8?q?pt=20=E2=9C=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gulpset/init.js | 94 +++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 3 ++ 2 files changed, 97 insertions(+) create mode 100755 gulpset/init.js diff --git a/gulpset/init.js b/gulpset/init.js new file mode 100755 index 0000000..d484ae5 --- /dev/null +++ b/gulpset/init.js @@ -0,0 +1,94 @@ +#!/usr/bin/env node +/* eslint-disable no-console */ +const cp = require('child_process'); +const path = require('path'); +const colors = require('ansi-colors'); +const fs = require('fs-extra'); + +const cwd = process.cwd(); +const pkgRootPath = path.resolve(__dirname, '..'); + +const packageJson = require('../package.json'); +// eslint-disable-next-line no-magic-numbers +const additionalArgs = require('minimist')(process.argv.slice(2))._; + +const handleExit = () => { + console.log('Exiting without error.'); + process.exit(); +}; + +const handleError = e => { + console.error('ERROR! An error was encountered while executing'); + console.error(e); + console.log('Exiting with error.'); + process.exit(1); +}; + +process.on('SIGINT', handleExit); +process.on('uncaughtException', handleError); + +function validateArgs(args) { + const prjName = args.length ? args[0] : undefined; + if (!prjName) { + console.error('Please specify the project name.'); + process.exit(1); + } +} + +/** + * Validate app name + * Exit with code 1 if name is invalid + * + * @param {string} name name of the app + * @param {Array} dependencies list of dependencies of `create-gulpset-skeleton` + */ +function checkAppName(name, dependencies) { + // TODO: validate package name base on npm naming rules + // https://github.com/npm/cli/blob/latest/doc/files/package.json.md#name +} + +/** + * Create new project `name` using `gulpset-skeleton` + * + * @param {*} name + */ +function createApp(name) { + const root = path.resolve(name); + const appName = path.basename(root); + + checkAppName(appName, [...Object.keys(packageJson.dependencies), ...Object.keys(packageJson.devDependencies)]); + if (fs.existsSync(path.join(cwd, name))) { + console.error(`ERROR! Directory ${name} already exist. Please remove it before proceeding.`); + process.exit(1); + } + fs.ensureDirSync(name); + + // TODO: use `fs.readdirSync` to list files and directories + const filesToCopy = [ + 'README.md', + 'aigis_config.yml', + 'gulpfile.js', + 'package.json', + 'webpack.config.js', + 'webpack.config.prod.js' + ]; + const directoriesToCopy = ['gulpset', 'src']; + + for (let i = 0; i < filesToCopy.length; i++) { + const srcFilePath = path.join(pkgRootPath, filesToCopy[i]); + const dstFilePath = path.join(cwd, name, filesToCopy[i]); + fs.copyFileSync(srcFilePath, dstFilePath); + } + + for (let i = 0; i < directoriesToCopy.length; i++) { + const srcDirPath = path.join(pkgRootPath, directoriesToCopy[i]); + const dstDirPath = path.join(cwd, name, directoriesToCopy[i]); + fs.copySync(srcDirPath, dstDirPath); + } + + // TODO: run `yarn install` +} + +validateArgs(additionalArgs); +const prjName = additionalArgs[0]; +createApp(prjName); diff --git a/package.json b/package.json index a3a3625..90c073e 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,9 @@ "eslint:fix": "yarn eslint --fix", "deployrsync": "gulp deployrsync" }, + "bin": { + "create-gulpset-skeleton": "gulpset/init.js" + }, "repository": { "type": "git", "url": "git+https://github.com/fourdigitdesign/gulpset.git" From 4435fa9e0604c63b047412b4e599d21d89203094 Mon Sep 17 00:00:00 2001 From: huyld Date: Thu, 15 Nov 2018 10:35:22 +0700 Subject: [PATCH 04/22] =?UTF-8?q?refactor(init):=20retrieve=20path=20of=20?= =?UTF-8?q?package.json=20from=20global=20node=5Fmodules=20=E2=99=BB?= =?UTF-8?q?=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gulpset/init.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gulpset/init.js b/gulpset/init.js index d484ae5..70fe296 100755 --- a/gulpset/init.js +++ b/gulpset/init.js @@ -6,9 +6,9 @@ const colors = require('ansi-colors'); const fs = require('fs-extra'); const cwd = process.cwd(); -const pkgRootPath = path.resolve(__dirname, '..'); +const pkgRootPath = path.resolve(__dirname, '../..'); -const packageJson = require('../package.json'); +const packageJson = require(path.join(pkgRootPath, 'package.json')); // eslint-disable-next-line no-magic-numbers const additionalArgs = require('minimist')(process.argv.slice(2))._; From 8fa947106070163e04348122954f5d59f9eb4580 Mon Sep 17 00:00:00 2001 From: huyld Date: Thu, 15 Nov 2018 11:31:53 +0700 Subject: [PATCH 05/22] =?UTF-8?q?refactor(init):=20move=20`init`=20script?= =?UTF-8?q?=20to=20dedicated=20directory=20=E2=99=BB=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gulpset/{init.js => init/index.js} | 0 package.json | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename gulpset/{init.js => init/index.js} (100%) diff --git a/gulpset/init.js b/gulpset/init/index.js similarity index 100% rename from gulpset/init.js rename to gulpset/init/index.js diff --git a/package.json b/package.json index 90c073e..3980be9 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,7 @@ "deployrsync": "gulp deployrsync" }, "bin": { - "create-gulpset-skeleton": "gulpset/init.js" + "create-gulpset-skeleton": "gulpset/init/index.js" }, "repository": { "type": "git", From f1ae1aa9d6ff0a3023fae4bfecc1df48ace63fe2 Mon Sep 17 00:00:00 2001 From: huyld Date: Thu, 15 Nov 2018 11:33:17 +0700 Subject: [PATCH 06/22] =?UTF-8?q?chore:=20add=20dependency=20to=20colorize?= =?UTF-8?q?=20messages=20=E2=9E=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `ansi-color` --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 3980be9..0b5eb03 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "dependencies": { "@fourdigit/sanitize-4d.css": "^7.0.4", "@fourdigit/scss-utilities": "^1.0.0", + "ansi-color": "^0.2.1", "cross-spawn": "^6.0.5", "fs-extra": "^7.0.1", "minimist": "^1.2.0" From 48d56d3adc8a3178edfc3d14ea608dc26faec22f Mon Sep 17 00:00:00 2001 From: huyld Date: Thu, 15 Nov 2018 13:39:54 +0700 Subject: [PATCH 07/22] =?UTF-8?q?fix(init):=20check=20if=20to-be-created?= =?UTF-8?q?=20project=20dir=20exists=20or=20not=20empty=20=F0=9F=90=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gulpset/init/index.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gulpset/init/index.js b/gulpset/init/index.js index 70fe296..a908990 100755 --- a/gulpset/init/index.js +++ b/gulpset/init/index.js @@ -57,8 +57,10 @@ function createApp(name) { const appName = path.basename(root); checkAppName(appName, [...Object.keys(packageJson.dependencies), ...Object.keys(packageJson.devDependencies)]); - if (fs.existsSync(path.join(cwd, name))) { - console.error(`ERROR! Directory ${name} already exist. Please remove it before proceeding.`); + + const pathOfNewPrj = path.join(cwd, name); + if (fs.existsSync(pathOfNewPrj) && fs.readdirSync(pathOfNewPrj).length > 0) { + console.error(`ERROR! Directory ${name} already exist and it's not empty. Please remove it before proceeding.`); process.exit(1); } fs.ensureDirSync(name); From b19a4668a4bdeebe27e332dde4390cf939efbf02 Mon Sep 17 00:00:00 2001 From: huyld Date: Thu, 15 Nov 2018 13:56:10 +0700 Subject: [PATCH 08/22] =?UTF-8?q?chore:=20add=20dependency=20to=20validate?= =?UTF-8?q?=20project=20name=20against=20NPM=20name=20rules=20=E2=9E=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `validate-npm-package-name` --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 0b5eb03..d6f17c6 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,8 @@ "ansi-color": "^0.2.1", "cross-spawn": "^6.0.5", "fs-extra": "^7.0.1", - "minimist": "^1.2.0" + "minimist": "^1.2.0", + "validate-npm-package-name": "^3.0.0" }, "directories": { "doc": "docs" From e6aec6dc6915456610d3f8c0c8d5a9fce90ec7f1 Mon Sep 17 00:00:00 2001 From: huyld Date: Thu, 15 Nov 2018 14:27:40 +0700 Subject: [PATCH 09/22] =?UTF-8?q?refactor(init):=20create=20dedicated=20me?= =?UTF-8?q?thod=20for=20validating=20project=20path=20=E2=99=BB=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gulpset/init/index.js | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/gulpset/init/index.js b/gulpset/init/index.js index a908990..9fdb04a 100755 --- a/gulpset/init/index.js +++ b/gulpset/init/index.js @@ -47,6 +47,21 @@ function checkAppName(name, dependencies) { // https://github.com/npm/cli/blob/latest/doc/files/package.json.md#name } +/** + * Validate the path of the to-be-created-project + * + * @param {string} projectName + */ +function checkProjectPath(projectName) { + const pathOfNewPrj = path.join(cwd, projectName); + if (fs.existsSync(pathOfNewPrj) && fs.readdirSync(pathOfNewPrj).length > 0) { + console.error( + `ERROR! Directory ${projectName} already exist and it's not empty. Please remove it before proceeding.` + ); + process.exit(1); + } +} + /** * Create new project `name` using `gulpset-skeleton` * @@ -58,11 +73,8 @@ function createApp(name) { checkAppName(appName, [...Object.keys(packageJson.dependencies), ...Object.keys(packageJson.devDependencies)]); - const pathOfNewPrj = path.join(cwd, name); - if (fs.existsSync(pathOfNewPrj) && fs.readdirSync(pathOfNewPrj).length > 0) { - console.error(`ERROR! Directory ${name} already exist and it's not empty. Please remove it before proceeding.`); - process.exit(1); - } + checkProjectPath(name); + fs.ensureDirSync(name); // TODO: use `fs.readdirSync` to list files and directories From ff034ae99ebcf5b50a05e66729589f0760bc44f9 Mon Sep 17 00:00:00 2001 From: huyld Date: Thu, 15 Nov 2018 15:56:01 +0700 Subject: [PATCH 10/22] =?UTF-8?q?feat(init):=20parse=20and=20validate=20co?= =?UTF-8?q?mmand=20arguments=20with=20`commander`=20=E2=9C=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gulpset/init/index.js | 33 ++++++++++++++++++++++++--------- package.json | 1 + 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/gulpset/init/index.js b/gulpset/init/index.js index 9fdb04a..bfb9dab 100755 --- a/gulpset/init/index.js +++ b/gulpset/init/index.js @@ -1,5 +1,6 @@ #!/usr/bin/env node /* eslint-disable no-console */ +const commander = require('commander'); const cp = require('child_process'); const path = require('path'); const colors = require('ansi-colors'); @@ -7,10 +8,17 @@ const fs = require('fs-extra'); const cwd = process.cwd(); const pkgRootPath = path.resolve(__dirname, '../..'); +let projectName; const packageJson = require(path.join(pkgRootPath, 'package.json')); -// eslint-disable-next-line no-magic-numbers -const additionalArgs = require('minimist')(process.argv.slice(2))._; +const program = new commander.Command(packageJson.name) + .version(packageJson.version) + .arguments('') + .usage(`${colors.green('')}`) + .action(name => { + projectName = name; + }) + .parse(process.argv); const handleExit = () => { console.log('Exiting without error.'); @@ -27,10 +35,18 @@ const handleError = e => { process.on('SIGINT', handleExit); process.on('uncaughtException', handleError); -function validateArgs(args) { - const prjName = args.length ? args[0] : undefined; - if (!prjName) { - console.error('Please specify the project name.'); +/** + * Validate command arguments + * + */ +function validateArgs() { + if (typeof projectName === 'undefined') { + console.error('Please specify the project directory:'); + console.log(` ${colors.cyan(program.name())} ${colors.green('')}`); + console.log(); + console.log('For example:'); + console.log(` ${colors.cyan(program.name())} ${colors.green('my-react-app')}`); + console.log(); process.exit(1); } } @@ -103,6 +119,5 @@ function createApp(name) { // TODO: run `yarn install` } -validateArgs(additionalArgs); -const prjName = additionalArgs[0]; -createApp(prjName); +validateArgs(); +createApp(projectName); diff --git a/package.json b/package.json index d6f17c6..df8282e 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "@fourdigit/sanitize-4d.css": "^7.0.4", "@fourdigit/scss-utilities": "^1.0.0", "ansi-color": "^0.2.1", + "commander": "^2.19.0", "cross-spawn": "^6.0.5", "fs-extra": "^7.0.1", "minimist": "^1.2.0", From 6d1848b31c6b26ec8ae17e377f6f512a193403f5 Mon Sep 17 00:00:00 2001 From: huyld Date: Thu, 15 Nov 2018 16:01:43 +0700 Subject: [PATCH 11/22] =?UTF-8?q?feat(init):=20validate=20project=20name?= =?UTF-8?q?=20=E2=9C=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gulpset/init/index.js | 46 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/gulpset/init/index.js b/gulpset/init/index.js index bfb9dab..752849a 100755 --- a/gulpset/init/index.js +++ b/gulpset/init/index.js @@ -5,6 +5,7 @@ const cp = require('child_process'); const path = require('path'); const colors = require('ansi-colors'); const fs = require('fs-extra'); +const validateProjectName = require('validate-npm-package-name'); const cwd = process.cwd(); const pkgRootPath = path.resolve(__dirname, '../..'); @@ -52,15 +53,50 @@ function validateArgs() { } /** - * Validate app name + * Print warnings and errors to console + * + * @param {Array} results array of warning and error messages + */ +function printValidationResults(results) { + if (typeof results !== 'undefined') { + results.forEach(error => { + console.error(colors.red(` * ${error}`)); + }); + } +} + +/** + * Validate project name * Exit with code 1 if name is invalid * - * @param {string} name name of the app + * @param {string} name name of the project * @param {Array} dependencies list of dependencies of `create-gulpset-skeleton` */ -function checkAppName(name, dependencies) { - // TODO: validate package name base on npm naming rules +function checkProjectName(name, dependencies) { + // Validate project name against NPM naming restriction // https://github.com/npm/cli/blob/latest/doc/files/package.json.md#name + const validationResult = validateProjectName(name); + if (!validationResult.validForNewPackages) { + console.error(`Could not create a project called ${colors.red(`"${name}"`)} because of npm naming restrictions:`); + printValidationResults(validationResult.errors); + printValidationResults(validationResult.warnings); + process.exit(1); + } + + // Check if project name conflicts with existing NPM packages + if (dependencies.indexOf(name) >= 0) { + console.error( + colors.red(`We cannot create a project called `) + + colors.green(name) + + colors.red( + ` because a dependency with the same name exists.\n` + + `Due to the way npm works, the following names are not allowed:\n\n` + ) + + colors.cyan(dependencies.map(depName => ` ${depName}`).join('\n')) + + colors.red('\n\nPlease choose a different project name.') + ); + process.exit(1); + } } /** @@ -87,7 +123,7 @@ function createApp(name) { const root = path.resolve(name); const appName = path.basename(root); - checkAppName(appName, [...Object.keys(packageJson.dependencies), ...Object.keys(packageJson.devDependencies)]); + checkProjectName(appName, [...Object.keys(packageJson.dependencies), ...Object.keys(packageJson.devDependencies)]); checkProjectPath(name); From 5f4b49d2478e709bea548c03d4e33020ea8744c5 Mon Sep 17 00:00:00 2001 From: huyld Date: Thu, 15 Nov 2018 16:46:13 +0700 Subject: [PATCH 12/22] =?UTF-8?q?feat(init):=20add=20logs=20and=20command?= =?UTF-8?q?=20=F0=9F=94=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gulpset/init/index.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gulpset/init/index.js b/gulpset/init/index.js index 752849a..412ff36 100755 --- a/gulpset/init/index.js +++ b/gulpset/init/index.js @@ -12,6 +12,8 @@ const pkgRootPath = path.resolve(__dirname, '../..'); let projectName; const packageJson = require(path.join(pkgRootPath, 'package.json')); + +// Parse command const program = new commander.Command(packageJson.name) .version(packageJson.version) .arguments('') @@ -117,7 +119,7 @@ function checkProjectPath(projectName) { /** * Create new project `name` using `gulpset-skeleton` * - * @param {*} name + * @param {string} name */ function createApp(name) { const root = path.resolve(name); @@ -129,6 +131,8 @@ function createApp(name) { fs.ensureDirSync(name); + console.log(`Creating a new gulpset project in ${colors.green(root)}.\n`); + // TODO: use `fs.readdirSync` to list files and directories const filesToCopy = [ 'README.md', @@ -152,6 +156,7 @@ function createApp(name) { fs.copySync(srcDirPath, dstDirPath); } + console.log(`Success! Created ${appName} at ${path.join(root)}`); // TODO: run `yarn install` } From 393f1ba58f1ad4f542733f1a5ce8aaab8d35a953 Mon Sep 17 00:00:00 2001 From: huyld Date: Thu, 15 Nov 2018 17:35:04 +0700 Subject: [PATCH 13/22] =?UTF-8?q?refactor(init):=20move=20`init`=20script?= =?UTF-8?q?=20to=20dedicated=20directory=20=E2=99=BB=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Again 🤦 --- {gulpset/init => bootstrap}/index.js | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename {gulpset/init => bootstrap}/index.js (98%) diff --git a/gulpset/init/index.js b/bootstrap/index.js similarity index 98% rename from gulpset/init/index.js rename to bootstrap/index.js index 412ff36..183c999 100755 --- a/gulpset/init/index.js +++ b/bootstrap/index.js @@ -8,7 +8,7 @@ const fs = require('fs-extra'); const validateProjectName = require('validate-npm-package-name'); const cwd = process.cwd(); -const pkgRootPath = path.resolve(__dirname, '../..'); +const pkgRootPath = path.resolve(__dirname, '..'); let projectName; const packageJson = require(path.join(pkgRootPath, 'package.json')); diff --git a/package.json b/package.json index df8282e..cc0f1d3 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "deployrsync": "gulp deployrsync" }, "bin": { - "create-gulpset-skeleton": "gulpset/init/index.js" + "create-gulpset-skeleton": "bootstrap/index.js" }, "repository": { "type": "git", From 0bf8268a7a0ec5c19129ea2f23481398baecbd3b Mon Sep 17 00:00:00 2001 From: huyld Date: Thu, 15 Nov 2018 17:58:03 +0700 Subject: [PATCH 14/22] =?UTF-8?q?style(init):=20colorize=20error=20message?= =?UTF-8?q?s=20and=20update=20example=20message=20=F0=9F=8E=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bootstrap/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bootstrap/index.js b/bootstrap/index.js index 183c999..45f8fbd 100755 --- a/bootstrap/index.js +++ b/bootstrap/index.js @@ -29,9 +29,9 @@ const handleExit = () => { }; const handleError = e => { - console.error('ERROR! An error was encountered while executing'); + console.error(colors.red('ERROR! An error was encountered while executing')); console.error(e); - console.log('Exiting with error.'); + console.log(colors.red('Exiting with error.')); process.exit(1); }; @@ -48,7 +48,7 @@ function validateArgs() { console.log(` ${colors.cyan(program.name())} ${colors.green('')}`); console.log(); console.log('For example:'); - console.log(` ${colors.cyan(program.name())} ${colors.green('my-react-app')}`); + console.log(` ${colors.cyan(program.name())} ${colors.green('my-gulpset-project')}`); console.log(); process.exit(1); } From 25ef69ae94b5ebb5c98e147a3143e6a570b2b044 Mon Sep 17 00:00:00 2001 From: huyld Date: Thu, 15 Nov 2018 18:27:12 +0700 Subject: [PATCH 15/22] =?UTF-8?q?chore(init):=20add=20templating=20assets?= =?UTF-8?q?=20for=20to-be-created=20project=20=F0=9F=8D=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bootstrap/assets/README.md | 59 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 bootstrap/assets/README.md diff --git a/bootstrap/assets/README.md b/bootstrap/assets/README.md new file mode 100644 index 0000000..d003d12 --- /dev/null +++ b/bootstrap/assets/README.md @@ -0,0 +1,59 @@ +This project was bootstrapped with [@fourdigit/gulpset](https://github.com/fourdigit/gulpset). + +## To generate production build(minified) + +1. `yarn build:prod` + +## each tasks + +### js settings + +- see `/webpack.config.js`, `/webpack.config.prod.js` & `/gulpset/tasks/scripts/index.js` + +#### When you use ES5 + +1. `/.eslintrc`: modify `@fourdigit/eslint-config-fourdigit/esnext` => `@fourdigit/eslint-config-fourdigit/base` +2. modify `copy` task (add `js` ext) +3. remove `scripts` task from `gulpfile.js` + +#### development & production + +Gulpset has 2 webpack settings & corresponding 2 gulp tasks. + +- webpack-watch + + - ./webpacck.config.js + - `mode: development` + - `process.env.NODE_ENV === 'development'` + +- webpack + - webpack.config.prod.js + - `mode: production` => webpack 4 automatically optimize your code for production. + - `process.env.NODE_ENV === 'production'` => you can use this environmental variable for environmental settings e.g. API key, endpoints. + +### scss settings + +- see `/gulpset/tasks/scss/index.js` +- some utility scss libs are loaded on `/src/assets/css/app.scss` + +### ejs settings + +- see `/gulpset/tasks/ejs/index.js` +- some utility functions are included here `/src/_utils.ejs` + +### deployrsync settings + +1. Open `/gulpset/tasks/deployrsync/index.js` +2. Set target user:hostname to `gulpset.confs.deployrsync.options.hostname` +3. Add private key of target server. e.g. `ssh-add ~/.ssh/xxxxxxxx_rsa` +4. Run `gulp deployrsync` + +#### Deploy via bitbucket-pipelines + +1. Create private key for target server. +2. Encode it into base 64. e.g `$ base64 gulpset_rsa| pbcopy` +3. On bitbucket web screen, enter repository settings +4. Go Pipelines settings > Enable Pipelines +5. Environment variables > make and set `PRIVATE_KEY` (make sure the to enable checkbox of "encrypt") and `TARGET_HOST` +6. Built files by newly pushed `develop` branch will be deployed to `TARGET_HOST` +7. if you want to use other branches, rewrite `branches` section on `bitbucket-pipelines.yml` From 2d1260c15a5957480f0399949292a9af1fea1b72 Mon Sep 17 00:00:00 2001 From: huyld Date: Thu, 15 Nov 2018 18:30:11 +0700 Subject: [PATCH 16/22] =?UTF-8?q?feat(init):=20copy=20assets=20to=20create?= =?UTF-8?q?d=20project=20=E2=9C=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bootstrap/index.js | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/bootstrap/index.js b/bootstrap/index.js index 45f8fbd..1155795 100755 --- a/bootstrap/index.js +++ b/bootstrap/index.js @@ -133,22 +133,23 @@ function createApp(name) { console.log(`Creating a new gulpset project in ${colors.green(root)}.\n`); - // TODO: use `fs.readdirSync` to list files and directories + // TODO: generate `package.json` file for new project with devDependencies copied from gulpset-skeleton package.json const filesToCopy = [ - 'README.md', + '.editorconfig', + '.eslintignore', + '.eslintrc', + '.prettierignore', + '.prettierrc.js', + '.stylelintrc.js', 'aigis_config.yml', + 'bitbucket-pipelines.yml', 'gulpfile.js', 'package.json', 'webpack.config.js', - 'webpack.config.prod.js' + 'webpack.config.prod.js', ]; const directoriesToCopy = ['gulpset', 'src']; - - for (let i = 0; i < filesToCopy.length; i++) { - const srcFilePath = path.join(pkgRootPath, filesToCopy[i]); - const dstFilePath = path.join(cwd, name, filesToCopy[i]); - fs.copyFileSync(srcFilePath, dstFilePath); - } + const bootstrapAssetsPath = 'bootstrap/assets'; for (let i = 0; i < directoriesToCopy.length; i++) { const srcDirPath = path.join(pkgRootPath, directoriesToCopy[i]); @@ -156,6 +157,19 @@ function createApp(name) { fs.copySync(srcDirPath, dstDirPath); } + // Copy files to root directory of created project + fs.readdirSync(path.join(pkgRootPath, bootstrapAssetsPath)).forEach(filename => { + const srcDirPath = path.join(pkgRootPath, bootstrapAssetsPath, filename); + const dstDirPath = path.join(cwd, name, filename); + fs.copySync(srcDirPath, dstDirPath); + }); + + for (let i = 0; i < filesToCopy.length; i++) { + const srcFilePath = path.join(pkgRootPath, filesToCopy[i]); + const dstFilePath = path.join(cwd, name, filesToCopy[i]); + fs.copyFileSync(srcFilePath, dstFilePath); + } + console.log(`Success! Created ${appName} at ${path.join(root)}`); // TODO: run `yarn install` } From 85194de94b955f37a810ba13efd65d2e5fb5d36d Mon Sep 17 00:00:00 2001 From: huyld Date: Fri, 16 Nov 2018 11:07:50 +0700 Subject: [PATCH 17/22] =?UTF-8?q?refactor(init):=20add=20common=20var=20fo?= =?UTF-8?q?r=20root=20path=20of=20new=20project=20=E2=99=BB=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bootstrap/index.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/bootstrap/index.js b/bootstrap/index.js index 1155795..62dad78 100755 --- a/bootstrap/index.js +++ b/bootstrap/index.js @@ -8,6 +8,7 @@ const fs = require('fs-extra'); const validateProjectName = require('validate-npm-package-name'); const cwd = process.cwd(); +var newPrjRootPath; // Root path of the new project const pkgRootPath = path.resolve(__dirname, '..'); let projectName; @@ -129,6 +130,8 @@ function createApp(name) { checkProjectPath(name); + newPrjRootPath = path.join(cwd, name); + fs.ensureDirSync(name); console.log(`Creating a new gulpset project in ${colors.green(root)}.\n`); @@ -153,20 +156,20 @@ function createApp(name) { for (let i = 0; i < directoriesToCopy.length; i++) { const srcDirPath = path.join(pkgRootPath, directoriesToCopy[i]); - const dstDirPath = path.join(cwd, name, directoriesToCopy[i]); + const dstDirPath = path.join(newPrjRootPath, directoriesToCopy[i]); fs.copySync(srcDirPath, dstDirPath); } // Copy files to root directory of created project fs.readdirSync(path.join(pkgRootPath, bootstrapAssetsPath)).forEach(filename => { const srcDirPath = path.join(pkgRootPath, bootstrapAssetsPath, filename); - const dstDirPath = path.join(cwd, name, filename); + const dstDirPath = path.join(newPrjRootPath, filename); fs.copySync(srcDirPath, dstDirPath); }); for (let i = 0; i < filesToCopy.length; i++) { const srcFilePath = path.join(pkgRootPath, filesToCopy[i]); - const dstFilePath = path.join(cwd, name, filesToCopy[i]); + const dstFilePath = path.join(newPrjRootPath, filesToCopy[i]); fs.copyFileSync(srcFilePath, dstFilePath); } From 7175f38f9a4f4babc4124674c0cdac617358062f Mon Sep 17 00:00:00 2001 From: huyld Date: Fri, 16 Nov 2018 11:10:52 +0700 Subject: [PATCH 18/22] =?UTF-8?q?feat(init):=20generate=20`package.json`?= =?UTF-8?q?=20file=20for=20new=20project=20=E2=9C=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bootstrap/index.js | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/bootstrap/index.js b/bootstrap/index.js index 62dad78..4be7fef 100755 --- a/bootstrap/index.js +++ b/bootstrap/index.js @@ -5,6 +5,7 @@ const cp = require('child_process'); const path = require('path'); const colors = require('ansi-colors'); const fs = require('fs-extra'); +const os = require('os'); const validateProjectName = require('validate-npm-package-name'); const cwd = process.cwd(); @@ -117,6 +118,34 @@ function checkProjectPath(projectName) { } } +/** + * Generate the `package.json` file for the new project + * + * @param {string} prjName name of the new project + * @returns new package.json object + */ +function generatePackageJson(prjName) { + + let newPkgJson = {}; + const dependencies = [ + '@fourdigit/sanitize-4d.css', + '@fourdigit/scss-utilities', + ]; + + newPkgJson.name = prjName; + newPkgJson.version = '0.1.0'; + newPkgJson.description = ''; + newPkgJson.main = packageJson.main; + newPkgJson.scripts = packageJson.scripts; + newPkgJson.devDependencies = packageJson.devDependencies; + newPkgJson.dependencies = {}; + dependencies.forEach(depName => { + newPkgJson.dependencies[depName] = packageJson.dependencies[depName]; + }); + + return newPkgJson; +} + /** * Create new project `name` using `gulpset-skeleton` * @@ -136,7 +165,7 @@ function createApp(name) { console.log(`Creating a new gulpset project in ${colors.green(root)}.\n`); - // TODO: generate `package.json` file for new project with devDependencies copied from gulpset-skeleton package.json + // Copy core files and templates const filesToCopy = [ '.editorconfig', '.eslintignore', @@ -147,7 +176,6 @@ function createApp(name) { 'aigis_config.yml', 'bitbucket-pipelines.yml', 'gulpfile.js', - 'package.json', 'webpack.config.js', 'webpack.config.prod.js', ]; @@ -173,6 +201,13 @@ function createApp(name) { fs.copyFileSync(srcFilePath, dstFilePath); } + // Create new `package.json` + const newPkgJson = generatePackageJson(name); + fs.writeFileSync( + path.join(newPrjRootPath, 'package.json'), + JSON.stringify(newPkgJson, null, 2) + os.EOL + ); + console.log(`Success! Created ${appName} at ${path.join(root)}`); // TODO: run `yarn install` } From 98a28ce867b6a13c4650ae924509ff28acb80ee0 Mon Sep 17 00:00:00 2001 From: huyld Date: Fri, 16 Nov 2018 13:34:58 +0700 Subject: [PATCH 19/22] =?UTF-8?q?feat(init);:=20install=20dependencies=20f?= =?UTF-8?q?or=20new=20project=20=E2=9C=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bootstrap/index.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bootstrap/index.js b/bootstrap/index.js index 4be7fef..3ca56f8 100755 --- a/bootstrap/index.js +++ b/bootstrap/index.js @@ -2,6 +2,7 @@ /* eslint-disable no-console */ const commander = require('commander'); const cp = require('child_process'); +const crossSpawn = require('cross-spawn'); const path = require('path'); const colors = require('ansi-colors'); const fs = require('fs-extra'); @@ -208,8 +209,11 @@ function createApp(name) { JSON.stringify(newPkgJson, null, 2) + os.EOL ); + crossSpawn.sync('yarn', ['install', '--cwd', newPrjRootPath], { + stdio: 'inherit', + }); + console.log(`Success! Created ${appName} at ${path.join(root)}`); - // TODO: run `yarn install` } validateArgs(); From 030043b92209bd0344c25e9e482960011ce7dd0f Mon Sep 17 00:00:00 2001 From: huyld Date: Fri, 16 Nov 2018 15:43:29 +0700 Subject: [PATCH 20/22] =?UTF-8?q?docs(README):=20update=20instructions=20?= =?UTF-8?q?=F0=9F=93=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instructions to create new project and start developing. --- README.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6459612..b269607 100644 --- a/README.md +++ b/README.md @@ -15,11 +15,17 @@ Gulp based project skeleton with modular tasks. - browser-sync (dev server) - rsync (deploy) +## creating project +``` +yarn global add create-gulpset-skeleton +create-gulpset-skeleton my-app +``` + ## starting development -1. download this repo from [releases](https://github.com/fourdigit/gulpset/releases) -2. `yarn` -3. `yarn start` +``` +yarn start +``` ## want to generate production build(minified) From 4eef972025773856e36a1ceadc6804cb4cd71183 Mon Sep 17 00:00:00 2001 From: huyld Date: Fri, 16 Nov 2018 15:47:32 +0700 Subject: [PATCH 21/22] =?UTF-8?q?refactor(init):=20remove=20unused=20impor?= =?UTF-8?q?t=20=F0=9F=94=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bootstrap/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/bootstrap/index.js b/bootstrap/index.js index 3ca56f8..0f796e7 100755 --- a/bootstrap/index.js +++ b/bootstrap/index.js @@ -1,7 +1,6 @@ #!/usr/bin/env node /* eslint-disable no-console */ const commander = require('commander'); -const cp = require('child_process'); const crossSpawn = require('cross-spawn'); const path = require('path'); const colors = require('ansi-colors'); From 13fef2cc3d0d05919e009a0d6a38dba30778af4b Mon Sep 17 00:00:00 2001 From: huyld Date: Fri, 16 Nov 2018 16:01:10 +0700 Subject: [PATCH 22/22] chore: add updated yarn.lock --- yarn.lock | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/yarn.lock b/yarn.lock index 2e76a51..a0982c0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -952,6 +952,11 @@ ansi-align@^2.0.0: dependencies: string-width "^2.0.0" +ansi-color@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/ansi-color/-/ansi-color-0.2.1.tgz#3e75c037475217544ed763a8db5709fa9ae5bf9a" + integrity sha1-PnXAN0dSF1RO12Oo21cJ+prlv5o= + ansi-colors@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" @@ -1899,6 +1904,11 @@ builtin-status-codes@^3.0.0: resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= +builtins@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" + integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og= + bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" @@ -2447,6 +2457,11 @@ commander@2.8.x, commander@~2.8.1: dependencies: graceful-readlink ">= 1.0.0" +commander@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== + commander@~2.13.0: version "2.13.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" @@ -4515,6 +4530,15 @@ fs-extra@^1.0.0: jsonfile "^2.1.0" klaw "^1.0.0" +fs-extra@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + fs-minipass@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" @@ -6429,6 +6453,13 @@ jsonfile@^3.0.0: optionalDependencies: graceful-fs "^4.1.6" +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + jsonify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" @@ -11813,6 +11844,13 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" +validate-npm-package-name@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" + integrity sha1-X6kS2B630MdK/BQN5zF/DKffQ34= + dependencies: + builtins "^1.0.3" + value-or-function@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/value-or-function/-/value-or-function-3.0.0.tgz#1c243a50b595c1be54a754bfece8563b9ff8d813"