1 /*
2  * Copyright (C) the libgit2 contributors. All rights reserved.
3  *
4  * This file is part of libgit2, distributed under the GNU GPL v2 with
5  * a Linking Exception. For full terms see the included COPYING file.
6  */
7 module libgit2_d.pathspec;
8 
9 
10 private static import libgit2_d.diff;
11 private static import libgit2_d.strarray;
12 private static import libgit2_d.types;
13 
14 extern (C):
15 nothrow @nogc:
16 public:
17 
18 /**
19  * Compiled pathspec
20  */
21 struct git_pathspec;
22 
23 /**
24  * List of filenames matching a pathspec
25  */
26 struct git_pathspec_match_list;
27 
28 /**
29  * Options controlling how pathspec match should be executed
30  */
31 enum git_pathspec_flag_t
32 {
33 	GIT_PATHSPEC_DEFAULT = 0,
34 
35 	/**
36 	 * GIT_PATHSPEC_IGNORE_CASE forces match to ignore case; otherwise
37 	 * match will use native case sensitivity of platform filesystem
38 	 */
39 	GIT_PATHSPEC_IGNORE_CASE = 1u << 0,
40 
41 	/**
42 	 * GIT_PATHSPEC_USE_CASE forces case sensitive match; otherwise
43 	 * match will use native case sensitivity of platform filesystem
44 	 */
45 	GIT_PATHSPEC_USE_CASE = 1u << 1,
46 
47 	/**
48 	 * GIT_PATHSPEC_NO_GLOB disables glob patterns and just uses simple
49 	 * string comparison for matching
50 	 */
51 	GIT_PATHSPEC_NO_GLOB = 1u << 2,
52 
53 	/**
54 	 * GIT_PATHSPEC_NO_MATCH_ERROR means the match functions return error
55 	 * code GIT_ENOTFOUND if no matches are found; otherwise no matches is
56 	 * still success (return 0) but `git_pathspec_match_list_entrycount`
57 	 * will indicate 0 matches.
58 	 */
59 	GIT_PATHSPEC_NO_MATCH_ERROR = 1u << 3,
60 
61 	/**
62 	 * GIT_PATHSPEC_FIND_FAILURES means that the `git_pathspec_match_list`
63 	 * should track which patterns matched which files so that at the end of
64 	 * the match we can identify patterns that did not match any files.
65 	 */
66 	GIT_PATHSPEC_FIND_FAILURES = 1u << 4,
67 
68 	/**
69 	 * GIT_PATHSPEC_FAILURES_ONLY means that the `git_pathspec_match_list`
70 	 * does not need to keep the actual matching filenames.  Use this to
71 	 * just test if there were any matches at all or in combination with
72 	 * GIT_PATHSPEC_FIND_FAILURES to validate a pathspec.
73 	 */
74 	GIT_PATHSPEC_FAILURES_ONLY = 1u << 5,
75 }
76 
77 //Declaration name in C language
78 enum
79 {
80 	GIT_PATHSPEC_DEFAULT = .git_pathspec_flag_t.GIT_PATHSPEC_DEFAULT,
81 	GIT_PATHSPEC_IGNORE_CASE = .git_pathspec_flag_t.GIT_PATHSPEC_IGNORE_CASE,
82 	GIT_PATHSPEC_USE_CASE = .git_pathspec_flag_t.GIT_PATHSPEC_USE_CASE,
83 	GIT_PATHSPEC_NO_GLOB = .git_pathspec_flag_t.GIT_PATHSPEC_NO_GLOB,
84 	GIT_PATHSPEC_NO_MATCH_ERROR = .git_pathspec_flag_t.GIT_PATHSPEC_NO_MATCH_ERROR,
85 	GIT_PATHSPEC_FIND_FAILURES = .git_pathspec_flag_t.GIT_PATHSPEC_FIND_FAILURES,
86 	GIT_PATHSPEC_FAILURES_ONLY = .git_pathspec_flag_t.GIT_PATHSPEC_FAILURES_ONLY,
87 }
88 
89 /**
90  * Compile a pathspec
91  *
92  * Params:
93  *      out_ = Output of the compiled pathspec
94  *      pathspec = A git_strarray of the paths to match
95  *
96  * Returns: 0 on success, <0 on failure
97  */
98 //GIT_EXTERN
99 int git_pathspec_new(.git_pathspec** out_, const (libgit2_d.strarray.git_strarray)* pathspec);
100 
101 /**
102  * Free a pathspec
103  *
104  * Params:
105  *      ps = The compiled pathspec
106  */
107 //GIT_EXTERN
108 void git_pathspec_free(.git_pathspec* ps);
109 
110 /**
111  * Try to match a path against a pathspec
112  *
113  * Unlike most of the other pathspec matching functions, this will not
114  * fall back on the native case-sensitivity for your platform.  You must
115  * explicitly pass flags to control case sensitivity or else this will
116  * fall back on being case sensitive.
117  *
118  * Params:
119  *      ps = The compiled pathspec
120  *      flags = Combination of git_pathspec_flag_t options to control match
121  *      path = The pathname to attempt to match
122  *
123  * Returns: 1 is path matches spec, 0 if it does not
124  */
125 //GIT_EXTERN
126 int git_pathspec_matches_path(const (.git_pathspec)* ps, uint flags, const (char)* path);
127 
128 /**
129  * Match a pathspec against the working directory of a repository.
130  *
131  * This matches the pathspec against the current files in the working
132  * directory of the repository.  It is an error to invoke this on a bare
133  * repo.  This handles git ignores (i.e. ignored files will not be
134  * considered to match the `pathspec` unless the file is tracked in the
135  * index).
136  *
137  * If `out` is not null, this returns a `git_patchspec_match_list`.  That
138  * contains the list of all matched filenames (unless you pass the
139  * `git_pathspec_flag_t.GIT_PATHSPEC_FAILURES_ONLY` flag) and may also contain the list of
140  * pathspecs with no match (if you used the `git_pathspec_flag_t.GIT_PATHSPEC_FIND_FAILURES`
141  * flag).  You must call `git_pathspec_match_list_free()` on this object.
142  *
143  * Params:
144  *      out_ = Output list of matches; pass null to just get return value
145  *      repo = The repository in which to match; bare repo is an error
146  *      flags = Combination of git_pathspec_flag_t options to control match
147  *      ps = Pathspec to be matched
148  *
149  * Returns: 0 on success, -1 on error, git_error_code.GIT_ENOTFOUND if no matches and the git_pathspec_flag_t.GIT_PATHSPEC_NO_MATCH_ERROR flag was given
150  */
151 //GIT_EXTERN
152 int git_pathspec_match_workdir(.git_pathspec_match_list** out_, libgit2_d.types.git_repository* repo, uint flags, .git_pathspec* ps);
153 
154 /**
155  * Match a pathspec against entries in an index.
156  *
157  * This matches the pathspec against the files in the repository index.
158  *
159  * NOTE: At the moment, the case sensitivity of this match is controlled
160  * by the current case-sensitivity of the index object itself and the
161  * USE_CASE and IGNORE_CASE flags will have no effect.  This behavior will
162  * be corrected in a future release.
163  *
164  * If `out` is not null, this returns a `git_patchspec_match_list`.  That
165  * contains the list of all matched filenames (unless you pass the
166  * `git_pathspec_flag_t.GIT_PATHSPEC_FAILURES_ONLY` flag) and may also contain the list of
167  * pathspecs with no match (if you used the `git_pathspec_flag_t.GIT_PATHSPEC_FIND_FAILURES`
168  * flag).  You must call `git_pathspec_match_list_free()` on this object.
169  *
170  * Params:
171  *      out_ = Output list of matches; pass null to just get return value
172  *      index = The index to match against
173  *      flags = Combination of git_pathspec_flag_t options to control match
174  *      ps = Pathspec to be matched
175  *
176  * Returns: 0 on success, -1 on error, git_error_code.GIT_ENOTFOUND if no matches and the git_pathspec_flag_t.GIT_PATHSPEC_NO_MATCH_ERROR flag is used
177  */
178 //GIT_EXTERN
179 int git_pathspec_match_index(.git_pathspec_match_list** out_, libgit2_d.types.git_index* index, uint flags, .git_pathspec* ps);
180 
181 /**
182  * Match a pathspec against files in a tree.
183  *
184  * This matches the pathspec against the files in the given tree.
185  *
186  * If `out` is not null, this returns a `git_patchspec_match_list`.  That
187  * contains the list of all matched filenames (unless you pass the
188  * `git_pathspec_flag_t.GIT_PATHSPEC_FAILURES_ONLY` flag) and may also contain the list of
189  * pathspecs with no match (if you used the `git_pathspec_flag_t.GIT_PATHSPEC_FIND_FAILURES`
190  * flag).  You must call `git_pathspec_match_list_free()` on this object.
191  *
192  * Params:
193  *      out_ = Output list of matches; pass null to just get return value
194  *      tree = The root-level tree to match against
195  *      flags = Combination of git_pathspec_flag_t options to control match
196  *      ps = Pathspec to be matched
197  *
198  * Returns: 0 on success, -1 on error, git_error_code.GIT_ENOTFOUND if no matches and the git_pathspec_flag_t.GIT_PATHSPEC_NO_MATCH_ERROR flag is used
199  */
200 //GIT_EXTERN
201 int git_pathspec_match_tree(.git_pathspec_match_list** out_, libgit2_d.types.git_tree* tree, uint flags, .git_pathspec* ps);
202 
203 /**
204  * Match a pathspec against files in a diff list.
205  *
206  * This matches the pathspec against the files in the given diff list.
207  *
208  * If `out` is not null, this returns a `git_patchspec_match_list`.  That
209  * contains the list of all matched filenames (unless you pass the
210  * `git_pathspec_flag_t.GIT_PATHSPEC_FAILURES_ONLY` flag) and may also contain the list of
211  * pathspecs with no match (if you used the `git_pathspec_flag_t.GIT_PATHSPEC_FIND_FAILURES`
212  * flag).  You must call `git_pathspec_match_list_free()` on this object.
213  *
214  * Params:
215  *      out_ = Output list of matches; pass null to just get return value
216  *      diff = A generated diff list
217  *      flags = Combination of git_pathspec_flag_t options to control match
218  *      ps = Pathspec to be matched
219  *
220  * Returns: 0 on success, -1 on error, git_error_code.GIT_ENOTFOUND if no matches and the git_pathspec_flag_t.GIT_PATHSPEC_NO_MATCH_ERROR flag is used
221  */
222 //GIT_EXTERN
223 int git_pathspec_match_diff(.git_pathspec_match_list** out_, libgit2_d.diff.git_diff* diff, uint flags, .git_pathspec* ps);
224 
225 /**
226  * Free memory associates with a git_pathspec_match_list
227  *
228  * Params:
229  *      m = The git_pathspec_match_list to be freed
230  */
231 //GIT_EXTERN
232 void git_pathspec_match_list_free(.git_pathspec_match_list* m);
233 
234 /**
235  * Get the number of items in a match list.
236  *
237  * Params:
238  *      m = The git_pathspec_match_list object
239  *
240  * Returns: Number of items in match list
241  */
242 //GIT_EXTERN
243 size_t git_pathspec_match_list_entrycount(const (.git_pathspec_match_list)* m);
244 
245 /**
246  * Get a matching filename by position.
247  *
248  * This routine cannot be used if the match list was generated by
249  * `git_pathspec_match_diff`.  If so, it will always return null.
250  *
251  * Params:
252  *      m = The git_pathspec_match_list object
253  *      pos = The index into the list
254  *
255  * Returns: The filename of the match
256  */
257 //GIT_EXTERN
258 const (char)* git_pathspec_match_list_entry(const (.git_pathspec_match_list)* m, size_t pos);
259 
260 /**
261  * Get a matching diff delta by position.
262  *
263  * This routine can only be used if the match list was generated by
264  * `git_pathspec_match_diff`.  Otherwise it will always return null.
265  *
266  * Params:
267  *      m = The git_pathspec_match_list object
268  *      pos = The index into the list
269  *
270  * Returns: The filename of the match
271  */
272 //GIT_EXTERN
273 const (libgit2_d.diff.git_diff_delta)* git_pathspec_match_list_diff_entry(const (.git_pathspec_match_list)* m, size_t pos);
274 
275 /**
276  * Get the number of pathspec items that did not match.
277  *
278  * This will be zero unless you passed git_pathspec_flag_t.GIT_PATHSPEC_FIND_FAILURES when
279  * generating the git_pathspec_match_list.
280  *
281  * Params:
282  *      m = The git_pathspec_match_list object
283  *
284  * Returns: Number of items in original pathspec that had no matches
285  */
286 //GIT_EXTERN
287 size_t git_pathspec_match_list_failed_entrycount(const (.git_pathspec_match_list)* m);
288 
289 /**
290  * Get an original pathspec string that had no matches.
291  *
292  * This will be return null for positions out of range.
293  *
294  * Params:
295  *      m = The git_pathspec_match_list object
296  *      pos = The index into the failed items
297  *
298  * Returns: The pathspec pattern that didn't match anything
299  */
300 //GIT_EXTERN
301 const (char)* git_pathspec_match_list_failed_entry(const (.git_pathspec_match_list)* m, size_t pos);