''' <summary>
''' Returns a collection of application versioned directories
''' found within the specified base directory, sorted by version.
''' </summary>
'''
''' <example> This is a code example.
''' <code language="VB">
''' Dim baseDir As String = "C:\Program Files\Squirrel Application"
''' Dim namePrefix As String = "app-" ' Case: "app-1.0.0"
''' Dim nameSuffix As String = Nothing
'''
''' Dim versionedDirs As SortedList(Of Version, DirectoryInfo) =
''' GetVersionedDirectories(baseDir, namePrefix, nameSuffix)
'''
''' Dim oldest As DirectoryInfo = versionedDirs.First.Value
''' Dim newest As DirectoryInfo = versionedDirs.Last.Value
'''
''' Console.WriteLine($"Oldest versioned directory name: {oldest.Name}")
''' Console.WriteLine($"Newest versioned directory name: {newest.Name}")
''' </code>
''' </example>
'''
''' <param name="baseDir">
''' The base directory that contains application versioned directories (for example: "<b>app-1.0.0</b>").
''' </param>
'''
''' <param name="namePrefix">
''' Optional. If specified, only directory names that begin with this prefix are included.
''' <para></para>
''' Default value is null.
''' </param>
'''
''' <param name="nameSuffix">
''' Optional. If specified, only directory names that ends with this suffix are included.
''' <para></para>
''' Default value is null.
''' </param>
'''
''' <returns>
''' A <see cref="SortedList(Of Version, DirectoryInfo)"/> where the keys are
''' <see cref="Version"/> objects parsed from the directory names, and the values
''' are the corresponding <see cref="DirectoryInfo"/> objects.
''' <para></para>
''' The collection is sorted in ascending order by version,
''' so <see cref="Enumerable.First"/> returns the oldest application version directory,
''' and <see cref="Enumerable.Last"/> returns the newest.
''' </returns>
'''
''' <exception cref="ArgumentNullException">
''' Thrown when the specified <paramref name="baseDir"/> is null.
''' </exception>
'''
''' <exception cref="DirectoryNotFoundException">
''' Thrown when the specified <paramref name="baseDir"/> does not exist.
''' </exception>
<DebuggerStepThrough>
Public Shared Function GetVersionedDirectories(baseDir As String,
Optional namePrefix As String = Nothing,
Optional nameSuffix As String = Nothing
) As SortedList(Of Version, DirectoryInfo)
Dim prefixText As String = If(String.IsNullOrEmpty(namePrefix), "", Regex.Escape(namePrefix))
Dim suffixText As String = If(String.IsNullOrEmpty(nameSuffix), "", Regex.Escape(nameSuffix))
Dim versionGroup As String = "(?<version>\d+(\.\d+){0,3})"
Dim pattern As String = $"^{prefixText}{versionGroup}{suffixText}$"
Dim searchRegex As New Regex(pattern, RegexOptions.IgnoreCase Or RegexOptions.Compiled)
Return GetVersionedDirectories(baseDir, searchRegex)
End Function
''' <summary>
''' Returns a collection of application versioned directories
''' found within the specified base directory, sorted by version.
''' </summary>
'''
''' <example> This is a code example.
''' <code language="VB">
''' Dim baseDir As String = "C:\Program Files\Squirrel Application"
''' Dim pattern As String = "^app-(?<version>\d+(\.\d+){0,3})$" ' Case: "app-1.0.0"
''' Dim searchRegex As New Regex(pattern, RegexOptions.IgnoreCase Or RegexOptions.Compiled)
'''
''' Dim versionedDirs As SortedList(Of Version, DirectoryInfo) =
''' GetVersionedDirectories(baseDir, searchRegex)
'''
''' Dim oldest As DirectoryInfo = versionedDirs.First.Value
''' Dim newest As DirectoryInfo = versionedDirs.Last.Value
'''
''' Console.WriteLine($"Oldest versioned directory name: {oldest.Name}")
''' Console.WriteLine($"Newest versioned directory name: {newest.Name}")
''' </code>
''' </example>
'''
''' <param name="baseDir">
''' The base directory that contains application versioned directories (for example: "<b>app-1.0.0</b>").
''' </param>
'''
''' <param name="searchRegex">
''' A <see cref="Regex"/> used to filter the directory names.
''' <para></para>
''' ⚠️ This regex must contain a named group called <b>version</b>,
''' which will be used to extract the version number from the directory name.
''' <para></para>
''' For example: <c>"^app-(?<version>\d+(\.\d+){0,3})$"</c>
''' </param>
'''
''' <returns>
''' A <see cref="SortedList(Of Version, DirectoryInfo)"/> where the keys are
''' <see cref="Version"/> objects parsed from the directory names, and the values
''' are the corresponding <see cref="DirectoryInfo"/> objects.
''' <para></para>
''' The collection is sorted in ascending order by version,
''' so <see cref="Enumerable.First"/> returns the oldest application version directory,
''' and <see cref="Enumerable.Last"/> returns the newest.
''' </returns>
'''
''' <exception cref="ArgumentNullException">
''' Thrown when the specified <paramref name="baseDir"/> or <paramref name="searchRegex"/> is null.
''' </exception>
'''
''' <exception cref="ArgumentException">
''' Thrown when the pattern of the specified <paramref name="searchRegex"/> does not contain a named group 'version'.
''' </exception>
'''
''' <exception cref="DirectoryNotFoundException">
''' Thrown when the specified <paramref name="baseDir"/> does not exist.
''' </exception>
<DebuggerStepThrough>
Public Shared Function GetVersionedDirectories(baseDir As String,
searchRegex As Regex
) As SortedList(Of Version, DirectoryInfo)
If String.IsNullOrWhiteSpace(baseDir) Then
Throw New ArgumentNullException(NameOf(baseDir))
End If
If searchRegex Is Nothing Then
Throw New ArgumentNullException(NameOf(searchRegex))
End If
If Not searchRegex.GetGroupNames().Contains("version") Then
Throw New ArgumentException("The provided regex pattern must contain a named group 'version'.", NameOf(searchRegex))
End If
If Not Directory.Exists(baseDir) Then
Throw New DirectoryNotFoundException(baseDir)
End If
Dim topLevelDirs As DirectoryInfo() =
New DirectoryInfo(baseDir).
GetDirectories("*", SearchOption.TopDirectoryOnly)
Dim versionedDirs As New SortedList(Of Version, DirectoryInfo)(
topLevelDirs.Length, Comparer(Of Version).Default
)
For Each topLevelDir As DirectoryInfo In topLevelDirs
Dim match As Match = searchRegex.Match(topLevelDir.Name)
If match.Success Then
Dim versionPart As String = match.Groups("version").Value
Dim ver As Version = Nothing
If Version.TryParse(versionPart, ver) Then
If Not versionedDirs.ContainsKey(ver) Then
versionedDirs.Add(ver, topLevelDir)
End If
End If
End If
Next
Return versionedDirs
End Function