diff --git a/_SETUP.md b/_SETUP.md index 5f6e59814..a663b37ef 100644 --- a/_SETUP.md +++ b/_SETUP.md @@ -1,6 +1,16 @@ # Setup - Setup your local webpack repository +At webpack we use `yarn` to execute commands. + +If you already have `yarn` installed, do: `yarn setup`. This will complete all required steps. + +If not, do: `npm run setup`, the setup will also install `yarn` for you. + +That's all. + +## Setup manually + +Setup your local webpack repository ```bash git clone https://github.com/webpack/webpack.git @@ -15,4 +25,4 @@ To run the entire test suite use: ```bash yarn test -``` \ No newline at end of file +``` diff --git a/package.json b/package.json index fa81cb2e7..4e39f66e7 100644 --- a/package.json +++ b/package.json @@ -88,33 +88,34 @@ "schemas/" ], "scripts": { + "setup": "node ./setup/setup.js", "test": "mocha test/*.test.js test/*.unittest.js --max-old-space-size=4096 --harmony --trace-deprecation", "test:integration": "mocha test/*.test.js --max-old-space-size=4096 --harmony --trace-deprecation", "test:unit": "mocha test/*.unittest.js --max-old-space-size=4096 --harmony --trace-deprecation", - "travis:integration": "npm run cover:init && npm run cover:integration && npm run cover:report-min", - "travis:unit": "npm run cover:init && npm run cover:unit && npm run cover:report-min", - "travis:lint": "npm run lint-files", - "travis:benchmark": "npm run benchmark", - "appveyor:integration": "npm run cover:init && npm run cover:integration && npm run cover:report-min", - "appveyor:unit": "npm run cover:init && npm run cover:unit && npm run cover:report-min", - "appveyor:benchmark": "npm run benchmark", + "travis:integration": "yarn cover:init && yarn cover:integration && yarn cover:report-min", + "travis:unit": "yarn cover:init && yarn cover:unit && yarn cover:report-min", + "travis:lint": "yarn lint", + "travis:benchmark": "yarn benchmark", + "appveyor:integration": "yarn cover:init && yarn cover:integration && yarn cover:report-min", + "appveyor:unit": "yarn cover:init && yarn cover:unit && yarn cover:report-min", + "appveyor:benchmark": "yarn benchmark", "circleci:test": "node node_modules/mocha/bin/mocha --max-old-space-size=4096 --harmony --trace-deprecation test/*.test.js test/*.unittest.js", - "circleci:lint": "npm run lint-files", + "circleci:lint": "yarn lint", "build:examples": "cd examples && node buildAll.js", - "pretest": "npm run lint-files", - "lint-files": "npm run lint && npm run schema-lint", - "lint": "eslint lib bin hot buildin \"test/*.js\" \"test/**/webpack.config.js\" \"examples/**/webpack.config.js\" \"schemas/**/*.js\"", - "fix": "npm run lint -- --fix", - "pretty-files": "prettier \"lib/**/*.js\" \"bin/*.js\" \"hot/*.js\" \"buildin/*.js\" \"test/*.js\" \"test/**/webpack.config.js\" \"examples/**/webpack.config.js\" \"schemas/**/*.js\" --write", + "pretest": "yarn lint", + "prelint": "yarn setup", + "lint": "yarn code-lint && yarn schema-lint", + "code-lint": "eslint setup lib bin hot buildin \"test/*.js\" \"test/**/webpack.config.js\" \"examples/**/webpack.config.js\" \"schemas/**/*.js\"", + "fix": "yarn code-lint --fix", + "pretty": "prettier \"setup/**/*.js\" \"lib/**/*.js\" \"bin/*.js\" \"hot/*.js\" \"buildin/*.js\" \"test/*.js\" \"test/**/webpack.config.js\" \"examples/**/webpack.config.js\" \"schemas/**/*.js\" --write", "schema-lint": "mocha test/*.lint.js --opts test/lint-mocha.opts", "benchmark": "mocha --max-old-space-size=4096 --harmony --trace-deprecation test/*.benchmark.js -R spec", - "cover": "npm run cover:init && npm run cover:all && npm run cover:report", + "cover": "yarn cover:init && yarn cover:all && yarn cover:report", "cover:init": "rimraf coverage", "cover:all": "node --max-old-space-size=4096 --harmony --trace-deprecation ./node_modules/istanbul/lib/cli.js cover --report none node_modules/mocha/bin/_mocha -- test/*.test.js test/*.unittest.js", "cover:integration": "node --max-old-space-size=4096 --harmony --trace-deprecation ./node_modules/istanbul/lib/cli.js cover --report none node_modules/mocha/bin/_mocha -- test/*.test.js", "cover:unit": "node --max-old-space-size=4096 --harmony --trace-deprecation ./node_modules/istanbul/lib/cli.js cover --report none node_modules/mocha/bin/_mocha -- test/*.unittest.js", "cover:report": "istanbul report", - "cover:report-min": "istanbul report --report lcovonly", - "publish-patch": "npm run lint && mocha && npm version patch && git push && git push --tags && npm publish" + "cover:report-min": "istanbul report --report lcovonly" } } diff --git a/setup/setup.js b/setup/setup.js new file mode 100644 index 000000000..ad774bc11 --- /dev/null +++ b/setup/setup.js @@ -0,0 +1,108 @@ +"use strict"; + +const fs = require("fs"); +const path = require("path"); +const root = process.cwd(); +const node_modulesFolder = path.resolve(root, "node_modules"); +const webpackDependencyFolder = path.resolve(root, "node_modules/webpack"); + +function setup() { + return checkSymlinkExistsAsync() + .then(hasSymlink => { + if (!hasSymlink) { + return ensureYarnInstalledAsync().then(() => { + return runSetupAsync().then(() => { + return checkSymlinkExistsAsync(); + }); + }); + } + }) + .then(message => { + process.exitCode = 0; + }) + .catch(e => { + console.error(e); + process.exitCode = 1; + }); +} + +function runSetupAsync() { + return exec("yarn", ["install"], "Install dependencies") + .then(() => exec("yarn", ["link"], "Create webpack symlink")) + .then(() => exec("yarn", ["link", "webpack"], "Link webpack into itself")); +} + +function checkSymlinkExistsAsync() { + return new Promise((resolve, reject) => { + if ( + fs.existsSync(node_modulesFolder) && + fs.existsSync(webpackDependencyFolder) && + fs.lstatSync(webpackDependencyFolder).isSymbolicLink() + ) { + resolve(true); + } else { + resolve(false); + } + }); +} + +function ensureYarnInstalledAsync() { + var semverPattern = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\+[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*)?$/; + return execGetOutput("yarn", ["-v"], "Check yarn version") + .then(stdout => semverPattern.test(stdout), () => false) + .then(hasYarn => hasYarn || installYarnAsync()); +} + +function installYarnAsync() { + return exec("npm", ["install", "-g", "yarn"], "Install yarn"); +} + +function exec(command, args, description) { + console.log(`Setup: ${description}`); + return new Promise((resolve, reject) => { + let cp = require("child_process").spawn(command, args, { + cwd: root, + stdio: "inherit", + shell: true + }); + cp.on("error", error => { + reject(new Error(`${description} failed with ${error}`)); + }); + cp.on("exit", exitCode => { + if (exitCode) { + reject(`${description} failed with exitcode ${exitCode}`); + } else { + resolve(); + } + }); + }); +} + +function execGetOutput(command, args, description) { + console.log(`Setup: ${description}`); + return new Promise((resolve, reject) => { + let cp = require("child_process").spawn(command, args, { + cwd: root, + stdio: [process.stdin, "pipe", process.stderr], + shell: true + }); + cp.on("error", error => { + reject(new Error(`${description} failed with ${error}`)); + }); + cp.on("exit", exitCode => { + if (exitCode) { + reject(`${description} failed with exitcode ${exitCode}`); + } else { + resolve( + Buffer.concat(buffers) + .toString("utf-8") + .trim() + ); + } + }); + const buffers = []; + cp.stdout.on("data", data => buffers.push(data)); + }); +} + +setup(); diff --git a/test/README.md b/test/README.md index 1b0c1c04b..05b25ccce 100644 --- a/test/README.md +++ b/test/README.md @@ -5,8 +5,7 @@ But don't give up hope!!! Although our tests may appear complex and overwhelming ## tl;dr * Clone repo -* install and link deps - * `yarn install && yarn link && yarn link webpack` +* Run tests (this automatically runs the setup) * `yarn test` * To run an individual suite: (recommended during development for easier isolated diffs)