D5237: fix: add suboption for configuring execution order of tools

2018-11-08 Thread hooper (Danny Hooper)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHGb9557567cc3f: fix: add suboption for configuring execution 
order of tools (authored by hooper, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D5237?vs=12473=12477

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

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
@@ -165,6 +165,26 @@
 [fix]
 failure = abort
   
+  When multiple tools are configured to affect a file, they execute in an order
+  defined by the :priority suboption. The priority suboption has a default 
value
+  of zero for each tool. Tools are executed in order of descending priority. 
The
+  execution order of tools with equal priority is unspecified. For example, you
+  could use the 'sort' and 'head' utilities to keep only the 10 smallest 
numbers
+  in a text file by ensuring that 'sort' runs before 'head':
+  
+[fix]
+sort:command = sort --numeric-sort
+head:command = head --lines=10
+sort:pattern = numbers.txt
+head:pattern = numbers.txt
+sort:priority = 2
+head:priority = 1
+  
+  To account for changes made by each tool, the line numbers used for
+  incremental formatting are recomputed before executing the next tool. So, 
each
+  tool may see different values for the arguments added by the :linerange
+  suboption.
+  
   list of commands:
   
fix   rewrite file content in changesets or working directory
@@ -1127,3 +1147,51 @@
   first
 
   $ cd ..
+
+The execution order of tools can be controlled. This example doesn't work if
+you sort after truncating, but the config defines the correct order while the
+definitions are out of order (which might imply the incorrect order given the
+implementation of fix). The goal is to use multiple tools to select the lowest
+5 numbers in the file.
+
+  $ hg init priorityexample
+  $ cd priorityexample
+
+  $ cat >> .hg/hgrc < [fix]
+  > head:command = head --lines=5
+  > head:pattern = numbers.txt
+  > head:priority = 1
+  > sort:command = sort --numeric-sort
+  > sort:pattern = numbers.txt
+  > sort:priority = 2
+  > EOF
+
+  $ printf "8\n2\n3\n6\n7\n4\n9\n5\n1\n0\n" > numbers.txt
+  $ hg add -q
+  $ hg fix -w
+  $ cat numbers.txt
+  0
+  1
+  2
+  3
+  4
+
+And of course we should be able to break this by reversing the execution order.
+Test negative priorities while we're at it.
+
+  $ cat >> .hg/hgrc < [fix]
+  > head:priority = -1
+  > sort:priority = -2
+  > EOF
+  $ printf "8\n2\n3\n6\n7\n4\n9\n5\n1\n0\n" > numbers.txt
+  $ hg fix -w
+  $ cat numbers.txt
+  2
+  3
+  6
+  7
+  8
+
+  $ cd ..
diff --git a/hgext/fix.py b/hgext/fix.py
--- a/hgext/fix.py
+++ b/hgext/fix.py
@@ -54,6 +54,24 @@
   [fix]
   failure = abort
 
+When multiple tools are configured to affect a file, they execute in an order
+defined by the :priority suboption. The priority suboption has a default value
+of zero for each tool. Tools are executed in order of descending priority. The
+execution order of tools with equal priority is unspecified. For example, you
+could use the 'sort' and 'head' utilities to keep only the 10 smallest numbers
+in a text file by ensuring that 'sort' runs before 'head'::
+
+  [fix]
+  sort:command = sort --numeric-sort
+  head:command = head --lines=10
+  sort:pattern = numbers.txt
+  head:pattern = numbers.txt
+  sort:priority = 2
+  head:priority = 1
+
+To account for changes made by each tool, the line numbers used for incremental
+formatting are recomputed before executing the next tool. So, each tool may see
+different values for the arguments added by the :linerange suboption.
 """
 
 from __future__ import absolute_import
@@ -100,10 +118,16 @@
 configitem = registrar.configitem(configtable)
 
 # Register the suboptions allowed for each configured fixer.
-FIXER_ATTRS = ('command', 'linerange', 'fileset', 'pattern')
+FIXER_ATTRS = {
+'command': None,
+'linerange': None,
+'fileset': None,
+'pattern': None,
+'priority': 0,
+}
 
-for key in FIXER_ATTRS:
-configitem('fix', '.*(:%s)?' % key, default=None, generic=True)
+for key, default in FIXER_ATTRS.items():
+configitem('fix', '.*(:%s)?' % key, default=default, generic=True)
 
 # A good default size allows most source code files to be fixed, but avoids
 # letting fixer tools choke on huge inputs, which could be surprising to the
@@ -602,18 +626,21 @@
 Each value is a Fixer object with methods that implement the behavior of 
the
 fixer's config suboptions. Does not validate the config values.
 """
-result = {}
+fixers = {}
 for name in fixernames(ui):
-result[name] = Fixer()
+fixers[name] = Fixer()
 attrs = ui.configsuboptions('fix', name)[1]
 if 'fileset' in attrs and 'pattern' not in attrs:
 ui.warn(_('the fix.tool:fileset config name 

D5237: fix: add suboption for configuring execution order of tools

2018-11-07 Thread hooper (Danny Hooper)
hooper updated this revision to Diff 12473.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D5237?vs=12461=12473

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

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
@@ -165,6 +165,26 @@
 [fix]
 failure = abort
   
+  When multiple tools are configured to affect a file, they execute in an order
+  defined by the :priority suboption. The priority suboption has a default 
value
+  of zero for each tool. Tools are executed in order of descending priority. 
The
+  execution order of tools with equal priority is unspecified. For example, you
+  could use the 'sort' and 'head' utilities to keep only the 10 smallest 
numbers
+  in a text file by ensuring that 'sort' runs before 'head':
+  
+[fix]
+sort:command = sort --numeric-sort
+head:command = head --lines=10
+sort:pattern = numbers.txt
+head:pattern = numbers.txt
+sort:priority = 2
+head:priority = 1
+  
+  To account for changes made by each tool, the line numbers used for
+  incremental formatting are recomputed before executing the next tool. So, 
each
+  tool may see different values for the arguments added by the :linerange
+  suboption.
+  
   list of commands:
   
fix   rewrite file content in changesets or working directory
@@ -1127,3 +1147,51 @@
   first
 
   $ cd ..
+
+The execution order of tools can be controlled. This example doesn't work if
+you sort after truncating, but the config defines the correct order while the
+definitions are out of order (which might imply the incorrect order given the
+implementation of fix). The goal is to use multiple tools to select the lowest
+5 numbers in the file.
+
+  $ hg init priorityexample
+  $ cd priorityexample
+
+  $ cat >> .hg/hgrc < [fix]
+  > head:command = head --lines=5
+  > head:pattern = numbers.txt
+  > head:priority = 1
+  > sort:command = sort --numeric-sort
+  > sort:pattern = numbers.txt
+  > sort:priority = 2
+  > EOF
+
+  $ printf "8\n2\n3\n6\n7\n4\n9\n5\n1\n0\n" > numbers.txt
+  $ hg add -q
+  $ hg fix -w
+  $ cat numbers.txt
+  0
+  1
+  2
+  3
+  4
+
+And of course we should be able to break this by reversing the execution order.
+Test negative priorities while we're at it.
+
+  $ cat >> .hg/hgrc < [fix]
+  > head:priority = -1
+  > sort:priority = -2
+  > EOF
+  $ printf "8\n2\n3\n6\n7\n4\n9\n5\n1\n0\n" > numbers.txt
+  $ hg fix -w
+  $ cat numbers.txt
+  2
+  3
+  6
+  7
+  8
+
+  $ cd ..
diff --git a/hgext/fix.py b/hgext/fix.py
--- a/hgext/fix.py
+++ b/hgext/fix.py
@@ -54,6 +54,24 @@
   [fix]
   failure = abort
 
+When multiple tools are configured to affect a file, they execute in an order
+defined by the :priority suboption. The priority suboption has a default value
+of zero for each tool. Tools are executed in order of descending priority. The
+execution order of tools with equal priority is unspecified. For example, you
+could use the 'sort' and 'head' utilities to keep only the 10 smallest numbers
+in a text file by ensuring that 'sort' runs before 'head'::
+
+  [fix]
+  sort:command = sort --numeric-sort
+  head:command = head --lines=10
+  sort:pattern = numbers.txt
+  head:pattern = numbers.txt
+  sort:priority = 2
+  head:priority = 1
+
+To account for changes made by each tool, the line numbers used for incremental
+formatting are recomputed before executing the next tool. So, each tool may see
+different values for the arguments added by the :linerange suboption.
 """
 
 from __future__ import absolute_import
@@ -100,10 +118,16 @@
 configitem = registrar.configitem(configtable)
 
 # Register the suboptions allowed for each configured fixer.
-FIXER_ATTRS = ('command', 'linerange', 'fileset', 'pattern')
+FIXER_ATTRS = {
+'command': None,
+'linerange': None,
+'fileset': None,
+'pattern': None,
+'priority': 0,
+}
 
-for key in FIXER_ATTRS:
-configitem('fix', '.*(:%s)?' % key, default=None, generic=True)
+for key, default in FIXER_ATTRS.items():
+configitem('fix', '.*(:%s)?' % key, default=default, generic=True)
 
 # A good default size allows most source code files to be fixed, but avoids
 # letting fixer tools choke on huge inputs, which could be surprising to the
@@ -602,18 +626,21 @@
 Each value is a Fixer object with methods that implement the behavior of 
the
 fixer's config suboptions. Does not validate the config values.
 """
-result = {}
+fixers = {}
 for name in fixernames(ui):
-result[name] = Fixer()
+fixers[name] = Fixer()
 attrs = ui.configsuboptions('fix', name)[1]
 if 'fileset' in attrs and 'pattern' not in attrs:
 ui.warn(_('the fix.tool:fileset config name is deprecated; '
   'please rename it to fix.tool:pattern\n'))
 attrs['pattern'] = attrs['fileset']
-for key in 

D5237: fix: add suboption for configuring execution order of tools

2018-11-07 Thread yuja (Yuya Nishihara)
yuja added a comment.


  > +  When multiple tools are configured to affect a file, they execute in an 
order
  >  +  defined by the :priority suboption. The priority suboption has a 
default value
  >  +  of zero for each tool. Tools are executed in order of ascending 
priority.
  
  Appears that we use "descending" priority in hooks and merge-tools. Let's
  follow these. Other than that, the patch looks good to me.

REPOSITORY
  rHG Mercurial

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

To: hooper, #hg-reviewers
Cc: yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: D5237: fix: add suboption for configuring execution order of tools

2018-11-07 Thread Yuya Nishihara
> +  When multiple tools are configured to affect a file, they execute in an 
> order
> +  defined by the :priority suboption. The priority suboption has a default 
> value
> +  of zero for each tool. Tools are executed in order of ascending priority.

Appears that we use "descending" priority in hooks and merge-tools. Let's
follow these. Other than that, the patch looks good to me.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D5237: fix: add suboption for configuring execution order of tools

2018-11-06 Thread hooper (Danny Hooper)
hooper updated this revision to Diff 12461.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D5237?vs=12460=12461

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

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
@@ -165,6 +165,26 @@
 [fix]
 failure = abort
   
+  When multiple tools are configured to affect a file, they execute in an order
+  defined by the :priority suboption. The priority suboption has a default 
value
+  of zero for each tool. Tools are executed in order of ascending priority. The
+  execution order of tools with equal priority is unspecified. For example, you
+  could use the 'sort' and 'head' utilities to keep only the 10 smallest 
numbers
+  in a text file by ensuring that 'sort' runs before 'head':
+  
+[fix]
+sort:command = sort --numeric-sort
+head:command = head --lines=10
+sort:pattern = numbers.txt
+head:pattern = numbers.txt
+sort:priority = 1
+head:priority = 2
+  
+  To account for changes made by each tool, the line numbers used for
+  incremental formatting are recomputed before executing the next tool. So, 
each
+  tool may see different values for the arguments added by the :linerange
+  suboption.
+  
   list of commands:
   
fix   rewrite file content in changesets or working directory
@@ -1127,3 +1147,51 @@
   first
 
   $ cd ..
+
+The execution order of tools can be controlled. This example doesn't work if
+you sort after truncating, but the config defines the correct order while the
+definitions are out of order (which might imply the incorrect order given the
+implementation of fix). The goal is to use multiple tools to select the lowest
+5 numbers in the file.
+
+  $ hg init priorityexample
+  $ cd priorityexample
+
+  $ cat >> .hg/hgrc < [fix]
+  > head:command = head --lines=5
+  > head:pattern = numbers.txt
+  > head:priority = 2
+  > sort:command = sort --numeric-sort
+  > sort:pattern = numbers.txt
+  > sort:priority = 1
+  > EOF
+
+  $ printf "8\n2\n3\n6\n7\n4\n9\n5\n1\n0\n" > numbers.txt
+  $ hg add -q
+  $ hg fix -w
+  $ cat numbers.txt
+  0
+  1
+  2
+  3
+  4
+
+And of course we should be able to break this by reversing the execution order.
+Test negative priorities while we're at it.
+
+  $ cat >> .hg/hgrc < [fix]
+  > head:priority = -2
+  > sort:priority = -1
+  > EOF
+  $ printf "8\n2\n3\n6\n7\n4\n9\n5\n1\n0\n" > numbers.txt
+  $ hg fix -w
+  $ cat numbers.txt
+  2
+  3
+  6
+  7
+  8
+
+  $ cd ..
diff --git a/hgext/fix.py b/hgext/fix.py
--- a/hgext/fix.py
+++ b/hgext/fix.py
@@ -54,6 +54,24 @@
   [fix]
   failure = abort
 
+When multiple tools are configured to affect a file, they execute in an order
+defined by the :priority suboption. The priority suboption has a default value
+of zero for each tool. Tools are executed in order of ascending priority. The
+execution order of tools with equal priority is unspecified. For example, you
+could use the 'sort' and 'head' utilities to keep only the 10 smallest numbers
+in a text file by ensuring that 'sort' runs before 'head'::
+
+  [fix]
+  sort:command = sort --numeric-sort
+  head:command = head --lines=10
+  sort:pattern = numbers.txt
+  head:pattern = numbers.txt
+  sort:priority = 1
+  head:priority = 2
+
+To account for changes made by each tool, the line numbers used for incremental
+formatting are recomputed before executing the next tool. So, each tool may see
+different values for the arguments added by the :linerange suboption.
 """
 
 from __future__ import absolute_import
@@ -100,10 +118,16 @@
 configitem = registrar.configitem(configtable)
 
 # Register the suboptions allowed for each configured fixer.
-FIXER_ATTRS = ('command', 'linerange', 'fileset', 'pattern')
+FIXER_ATTRS = {
+'command': None,
+'linerange': None,
+'fileset': None,
+'pattern': None,
+'priority': 0,
+}
 
-for key in FIXER_ATTRS:
-configitem('fix', '.*(:%s)?' % key, default=None, generic=True)
+for key, default in FIXER_ATTRS.items():
+configitem('fix', '.*(:%s)?' % key, default=default, generic=True)
 
 # A good default size allows most source code files to be fixed, but avoids
 # letting fixer tools choke on huge inputs, which could be surprising to the
@@ -602,18 +626,20 @@
 Each value is a Fixer object with methods that implement the behavior of 
the
 fixer's config suboptions. Does not validate the config values.
 """
-result = {}
+fixers = {}
 for name in fixernames(ui):
-result[name] = Fixer()
+fixers[name] = Fixer()
 attrs = ui.configsuboptions('fix', name)[1]
 if 'fileset' in attrs and 'pattern' not in attrs:
 ui.warn(_('the fix.tool:fileset config name is deprecated; '
   'please rename it to fix.tool:pattern\n'))
 attrs['pattern'] = attrs['fileset']
-for key in FIXER_ATTRS:
- 

D5237: fix: add suboption for configuring execution order of tools

2018-11-06 Thread hooper (Danny Hooper)
hooper created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  This could be accomplished by using wrapper scripts, but that would diminish
  the usefulness of the incremental formatting logic. Configuring execution 
order
  along with other things in the hgrc is probably more convenient anyway.
  
  This change highlights some awkwardness with suboptions and default values,
  which should be addressed separately.

REPOSITORY
  rHG Mercurial

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

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
@@ -165,6 +165,26 @@
 [fix]
 failure = abort
   
+  When multiple tools are configured to affect a file, they execute in an order
+  defined by the :priority suboption. The priority suboption has a default 
value
+  of zero for each tool. Tools are executed in order of ascending priority. The
+  execution order of tools with equal priority is unspecified. For example, you
+  could use the 'sort' and 'head' utilities to keep only the 10 smallest 
numbers
+  in a text file by ensuring that 'sort' runs before 'head':
+  
+[fix]
+sort:command = sort --numeric-sort
+head:command = head --lines=10
+sort:pattern = numbers.txt
+head:pattern = numbers.txt
+sort:priority = 1
+head:priority = 2
+  
+  To account for changes made by each tool, the line numbers used for
+  incremental formatting are recomputed before executing the next tool. So, 
each
+  tool may see different values for the arguments added by the :linerange
+  suboption.
+  
   list of commands:
   
fix   rewrite file content in changesets or working directory
@@ -1127,3 +1147,52 @@
   first
 
   $ cd ..
+
+The execution order of tools can be controlled. This example doesn't work if
+you sort after truncating, but the config defines the correct order while the
+definitions are out of order (which might imply the incorrect order given the
+implementation of fix). The goal is to use multiple tools to select the lowest
+5 numbers in the file.
+
+  $ hg init priorityexample
+  $ cd priorityexample
+
+  $ cat >> .hg/hgrc < [fix]
+  > head:command = head --lines=5
+  > head:pattern = numbers.txt
+  > head:priority = 2
+  > sort:command = sort --numeric-sort
+  > sort:pattern = numbers.txt
+  > sort:priority = 1
+  > EOF
+
+  $ printf "8\n2\n3\n6\n7\n4\n9\n5\n1\n0\n" > numbers.txt
+  $ hg add -q
+  $ hg fix -w
+  $ cat numbers.txt
+  0
+  1
+  2
+  3
+  4
+
+And of course we should be able to break this by reversing the execution order.
+Test negative priorities while we're at it.
+
+  $ cat >> .hg/hgrc < [fix]
+  > head:priority = -2
+  > sort:priority = -1
+  > EOF
+  $ printf "8\n2\n3\n6\n7\n4\n9\n5\n1\n0\n" > numbers.txt
+  $ hg fix -w
+  $ cat numbers.txt
+  2
+  3
+  6
+  7
+  8
+
+
+  $ cd ..
diff --git a/hgext/fix.py b/hgext/fix.py
--- a/hgext/fix.py
+++ b/hgext/fix.py
@@ -54,6 +54,24 @@
   [fix]
   failure = abort
 
+When multiple tools are configured to affect a file, they execute in an order
+defined by the :priority suboption. The priority suboption has a default value
+of zero for each tool. Tools are executed in order of ascending priority. The
+execution order of tools with equal priority is unspecified. For example, you
+could use the 'sort' and 'head' utilities to keep only the 10 smallest numbers
+in a text file by ensuring that 'sort' runs before 'head'::
+
+  [fix]
+  sort:command = sort --numeric-sort
+  head:command = head --lines=10
+  sort:pattern = numbers.txt
+  head:pattern = numbers.txt
+  sort:priority = 1
+  head:priority = 2
+
+To account for changes made by each tool, the line numbers used for incremental
+formatting are recomputed before executing the next tool. So, each tool may see
+different values for the arguments added by the :linerange suboption.
 """
 
 from __future__ import absolute_import
@@ -100,10 +118,16 @@
 configitem = registrar.configitem(configtable)
 
 # Register the suboptions allowed for each configured fixer.
-FIXER_ATTRS = ('command', 'linerange', 'fileset', 'pattern')
+FIXER_ATTRS = {
+'command': None,
+'linerange': None,
+'fileset': None,
+'pattern': None,
+'priority': 0,
+}
 
-for key in FIXER_ATTRS:
-configitem('fix', '.*(:%s)?' % key, default=None, generic=True)
+for key, default in FIXER_ATTRS.items():
+configitem('fix', '.*(:%s)?' % key, default=default, generic=True)
 
 # A good default size allows most source code files to be fixed, but avoids
 # letting fixer tools choke on huge inputs, which could be surprising to the
@@ -602,18 +626,20 @@
 Each value is a Fixer object with methods that implement the behavior of 
the
 fixer's config suboptions. Does not validate the config values.
 """
-result = {}
+fixers = {}
 for name in fixernames(ui):
-result[name] = Fixer()
+