Skip to content
This repository was archived by the owner on Apr 25, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d3ddba6
chore: change package name to compromise `yarn create` command ⚙️
huyld Nov 14, 2018
67253f5
chore: add dependencies ➕
huyld Nov 14, 2018
0a6a7df
feat(init): add initialization script ✨
huyld Nov 14, 2018
4435fa9
refactor(init): retrieve path of package.json from global node_module…
huyld Nov 15, 2018
8fa9471
refactor(init): move `init` script to dedicated directory ♻️
huyld Nov 15, 2018
f1ae1aa
chore: add dependency to colorize messages ➕
huyld Nov 15, 2018
48d56d3
fix(init): check if to-be-created project dir exists or not empty 🐛
huyld Nov 15, 2018
b19a466
chore: add dependency to validate project name against NPM name rules ➕
huyld Nov 15, 2018
e6aec6d
refactor(init): create dedicated method for validating project path ♻️
huyld Nov 15, 2018
ff034ae
feat(init): parse and validate command arguments with `commander` ✨
huyld Nov 15, 2018
6d1848b
feat(init): validate project name ✨
huyld Nov 15, 2018
5f4b49d
feat(init): add logs and command 🔊
huyld Nov 15, 2018
393f1ba
refactor(init): move `init` script to dedicated directory ♻️
huyld Nov 15, 2018
0bf8268
style(init): colorize error messages and update example message 🎨
huyld Nov 15, 2018
25ef69a
chore(init): add templating assets for to-be-created project 🍱
huyld Nov 15, 2018
2d1260c
feat(init): copy assets to created project ✨
huyld Nov 15, 2018
85194de
refactor(init): add common var for root path of new project ♻️
huyld Nov 16, 2018
7175f38
feat(init): generate `package.json` file for new project ✨
huyld Nov 16, 2018
98a28ce
feat(init);: install dependencies for new project ✨
huyld Nov 16, 2018
030043b
docs(README): update instructions 📝
huyld Nov 16, 2018
4eef972
refactor(init): remove unused import 🔥
huyld Nov 16, 2018
13fef2c
chore: add updated yarn.lock
huyld Nov 16, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
59 changes: 59 additions & 0 deletions bootstrap/assets/README.md
Original file line number Diff line number Diff line change
@@ -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`
219 changes: 219 additions & 0 deletions bootstrap/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
#!/usr/bin/env node
/* eslint-disable no-console */
const commander = require('commander');
const crossSpawn = require('cross-spawn');
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();
var newPrjRootPath; // Root path of the new project
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('<project-directory>')
.usage(`${colors.green('<project-directory>')}`)
.action(name => {
projectName = name;
})
.parse(process.argv);

const handleExit = () => {
console.log('Exiting without error.');
process.exit();
};

const handleError = e => {
console.error(colors.red('ERROR! An error was encountered while executing'));
console.error(e);
console.log(colors.red('Exiting with error.'));
process.exit(1);
};

process.on('SIGINT', handleExit);
process.on('uncaughtException', handleError);

/**
* Validate command arguments
*
*/
function validateArgs() {
if (typeof projectName === 'undefined') {
console.error('Please specify the project directory:');
console.log(` ${colors.cyan(program.name())} ${colors.green('<project-directory>')}`);
console.log();
console.log('For example:');
console.log(` ${colors.cyan(program.name())} ${colors.green('my-gulpset-project')}`);
console.log();
process.exit(1);
}
}

/**
* Print warnings and errors to console
*
* @param {Array<string>} 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 project
* @param {Array<string>} dependencies list of dependencies of `create-gulpset-skeleton`
*/
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);
}
}

/**
* 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);
}
}

/**
* 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`
*
* @param {string} name
*/
function createApp(name) {
const root = path.resolve(name);
const appName = path.basename(root);

checkProjectName(appName, [...Object.keys(packageJson.dependencies), ...Object.keys(packageJson.devDependencies)]);

checkProjectPath(name);

newPrjRootPath = path.join(cwd, name);

fs.ensureDirSync(name);

console.log(`Creating a new gulpset project in ${colors.green(root)}.\n`);

// Copy core files and templates
const filesToCopy = [
'.editorconfig',
'.eslintignore',
'.eslintrc',
'.prettierignore',
'.prettierrc.js',
'.stylelintrc.js',
'aigis_config.yml',
'bitbucket-pipelines.yml',
'gulpfile.js',
'webpack.config.js',
'webpack.config.prod.js',
];
const directoriesToCopy = ['gulpset', 'src'];
const bootstrapAssetsPath = 'bootstrap/assets';

for (let i = 0; i < directoriesToCopy.length; i++) {
const srcDirPath = path.join(pkgRootPath, 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(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(newPrjRootPath, filesToCopy[i]);
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
);

crossSpawn.sync('yarn', ['install', '--cwd', newPrjRootPath], {
stdio: 'inherit',
});

console.log(`Success! Created ${appName} at ${path.join(root)}`);
}

validateArgs();
createApp(projectName);
13 changes: 11 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down Expand Up @@ -58,7 +58,13 @@
},
"dependencies": {
"@fourdigit/sanitize-4d.css": "^7.0.4",
"@fourdigit/scss-utilities": "^1.0.0"
"@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",
"validate-npm-package-name": "^3.0.0"
},
"directories": {
"doc": "docs"
Expand All @@ -69,6 +75,9 @@
"eslint:fix": "yarn eslint --fix",
"deployrsync": "gulp deployrsync"
},
"bin": {
"create-gulpset-skeleton": "bootstrap/index.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/fourdigitdesign/gulpset.git"
Expand Down
Loading