mirror of
https://github.com/apache/lucene.git
synced 2025-02-20 17:07:09 +00:00
LUCENE-5962: Rename diffSources.py to createPatch.py and make work it work with all text file types
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1626890 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
34890299da
commit
c599b96748
131
dev-tools/scripts/createPatch.py
Normal file
131
dev-tools/scripts/createPatch.py
Normal file
@ -0,0 +1,131 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
'''
|
||||
Creates a unified diff, applyable by the patch tool, between two source checkouts.
|
||||
|
||||
Note that .gitignore or svn:ignore rules are used to filter out files that would normally
|
||||
not be checked in.
|
||||
|
||||
While you could use this to make a committable patch from a branch,
|
||||
that approach loses the svn history from the branch (better to use
|
||||
"svn merge --reintegrate", for example). This diff output should
|
||||
not be considered "authoritative" from a merging standpoint as it
|
||||
does not reflect what svn will do on merge.
|
||||
'''
|
||||
|
||||
from argparse import ArgumentParser, RawTextHelpFormatter
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
def make_filter_func(src_dir):
|
||||
if os.path.exists(os.path.join(src_dir, '.git')):
|
||||
def git_filter(filename):
|
||||
rc = subprocess.call('git --git-dir=%s check-ignore %s' % (src_dir, filename), shell=True)
|
||||
return rc == 0
|
||||
return git_filter
|
||||
|
||||
else:
|
||||
def svn_filter(filename):
|
||||
# we can't find if svn will ignore a file unless it exists...
|
||||
created = False
|
||||
if not os.path.exists(filename):
|
||||
head,tail = os.path.split(filename)
|
||||
# find a parent directory that already exists, so we
|
||||
# can see if that is ignored by svn
|
||||
while not os.path.exists(head):
|
||||
filename = head
|
||||
head,tail = os.path.split(filename)
|
||||
created = True
|
||||
subprocess.check_call('touch %s' % filename, shell=True)
|
||||
try:
|
||||
output = subprocess.check_output('svn status %s' % filename,
|
||||
shell=True, stderr=subprocess.STDOUT).strip()
|
||||
return output.startswith(b'I')
|
||||
finally:
|
||||
if created and os.path.exists(filename):
|
||||
os.remove(filename)
|
||||
|
||||
return svn_filter
|
||||
|
||||
def print_filtered_output(output, should_filter):
|
||||
filtering = False
|
||||
line = output.readline()
|
||||
while line:
|
||||
|
||||
if line.startswith(b'diff '):
|
||||
fromfile, tofile = line.decode('utf-8').split()[-2:]
|
||||
if os.path.exists(fromfile) or \
|
||||
os.path.exists(tofile):
|
||||
filtering = should_filter(fromfile)
|
||||
else:
|
||||
# If both files do not exist, then the filename must contain spaces,
|
||||
# which breaks our split logic. In this case, just ignore, since
|
||||
# patch cannot handle filenames with spaces anyways.
|
||||
filtering = True
|
||||
elif line.startswith(b'Binary files'):
|
||||
filtering = True
|
||||
|
||||
if not filtering:
|
||||
print(line.decode('utf-8'), end='')
|
||||
|
||||
line = output.readline()
|
||||
|
||||
def run_diff(from_dir, to_dir, skip_whitespace):
|
||||
flags = '-ruN'
|
||||
if skip_whitespace:
|
||||
flags += 'bBw'
|
||||
|
||||
args = ['diff', flags]
|
||||
for ignore in ('.svn', '.git', 'build', '.caches'):
|
||||
args.append('-x')
|
||||
args.append(ignore)
|
||||
args.append(from_dir)
|
||||
args.append(to_dir)
|
||||
|
||||
return subprocess.Popen(args, shell=False, stdout=subprocess.PIPE)
|
||||
|
||||
def parse_config():
|
||||
parser = ArgumentParser(description=__doc__, formatter_class=RawTextHelpFormatter)
|
||||
parser.add_argument('--skip-whitespace', action='store_true', default=False,
|
||||
help='Ignore whitespace differences')
|
||||
parser.add_argument('from_dir', help='Source directory to diff from')
|
||||
parser.add_argument('to_dir', help='Source directory to diff to')
|
||||
c = parser.parse_args()
|
||||
|
||||
if not os.path.isdir(c.from_dir):
|
||||
parser.error('\'from\' path %s is not a valid directory' % c.from_dir)
|
||||
if not os.path.exists(os.path.join(c.from_dir, 'lucene', 'CHANGES.txt')):
|
||||
parser.error('\'from\' path %s is not a valid lucene/solr checkout' % c.from_dir)
|
||||
if not os.path.isdir(c.to_dir):
|
||||
parser.error('\'to\' path %s is not a valid directory' % c.to_dir)
|
||||
if not os.path.exists(os.path.join(c.to_dir, 'lucene', 'CHANGES.txt')):
|
||||
parser.error('\'to\' path %s is not a valid lucene/solr checkout' % c.to_dir)
|
||||
|
||||
return c
|
||||
|
||||
def main():
|
||||
c = parse_config()
|
||||
|
||||
p = run_diff(c.from_dir, c.to_dir, c.skip_whitespace)
|
||||
should_filter = make_filter_func(c.from_dir)
|
||||
print_filtered_output(p.stdout, should_filter)
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
print('\nReceived Ctrl-C, exiting early')
|
||||
|
@ -1,72 +0,0 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
|
||||
# recursive, unified output format, treat missing files as present but empty
|
||||
DIFF_FLAGS = '-ruN'
|
||||
|
||||
if '-skipWhitespace' in sys.argv:
|
||||
sys.argv.remove('-skipWhitespace')
|
||||
# ignores only whitespace changes
|
||||
DIFF_FLAGS += 'bBw'
|
||||
|
||||
if len(sys.argv) != 3:
|
||||
print
|
||||
print 'Usage: python -u diffSources.py <dir1> <dir2> [-skipWhitespace]'
|
||||
print
|
||||
print '''This tool creates an applying patch between two directories.
|
||||
|
||||
While you could use this to make a committable patch from a branch, that approach loses
|
||||
the svn history from the branch (better to use "svn merge --reintegrate", for example). This
|
||||
diff output should not be considered "authoritative" from a merging standpoint as it does
|
||||
not reflect what svn will do on merge.
|
||||
'''
|
||||
print
|
||||
sys.exit(0)
|
||||
|
||||
p = subprocess.Popen(['diff', DIFF_FLAGS, '-x', '.svn', '-x', 'build', sys.argv[1], sys.argv[2]], shell=False, stdout=subprocess.PIPE)
|
||||
|
||||
keep = False
|
||||
while True:
|
||||
l = p.stdout.readline()
|
||||
if l == '':
|
||||
break
|
||||
if l.endswith('\r\n'):
|
||||
l = l[:-2]
|
||||
elif l.endswith('\n'):
|
||||
l = l[:-1]
|
||||
if l.startswith('diff ') or l.startswith('Binary files '):
|
||||
|
||||
if l.endswith('timehints.txt') or l.find('/build/') != -1 or l.find('/.svn/') != -1:
|
||||
keep = False
|
||||
elif l.lower().startswith('Only in'):
|
||||
keep = True
|
||||
elif l.find('/META-INF/') != -1:
|
||||
keep = True
|
||||
else:
|
||||
ext = os.path.splitext(l)[-1]
|
||||
keep = ext in ('.xml', '.iml', '.html', '.template', '.py', '.g', '.properties', '.java')
|
||||
|
||||
if keep:
|
||||
print
|
||||
print
|
||||
print l.strip()
|
||||
elif keep:
|
||||
print l
|
||||
elif l.startswith('Only in'):
|
||||
print l.strip()
|
@ -193,6 +193,9 @@ Build
|
||||
|
||||
* LUCENE-5902: Add bumpVersion.py script to manage version increase after release branch is cut.
|
||||
|
||||
* LUCENE-5962: Rename diffSources.py to createPatch.py and make it work with all text file types.
|
||||
(Ryan Ernst)
|
||||
|
||||
Other
|
||||
|
||||
* LUCENE-5563: Removed sep layout: which has fallen behind on features and doesn't
|
||||
|
Loading…
x
Reference in New Issue
Block a user