Merge branch 'stable'
[stgit] / stgit / commands / series.py
CommitLineData
fcee87cf
CM
1
2__copyright__ = """
3Copyright (C) 2005, Catalin Marinas <catalin.marinas@gmail.com>
4
5This program is free software; you can redistribute it and/or modify
6it under the terms of the GNU General Public License version 2 as
7published by the Free Software Foundation.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17"""
18
575bbdae 19from stgit.argparse import opt
448e5d9d
CM
20from stgit.commands import common
21from stgit.commands.common import parse_patches
22from stgit.out import out
607326fd 23from stgit.config import config
6c8a90e1 24from stgit import argparse
fcee87cf 25
575bbdae 26help = 'Print the patch series'
33ff9cdd 27kind = 'stack'
575bbdae
KH
28usage = ['[options] [<patch-range>]']
29description = """
f2496074
KH
30Show all the patches in the series, or just those in the given range,
31ordered from top to bottom.
32
33The applied patches are prefixed with a +++ (except the current patch,
34which is prefixed with a +>+), the unapplied patches with a +-+, and
35the hidden patches with a +!+.
36
37Empty patches are prefixed with a '0'."""
fcee87cf 38
6c8a90e1
KH
39args = [argparse.patch_range(argparse.applied_patches,
40 argparse.unapplied_patches,
41 argparse.hidden_patches)]
575bbdae 42options = [
6c8a90e1 43 opt('-b', '--branch', args = [argparse.stg_branches],
575bbdae
KH
44 short = 'Use BRANCH instead of the default branch'),
45 opt('-a', '--all', action = 'store_true',
46 short = 'Show all patches, including the hidden ones'),
47 opt('-A', '--applied', action = 'store_true',
48 short = 'Show the applied patches only'),
49 opt('-U', '--unapplied', action = 'store_true',
50 short = 'Show the unapplied patches only'),
51 opt('-H', '--hidden', action = 'store_true',
52 short = 'Show the hidden patches only'),
6c8a90e1 53 opt('-m', '--missing', metavar = 'BRANCH', args = [argparse.stg_branches],
575bbdae
KH
54 short = 'Show patches in BRANCH missing in current'),
55 opt('-c', '--count', action = 'store_true',
56 short = 'Print the number of patches in the series'),
57 opt('-d', '--description', action = 'store_true',
58 short = 'Show a short description for each patch'),
59 opt('--author', action = 'store_true',
60 short = 'Show the author name for each patch'),
61 opt('-e', '--empty', action = 'store_true',
f2496074
KH
62 short = 'Check whether patches are empty', long = """
63 Before the +++, +>+, +-+, and +!+ prefixes, print a column
64 that contains either +0+ (for empty patches) or a space (for
65 non-empty patches)."""),
575bbdae
KH
66 opt('--showbranch', action = 'store_true',
67 short = 'Append the branch name to the listed patches'),
68 opt('--noprefix', action = 'store_true',
69 short = 'Do not show the patch status prefix'),
70 opt('-s', '--short', action = 'store_true',
71 short = 'List just the patches around the topmost patch')]
fcee87cf 72
575bbdae 73directory = common.DirectoryHasRepositoryLib()
fcee87cf 74
448e5d9d 75def __get_description(stack, patch):
f82e85bc
CL
76 """Extract and return a patch's short description
77 """
448e5d9d
CM
78 cd = stack.patches.get(patch).commit.data
79 descr = cd.message.strip()
f82e85bc
CL
80 descr_lines = descr.split('\n')
81 return descr_lines[0].rstrip()
82
448e5d9d 83def __get_author(stack, patch):
54fac8e6
CM
84 """Extract and return a patch's short description
85 """
448e5d9d
CM
86 cd = stack.patches.get(patch).commit.data
87 return cd.author.name
54fac8e6 88
2775a653 89def __print_patch(stack, patch, branch_str, prefix, length, options):
841c7b2a
CM
90 """Print a patch name, description and various markers.
91 """
f483998b
CM
92 if options.noprefix:
93 prefix = ''
2775a653
DK
94 elif options.empty:
95 if stack.patches.get(patch).is_empty():
96 prefix = '0' + prefix
97 else:
98 prefix = ' ' + prefix
f483998b 99
e4560d7e 100 patch_str = branch_str + patch
f483998b 101
54fac8e6
CM
102 if options.description or options.author:
103 patch_str = patch_str.ljust(length)
104
f82e85bc 105 if options.description:
448e5d9d 106 out.stdout(prefix + patch_str + ' # ' + __get_description(stack, patch))
54fac8e6 107 elif options.author:
448e5d9d 108 out.stdout(prefix + patch_str + ' # ' + __get_author(stack, patch))
f82e85bc 109 else:
27ac2b7e 110 out.stdout(prefix + patch_str)
f82e85bc 111
fcee87cf
CM
112def func(parser, options, args):
113 """Show the patch series
114 """
1f396835 115 if options.all and options.short:
448e5d9d
CM
116 raise common.CmdException, 'combining --all and --short is meaningless'
117
13b26f1a 118 stack = directory.repository.get_stack(options.branch)
448e5d9d
CM
119 if options.missing:
120 cmp_stack = stack
121 stack = directory.repository.get_stack(options.missing)
122
ca8b854c 123 # current series patches
f9d9a062
CM
124 applied = unapplied = hidden = ()
125 if options.applied or options.unapplied or options.hidden:
126 if options.all:
127 raise common.CmdException, \
128 '--all cannot be used with --applied/unapplied/hidden'
129 if options.applied:
130 applied = stack.patchorder.applied
131 if options.unapplied:
132 unapplied = stack.patchorder.unapplied
133 if options.hidden:
134 hidden = stack.patchorder.hidden
135 elif options.all:
448e5d9d
CM
136 applied = stack.patchorder.applied
137 unapplied = stack.patchorder.unapplied
138 hidden = stack.patchorder.hidden
ca8b854c 139 else:
448e5d9d
CM
140 applied = stack.patchorder.applied
141 unapplied = stack.patchorder.unapplied
ca8b854c 142
19ac8fe4 143 if options.missing:
448e5d9d 144 cmp_patches = cmp_stack.patchorder.all
19ac8fe4 145 else:
448e5d9d 146 cmp_patches = ()
19ac8fe4 147
0aebdb85
CM
148 # the filtering range covers the whole series
149 if args:
ca8b854c
CM
150 show_patches = parse_patches(args, applied + unapplied + hidden,
151 len(applied))
0aebdb85 152 else:
ca8b854c 153 show_patches = applied + unapplied + hidden
0aebdb85 154
841c7b2a
CM
155 # missing filtering
156 show_patches = [p for p in show_patches if p not in cmp_patches]
157
0aebdb85 158 # filter the patches
841c7b2a
CM
159 applied = [p for p in applied if p in show_patches]
160 unapplied = [p for p in unapplied if p in show_patches]
ca8b854c 161 hidden = [p for p in hidden if p in show_patches]
948dae34 162
47d6ad47 163 if options.short:
c73e63b7 164 nr = int(config.get('stgit.shortnr'))
c6f366f6
CM
165 if len(applied) > nr:
166 applied = applied[-(nr+1):]
ca8b854c
CM
167 n = len(unapplied)
168 if n > nr:
c6f366f6 169 unapplied = unapplied[:nr]
ca8b854c
CM
170 elif n < nr:
171 hidden = hidden[:nr-n]
47d6ad47 172
ca8b854c 173 patches = applied + unapplied + hidden
0aebdb85
CM
174
175 if options.count:
27ac2b7e 176 out.stdout(len(patches))
0aebdb85
CM
177 return
178
43e97a20
CM
179 if not patches:
180 return
181
f483998b 182 if options.showbranch:
e4560d7e 183 branch_str = stack.name + ':'
f483998b
CM
184 else:
185 branch_str = ''
186
448e5d9d
CM
187 max_len = 0
188 if len(patches) > 0:
189 max_len = max([len(i + branch_str) for i in patches])
841c7b2a 190
448e5d9d
CM
191 if applied:
192 for p in applied[:-1]:
2775a653
DK
193 __print_patch(stack, p, branch_str, '+ ', max_len, options)
194 __print_patch(stack, applied[-1], branch_str, '> ', max_len,
448e5d9d 195 options)
f82e85bc 196
448e5d9d 197 for p in unapplied:
2775a653 198 __print_patch(stack, p, branch_str, '- ', max_len, options)
ca8b854c 199
448e5d9d 200 for p in hidden:
2775a653 201 __print_patch(stack, p, branch_str, '! ', max_len, options)