2

Using a command line parser gives a string containing a filename argument, which in this case is "../somedir". How to convert this string into a typesafe Path Rel Dir from Path to combine later with the current directory?

relDir1 <- parseRelDir fp

throws an error (as indicated in the description, because it "contains a .. path component representing the parent directory")

Trying to combine the currentDir with the String from the command line first, as in

relDir2 <- parseRelDir (currDir </> fp) 

returns the same error.

I found a "hack", using collapse from FileSystem.Path, which requires an decodeString and a encodeString to convert from String (aka FilePath) to the special FilePath used:

combPath = toFilePath currDir </> (locationDir $ flags) :: FilePath 
collPath = collapse . decodeString $ combPath   
absdir = makeAbsDir . encodeString $ collPath :: Path Abs Dir 

but assume there is somewhere a better approach to this common task?

user855443
  • 2,596
  • 3
  • 25
  • 37

2 Answers2

4

Perhaps you are looking for canonicalizePath. Starting ghci in /home/<my-user>:

System.Directory> canonicalizePath ".."
"/home"
Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380
1

You linked to the documentation of the Path package. There are 6 mentions of .. if you search that page, and one of them is clearly addressing your question:

Sometimes you have user input that contains ../. The solution we went with is to have a function like resolveDir (found in path-io package):

resolveDir :: (MonadIO m, MonadThrow m)
           => Path Abs Dir -> FilePath -> m (Path Abs Dir) 

Which will call canonicalizePath which collapses and normalizes a path and then we parse with regular old parseAbsDir and we’re cooking with gas. This and others like it might get added to the path package.

amalloy
  • 89,153
  • 8
  • 140
  • 205
  • I did not understand the information in the Path package. With the added information about `canonicalizePath` I saw that `absdir <- resolveDir currDir (locationDir flags)` produces the desired result! – user855443 Apr 03 '23 at 15:24