1{-| Patch matching options.
2
3These are all of the same type 'MatchOption' defined below.
4
5Multiple flags per option are allowed and do not raise a conflict error.
6This is how Darcs currently operates, even though I suspect that it ignores
7all but the first 'MatchFlag' (since it does so for many other options).
8
9Given a suitable semantics (and documentation thereof), for instance \"all
10the given patterns must match\", this could be turned into a useful feature.
11
12-}
13module Darcs.UI.Options.Matching
14    ( MatchFlag(..) -- re-export
15    , matchUpToOne
16    , matchOneContext
17    , matchOneNontag
18    , matchSeveral
19    , matchSeveralOrFirst
20    , matchSeveralOrLast
21    , matchRange
22    , matchOneOrRange
23    , matchSeveralOrRange
24    -- * exported for for checking
25    , context
26    , matchLast
27    , matchFrom
28    , matchAny -- temporary hack
29    ) where
30
31import Darcs.Prelude hiding ( last )
32
33import Darcs.Patch.Match ( MatchFlag(..) )
34import qualified Darcs.UI.Options.Flags as F ( DarcsFlag(..) )
35import Darcs.UI.Options.Core
36import Darcs.UI.Options.Util
37
38-- * Type instantiations
39
40type MatchOption = PrimDarcsOption [MatchFlag]
41
42-- * Combined matching options
43
44matchUpToOne :: MatchOption -- ^ show files/contents, dist, annotate
45matchUpToOne = mconcat [match, patch, hash, tag, index]
46
47-- | Used by: clone
48matchOneContext :: MatchOption
49matchOneContext = mconcat [toMatch, toPatch, toHash, tag, context]
50
51-- [NOTE --index removed from matchOneNontag because issue1926]
52-- The --index option was removed for 2.5 release because it isn't handled
53-- by amend-record (see issue1926).
54--
55-- At this moment, amend-record is the only command that uses 'matchOneNontag',
56-- so there is no other command affected.
57
58-- | Used by: amend
59matchOneNontag :: MatchOption
60matchOneNontag =  match <> patch <> hash
61
62-- | Used by: rebase pull/apply, send, push, pull, apply, fetch
63matchSeveral :: MatchOption
64matchSeveral = matches <> patches <> tags <> hash
65
66matchLast :: MatchOption
67matchLast = last
68
69-- | Used by: rebase unsuspend/reify
70matchSeveralOrFirst :: MatchOption
71matchSeveralOrFirst = mconcat [ matchTo, last, matches, patches, tags, hash ]
72
73-- | Used by: unrecord, obliterate, rebase suspend, rollback
74matchSeveralOrLast :: MatchOption
75matchSeveralOrLast = mconcat [ matchFrom, last, matches, patches, tags, hash ]
76
77-- | Used by: diff
78matchOneOrRange :: MatchOption
79matchOneOrRange = mconcat [ match, patch, hash ] <> matchRange
80
81-- | Used by: show dependencies
82matchRange :: MatchOption
83matchRange = mconcat [ matchTo, matchFrom, last, indexes ]
84
85-- | Used by: log
86matchSeveralOrRange :: MatchOption
87matchSeveralOrRange = mconcat
88  [ matchTo, matchFrom, last, indexes, matches, patches, tags, hash ]
89
90matchTo :: MatchOption
91matchTo = toMatch <> toPatch <> toHash <> toTag
92
93matchFrom :: MatchOption
94matchFrom = fromMatch <> fromPatch <> fromHash <> fromTag
95
96matchAny :: MatchOption
97matchAny = mconcat [ toMatch, toPatch, toHash, toTag,
98  fromMatch, fromPatch, fromHash, fromTag,
99  tag, tags, patch, patches, hash, match, matches, index, indexes, context, last ]
100
101-- * Primitive matching options
102
103toMatch, toPatch, toHash, toTag,
104  fromMatch, fromPatch, fromHash, fromTag,
105  tag, tags,
106  patch, patches,
107  hash,
108  match, matches,
109  index, indexes,
110  context, last :: MatchOption
111
112toMatch = OptSpec {..} where
113  ounparse k mfs = k [ F.UpToPattern s | UpToPattern s <- mfs ]
114  oparse k fs = k [ UpToPattern s | F.UpToPattern s <- fs ]
115  ocheck _ = []
116  odesc = [ strArg [] ["to-match"] F.UpToPattern "PATTERN"
117    "select changes up to a patch matching PATTERN" ]
118
119toPatch = OptSpec {..} where
120  ounparse k mfs = k [ F.UpToPatch s | UpToPatch s <- mfs ]
121  oparse k fs = k [ UpToPatch s | F.UpToPatch s <- fs ]
122  ocheck _ = []
123  odesc = [ strArg [] ["to-patch"] F.UpToPatch "REGEXP"
124    "select changes up to a patch matching REGEXP" ]
125
126toHash = OptSpec {..} where
127  ounparse k mfs = k [ F.UpToHash s | UpToHash s <- mfs ]
128  oparse k fs = k [ UpToHash s | F.UpToHash s <- fs ]
129  ocheck _ = []
130  odesc = [ strArg [] ["to-hash"] F.UpToHash "HASH"
131    "select changes up to a patch with HASH" ]
132
133context = OptSpec {..} where
134  ounparse k mfs = k [ F.Context p | Context p <- mfs ]
135  oparse k fs = k [ Context p | F.Context p <- fs ]
136  ocheck _ = []
137  odesc = [ absPathArg [] ["context"] F.Context "FILENAME"
138    "version specified by the context in FILENAME" ]
139
140toTag = OptSpec {..} where
141  ounparse k mfs = k [ F.UpToTag s | UpToTag s <- mfs ]
142  oparse k fs = k [ UpToTag s | F.UpToTag s <- fs ]
143  ocheck _ = []
144  odesc = [ strArg [] ["to-tag"] F.UpToTag "REGEXP"
145    "select changes up to a tag matching REGEXP" ]
146
147fromMatch = OptSpec {..} where
148  ounparse k mfs = k [ F.AfterPattern s | AfterPattern s <- mfs ]
149  oparse k fs = k [ AfterPattern s | F.AfterPattern s <- fs ]
150  ocheck _ = []
151  odesc = [ strArg [] ["from-match"] F.AfterPattern "PATTERN"
152    "select changes starting with a patch matching PATTERN" ]
153
154fromPatch = OptSpec {..} where
155  ounparse k mfs = k [ F.AfterPatch s | AfterPatch s <- mfs ]
156  oparse k fs = k [ AfterPatch s | F.AfterPatch s <- fs ]
157  ocheck _ = []
158  odesc = [ strArg [] ["from-patch"] F.AfterPatch "REGEXP"
159    "select changes starting with a patch matching REGEXP" ]
160
161fromHash = OptSpec {..} where
162  ounparse k mfs = k [ F.AfterHash s | AfterHash s <- mfs ]
163  oparse k fs = k [ AfterHash s | F.AfterHash s <- fs ]
164  ocheck _ = []
165  odesc = [ strArg [] ["from-hash"] F.AfterHash "HASH"
166    "select changes starting with a patch with HASH" ]
167
168fromTag = OptSpec {..} where
169  ounparse k mfs = k [ F.AfterTag s | AfterTag s <- mfs ]
170  oparse k fs = k [ AfterTag s | F.AfterTag s <- fs ]
171  ocheck _ = []
172  odesc = [ strArg [] ["from-tag"] F.AfterTag "REGEXP"
173    "select changes starting with a tag matching REGEXP" ]
174
175tag = OptSpec {..} where
176  ounparse k mfs = k [ F.OneTag s | OneTag s <- mfs ]
177  oparse k fs = k [ OneTag s | F.OneTag s <- fs ]
178  ocheck _ = []
179  odesc = [ strArg ['t'] ["tag"] F.OneTag "REGEXP" "select tag matching REGEXP" ]
180
181tags = OptSpec {..} where
182  ounparse k mfs = k [ F.OneTag s | OneTag s <- mfs ]
183  oparse k fs = k [ OneTag s | F.OneTag s <- fs ]
184  ocheck _ = []
185  odesc = [ strArg ['t'] ["tags"] F.OneTag "REGEXP" "select tags matching REGEXP" ]
186
187patch = OptSpec {..} where
188  ounparse k mfs = k [ F.OnePatch s | OnePatch s <- mfs ]
189  oparse k fs = k [ OnePatch s | F.OnePatch s <- fs ]
190  ocheck _ = []
191  odesc = [ strArg ['p'] ["patch"] F.OnePatch "REGEXP"
192    "select a single patch matching REGEXP" ]
193
194patches = OptSpec {..} where
195  ounparse k mfs = k [ F.SeveralPatch s | SeveralPatch s <- mfs ]
196  oparse k fs = k [ SeveralPatch s | F.SeveralPatch s <- fs ]
197  ocheck _ = []
198  odesc = [ strArg ['p'] ["patches"] F.SeveralPatch "REGEXP"
199    "select patches matching REGEXP" ]
200
201hash = OptSpec {..} where
202  ounparse k mfs = k [ F.OneHash s | OneHash s <- mfs ]
203  oparse k fs = k [ OneHash s | F.OneHash s <- fs ]
204  ocheck _ = []
205  odesc = [ strArg ['h'] ["hash"] F.OneHash "HASH"
206    "select a single patch with HASH" ]
207
208match = OptSpec {..} where
209  ounparse k mfs = k [ F.OnePattern s | OnePattern s <- mfs ]
210  oparse k fs = k [ OnePattern s | F.OnePattern s <- fs ]
211  ocheck _ = []
212  odesc = [ strArg [] ["match"] F.OnePattern "PATTERN"
213    "select a single patch matching PATTERN" ]
214
215matches = OptSpec {..} where
216  ounparse k mfs = k [ F.SeveralPattern s | SeveralPattern s <- mfs ]
217  oparse k fs = k [ SeveralPattern s | F.SeveralPattern s <- fs ]
218  ocheck _ = []
219  odesc = [ strArg [] ["matches"] F.SeveralPattern "PATTERN"
220    "select patches matching PATTERN" ]
221
222last = OptSpec {..} where
223  ounparse k mfs = k [ F.LastN (showIntArg n) | LastN n <- mfs ]
224  oparse k fs = k [ LastN (argparse s) | F.LastN s <- fs ]
225  ocheck _ = []
226  odesc = [ strArg [] ["last"] F.LastN "NUMBER" "select the last NUMBER patches" ]
227  argparse = parseIntArg "count" (>=0)
228
229index = OptSpec {..} where
230  ounparse k mfs = k [ F.OneIndex (showIntArg n) | OneIndex n <- mfs ]
231  oparse k fs = k [ OneIndex (argparse s) | F.OneIndex s <- fs ]
232  ocheck _ = []
233  odesc = [ strArg ['n'] ["index"] F.OneIndex "N" "select one patch" ]
234  argparse = parseIntArg "index" (>0)
235
236indexes = OptSpec {..} where
237  ounparse k mfs = k [ F.IndexRange (showIndexRangeArg (n,m)) | IndexRange n m <- mfs ]
238  oparse k fs = k [ uncurry IndexRange (argparse s) | F.IndexRange s <- fs ]
239  ocheck _ = []
240  odesc = [ strArg ['n'] ["index"] F.IndexRange "N-M" "select a range of patches" ]
241  argparse = parseIndexRangeArg
242