Skip to content

Commit 9f34f0b

Browse files
authored
Added EnsureFolder to command line extensions (#313)
* Allows for standard mechanism to create a folder that doesn't exist. * As with any part of the command line handling, this is NOT a securing check/test. It is only a convenience. Apps operating at elevated levels need to perform the normal hardening/protections associated with a privileged operation.
1 parent e8d71da commit 9f34f0b

1 file changed

Lines changed: 51 additions & 1 deletion

File tree

src/Ubiquity.NET.CommandLine/SymbolValidationExtensions.cs

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ public static void ValidateFileExists( ArgumentResult result )
119119
}
120120
}
121121

122-
/// <summary>Extension method to add the <see cref="ValidateFolderExists(OptionResult)"/></summary>
122+
/// <summary>Extension method to add the <see cref="ValidateFolderExists(OptionResult)"/> validator</summary>
123123
/// <param name="self">Option to add the validator for</param>
124124
/// <returns><paramref name="self"/> for fluent use</returns>
125125
public static Option<DirectoryInfo> AcceptExistingFolderOnly( this Option<DirectoryInfo> self )
@@ -149,5 +149,55 @@ public static void ValidateFolderExists( OptionResult result )
149149
}
150150
}
151151
}
152+
153+
/// <summary>Extension method to add the <see cref="EnsureFolderExists(OptionResult)"/> validator</summary>
154+
/// <param name="self">Option to add the validator for</param>
155+
/// <returns><paramref name="self"/> for fluent use</returns>
156+
public static Option<DirectoryInfo> EnsureFolder( this Option<DirectoryInfo> self )
157+
{
158+
self.AddValidator(EnsureFolderExists);
159+
return self;
160+
}
161+
162+
/// <summary>Option validator for an Option's tokens that ensures each Folder exists (creates it if not present)</summary>
163+
/// <param name="result">result to validate</param>
164+
/// <remarks>
165+
/// This is a parse validation that will create a directory that does not exist. It is explicitly NOT a security
166+
/// check/test!. Apps MUST NOT assume anything about the folder beyond the fact that it existed AT THE TIME this
167+
/// validation ran. It might not exist when needed, might have been replaced since, or may exist as or been
168+
/// replaced by a link to something else later or even deleted later. None of those scenarios is verified or
169+
/// prevented by this.
170+
/// </remarks>
171+
public static void EnsureFolderExists( OptionResult result )
172+
{
173+
string value = result.Option.HelpName ?? result.Option.Name;
174+
foreach (Token token in result.Tokens)
175+
{
176+
if (!Directory.Exists(token.Value))
177+
{
178+
try
179+
{
180+
Directory.CreateDirectory(token.Value);
181+
}
182+
catch(Exception ex) when (IsDirectoryException(ex))
183+
{
184+
result.AddError($"Attempt to create directory '{token.Value}' resulted in {ex.Message}");
185+
}
186+
187+
break;
188+
}
189+
}
190+
}
191+
192+
// returns true if the exception is one of the documented types for Directory.CreateDirectory().
193+
private static bool IsDirectoryException(Exception ex)
194+
{
195+
return ex is IOException or
196+
UnauthorizedAccessException or
197+
ArgumentException or
198+
PathTooLongException or
199+
DirectoryNotFoundException or
200+
NotSupportedException;
201+
}
152202
}
153203
}

0 commit comments

Comments
 (0)