diff --git a/.autod.conf.js b/.autod.conf.js deleted file mode 100644 index 1ee8b82..0000000 --- a/.autod.conf.js +++ /dev/null @@ -1,30 +0,0 @@ -'use strict'; - -module.exports = { - write: true, - prefix: '^', - devprefix: '^', - exclude: [ - 'test/fixtures', - ], - dep: [ - 'egg-init-config', - ], - devdep: [ - 'autod', - 'egg-bin', - 'egg-ci', - 'eslint', - 'eslint-config-egg' - ], - semver: [ - 'egg-bin@1', - 'inquirer@3', - 'eslint@4', - 'eslint-config-egg@6', - 'mem-fs-editor@4', - 'yargs@11', - 'proxy-agent@2', - ], - registry: 'https://r.cnpmjs.org', -}; diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml deleted file mode 100644 index 9096c4a..0000000 --- a/.github/workflows/codeql.yml +++ /dev/null @@ -1,76 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "CodeQL" - -on: - push: - branches: [ "master" ] - pull_request: - # The branches below must be a subset of the branches above - branches: [ "master" ] - schedule: - - cron: '32 2 * * 4' - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: [ 'javascript' ] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] - # Use only 'java' to analyze code written in Java, Kotlin or both - # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both - # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - - # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality - - - # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v2 - - # ℹ️ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - # If the Autobuild fails above, remove it and uncomment the following three lines. - # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. - - # - run: | - # echo "Run, Build Application using script" - # ./location_of_script_within_repo/buildscript.sh - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - with: - category: "/language:${{matrix.language}}" diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 470fef1..a675fe7 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -1,46 +1,16 @@ -# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node -# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions - -name: Node.js CI +name: CI on: push: - branches: - - main - - master + branches: [ master ] + pull_request: - branches: - - main - - master - schedule: - - cron: '0 2 * * *' + branches: [ master ] jobs: - build: - runs-on: ${{ matrix.os }} - - strategy: - fail-fast: false - matrix: - node-version: [10, 12, 14, 16] - os: [ubuntu-latest, windows-latest, macos-latest] - - steps: - - name: Checkout Git Source - uses: actions/checkout@v2 - - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - - - name: Install Dependencies - run: npm i -g npminstall && npminstall - - - name: Continuous Integration - run: npm run ci - - - name: Code Coverage - uses: codecov/codecov-action@v1 - with: - token: ${{ secrets.CODECOV_TOKEN }} + Job: + name: Node.js + uses: node-modules/github-actions/.github/workflows/node-test.yml@master + with: + os: 'ubuntu-latest, windows-latest' + version: '16, 18, 20' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..970aedc --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,12 @@ +name: Release +on: + push: + branches: [ master ] + +jobs: + release: + name: Node.js + uses: eggjs/github-actions/.github/workflows/node-release.yml@master + secrets: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + GIT_TOKEN: ${{ secrets.GIT_TOKEN }} diff --git a/History.md b/CHANGELOG.md similarity index 100% rename from History.md rename to CHANGELOG.md diff --git a/README.md b/README.md index e03ea33..5171f27 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,8 @@ -egg-init -======= +# egg-init [![NPM version][npm-image]][npm-url] [![Node.js CI](https://github.com/eggjs/egg-init/actions/workflows/nodejs.yml/badge.svg)](https://github.com/eggjs/egg-init/actions/workflows/nodejs.yml) [![Test coverage][codecov-image]][codecov-url] -[![David deps][david-image]][david-url] [![Known Vulnerabilities][snyk-image]][snyk-url] [![npm download][download-image]][download-url] @@ -22,14 +20,14 @@ Init egg app helper tools. ## Install ```bash -$ npm i egg-init -g -$ egg-init -h +npm i egg-init -g +egg-init -h ``` ## Create a `simple` type application ```bash -$ egg-init --type simple [dest] +egg-init --type simple [dest] ``` ## Or select a boilerplate by yourself @@ -43,7 +41,7 @@ $ egg-init dest ## Command -``` +```bash Usage: egg-init [dir] --type=simple Options: @@ -67,29 +65,30 @@ We use npm package to manager boilerplate, you can follow this steps: - Use `egg-init --template=PATH` to check - `index.js` can define variables which can be useed on template, like `{{name}}`, but `\{{name}}` will ignore. - ```js - module.exports = { - name: { - desc: 'package-name', - }, - pluginName: { - desc: 'plugin-name', - default(vars) { - return vars.name; - }, - filter(v) { - return 'egg-' + v; - }, - }, - description: { - desc: 'my best plugin', - }, - author: { - desc: 'author', - default: 'eggjs team' - }, - }; - ``` +```js +module.exports = { + name: { + desc: 'package-name', + }, + pluginName: { + desc: 'plugin-name', + default(vars) { + return vars.name; + }, + filter(v) { + return 'egg-' + v; + }, + }, + description: { + desc: 'my best plugin', + }, + author: { + desc: 'author', + default: 'eggjs team' + }, +}; +``` + - Write unit test, see `npm scripts` at [egg-boilerplate-simple](https://github.com/eggjs/egg-boilerplate-simple/blob/master/package.json#L5) - Add your package name to [egg-init-config](https://github.com/eggjs/egg-init-config)'s package.json `config.boilerplate` property - Publish your package to npm @@ -105,8 +104,8 @@ We use npm package to manager boilerplate, you can follow this steps: |[
atian25](https://github.com/atian25)
|[
fengmk2](https://github.com/fengmk2)
|[
thonatos](https://github.com/thonatos)
|[
dead-horse](https://github.com/dead-horse)
|[
popomore](https://github.com/popomore)
|[
killagu](https://github.com/killagu)
| | :---: | :---: | :---: | :---: | :---: | :---: | |[
whxaxes](https://github.com/whxaxes)
|[
jtyjty99999](https://github.com/jtyjty99999)
|[
edokeh](https://github.com/edokeh)
|[
DanielWLam](https://github.com/DanielWLam)
|[
Janlaywss](https://github.com/Janlaywss)
|[
Runrioter](https://github.com/Runrioter)
| -[
snyk-bot](https://github.com/snyk-bot)
|[
WinjayYu](https://github.com/WinjayYu)
|[
ShirasawaSama](https://github.com/ShirasawaSama)
|[
supperchong](https://github.com/supperchong)
+[
snyk-bot](https://github.com/snyk-bot)
|[
WinjayYu](https://github.com/WinjayYu)
|[
ShirasawaSama](https://github.com/ShirasawaSama)
|[
supperchong](https://github.com/supperchong)
|[
hyj1991](https://github.com/hyj1991)
-This project follows the git-contributor [spec](https://github.com/xudafeng/git-contributor), auto updated at `Wed Nov 10 2021 08:41:48 GMT+0800`. +This project follows the git-contributor [spec](https://github.com/xudafeng/git-contributor), auto updated at `Sat Nov 25 2023 23:06:04 GMT+0800`. diff --git a/README.zh-CN.md b/README.zh-CN.md index bc2128c..48ab9d0 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -1,5 +1,4 @@ -egg-init -======= +# egg-init [![NPM version][npm-image]][npm-url] [![Node.js CI](https://github.com/eggjs/egg-init/actions/workflows/nodejs.yml/badge.svg)](https://github.com/eggjs/egg-init/actions/workflows/nodejs.yml) @@ -21,14 +20,14 @@ Egg 应用初始化工具,所有 Egg 应用开发必须安装。 ## Install ```bash -$ npm i egg-init -g -$ egg-init -h +npm i egg-init -g +egg-init -h ``` ## 创建 `simple` 类型的应用 ```bash -$ egg-init --type simple [dest] +egg-init --type simple [dest] ``` ## 不输入类型可以选择 @@ -42,7 +41,7 @@ $ egg-init dest ## 支持的参数 -``` +```bash Usage: egg-init [dir] --type=simple Options: @@ -86,3 +85,15 @@ module.exports = { ## License [MIT](LICENSE) + + +## Contributors + +|[
atian25](https://github.com/atian25)
|[
fengmk2](https://github.com/fengmk2)
|[
thonatos](https://github.com/thonatos)
|[
dead-horse](https://github.com/dead-horse)
|[
popomore](https://github.com/popomore)
|[
killagu](https://github.com/killagu)
| +| :---: | :---: | :---: | :---: | :---: | :---: | +|[
whxaxes](https://github.com/whxaxes)
|[
jtyjty99999](https://github.com/jtyjty99999)
|[
edokeh](https://github.com/edokeh)
|[
DanielWLam](https://github.com/DanielWLam)
|[
Janlaywss](https://github.com/Janlaywss)
|[
Runrioter](https://github.com/Runrioter)
| +[
snyk-bot](https://github.com/snyk-bot)
|[
WinjayYu](https://github.com/WinjayYu)
|[
ShirasawaSama](https://github.com/ShirasawaSama)
|[
supperchong](https://github.com/supperchong)
|[
hyj1991](https://github.com/hyj1991)
+ +This project follows the git-contributor [spec](https://github.com/xudafeng/git-contributor), auto updated at `Sat Nov 25 2023 23:06:04 GMT+0800`. + + \ No newline at end of file diff --git a/bin/egg-init.js b/bin/egg-init.js index ffd3b7e..835ca9d 100755 --- a/bin/egg-init.js +++ b/bin/egg-init.js @@ -1,13 +1,10 @@ #!/usr/bin/env node -'use strict'; - -const co = require('co'); const Command = require('..'); -co(function* () { - yield new Command().run(process.cwd(), process.argv.slice(2)); -}).catch(err => { +(async () => { + await new Command().run(process.cwd(), process.argv.slice(2)); +})().catch(err => { console.error(err.stack); process.exit(1); }); diff --git a/lib/init_command.js b/lib/init_command.js index ebef4e2..6da17d1 100644 --- a/lib/init_command.js +++ b/lib/init_command.js @@ -1,9 +1,7 @@ -'use strict'; - -const os = require('os'); -const assert = require('assert'); -const fs = require('fs'); -const path = require('path'); +const os = require('node:os'); +const assert = require('node:assert'); +const fs = require('node:fs'); +const path = require('node:path'); const urllib = require('urllib'); const updater = require('npm-updater'); const mkdirp = require('mkdirp'); @@ -11,11 +9,10 @@ const inquirer = require('inquirer'); const yargs = require('yargs'); const glob = require('globby'); const is = require('is-type-of'); -const homedir = require('node-homedir'); +const { homedir } = require('node-homedir'); const compressing = require('compressing'); const rimraf = require('mz-modules/rimraf'); const isTextOrBinary = require('istextorbinary'); -const ProxyAgent = require('proxy-agent'); const chalk = require('chalk'); module.exports = class Command { @@ -25,7 +22,7 @@ module.exports = class Command { this.configName = options.configName || 'egg-init-config'; this.pkgInfo = options.pkgInfo || require('../package.json'); this.needUpdate = options.needUpdate !== false; - this.httpClient = urllib.create(); + this.httpClient = urllib; this.inquirer = inquirer; this.fileMapping = { @@ -39,18 +36,9 @@ module.exports = class Command { }; } - * run(cwd, args) { + async run(cwd, args) { const argv = this.argv = this.getParser().parse(args || []); this.cwd = cwd; - // console.log('%j', argv); - - const proxyHost = process.env.http_proxy || process.env.HTTP_PROXY; - if (proxyHost) { - const proxyAgent = new ProxyAgent(proxyHost); - this.httpClient.agent = proxyAgent; - this.httpClient.httpsAgent = proxyAgent; - this.log(`use http_proxy: ${proxyHost}`); - } // detect registry url this.registryUrl = this.getRegistryByType(argv.registry); @@ -58,7 +46,7 @@ module.exports = class Command { if (this.needUpdate) { // check update - yield updater({ + await updater({ package: this.pkgInfo, registry: this.registryUrl, level: 'major', @@ -66,34 +54,34 @@ module.exports = class Command { } // ask for target dir - this.targetDir = yield this.getTargetDirectory(); + this.targetDir = await this.getTargetDirectory(); // use local template - let templateDir = yield this.getTemplateDir(); + let templateDir = await this.getTemplateDir(); if (!templateDir) { // support --package= let pkgName = this.argv.package; if (!pkgName) { // list boilerplate - const boilerplateMapping = yield this.fetchBoilerplateMapping(); + const boilerplateMapping = await this.fetchBoilerplateMapping(); // ask for boilerplate let boilerplate; if (argv.type && boilerplateMapping.hasOwnProperty(argv.type)) { boilerplate = boilerplateMapping[argv.type]; } else { - boilerplate = yield this.askForBoilerplateType(boilerplateMapping); + boilerplate = await this.askForBoilerplateType(boilerplateMapping); if (!boilerplate) return; } this.log(`use boilerplate: ${boilerplate.name}(${boilerplate.package})`); pkgName = boilerplate.package; } // download boilerplate - templateDir = yield this.downloadBoilerplate(pkgName); + templateDir = await this.downloadBoilerplate(pkgName); } // copy template - yield this.processFiles(this.targetDir, templateDir); + await this.processFiles(this.targetDir, templateDir); // done this.printUsage(this.targetDir); } @@ -130,20 +118,21 @@ module.exports = class Command { } return result; } + /** * show boilerplate list and let user choose one * * @param {Object} mapping - boilerplate config mapping, `{ simple: { "name": "simple", "package": "egg-boilerplate-simple", "description": "Simple egg app boilerplate" } }` * @return {Object} boilerplate config item */ - * askForBoilerplateType(mapping) { + async askForBoilerplateType(mapping) { // group by category // group the mapping object by property 'category' or 'other' if item of mapping doesn't have 'category' property const groupMapping = this.groupBy(mapping, 'category', 'other'); const groupNames = Object.keys(groupMapping); let group; if (groupNames.length > 1) { - const answers = yield inquirer.prompt({ + const answers = await inquirer.prompt({ name: 'group', type: 'list', message: 'Please select a boilerplate category', @@ -165,7 +154,7 @@ module.exports = class Command { }); choices.unshift(new inquirer.Separator()); - const { boilerplateInfo } = yield inquirer.prompt({ + const { boilerplateInfo } = await inquirer.prompt({ name: 'boilerplateInfo', type: 'list', message: 'Please select a boilerplate type', @@ -175,7 +164,7 @@ module.exports = class Command { if (!boilerplateInfo.deprecate) return boilerplateInfo; // ask for deprecate - const { shouldInstall } = yield inquirer.prompt({ + const { shouldInstall } = await inquirer.prompt({ name: 'shouldInstall', type: 'list', message: 'It\'s deprecated', @@ -205,7 +194,7 @@ module.exports = class Command { * @param {String} templateDir - template dir * @return {Object} variable scope */ - * askForVariable(targetDir, templateDir) { + async askForVariable(targetDir, templateDir) { let questions; try { questions = require(templateDir); @@ -244,7 +233,7 @@ module.exports = class Command { this.log('use default due to --silent, %j', result); return result; } else { - return yield inquirer.prompt(keys.map(key => { + return await inquirer.prompt(keys.map(key => { const question = questions[key]; return { type: question.type || 'input', @@ -264,9 +253,9 @@ module.exports = class Command { * @param {String} templateDir - template dir, must contain a folder which named `boilerplate` * @return {String[]} file names */ - * processFiles(targetDir, templateDir) { + async processFiles(targetDir, templateDir) { const src = path.join(templateDir, 'boilerplate'); - const locals = yield this.askForVariable(targetDir, templateDir); + const locals = await this.askForVariable(targetDir, templateDir); const files = glob.sync('**/*', { cwd: src, dot: true, @@ -386,7 +375,7 @@ module.exports = class Command { * ask for target directory, will check if dir is valid. * @return {String} Full path of target directory */ - * getTargetDirectory() { + async getTargetDirectory() { const dir = this.argv._[0] || this.argv.dir || ''; let targetDir = path.resolve(this.cwd, dir); const force = this.argv.force; @@ -419,7 +408,7 @@ module.exports = class Command { const isValid = validate(targetDir); if (isValid !== true) { this.log(isValid); - const answer = yield this.inquirer.prompt({ + const answer = await this.inquirer.prompt({ name: 'dir', message: 'Please enter target dir: ', default: dir || '.', @@ -436,7 +425,7 @@ module.exports = class Command { * find template dir from support `--template=` * @return {undefined|String} template files dir */ - * getTemplateDir() { + async getTemplateDir() { let templateDir; // when use `egg-init --template=PATH` if (this.argv.template) { @@ -457,8 +446,8 @@ module.exports = class Command { * @param {String} [pkgName] - config package name, default to `this.configName` * @return {Object} boilerplate config mapping, `{ simple: { "name": "simple", "package": "egg-boilerplate-simple", "description": "Simple egg app boilerplate" } }` */ - * fetchBoilerplateMapping(pkgName) { - const pkgInfo = yield this.getPackageInfo(pkgName || this.configName, true); + async fetchBoilerplateMapping(pkgName) { + const pkgInfo = await this.getPackageInfo(pkgName || this.configName, true); const mapping = pkgInfo.config.boilerplate; Object.keys(mapping).forEach(key => { const item = mapping[key]; @@ -502,17 +491,17 @@ module.exports = class Command { * @param {String} pkgName - boilerplate package name * @return {String} extract directory */ - * downloadBoilerplate(pkgName) { - const result = yield this.getPackageInfo(pkgName, false); + async downloadBoilerplate(pkgName) { + const result = await this.getPackageInfo(pkgName, false); const tgzUrl = result.dist.tarball; this.log(`downloading ${tgzUrl}`); const saveDir = path.join(os.tmpdir(), 'egg-init-boilerplate'); - yield rimraf(saveDir); + await rimraf(saveDir); - const response = yield this.curl(tgzUrl, { streaming: true, followRedirect: true }); - yield compressing.tgz.uncompress(response.res, saveDir); + const response = await this.curl(tgzUrl, { streaming: true, followRedirect: true }); + await compressing.tgz.uncompress(response.res, saveDir); this.log(`extract to ${saveDir}`); return path.join(saveDir, '/package'); @@ -524,8 +513,8 @@ module.exports = class Command { * @param {Object} [options] - request options * @return {Object} response data */ - * curl(url, options) { - return yield this.httpClient.request(url, options); + async curl(url, options) { + return await this.httpClient.request(url, options); } /** @@ -535,10 +524,10 @@ module.exports = class Command { * @param {Boolean} [withFallback] - when http request fail, whethe to require local * @return {Object} pkgInfo */ - * getPackageInfo(pkgName, withFallback) { + async getPackageInfo(pkgName, withFallback) { this.log(`fetching npm info of ${pkgName}`); try { - const result = yield this.curl(`${this.registryUrl}/${pkgName}/latest`, { + const result = await this.curl(`${this.registryUrl}/${pkgName}/latest`, { dataType: 'json', followRedirect: true, maxRedirects: 5, diff --git a/package.json b/package.json index d1a43ea..1bd474e 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,6 @@ "test": "npm run lint -- --fix && egg-bin test", "cov": "egg-bin cov", "ci": "npm run lint && egg-bin cov", - "autod": "autod", "contributor": "git-contributor" }, "preferGlobal": true, @@ -21,32 +20,26 @@ ], "dependencies": { "chalk": "^4.0.0", - "co": "^4.6.0", - "compressing": "^1.4.0", + "compressing": "^1.10.0", "egg-init-config": "^1.5.0", "globby": "^9.0.0", - "inquirer": "^7.0.0", - "is-type-of": "^1.2.1", + "inquirer": "^8.2.6", + "is-type-of": "^2.1.0", "istextorbinary": "^2.5.1", "mkdirp": "^0.5.1", "mz-modules": "^2.1.0", - "node-homedir": "^1.1.1", + "node-homedir": "^2.0.0", "npm-updater": "^3.0.3", - "proxy-agent": "^2.3.1", - "urllib": "^2.33.0", + "urllib": "^3.19.3", "yargs": "^11.1.0" }, "devDependencies": { - "autod": "^3.0.1", - "coffee": "^3.3.0", - "egg-bin": "^1.11.1", - "egg-ci": "^1.11.0", - "eslint": "^6.6.0", - "eslint-config-egg": "^9.0.0", - "git-contributor": "^1.0.10", - "mm": "^2.4.1", - "power-assert": "^1.4.4", - "proxy": "^1.0.0" + "coffee": "5", + "egg-bin": "6", + "eslint": "8", + "eslint-config-egg": "13", + "git-contributor": "2", + "mm": "^2.4.1" }, "homepage": "https://github.com/eggjs/egg-init", "repository": { @@ -58,12 +51,8 @@ "egg", "egg-init" ], - "ci": { - "version": "10, 12, 14, 16", - "type": "github" - }, "engines": { - "node": ">=10.0.0" + "node": ">=16.0.0" }, - "author": "fengmk2 (http://fengmk2.com)" + "author": "fengmk2 (https://github.com/fengmk2)" } diff --git a/test/category.test.js b/test/category.test.js index 57e0dbd..aaa3b85 100644 --- a/test/category.test.js +++ b/test/category.test.js @@ -1,5 +1,3 @@ -'use strict'; - const fs = require('fs'); const path = require('path'); const rimraf = require('mz-modules/rimraf'); @@ -13,8 +11,8 @@ const Command = require('../lib/init_command'); describe('test/category.test', () => { let command; let helper; - before(function* () { - yield rimraf(tmp); + before(async () => { + await rimraf(tmp); command = new Command({ configName: 'egg-init-config-category', }); @@ -23,14 +21,14 @@ describe('test/category.test', () => { beforeEach(() => rimraf(tmp)); - afterEach(function* () { - yield rimraf(tmp); + afterEach(async () => { + await rimraf(tmp); helper.restore(); }); - it('should work', function* () { + it('should work', async () => { const boilerplatePath = path.join(__dirname, 'fixtures/simple-test'); - yield command.run(tmp, [ 'simple-app', '--template=' + boilerplatePath, '--silent' ]); + await command.run(tmp, [ 'simple-app', '--template=' + boilerplatePath, '--silent' ]); assert(fs.existsSync(path.join(command.targetDir, '.gitignore'))); assert(fs.existsSync(path.join(command.targetDir, '.eslintrc'))); @@ -43,37 +41,39 @@ describe('test/category.test', () => { assert(/# simple-app/.test(content)); }); - it('should work with prompt', function* () { - helper.mock([[ 'simple-app', 'this is xxx', 'TZ', helper.KEY_ENTER, 'test', helper.KEY_ENTER ]]); - const boilerplatePath = path.join(__dirname, 'fixtures/simple-test'); - yield command.run(tmp, [ 'simple-app', '--force', '--template=' + boilerplatePath ]); - - assert(fs.existsSync(path.join(command.targetDir, '.gitignore'))); - assert(fs.existsSync(path.join(command.targetDir, '.eslintrc'))); - assert(fs.existsSync(path.join(command.targetDir, 'package.json'))); - assert(fs.existsSync(path.join(command.targetDir, 'simple-app'))); - assert(fs.existsSync(path.join(command.targetDir, 'test', 'simple-app.test.js'))); - - const content = fs.readFileSync(path.join(command.targetDir, 'README.md'), 'utf-8'); - assert(/default-simple-app/.test(content)); - assert(/filter-test/.test(content)); - }); - - it('should prompt', function* () { - helper.mock([ helper.KEY_DOWN, [ 'test', 'this is xxx', 'TZ', helper.KEY_ENTER ]]); - yield command.run(tmp, [ 'prompt-app', '--force' ]); - - assert(fs.existsSync(path.join(command.targetDir, '.gitignore'))); - assert(fs.existsSync(path.join(command.targetDir, 'package.json'))); - - const content = fs.readFileSync(path.join(command.targetDir, 'README.md'), 'utf-8'); - assert(/Development/.test(content)); - }); - it('.replaceTemplate', () => { assert(command.replaceTemplate('hi, {{ user }}', { user: 'egg' }) === 'hi, egg'); assert(command.replaceTemplate('hi, {{ user }}\n{{type}} {{user}}', { user: 'egg', type: 'init' }) === 'hi, egg\ninit egg'); assert(command.replaceTemplate('hi, {{ user }}', {}) === 'hi, {{ user }}'); assert(command.replaceTemplate('hi, \\{{ user }}', { user: 'egg' }) === 'hi, {{ user }}'); }); + + if (!process.env.CI) { + it('should work with prompt', async () => { + helper.mock([[ 'simple-app', 'this is xxx', 'TZ', helper.KEY_ENTER, 'test', helper.KEY_ENTER ]]); + const boilerplatePath = path.join(__dirname, 'fixtures/simple-test'); + await command.run(tmp, [ 'simple-app', '--force', '--template=' + boilerplatePath ]); + + assert(fs.existsSync(path.join(command.targetDir, '.gitignore'))); + assert(fs.existsSync(path.join(command.targetDir, '.eslintrc'))); + assert(fs.existsSync(path.join(command.targetDir, 'package.json'))); + assert(fs.existsSync(path.join(command.targetDir, 'simple-app'))); + assert(fs.existsSync(path.join(command.targetDir, 'test', 'simple-app.test.js'))); + + const content = fs.readFileSync(path.join(command.targetDir, 'README.md'), 'utf-8'); + assert(/default-simple-app/.test(content)); + assert(/filter-test/.test(content)); + }); + + it('should prompt', async () => { + helper.mock([ helper.KEY_DOWN, [ 'test', 'this is xxx', 'TZ', helper.KEY_ENTER ]]); + await command.run(tmp, [ 'prompt-app', '--force' ]); + + assert(fs.existsSync(path.join(command.targetDir, '.gitignore'))); + assert(fs.existsSync(path.join(command.targetDir, 'package.json'))); + + const content = fs.readFileSync(path.join(command.targetDir, 'README.md'), 'utf-8'); + assert(/Development/.test(content)); + }); + } }); diff --git a/test/fixtures/simple-test/index.js b/test/fixtures/simple-test/index.js index c45010e..df51cee 100644 --- a/test/fixtures/simple-test/index.js +++ b/test/fixtures/simple-test/index.js @@ -1,5 +1,3 @@ -'use strict'; - module.exports = { name: { desc: 'project name', diff --git a/test/helper.js b/test/helper.js index a2d9d50..4bb546e 100644 --- a/test/helper.js +++ b/test/helper.js @@ -1,6 +1,5 @@ -'use strict'; -const co = require('co'); const sleep = require('mz-modules/sleep'); + module.exports = class Helper { constructor(command) { this.command = command; @@ -38,19 +37,9 @@ module.exports = class Helper { if (questionNumber !== keys.length) { throw new Error('the number of prompt question must equal the number of mock keys'); } - co(this.sendKey(rl, keys)); - - /** - * Window will block after input.emit,input resume and sleep can fix this. - * The bug only happen when simulate user input. - * detail: https://github.com/SBoudrias/Inquirer.js/issues/870 - */ - return result.then(co.wrap(function* (v) { - rl.input.resume(); - yield sleep(10); - return v; - })); + this.sendKey(rl, keys); + return result; }; } @@ -67,10 +56,9 @@ module.exports = class Helper { * @param {Object} rl - the instance of readline * @param {Array} arr - key list, send one by one after a tick */ - * sendKey(rl, arr) { - + async sendKey(rl, arr) { for (const key of arr) { - yield sleep(200); + await sleep(200); if (typeof key === 'string') { rl.input.emit('keypress', key + '\r'); diff --git a/test/init.test.js b/test/init.test.js index 3031ae7..9ff850d 100644 --- a/test/init.test.js +++ b/test/init.test.js @@ -1,5 +1,3 @@ -'use strict'; - const os = require('os'); const fs = require('fs'); const path = require('path'); @@ -15,22 +13,22 @@ const Command = require('..'); describe('test/init.test.js', () => { let command; let helper; - before(function* () { - yield rimraf(tmp); + before(async () => { + await rimraf(tmp); command = new Command(); helper = new Helper(command); }); beforeEach(() => rimraf(tmp)); - afterEach(function* () { - yield rimraf(tmp); + afterEach(async () => { + await rimraf(tmp); helper.restore(); }); - it('should work', function* () { + it('should work', async () => { const boilerplatePath = path.join(__dirname, 'fixtures/simple-test'); - yield command.run(tmp, [ 'simple-app', '--template=' + boilerplatePath, '--silent' ]); + await command.run(tmp, [ 'simple-app', '--template=' + boilerplatePath, '--silent' ]); assert(fs.existsSync(path.join(command.targetDir, '.gitignore'))); assert(fs.existsSync(path.join(command.targetDir, '.eslintrc'))); @@ -47,34 +45,6 @@ describe('test/init.test.js', () => { assert(/# simple-app/.test(content)); }); - it('should work with prompt', function* () { - helper.mock([[ 'simple-app', 'this is xxx', 'TZ', helper.KEY_ENTER, 'test', helper.KEY_ENTER ]]); - const boilerplatePath = path.join(__dirname, 'fixtures/simple-test'); - yield command.run(tmp, [ 'simple-app', '--force', '--template=' + boilerplatePath ]); - - assert(fs.existsSync(path.join(command.targetDir, '.gitignore'))); - assert(fs.existsSync(path.join(command.targetDir, '.eslintrc'))); - assert(fs.existsSync(path.join(command.targetDir, 'package.json'))); - assert(fs.existsSync(path.join(command.targetDir, 'simple-app'))); - assert(fs.existsSync(path.join(command.targetDir, 'test', 'simple-app.test.js'))); - - const content = fs.readFileSync(path.join(command.targetDir, 'README.md'), 'utf-8'); - assert(/default-simple-app/.test(content)); - assert(/filter-test/.test(content)); - assert(/listA/.test(content)); - }); - - it('should prompt', function* () { - helper.mock([ helper.KEY_DOWN, [ 'test', 'this is xxx', 'TZ', helper.KEY_ENTER ]]); - yield command.run(tmp, [ 'prompt-app', '--force' ]); - - assert(fs.existsSync(path.join(command.targetDir, '.gitignore'))); - assert(fs.existsSync(path.join(command.targetDir, 'package.json'))); - - const content = fs.readFileSync(path.join(command.targetDir, 'README.md'), 'utf-8'); - assert(/Development/.test(content)); - }); - it('.replaceTemplate', () => { assert(command.replaceTemplate('hi, {{ user }}', { user: 'egg' }) === 'hi, egg'); assert(command.replaceTemplate('hi, {{ user }}\n{{type}} {{user}}', { user: 'egg', type: 'init' }) === 'hi, egg\ninit egg'); @@ -82,8 +52,8 @@ describe('test/init.test.js', () => { assert(command.replaceTemplate('hi, \\{{ user }}', { user: 'egg' }) === 'hi, {{ user }}'); }); - it('should works with remote boilerplate', function* () { - yield command.run(tmp, [ 'simple-app', '--type=simple', '--silent' ]); + it('should works with remote boilerplate', async () => { + await command.run(tmp, [ 'simple-app', '--type=simple', '--silent' ]); assert(fs.existsSync(path.join(command.targetDir, '.gitignore'))); assert(fs.existsSync(path.join(command.targetDir, '.eslintrc'))); @@ -92,4 +62,34 @@ describe('test/init.test.js', () => { assert(fs.existsSync(path.join(command.targetDir, 'test/app/controller/home.test.js'))); assert(fs.existsSync(path.join(command.targetDir, 'app/controller/home.js'))); }); + + if (!process.env.CI) { + it('should work with prompt', async () => { + helper.mock([[ 'simple-app', 'this is xxx', 'TZ', helper.KEY_ENTER, 'test', helper.KEY_ENTER ]]); + const boilerplatePath = path.join(__dirname, 'fixtures/simple-test'); + await command.run(tmp, [ 'simple-app', '--force', '--template=' + boilerplatePath ]); + + assert(fs.existsSync(path.join(command.targetDir, '.gitignore'))); + assert(fs.existsSync(path.join(command.targetDir, '.eslintrc'))); + assert(fs.existsSync(path.join(command.targetDir, 'package.json'))); + assert(fs.existsSync(path.join(command.targetDir, 'simple-app'))); + assert(fs.existsSync(path.join(command.targetDir, 'test', 'simple-app.test.js'))); + + const content = fs.readFileSync(path.join(command.targetDir, 'README.md'), 'utf-8'); + assert(/default-simple-app/.test(content)); + assert(/filter-test/.test(content)); + assert(/listA/.test(content)); + }); + + it('should prompt', async () => { + helper.mock([ helper.KEY_DOWN, [ 'test', 'this is xxx', 'TZ', helper.KEY_ENTER ]]); + await command.run(tmp, [ 'prompt-app', '--force' ]); + + assert(fs.existsSync(path.join(command.targetDir, '.gitignore'))); + assert(fs.existsSync(path.join(command.targetDir, 'package.json'))); + + const content = fs.readFileSync(path.join(command.targetDir, 'README.md'), 'utf-8'); + assert(/Development/.test(content)); + }); + } }); diff --git a/test/proxy.test.js b/test/proxy.test.js deleted file mode 100644 index 07628bc..0000000 --- a/test/proxy.test.js +++ /dev/null @@ -1,59 +0,0 @@ -'use strict'; - -const fs = require('fs'); -const path = require('path'); -const rimraf = require('mz-modules/rimraf'); -const assert = require('assert'); -const Helper = require('./helper'); -const proxy = require('proxy'); -const mm = require('mm'); - -const tmp = path.join(__dirname, '../.tmp'); - -const Command = require('..'); - -describe('test/proxy.test.js', () => { - let command; - let helper; - let proxyServer; - let proxyPort; - - before(function* () { - yield rimraf(tmp); - command = new Command(); - helper = new Helper(command); - }); - - before(done => { - proxyServer = proxy(); - proxyServer.listen(() => { - proxyPort = proxyServer.address().port; - done(); - }); - }); - - beforeEach(() => rimraf(tmp)); - - afterEach(function* () { - mm.restore(); - yield rimraf(tmp); - helper.restore(); - }); - - after(() => { - proxyServer.close(); - }); - - it.skip('should work', function* () { - mm(process.env, 'http_proxy', 'http://127.0.0.1:' + proxyPort); - - helper.mock([ helper.KEY_DOWN, [ 'test', 'this is xxx', 'TZ', helper.KEY_ENTER ]]); - yield command.run(tmp, [ 'prompt-app', '--force' ]); - - assert(fs.existsSync(path.join(command.targetDir, '.gitignore'))); - assert(fs.existsSync(path.join(command.targetDir, 'package.json'))); - - const content = fs.readFileSync(path.join(command.targetDir, 'README.md'), 'utf-8'); - assert(/Development/.test(content)); - }); -});