UNPKG

3.48 kBJavaScriptView Raw
1const downloadUrl = require('download')
2const gitclone = require('git-clone')
3const rm = require('rimraf').sync
4const logger = require('./logger')
5
6/**
7 * Expose `download`.
8 */
9
10module.exports = download
11
12/**
13 * Download `repo` to `dest` and callback `fn(err)`.
14 *
15 * @param {String} repo
16 * @param {String} dest
17 * @param {Object} opts
18 * @param {Function} fn
19 */
20
21function download(repo, dest, opts, fn) {
22 console.log(
23 `
24 ${repo}
25 `
26 )
27 if (typeof opts === 'function') {
28 fn = opts
29 opts = null
30 }
31 opts = opts || {}
32 const clone = opts.clone || false
33 const gitServer = opts.gitServer || false
34
35 if (gitServer) {
36 repo = normalize(`direct:${gitServer}${clone ? ':' : '/'}${repo}`, clone)
37 } else {
38 repo = normalize(repo, clone)
39 }
40
41 logger.debug('repo', repo)
42
43 if (clone) {
44 gitclone(repo.url, dest, { checkout: repo.checkout, shallow: repo.checkout === 'master' }, err => {
45 if (err === undefined) {
46 rm(dest + '/.git')
47 fn()
48 } else {
49 fn(err)
50 }
51 })
52 } else {
53 downloadUrl(repo.url, dest, { extract: true, strip: 1, mode: '666', headers: { accept: 'application/zip' } })
54 .then(() => {
55 fn()
56 })
57 .catch(err => {
58 fn(err)
59 })
60 }
61}
62
63/**
64 * Normalize a repo string.
65 *
66 * @param {String} repo
67 * @return {Object}
68 */
69
70function normalize(repo, clone) {
71 let regex = /^(?:(direct):([^#]+)(?:#(.+))?)$/
72 let match = regex.exec(repo)
73
74 if (match) {
75 let url = match[2]
76 const checkout = match[3] || 'master'
77
78 if (clone) {
79 url = url.replace(/^(f|ht)tps?:\/\//, '')
80 url = 'git@' + url + '.git'
81 }
82 return {
83 type: 'direct',
84 url,
85 checkout
86 }
87 }
88 regex = /^(?:(github|gitlab|bitbucket):)?(?:(.+):)?([^/]+)\/([^#]+)(?:#(.+))?$/
89 match = regex.exec(repo)
90 const type = match[1] || 'github'
91 let origin = match[2] || null
92 const owner = match[3]
93 const name = match[4]
94 const checkout = match[5] || 'master'
95
96 if (origin === null) {
97 if (type === 'github') {
98 origin = 'github.com'
99 } else if (type === 'gitlab') {
100 origin = 'gitlab.com'
101 } else if (type === 'bitbucket') {
102 origin = 'bitbucket.com'
103 }
104 }
105
106 const nRepo = {
107 type,
108 origin,
109 owner,
110 name,
111 checkout
112 }
113
114 nRepo.url = getUrl(nRepo, clone)
115 return nRepo
116}
117
118/**
119 * Adds protocol to url in none specified
120 *
121 * @param {String} url
122 * @return {String}
123 */
124
125function addProtocol(origin, clone) {
126 if (!/^(f|ht)tps?:\/\//i.test(origin)) {
127 if (clone) {
128 origin = 'git@' + origin
129 } else {
130 origin = 'https://' + origin
131 }
132 }
133
134 return origin
135}
136
137/**
138 * Return a zip or git url for a given `repo`.
139 *
140 * @param {Object} repo
141 * @return {String}
142 */
143
144function getUrl(repo, clone) {
145 let url
146
147 // Get origin with protocol and add trailing slash or colon (for ssh)
148 let origin = addProtocol(repo.origin, clone)
149 if (/^git@/i.test(origin)) {
150 origin += ':'
151 } else {
152 origin += '/'
153 }
154
155 // Build url
156 if (clone) {
157 url = origin + repo.owner + '/' + repo.name + '.git'
158 } else if (repo.type === 'github') {
159 url = origin + repo.owner + '/' + repo.name + '/archive/' + repo.checkout + '.zip'
160 } else if (repo.type === 'gitlab') {
161 url = origin + repo.owner + '/' + repo.name + '/repository/archive.zip?ref=' + repo.checkout
162 } else if (repo.type === 'bitbucket') {
163 url = origin + repo.owner + '/' + repo.name + '/get/' + repo.checkout + '.zip'
164 }
165
166 return url
167}