Skip to content

Commit 56c5808

Browse files
committed
feat: Implement Hex Enumerable Ecosystem
1 parent b9ea895 commit 56c5808

File tree

4 files changed

+211
-1
lines changed

4 files changed

+211
-1
lines changed

osv/ecosystems/_ecosystems.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from .cran import CRAN
2222
from .debian import Debian, DPKG
2323
from .haskell import Hackage, GHC
24+
from .hex import Hex
2425
from .maven import Maven
2526
from .nuget import NuGet
2627
from .packagist import Packagist
@@ -46,7 +47,7 @@
4647
'GHC': GHC,
4748
'Go': SemverEcosystem,
4849
'Hackage': Hackage,
49-
'Hex': SemverEcosystem,
50+
'Hex': Hex,
5051
'Julia': SemverEcosystem,
5152
'Mageia': RPM,
5253
'Maven': Maven,

osv/ecosystems/cassettes/HexEcosystemTest.test_enumerate.yaml

Lines changed: 122 additions & 0 deletions
Large diffs are not rendered by default.

osv/ecosystems/hex.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
"""Hex ecosystem helper."""
15+
16+
import json
17+
from typing import List
18+
19+
from . import config
20+
from .ecosystems_base import EnumerableEcosystem, EnumerateError
21+
from .semver_ecosystem_helper import SemverEcosystem
22+
from ..request_helper import RequestError, RequestHelper
23+
24+
class Hex(EnumerableEcosystem, SemverEcosystem):
25+
"""Hex ecosystem"""
26+
27+
_API_PACKAGE_URL = 'https://hex.pm/api/packages/{package}'
28+
29+
def enumerate_versions(self,
30+
package,
31+
introduced,
32+
fixed=None,
33+
last_affected=None,
34+
limits=None):
35+
url = self._API_PACKAGE_URL.format(package=package.lower())
36+
request_helper = RequestHelper(config.shared_cache)
37+
try:
38+
text_response = request_helper.get(url)
39+
except RequestError as ex:
40+
if ex.response.status_code == 404:
41+
raise EnumerateError(f'Package {package} not found') from ex
42+
raise RuntimeError('Failed to get Hex versions for '
43+
f'{package} with: {ex.response.text}') from ex
44+
45+
response = json.loads(text_response)
46+
versions: list[str] = [x['version'] for x in response['releases']]
47+
self.sort_versions(versions)
48+
49+
return self._get_affected_versions(versions, introduced, fixed,
50+
last_affected, limits)

osv/ecosystems/hex_test.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
"""Hex ecosystem helper tests."""
15+
16+
import os
17+
import vcr.unittest
18+
19+
from .. import ecosystems
20+
21+
22+
class HexEcosystemTest(vcr.unittest.VCRTestCase):
23+
"""Hex ecosystem helper tests."""
24+
_TEST_DATA_DIR = os.path.join(
25+
os.path.dirname(os.path.abspath(__file__)), 'testdata')
26+
27+
def test_enumerate(self):
28+
"""Test enumerate."""
29+
ecosystem = ecosystems.get('Hex')
30+
self.assertEqual(['3.6.3', '3.7.0'],
31+
ecosystem.enumerate_versions(
32+
'ash', '3.6.3',
33+
last_affected='3.7.0'))
34+
self.assertEqual(['3.6.3', '3.7.0'],
35+
ecosystem.enumerate_versions(
36+
'ash', '3.6.3',
37+
fixed='3.7.1'))

0 commit comments

Comments
 (0)