spack list: latest version (JSON) (#11652)
List the latest version of each package in JSON encoding. Preparation for consumption for a "spack badge" service.
This commit is contained in:
parent
6d56d45454
commit
61333dc606
4 changed files with 81 additions and 1 deletions
|
@ -13,6 +13,7 @@
|
|||
import re
|
||||
import sys
|
||||
import math
|
||||
import json
|
||||
|
||||
import llnl.util.tty as tty
|
||||
from llnl.util.tty.colify import colify
|
||||
|
@ -20,6 +21,7 @@
|
|||
import spack.dependency
|
||||
import spack.repo
|
||||
import spack.cmd.common.arguments as arguments
|
||||
from spack.version import VersionList
|
||||
|
||||
description = "list and search available packages"
|
||||
section = "basic"
|
||||
|
@ -116,6 +118,46 @@ def rows_for_ncols(elts, ncols):
|
|||
yield row
|
||||
|
||||
|
||||
def get_dependencies(pkg):
|
||||
all_deps = {}
|
||||
for deptype in spack.dependency.all_deptypes:
|
||||
deps = pkg.dependencies_of_type(deptype)
|
||||
all_deps[deptype] = [d for d in deps]
|
||||
|
||||
return all_deps
|
||||
|
||||
|
||||
@formatter
|
||||
def version_json(pkg_names, out):
|
||||
"""Print all packages with their latest versions."""
|
||||
pkgs = [spack.repo.get(name) for name in pkg_names]
|
||||
|
||||
out.write('[\n')
|
||||
|
||||
# output name and latest version for each package
|
||||
pkg_latest = ",\n".join([
|
||||
' {{"name": "{0}",\n'
|
||||
' "latest_version": "{1}",\n'
|
||||
' "versions": {2},\n'
|
||||
' "homepage": "{3}",\n'
|
||||
' "file": "{4}",\n'
|
||||
' "maintainers": {5},\n'
|
||||
' "dependencies": {6}'
|
||||
'}}'.format(
|
||||
pkg.name,
|
||||
VersionList(pkg.versions).preferred(),
|
||||
json.dumps([str(v) for v in reversed(sorted(pkg.versions))]),
|
||||
pkg.homepage,
|
||||
github_url(pkg),
|
||||
json.dumps(pkg.maintainers),
|
||||
json.dumps(get_dependencies(pkg))
|
||||
) for pkg in pkgs
|
||||
])
|
||||
out.write(pkg_latest)
|
||||
# important: no trailing comma in JSON arrays
|
||||
out.write('\n]\n')
|
||||
|
||||
|
||||
@formatter
|
||||
def html(pkg_names, out):
|
||||
"""Print out information on all packages in Sphinx HTML.
|
||||
|
|
|
@ -44,6 +44,15 @@ def test_list_format_name_only():
|
|||
assert 'hdf5' in output
|
||||
|
||||
|
||||
@pytest.mark.maybeslow
|
||||
def test_list_format_version_json():
|
||||
output = list('--format', 'version_json')
|
||||
assert ' {"name": "cloverleaf3d",' in output
|
||||
assert ' {"name": "hdf5",' in output
|
||||
import json
|
||||
json.loads(output)
|
||||
|
||||
|
||||
@pytest.mark.maybeslow
|
||||
def test_list_format_html():
|
||||
output = list('--format', 'html')
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
"""
|
||||
import pytest
|
||||
|
||||
from spack.version import Version, ver
|
||||
from spack.version import Version, VersionList, ver
|
||||
|
||||
|
||||
def assert_ver_lt(a, b):
|
||||
|
@ -548,3 +548,15 @@ def test_get_item():
|
|||
# Raise TypeError on tuples
|
||||
with pytest.raises(TypeError):
|
||||
b.__getitem__(1, 2)
|
||||
|
||||
|
||||
def test_list_highest():
|
||||
vl = VersionList(['master', '1.2.3', 'develop', '3.4.5', 'foobar'])
|
||||
assert vl.highest() == Version('develop')
|
||||
assert vl.lowest() == Version('foobar')
|
||||
assert vl.highest_numeric() == Version('3.4.5')
|
||||
|
||||
vl2 = VersionList(['master', 'develop'])
|
||||
assert vl2.highest_numeric() is None
|
||||
assert vl2.preferred() == Version('develop')
|
||||
assert vl2.lowest() == Version('master')
|
||||
|
|
|
@ -643,6 +643,23 @@ def highest(self):
|
|||
else:
|
||||
return self[-1].highest()
|
||||
|
||||
def highest_numeric(self):
|
||||
"""Get the highest numeric version in the list."""
|
||||
numeric_versions = list(filter(
|
||||
lambda v: str(v) not in infinity_versions,
|
||||
self.versions))
|
||||
if not any(numeric_versions):
|
||||
return None
|
||||
else:
|
||||
return numeric_versions[-1].highest()
|
||||
|
||||
def preferred(self):
|
||||
"""Get the preferred (latest) version in the list."""
|
||||
latest = self.highest_numeric()
|
||||
if latest is None:
|
||||
latest = self.highest()
|
||||
return latest
|
||||
|
||||
@coerced
|
||||
def overlaps(self, other):
|
||||
if not other or not self:
|
||||
|
|
Loading…
Reference in a new issue