cristianbuse / VBA-FileTools

Useful methods for interacting with the file system
MIT License
81 stars 23 forks source link

GetLocalPath will not return a path with prefix "." or ".." #16

Closed Kaydron1000 closed 1 year ago

Kaydron1000 commented 1 year ago

I was working with relative paths and found out GetLocalPath does not like to work with them.

I found a possible fix in the FixPathSeparators function. I think the code below should be added " 'Adding relative directory if specified"

I included additional code already existing for reference.

    'Adding relative directory if specified
    If Left$(pathToFix, 2) = ".." Or Left(pathToFix, 1) = "." Then
        resultPath = BuildPath(CurDir, pathToFix)
    End If

    '
    Const fCurrent As String = ps & "." & ps
    Const fParent As String = ps & ".." & ps
    Dim sepIndex As Long
    Dim i As Long: i = 0
    '
    'Remove any current folder references
    Do
        i = InStr(i + 1, resultPath, fCurrent)
        If i = 0 Then i = InStr(Len(resultPath) - 1, resultPath, ps & ".")
        If i > 0 Then Mid$(resultPath, i + 1, 1) = ps
    Loop Until i = 0

I haven't done a full analysis of your code to know if adding that will break anything, but from a quick glance it appears nothing should break.

Let me know if this will fit into the intention of your functions and I can send a pull request.

Example input output Before update:

Example input output After update:

cristianbuse commented 1 year ago

Hi @Kaydron1000 ,

I tend not to work with relative paths but rather be specific with full paths so that I minimize unexpected errors, since CurDir can be set from anywhere else in the program via ChDir. The GetLocalPath expects a fullPath - as the first parameter name suggests. The FixPathSeparators indeed deals with . and .. but only in the middle, not the left side.

Your call could be simply written as GetLocalPath(BuildPath(CurDir, ".\LogOutput")) and this would achieve the desired result while being specific.

I guess we could add an extra Boolean parameter that allows the behaviour you suggested. Something like:

Public Function GetLocalPath(ByRef fullPath As String _
                           , Optional ByVal rebuildCache As Boolean = False _
                           , Optional ByVal returnInputOnFail As Boolean = False _
                           , Optional ByVal useCurDirForRelativePaths As Boolean = False) As String

where the user can explicitly set the useCurDirForRelativePaths = True if he/she wants to work directly with relative paths. However, I still prefer keeping things explicit as I haven't really seen anyone use CurDir in a production environment so far.

Can you please give me an example where using CurDir has any kind of advantage? I am happy to implement it if you can convince me :smiley:

Thanks!

Kaydron1000 commented 1 year ago

I typically use relative path for loading in things such as configuration or exporting log files. The path is usually in reference to either executing application or selected input which could be 2 different directories.

I would have to agree with the idea that specifying the relative location is ideal/required, and I also do this by usually making some function that replaces "." with directory of executing assembly.

I agree with your statement. I'll close the issue as resolved. Thanks for your insight!