1 | var downloadUrl = require('download')
|
2 | var gitclone = require('git-clone')
|
3 | var rm = require('rimraf').sync
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 | module.exports = download
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 | function 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 |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 | function 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 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 | function 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 |
|
137 |
|
138 |
|
139 |
|
140 |
|
141 |
|
142 | function getUrl (repo, clone) {
|
143 | var url
|
144 |
|
145 |
|
146 | var origin = addProtocol(repo.origin, clone)
|
147 | if (/^git\@/i.test(origin)) {
|
148 | origin = origin + ':'
|
149 | } else {
|
150 | origin = origin + '/'
|
151 | }
|
152 |
|
153 |
|
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 | }
|