Skip to content

Commit 53a4b75

Browse files
committed
Support npm-style #ref suffix; fixes issue 16
1 parent ff5c252 commit 53a4b75

File tree

3 files changed

+61
-6
lines changed

3 files changed

+61
-6
lines changed

giturlparse/parser.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ def get_parsed(self):
4848
'port',
4949
'name',
5050
'owner',
51+
'ref',
5152
])
5253

5354
def parse(self):
@@ -68,34 +69,39 @@ def parse(self):
6869
'port': None,
6970
'name': None,
7071
'owner': None,
72+
'ref': None,
7173
}
7274
regexes = [
7375
(r'^(?P<protocol>https?|git|ssh|rsync)\://'
7476
'(?:(?P<user>.+)@)*'
7577
'(?P<resource>[a-z0-9_.-]*)'
7678
'[:/]*'
7779
'(?P<port>[\d]+){0,1}'
78-
'(?P<pathname>\/(?P<owner>.+)/(?P<name>.+).git)'),
80+
'(?P<pathname>\/(?P<owner>.+)/(?P<name>.+).git)'
81+
'(#(?P<ref>.+)){0,1}$'),
7982
(r'(git\+)?'
8083
'((?P<protocol>\w+)://)'
8184
'((?P<user>\w+)@)?'
8285
'((?P<resource>[\w\.\-]+))'
8386
'(:(?P<port>\d+))?'
8487
'(?P<pathname>(\/(?P<owner>\w+)/)?'
85-
'(\/?(?P<name>[\w\-]+)(\.git)?)?)'),
88+
'(\/?(?P<name>[\w\-]+)(\.git)?)?)'
89+
'(#(?P<ref>.+)){0,1}$'),
8690
(r'^(?:(?P<user>.+)@)*'
8791
'(?P<resource>[a-z0-9_.-]*)[:/]*'
8892
'(?P<port>[\d]+){0,1}'
89-
'[:](?P<pathname>\/?(?P<owner>.+)/(?P<name>.+).git)'),
93+
'[:](?P<pathname>\/?(?P<owner>.+)/(?P<name>.+).git)'
94+
'(#(?P<ref>.+)){0,1}$'),
9095
(r'((?P<user>\w+)@)?'
9196
'((?P<resource>[\w\.\-]+))'
9297
'[\:\/]{1,2}'
9398
'(?P<pathname>((?P<owner>\w+)/)?'
94-
'((?P<name>[\w\-]+)(\.git)?)?)'),
99+
'((?P<name>[\w\-]+)(\.git)?)?)'
100+
'(#(?P<ref>.+)){0,1}$'),
95101
]
96102
for regex in regexes:
97-
if re.search(regex, self._url):
98-
m = re.search(regex, self._url)
103+
m = re.search(regex, self._url)
104+
if m:
99105
d.update(m.groupdict())
100106
break
101107
else:

test/conftest.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ def git_urls():
3737
'port': None,
3838
'name': 'repo',
3939
'owner': 'owner',
40+
'ref': None,
4041
},
4142
'ssh://[email protected]:29418/owner/repo.git': {
4243
'pathname': '/owner/repo.git',
@@ -48,6 +49,7 @@ def git_urls():
4849
'port': '29418',
4950
'name': 'repo',
5051
'owner': 'owner',
52+
'ref': None,
5153
},
5254
'ssh://example.com/owner/repo.git': {
5355
'pathname': '/owner/repo.git',
@@ -59,6 +61,7 @@ def git_urls():
5961
'port': None,
6062
'name': 'repo',
6163
'owner': 'owner',
64+
'ref': None,
6265
},
6366
'ssh://example.com:29418/owner/repo.git': {
6467
'pathname': '/owner/repo.git',
@@ -70,6 +73,7 @@ def git_urls():
7073
'port': '29418',
7174
'name': 'repo',
7275
'owner': 'owner',
76+
'ref': None,
7377
},
7478
'[email protected]:/owner/repo.git': {
7579
'pathname': '/owner/repo.git',
@@ -81,6 +85,7 @@ def git_urls():
8185
'port': None,
8286
'name': 'repo',
8387
'owner': 'owner',
88+
'ref': None,
8489
},
8590
'example.com:/owner/repo.git': {
8691
'pathname': '/owner/repo.git',
@@ -92,6 +97,7 @@ def git_urls():
9297
'port': None,
9398
'name': 'repo',
9499
'owner': 'owner',
100+
'ref': None,
95101
},
96102
'[email protected]:owner/repo.git': {
97103
'pathname': 'owner/repo.git',
@@ -103,6 +109,34 @@ def git_urls():
103109
'port': None,
104110
'name': 'repo',
105111
'owner': 'owner',
112+
'ref': None,
113+
},
114+
# gitlab and github allow omitting the .git
115+
'[email protected]:owner/repo': {
116+
'pathname': 'owner/repo',
117+
'protocols': [],
118+
'protocol': 'ssh',
119+
'href': '[email protected]:owner/repo',
120+
'resource': 'example.com',
121+
'user': 'user',
122+
'port': None,
123+
'name': 'repo',
124+
'owner': 'owner',
125+
'ref': None,
126+
},
127+
# npm and others allow specifying a branch or commit
128+
# See https://docs.npmjs.com/files/package.json#git-urls-as-dependencies
129+
'[email protected]:owner/repo.git#blort': {
130+
'pathname': 'owner/repo.git',
131+
'protocols': [],
132+
'protocol': 'ssh',
133+
'href': '[email protected]:owner/repo.git#blort',
134+
'resource': 'example.com',
135+
'user': 'user',
136+
'port': None,
137+
'name': 'repo',
138+
'owner': 'owner',
139+
'ref': 'blort',
106140
},
107141
'[email protected]:owner/repo.git': {
108142
'pathname': 'owner/repo.git',
@@ -114,6 +148,7 @@ def git_urls():
114148
'port': None,
115149
'name': 'repo',
116150
'owner': 'owner',
151+
'ref': None,
117152
},
118153
'example.com:owner/repo.git': {
119154
'pathname': 'owner/repo.git',
@@ -125,6 +160,7 @@ def git_urls():
125160
'port': None,
126161
'name': 'repo',
127162
'owner': 'owner',
163+
'ref': None,
128164
},
129165
'rsync://example.com/owner/repo.git': {
130166
'pathname': '/owner/repo.git',
@@ -136,6 +172,7 @@ def git_urls():
136172
'port': None,
137173
'name': 'repo',
138174
'owner': 'owner',
175+
'ref': None,
139176
},
140177
'git://example.com/owner/repo.git': {
141178
'pathname': '/owner/repo.git',
@@ -147,6 +184,7 @@ def git_urls():
147184
'port': None,
148185
'name': 'repo',
149186
'owner': 'owner',
187+
'ref': None,
150188
},
151189
'http://example.com/owner/repo.git': {
152190
'pathname': '/owner/repo.git',
@@ -158,6 +196,7 @@ def git_urls():
158196
'port': None,
159197
'name': 'repo',
160198
'owner': 'owner',
199+
'ref': None,
161200
},
162201
'https://example.com/owner/repo.git': {
163202
'pathname': '/owner/repo.git',
@@ -169,6 +208,7 @@ def git_urls():
169208
'port': None,
170209
'name': 'repo',
171210
'owner': 'owner',
211+
'ref': None,
172212
},
173213
'https://example.com/owner/repo': {
174214
'pathname': '/owner/repo',
@@ -180,6 +220,7 @@ def git_urls():
180220
'port': None,
181221
'name': 'repo',
182222
'owner': 'owner',
223+
'ref': None,
183224
},
184225
'example.com:repo.git': {
185226
'pathname': 'repo.git',
@@ -191,6 +232,7 @@ def git_urls():
191232
'port': None,
192233
'name': 'repo',
193234
'owner': None,
235+
'ref': None,
194236
},
195237
'https://example.com/repo': {
196238
'pathname': '/repo',
@@ -202,6 +244,7 @@ def git_urls():
202244
'port': None,
203245
'name': 'repo',
204246
'owner': None,
247+
'ref': None,
205248
},
206249
'https://example.in/repo': {
207250
'pathname': '/repo',
@@ -213,6 +256,7 @@ def git_urls():
213256
'port': None,
214257
'name': 'repo',
215258
'owner': None,
259+
'ref': None,
216260
},
217261
'[email protected]:repo.git': {
218262
'pathname': 'repo.git',
@@ -224,6 +268,7 @@ def git_urls():
224268
'port': None,
225269
'name': 'repo',
226270
'owner': None,
271+
'ref': None,
227272
},
228273
'git+ssh://example.com/owner/repo.git': {
229274
'pathname': '/owner/repo.git',
@@ -235,6 +280,7 @@ def git_urls():
235280
'port': None,
236281
'name': 'repo',
237282
'owner': 'owner',
283+
'ref': None,
238284
},
239285
'git+https://example.com/owner/repo.git': {
240286
'pathname': '/owner/repo.git',
@@ -246,6 +292,7 @@ def git_urls():
246292
'port': None,
247293
'name': 'repo',
248294
'owner': 'owner',
295+
'ref': None,
249296
},
250297
'https://[email protected]/user/repo': {
251298
'pathname': '/user/repo',
@@ -257,6 +304,7 @@ def git_urls():
257304
'port': None,
258305
'name': 'repo',
259306
'owner': 'user',
307+
'ref': None,
260308
},
261309
}
262310

test/test_parser.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ def test_parse(git_urls):
3939
assert d['port'] == result.port
4040
assert d['name'] == result.name
4141
assert d['owner'] == result.owner
42+
assert d['ref'] == result.ref
4243

4344

4445
def test_parse_raises_on_invalid_url(invalid_urls):

0 commit comments

Comments
 (0)