forked from WebKit/WebKit
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrebase-patch-after-webkit-move
More file actions
executable file
·152 lines (123 loc) · 6.12 KB
/
rebase-patch-after-webkit-move
File metadata and controls
executable file
·152 lines (123 loc) · 6.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#!/usr/bin/env python
# Copyright (C) 2017 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# A webkitpy import needs to go first for autoinstaller to work with subsequent imports.
import webkitpy
import os
import six
import sys
REBASE_DICTIONARY = {
'WebKit2/': 'WebKit/',
'WebKit/': 'WebKitLegacy/'
}
class RebaseStatus:
DO_NOT_NEED = 0
MAYBE_NEED = 1
NEED = 2
ALREADY = 3
def append_source(path):
return os.path.join('Source', path)
def is_editable_line(line):
editable_prefixes = ('Index: ', '--- ', '+++ ', 'diff --git ')
return any(map(line.startswith, editable_prefixes))
def needs_rebase(line):
if not is_editable_line(line):
return RebaseStatus.DO_NOT_NEED
for current_name, rebased_name in six.iteritems(REBASE_DICTIONARY):
# Check if we've already rebased. We need to check if the rebased_name is already in the REBASE_DICTIONARY,
# in this case, we don't know if we've already been rebased.
if append_source(rebased_name) in line and rebased_name not in REBASE_DICTIONARY:
return RebaseStatus.ALREADY
# Check if we need to rebase. We need to check if the current name is one of the potential rebase names.
# In this case, we don't know if we need the rebase.
if append_source(current_name) in line and current_name not in REBASE_DICTIONARY.values():
return RebaseStatus.NEED
# Check if we might need a rebase
for current_name, rebased_name in six.iteritems(REBASE_DICTIONARY):
if append_source(current_name) in line:
return RebaseStatus.MAYBE_NEED
return RebaseStatus.DO_NOT_NEED
def rebase_line(line):
if not is_editable_line(line):
for current_name, rebased_name in six.iteritems(REBASE_DICTIONARY):
if current_name in line:
sys.stderr.write('Found an instance of {} in the patch. Did you mean to replace it with {}?\n'.format(current_name, rebased_name))
return line
for current_name, rebased_name in six.iteritems(REBASE_DICTIONARY):
if append_source(current_name) in line:
return line.replace(append_source(current_name), append_source(rebased_name))
return line
def rebase(patch_content, output_file, patch_name):
rebase_status = RebaseStatus.DO_NOT_NEED
for line in patch_content:
line_status = needs_rebase(line)
if (rebase_status == RebaseStatus.NEED and line_status == RebaseStatus.ALREADY) or (rebase_status == RebaseStatus.ALREADY and line_status == RebaseStatus.NEED):
sys.stderr.write('{} is a partially rebased patch\n'.format(patch_name))
return -1
rebase_status = max(rebase_status, line_status)
if rebase_status == RebaseStatus.MAYBE_NEED and output_file == sys.stdout:
sys.stderr.write('Cannot determine if path from {} has already been rebased, rebasing anyways\n'.format(patch_name))
elif rebase_status == RebaseStatus.MAYBE_NEED:
rebase_status = RebaseStatus.MAYBE_NEED
sys.stdout.write('{} may have already been rebased, are you sure you want to rebase it Y/n?\n'.format(patch_name))
line = sys.stdin.readline().rstrip().upper()
if line == 'Y' or line == 'YES':
rebase_status = RebaseStatus.NEED
if rebase_status == RebaseStatus.ALREADY or rebase_status == RebaseStatus.MAYBE_NEED:
# Output the provided patch if no re-base is required
for line in patch_content:
output_file.write(line)
return 0
if rebase_status == RebaseStatus.MAYBE_NEED:
sys.stderr.write('Cannot determine if path from {} has already been rebased, rebasing anyways\n'.format(patch_name))
for line in patch_content:
output_file.write(rebase_line(line))
return 0
def parse_arguments():
files_to_rebase = []
if len(sys.argv) == 1:
sys.stderr.write('Reading patch from stdin\n')
return []
elif sys.argv[1] == '-h' or sys.argv[1] == 'help':
print('rebase-patch-after-webkit-move usage:')
print('\trebase-patch-after-webkit-move -h, help')
print('\t\tPrint this message')
print('\trebase-patch-after-webkit-move <path to patch>')
print('\t\tReplace the patch at the provided path with a rebased patch')
print('\trebase-patch-after-webkit-move')
print('\t\tTreat stdin as the patch to be rebased')
exit(0)
for path in sys.argv[1:]:
if not os.path.isfile(path):
sys.stderr.write('{} does not exist, cannot rebase patch\n'.format(path))
exit(1)
files_to_rebase.append(path)
return files_to_rebase
if __name__ == '__main__':
files_to_rebase = parse_arguments()
status = 0
for path in files_to_rebase:
if rebase(open(path, 'r').readlines(), open(path, 'w'), path) != 0:
status = 1
if not files_to_rebase:
status = rebase(sys.stdin.readlines(), sys.stdout, 'STDIN')
exit(status)