summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/spack/spack/cmd/list.py42
-rw-r--r--lib/spack/spack/test/cmd/list.py9
-rw-r--r--lib/spack/spack/test/versions.py14
-rw-r--r--lib/spack/spack/version.py17
4 files changed, 81 insertions, 1 deletions
diff --git a/lib/spack/spack/cmd/list.py b/lib/spack/spack/cmd/list.py
index 9fe2809097..570dcc7e27 100644
--- a/lib/spack/spack/cmd/list.py
+++ b/lib/spack/spack/cmd/list.py
@@ -13,6 +13,7 @@ import os
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 @@ from llnl.util.tty.colify import colify
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.
diff --git a/lib/spack/spack/test/cmd/list.py b/lib/spack/spack/test/cmd/list.py
index 3cd8207ba2..6590b9ab2a 100644
--- a/lib/spack/spack/test/cmd/list.py
+++ b/lib/spack/spack/test/cmd/list.py
@@ -45,6 +45,15 @@ def test_list_format_name_only():
@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')
assert '<div class="section" id="cloverleaf3d">' in output
diff --git a/lib/spack/spack/test/versions.py b/lib/spack/spack/test/versions.py
index 11da83df8c..b39da0c698 100644
--- a/lib/spack/spack/test/versions.py
+++ b/lib/spack/spack/test/versions.py
@@ -9,7 +9,7 @@ where it makes sense.
"""
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')
diff --git a/lib/spack/spack/version.py b/lib/spack/spack/version.py
index 0235ce0182..286943119f 100644
--- a/lib/spack/spack/version.py
+++ b/lib/spack/spack/version.py
@@ -643,6 +643,23 @@ class VersionList(object):
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: