UNPKG

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