]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Add a script that finds deprecated items. 4344/head
authorDavid Wells <wellsd2@rpi.edu>
Thu, 4 May 2017 19:17:58 +0000 (15:17 -0400)
committerDavid Wells <wellsd2@rpi.edu>
Mon, 8 May 2017 12:16:42 +0000 (08:16 -0400)
contrib/utilities/print_deprecated.py [new file with mode: 0644]

diff --git a/contrib/utilities/print_deprecated.py b/contrib/utilities/print_deprecated.py
new file mode 100644 (file)
index 0000000..642173c
--- /dev/null
@@ -0,0 +1,140 @@
+#!/usr/bin/env python
+
+## ---------------------------------------------------------------------
+##
+## Copyright (C) 2017 by the deal.II authors
+##
+## This file is part of the deal.II library.
+##
+## The deal.II library is free software; you can use it, redistribute
+## it, and/or modify it under the terms of the GNU Lesser General
+## Public License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+## The full text of the license can be found in the file LICENSE at
+## the top level of the deal.II distribution.
+##
+## ---------------------------------------------------------------------
+"""Search the ./include directory and print out a summary of each deprecated
+object, class, function, etc. Compatile with emacs' compilation-mode.
+
+You may need to run
+
+    git fetch --tags upstream
+
+to make the tag (i.e., which release corresponds to which commit) printing work.
+"""
+
+from __future__ import print_function
+
+import datetime
+import errno
+import os
+import re
+import subprocess
+import sys
+
+
+def decode_and_split(string):
+    """Decode a string as unicode and split its lines. Works with python 2 and
+    python 3.
+    """
+    if sys.version_info.major > 2:
+        return str(string, 'utf8').splitlines()
+    else:
+        return unicode(string, errors='replace').splitlines()
+
+
+class DeprecatedDeclaration(object):
+    """A record of a deprecated declaration. The input line containing the
+    deprecation usually comes from some grep-like program and is assumed to have
+    a file name, line number, and contain DEAL_II_DEPRECATED, e.g.,
+
+    ./include/deal.II/base/utilities.h:457: bool job_supports_mpi() DEAL_II_DEPRECATED;
+
+    is one such valid line. The file name and line number are used to query git
+    for information regarding when the deprecation notice appeared. The line
+    itself is printed out later.
+    """
+    def __init__(self, line):
+        assert "DEAL_II_DEPRECATED" in line
+        # in case the line contains extra ':'s, split input based on where grep
+        # puts the line number:
+        line_number_re = re.search(":[0-9]+:", line)
+        if line_number_re:
+            line_number_range = (line_number_re.regs[0][0] + 1,
+                                 line_number_re.regs[0][1] - 1)
+            self.file_name = line[0:line_number_range[0] - 1]
+            self.line_n = int(line[slice(*line_number_range)])
+            self.deprecation_line = line[line_number_range[1] + 1:].strip()
+        else:
+            raise ValueError("The given line does not contain a line number of "
+                             "the form, e.g., :42:.")
+
+        git_log_output = subprocess.check_output(["git", "blame", "-p",
+                                                  "-L", "{0},{0}".format(self.line_n),
+                                                  self.file_name])
+
+        self.git_log_output = decode_and_split(git_log_output)
+        self.commit_hash = self.git_log_output[0].split(' ')[0]
+        self.commit_summary = self.git_log_output[9][len("summary "):]
+        self.epoch_time = int(self.git_log_output[7][len("commiter-time "):])
+        self.output_time = datetime.datetime.utcfromtimestamp(self.epoch_time)
+
+        git_tag_output = subprocess.check_output(["git", "tag", "--contains",
+                                                  self.commit_hash])
+        git_tag_output = decode_and_split(git_tag_output)
+        relevant_tags = [tag for tag in git_tag_output if "rc" not in tag]
+        if relevant_tags:
+            self.release = relevant_tags[0][1:] # skip the prepended 'v'
+        else:
+            self.release = ""
+
+
+    def print_record(self):
+        """Print a description of the record to stdout. The 'Release' field
+        corresponds to the release number in which the declaration was first
+        marked as deprecated.
+        """
+        print("File: " + self.file_name + ":" + str(self.line_n) + ": ")
+        print("Line: " + self.deprecation_line)
+        print("Date: " + str(self.output_time))
+        print("Message: " + self.commit_summary)
+        print("Hash: " + self.commit_hash)
+        print("Release: " + self.release)
+
+
+def main():
+    # check that we are in the top directory
+    if not all((os.path.isdir(directory)
+                for directory in ["./include", "./tests", "./examples"])):
+        raise Exception("This script must be called from the top-level directory of deal.II.")
+    result = subprocess.check_output(["grep", "-R", "--line-number", "DEAL_II_DEPRECATED",
+                                      "./include/"])
+    result = decode_and_split(result)
+
+    deprecated_declarations = list()
+    for line in result:
+        try:
+            deprecated_declarations.append(DeprecatedDeclaration(line))
+        except subprocess.CalledProcessError: # ignore errors coming from git
+            pass
+
+    deprecated_declarations.sort(key=lambda u: u.epoch_time)
+
+    try:
+        for record in deprecated_declarations:
+            record.print_record()
+            print("")
+
+        sys.stderr.flush()
+        sys.stdout.flush()
+    except IOError as pipe_error:
+        if pipe_error.errno == errno.EPIPE:
+            # this is OK, it usually just means the user piped this script to
+            # head or some other screen capturing program that ignores some of
+            # its input
+            pass
+
+
+if __name__ == '__main__':
+    main()

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.