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