Skip to content

Commit ed4477c

Browse files
committed
Support Go module fallback for nested package paths
1 parent a0e2ff7 commit ed4477c

File tree

2 files changed

+38
-7
lines changed

2 files changed

+38
-7
lines changed

pre_commit_mirror_maker/languages.py

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
from __future__ import annotations
22

33
import json
4+
import os
45
import re
56
import subprocess
7+
import urllib.error
68
import urllib.request
79

810
from packaging import requirements
@@ -41,11 +43,26 @@ def golang_get_package_versions(package_name: str) -> list[str]:
4143
r'[A-Z]',
4244
lambda m: f'!{m.group(0).lower()}', package_name,
4345
)
44-
url = f'https://proxy.golang.org/{escaped}/@v/list'
45-
resp = urllib.request.urlopen(url).read().decode()
46-
return sorted(
47-
(v.removeprefix('v') for v in resp.splitlines()),
48-
key=version.parse,
46+
47+
# Greedily choose the longest non-404 path
48+
# (based on https://go.dev/ref/mod#resolve-pkg-mod)
49+
while escaped:
50+
url = f'https://proxy.golang.org/{escaped}/@v/list'
51+
try:
52+
resp = urllib.request.urlopen(url).read().decode()
53+
except urllib.error.HTTPError as exc:
54+
if exc.code == 404:
55+
escaped = os.path.dirname(escaped)
56+
continue
57+
raise
58+
59+
return sorted(
60+
(v.removeprefix('v') for v in resp.splitlines()),
61+
key=version.parse,
62+
)
63+
64+
raise ValueError(
65+
f'Cannot find package name {package_name} on proxy.golang.org',
4966
)
5067

5168

tests/languages_test.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from __future__ import annotations
22

3+
import pytest
4+
35
from pre_commit_mirror_maker.languages import golang_get_package_versions
46
from pre_commit_mirror_maker.languages import node_get_package_versions
57
from pre_commit_mirror_maker.languages import python_get_package_versions
@@ -42,8 +44,20 @@ def test_rust_get_package_version_output():
4244
assert_all_text(ret)
4345

4446

45-
def test_golang_get_package_version_output():
46-
ret = golang_get_package_versions('mvdan.cc/gofumpt')
47+
@pytest.mark.parametrize(
48+
'package_name',
49+
(
50+
'mvdan.cc/gofumpt',
51+
'mvdan.cc/sh/v3/cmd/shfmt',
52+
),
53+
)
54+
def test_golang_get_package_version_output(package_name):
55+
ret = golang_get_package_versions(package_name)
4756
assert ret
4857
assert not any(v.startswith('v') for v in ret)
4958
assert_all_text(ret)
59+
60+
61+
def test_golang_get_package_version_invalid_package():
62+
with pytest.raises(ValueError):
63+
golang_get_package_versions('mvdan.cc/foo')

0 commit comments

Comments
 (0)