Mercurial > hg-stable
annotate hgext/fix.py @ 37618:1edf3738e000
fix: port most of the way to python 3
Only most of the way because we now have to decide: if we want to keep
the current .format() interface for the config in hgrc, we have to use
unicodes to do formatting in Python 3, rather than bytes. I'm
basically fine with that, so a follow-up patch will do so.
Differential Revision: https://phab.mercurial-scm.org/D3300
author | Augie Fackler <augie@google.com> |
---|---|
date | Thu, 12 Apr 2018 14:27:13 -0400 |
parents | e2506748b47f |
children | d6970628b95f |
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} |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
18 clang-format:fileset=set:**.cpp or **.hpp |
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 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
22 fixed file content is expected on standard output. If there is any output on |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
23 standard error, the file will not be affected. Some values may be substituted |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
24 into the command:: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
25 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
26 {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
|
27 {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
|
28 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
29 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
|
30 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
|
31 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
|
32 substituted into the command:: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
33 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
34 {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
|
35 {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
|
36 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
37 The :fileset suboption determines which files will be passed through each |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
38 configured tool. See :hg:`help fileset` for possible values. If there are file |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
39 arguments to :hg:`fix`, the intersection of these filesets is used. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
40 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
41 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
|
42 processed by :hg:`fix`:: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
43 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
44 [fix] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
45 maxfilesize=2MB |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
46 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
47 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
48 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
49 from __future__ import absolute_import |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
50 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
51 import collections |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
52 import itertools |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
53 import os |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
54 import re |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
55 import subprocess |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
56 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
57 from mercurial.i18n import _ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
58 from mercurial.node import nullrev |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
59 from mercurial.node import wdirrev |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
60 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
61 from mercurial import ( |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
62 cmdutil, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
63 context, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
64 copies, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
65 error, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
66 mdiff, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
67 merge, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
68 obsolete, |
37618
1edf3738e000
fix: port most of the way to python 3
Augie Fackler <augie@google.com>
parents:
37595
diff
changeset
|
69 pycompat, |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
70 registrar, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
71 scmutil, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
72 util, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
73 ) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
74 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
75 # 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
|
76 # 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
|
77 # 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
|
78 # leave the attribute unspecified. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
79 testedwith = 'ships-with-hg-core' |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
80 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
81 cmdtable = {} |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
82 command = registrar.command(cmdtable) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
83 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
84 configtable = {} |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
85 configitem = registrar.configitem(configtable) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
86 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
87 # Register the suboptions allowed for each configured fixer. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
88 FIXER_ATTRS = ('command', 'linerange', 'fileset') |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
89 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
90 for key in FIXER_ATTRS: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
91 configitem('fix', '.*(:%s)?' % key, default=None, generic=True) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
92 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
93 # 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
|
94 # 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
|
95 # user. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
96 configitem('fix', 'maxfilesize', default='2MB') |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
97 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
98 @command('fix', |
37595
e2506748b47f
fix: add --all flag to fix non-public non-obsolete revisions
Danny Hooper <hooper@google.com>
parents:
37215
diff
changeset
|
99 [('', 'all', False, _('fix all non-public non-obsolete revisions')), |
e2506748b47f
fix: add --all flag to fix non-public non-obsolete revisions
Danny Hooper <hooper@google.com>
parents:
37215
diff
changeset
|
100 ('', 'base', [], _('revisions to diff against (overrides automatic ' |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
101 'selection, and applies to every revision being ' |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
102 'fixed)'), _('REV')), |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
103 ('r', 'rev', [], _('revisions to fix'), _('REV')), |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
104 ('w', 'working-dir', False, _('fix the working directory')), |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
105 ('', 'whole', False, _('always fix every line of a file'))], |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
106 _('[OPTION]... [FILE]...')) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
107 def fix(ui, repo, *pats, **opts): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
108 """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
|
109 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
110 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
|
111 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
|
112 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
|
113 whole file regardless of --whole. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
114 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
115 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
|
116 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
|
117 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
|
118 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
|
119 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
|
120 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
121 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
|
122 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
|
123 directory will update to the replacement revision. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
124 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
125 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
|
126 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
|
127 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
|
128 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
|
129 """ |
37618
1edf3738e000
fix: port most of the way to python 3
Augie Fackler <augie@google.com>
parents:
37595
diff
changeset
|
130 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
|
131 if opts['all']: |
e2506748b47f
fix: add --all flag to fix non-public non-obsolete revisions
Danny Hooper <hooper@google.com>
parents:
37215
diff
changeset
|
132 if opts['rev']: |
e2506748b47f
fix: add --all flag to fix non-public non-obsolete revisions
Danny Hooper <hooper@google.com>
parents:
37215
diff
changeset
|
133 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
|
134 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
|
135 opts['working_dir'] = True |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
136 with repo.wlock(), repo.lock(): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
137 revstofix = getrevstofix(ui, repo, opts) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
138 basectxs = getbasectxs(repo, opts, revstofix) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
139 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
|
140 basectxs) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
141 filedata = collections.defaultdict(dict) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
142 replacements = {} |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
143 fixers = getfixers(ui) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
144 # Some day this loop can become a worker pool, but for now it's easier |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
145 # to fix everything serially in topological order. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
146 for rev, path in sorted(workqueue): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
147 ctx = repo[rev] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
148 olddata = ctx[path].data() |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
149 newdata = fixfile(ui, opts, fixers, ctx, path, basectxs[rev]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
150 if newdata != olddata: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
151 filedata[rev][path] = newdata |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
152 numitems[rev] -= 1 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
153 if not numitems[rev]: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
154 if rev == wdirrev: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
155 writeworkingdir(repo, ctx, filedata[rev], replacements) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
156 else: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
157 replacerev(ui, repo, ctx, filedata[rev], replacements) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
158 del filedata[rev] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
159 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
160 replacements = {prec: [succ] for prec, succ in replacements.iteritems()} |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
161 scmutil.cleanupnodes(repo, replacements, 'fix') |
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 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
|
164 """"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
|
165 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
166 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
|
167 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
|
168 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
|
169 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
|
170 or into a replacement revision. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
171 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
172 workqueue = [] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
173 numitems = collections.defaultdict(int) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
174 maxfilesize = ui.configbytes('fix', 'maxfilesize') |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
175 for rev in revstofix: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
176 fixctx = repo[rev] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
177 match = scmutil.match(fixctx, pats, opts) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
178 for path in pathstofix(ui, repo, pats, opts, match, basectxs[rev], |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
179 fixctx): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
180 if path not in fixctx: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
181 continue |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
182 fctx = fixctx[path] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
183 if fctx.islink(): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
184 continue |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
185 if fctx.size() > maxfilesize: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
186 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
|
187 (util.bytecount(maxfilesize), path)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
188 continue |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
189 workqueue.append((rev, path)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
190 numitems[rev] += 1 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
191 return workqueue, numitems |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
192 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
193 def getrevstofix(ui, repo, opts): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
194 """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
|
195 revs = set(scmutil.revrange(repo, opts['rev'])) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
196 for rev in revs: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
197 checkfixablectx(ui, repo, repo[rev]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
198 if revs: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
199 cmdutil.checkunfinished(repo) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
200 checknodescendants(repo, revs) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
201 if opts.get('working_dir'): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
202 revs.add(wdirrev) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
203 if list(merge.mergestate.read(repo).unresolved()): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
204 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
|
205 if not revs: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
206 raise error.Abort( |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
207 '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
|
208 return revs |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
209 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
210 def checknodescendants(repo, revs): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
211 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
|
212 repo.revs('(%ld::) - (%ld)', revs, revs)): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
213 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
|
214 'with all its descendants')) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
215 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
216 def checkfixablectx(ui, repo, ctx): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
217 """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
|
218 if not ctx.mutable(): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
219 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
|
220 (scmutil.formatchangeid(ctx),)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
221 if ctx.obsolete(): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
222 # 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
|
223 allowdivergence = ui.configbool('experimental', |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
224 'evolution.allowdivergence') |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
225 if not allowdivergence: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
226 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
|
227 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
228 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
|
229 """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
|
230 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
231 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
|
232 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
|
233 ancestors of the context being fixed. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
234 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
235 files = set() |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
236 for basectx in basectxs: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
237 stat = repo.status( |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
238 basectx, fixctx, match=match, clean=bool(pats), unknown=bool(pats)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
239 files.update( |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
240 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
|
241 stat.unknown))) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
242 return files |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
243 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
244 def lineranges(opts, path, basectxs, fixctx, content2): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
245 """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
|
246 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
247 Of the form [(10, 20), (30, 40)]. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
248 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
249 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
|
250 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
|
251 renamed versus any of them. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
252 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
253 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
|
254 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
|
255 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
256 if opts.get('whole'): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
257 # 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
|
258 # 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
|
259 return difflineranges('', content2) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
260 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
261 rangeslist = [] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
262 for basectx in basectxs: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
263 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
|
264 if basepath in basectx: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
265 content1 = basectx[basepath].data() |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
266 else: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
267 content1 = '' |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
268 rangeslist.extend(difflineranges(content1, content2)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
269 return unionranges(rangeslist) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
270 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
271 def unionranges(rangeslist): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
272 """Return the union of some closed intervals |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
273 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
274 >>> unionranges([]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
275 [] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
276 >>> unionranges([(1, 100)]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
277 [(1, 100)] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
278 >>> unionranges([(1, 100), (1, 100)]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
279 [(1, 100)] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
280 >>> unionranges([(1, 100), (2, 100)]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
281 [(1, 100)] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
282 >>> unionranges([(1, 99), (1, 100)]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
283 [(1, 100)] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
284 >>> unionranges([(1, 100), (40, 60)]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
285 [(1, 100)] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
286 >>> unionranges([(1, 49), (50, 100)]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
287 [(1, 100)] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
288 >>> unionranges([(1, 48), (50, 100)]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
289 [(1, 48), (50, 100)] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
290 >>> unionranges([(1, 2), (3, 4), (5, 6)]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
291 [(1, 6)] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
292 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
293 rangeslist = sorted(set(rangeslist)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
294 unioned = [] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
295 if rangeslist: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
296 unioned, rangeslist = [rangeslist[0]], rangeslist[1:] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
297 for a, b in rangeslist: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
298 c, d = unioned[-1] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
299 if a > d + 1: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
300 unioned.append((a, b)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
301 else: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
302 unioned[-1] = (c, max(b, d)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
303 return unioned |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
304 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
305 def difflineranges(content1, content2): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
306 """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
|
307 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
308 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
|
309 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
|
310 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
|
311 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
|
312 the string. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
313 |
37215
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
314 >>> from mercurial import pycompat |
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
315 >>> 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
|
316 >>> 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
|
317 >>> difflineranges2(b'', b'') |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
318 [] |
37215
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
319 >>> difflineranges2(b'a', b'') |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
320 [] |
37215
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
321 >>> difflineranges2(b'', b'A') |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
322 [(1, 1)] |
37215
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
323 >>> difflineranges2(b'a', b'a') |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
324 [] |
37215
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
325 >>> difflineranges2(b'a', b'A') |
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
326 [(1, 1)] |
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
327 >>> difflineranges2(b'ab', b'') |
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
328 [] |
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
329 >>> difflineranges2(b'', b'AB') |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
330 [(1, 2)] |
37215
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
331 >>> difflineranges2(b'abc', b'ac') |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
332 [] |
37215
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
333 >>> difflineranges2(b'ab', b'aCb') |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
334 [(2, 2)] |
37215
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
335 >>> difflineranges2(b'abc', b'aBc') |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
336 [(2, 2)] |
37215
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
337 >>> difflineranges2(b'ab', b'AB') |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
338 [(1, 2)] |
37215
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
339 >>> difflineranges2(b'abcde', b'aBcDe') |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
340 [(2, 2), (4, 4)] |
37215
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37209
diff
changeset
|
341 >>> difflineranges2(b'abcde', b'aBCDe') |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
342 [(2, 4)] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
343 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
344 ranges = [] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
345 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
|
346 firstline, lastline = lines[2:4] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
347 if kind == '!' and firstline != lastline: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
348 ranges.append((firstline + 1, lastline)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
349 return ranges |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
350 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
351 def getbasectxs(repo, opts, revstofix): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
352 """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
|
353 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
354 The base contexts determine which lines are considered modified when we |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
355 attempt to fix just the modified lines in a file. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
356 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
357 # 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
|
358 # 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
|
359 if opts.get('base'): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
360 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
|
361 if not baserevs: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
362 baserevs = {nullrev} |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
363 basectxs = {repo[rev] for rev in baserevs} |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
364 return {rev: basectxs for rev in revstofix} |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
365 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
366 # 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
|
367 # 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
|
368 basectxs = collections.defaultdict(set) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
369 for rev in sorted(revstofix): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
370 ctx = repo[rev] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
371 for pctx in ctx.parents(): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
372 if pctx.rev() in basectxs: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
373 basectxs[rev].update(basectxs[pctx.rev()]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
374 else: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
375 basectxs[rev].add(pctx) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
376 return basectxs |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
377 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
378 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
|
379 """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
|
380 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
381 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
|
382 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
|
383 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
|
384 (i.e. they will only avoid lines that are common to all basectxs). |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
385 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
386 newdata = fixctx[path].data() |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
387 for fixername, fixer in fixers.iteritems(): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
388 if fixer.affects(opts, fixctx, path): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
389 ranges = lineranges(opts, path, basectxs, fixctx, newdata) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
390 command = fixer.command(path, ranges) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
391 if command is None: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
392 continue |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
393 ui.debug('subprocess: %s\n' % (command,)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
394 proc = subprocess.Popen( |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
395 command, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
396 shell=True, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
397 cwd='/', |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
398 stdin=subprocess.PIPE, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
399 stdout=subprocess.PIPE, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
400 stderr=subprocess.PIPE) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
401 newerdata, stderr = proc.communicate(newdata) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
402 if stderr: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
403 showstderr(ui, fixctx.rev(), fixername, stderr) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
404 else: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
405 newdata = newerdata |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
406 return newdata |
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 def showstderr(ui, rev, fixername, stderr): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
409 """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
|
410 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
411 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
|
412 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
|
413 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
|
414 relevant. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
415 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
416 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
|
417 if line: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
418 ui.warn(('[')) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
419 if rev is None: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
420 ui.warn(_('wdir'), label='evolve.rev') |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
421 else: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
422 ui.warn((str(rev)), label='evolve.rev') |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
423 ui.warn(('] %s: %s\n') % (fixername, line)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
424 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
425 def writeworkingdir(repo, ctx, filedata, replacements): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
426 """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
|
427 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
428 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
|
429 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
|
430 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
|
431 unless the --working-dir flag is given. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
432 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
433 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
|
434 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
435 for path, data in filedata.iteritems(): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
436 fctx = ctx[path] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
437 fctx.write(data, fctx.flags()) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
438 if repo.dirstate[path] == 'n': |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
439 repo.dirstate.normallookup(path) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
440 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
441 oldparentnodes = repo.dirstate.parents() |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
442 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
|
443 if newparentnodes != oldparentnodes: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
444 repo.setparents(*newparentnodes) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
445 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
446 def replacerev(ui, repo, ctx, filedata, replacements): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
447 """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
|
448 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
449 "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
|
450 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
451 "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
|
452 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
|
453 "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
|
454 they will be added. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
455 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
456 "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
|
457 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
|
458 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
|
459 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
460 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
|
461 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
|
462 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
|
463 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
|
464 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
465 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
466 p1rev, p2rev = repo.changelog.parentrevs(ctx.rev()) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
467 p1ctx, p2ctx = repo[p1rev], repo[p2rev] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
468 newp1node = replacements.get(p1ctx.node(), p1ctx.node()) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
469 newp2node = replacements.get(p2ctx.node(), p2ctx.node()) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
470 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
471 def filectxfn(repo, memctx, path): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
472 if path not in ctx: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
473 return None |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
474 fctx = ctx[path] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
475 copied = fctx.renamed() |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
476 if copied: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
477 copied = copied[0] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
478 return context.memfilectx( |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
479 repo, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
480 memctx, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
481 path=fctx.path(), |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
482 data=filedata.get(path, fctx.data()), |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
483 islink=fctx.islink(), |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
484 isexec=fctx.isexec(), |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
485 copied=copied) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
486 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
487 overrides = {('phases', 'new-commit'): ctx.phase()} |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
488 with ui.configoverride(overrides, source='fix'): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
489 memctx = context.memctx( |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
490 repo, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
491 parents=(newp1node, newp2node), |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
492 text=ctx.description(), |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
493 files=set(ctx.files()) | set(filedata.keys()), |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
494 filectxfn=filectxfn, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
495 user=ctx.user(), |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
496 date=ctx.date(), |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
497 extra=ctx.extra(), |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
498 branch=ctx.branch(), |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
499 editor=None) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
500 sucnode = memctx.commit() |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
501 prenode = ctx.node() |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
502 if prenode == sucnode: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
503 ui.debug('node %s already existed\n' % (ctx.hex())) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
504 else: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
505 replacements[ctx.node()] = sucnode |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
506 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
507 def getfixers(ui): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
508 """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
|
509 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
510 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
|
511 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
|
512 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
513 result = {} |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
514 for name in fixernames(ui): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
515 result[name] = Fixer() |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
516 attrs = ui.configsuboptions('fix', name)[1] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
517 for key in FIXER_ATTRS: |
37618
1edf3738e000
fix: port most of the way to python 3
Augie Fackler <augie@google.com>
parents:
37595
diff
changeset
|
518 setattr(result[name], pycompat.sysstr('_' + key), |
1edf3738e000
fix: port most of the way to python 3
Augie Fackler <augie@google.com>
parents:
37595
diff
changeset
|
519 attrs.get(key, '')) |
37185
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
520 return result |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
521 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
522 def fixernames(ui): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
523 """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
|
524 names = set() |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
525 for k, v in ui.configitems('fix'): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
526 if ':' in k: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
527 names.add(k.split(':', 1)[0]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
528 return names |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
529 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
530 class Fixer(object): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
531 """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
|
532 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
533 def affects(self, opts, fixctx, path): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
534 """Should this fixer run on the file at the given path and context?""" |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
535 return scmutil.match(fixctx, [self._fileset], opts)(path) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
536 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
537 def command(self, path, ranges): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
538 """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
|
539 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
540 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
|
541 parameters. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
542 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
543 parts = [self._command.format(rootpath=path, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
544 basename=os.path.basename(path))] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
545 if self._linerange: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
546 if not ranges: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
547 # 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
|
548 return None |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
549 for first, last in ranges: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
550 parts.append(self._linerange.format(first=first, last=last)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
551 return ' '.join(parts) |