D6723: fix: allow tools to use :linerange, but also run if a file is unchanged

hooper (Danny Hooper) phabricator at mercurial-scm.org
Tue Aug 13 18:21:12 EDT 2019


hooper updated this revision to Diff 16181.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D6723?vs=16178&id=16181

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D6723/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D6723

AFFECTED FILES
  hgext/fix.py
  tests/test-fix.t

CHANGE DETAILS

diff --git a/tests/test-fix.t b/tests/test-fix.t
--- a/tests/test-fix.t
+++ b/tests/test-fix.t
@@ -147,6 +147,15 @@
     {first}   The 1-based line number of the first line in the modified range
     {last}    The 1-based line number of the last line in the modified range
   
+  Deleted sections of a file will be ignored by :linerange, because there is no
+  corresponding line range in the version being fixed.
+  
+  By default, tools that set :linerange will only be executed if there is at
+  least one changed line range. This is meant to prevent accidents like running
+  a code formatter in such a way that it unexpectedly reformats the whole file.
+  If such a tool needs to operate on unchanged files, it should set the
+  :skipclean suboption to false.
+  
   The :pattern suboption determines which files will be passed through each
   configured tool. See 'hg help patterns' for possible values. If there are file
   arguments to 'hg fix', the intersection of these patterns is used.
@@ -1356,3 +1365,34 @@
   fixed
 
   $ cd ..
+
+Tools should be able to run on unchanged files, even if they set :linerange.
+This includes a corner case where deleted chunks of a file are not considered
+changes.
+
+  $ hg init skipclean
+  $ cd skipclean
+
+  $ printf "a\nb\nc\n" > foo
+  $ printf "a\nb\nc\n" > bar
+  $ printf "a\nb\nc\n" > baz
+  $ hg commit -Aqm "base"
+
+  $ printf "a\nc\n" > foo
+  $ printf "a\nx\nc\n" > baz
+
+  $ hg fix --working-dir foo bar baz \
+  >        --config 'fix.changedlines:command=printf "Line ranges:\n"; ' \
+  >        --config 'fix.changedlines:linerange=printf "{first} through {last}\n"; ' \
+  >        --config 'fix.changedlines:pattern=rootglob:**' \
+  >        --config 'fix.changedlines:skipclean=false'
+
+  $ cat foo
+  Line ranges:
+  $ cat bar
+  Line ranges:
+  $ cat baz
+  Line ranges:
+  2 through 2
+
+  $ cd ..
diff --git a/hgext/fix.py b/hgext/fix.py
--- a/hgext/fix.py
+++ b/hgext/fix.py
@@ -36,6 +36,15 @@
   {first}   The 1-based line number of the first line in the modified range
   {last}    The 1-based line number of the last line in the modified range
 
+Deleted sections of a file will be ignored by :linerange, because there is no
+corresponding line range in the version being fixed.
+
+By default, tools that set :linerange will only be executed if there is at least
+one changed line range. This is meant to prevent accidents like running a code
+formatter in such a way that it unexpectedly reformats the whole file. If such a
+tool needs to operate on unchanged files, it should set the :skipclean suboption
+to false.
+
 The :pattern suboption determines which files will be passed through each
 configured tool. See :hg:`help patterns` for possible values. If there are file
 arguments to :hg:`fix`, the intersection of these patterns is used.
@@ -126,6 +135,7 @@
 
 from mercurial.utils import (
     procutil,
+    stringutil,
 )
 
 from mercurial import (
@@ -162,6 +172,7 @@
     'pattern': None,
     'priority': 0,
     'metadata': False,
+    'skipclean': 'true',
 }
 
 for key, default in FIXER_ATTRS.items():
@@ -713,6 +724,7 @@
             setattr(fixers[name], pycompat.sysstr('_' + key),
                     attrs.get(key, default))
         fixers[name]._priority = int(fixers[name]._priority)
+        fixers[name]._skipclean = stringutil.parsebool(fixers[name]._skipclean)
         # Don't use a fixer if it has no pattern configured. It would be
         # dangerous to let it affect all files. It would be pointless to let it
         # affect no files. There is no reasonable subset of files to use as the
@@ -756,7 +768,7 @@
                         {'rootpath': path, 'basename': os.path.basename(path)})]
         if self._linerange:
             ranges = rangesfn()
-            if not ranges:
+            if self._skipclean and not ranges:
                 # No line ranges to fix, so don't run the fixer.
                 return None
             for first, last in ranges:



To: hooper, #hg-reviewers
Cc: mercurial-devel


More information about the Mercurial-devel mailing list