1 /++
2 $(H2 Scriptlike $(SCRIPTLIKE_VERSION))
3 
4 Extra Scriptlike-only functionality to complement $(MODULE_STD_FILE).
5 
6 Copyright: Copyright (C) 2014-2015 Nick Sabalausky
7 License:   zlib/libpng
8 Authors:   Nick Sabalausky
9 +/
10 module scriptlike.file.extras;
11 
12 import std.algorithm;
13 import std.datetime;
14 import std.traits;
15 import std.typecons;
16 
17 static import std.file;
18 static import std.path;
19 
20 import scriptlike.core;
21 import scriptlike.path;
22 import scriptlike.file.wrappers;
23 
24 /// Checks if the path exists as a directory.
25 ///
26 /// This is like $(FULL_STD_FILE isDir), but returns false instead of
27 /// throwing if the path doesn't exist.
28 bool existsAsDir(in string path) @trusted
29 {
30 	yapFunc(path.escapeShellArg());
31 	return std.file.exists(path) && std.file.isDir(path);
32 }
33 ///ditto
34 bool existsAsDir(in Path path) @trusted
35 {
36 	return existsAsDir(path.toRawString());
37 }
38 
39 /// Checks if the path exists as a file.
40 ///
41 /// This is like $(FULL_STD_FILE isFile), but returns false instead of
42 /// throwing if the path doesn't exist.
43 bool existsAsFile(in string path) @trusted
44 {
45 	yapFunc(path.escapeShellArg());
46 	return std.file.exists(path) && std.file.isFile(path);
47 }
48 ///ditto
49 bool existsAsFile(in Path path) @trusted
50 {
51 	return existsAsFile(path.toRawString());
52 }
53 
54 /// Checks if the path exists as a symlink.
55 ///
56 /// This is like $(FULL_STD_FILE isSymlink), but returns false instead of
57 /// throwing if the path doesn't exist.
58 bool existsAsSymlink()(in string path) @trusted
59 {
60 	yapFunc(path.escapeShellArg());
61 	return std.file.exists(path) && std.file.isSymlink(path);
62 }
63 ///ditto
64 bool existsAsSymlink(in Path path) @trusted
65 {
66 	return existsAsSymlink(path.toRawString());
67 }
68 
69 /// If 'from' exists, then rename. Otherwise do nothing.
70 /// Supports Path and command echoing.
71 ///
72 /// Returns: Success?
73 bool tryRename(T1, T2)(T1 from, T2 to)
74 	if(
75 		(is(T1==string) || is(T1==Path)) &&
76 		(is(T2==string) || is(T2==Path))
77 	)
78 {
79 	if(from.exists())
80 	{
81 		rename(from, to);
82 		return true;
83 	}
84 
85 	return false;
86 }
87 
88 /// If 'name' exists, then remove. Otherwise do nothing.
89 /// Supports Path, command echoing and dryrun.
90 ///
91 /// Returns: Success?
92 bool tryRemove(T)(T name) if(is(T==string) || is(T==Path))
93 {
94 	if(name.exists())
95 	{
96 		remove(name);
97 		return true;
98 	}
99 	
100 	return false;
101 }
102 
103 /// If 'name' doesn't already exist, then mkdir. Otherwise do nothing.
104 /// Supports Path and command echoing.
105 /// Returns: Success?
106 bool tryMkdir(T)(T name) if(is(T==string) || is(T==Path))
107 {
108 	if(!name.exists())
109 	{
110 		mkdir(name);
111 		return true;
112 	}
113 	
114 	return false;
115 }
116 
117 /// If 'name' doesn't already exist, then mkdirRecurse. Otherwise do nothing.
118 /// Supports Path and command echoing.
119 /// Returns: Success?
120 bool tryMkdirRecurse(T)(T name) if(is(T==string) || is(T==Path))
121 {
122 	if(!name.exists())
123 	{
124 		mkdirRecurse(name);
125 		return true;
126 	}
127 	
128 	return false;
129 }
130 
131 /// If 'name' exists, then rmdir. Otherwise do nothing.
132 /// Supports Path and command echoing.
133 /// Returns: Success?
134 bool tryRmdir(T)(T name) if(is(T==string) || is(T==Path))
135 {
136 	if(name.exists())
137 	{
138 		rmdir(name);
139 		return true;
140 	}
141 	
142 	return false;
143 }
144 
145 version(ddoc_scriptlike_d)
146 {
147 	/// Posix-only. If 'original' exists, then symlink. Otherwise do nothing.
148 	/// Supports Path and command echoing.
149 	/// Returns: Success?
150 	bool trySymlink(T1, T2)(T1 original, T2 link)
151 		if(
152 			(is(T1==string) || is(T1==Path)) &&
153 			(is(T2==string) || is(T2==Path))
154 		);
155 }
156 else version(Posix)
157 {
158 	bool trySymlink(T1, T2)(T1 original, T2 link)
159 		if(
160 			(is(T1==string) || is(T1==Path)) &&
161 			(is(T2==string) || is(T2==Path))
162 		)
163 	{
164 		if(original.exists())
165 		{
166 			symlink(original, link);
167 			return true;
168 		}
169 		
170 		return false;
171 	}
172 }
173 
174 /// If 'from' exists, then copy. Otherwise do nothing.
175 /// Supports Path and command echoing.
176 /// Returns: Success?
177 bool tryCopy(T1, T2)(T1 from, T2 to)
178 	if(
179 		(is(T1==string) || is(T1==Path)) &&
180 		(is(T2==string) || is(T2==Path))
181 	)
182 {
183 	if(from.exists())
184 	{
185 		copy(from, to);
186 		return true;
187 	}
188 	
189 	return false;
190 }
191 
192 /// If 'name' exists, then rmdirRecurse. Otherwise do nothing.
193 /// Supports Path and command echoing.
194 /// Returns: Success?
195 bool tryRmdirRecurse(T)(T name) if(is(T==string) || is(T==Path))
196 {
197 	if(name.exists())
198 	{
199 		rmdirRecurse(name);
200 		return true;
201 	}
202 	
203 	return false;
204 }