1 /// Utility functions to work with paths 2 module thepath.utils; 3 4 private import std.exception: enforce; 5 private static import std.path; 6 7 private import thepath.exception: PathException; 8 private import thepath.path: Path; 9 10 11 /** Create temporary directory 12 * Note, that caller is responsible to remove created directory. 13 * The temp directory will be created inside specified path. 14 * 15 * Params: 16 * path = path to already existing directory to create 17 * temp directory inside. Default: std.file.tempDir 18 * prefix = prefix to be used in name of temp directory. Default: "tmp" 19 * Returns: string, representing path to created temporary directory 20 * Throws: PathException in case of error 21 **/ 22 string createTempDirectory(in string prefix="tmp") { 23 import std.file : tempDir; 24 return createTempDirectory(tempDir, prefix); 25 } 26 27 /// ditto 28 string createTempDirectory(in string path, in string prefix) { 29 version(Posix) { 30 import std.string : fromStringz; 31 import std.conv: to; 32 import core.sys.posix.stdlib : mkdtemp; 33 34 // Prepare template for mkdtemp function. 35 // It have to be mutable array of chars ended with zero to be compatibale 36 // with mkdtemp function. 37 scope char[] tempname_str = std.path.buildNormalizedPath( 38 std.path.expandTilde(path), 39 prefix ~ "-XXXXXX").dup ~ "\0"; 40 41 // mkdtemp will modify tempname_str directly. and res is pointer to 42 // tempname_str in case of success. 43 char* res = mkdtemp(tempname_str.ptr); 44 enforce!PathException( 45 res !is null, "Cannot create temporary directory"); 46 47 // Converting to string will duplicate result. 48 // But may be it have sense to do it in more obvious way 49 // for example: return tempname_str[0..$-1].idup; 50 return to!string(res.fromStringz); 51 } else { 52 import std.ascii: letters; 53 import std.random: uniform; 54 55 // Generate new random temp path to test using provided path and prefix 56 // as template. 57 string generate_temp_dir() { 58 string suffix = "-"; 59 for(ubyte i; i<6; i++) suffix ~= letters[uniform(0, $)]; 60 return std.path.buildNormalizedPath( 61 std.path.expandTilde(path), prefix ~ suffix); 62 } 63 64 string temp_dir = generate_temp_dir(); 65 while (std.file.exists(temp_dir)) { 66 temp_dir = generate_temp_dir(); 67 } 68 std.file.mkdir(temp_dir); 69 return temp_dir; 70 } 71 } 72 73 74 /** Create temporary directory 75 * Note, that caller is responsible to remove created directory. 76 * The temp directory will be created inside specified path. 77 * 78 * Params: 79 * path = path to already existing directory to create 80 * temp directory inside. Default: std.file.tempDir 81 * prefix = prefix to be used in name of temp directory. Default: "tmp" 82 * Returns: Path to created temp directory 83 * Throws: PathException in case of error 84 **/ 85 Path createTempPath(in string prefix="tmp") { 86 return Path(createTempDirectory(prefix)); 87 } 88 89 /// ditto 90 Path createTempPath(in string path, in string prefix) { 91 return Path(createTempDirectory(path, prefix)); 92 } 93 94 /// ditto 95 Path createTempPath(in Path path, in string prefix) { 96 return createTempPath(path.toString, prefix); 97 } 98 99