diff --git a/lib/utils/template_generator.js b/lib/utils/template_generator.js index 2d884c05b..906f4ca9f 100644 --- a/lib/utils/template_generator.js +++ b/lib/utils/template_generator.js @@ -15,7 +15,29 @@ class TemplateGenerator { } } - downloadAndGenerate(uri, destinationFolder, name) { + download(url, tmpFilePath, browse) { + console.log(__('Installing template from ' + browse).green); + console.log(__('Downloading template...').green); + fs.mkdirpSync(utils.dirname(tmpFilePath)); + return new Promise((resolve, reject) => { + utils.downloadFile(url, tmpFilePath, (err) => { + if (err) { + console.error(utils.errorMessage(err).red); + reject(err); + } else { + resolve(); + } + }); + }); + } + + downloadFailed() { + console.error('Does the template really exist?'.red); + console.error(`Embark's supported templates: https://embark.status.im/templates/`.green); + process.exit(1); + } + + async downloadAndGenerate(uri, destinationFolder, name) { const fspath = utils.joinPath(destinationFolder, name); this.checkPathExists(fspath); const self = this; @@ -28,27 +50,31 @@ class TemplateGenerator { } let {url, filePath, browse} = ext; let tmpFilePath = fs.tmpDir(filePath); - console.log(__('Installing template from ' + browse).green); - console.log(__('Downloading template...').green); - - fs.mkdirpSync(utils.dirname(tmpFilePath)); - utils.downloadFile(url, tmpFilePath, (err) => { - if (err) { - console.error(utils.errorMessage(err).red); - console.error('Does the template really exist?'.red); - console.error(`Embark's supported templates: https://embark.status.im/templates/`.green); - process.exit(1); - } - utils.extractZip(tmpFilePath, fspath, { - map: file => { - let fixed_path = file.path.split('/'); - fixed_path.shift(); // remove first directory - file.path = utils.joinPath(...fixed_path); - return file; + try { + try { + await this.download(url, tmpFilePath, browse); + } catch (err) { + let {url_fallback, filePath_fallback, browse_fallback} = ext; + if (url_fallback) { + console.log(__('Retrying with the master branch...').green); + tmpFilePath = fs.tmpDir(filePath_fallback); + await this.download(url_fallback, tmpFilePath, browse_fallback); + } else { + throw new Error(); } - }, () => { - self.installTemplate(fspath, name, true); - }); + } + } catch (e) { + this.downloadFailed(); + } + utils.extractZip(tmpFilePath, fspath, { + map: file => { + let fixed_path = file.path.split('/'); + fixed_path.shift(); // remove first directory + file.path = utils.joinPath(...fixed_path); + return file; + } + }, () => { + self.installTemplate(fspath, name, true); }); } @@ -102,24 +128,36 @@ class TemplateGenerator { getExternalProject(uri) { let url, folder, hgi; + let fallback, url_fallback, folder_fallback, hgi_fallback; hgi = hostedGitInfo.fromUrl(uri); if (!hgi || hgi.user.includes('#')) { let templateAndBranch = uri.split('#'); if (templateAndBranch.length === 1) { + fallback = true; let embarkVersion = semver(require('../../package.json').version); templateAndBranch.push(`${embarkVersion.major}.${embarkVersion.minor}`); } templateAndBranch[0] = `embark-framework/embark-${templateAndBranch[0]}-template`; hgi = hostedGitInfo.fromUrl(templateAndBranch.join('#')); + if (fallback) { + hgi_fallback = hostedGitInfo.fromUrl(templateAndBranch[0]); + } } if(!hgi) { throw new Error('Unsupported template name or git host URL'); } url = hgi.tarball(); folder = `${hgi.user}/${hgi.project}/${hgi.committish || 'master'}`; + if (fallback) { + url_fallback = hgi_fallback.tarball(); + folder_fallback = `${hgi_fallback.user}/${hgi_fallback.project}/master`; + } return { url, filePath: utils.joinPath(".embark/templates/", folder, "archive.zip"), - browse: decodeURIComponent(hgi.browse()) + browse: decodeURIComponent(hgi.browse()), + url_fallback, + filePath_fallback: fallback && utils.joinPath(".embark/templates/", folder_fallback, "archive.zip"), + browse_fallback: fallback && decodeURIComponent(hgi_fallback.browse()) }; } }