UNPKG

2.22 kBJavaScriptView Raw
1const path = require('path')
2
3const ora = require('ora')
4const chalk = require('chalk')
5const rimraf = require('rimraf')
6
7const { logger, http, util } = require('../common')
8
9/**
10 * Template name is local path
11 * @param {String} template template name or uri
12 */
13const isLocalPath = template => {
14 return /^[./]|^[a-zA-Z]:/.test(template)
15}
16
17/**
18 * Get template url
19 * @param {String} template template name or uri
20 */
21const getTemplateUrl = template => {
22 // full url
23 if (/^https?:/.test(template)) return template
24 // short name
25 // `zce-templates` is official templates org
26 template = template.includes('/') ? template : `zce-templates/${template}`
27 // branch
28 const temp = template.split('#')
29 // github archive link
30 return `https://github.com/${temp[0]}/archive/${temp[1] || 'master'}.zip`
31}
32
33/**
34 * Resolve template from local or remote
35 * TODO: template version
36 * @param {String} template template name or uri
37 * @param {Boolean} offline offline mode
38 */
39module.exports = async (template, offline) => {
40 if (isLocalPath(template)) {
41 // local template path
42 return path.resolve(template)
43 }
44
45 // fetch remote template
46 const templateUrl = getTemplateUrl(template)
47
48 const cachePath = util.getDataPath('generator/cache', templateUrl.replace(/[\W]+/g, '-'))
49
50 const cacheExists = await util.exists(cachePath) && await util.isDirectory(cachePath)
51
52 if (offline) {
53 // offline mode
54 if (cacheExists) {
55 // found cached template
56 logger.log(`🚆 Use cached template @ ${chalk.yellow(util.tildify(cachePath))}.`)
57 return cachePath
58 }
59
60 logger.log(`😔 Template cache ${chalk.yellow(util.tildify(cachePath))} not found.`)
61 }
62
63 // clear cache
64 cacheExists && rimraf.sync(cachePath)
65
66 const spinner = ora('Downloading template...')
67
68 try {
69 spinner.start()
70 await http.download(templateUrl, cachePath, { extract: true, strip: 1, mode: 666 })
71 spinner.succeed('Download complete.')
72 return cachePath
73 } catch (e) {
74 spinner.fail('Download failed.')
75 throw new Error(`Failed to fetch template "${template}": ${e.message}.`)
76 }
77}
78
79// for unit test
80module.exports.isLocalPath = isLocalPath
81module.exports.getTemplateUrl = getTemplateUrl