From d9745b6d8ed06f8d281e5e67b4d99358e71c45dd Mon Sep 17 00:00:00 2001 From: Duncan Macleod Date: Fri, 14 Jan 2022 16:12:14 +0000 Subject: [PATCH 1/5] setup.cfg: add configuration for flake8 --- setup.cfg | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/setup.cfg b/setup.cfg index 5a42005e..32b0304d 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, -- GitLab From 2aa85b907c995b5ae630e93c82b9ac731c5f27fb Mon Sep 17 00:00:00 2001 From: Duncan Macleod Date: Fri, 14 Jan 2022 16:50:39 +0000 Subject: [PATCH 2/5] misc: update generate_vcs_info.py mainly formatting and syntax, minor structural changes --- misc/generate_vcs_info.py | 376 +++++++++++++------------------------- misc/git_version.py.in | 3 +- setup.py | 12 +- 3 files changed, 133 insertions(+), 258 deletions(-) diff --git a/misc/generate_vcs_info.py b/misc/generate_vcs_info.py index 38df464e..124eee21 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 278dc795..07df65a8 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.py b/setup.py index eec75d98..d2ee69eb 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 -- GitLab From 5170a45132c6933beb35a576228fbfbbc893b726 Mon Sep 17 00:00:00 2001 From: Duncan Macleod Date: Fri, 14 Jan 2022 16:54:59 +0000 Subject: [PATCH 3/5] test: remove unused variable in lal_verify.py --- test/lal_verify.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/lal_verify.py b/test/lal_verify.py index 017eba45..84d0d5e1 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)))) -- GitLab From 7edc70bfdf4f72d6cbb0a69e03a0d67b24dbf7d4 Mon Sep 17 00:00:00 2001 From: Duncan Macleod Date: Fri, 14 Jan 2022 16:55:45 +0000 Subject: [PATCH 4/5] test: fix lint issue in test_ldbd.py --- test/test_ldbd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_ldbd.py b/test/test_ldbd.py index 81acdab9..9f8ca64c 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): -- GitLab From cfd41795b017724f95566178f022e41ad6856654 Mon Sep 17 00:00:00 2001 From: Duncan Macleod Date: Mon, 17 Jan 2022 14:47:30 +0000 Subject: [PATCH 5/5] ci: don't allow the flake8 job to fail --- .gitlab-ci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0a1f34ac..5f0268af 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: -- GitLab