From 4dac4736e73ec6414b5848714c5dd7f9f9171784 Mon Sep 17 00:00:00 2001 From: Todd Gamblin Date: Thu, 19 Oct 2017 14:27:15 -0700 Subject: spack blame can take a path to a file in the Spack repo (#5793) - Previously `spack blame` only worked for package names; now it works for paths as well, so developers can use it on core spack files. --- lib/spack/spack/cmd/blame.py | 23 ++++++++++++++++------- lib/spack/spack/test/cmd/blame.py | 12 ++++++++++++ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/lib/spack/spack/cmd/blame.py b/lib/spack/spack/cmd/blame.py index 3bf5e37abb..48ee6dd029 100644 --- a/lib/spack/spack/cmd/blame.py +++ b/lib/spack/spack/cmd/blame.py @@ -22,6 +22,7 @@ # License along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################## +import os import re import llnl.util.tty as tty @@ -52,26 +53,34 @@ def setup_parser(subparser): help='show git blame output instead of summary') subparser.add_argument( - 'package_name', help='name of package to show contributions for') + 'package_name', help='name of package to show contributions for, ' + 'or path to a file in the spack repo') def blame(parser, args): # make sure this is a git repo if not spack_is_git_repo(): - tty.die("This spack is not a git clone. Can't use 'spack pkg'") + tty.die("This spack is not a git clone. Can't use 'spack blame'") git = which('git', required=True) - # Get package and package file name - pkg = spack.repo.get(args.package_name) - package_py = pkg.module.__file__.rstrip('c') # .pyc -> .py + # Get name of file to blame + blame_file = None + if os.path.isfile(args.package_name): + path = os.path.realpath(args.package_name) + if path.startswith(spack.prefix): + blame_file = path + + if not blame_file: + pkg = spack.repo.get(args.package_name) + blame_file = pkg.module.__file__.rstrip('c') # .pyc -> .py # get git blame for the package with working_dir(spack.prefix): if args.view == 'git': - git('blame', package_py) + git('blame', blame_file) return else: - output = git('blame', '--line-porcelain', package_py, output=str) + output = git('blame', '--line-porcelain', blame_file, output=str) lines = output.split('\n') # Histogram authors diff --git a/lib/spack/spack/test/cmd/blame.py b/lib/spack/spack/test/cmd/blame.py index 9342ff1f7c..0f03461f55 100644 --- a/lib/spack/spack/test/cmd/blame.py +++ b/lib/spack/spack/test/cmd/blame.py @@ -24,6 +24,9 @@ ############################################################################## import pytest +from llnl.util.filesystem import working_dir + +import spack import spack.cmd from spack.main import SpackCommand from spack.util.executable import which @@ -51,6 +54,15 @@ def test_blame_by_percent(builtin_mock): assert 'EMAIL' in out +def test_blame_file(builtin_mock): + """Sanity check the blame command to make sure it works.""" + with working_dir(spack.prefix): + out = blame('bin/spack') + assert 'LAST_COMMIT' in out + assert 'AUTHOR' in out + assert 'EMAIL' in out + + def test_blame_by_git(builtin_mock, capfd): """Sanity check the blame command to make sure it works.""" with capfd.disabled(): -- cgit v1.2.3-60-g2f50