{-# language ViewPatterns #-} module DhallToCabal.Util ( relativeTo ) where import System.FilePath ( dropTrailingPathSeparator, joinPath, normalise, splitDirectories, takeDirectory ) -- | Like 'System.FilePath.makeRelative', but will introduce @..@ -- segments (and hence will misbehave in the presence of symlinks). -- -- If the path being relativised is identical to the root path, then -- this will return the empty string. relativeTo :: FilePath -- ^ The path to be relative to. Note that the final file-name is -- ignored: @foo/bar@ is relative to @foo/@, even if @foo/bar@ is -- a directory. -> FilePath -- ^ The path to relativise. -> FilePath relativeTo = \ ( splitDirectories . dropTrailingPathSeparator . takeDirectory . normalise -> base ) -> \ ( splitDirectories . normalise -> path ) -> joinPath ( go base path ) where -- @normalise "."@ is @"."@, so we have to take care here with dots. go ( a : as ) ( b : bs ) | a == b = go as bs | a == "." = go as ( b : bs ) | b == "." = go (a : as) bs | otherwise = ( ".." <$ ( a : as ) ) ++ ( b : bs ) go [] bs = bs go as [] = ".." <$ as