packages feed

hsinstall-3.1: src/lib/HSInstall/Paths.hs

{- |
  Deployed file location support library for software deployed with the
  hsinstall utility. Or, really, anything that roughly follows an FHS-like
  deployment structure.
-}
module HSInstall.Paths
  ( getShareDir
  )
  where

import System.Directory (doesDirectoryExist)
import System.Environment (getExecutablePath)
import System.FilePath ((</>), takeDirectory, takeFileName)


{- |
  Get a path to the share directory relative to the binary location. The
  argument passed here is expected to be the output of @getDataDir@ generated
  by Cabal at compile time in the @Paths_PROJECTNAME@ module.

  Usage:

  @
    import HSInstall.Paths (getShareDir)
    import Paths_PROJECTNAME (getDataDir)
    import System.FilePath ((</>))

    shareDir <- getShareDir getDataDir
    let resourcesDir = shareDir </> "resources"
  @

  If your binary is at @\/foo\/bar\/usr\/bin\/BINARY@, this library will generate
  this path: @\/foo\/bar\/usr\/share\/PROJECTNAME@

  If this directory doesn't exist (because you're developing it and haven't yet
  constructed the AppImage or haven't built the dist dir), @./@ will be returned.
-}
getShareDir :: IO FilePath -> IO FilePath
getShareDir cabalDataDir = do
  appDir <- stripVersion . takeFileName <$> cabalDataDir
  sharePath <- ( </> "share" </> appDir )
    . takeDirectory . takeDirectory <$> getExecutablePath

  sharePathExists <- doesDirectoryExist sharePath
  pure $ if sharePathExists then sharePath else "."


stripVersion :: String -> String
stripVersion = reverse . drop 1 . dropWhile (/= '-') . reverse