1 /* 2 * Copyright Andrej Mitrovic 2013. 3 * Distributed under the Boost Software License, Version 1.0. 4 * (See accompanying file LICENSE_1_0.txt or copy at 5 * http://www.boost.org/LICENSE_1_0.txt) 6 */ 7 module git.attribute; 8 9 import std.file; 10 import std.path; 11 import std.stdio; 12 import std.string; 13 14 import git.repository; 15 16 import deimos.git2.attr; 17 import deimos.git2.common; 18 import deimos.git2.types; 19 import deimos.git2.util; 20 21 /** 22 Git attributes, see: 23 http://git-scm.com/book/ch7-2.html 24 */ 25 26 unittest 27 { 28 auto repo = initRepo(_userRepo, OpenBare.yes); 29 scope(exit) rmdirRecurse(_userRepo); 30 31 string[] attributes = [ 32 "*.c foo" 33 ]; 34 35 std.file.write(buildPath(repo.path, ".gitattributes"), attributes.join()); 36 } 37 38 extern (C): 39 40 /** 41 * GIT_ATTR_TRUE checks if an attribute is set on. In core git 42 * parlance, this the value for "Set" attributes. 43 * 44 * For example, if the attribute file contains: 45 * 46 * *.c foo 47 * 48 * Then for file `xyz.c` looking up attribute "foo" gives a value for 49 * which `GIT_ATTR_TRUE(value)` is true. 50 */ 51 bool GIT_ATTR_TRUE(T)(T attr) { return git_attr_value(attr) == git_attr_t.GIT_ATTR_TRUE_T; } 52 53 /** 54 * GIT_ATTR_FALSE checks if an attribute is set off. In core git 55 * parlance, this is the value for attributes that are "Unset" (not to 56 * be confused with values that a "Unspecified"). 57 * 58 * For example, if the attribute file contains: 59 * 60 * *.h -foo 61 * 62 * Then for file `zyx.h` looking up attribute "foo" gives a value for 63 * which `GIT_ATTR_FALSE(value)` is true. 64 */ 65 bool GIT_ATTR_FALSE(T)(T attr) { return git_attr_value(attr) == git_attr_t.GIT_ATTR_FALSE_T; } 66 67 /** 68 * GIT_ATTR_UNSPECIFIED checks if an attribute is unspecified. This 69 * may be due to the attribute not being mentioned at all or because 70 * the attribute was explicitly set unspecified via the `!` operator. 71 * 72 * For example, if the attribute file contains: 73 * 74 * *.c foo 75 * *.h -foo 76 * onefile.c !foo 77 * 78 * Then for `onefile.c` looking up attribute "foo" yields a value with 79 * `GIT_ATTR_UNSPECIFIED(value)` of true. Also, looking up "foo" on 80 * file `onefile.rb` or looking up "bar" on any file will all give 81 * `GIT_ATTR_UNSPECIFIED(value)` of true. 82 */ 83 bool GIT_ATTR_UNSPECIFIED(T)(T attr) { return git_attr_value(attr) == git_attr_t.GIT_ATTR_UNSPECIFIED_T; } 84 85 /** 86 * GIT_ATTR_HAS_VALUE checks if an attribute is set to a value (as 87 * opposed to TRUE, FALSE or UNSPECIFIED). This would be the case if 88 * for a file with something like: 89 * 90 * *.txt eol=lf 91 * 92 * Given this, looking up "eol" for `onefile.txt` will give back the 93 * string "lf" and `GIT_ATTR_SET_TO_VALUE(attr)` will return true. 94 */ 95 bool GIT_ATTR_HAS_VALUE(T)(T attr) { return git_attr_value(attr) == git_attr_t.GIT_ATTR_VALUE_T; } 96 97 enum git_attr_t 98 { 99 GIT_ATTR_UNSPECIFIED_T = 0, 100 GIT_ATTR_TRUE_T, 101 GIT_ATTR_FALSE_T, 102 GIT_ATTR_VALUE_T, 103 } 104 105 /* 106 * Return the value type for a given attribute. 107 * 108 * This can be either `TRUE`, `FALSE`, `UNSPECIFIED` (if the attribute 109 * was not set at all), or `VALUE`, if the attribute was set to 110 * an actual string. 111 * 112 * If the attribute has a `VALUE` string, it can be accessed normally 113 * as a NULL-terminated C string. 114 * 115 * @param attr The attribute 116 * @return the value type for the attribute 117 */ 118 git_attr_t git_attr_value(const(char)* attr); 119 120 /** 121 * Check attribute flags: Reading values from index and working directory. 122 * 123 * When checking attributes, it is possible to check attribute files 124 * in both the working directory (if there is one) and the index (if 125 * there is one). You can explicitly choose where to check and in 126 * which order using the following flags. 127 * 128 * Core git usually checks the working directory then the index, 129 * except during a checkout when it checks the index first. It will 130 * use index only for creating archives or for a bare repo (if an 131 * index has been specified for the bare repo). 132 */ 133 enum GIT_ATTR_CHECK_FILE_THEN_INDEX = 0; 134 enum GIT_ATTR_CHECK_INDEX_THEN_FILE = 1; 135 enum GIT_ATTR_CHECK_INDEX_ONLY = 2; 136 137 /** 138 * Check attribute flags: Using the system attributes file. 139 * 140 * Normally, attribute checks include looking in the /etc (or system 141 * equivalent) directory for a `gitattributes` file. Passing this 142 * flag will cause attribute checks to ignore that file. 143 */ 144 enum GIT_ATTR_CHECK_NO_SYSTEM = 1 << 2; 145 146 /** 147 * Look up the value of one git attribute for path. 148 * 149 * @param value_out Output of the value of the attribute. Use the GIT_ATTR_... 150 * macros to test for TRUE, FALSE, UNSPECIFIED, etc. or just 151 * use the string value for attributes set to a value. You 152 * should NOT modify or free this value. 153 * @param repo The repository containing the path. 154 * @param flags A combination of GIT_ATTR_CHECK... flags. 155 * @param path The path to check for attributes. Relative paths are 156 * interpreted relative to the repo root. The file does 157 * not have to exist, but if it does not, then it will be 158 * treated as a plain file (not a directory). 159 * @param name The name of the attribute to look up. 160 */ 161 int git_attr_get( 162 const(char)** value_out, 163 git_repository *repo, 164 uint32_t flags, 165 const(char)* path, 166 const(char)* name); 167 168 /** 169 * Look up a list of git attributes for path. 170 * 171 * Use this if you have a known list of attributes that you want to 172 * look up in a single call. This is somewhat more efficient than 173 * calling `git_attr_get()` multiple times. 174 * 175 * For example, you might write: 176 * 177 * const(char)*attrs[] = { "crlf", "diff", "foo" }; 178 * const(char)**values[3]; 179 * git_attr_get_many(values, repo, 0, "my/fun/file.c", 3, attrs); 180 * 181 * Then you could loop through the 3 values to get the settings for 182 * the three attributes you asked about. 183 * 184 * @param values_out An array of num_attr entries that will have string 185 * pointers written into it for the values of the attributes. 186 * You should not modify or free the values that are written 187 * into this array (although of course, you should free the 188 * array itself if you allocated it). 189 * @param repo The repository containing the path. 190 * @param flags A combination of GIT_ATTR_CHECK... flags. 191 * @param path The path inside the repo to check attributes. This 192 * does not have to exist, but if it does not, then 193 * it will be treated as a plain file (i.e. not a directory). 194 * @param num_attr The number of attributes being looked up 195 * @param names An array of num_attr strings containing attribute names. 196 */ 197 int git_attr_get_many( 198 const(char)** values_out, 199 git_repository *repo, 200 uint32_t flags, 201 const(char)* path, 202 size_t num_attr, 203 const(char)** names); 204 205 alias git_attr_foreach_cb = int function(const(char)* name, const(char)* value, void *payload); 206 207 /** 208 * Loop over all the git attributes for a path. 209 * 210 * @param repo The repository containing the path. 211 * @param flags A combination of GIT_ATTR_CHECK... flags. 212 * @param path Path inside the repo to check attributes. This does not have 213 * to exist, but if it does not, then it will be treated as a 214 * plain file (i.e. not a directory). 215 * @param callback Function to invoke on each attribute name and value. The 216 * value may be NULL is the attribute is explicitly set to 217 * UNSPECIFIED using the '!' sign. Callback will be invoked 218 * only once per attribute name, even if there are multiple 219 * rules for a given file. The highest priority rule will be 220 * used. Return a non-zero value from this to stop looping. 221 * @param payload Passed on as extra parameter to callback function. 222 * @return 0 on success, GIT_EUSER on non-zero callback, or error code 223 */ 224 int git_attr_foreach( 225 git_repository *repo, 226 uint32_t flags, 227 const(char)* path, 228 git_attr_foreach_cb callback, 229 void *payload); 230 231 /** 232 * Flush the gitattributes cache. 233 * 234 * Call this if you have reason to believe that the attributes files on 235 * disk no longer match the cached contents of memory. This will cause 236 * the attributes files to be reloaded the next time that an attribute 237 * access function is called. 238 */ 239 void git_attr_cache_flush( 240 git_repository *repo); 241 242 /** 243 * Add a macro definition. 244 * 245 * Macros will automatically be loaded from the top level `.gitattributes` 246 * file of the repository (plus the build-in "binary" macro). This 247 * function allows you to add others. For example, to add the default 248 * macro, you would call: 249 * 250 * git_attr_add_macro(repo, "binary", "-diff -crlf"); 251 */ 252 int git_attr_add_macro( 253 git_repository *repo, 254 const(char)* name, 255 const(char)* values);