Использование анализатора командной строки дает строку, содержащую аргумент имени файла, в данном случае это «../somedir». Как преобразовать эту строку в типобезопасный Path Rel Dir
из Путь, чтобы позже объединить с текущим каталогом?
relDir1 <- parseRelDir fp
выдает ошибку (как указано в описании , потому что он «содержит компонент пути .., представляющий родительский каталог»)
Попытка сначала объединить currentDir со строкой из командной строки, как в
relDir2 <- parseRelDir (currDir </> fp)
возвращает ту же ошибку.
Я нашел «хак», используя collapse
из FileSystem.Path, который требует decodeString
и encodeString
для преобразования из String (он же FilePath) в специальный FilePath
используемый:
combPath = toFilePath currDir </> (locationDir $ flags) :: FilePath
collPath = collapse . decodeString $ combPath
absdir = makeAbsDir . encodeString $ collPath :: Path Abs Dir
но предположим, что есть лучший подход к этой общей задаче?
Возможно, вы ищете canonicalizePath. Запуск ghci в /home/<my-user>
:
System.Directory> canonicalizePath ".."
"/home"
Вы ссылаетесь на документацию пакета Path. Есть 6 упоминаний ..
, если вы выполните поиск на этой странице, и одно из них явно относится к вашему вопросу:
Иногда у вас есть пользовательский ввод, который содержит
../
. Решение, которое мы выбрали with должна иметь функцию вроде resolveDir (найдена в пакете path-io):resolveDir :: (MonadIO m, MonadThrow m) => Path Abs Dir -> FilePath -> m (Path Abs Dir)
Который вызовет canonicalizePath, который сворачивает и нормализует путь, а затем разбираем обычным старым parseAbsDir и готовим газом. Этот и другие, подобные этому, могут быть добавлены в пакет пути.
Я не понял информацию в пакете Path. С добавленной информацией о
canonicalizePath
я увидел, чтоabsdir <- resolveDir currDir (locationDir flags)
дает желаемый результат!