1 module caLib_util.tempdir;
2 
3 import std.file : tempDir, mkdirRecurse, rmdirRecurse, exists, dirEntries, SpanMode, FileException;
4 import std.random : uniform;
5 import std.conv : to;
6 import std.path : buildNormalizedPath;
7 import std.exception : enforce;
8 
9 
10 private immutable string tempDirsRoot;
11 
12 shared static this()
13 {
14 	if(tempDir() == ".")
15 		tempDirsRoot = makeTempDirsRoot();
16 	else
17 		tempDirsRoot = tempDir();
18 
19 	removeTempFiles();
20 }
21 
22 shared static ~this()
23 {
24 	removeTempFiles();
25 }
26 
27 
28 
29 string makePrivateTempDir() { return makePrivateTempDir(0); }
30 
31 string makePrivateTempDir(int n)
32 {
33 	// we will only try to make a temporary directory 1000 times
34 	enforce(n < 1000,
35 		"Could not create a temporary directory");
36 
37 	// the new temporary directory
38 	string dir = buildNormalizedPath(tempDirsRoot, "caLib3_",
39 		to!string(uniform(1000, 9999)));
40 
41 	// if it already exists, try again
42 	if(exists(dir))
43 		return makePrivateTempDir(n+1);
44 
45 	// otherwise, make the directory and return the path to it
46 	mkdirRecurse(dir);
47 	return dir;
48 }
49 
50 
51 
52 private void removeTempFiles()
53 {
54 	if(!exists(tempDirsRoot))
55 		return;
56 	
57 	auto dirs = dirEntries(tempDirsRoot, SpanMode.shallow);
58 	
59 	foreach(dirPath ; dirs)
60 	{
61 		string dirName = dirPath[tempDirsRoot.length .. dirPath.length];
62 		if(dirName.length >= 7 && dirName[0 .. 7] == "caLib3_")
63 			rmdirRecurse(dirPath);
64 	}
65 }
66 
67 
68 
69 private string makeTempDirsRoot()
70 {
71 	assert(0, "Can't create temporary file:" ~
72 		"This os has no location for temporary files");
73 }