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.sys.filter; 8 9 10 private static import libgit2_d.buffer; 11 private static import libgit2_d.filter; 12 private static import libgit2_d.oid; 13 private static import libgit2_d.types; 14 15 /** 16 * @file git2/sys/filter.h 17 * @brief Git filter backend and plugin routines 18 * @defgroup git_backend Git custom backend APIs 19 * @ingroup Git 20 * @{ 21 */ 22 extern (C): 23 nothrow @nogc: 24 package(libgit2_d): 25 26 /** 27 * Look up a filter by name 28 * 29 * Params: 30 * name = The name of the filter 31 * 32 * Returns: Pointer to the filter object or null if not found 33 */ 34 //GIT_EXTERN 35 .git_filter* git_filter_lookup(const (char)* name); 36 37 enum GIT_FILTER_CRLF = "crlf"; 38 enum GIT_FILTER_IDENT = "ident"; 39 40 /** 41 * This is priority that the internal CRLF filter will be registered with 42 */ 43 enum GIT_FILTER_CRLF_PRIORITY = 0; 44 45 /** 46 * This is priority that the internal ident filter will be registered with 47 */ 48 enum GIT_FILTER_IDENT_PRIORITY = 100; 49 50 /** 51 * This is priority to use with a custom filter to imitate a core Git 52 * filter driver, so that it will be run last on checkout and first on 53 * checkin. You do not have to use this, but it helps compatibility. 54 */ 55 enum GIT_FILTER_DRIVER_PRIORITY = 200; 56 57 /** 58 * Create a new empty filter list 59 * 60 * Normally you won't use this because `git_filter_list_load` will create 61 * the filter list for you, but you can use this in combination with the 62 * `git_filter_lookup` and `git_filter_list_push` functions to assemble 63 * your own chains of filters. 64 */ 65 //GIT_EXTERN 66 int git_filter_list_new(libgit2_d.filter.git_filter_list** out_, libgit2_d.types.git_repository* repo, libgit2_d.filter.git_filter_mode_t mode, uint options); 67 68 /** 69 * Add a filter to a filter list with the given payload. 70 * 71 * Normally you won't have to do this because the filter list is created 72 * by calling the "check" function on registered filters when the filter 73 * attributes are set, but this does allow more direct manipulation of 74 * filter lists when desired. 75 * 76 * Note that normally the "check" function can set up a payload for the 77 * filter. Using this function, you can either pass in a payload if you 78 * know the expected payload format, or you can pass null. Some filters 79 * may fail with a null payload. Good luck! 80 */ 81 //GIT_EXTERN 82 int git_filter_list_push(libgit2_d.filter.git_filter_list* fl, .git_filter* filter, void* payload); 83 84 /** 85 * Look up how many filters are in the list 86 * 87 * We will attempt to apply all of these filters to any data passed in, 88 * but note that the filter apply action still has the option of skipping 89 * data that is passed in (for example, the CRLF filter will skip data 90 * that appears to be binary). 91 * 92 * Params: 93 * fl = A filter list 94 * 95 * Returns: The number of filters in the list 96 */ 97 //GIT_EXTERN 98 size_t git_filter_list_length(const (libgit2_d.filter.git_filter_list)* fl); 99 100 /** 101 * A filter source represents a file/blob to be processed 102 */ 103 struct git_filter_source; 104 105 /** 106 * Get the repository that the source data is coming from. 107 */ 108 //GIT_EXTERN 109 libgit2_d.types.git_repository* git_filter_source_repo(const (.git_filter_source)* src); 110 111 /** 112 * Get the path that the source data is coming from. 113 */ 114 //GIT_EXTERN 115 const (char)* git_filter_source_path(const (.git_filter_source)* src); 116 117 /** 118 * Get the file mode of the source file 119 * If the mode is unknown, this will return 0 120 */ 121 //GIT_EXTERN 122 ushort git_filter_source_filemode(const (.git_filter_source)* src); 123 124 /** 125 * Get the OID of the source 126 * If the OID is unknown (often the case with git_filter_mode_t.GIT_FILTER_CLEAN) then 127 * this will return null. 128 */ 129 //GIT_EXTERN 130 const (libgit2_d.oid.git_oid)* git_filter_source_id(const (.git_filter_source)* src); 131 132 /** 133 * Get the git_filter_mode_t to be used 134 */ 135 //GIT_EXTERN 136 libgit2_d.filter.git_filter_mode_t git_filter_source_mode(const (.git_filter_source)* src); 137 138 /** 139 * Get the combination git_filter_flag_t options to be applied 140 */ 141 //GIT_EXTERN 142 uint git_filter_source_flags(const (.git_filter_source)* src); 143 144 /** 145 * Initialize callback on filter 146 * 147 * Specified as `filter.initialize`, this is an optional callback invoked 148 * before a filter is first used. It will be called once at most. 149 * 150 * If non-null, the filter's `initialize` callback will be invoked right 151 * before the first use of the filter, so you can defer expensive 152 * initialization operations (in case libgit2 is being used in a way that 153 * doesn't need the filter). 154 */ 155 alias git_filter_init_fn = int function(.git_filter* self); 156 157 /** 158 * Shutdown callback on filter 159 * 160 * Specified as `filter.shutdown`, this is an optional callback invoked 161 * when the filter is unregistered or when libgit2 is shutting down. It 162 * will be called once at most and should release resources as needed. 163 * This may be called even if the `initialize` callback was not made. 164 * 165 * Typically this function will free the `git_filter` object itself. 166 */ 167 alias git_filter_shutdown_fn = void function(.git_filter* self); 168 169 /** 170 * Callback to decide if a given source needs this filter 171 * 172 * Specified as `filter.check`, this is an optional callback that checks 173 * if filtering is needed for a given source. 174 * 175 * It should return 0 if the filter should be applied (i.e. success), 176 * git_error_code.GIT_PASSTHROUGH if the filter should not be applied, or an error code 177 * to fail out of the filter processing pipeline and return to the caller. 178 * 179 * The `attr_values` will be set to the values of any attributes given in 180 * the filter definition. See `git_filter` below for more detail. 181 * 182 * The `payload` will be a pointer to a reference payload for the filter. 183 * This will start as null, but `check` can assign to this pointer for 184 * later use by the `apply` callback. Note that the value should be heap 185 * allocated (not stack), so that it doesn't go away before the `apply` 186 * callback can use it. If a filter allocates and assigns a value to the 187 * `payload`, it will need a `cleanup` callback to free the payload. 188 */ 189 alias git_filter_check_fn = int function(.git_filter* self, void** payload, /* points to null ptr on entry, may be set */ 190 const (.git_filter_source)* src, const (char)** attr_values); 191 192 /** 193 * Callback to actually perform the data filtering 194 * 195 * Specified as `filter.apply`, this is the callback that actually filters 196 * data. If it successfully writes the output, it should return 0. Like 197 * `check`, it can return git_error_code.GIT_PASSTHROUGH to indicate that the filter 198 * doesn't want to run. Other error codes will stop filter processing and 199 * return to the caller. 200 * 201 * The `payload` value will refer to any payload that was set by the 202 * `check` callback. It may be read from or written to as needed. 203 */ 204 alias git_filter_apply_fn = int function(.git_filter* self, void** payload, /* may be read and/or set */ 205 libgit2_d.buffer.git_buf* to, const (libgit2_d.buffer.git_buf)* from, const (.git_filter_source)* src); 206 207 alias git_filter_stream_fn = int function(libgit2_d.types.git_writestream** out_, .git_filter* self, void** payload, const (.git_filter_source)* src, libgit2_d.types.git_writestream* next); 208 209 /** 210 * Callback to clean up after filtering has been applied 211 * 212 * Specified as `filter.cleanup`, this is an optional callback invoked 213 * after the filter has been applied. If the `check` or `apply` callbacks 214 * allocated a `payload` to keep per-source filter state, use this 215 * callback to free that payload and release resources as required. 216 */ 217 alias git_filter_cleanup_fn = void function(.git_filter* self, void* payload); 218 219 /** 220 * Filter structure used to register custom filters. 221 * 222 * To associate extra data with a filter, allocate extra data and put the 223 * `git_filter` struct at the start of your data buffer, then cast the 224 * `self` pointer to your larger structure when your callback is invoked. 225 */ 226 struct git_filter 227 { 228 /** 229 * The `version` field should be set to `GIT_FILTER_VERSION`. 230 */ 231 uint version_; 232 233 /** 234 * A whitespace-separated list of attribute names to check for this 235 * filter (e.g. "eol crlf text"). If the attribute name is bare, it 236 * will be simply loaded and passed to the `check` callback. If it 237 * has a value (i.e. "name=value"), the attribute must match that 238 * value for the filter to be applied. The value may be a wildcard 239 * (eg, "name=*"), in which case the filter will be invoked for any 240 * value for the given attribute name. See the attribute parameter 241 * of the `check` callback for the attribute value that was specified. 242 */ 243 const (char)* attributes; 244 245 /** 246 * Called when the filter is first used for any file. 247 */ 248 .git_filter_init_fn initialize; 249 250 /** 251 * Called when the filter is removed or unregistered from the system. 252 */ 253 .git_filter_shutdown_fn shutdown; 254 255 /** 256 * Called to determine whether the filter should be invoked for a 257 * given file. If this function returns `git_error_code.GIT_PASSTHROUGH` then the 258 * `apply` function will not be invoked and the contents will be passed 259 * through unmodified. 260 */ 261 .git_filter_check_fn check; 262 263 /** 264 * Called to actually apply the filter to file contents. If this 265 * function returns `git_error_code.GIT_PASSTHROUGH` then the contents will be passed 266 * through unmodified. 267 */ 268 .git_filter_apply_fn apply; 269 270 /** 271 * Called to apply the filter in a streaming manner. If this is not 272 * specified then the system will call `apply` with the whole buffer. 273 */ 274 .git_filter_stream_fn stream; 275 276 /** 277 * Called when the system is done filtering for a file. 278 */ 279 .git_filter_cleanup_fn cleanup; 280 } 281 282 enum GIT_FILTER_VERSION = 1; 283 284 pragma(inline, true) 285 pure nothrow @safe @nogc 286 .git_filter GIT_FILTER_INIT() 287 288 do 289 { 290 .git_filter OUTPUT = 291 { 292 version_: .GIT_FILTER_VERSION, 293 }; 294 295 return OUTPUT; 296 } 297 298 /** 299 * Initializes a `git_filter` with default values. Equivalent to 300 * creating an instance with GIT_FILTER_INIT. 301 * 302 * Params: 303 * filter = the `git_filter` struct to initialize. 304 * version = Version the struct; pass `GIT_FILTER_VERSION` 305 * 306 * Returns: Zero on success; -1 on failure. 307 */ 308 //GIT_EXTERN 309 int git_filter_init(.git_filter* filter, uint version_); 310 311 /** 312 * Register a filter under a given name with a given priority. 313 * 314 * As mentioned elsewhere, the initialize callback will not be invoked 315 * immediately. It is deferred until the filter is used in some way. 316 * 317 * A filter's attribute checks and `check` and `apply` callbacks will be 318 * issued in order of `priority` on smudge (to workdir), and in reverse 319 * order of `priority` on clean (to odb). 320 * 321 * Two filters are preregistered with libgit2: 322 * - GIT_FILTER_CRLF with priority 0 323 * - GIT_FILTER_IDENT with priority 100 324 * 325 * Currently the filter registry is not thread safe, so any registering or 326 * deregistering of filters must be done outside of any possible usage of 327 * the filters (i.e. during application setup or shutdown). 328 * 329 * Params: 330 * name = A name by which the filter can be referenced. Attempting to register with an in-use name will return git_error_code.GIT_EEXISTS. 331 * filter = The filter definition. This pointer will be stored as is by libgit2 so it must be a durable allocation (either static or on the heap). 332 * priority = The priority for filter application 333 * 334 * Returns: 0 on successful registry, error code <0 on failure 335 */ 336 //GIT_EXTERN 337 int git_filter_register(const (char)* name, .git_filter* filter, int priority); 338 339 /** 340 * Remove the filter with the given name 341 * 342 * Attempting to remove the builtin libgit2 filters is not permitted and 343 * will return an error. 344 * 345 * Currently the filter registry is not thread safe, so any registering or 346 * deregistering of filters must be done outside of any possible usage of 347 * the filters (i.e. during application setup or shutdown). 348 * 349 * Params: 350 * name = The name under which the filter was registered 351 * 352 * Returns: 0 on success, error code <0 on failure 353 */ 354 //GIT_EXTERN 355 int git_filter_unregister(const (char)* name); 356 357 /** @} */