From c029c8ff89b3567ef2fde8f238add57bf1314423 Mon Sep 17 00:00:00 2001 From: Todd Gamblin Date: Thu, 30 Jan 2020 19:07:24 -0800 Subject: `spack -V` is now more descriptive for dev branches `spack -V` previously always returned the version of spack from `spack.spack_version`. This gives us a general idea of what version users are on, but if they're on `develop` or on some branch, we have to ask more questions. This PR makes `spack -V` check whether this instance of Spack is a git repository, and if it is, it appends useful information from `git describe --tags` to the version. Specifically, it adds: - number of commits since the last release tag - abbreviated (but unique) commit hash So, if you're on `develop` you might get something like this: $ spack -V 0.13.3-912-3519a1762 This means you're on commit 3519a1762, which is 912 commits ahead of the 0.13.3 release. If you are on a release branch, or if you are using a tarball of Spack, you'll get the usual `spack.spack_version`: $ spack -V 0.13.3 This should help when asking users what version they are on, since a lot of people use the `develop` branch. --- lib/spack/spack/main.py | 32 +++++++++++++++++++++- lib/spack/spack/test/main.py | 63 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 lib/spack/spack/test/main.py (limited to 'lib') diff --git a/lib/spack/spack/main.py b/lib/spack/spack/main.py index 4ce4ae331e..4386f50435 100644 --- a/lib/spack/spack/main.py +++ b/lib/spack/spack/main.py @@ -13,6 +13,7 @@ from __future__ import print_function import sys import re import os +import os.path import inspect import pstats import argparse @@ -35,6 +36,7 @@ import spack.repo import spack.store import spack.util.debug import spack.util.path +import spack.util.executable as exe from spack.error import SpackError @@ -107,6 +109,34 @@ def add_all_commands(parser): parser.add_command(cmd) +def get_version(): + """Get a descriptive version of this instance of Spack. + + If this is a git repository, and if it is not on a release tag, + return a string like: + + release_version-commits_since_release-commit + + If we *are* at a release tag, or if this is not a git repo, return + the real spack release number (e.g., 0.13.3). + + """ + git_path = os.path.join(spack.paths.prefix, ".git") + if os.path.exists(git_path): + git = exe.which("git") + if git: + desc = git("-C", spack.paths.prefix, "describe", "--tags", + output=str, fail_on_error=False) + + if git.returncode == 0: + match = re.match(r"v([^-]+)-([^-]+)-g([a-f\d]+)", desc) + if match: + v, n, commit = match.groups() + return "%s-%s-%s" % (v, n, commit) + + return spack.spack_version + + def index_commands(): """create an index of commands by section for this help level""" index = {} @@ -679,7 +709,7 @@ def main(argv=None): # -h, -H, and -V are special as they do not require a command, but # all the other options do nothing without a command. if args.version: - print(spack.spack_version) + print(get_version()) return 0 elif args.help: sys.stdout.write(parser.format_help(level=args.help)) diff --git a/lib/spack/spack/test/main.py b/lib/spack/spack/test/main.py new file mode 100644 index 0000000000..c35a6e195b --- /dev/null +++ b/lib/spack/spack/test/main.py @@ -0,0 +1,63 @@ +# Copyright 2013-2020 Lawrence Livermore National Security, LLC and other +# Spack Project Developers. See the top-level COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) + +import os + +import llnl.util.filesystem as fs + +import spack.paths +from spack.main import get_version, main + + +def test_get_version_no_match_git(tmpdir, working_env): + git = str(tmpdir.join("git")) + with open(git, "w") as f: + f.write("""#!/bin/sh +echo v0.13.3 +""") + fs.set_executable(git) + + os.environ["PATH"] = str(tmpdir) + assert spack.spack_version == get_version() + + +def test_get_version_match_git(tmpdir, working_env): + git = str(tmpdir.join("git")) + with open(git, "w") as f: + f.write("""#!/bin/sh +echo v0.13.3-912-g3519a1762 +""") + fs.set_executable(git) + + os.environ["PATH"] = str(tmpdir) + assert "0.13.3-912-3519a1762" == get_version() + + +def test_get_version_no_repo(tmpdir, monkeypatch): + monkeypatch.setattr(spack.paths, "prefix", str(tmpdir)) + assert spack.spack_version == get_version() + + +def test_get_version_no_git(tmpdir, working_env): + os.environ["PATH"] = str(tmpdir) + assert spack.spack_version == get_version() + + +def test_main_calls_get_version(tmpdir, capsys, working_env): + os.environ["PATH"] = str(tmpdir) + main(["-V"]) + assert spack.spack_version == capsys.readouterr()[0].strip() + + +def test_get_version_bad_git(tmpdir, working_env): + bad_git = str(tmpdir.join("git")) + with open(bad_git, "w") as f: + f.write("""#!/bin/sh +exit 1 +""") + fs.set_executable(bad_git) + + os.environ["PATH"] = str(tmpdir) + assert spack.spack_version == get_version() -- cgit v1.2.3-60-g2f50