Mercurial > hg-stable
annotate hgext/fix.py @ 42687:2987d015aba4
fix: ignore fixer tool configurations that are missing patterns
This is to prevent a crash under the same circumstances.
This is also to avoid data loss due to accidental application of a fixer tool
to all files, if the matching logic somehow changed to that effect. Affecting
all files until otherwise configured would be dangerous, and not very useful.
We shouldn't abort because there may be other fixers, and it may still be
useful to run them without having to adjust configuration. A user might not
feel confident in changing configs, for example.
Differential Revision: https://phab.mercurial-scm.org/D6693
author | Danny Hooper <hooper@google.com> |
---|---|
date | Wed, 24 Jul 2019 16:19:00 -0700 |
parents | 9ed63cd0026c |
children | 74b4cd091e0d |
rev | line source |
---|---|
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
1 # fix - rewrite file content in changesets and working copy |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
2 # |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
3 # Copyright 2018 Google LLC. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
4 # |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
6 # GNU General Public License version 2 or any later version. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
7 """rewrite file content in changesets or working copy (EXPERIMENTAL) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
8 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
9 Provides a command that runs configured tools on the contents of modified files, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
10 writing back any fixes to the working copy or replacing changesets. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
11 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
12 Here is an example configuration that causes :hg:`fix` to apply automatic |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
13 formatting fixes to modified lines in C++ code:: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
14 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
15 [fix] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
16 clang-format:command=clang-format --assume-filename={rootpath} |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
17 clang-format:linerange=--lines={first}:{last} |
40583
2ecf5c24d0cd
fix: rename :fileset subconfig to :pattern
Danny Hooper <hooper@google.com>
parents:
40582
diff
changeset
|
18 clang-format:pattern=set:**.cpp or **.hpp |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
19 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
20 The :command suboption forms the first part of the shell command that will be |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
21 used to fix a file. The content of the file is passed on standard input, and the |
40582
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
22 fixed file content is expected on standard output. Any output on standard error |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
23 will be displayed as a warning. If the exit status is not zero, the file will |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
24 not be affected. A placeholder warning is displayed if there is a non-zero exit |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
25 status but no standard error output. Some values may be substituted into the |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
26 command:: |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
27 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
28 {rootpath} The path of the file being fixed, relative to the repo root |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
29 {basename} The name of the file being fixed, without the directory path |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
30 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
31 If the :linerange suboption is set, the tool will only be run if there are |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
32 changed lines in a file. The value of this suboption is appended to the shell |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
33 command once for every range of changed lines in the file. Some values may be |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
34 substituted into the command:: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
35 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
36 {first} The 1-based line number of the first line in the modified range |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
37 {last} The 1-based line number of the last line in the modified range |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
38 |
40583
2ecf5c24d0cd
fix: rename :fileset subconfig to :pattern
Danny Hooper <hooper@google.com>
parents:
40582
diff
changeset
|
39 The :pattern suboption determines which files will be passed through each |
2ecf5c24d0cd
fix: rename :fileset subconfig to :pattern
Danny Hooper <hooper@google.com>
parents:
40582
diff
changeset
|
40 configured tool. See :hg:`help patterns` for possible values. If there are file |
2ecf5c24d0cd
fix: rename :fileset subconfig to :pattern
Danny Hooper <hooper@google.com>
parents:
40582
diff
changeset
|
41 arguments to :hg:`fix`, the intersection of these patterns is used. |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
42 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
43 There is also a configurable limit for the maximum size of file that will be |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
44 processed by :hg:`fix`:: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
45 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
46 [fix] |
40582
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
47 maxfilesize = 2MB |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
48 |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
49 Normally, execution of configured tools will continue after a failure (indicated |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
50 by a non-zero exit status). It can also be configured to abort after the first |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
51 such failure, so that no files will be affected if any tool fails. This abort |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
52 will also cause :hg:`fix` to exit with a non-zero status:: |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
53 |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
54 [fix] |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
55 failure = abort |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
56 |
40613
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
57 When multiple tools are configured to affect a file, they execute in an order |
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
58 defined by the :priority suboption. The priority suboption has a default value |
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
59 of zero for each tool. Tools are executed in order of descending priority. The |
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
60 execution order of tools with equal priority is unspecified. For example, you |
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
61 could use the 'sort' and 'head' utilities to keep only the 10 smallest numbers |
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
62 in a text file by ensuring that 'sort' runs before 'head':: |
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
63 |
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
64 [fix] |
41129
d8f5c615e811
tests: use more portable flags in test-fix.t
Danny Hooper <hooper@google.com>
parents:
40617
diff
changeset
|
65 sort:command = sort -n |
d8f5c615e811
tests: use more portable flags in test-fix.t
Danny Hooper <hooper@google.com>
parents:
40617
diff
changeset
|
66 head:command = head -n 10 |
40613
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
67 sort:pattern = numbers.txt |
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
68 head:pattern = numbers.txt |
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
69 sort:priority = 2 |
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
70 head:priority = 1 |
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
71 |
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
72 To account for changes made by each tool, the line numbers used for incremental |
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
73 formatting are recomputed before executing the next tool. So, each tool may see |
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
74 different values for the arguments added by the :linerange suboption. |
42229
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
75 |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
76 Each fixer tool is allowed to return some metadata in addition to the fixed file |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
77 content. The metadata must be placed before the file content on stdout, |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
78 separated from the file content by a zero byte. The metadata is parsed as a JSON |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
79 value (so, it should be UTF-8 encoded and contain no zero bytes). A fixer tool |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
80 is expected to produce this metadata encoding if and only if the :metadata |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
81 suboption is true:: |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
82 |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
83 [fix] |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
84 tool:command = tool --prepend-json-metadata |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
85 tool:metadata = true |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
86 |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
87 The metadata values are passed to hooks, which can be used to print summaries or |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
88 perform other post-fixing work. The supported hooks are:: |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
89 |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
90 "postfixfile" |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
91 Run once for each file in each revision where any fixer tools made changes |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
92 to the file content. Provides "$HG_REV" and "$HG_PATH" to identify the file, |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
93 and "$HG_METADATA" with a map of fixer names to metadata values from fixer |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
94 tools that affected the file. Fixer tools that didn't affect the file have a |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
95 valueof None. Only fixer tools that executed are present in the metadata. |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
96 |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
97 "postfix" |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
98 Run once after all files and revisions have been handled. Provides |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
99 "$HG_REPLACEMENTS" with information about what revisions were created and |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
100 made obsolete. Provides a boolean "$HG_WDIRWRITTEN" to indicate whether any |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
101 files in the working copy were updated. Provides a list "$HG_METADATA" |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
102 mapping fixer tool names to lists of metadata values returned from |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
103 executions that modified a file. This aggregates the same metadata |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
104 previously passed to the "postfixfile" hook. |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
105 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
106 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
107 from __future__ import absolute_import |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
108 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
109 import collections |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
110 import itertools |
42229
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
111 import json |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
112 import os |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
113 import re |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
114 import subprocess |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
115 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
116 from mercurial.i18n import _ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
117 from mercurial.node import nullrev |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
118 from mercurial.node import wdirrev |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
119 |
39831
c31ce080eb75
py3: convert arguments, cwd and env to native strings when spawning subprocess
Matt Harbison <matt_harbison@yahoo.com>
parents:
39005
diff
changeset
|
120 from mercurial.utils import ( |
c31ce080eb75
py3: convert arguments, cwd and env to native strings when spawning subprocess
Matt Harbison <matt_harbison@yahoo.com>
parents:
39005
diff
changeset
|
121 procutil, |
c31ce080eb75
py3: convert arguments, cwd and env to native strings when spawning subprocess
Matt Harbison <matt_harbison@yahoo.com>
parents:
39005
diff
changeset
|
122 ) |
c31ce080eb75
py3: convert arguments, cwd and env to native strings when spawning subprocess
Matt Harbison <matt_harbison@yahoo.com>
parents:
39005
diff
changeset
|
123 |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
124 from mercurial import ( |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
125 cmdutil, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
126 context, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
127 copies, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
128 error, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
129 mdiff, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
130 merge, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
131 obsolete, |
37618
1edf3738e000
fix: port most of the way to python 3
Augie Fackler <augie@google.com>
parents:
37595
diff
changeset
|
132 pycompat, |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
133 registrar, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
134 scmutil, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
135 util, |
38537
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
136 worker, |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
137 ) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
138 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
139 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
140 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
141 # be specifying the version(s) of Mercurial they are tested with, or |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
142 # leave the attribute unspecified. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
143 testedwith = 'ships-with-hg-core' |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
144 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
145 cmdtable = {} |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
146 command = registrar.command(cmdtable) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
147 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
148 configtable = {} |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
149 configitem = registrar.configitem(configtable) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
150 |
42229
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
151 # Register the suboptions allowed for each configured fixer, and default values. |
40613
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
152 FIXER_ATTRS = { |
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
153 'command': None, |
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
154 'linerange': None, |
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
155 'pattern': None, |
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
156 'priority': 0, |
42229
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
157 'metadata': False, |
40613
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
158 } |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
159 |
40613
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
160 for key, default in FIXER_ATTRS.items(): |
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
161 configitem('fix', '.*(:%s)?' % key, default=default, generic=True) |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
162 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
163 # A good default size allows most source code files to be fixed, but avoids |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
164 # letting fixer tools choke on huge inputs, which could be surprising to the |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
165 # user. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
166 configitem('fix', 'maxfilesize', default='2MB') |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
167 |
40582
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
168 # Allow fix commands to exit non-zero if an executed fixer tool exits non-zero. |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
169 # This helps users do shell scripts that stop when a fixer tool signals a |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
170 # problem. |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
171 configitem('fix', 'failure', default='continue') |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
172 |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
173 def checktoolfailureaction(ui, message, hint=None): |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
174 """Abort with 'message' if fix.failure=abort""" |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
175 action = ui.config('fix', 'failure') |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
176 if action not in ('continue', 'abort'): |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
177 raise error.Abort(_('unknown fix.failure action: %s') % (action,), |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
178 hint=_('use "continue" or "abort"')) |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
179 if action == 'abort': |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
180 raise error.Abort(message, hint=hint) |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
181 |
38987
b0c591950e51
fix: pull out flag definitions to make them re-usable from extensions
Danny Hooper <hooper@google.com>
parents:
38899
diff
changeset
|
182 allopt = ('', 'all', False, _('fix all non-public non-obsolete revisions')) |
b0c591950e51
fix: pull out flag definitions to make them re-usable from extensions
Danny Hooper <hooper@google.com>
parents:
38899
diff
changeset
|
183 baseopt = ('', 'base', [], _('revisions to diff against (overrides automatic ' |
b0c591950e51
fix: pull out flag definitions to make them re-usable from extensions
Danny Hooper <hooper@google.com>
parents:
38899
diff
changeset
|
184 'selection, and applies to every revision being ' |
b0c591950e51
fix: pull out flag definitions to make them re-usable from extensions
Danny Hooper <hooper@google.com>
parents:
38899
diff
changeset
|
185 'fixed)'), _('REV')) |
b0c591950e51
fix: pull out flag definitions to make them re-usable from extensions
Danny Hooper <hooper@google.com>
parents:
38899
diff
changeset
|
186 revopt = ('r', 'rev', [], _('revisions to fix'), _('REV')) |
b0c591950e51
fix: pull out flag definitions to make them re-usable from extensions
Danny Hooper <hooper@google.com>
parents:
38899
diff
changeset
|
187 wdiropt = ('w', 'working-dir', False, _('fix the working directory')) |
b0c591950e51
fix: pull out flag definitions to make them re-usable from extensions
Danny Hooper <hooper@google.com>
parents:
38899
diff
changeset
|
188 wholeopt = ('', 'whole', False, _('always fix every line of a file')) |
b0c591950e51
fix: pull out flag definitions to make them re-usable from extensions
Danny Hooper <hooper@google.com>
parents:
38899
diff
changeset
|
189 usage = _('[OPTION]... [FILE]...') |
b0c591950e51
fix: pull out flag definitions to make them re-usable from extensions
Danny Hooper <hooper@google.com>
parents:
38899
diff
changeset
|
190 |
40293
c303d65d2e34
help: assigning categories to existing commands
rdamazio@google.com
parents:
39841
diff
changeset
|
191 @command('fix', [allopt, baseopt, revopt, wdiropt, wholeopt], usage, |
c303d65d2e34
help: assigning categories to existing commands
rdamazio@google.com
parents:
39841
diff
changeset
|
192 helpcategory=command.CATEGORY_FILE_CONTENTS) |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
193 def fix(ui, repo, *pats, **opts): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
194 """rewrite file content in changesets or working directory |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
195 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
196 Runs any configured tools to fix the content of files. Only affects files |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
197 with changes, unless file arguments are provided. Only affects changed lines |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
198 of files, unless the --whole flag is used. Some tools may always affect the |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
199 whole file regardless of --whole. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
200 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
201 If revisions are specified with --rev, those revisions will be checked, and |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
202 they may be replaced with new revisions that have fixed file content. It is |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
203 desirable to specify all descendants of each specified revision, so that the |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
204 fixes propagate to the descendants. If all descendants are fixed at the same |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
205 time, no merging, rebasing, or evolution will be required. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
206 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
207 If --working-dir is used, files with uncommitted changes in the working copy |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
208 will be fixed. If the checked-out revision is also fixed, the working |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
209 directory will update to the replacement revision. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
210 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
211 When determining what lines of each file to fix at each revision, the whole |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
212 set of revisions being fixed is considered, so that fixes to earlier |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
213 revisions are not forgotten in later ones. The --base flag can be used to |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
214 override this default behavior, though it is not usually desirable to do so. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
215 """ |
37618
1edf3738e000
fix: port most of the way to python 3
Augie Fackler <augie@google.com>
parents:
37595
diff
changeset
|
216 opts = pycompat.byteskwargs(opts) |
37595
e2506748b47f
fix: add --all flag to fix non-public non-obsolete revisions
Danny Hooper <hooper@google.com>
parents:
37215
diff
changeset
|
217 if opts['all']: |
e2506748b47f
fix: add --all flag to fix non-public non-obsolete revisions
Danny Hooper <hooper@google.com>
parents:
37215
diff
changeset
|
218 if opts['rev']: |
e2506748b47f
fix: add --all flag to fix non-public non-obsolete revisions
Danny Hooper <hooper@google.com>
parents:
37215
diff
changeset
|
219 raise error.Abort(_('cannot specify both "--rev" and "--all"')) |
e2506748b47f
fix: add --all flag to fix non-public non-obsolete revisions
Danny Hooper <hooper@google.com>
parents:
37215
diff
changeset
|
220 opts['rev'] = ['not public() and not obsolete()'] |
e2506748b47f
fix: add --all flag to fix non-public non-obsolete revisions
Danny Hooper <hooper@google.com>
parents:
37215
diff
changeset
|
221 opts['working_dir'] = True |
38426
c1f4364f9336
fix: include cleanupnodes() in transaction
Martin von Zweigbergk <martinvonz@google.com>
parents:
37774
diff
changeset
|
222 with repo.wlock(), repo.lock(), repo.transaction('fix'): |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
223 revstofix = getrevstofix(ui, repo, opts) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
224 basectxs = getbasectxs(repo, opts, revstofix) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
225 workqueue, numitems = getworkqueue(ui, repo, pats, opts, revstofix, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
226 basectxs) |
38537
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
227 fixers = getfixers(ui) |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
228 |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
229 # There are no data dependencies between the workers fixing each file |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
230 # revision, so we can use all available parallelism. |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
231 def getfixes(items): |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
232 for rev, path in items: |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
233 ctx = repo[rev] |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
234 olddata = ctx[path].data() |
42229
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
235 metadata, newdata = fixfile(ui, opts, fixers, ctx, path, |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
236 basectxs[rev]) |
38537
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
237 # Don't waste memory/time passing unchanged content back, but |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
238 # produce one result per item either way. |
42229
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
239 yield (rev, path, metadata, |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
240 newdata if newdata != olddata else None) |
40417
8ebb05f747e5
fix: disable use of thread-based worker
Yuya Nishihara <yuya@tcha.org>
parents:
40293
diff
changeset
|
241 results = worker.worker(ui, 1.0, getfixes, tuple(), workqueue, |
8ebb05f747e5
fix: disable use of thread-based worker
Yuya Nishihara <yuya@tcha.org>
parents:
40293
diff
changeset
|
242 threadsafe=False) |
38537
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
243 |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
244 # We have to hold on to the data for each successor revision in memory |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
245 # until all its parents are committed. We ensure this by committing and |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
246 # freeing memory for the revisions in some topological order. This |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
247 # leaves a little bit of memory efficiency on the table, but also makes |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
248 # the tests deterministic. It might also be considered a feature since |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
249 # it makes the results more easily reproducible. |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
250 filedata = collections.defaultdict(dict) |
42229
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
251 aggregatemetadata = collections.defaultdict(list) |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
252 replacements = {} |
38988
35bc4b6e132d
fix: correctly set wdirwritten given that the dict item is deleted
Danny Hooper <hooper@google.com>
parents:
38987
diff
changeset
|
253 wdirwritten = False |
38537
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
254 commitorder = sorted(revstofix, reverse=True) |
38538
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38537
diff
changeset
|
255 with ui.makeprogress(topic=_('fixing'), unit=_('files'), |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38537
diff
changeset
|
256 total=sum(numitems.values())) as progress: |
42229
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
257 for rev, path, filerevmetadata, newdata in results: |
38538
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38537
diff
changeset
|
258 progress.increment(item=path) |
42229
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
259 for fixername, fixermetadata in filerevmetadata.items(): |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
260 aggregatemetadata[fixername].append(fixermetadata) |
38538
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38537
diff
changeset
|
261 if newdata is not None: |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38537
diff
changeset
|
262 filedata[rev][path] = newdata |
42229
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
263 hookargs = { |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
264 'rev': rev, |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
265 'path': path, |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
266 'metadata': filerevmetadata, |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
267 } |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
268 repo.hook('postfixfile', throw=False, |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
269 **pycompat.strkwargs(hookargs)) |
38538
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38537
diff
changeset
|
270 numitems[rev] -= 1 |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38537
diff
changeset
|
271 # Apply the fixes for this and any other revisions that are |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38537
diff
changeset
|
272 # ready and sitting at the front of the queue. Using a loop here |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38537
diff
changeset
|
273 # prevents the queue from being blocked by the first revision to |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38537
diff
changeset
|
274 # be ready out of order. |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38537
diff
changeset
|
275 while commitorder and not numitems[commitorder[-1]]: |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38537
diff
changeset
|
276 rev = commitorder.pop() |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38537
diff
changeset
|
277 ctx = repo[rev] |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38537
diff
changeset
|
278 if rev == wdirrev: |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38537
diff
changeset
|
279 writeworkingdir(repo, ctx, filedata[rev], replacements) |
38988
35bc4b6e132d
fix: correctly set wdirwritten given that the dict item is deleted
Danny Hooper <hooper@google.com>
parents:
38987
diff
changeset
|
280 wdirwritten = bool(filedata[rev]) |
38538
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38537
diff
changeset
|
281 else: |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38537
diff
changeset
|
282 replacerev(ui, repo, ctx, filedata[rev], replacements) |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38537
diff
changeset
|
283 del filedata[rev] |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
284 |
38988
35bc4b6e132d
fix: correctly set wdirwritten given that the dict item is deleted
Danny Hooper <hooper@google.com>
parents:
38987
diff
changeset
|
285 cleanup(repo, replacements, wdirwritten) |
42229
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
286 hookargs = { |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
287 'replacements': replacements, |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
288 'wdirwritten': wdirwritten, |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
289 'metadata': aggregatemetadata, |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
290 } |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
291 repo.hook('postfix', throw=True, **pycompat.strkwargs(hookargs)) |
38851
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38811
diff
changeset
|
292 |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38811
diff
changeset
|
293 def cleanup(repo, replacements, wdirwritten): |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38811
diff
changeset
|
294 """Calls scmutil.cleanupnodes() with the given replacements. |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38811
diff
changeset
|
295 |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38811
diff
changeset
|
296 "replacements" is a dict from nodeid to nodeid, with one key and one value |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38811
diff
changeset
|
297 for every revision that was affected by fixing. This is slightly different |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38811
diff
changeset
|
298 from cleanupnodes(). |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38811
diff
changeset
|
299 |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38811
diff
changeset
|
300 "wdirwritten" is a bool which tells whether the working copy was affected by |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38811
diff
changeset
|
301 fixing, since it has no entry in "replacements". |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38811
diff
changeset
|
302 |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38811
diff
changeset
|
303 Useful as a hook point for extending "hg fix" with output summarizing the |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38811
diff
changeset
|
304 effects of the command, though we choose not to output anything here. |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38811
diff
changeset
|
305 """ |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38811
diff
changeset
|
306 replacements = {prec: [succ] for prec, succ in replacements.iteritems()} |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38811
diff
changeset
|
307 scmutil.cleanupnodes(repo, replacements, 'fix', fixphase=True) |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
308 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
309 def getworkqueue(ui, repo, pats, opts, revstofix, basectxs): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
310 """"Constructs the list of files to be fixed at specific revisions |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
311 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
312 It is up to the caller how to consume the work items, and the only |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
313 dependence between them is that replacement revisions must be committed in |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
314 topological order. Each work item represents a file in the working copy or |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
315 in some revision that should be fixed and written back to the working copy |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
316 or into a replacement revision. |
38537
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
317 |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
318 Work items for the same revision are grouped together, so that a worker |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
319 pool starting with the first N items in parallel is likely to finish the |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
320 first revision's work before other revisions. This can allow us to write |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
321 the result to disk and reduce memory footprint. At time of writing, the |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
322 partition strategy in worker.py seems favorable to this. We also sort the |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
323 items by ascending revision number to match the order in which we commit |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
324 the fixes later. |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
325 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
326 workqueue = [] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
327 numitems = collections.defaultdict(int) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
328 maxfilesize = ui.configbytes('fix', 'maxfilesize') |
38537
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38429
diff
changeset
|
329 for rev in sorted(revstofix): |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
330 fixctx = repo[rev] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
331 match = scmutil.match(fixctx, pats, opts) |
42009
8f427f7c1f71
fix: make the order of the work queue deterministic
Danny Hooper <hooper@google.com>
parents:
42008
diff
changeset
|
332 for path in sorted(pathstofix( |
8f427f7c1f71
fix: make the order of the work queue deterministic
Danny Hooper <hooper@google.com>
parents:
42008
diff
changeset
|
333 ui, repo, pats, opts, match, basectxs[rev], fixctx)): |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
334 fctx = fixctx[path] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
335 if fctx.islink(): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
336 continue |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
337 if fctx.size() > maxfilesize: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
338 ui.warn(_('ignoring file larger than %s: %s\n') % |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
339 (util.bytecount(maxfilesize), path)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
340 continue |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
341 workqueue.append((rev, path)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
342 numitems[rev] += 1 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
343 return workqueue, numitems |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
344 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
345 def getrevstofix(ui, repo, opts): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
346 """Returns the set of revision numbers that should be fixed""" |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
347 revs = set(scmutil.revrange(repo, opts['rev'])) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
348 for rev in revs: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
349 checkfixablectx(ui, repo, repo[rev]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
350 if revs: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
351 cmdutil.checkunfinished(repo) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
352 checknodescendants(repo, revs) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
353 if opts.get('working_dir'): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
354 revs.add(wdirrev) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
355 if list(merge.mergestate.read(repo).unresolved()): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
356 raise error.Abort('unresolved conflicts', hint="use 'hg resolve'") |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
357 if not revs: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
358 raise error.Abort( |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
359 'no changesets specified', hint='use --rev or --working-dir') |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
360 return revs |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
361 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
362 def checknodescendants(repo, revs): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
363 if (not obsolete.isenabled(repo, obsolete.allowunstableopt) and |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
364 repo.revs('(%ld::) - (%ld)', revs, revs)): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
365 raise error.Abort(_('can only fix a changeset together ' |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
366 'with all its descendants')) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
367 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
368 def checkfixablectx(ui, repo, ctx): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
369 """Aborts if the revision shouldn't be replaced with a fixed one.""" |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
370 if not ctx.mutable(): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
371 raise error.Abort('can\'t fix immutable changeset %s' % |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
372 (scmutil.formatchangeid(ctx),)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
373 if ctx.obsolete(): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
374 # It would be better to actually check if the revision has a successor. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
375 allowdivergence = ui.configbool('experimental', |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
376 'evolution.allowdivergence') |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
377 if not allowdivergence: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
378 raise error.Abort('fixing obsolete revision could cause divergence') |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
379 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
380 def pathstofix(ui, repo, pats, opts, match, basectxs, fixctx): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
381 """Returns the set of files that should be fixed in a context |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
382 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
383 The result depends on the base contexts; we include any file that has |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
384 changed relative to any of the base contexts. Base contexts should be |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
385 ancestors of the context being fixed. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
386 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
387 files = set() |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
388 for basectx in basectxs: |
38811
260c17eaf3f7
fix: use ctx1.status(ctx2) instead of repo.status(ctx1, ctx2)
Martin von Zweigbergk <martinvonz@google.com>
parents:
38591
diff
changeset
|
389 stat = basectx.status(fixctx, match=match, listclean=bool(pats), |
260c17eaf3f7
fix: use ctx1.status(ctx2) instead of repo.status(ctx1, ctx2)
Martin von Zweigbergk <martinvonz@google.com>
parents:
38591
diff
changeset
|
390 listunknown=bool(pats)) |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
391 files.update( |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
392 set(itertools.chain(stat.added, stat.modified, stat.clean, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
393 stat.unknown))) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
394 return files |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
395 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
396 def lineranges(opts, path, basectxs, fixctx, content2): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
397 """Returns the set of line ranges that should be fixed in a file |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
398 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
399 Of the form [(10, 20), (30, 40)]. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
400 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
401 This depends on the given base contexts; we must consider lines that have |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
402 changed versus any of the base contexts, and whether the file has been |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
403 renamed versus any of them. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
404 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
405 Another way to understand this is that we exclude line ranges that are |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
406 common to the file in all base contexts. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
407 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
408 if opts.get('whole'): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
409 # Return a range containing all lines. Rely on the diff implementation's |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
410 # idea of how many lines are in the file, instead of reimplementing it. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
411 return difflineranges('', content2) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
412 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
413 rangeslist = [] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
414 for basectx in basectxs: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
415 basepath = copies.pathcopies(basectx, fixctx).get(path, path) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
416 if basepath in basectx: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
417 content1 = basectx[basepath].data() |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
418 else: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
419 content1 = '' |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
420 rangeslist.extend(difflineranges(content1, content2)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
421 return unionranges(rangeslist) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
422 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
423 def unionranges(rangeslist): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
424 """Return the union of some closed intervals |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
425 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
426 >>> unionranges([]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
427 [] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
428 >>> unionranges([(1, 100)]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
429 [(1, 100)] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
430 >>> unionranges([(1, 100), (1, 100)]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
431 [(1, 100)] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
432 >>> unionranges([(1, 100), (2, 100)]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
433 [(1, 100)] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
434 >>> unionranges([(1, 99), (1, 100)]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
435 [(1, 100)] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
436 >>> unionranges([(1, 100), (40, 60)]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
437 [(1, 100)] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
438 >>> unionranges([(1, 49), (50, 100)]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
439 [(1, 100)] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
440 >>> unionranges([(1, 48), (50, 100)]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
441 [(1, 48), (50, 100)] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
442 >>> unionranges([(1, 2), (3, 4), (5, 6)]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
443 [(1, 6)] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
444 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
445 rangeslist = sorted(set(rangeslist)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
446 unioned = [] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
447 if rangeslist: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
448 unioned, rangeslist = [rangeslist[0]], rangeslist[1:] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
449 for a, b in rangeslist: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
450 c, d = unioned[-1] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
451 if a > d + 1: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
452 unioned.append((a, b)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
453 else: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
454 unioned[-1] = (c, max(b, d)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
455 return unioned |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
456 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
457 def difflineranges(content1, content2): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
458 """Return list of line number ranges in content2 that differ from content1. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
459 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
460 Line numbers are 1-based. The numbers are the first and last line contained |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
461 in the range. Single-line ranges have the same line number for the first and |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
462 last line. Excludes any empty ranges that result from lines that are only |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
463 present in content1. Relies on mdiff's idea of where the line endings are in |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
464 the string. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
465 |
37215
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
466 >>> from mercurial import pycompat |
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
467 >>> lines = lambda s: b'\\n'.join([c for c in pycompat.iterbytestr(s)]) |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
468 >>> difflineranges2 = lambda a, b: difflineranges(lines(a), lines(b)) |
37215
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
469 >>> difflineranges2(b'', b'') |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
470 [] |
37215
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
471 >>> difflineranges2(b'a', b'') |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
472 [] |
37215
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
473 >>> difflineranges2(b'', b'A') |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
474 [(1, 1)] |
37215
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
475 >>> difflineranges2(b'a', b'a') |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
476 [] |
37215
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
477 >>> difflineranges2(b'a', b'A') |
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
478 [(1, 1)] |
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
479 >>> difflineranges2(b'ab', b'') |
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
480 [] |
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
481 >>> difflineranges2(b'', b'AB') |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
482 [(1, 2)] |
37215
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
483 >>> difflineranges2(b'abc', b'ac') |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
484 [] |
37215
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
485 >>> difflineranges2(b'ab', b'aCb') |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
486 [(2, 2)] |
37215
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
487 >>> difflineranges2(b'abc', b'aBc') |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
488 [(2, 2)] |
37215
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
489 >>> difflineranges2(b'ab', b'AB') |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
490 [(1, 2)] |
37215
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
491 >>> difflineranges2(b'abcde', b'aBcDe') |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
492 [(2, 2), (4, 4)] |
37215
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
493 >>> difflineranges2(b'abcde', b'aBCDe') |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
494 [(2, 4)] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
495 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
496 ranges = [] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
497 for lines, kind in mdiff.allblocks(content1, content2): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
498 firstline, lastline = lines[2:4] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
499 if kind == '!' and firstline != lastline: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
500 ranges.append((firstline + 1, lastline)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
501 return ranges |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
502 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
503 def getbasectxs(repo, opts, revstofix): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
504 """Returns a map of the base contexts for each revision |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
505 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
506 The base contexts determine which lines are considered modified when we |
38591
f068495a1c28
fix: add test case that shows why --whole with --base is useful
Danny Hooper <hooper@google.com>
parents:
38538
diff
changeset
|
507 attempt to fix just the modified lines in a file. It also determines which |
f068495a1c28
fix: add test case that shows why --whole with --base is useful
Danny Hooper <hooper@google.com>
parents:
38538
diff
changeset
|
508 files we attempt to fix, so it is important to compute this even when |
f068495a1c28
fix: add test case that shows why --whole with --base is useful
Danny Hooper <hooper@google.com>
parents:
38538
diff
changeset
|
509 --whole is used. |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
510 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
511 # The --base flag overrides the usual logic, and we give every revision |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
512 # exactly the set of baserevs that the user specified. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
513 if opts.get('base'): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
514 baserevs = set(scmutil.revrange(repo, opts.get('base'))) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
515 if not baserevs: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
516 baserevs = {nullrev} |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
517 basectxs = {repo[rev] for rev in baserevs} |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
518 return {rev: basectxs for rev in revstofix} |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
519 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
520 # Proceed in topological order so that we can easily determine each |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
521 # revision's baserevs by looking at its parents and their baserevs. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
522 basectxs = collections.defaultdict(set) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
523 for rev in sorted(revstofix): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
524 ctx = repo[rev] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
525 for pctx in ctx.parents(): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
526 if pctx.rev() in basectxs: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
527 basectxs[rev].update(basectxs[pctx.rev()]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
528 else: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
529 basectxs[rev].add(pctx) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
530 return basectxs |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
531 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
532 def fixfile(ui, opts, fixers, fixctx, path, basectxs): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
533 """Run any configured fixers that should affect the file in this context |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
534 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
535 Returns the file content that results from applying the fixers in some order |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
536 starting with the file's content in the fixctx. Fixers that support line |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
537 ranges will affect lines that have changed relative to any of the basectxs |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
538 (i.e. they will only avoid lines that are common to all basectxs). |
39005
a009589cd32a
fix: determine fixer tool failure by exit code instead of stderr
Danny Hooper <hooper@google.com>
parents:
38988
diff
changeset
|
539 |
a009589cd32a
fix: determine fixer tool failure by exit code instead of stderr
Danny Hooper <hooper@google.com>
parents:
38988
diff
changeset
|
540 A fixer tool's stdout will become the file's new content if and only if it |
a009589cd32a
fix: determine fixer tool failure by exit code instead of stderr
Danny Hooper <hooper@google.com>
parents:
38988
diff
changeset
|
541 exits with code zero. |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
542 """ |
42229
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
543 metadata = {} |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
544 newdata = fixctx[path].data() |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
545 for fixername, fixer in fixers.iteritems(): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
546 if fixer.affects(opts, fixctx, path): |
38899
257c9846b532
fix: compute changed lines lazily to make whole-file fixer tools faster
Danny Hooper <hooper@google.com>
parents:
38851
diff
changeset
|
547 rangesfn = lambda: lineranges(opts, path, basectxs, fixctx, newdata) |
257c9846b532
fix: compute changed lines lazily to make whole-file fixer tools faster
Danny Hooper <hooper@google.com>
parents:
38851
diff
changeset
|
548 command = fixer.command(ui, path, rangesfn) |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
549 if command is None: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
550 continue |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
551 ui.debug('subprocess: %s\n' % (command,)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
552 proc = subprocess.Popen( |
39841
f1d6021453c2
py3: remove a couple of superfluous calls to pycompat.rapply()
Matt Harbison <matt_harbison@yahoo.com>
parents:
39831
diff
changeset
|
553 procutil.tonativestr(command), |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
554 shell=True, |
39831
c31ce080eb75
py3: convert arguments, cwd and env to native strings when spawning subprocess
Matt Harbison <matt_harbison@yahoo.com>
parents:
39005
diff
changeset
|
555 cwd=procutil.tonativestr(b'/'), |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
556 stdin=subprocess.PIPE, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
557 stdout=subprocess.PIPE, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
558 stderr=subprocess.PIPE) |
42229
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
559 stdout, stderr = proc.communicate(newdata) |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
560 if stderr: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
561 showstderr(ui, fixctx.rev(), fixername, stderr) |
42229
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
562 newerdata = stdout |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
563 if fixer.shouldoutputmetadata(): |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
564 try: |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
565 metadatajson, newerdata = stdout.split('\0', 1) |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
566 metadata[fixername] = json.loads(metadatajson) |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
567 except ValueError: |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
568 ui.warn(_('ignored invalid output from fixer tool: %s\n') % |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
569 (fixername,)) |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
570 continue |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
571 else: |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
572 metadata[fixername] = None |
39005
a009589cd32a
fix: determine fixer tool failure by exit code instead of stderr
Danny Hooper <hooper@google.com>
parents:
38988
diff
changeset
|
573 if proc.returncode == 0: |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
574 newdata = newerdata |
40582
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
575 else: |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
576 if not stderr: |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
577 message = _('exited with status %d\n') % (proc.returncode,) |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
578 showstderr(ui, fixctx.rev(), fixername, message) |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
579 checktoolfailureaction( |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
580 ui, _('no fixes will be applied'), |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
581 hint=_('use --config fix.failure=continue to apply any ' |
93bab80993f4
fix: add a config to abort when a fixer tool fails
Danny Hooper <hooper@google.com>
parents:
40417
diff
changeset
|
582 'successful fixes anyway')) |
42229
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
583 return metadata, newdata |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
584 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
585 def showstderr(ui, rev, fixername, stderr): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
586 """Writes the lines of the stderr string as warnings on the ui |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
587 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
588 Uses the revision number and fixername to give more context to each line of |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
589 the error message. Doesn't include file names, since those take up a lot of |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
590 space and would tend to be included in the error message if they were |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
591 relevant. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
592 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
593 for line in re.split('[\r\n]+', stderr): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
594 if line: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
595 ui.warn(('[')) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
596 if rev is None: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
597 ui.warn(_('wdir'), label='evolve.rev') |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
598 else: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
599 ui.warn((str(rev)), label='evolve.rev') |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
600 ui.warn(('] %s: %s\n') % (fixername, line)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
601 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
602 def writeworkingdir(repo, ctx, filedata, replacements): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
603 """Write new content to the working copy and check out the new p1 if any |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
604 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
605 We check out a new revision if and only if we fixed something in both the |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
606 working directory and its parent revision. This avoids the need for a full |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
607 update/merge, and means that the working directory simply isn't affected |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
608 unless the --working-dir flag is given. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
609 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
610 Directly updates the dirstate for the affected files. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
611 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
612 for path, data in filedata.iteritems(): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
613 fctx = ctx[path] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
614 fctx.write(data, fctx.flags()) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
615 if repo.dirstate[path] == 'n': |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
616 repo.dirstate.normallookup(path) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
617 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
618 oldparentnodes = repo.dirstate.parents() |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
619 newparentnodes = [replacements.get(n, n) for n in oldparentnodes] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
620 if newparentnodes != oldparentnodes: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
621 repo.setparents(*newparentnodes) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
622 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
623 def replacerev(ui, repo, ctx, filedata, replacements): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
624 """Commit a new revision like the given one, but with file content changes |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
625 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
626 "ctx" is the original revision to be replaced by a modified one. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
627 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
628 "filedata" is a dict that maps paths to their new file content. All other |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
629 paths will be recreated from the original revision without changes. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
630 "filedata" may contain paths that didn't exist in the original revision; |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
631 they will be added. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
632 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
633 "replacements" is a dict that maps a single node to a single node, and it is |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
634 updated to indicate the original revision is replaced by the newly created |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
635 one. No entry is added if the replacement's node already exists. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
636 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
637 The new revision has the same parents as the old one, unless those parents |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
638 have already been replaced, in which case those replacements are the parents |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
639 of this new revision. Thus, if revisions are replaced in topological order, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
640 there is no need to rebase them into the original topology later. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
641 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
642 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
643 p1rev, p2rev = repo.changelog.parentrevs(ctx.rev()) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
644 p1ctx, p2ctx = repo[p1rev], repo[p2rev] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
645 newp1node = replacements.get(p1ctx.node(), p1ctx.node()) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
646 newp2node = replacements.get(p2ctx.node(), p2ctx.node()) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
647 |
40617
ad71c792a8d8
fix: add extra field to fixed revisions to avoid creating obsolescence cycles
Danny Hooper <hooper@google.com>
parents:
40613
diff
changeset
|
648 # We don't want to create a revision that has no changes from the original, |
ad71c792a8d8
fix: add extra field to fixed revisions to avoid creating obsolescence cycles
Danny Hooper <hooper@google.com>
parents:
40613
diff
changeset
|
649 # but we should if the original revision's parent has been replaced. |
ad71c792a8d8
fix: add extra field to fixed revisions to avoid creating obsolescence cycles
Danny Hooper <hooper@google.com>
parents:
40613
diff
changeset
|
650 # Otherwise, we would produce an orphan that needs no actual human |
ad71c792a8d8
fix: add extra field to fixed revisions to avoid creating obsolescence cycles
Danny Hooper <hooper@google.com>
parents:
40613
diff
changeset
|
651 # intervention to evolve. We can't rely on commit() to avoid creating the |
ad71c792a8d8
fix: add extra field to fixed revisions to avoid creating obsolescence cycles
Danny Hooper <hooper@google.com>
parents:
40613
diff
changeset
|
652 # un-needed revision because the extra field added below produces a new hash |
ad71c792a8d8
fix: add extra field to fixed revisions to avoid creating obsolescence cycles
Danny Hooper <hooper@google.com>
parents:
40613
diff
changeset
|
653 # regardless of file content changes. |
ad71c792a8d8
fix: add extra field to fixed revisions to avoid creating obsolescence cycles
Danny Hooper <hooper@google.com>
parents:
40613
diff
changeset
|
654 if (not filedata and |
ad71c792a8d8
fix: add extra field to fixed revisions to avoid creating obsolescence cycles
Danny Hooper <hooper@google.com>
parents:
40613
diff
changeset
|
655 p1ctx.node() not in replacements and |
ad71c792a8d8
fix: add extra field to fixed revisions to avoid creating obsolescence cycles
Danny Hooper <hooper@google.com>
parents:
40613
diff
changeset
|
656 p2ctx.node() not in replacements): |
ad71c792a8d8
fix: add extra field to fixed revisions to avoid creating obsolescence cycles
Danny Hooper <hooper@google.com>
parents:
40613
diff
changeset
|
657 return |
ad71c792a8d8
fix: add extra field to fixed revisions to avoid creating obsolescence cycles
Danny Hooper <hooper@google.com>
parents:
40613
diff
changeset
|
658 |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
659 def filectxfn(repo, memctx, path): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
660 if path not in ctx: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
661 return None |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
662 fctx = ctx[path] |
41994
550a172a603b
memctx: rename constructor argument "copied" to "copysource" (API)
Martin von Zweigbergk <martinvonz@google.com>
parents:
41786
diff
changeset
|
663 copysource = fctx.copysource() |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
664 return context.memfilectx( |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
665 repo, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
666 memctx, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
667 path=fctx.path(), |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
668 data=filedata.get(path, fctx.data()), |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
669 islink=fctx.islink(), |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
670 isexec=fctx.isexec(), |
41994
550a172a603b
memctx: rename constructor argument "copied" to "copysource" (API)
Martin von Zweigbergk <martinvonz@google.com>
parents:
41786
diff
changeset
|
671 copysource=copysource) |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
672 |
40617
ad71c792a8d8
fix: add extra field to fixed revisions to avoid creating obsolescence cycles
Danny Hooper <hooper@google.com>
parents:
40613
diff
changeset
|
673 extra = ctx.extra().copy() |
ad71c792a8d8
fix: add extra field to fixed revisions to avoid creating obsolescence cycles
Danny Hooper <hooper@google.com>
parents:
40613
diff
changeset
|
674 extra['fix_source'] = ctx.hex() |
ad71c792a8d8
fix: add extra field to fixed revisions to avoid creating obsolescence cycles
Danny Hooper <hooper@google.com>
parents:
40613
diff
changeset
|
675 |
38429
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38426
diff
changeset
|
676 memctx = context.memctx( |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38426
diff
changeset
|
677 repo, |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38426
diff
changeset
|
678 parents=(newp1node, newp2node), |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38426
diff
changeset
|
679 text=ctx.description(), |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38426
diff
changeset
|
680 files=set(ctx.files()) | set(filedata.keys()), |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38426
diff
changeset
|
681 filectxfn=filectxfn, |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38426
diff
changeset
|
682 user=ctx.user(), |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38426
diff
changeset
|
683 date=ctx.date(), |
40617
ad71c792a8d8
fix: add extra field to fixed revisions to avoid creating obsolescence cycles
Danny Hooper <hooper@google.com>
parents:
40613
diff
changeset
|
684 extra=extra, |
38429
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38426
diff
changeset
|
685 branch=ctx.branch(), |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38426
diff
changeset
|
686 editor=None) |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38426
diff
changeset
|
687 sucnode = memctx.commit() |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38426
diff
changeset
|
688 prenode = ctx.node() |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38426
diff
changeset
|
689 if prenode == sucnode: |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38426
diff
changeset
|
690 ui.debug('node %s already existed\n' % (ctx.hex())) |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38426
diff
changeset
|
691 else: |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38426
diff
changeset
|
692 replacements[ctx.node()] = sucnode |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
693 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
694 def getfixers(ui): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
695 """Returns a map of configured fixer tools indexed by their names |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
696 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
697 Each value is a Fixer object with methods that implement the behavior of the |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
698 fixer's config suboptions. Does not validate the config values. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
699 """ |
40613
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
700 fixers = {} |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
701 for name in fixernames(ui): |
40613
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
702 fixers[name] = Fixer() |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
703 attrs = ui.configsuboptions('fix', name)[1] |
40613
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
704 for key, default in FIXER_ATTRS.items(): |
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
705 setattr(fixers[name], pycompat.sysstr('_' + key), |
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
706 attrs.get(key, default)) |
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
707 fixers[name]._priority = int(fixers[name]._priority) |
42687
2987d015aba4
fix: ignore fixer tool configurations that are missing patterns
Danny Hooper <hooper@google.com>
parents:
42685
diff
changeset
|
708 # Don't use a fixer if it has no pattern configured. It would be |
2987d015aba4
fix: ignore fixer tool configurations that are missing patterns
Danny Hooper <hooper@google.com>
parents:
42685
diff
changeset
|
709 # dangerous to let it affect all files. It would be pointless to let it |
2987d015aba4
fix: ignore fixer tool configurations that are missing patterns
Danny Hooper <hooper@google.com>
parents:
42685
diff
changeset
|
710 # affect no files. There is no reasonable subset of files to use as the |
2987d015aba4
fix: ignore fixer tool configurations that are missing patterns
Danny Hooper <hooper@google.com>
parents:
42685
diff
changeset
|
711 # default. |
2987d015aba4
fix: ignore fixer tool configurations that are missing patterns
Danny Hooper <hooper@google.com>
parents:
42685
diff
changeset
|
712 if fixers[name]._pattern is None: |
2987d015aba4
fix: ignore fixer tool configurations that are missing patterns
Danny Hooper <hooper@google.com>
parents:
42685
diff
changeset
|
713 ui.warn( |
2987d015aba4
fix: ignore fixer tool configurations that are missing patterns
Danny Hooper <hooper@google.com>
parents:
42685
diff
changeset
|
714 _('fixer tool has no pattern configuration: %s\n') % (name,)) |
2987d015aba4
fix: ignore fixer tool configurations that are missing patterns
Danny Hooper <hooper@google.com>
parents:
42685
diff
changeset
|
715 del fixers[name] |
40613
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
716 return collections.OrderedDict( |
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
717 sorted(fixers.items(), key=lambda item: item[1]._priority, |
b9557567cc3f
fix: add suboption for configuring execution order of tools
Danny Hooper <hooper@google.com>
parents:
40583
diff
changeset
|
718 reverse=True)) |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
719 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
720 def fixernames(ui): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
721 """Returns the names of [fix] config options that have suboptions""" |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
722 names = set() |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
723 for k, v in ui.configitems('fix'): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
724 if ':' in k: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
725 names.add(k.split(':', 1)[0]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
726 return names |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
727 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
728 class Fixer(object): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
729 """Wraps the raw config values for a fixer with methods""" |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
730 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
731 def affects(self, opts, fixctx, path): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
732 """Should this fixer run on the file at the given path and context?""" |
42687
2987d015aba4
fix: ignore fixer tool configurations that are missing patterns
Danny Hooper <hooper@google.com>
parents:
42685
diff
changeset
|
733 return (self._pattern is not None and |
2987d015aba4
fix: ignore fixer tool configurations that are missing patterns
Danny Hooper <hooper@google.com>
parents:
42685
diff
changeset
|
734 scmutil.match(fixctx, [self._pattern], opts)(path)) |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
735 |
42229
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
736 def shouldoutputmetadata(self): |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
737 """Should the stdout of this fixer start with JSON and a null byte?""" |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
738 return self._metadata |
0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
Danny Hooper <hooper@google.com>
parents:
42009
diff
changeset
|
739 |
38899
257c9846b532
fix: compute changed lines lazily to make whole-file fixer tools faster
Danny Hooper <hooper@google.com>
parents:
38851
diff
changeset
|
740 def command(self, ui, path, rangesfn): |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
741 """A shell command to use to invoke this fixer on the given file/lines |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
742 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
743 May return None if there is no appropriate command to run for the given |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
744 parameters. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
745 """ |
37774
d6970628b95f
fix: use templater to substitute values in command string
Yuya Nishihara <yuya@tcha.org>
parents:
37618
diff
changeset
|
746 expand = cmdutil.rendercommandtemplate |
d6970628b95f
fix: use templater to substitute values in command string
Yuya Nishihara <yuya@tcha.org>
parents:
37618
diff
changeset
|
747 parts = [expand(ui, self._command, |
d6970628b95f
fix: use templater to substitute values in command string
Yuya Nishihara <yuya@tcha.org>
parents:
37618
diff
changeset
|
748 {'rootpath': path, 'basename': os.path.basename(path)})] |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
749 if self._linerange: |
38899
257c9846b532
fix: compute changed lines lazily to make whole-file fixer tools faster
Danny Hooper <hooper@google.com>
parents:
38851
diff
changeset
|
750 ranges = rangesfn() |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
751 if not ranges: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
752 # No line ranges to fix, so don't run the fixer. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
753 return None |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
754 for first, last in ranges: |
37774
d6970628b95f
fix: use templater to substitute values in command string
Yuya Nishihara <yuya@tcha.org>
parents:
37618
diff
changeset
|
755 parts.append(expand(ui, self._linerange, |
d6970628b95f
fix: use templater to substitute values in command string
Yuya Nishihara <yuya@tcha.org>
parents:
37618
diff
changeset
|
756 {'first': first, 'last': last})) |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
757 return ' '.join(parts) |