Control: tag -1 + patch

Hello,

I'd like to suggest a patch for this, please find them enclosed.
The patches base on the currently unreleased ed9350e, or "v2.15.10-2-ged9350e" as git describe puts it.

In fact, these are two patches, one of which "cleans up" a specific aspect so that the second patch can implement the desired feature (--dry-run).

I'd like to submit even more patches, outside the scope of this bug, e.g. for #788998, and the leaking fds, and maybe #701646, and maybe adding a test for w-a-s, and ...
How does this work? Submitting patches to a bug doesn't scale well.

Regards,
Ben
>From ba69efde72720cb8727aa3221de9829b76f43c8b Mon Sep 17 00:00:00 2001
From: Ben Wiederhake <benwiederhake.git...@gmx.de>
Date: Wed, 6 Jan 2016 00:02:31 +0100
Subject: [PATCH 1/2] wrap-and-sort: Pass options dict for brevity

---
 scripts/wrap-and-sort | 40 +++++++++++++++++-----------------------
 1 file changed, 17 insertions(+), 23 deletions(-)

diff --git a/scripts/wrap-and-sort b/scripts/wrap-and-sort
index 98a4bb5..15c8bb0 100755
--- a/scripts/wrap-and-sort
+++ b/scripts/wrap-and-sort
@@ -64,34 +64,30 @@ SUPPORTED_FILES = (
 
 
 class WrapAndSortControl(Control):
-    def __init__(self, filename, max_line_length):
+    def __init__(self, filename, options):
         super().__init__(filename)
-        self.max_line_length = max_line_length
+        self.opts = options
 
-    def wrap_and_sort(self, wrap_always, short_indent, sort_paragraphs,
-                      keep_first, trailing_comma):
+    def wrap_and_sort(self):
         for paragraph in self.paragraphs:
             for field in CONTROL_LIST_FIELDS:
                 if field in paragraph:
-                    self._wrap_field(paragraph, field, wrap_always,
-                                     short_indent, trailing_comma)
+                    self._wrap_field(paragraph, field, True)
             if "Uploaders" in paragraph:
-                self._wrap_field(paragraph, "Uploaders", wrap_always,
-                                 short_indent, trailing_comma, False)
+                self._wrap_field(paragraph, "Uploaders", False)
             if "Architecture" in paragraph:
                 archs = set(paragraph["Architecture"].split())
                 # Sort, with wildcard entries (such as linux-any) first:
                 archs = sorted(archs, key=lambda x: ("any" not in x, x))
                 paragraph["Architecture"] = " ".join(archs)
 
-        if sort_paragraphs:
-            first = self.paragraphs[:1 + int(keep_first)]
-            sortable = self.paragraphs[1 + int(keep_first):]
+        if self.opts.sort_binary_packages:
+            first = self.paragraphs[:1 + int(self.opts.keep_first)]
+            sortable = self.paragraphs[1 + int(self.opts.keep_first):]
             key = lambda x: x.get("Package")
             self.paragraphs = first + sorted(sortable, key=key)
 
-    def _wrap_field(self, control, entry, wrap_always, short_indent,
-                    trailing_comma, sort=True):
+    def _wrap_field(self, control, entry, sort):
         # An empty element is not explicitly disallowed by Policy but known to
         # break QA tools, so remove any
         packages = list(filter(None, [x.strip() for x in control[entry].split(",")]))
@@ -105,20 +101,20 @@ class WrapAndSortControl(Control):
             packages = sort_list(packages)
 
         length = len(entry) + sum([2 + len(package) for package in packages])
-        if wrap_always or length > self.max_line_length:
+        if self.opts.wrap_always or length > self.opts.max_line_length:
             indentation = " "
-            if not short_indent:
-                indentation *= len(entry) + 2
+            if not self.opts.short_indent:
+                indentation *= len(entry) + len(": ")
             packages_with_indention = [indentation + x for x in packages]
             packages_with_indention = ",\n".join(packages_with_indention)
-            if trailing_comma:
+            if self.opts.trailing_comma:
                 packages_with_indention += ','
-            if short_indent:
+            if self.opts.short_indent:
                 control[entry] = "\n" + packages_with_indention
             else:
                 control[entry] = packages_with_indention.strip()
         else:
-            control[entry] = ", ".join(packages).strip()
+            control[entry] = ", ".join(packages)
 
 
 class Install(object):
@@ -168,12 +164,10 @@ def wrap_and_sort(options):
     for control_file in control_files:
         if options.verbose:
             print(control_file)
-        control = WrapAndSortControl(control_file, options.max_line_length)
+        control = WrapAndSortControl(control_file, options)
         if options.cleanup:
             control.strip_trailing_spaces()
-        control.wrap_and_sort(options.wrap_always, options.short_indent,
-                              options.sort_binary_packages, options.keep_first,
-                              options.trailing_comma)
+        control.wrap_and_sort()
         control.save()
 
     copyright_files = [f for f in options.files
-- 
2.6.4

>From 7f3c2bdb31f1066a92f0136ed4a5cbc3215d1943 Mon Sep 17 00:00:00 2001
From: Ben Wiederhake <benwiederhake.git...@gmx.de>
Date: Wed, 6 Jan 2016 00:35:53 +0100
Subject: [PATCH 2/2] wrap-and-sort: Add option --dry-run

---
 debian/changelog      |  4 ++++
 scripts/wrap-and-sort | 58 +++++++++++++++++++++++++++++++++++++++------------
 2 files changed, 49 insertions(+), 13 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 7d158bf..3c7eb9f 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -6,6 +6,10 @@ devscripts (2.15.11) UNRELEASED; urgency=medium
       Patch by Alex Mestiashvili <mailatgo...@gmail.com>
     - fix crash when --rename is passed
 
+  [ Ben Wiederhake ]
+  * wrap-and-sort:
+    - New switch --dry-run (Closes: #808574)
+
  -- Antonio Terceiro <terce...@debian.org>  Tue, 05 Jan 2016 13:01:05 -0200
 
 devscripts (2.15.10) unstable; urgency=low
diff --git a/scripts/wrap-and-sort b/scripts/wrap-and-sort
index 15c8bb0..6a047a2 100755
--- a/scripts/wrap-and-sort
+++ b/scripts/wrap-and-sort
@@ -116,11 +116,23 @@ class WrapAndSortControl(Control):
         else:
             control[entry] = ", ".join(packages)
 
+    def save(self):
+        if self.opts.dry_run:
+            # Copied from control.py (1 line):
+            content = "\n".join([x.dump() for x in self.paragraphs])
+            control_file = open(self.filename, "r")
+            if content != control_file.read():
+                self.opts.modified_files.append(self.filename);
+            control_file.close()
+        else:
+            super().save()
+
 
 class Install(object):
-    def __init__(self, filename):
+    def __init__(self, filename, options):
         self.content = None
         self.filename = None
+        self.opts = options
         self.open(filename)
 
     def open(self, filename):
@@ -128,29 +140,37 @@ class Install(object):
         self.filename = filename
         self.content = list(filter(None, [l.strip() for l in open(filename).readlines()]))
 
-    def save(self, filename=None):
-        if filename:
-            self.filename = filename
-        install_file = open(self.filename, "w")
-        install_file.write("\n".join(self.content) + "\n")
+    def save(self):
+        to_write = "\n".join(self.content) + "\n"
+        install_file = open(self.filename, "w" if not self.opts.dry_run else "r")
+        if self.opts.dry_run:
+            if to_write != install_file.read():
+                self.opts.modified_files.append(self.filename)
+        else:
+            install_file.write(to_write)
         install_file.close()
 
     def sort(self):
         self.content = sorted(self.content)
 
 
-def remove_trailing_whitespaces(filename):
+def remove_trailing_whitespaces(filename, options):
     assert os.path.isfile(filename), "%s does not exist." % (filename)
     content = open(filename).read()
     if len(content) == 0:
         return
+    old_content = content
     content = content.rstrip() + "\n"
     lines = content.split("\n")
     lines = [l.rstrip() for l in lines]
-    new_content = "\n".join(lines)
-    f = open(filename, "w")
-    f.write(new_content)
-    f.close()
+    content = "\n".join(lines)
+    if options.dry_run:
+        if content != old_content:
+            options.modified_files.append(filename)
+    else:
+        f = open(filename, "w")
+        f.write(content)
+        f.close()
 
 
 def sort_list(unsorted_list):
@@ -175,14 +195,14 @@ def wrap_and_sort(options):
     for copyright_file in copyright_files:
         if options.verbose:
             print(copyright_file)
-        remove_trailing_whitespaces(copyright_file)
+        remove_trailing_whitespaces(copyright_file, options)
 
     pattern = "(dirs|docs|examples|info|install|links|maintscript|manpages)$"
     install_files = [f for f in options.files if re.search(pattern, f)]
     for install_file in sorted(install_files):
         if options.verbose:
             print(install_file)
-        install = Install(install_file)
+        install = Install(install_file, options)
         install.sort()
         install.save()
 
@@ -235,8 +255,12 @@ def main():
                       dest="verbose", action="store_true", default=False)
     parser.add_option("--max-line-length", type='int', default=79,
                       help="set maximum allowed line length before wrapping (default: %default)")
+    parser.add_option("--dry-run", help="do not modify any file, instead only"
+                      "print the files that would be modified",
+                      dest="dry_run", action="store_true", default=False)
 
     (options, args) = parser.parse_args()
+    options.modified_files = []
 
     if len(args) != 0:
         parser.error("Unsupported additional parameters specified: %s" %
@@ -255,5 +279,13 @@ def main():
 
     wrap_and_sort(options)
 
+    # Only report at the end, to avoid potential clash with --verbose
+    if options.modified_files:
+        print("--- Would modify the following files: ---")
+        print("\n".join(options.modified_files))
+    elif options.dry_run:
+        print("--- No files need modification ---")
+
+
 if __name__ == "__main__":
     main()
-- 
2.6.4

Reply via email to