index.js
3.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*!
* parse-github-url <https://github.com/jonschlinkert/parse-github-url>
*
* Copyright (c) 2015-2017, Jon Schlinkert.
* Released under the MIT License.
*/
'use strict';
var url = require('url');
var cache = {};
module.exports = function parseGithubUrl(str) {
return cache[str] || (cache[str] = parse(str));
};
function parse(str) {
if (typeof str !== 'string' || !str.length) {
return null;
}
if (str.indexOf('git@gist') !== -1 || str.indexOf('//gist') !== -1) {
return null;
}
// parse the URL
var obj = url.parse(str);
if (typeof obj.path !== 'string' || !obj.path.length || typeof obj.pathname !== 'string' || !obj.pathname.length) {
return null;
}
if (!obj.host && /^git@/.test(str) === true) {
// return the correct host for git@ URLs
obj.host = url.parse('http://' + str).host;
}
obj.path = trimSlash(obj.path);
obj.pathname = trimSlash(obj.pathname);
obj.filepath = null;
if (obj.path.indexOf('repos') === 0) {
obj.path = obj.path.slice(6);
}
var seg = obj.path.split('/').filter(Boolean);
var hasBlob = seg[2] === 'blob';
if (hasBlob && !isChecksum(seg[3])) {
obj.branch = seg[3];
if (seg.length > 4) {
obj.filepath = seg.slice(4).join('/');
}
}
var blob = str.indexOf('blob');
if (blob !== -1) {
obj.blob = str.slice(blob + 5);
}
var tree = str.indexOf('tree');
if (tree !== -1) {
var idx = tree + 5;
var branch = str.slice(idx);
var slash = branch.indexOf('/');
if (slash !== -1) {
branch = branch.slice(0, slash);
}
obj.branch = branch;
}
obj.owner = owner(seg[0]);
obj.name = name(seg[1]);
if (seg.length > 1 && obj.owner && obj.name) {
obj.repo = obj.owner + '/' + obj.name;
} else {
var href = obj.href.split(':');
if (href.length === 2 && obj.href.indexOf('//') === -1) {
obj.repo = obj.repo || href[href.length - 1];
var repoSegments = obj.repo.split('/');
obj.owner = repoSegments[0];
obj.name = repoSegments[1];
} else {
var match = obj.href.match(/\/([^\/]*)$/);
obj.owner = match ? match[1] : null;
obj.repo = null;
}
if (obj.repo && (!obj.owner || !obj.name)) {
var segs = obj.repo.split('/');
if (segs.length === 2) {
obj.owner = segs[0];
obj.name = segs[1];
}
}
}
if (!obj.branch) {
obj.branch = seg[2] || getBranch(obj.path, obj);
if (seg.length > 3) {
obj.filepath = seg.slice(3).join('/');
}
}
obj.host = obj.host || 'github.com';
obj.owner = obj.owner || null;
obj.name = obj.name || null;
obj.repository = obj.repo;
return obj;
}
function isChecksum(str) {
return /^[a-f0-9]{40}$/i.test(str);
}
function getBranch(str, obj) {
var segs = str.split('#');
var branch;
if (segs.length > 1) {
branch = segs[segs.length - 1];
}
if (!branch && obj.hash && obj.hash.charAt(0) === '#') {
branch = obj.hash.slice(1);
}
return branch || 'master';
}
function trimSlash(path) {
return path.charAt(0) === '/' ? path.slice(1) : path;
}
function name(str) {
return str ? str.replace(/^\W+|\.git$/g, '') : null;
}
function owner(str) {
if (!str) return null;
var idx = str.indexOf(':');
if (idx > -1) {
return str.slice(idx + 1);
}
return str;
}