Commit | Line | Data |
---|---|---|
0d2cd1e4 CM |
1 | __copyright__ = """ |
2 | Copyright (C) 2005, Catalin Marinas <catalin.marinas@gmail.com> | |
3 | ||
4 | This program is free software; you can redistribute it and/or modify | |
5 | it under the terms of the GNU General Public License version 2 as | |
6 | published by the Free Software Foundation. | |
7 | ||
8 | This program is distributed in the hope that it will be useful, | |
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | GNU General Public License for more details. | |
12 | ||
13 | You should have received a copy of the GNU General Public License | |
14 | along with this program; if not, write to the Free Software | |
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
16 | """ | |
17 | ||
18 | import sys, os | |
19 | from optparse import OptionParser, make_option | |
20 | ||
21 | from stgit.commands.common import * | |
22 | from stgit.utils import * | |
23 | from stgit import stack, git | |
24 | ||
25 | ||
26 | help = 'import a GNU diff file as a new patch' | |
27 | usage = """%prog [options] [<file>] | |
28 | ||
29 | Create a new patch and apply the given GNU diff file (or the standard | |
30 | input). By default, the file name is used as the patch name but this | |
31 | can be overriden with the '--name' option. The patch can either be a | |
32 | normal file with the description at the top or it can have standard | |
33 | mail format, the Subject, From and Date headers being used for | |
34 | generating the patch information. | |
35 | ||
36 | The patch description has to be separated from the data with a '---' | |
37 | line. For a normal file, if no author information is given, the first | |
38 | 'Signed-off-by:' line is used.""" | |
39 | ||
40 | options = [make_option('-m', '--mail', | |
41 | help = 'import the patch from a standard e-mail file', | |
42 | action = 'store_true'), | |
43 | make_option('-n', '--name', | |
44 | help = 'use NAME as the patch name'), | |
45 | make_option('-a', '--author', metavar = '"NAME <EMAIL>"', | |
46 | help = 'use "NAME <EMAIL>" as the author details'), | |
47 | make_option('--authname', | |
48 | help = 'use AUTHNAME as the author name'), | |
49 | make_option('--authemail', | |
50 | help = 'use AUTHEMAIL as the author e-mail'), | |
51 | make_option('--authdate', | |
52 | help = 'use AUTHDATE as the author date'), | |
53 | make_option('--commname', | |
54 | help = 'use COMMNAME as the committer name'), | |
55 | make_option('--commemail', | |
56 | help = 'use COMMEMAIL as the committer e-mail')] | |
57 | ||
58 | ||
59 | def __parse_mail(filename = None): | |
60 | """Parse the input file in a mail format and return (description, | |
61 | authname, authemail, authdate) | |
62 | """ | |
63 | if filename: | |
64 | f = file(filename) | |
65 | else: | |
66 | f = sys.stdin | |
67 | ||
68 | descr = authname = authemail = authdate = None | |
69 | ||
70 | # parse the headers | |
71 | for line in f: | |
72 | line = line.strip() | |
73 | if re.match('from:\s+', line, re.I): | |
74 | auth = re.findall('^.*?:\s+(.*)$', line)[0] | |
75 | authname, authemail = name_email(auth) | |
76 | elif re.match('date:\s+', line, re.I): | |
77 | authdate = re.findall('^.*?:\s+(.*)$', line)[0] | |
78 | elif re.match('subject:\s+', line, re.I): | |
79 | descr = re.findall('^.*?:\s+(.*)$', line)[0] | |
80 | elif line == '': | |
81 | # end of headers | |
82 | break | |
83 | ||
186e6b6b | 84 | # remove the '[*PATCH*]' expression in the subject |
0d2cd1e4 | 85 | if descr: |
186e6b6b | 86 | descr = re.findall('^(\[[^\s]*PATCH.*?\])?\s*(.*)$', descr)[0][1] |
0d2cd1e4 CM |
87 | descr += '\n\n' |
88 | else: | |
89 | raise CmdException, 'Subject: line not found' | |
90 | ||
91 | # the rest of the patch description | |
92 | for line in f: | |
70893e13 | 93 | if re.match('---\s*$', line) or re.match('diff -', line): |
0d2cd1e4 CM |
94 | break |
95 | else: | |
96 | descr += line | |
97 | descr.rstrip() | |
98 | ||
99 | if filename: | |
100 | f.close() | |
101 | ||
102 | return (descr, authname, authemail, authdate) | |
103 | ||
104 | def __parse_patch(filename = None): | |
105 | """Parse the input file and return (description, authname, | |
106 | authemail, authdate) | |
107 | """ | |
108 | if filename: | |
109 | f = file(filename) | |
110 | else: | |
111 | f = sys.stdin | |
112 | ||
113 | authname = authemail = authdate = None | |
114 | ||
115 | descr = '' | |
116 | for line in f: | |
117 | # the first 'Signed-of-by:' is the author | |
118 | if not authname and re.match('signed-off-by:\s+', line, re.I): | |
119 | auth = re.findall('^.*?:\s+(.*)$', line)[0] | |
120 | authname, authemail = name_email(auth) | |
121 | ||
70893e13 | 122 | if re.match('---\s*$', line) or re.match('diff -', line): |
0d2cd1e4 CM |
123 | break |
124 | else: | |
125 | descr += line | |
126 | descr.rstrip() | |
127 | ||
128 | if descr == '': | |
129 | descr = None | |
130 | ||
131 | if filename: | |
132 | f.close() | |
133 | ||
134 | return (descr, authname, authemail, authdate) | |
135 | ||
136 | def func(parser, options, args): | |
137 | """Import a GNU diff file as a new patch | |
138 | """ | |
139 | if len(args) > 1: | |
140 | parser.error('incorrect number of arguments') | |
141 | ||
142 | check_local_changes() | |
143 | check_conflicts() | |
144 | check_head_top_equal() | |
145 | ||
146 | if len(args) == 1: | |
147 | filename = args[0] | |
5185abc1 | 148 | else: |
0d2cd1e4 | 149 | filename = None |
5185abc1 CM |
150 | |
151 | if options.name: | |
0d2cd1e4 | 152 | patch = options.name |
5185abc1 CM |
153 | elif filename: |
154 | patch = os.path.basename(filename) | |
0d2cd1e4 CM |
155 | else: |
156 | raise CmdException, 'Unkown patch name' | |
157 | ||
158 | # the defaults | |
159 | message = author_name = author_email = author_date = committer_name = \ | |
160 | committer_email = None | |
161 | ||
162 | if options.author: | |
163 | options.authname, options.authemail = name_email(options.author) | |
164 | ||
165 | if options.mail: | |
166 | message, author_name, author_email, author_date = \ | |
167 | __parse_mail(filename) | |
168 | else: | |
169 | message, author_name, author_email, author_date = \ | |
170 | __parse_patch(filename) | |
171 | ||
172 | # override the automatically parsed settings | |
173 | if options.authname: | |
174 | author_name = options.authname | |
175 | if options.authemail: | |
176 | author_email = options.authemail | |
177 | if options.authdate: | |
178 | author_date = options.authdate | |
179 | if options.commname: | |
180 | committer_name = options.commname | |
181 | if options.commemail: | |
182 | committer_email = options.commemail | |
183 | ||
184 | crt_series.new_patch(patch, message = message, | |
185 | author_name = author_name, | |
186 | author_email = author_email, | |
187 | author_date = author_date, | |
188 | committer_name = committer_name, | |
189 | committer_email = committer_email) | |
190 | ||
191 | print 'Importing patch %s...' % patch, | |
192 | sys.stdout.flush() | |
193 | ||
194 | git.apply_patch(filename) | |
195 | crt_series.refresh_patch() | |
196 | ||
197 | print 'done' | |
198 | print_crt_patch() |