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