diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 0a1f34ac2e32395f5ea4aeafc97165e424b63d5e..5f0268af37d27ed271d876de4fd9399ae6e55f6f 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -300,8 +300,6 @@ flake8:
- .python:flake8
- .lint
needs: []
- allow_failure: true
- # ... for now
.rpmlint:
extends:
diff --git a/misc/generate_vcs_info.py b/misc/generate_vcs_info.py
index 38df464ec40d7f8eff383114273017b6d3b2d4d9..124eee21a56bf2bd6209825846e73f344f794e62 100644
--- a/misc/generate_vcs_info.py
+++ b/misc/generate_vcs_info.py
@@ -20,270 +20,142 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-#
-# preamble
-#
-
-# metadata
-from __future__ import print_function
-__author__ = 'Adam Mercer '
-
-# import required system modules
import os
-import sys
-import time
-import optparse
-import filecmp
-import shutil
import subprocess
+import time
+
+__author__ = 'Adam Mercer '
-#
-# class definitions
-#
# version info class
class git_info(object):
- def __init__(self):
- id = None
- date = None
- branch = None
- tag = None
- author = None
- committer = None
- status = None
-
-# git invocation error exception handler
-class GitInvocationError(LookupError):
- pass
-
-#
-# helper methods
-#
-
-# command line option parsing
-def parse_args():
- # usage information
- usage = '%prog [options] project src_dir build_dir'
-
- # define option parser
- parser = optparse.OptionParser(usage=usage)
- parser.add_option('--sed', action='store_true', default=False,
- help='output sed commands for version replacement')
- parser.add_option('--sed-file', action='store_true', default=False,
- help='output sed file for version replacement')
-
- # parse command line options
- opts, args = parser.parse_args()
-
- # check for positional arguments
- if (len(args) != 3):
- parser.error('incorrect number of command line options specified')
-
- # check that both --sed and --file are not specified
- if opts.sed and opts.sed_file:
- parser.error('cannot specify both --sed and --sed-file')
-
- return opts, args[0], args[1], args[2]
-
-#
-# process management methods
-#
-
-# return output from running given command
-def call_out(command):
- """
- Run the given command (with shell=False) and return a tuple of
- (int returncode, str output). Strip the output of enclosing whitespace.
- """
- # start external command process
- p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-
- # get outputs
- out, _ = p.communicate()
-
- return p.returncode, str(out.strip().decode('utf8'))
+ def __init__(self):
+ self.id = None
+ self.date = None
+ self.branch = None
+ self.tag = None
+ self.author = None
+ self.committer = None
+ self.status = None
+
+
+def check_output(command):
+ """Wrapper for subprocess.check_output that discards stderr.
+ """
+ try:
+ return subprocess.check_output(
+ command,
+ encoding="utf-8",
+ stderr=subprocess.DEVNULL,
+ ).strip()
+ except subprocess.CalledProcessError as exc:
+ raise RuntimeError from exc
-def check_call_out(command):
- """
- Run the given command (with shell=False) and return the output as a
- string. Strip the output of enclosing whitespace.
- If the return code is non-zero, throw GitInvocationError.
- """
- # start external command process
- p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-
- # get outputs
- out, _ = p.communicate()
-
- # throw exception if process failed
- if p.returncode != 0:
- raise GitInvocationError('failed to run "%s"' % " ".join(command))
- return str(out.strip().decode('utf8'))
-
-#
-# git version method
-#
def in_git_repository():
- """
- Return True if git is available and we are in a git repository; else
- return False.
+ """
+ Return True if git is available and we are in a git repository; else
+ return False.
+
+ NB: Unfortunately there is a magic number without any documentation to back
+ it up. It turns out that git status returns non-zero exit codes for all
+ sorts of success conditions, but I cannot find any documentation of them.
+ 128 was determined empirically. I sure hope that it's portable.
+ """
+ try:
+ return subprocess.call(
+ ('git', 'status'),
+ stdout=subprocess.DEVNULL,
+ stderr=subprocess.DEVNULL,
+ ) != 128
+ except OSError:
+ # git is not installed
+ return False
- NB: Unfortunately there is a magic number without any documentation to back
- it up. It turns out that git status returns non-zero exit codes for all sorts
- of success conditions, but I cannot find any documentation of them. 128 was
- determined empirically. I sure hope that it's portable.
- """
- try:
- return call_out(('git', 'status'))[0] != 128
- except OSError:
- # git is not installed
- return False
-# generate sed command file containing version info
def generate_git_version_info():
- if not in_git_repository():
- raise GitInvocationError(
- 'Not in git checkout or cannot find git executable.')
-
- # info object
- info = git_info()
-
- # determine basic info about the commit
- # %H -- full git hash id
- # %ct -- commit time
- # %an, %ae -- author name, email
- # %cn, %ce -- committer name, email
- git_id, git_udate, git_author_name, git_author_email, \
- git_committer_name, git_committer_email = \
- check_call_out(('git', 'log', '-1',
- '--pretty=format:%H,%ct,%an,%ae,%cn,%ce')).split(",")
-
- git_date = time.strftime('%Y-%m-%d %H:%M:%S +0000',
- time.gmtime(float(git_udate)))
- git_author = '%s <%s>' % (git_author_name, git_author_email)
- git_committer = '%s <%s>' % (git_committer_name, git_committer_email)
-
- # determine branch
- branch_match = check_call_out(('git', 'rev-parse',
- '--symbolic-full-name', 'HEAD'))
- if branch_match == "HEAD":
- git_branch = None
- else:
- git_branch = os.path.basename(branch_match)
-
- # determine tag
- try:
- git_tag = check_call_out(('git', 'describe', '--exact-match',
- '--tags', git_id))
- except GitInvocationError:
- git_tag = None
-
- # refresh index
- check_call_out(('git', 'update-index', '-q', '--refresh'))
-
- # check working copy for changes
- status_output = subprocess.call(('git', 'diff-files', '--quiet'))
- if status_output != 0:
- git_status = 'UNCLEAN: Modified working tree'
- else:
- # check index for changes
- status_output = subprocess.call(('git', 'diff-index', '--cached',
- '--quiet', 'HEAD'))
- if status_output != 0:
- git_status = 'UNCLEAN: Modified index'
- else:
- git_status = 'CLEAN: All modifications committed'
-
- # determine version strings
- info.id = git_id
- info.date = git_date
- info.branch = git_branch
- info.tag = git_tag
- info.author = git_author
- info.committer = git_committer
- info.status = git_status
-
- return info
-
-#
-# main program entry point
-#
-
-if __name__ == "__main__":
- # parse command line options
- options, project, src_dir, build_dir = parse_args()
-
- # filenames
- basename = '%sVCSInfo.h' % project
- infile = '%s.in' % basename # used after chdir to src_dir
- tmpfile= '%s/%s.tmp' % (build_dir, basename)
- srcfile = '%s/%s' % (src_dir, basename)
- dstfile = '%s/%s' % (build_dir, basename)
-
- # copy vcs header to build_dir, if appropriate
- if os.access(srcfile, os.F_OK) and not os.access(dstfile, os.F_OK):
- shutil.copy(srcfile, dstfile)
-
- # change to src_dir
- os.chdir(src_dir)
-
- # generate version information output, if appropriate
- # NB: First assume that git works and we are in a repository since
- # checking it is expensive and rarely necessary.
- try:
- info = generate_git_version_info()
- except GitInvocationError:
- # We expect a failure if either git is not available or we are not
- # in a repository. Any other failure is unexpected and should throw an
- # error.
if not in_git_repository():
- sys.exit(0)
+ raise RuntimeError(
+ 'not in git checkout or cannot find git executable',
+ )
+
+ # info object
+ info = git_info()
+
+ # determine basic info about the commit
+ # %H -- full git hash id
+ # %ct -- commit time
+ # %an, %ae -- author name, email
+ # %cn, %ce -- committer name, email
+ (
+ git_id,
+ git_udate,
+ git_author_name,
+ git_author_email,
+ git_committer_name,
+ git_committer_email,
+ ) = check_output((
+ 'git',
+ 'log',
+ '-1',
+ '--pretty=format:%H,%ct,%an,%ae,%cn,%ce',
+ )).split(",")
+
+ git_date = time.strftime(
+ '%Y-%m-%d %H:%M:%S +0000',
+ time.gmtime(float(git_udate)),
+ )
+ git_author = '%s <%s>' % (git_author_name, git_author_email)
+ git_committer = '%s <%s>' % (git_committer_name, git_committer_email)
+
+ # determine branch
+ branch_match = check_output((
+ 'git',
+ 'rev-parse',
+ '--symbolic-full-name',
+ 'HEAD',
+ ))
+ if branch_match == "HEAD":
+ git_branch = None
else:
- sys.exit("Unexpected failure in discovering the git version")
-
- if options.sed_file:
- # output sed command file to stdout
- print('s/@ID@/%s/g' % info.id)
- print('s/@DATE@/%s/g' % info.date)
- print('s/@BRANCH@/%s/g' % info.branch)
- print('s/@TAG@/%s/g' % info.tag)
- print('s/@AUTHOR@/%s/g' % info.author)
- print('s/@COMMITTER@/%s/g' % info.committer)
- print('s/@STATUS@/%s/g' % info.status)
- elif options.sed:
- # generate sed command line options
- sed_cmd = ('sed',
- '-e', 's/@ID@/%s/' % info.id,
- '-e', 's/@DATE@/%s/' % info.date,
- '-e', 's/@BRANCH@/%s/' % info.branch,
- '-e', 's/@TAG@/%s/' % info.tag,
- '-e', 's/@AUTHOR@/%s/' % info.author,
- '-e', 's/@COMMITTER@/%s/' % info.committer,
- '-e', 's/@STATUS@/%s/' % info.status,
- infile)
-
- # create tmp file
- # FIXME: subprocess.check_call becomes available in Python 2.5
- sed_retcode = subprocess.call(sed_cmd, stdout=open(tmpfile, "w"))
- if sed_retcode:
- raise GitInvocationError(
- "Failed call (modulo quoting): %s > %s"
- % (" ".join(sed_cmd), tmpfile))
-
- # only update vcs header if appropriate
- if os.access(dstfile, os.F_OK) and filecmp.cmp(dstfile, tmpfile):
- os.remove(tmpfile)
+ git_branch = os.path.basename(branch_match)
+
+ # determine tag
+ try:
+ git_tag = check_output((
+ 'git',
+ 'describe',
+ '--exact-match',
+ '--tags',
+ git_id,
+ ))
+ except RuntimeError:
+ git_tag = None
+
+ # refresh index
+ subprocess.check_call(('git', 'update-index', '-q', '--refresh'))
+
+ # check working copy for changes
+ if subprocess.call(('git', 'diff-files', '--quiet')):
+ git_status = 'UNCLEAN: Modified working tree'
+ elif subprocess.call((
+ 'git',
+ 'diff-index',
+ '--cached',
+ '--quiet',
+ 'HEAD',
+ )):
+ git_status = 'UNCLEAN: Modified index'
else:
- os.rename(tmpfile, dstfile)
- else:
- # output version info
- print('Id: %s' % info.id)
- print('Date: %s' % info.date)
- print('Branch: %s' % info.branch)
- print('Tag: %s' % info.tag)
- print('Author: %s' % info.author)
- print('Committer: %s' % info.committer)
- print('Status: %s' % info.status)
-
-# vim: syntax=python tw=72 ts=2 et
+ git_status = 'CLEAN: All modifications committed'
+
+ # determine version strings
+ info.id = git_id
+ info.date = git_date
+ info.branch = git_branch
+ info.tag = git_tag
+ info.author = git_author
+ info.committer = git_committer
+ info.status = git_status
+
+ return info
diff --git a/misc/git_version.py.in b/misc/git_version.py.in
index 278dc79563e6e9a14555097489721873bdd0ad64..07df65a85d88e191d6a0be21faa4bd7722747abf 100644
--- a/misc/git_version.py.in
+++ b/misc/git_version.py.in
@@ -34,9 +34,11 @@ Repository status: {0.status}"""
import warnings
+
class VersionMismatchError(ValueError):
pass
+
def check_match(foreign_id, onmismatch="raise"):
"""
If foreign_id != id, perform an action specified by the onmismatch
@@ -56,4 +58,3 @@ def check_match(foreign_id, onmismatch="raise"):
# in the backtrace, show calling code
warnings.warn(msg, UserWarning)
-
diff --git a/setup.cfg b/setup.cfg
index 5a42005ef66f3e34e08a37ecdeef916b0e219e4b..32b0304d228acce4f8682bd567ac2742abb31216 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -5,3 +5,23 @@ license_file = LICENSE
source = glue
omit =
glue/markup.py
+
+[flake8]
+select =
+ F,
+ W,
+extend-ignore =
+ W191, # tab indentation
+exclude =
+ __pycache__,
+ .eggs/,
+ .git/,
+ build/,
+ venv/,
+ # deprecated modules
+ glue/iterutils.py,
+ glue/ligolw/**.py,
+ glue/markup.py,
+ test/iterutils_verify.py,
+ test/*ligolw*.py,
+ test/ligo_lw*.py,
diff --git a/setup.py b/setup.py
index eec75d9896c3baf2f087c7ce35913800476eaf57..d2ee69eb91e1366a6e47e7703e719f5739fff0ef 100644
--- a/setup.py
+++ b/setup.py
@@ -40,11 +40,13 @@ def write_build_info():
)
# determine builder
- retcode, builder_name = gvcsi.call_out(('git', 'config', 'user.name'))
- if retcode:
+ try:
+ builder_name = gvcsi.check_output(('git', 'config', 'user.name'))
+ except RuntimeError:
builder_name = "Unknown User"
- retcode, builder_email = gvcsi.call_out(('git', 'config', 'user.email'))
- if retcode:
+ try:
+ builder_email = gvcsi.check_output(('git', 'config', 'user.email'))
+ except RuntimeError:
builder_email = ""
vcs_info.builder = "%s <%s>" % (builder_name, builder_email)
@@ -58,7 +60,7 @@ class glue_build_py(build_py.build_py):
self.announce("generating glue/git_version.py", level=2)
try:
write_build_info()
- except gvcsi.GitInvocationError:
+ except RuntimeError:
if not os.path.exists("glue/git_version.py"):
raise
# probably being built from a release tarball; don't overwrite
diff --git a/test/lal_verify.py b/test/lal_verify.py
index 017eba45f6cf979ed504515dda60f8327e8600f3..84d0d5e1f448936ec448e483b27bf5c95242d5c1 100644
--- a/test/lal_verify.py
+++ b/test/lal_verify.py
@@ -127,7 +127,7 @@ class test_LIGOTimeGPS(unittest.TestCase):
arg2 = 100**(random.random() * 2 - 1)
try:
self.assertEqual(abs(op(arg1, arg2) - fromswig(swigop(toswig(arg1), arg2))) <= 1e-9, True)
- except AssertionError as s:
+ except AssertionError:
raise AssertionError("%s(%s, %s) comparison failed: %s != %s" % (key, str(arg1), "%.17g" % arg2, str(op(arg1, arg2)), str(swigop(toswig(arg1), arg2))))
diff --git a/test/test_ldbd.py b/test/test_ldbd.py
index 81acdab9fc1236b718bb2914e059009befa2ad42..9f8ca64c77d5536e1fc254e40dfe6fa1f4b6b1f4 100644
--- a/test/test_ldbd.py
+++ b/test/test_ldbd.py
@@ -24,7 +24,7 @@ LIGO_LW_XML = """
-""".strip()
+""".strip() # noqa: E501
class TestLdbd(unittest.TestCase):