packages feed

hsinstall 2.8 → 2.9

raw patch · 15 files changed

+199/−185 lines, 15 filesdep +formattingdep +prettyprinterdep −ansi-wl-pprintdep −newtype-genericsdep ~Cabaldep ~basedep ~directory

Dependencies added: formatting, prettyprinter

Dependencies removed: ansi-wl-pprint, newtype-generics

Dependency ranges changed: Cabal, base, directory, exceptions, filepath, heredoc, hsinstall, optparse-applicative, process, safe-exceptions, transformers

Files

.gitignore view
@@ -1,2 +1,5 @@ # Stack uses this directory as scratch space. /.stack-work/++# Made by hasktags+tags
CHANGELOG.md view
@@ -1,3 +1,22 @@+2.9 (2025-07-30)++  * Moved CHANGELOG.md to extra-doc-files stanza+  * Added bounds to build-depends libraries+  * Removed OverloadedStrings directives from source files+  * Switched from putStrLn and printf to the formatting library+  * Implemented some hlint suggestions+  * Fixed odd range in build-depends for base+  * Switched to the more modern prettyprinter library+  * Tidied up a bit in the cabal file+  * Removed extra whitespace in imports+  * Moved Stackage snapshot up to lts-22.6+  * Replaced (++) with (<>) in a few places+  * Added optional GPG2 signing to appimage creation+  * Switched from newtype-generics to OverloadedRecordDot+  * Removed ending copyright year+  * Fixed linuxdeploy version env variable name++ 2.8 (2023-01-28)    * Fix for change to the Cabal Distribution API
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2016-2023, Dino Morelli <dino@ui3.info>+Copyright (c) 2016, Dino Morelli <dino@ui3.info>  Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided
hsinstall.cabal view
@@ -1,20 +1,22 @@ cabal-version: 2.2  name: hsinstall-version: 2.8+version: 2.9 synopsis: Install Haskell software-description: This is a tool for deploying software projects into directory structures suitable for installation on a system. It builds upon the `stack install` command and adds more features. It's also a tool for easier AppImage creation.+description: This is a tool for deploying software projects into directory+  structures suitable for installation on a system. It builds upon the `stack+  install` command and adds more features. It's also a tool for easier AppImage+  creation. category: Utility homepage: https://github.com/dino-/hsinstall#readme bug-reports: https://github.com/dino-/hsinstall/issues author: Dino Morelli maintainer: Dino Morelli <dino@ui3.info>-copyright: 2016-2023 Dino Morelli+copyright: 2016 Dino Morelli license: ISC license-file: LICENSE build-type: Simple extra-source-files:-  CHANGELOG.md   doc/hcar/hsinstall.tex   .gitignore   hsinstall/share/applications/hsinstall.desktop@@ -23,6 +25,8 @@   README.md   stack.yaml   stack.yaml.lock+extra-doc-files:+  CHANGELOG.md  source-repository head   type: git@@ -52,9 +56,6 @@     ScopedTypeVariables     StandaloneDeriving     TupleSections-  build-depends:-      directory-    , filepath   ghc-options:     -fwarn-tabs     -Wall@@ -63,6 +64,12 @@     -Wincomplete-uni-patterns     -Wpartial-fields     -Wredundant-constraints+  build-depends:+      base >=3 && <5+    , directory >=1.3.8.1 && <1.4+    , filepath >=1.4.100.4 && <1.5+  other-modules:+    Paths_hsinstall   autogen-modules:     Paths_hsinstall @@ -74,8 +81,7 @@       Paths_hsinstall   hs-source-dirs:       src/lib-  build-depends:-      base >=4.8 && <5.0+  -- build-depends:  executable hsinstall   import: lang@@ -92,14 +98,13 @@   hs-source-dirs:       src/app   build-depends:-      ansi-wl-pprint-    , base >=4.8 && <5.0-    , Cabal-    , exceptions-    , heredoc-    , hsinstall-    , newtype-generics-    , optparse-applicative-    , process-    , safe-exceptions-    , transformers+      Cabal >=3.10.1.0 && <4+    , exceptions >=0.10.7 && <1+    , formatting >=7.2.0 && <8+    , heredoc >=0.2.0.0 && <0.3+    , hsinstall <3+    , optparse-applicative >=0.18.1.0 && <0.19+    , prettyprinter >=1.7.1 && <2+    , process >=1.6.17.0 && <2+    , safe-exceptions >=0.1.7.4 && <0.2+    , transformers >=0.6.1.0 && <0.7
src/app/HSInstall/AppImage.hs view
@@ -1,18 +1,18 @@-{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE OverloadedRecordDot #-}  module HSInstall.AppImage-  ( mkAppImage, prepAppImageFiles )+  ( mkAppImage, prepAppImageFiles+  )   where -import Control.Monad ( unless )-import Control.Newtype.Generics ( op )+import Control.Monad (unless) import qualified System.Directory as Dir-import System.Environment ( setEnv )-import System.FilePath ( (</>), (<.>), takeDirectory )-import System.Process ( callProcess )+import System.Environment (setEnv)+import System.FilePath ((</>), (<.>), takeDirectory)+import System.Process (callProcess) -import HSInstall.Common ( ExeFile (..), TmplDir (..), dumpStockIcon-  , tmplDir )+import HSInstall.Common (ExeFile (..), Signing (SigningKeyId)+  , TmplDir (v), dumpStockIcon , tmplDir) import HSInstall.DeploymentInfo   ( BinDir (..)   , PrefixDir (..)@@ -25,10 +25,10 @@   desktopDir :: FilePath-desktopDir = op TmplDir tmplDir </> "share" </> "applications"+desktopDir = tmplDir.v </> "share" </> "applications"  iconDir :: FilePath-iconDir = op TmplDir tmplDir </> "share" </> "icons" </> "hicolor" </> "scalable" </> "apps"+iconDir = tmplDir.v </> "share" </> "icons" </> "hicolor" </> "scalable" </> "apps"   prepAppImageFiles :: ExeFile -> IO DesktopFileStatus@@ -48,30 +48,35 @@  newtype Arg = Arg String -mkAppImage :: ExeFile -> DeploymentInfo -> DesktopFileStatus -> IO ()+mkAppImage :: Signing -> ExeFile -> DeploymentInfo -> DesktopFileStatus -> IO () -mkAppImage exeFile di DesktopExists = do+mkAppImage signing exeFile di DesktopExists = do   let desktopArg = Arg ("--desktop-file=" <>-        (desktopDir </> op ExeFile exeFile <.> "desktop"))-  mkAppImage' exeFile di desktopArg+        (desktopDir </> exeFile.v <.> "desktop"))+  mkAppImage' signing exeFile di desktopArg -mkAppImage exeFile di CreateNewDesktop = do-  mkAppImage' exeFile di (Arg "--create-desktop-file")+mkAppImage signing exeFile di CreateNewDesktop = do+  mkAppImage' signing exeFile di (Arg "--create-desktop-file")   -- Now copy the freshly-created .desktop file into the project sources-  let desktopFile = op ExeFile exeFile <.> "desktop"+  let desktopFile = exeFile.v <.> "desktop"   Dir.createDirectoryIfMissing True desktopDir   Dir.copyFile-    ((op PrefixDir . prefixDir $ di) </> "share" </> "applications" </> desktopFile)+    (di.prefixDir.v </> "share" </> "applications" </> desktopFile)     (desktopDir </> desktopFile)  -mkAppImage' :: ExeFile -> DeploymentInfo -> Arg -> IO ()-mkAppImage' (ExeFile exeFp) di (Arg desktopArg) = do-  setEnv "VERSION" (prettyShow . version $ di)+mkAppImage' :: Signing -> ExeFile -> DeploymentInfo -> Arg -> IO ()+mkAppImage' signing (ExeFile exeFp) di (Arg desktopArg) = do+  setEnv "LINUXDEPLOY_OUTPUT_VERSION" (prettyShow . version $ di)+  case signing of+    (SigningKeyId keyId) -> do+      setEnv "LDAI_SIGN" "1"+      setEnv "LDAI_SIGN_KEY" keyId+    _ -> pure ()   callProcess "linuxdeploy-x86_64.AppImage"-    [ "--appdir=" ++ (takeDirectory . op PrefixDir . prefixDir $ di)-    , "--executable=" <> ((op BinDir . binDir $ di) </> exeFp)+    [ "--appdir=" <> takeDirectory di.prefixDir.v+    , "--executable=" <> (di.binDir.v </> exeFp)     , desktopArg-    , "--icon-file=" ++ (iconDir </> exeFp <.> "svg")+    , "--icon-file=" <> (iconDir </> exeFp <.> "svg")     , "--output=appimage"     ]
src/app/HSInstall/Build.hs view
@@ -7,12 +7,12 @@   )   where -import System.Directory ( getDirectoryContents )-import System.Process ( callProcess )+import System.Directory (getDirectoryContents)+import System.Process (callProcess) -import HSInstall.Common ( ExeFile (..) )-import HSInstall.Except ( justDoIt )-import HSInstall.Opts ( BuildMode (AppImageExe, Project) )+import HSInstall.Common (ExeFile (..))+import HSInstall.Except (justDoIt)+import HSInstall.Opts (BuildMode (AppImageExe, Project))   data BuildTool = Cabal | Stack
src/app/HSInstall/Common.hs view
@@ -1,35 +1,31 @@-{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DuplicateRecordFields #-}  module HSInstall.Common   ( ExeFile (..)+  , Signing (..)   , TmplDir (..)   , dumpStockIcon   , tmplDir   )   where -import Control.Newtype.Generics-import Data.Maybe ( fromMaybe )-import GHC.Generics-import HSInstall.Paths ( getShareDir )-import Paths_hsinstall ( getDataDir )-import System.Directory ( copyFile )-import System.FilePath ( (</>), (<.>) )+import Data.Maybe (fromMaybe)+import HSInstall.Paths (getShareDir)+import Paths_hsinstall (getDataDir)+import System.Directory (copyFile)+import System.FilePath ((</>), (<.>))  -newtype TmplDir = TmplDir FilePath-  deriving Generic--instance Newtype TmplDir+newtype TmplDir = TmplDir { v :: FilePath }  tmplDir :: TmplDir-tmplDir = pack $ "." </> "hsinstall"+tmplDir = TmplDir $ "." </> "hsinstall"  -newtype ExeFile = ExeFile FilePath-  deriving Generic+newtype ExeFile = ExeFile { v :: FilePath } -instance Newtype ExeFile++data Signing = SigningKeyId String | NoSignature   dumpStockIcon :: Maybe FilePath -> IO ()
src/app/HSInstall/DeploymentInfo.hs view
@@ -1,5 +1,4 @@-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DuplicateRecordFields, OverloadedRecordDot #-}  module HSInstall.DeploymentInfo   ( BinDir (..)@@ -14,10 +13,9 @@   )   where -import Control.Applicative ( (<|>) )-import Control.Monad.Trans.Maybe ( MaybeT (..), runMaybeT )-import Control.Newtype.Generics-import Data.List ( find, isSuffixOf )+import Control.Applicative ((<|>))+import Control.Monad.Trans.Maybe (MaybeT (..), runMaybeT)+import Data.List (find, isSuffixOf) import Distribution.Package   ( PackageId   , PackageIdentifier (pkgName, pkgVersion)@@ -26,18 +24,16 @@   ( GenericPackageDescription (packageDescription)   , PackageDescription (package)   )-import Distribution.Pretty ( prettyShow )-import Distribution.Simple.PackageDescription-  ( readGenericPackageDescription )-import Distribution.Types.PackageName ( unPackageName )-import Distribution.Types.Version ( Version )-import Distribution.Verbosity ( normal )-import GHC.Generics hiding ( Prefix )-import System.Directory ( getDirectoryContents )-import System.FilePath ( (</>), (<.>) )+import Distribution.Pretty (prettyShow)+import Distribution.Simple.PackageDescription (readGenericPackageDescription)+import Distribution.Types.PackageName (unPackageName)+import Distribution.Types.Version (Version)+import Distribution.Verbosity (normal)+import System.Directory (getDirectoryContents)+import System.FilePath ((</>), (<.>)) -import HSInstall.Build ( BuildTool, makeCabal )-import HSInstall.Common ( ExeFile (..) )+import HSInstall.Build (BuildTool, makeCabal)+import HSInstall.Common (ExeFile (..)) import HSInstall.Except   ( HSInstallException (NoCabalFiles)   , throwM@@ -49,20 +45,11 @@   )  -newtype PrefixDir = PrefixDir FilePath-  deriving Generic--instance Newtype PrefixDir--newtype BinDir = BinDir FilePath-  deriving Generic--instance Newtype BinDir+newtype PrefixDir = PrefixDir { v :: FilePath } -newtype DocDir = DocDir FilePath-  deriving Generic+newtype BinDir = BinDir { v :: FilePath } -instance Newtype DocDir+newtype DocDir = DocDir { v :: FilePath }  data DeploymentInfo = DeploymentInfo   { prefixDir :: PrefixDir@@ -105,5 +92,5 @@ computePrefixDir :: PrefixOpt -> BuildMode -> PrefixDir computePrefixDir (Prefix prefixFp) _ = PrefixDir prefixFp computePrefixDir NoPrefixSpecified (AppImageExe (ExeFile exeFp)) =-  over PrefixDir (exeFp <.>) defaultPrefix+  PrefixDir $ exeFp <.> defaultPrefix.v computePrefixDir NoPrefixSpecified Project = defaultPrefix
src/app/HSInstall/Except.hs view
@@ -1,6 +1,3 @@-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE ScopedTypeVariables #-}- module HSInstall.Except   ( HSInstallException (..)   , justDoIt@@ -11,11 +8,11 @@   )   where -import Control.Exception.Safe-  ( Exception, Handler (..), Typeable, catches, catchIO, throwM )-import Control.Monad.Catch ( MonadCatch )-import GHC.IO.Exception ( IOException )-import System.Exit ( die )+import Control.Exception.Safe (Exception, Handler (..), Typeable, catches,+  catchIO, throwM)+import Control.Monad.Catch (MonadCatch)+import GHC.IO.Exception (IOException)+import System.Exit (die)   data HSInstallException
src/app/HSInstall/Opts.hs view
@@ -1,6 +1,4 @@-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE DuplicateRecordFields, QuasiQuotes #-}  module HSInstall.Opts   ( BuildMode (..)@@ -12,28 +10,21 @@   )   where -import Control.Newtype.Generics-import Data.Version ( showVersion )-import GHC.Generics hiding ( Prefix )+import Data.Version (showVersion)+import Formatting ((%+), format, formatToString)+import Formatting.ShortFormatters (s) import Options.Applicative-import Paths_hsinstall ( version )-import System.Environment ( getProgName )-import Text.Heredoc ( here )-import Text.PrettyPrint.ANSI.Leijen ( string )-import Text.Printf ( printf )+import Paths_hsinstall (version)+import Prettyprinter (pretty)+import System.Environment (getProgName)+import Text.Heredoc (here) -import HSInstall.Common ( ExeFile (..) )+import HSInstall.Common (ExeFile (..), Signing (SigningKeyId, NoSignature))  -newtype CleanSwitch = CleanSwitch Bool-  deriving Generic--instance Newtype CleanSwitch--newtype DumpIconSwitch = DumpIconSwitch Bool-  deriving Generic+newtype CleanSwitch = CleanSwitch { v :: Bool } -instance Newtype DumpIconSwitch+newtype DumpIconSwitch = DumpIconSwitch { v :: Bool }  data BuildMode = AppImageExe ExeFile | Project @@ -44,9 +35,11 @@   , optDumpIcon :: DumpIconSwitch   , optBuildMode :: BuildMode   , optPrefix :: PrefixOpt+  , optSigning :: Signing   }  +{- HLINT ignore "Functor law" -} parser :: Parser Options parser = Options   <$> ( CleanSwitch <$> switch@@ -60,29 +53,32 @@         <> help "Save a default icon, unix-terminal.svg, to the current working directory"         )       )-  <*> ( maybe Project (AppImageExe . ExeFile) <$> optional-        ( strOption-          (  long "mk-appimage"-          <> short 'i'-          <> metavar "EXE"-          <> help "Prepare the AppDir structure and build an AppImage for EXE. Changes PREFIX to EXE.AppDir/usr."-          )+  <*> option ( AppImageExe . ExeFile <$> str )+        (  long "mk-appimage"+        <> short 'i'+        <> metavar "EXE"+        <> help "Prepare the AppDir structure and build an AppImage for EXE. Changes PREFIX to EXE.AppDir/usr."+        <> value Project         )-      )-  <*> ( maybe NoPrefixSpecified Prefix <$> optional-        ( strOption-          (  long "prefix"-          <> short 'p'-          <> metavar "DIR"-          <> help "Install prefix directory (Default: AppDir/usr)"-          )+  <*> option ( Prefix <$> str )+        (  long "prefix"+        <> short 'p'+        <> metavar "DIR"+        <> help "Install prefix directory (Default: AppDir/usr)"+        <> value NoPrefixSpecified         )-      )+  <*> option ( SigningKeyId <$> str )+        (  long "sign"+        <> short 's'+        <> metavar "KEY_ID"+        <> help "Sign the AppImage with the specified GPG2 key id"+        <> value NoSignature+        )   versionHelper :: String -> Parser (a -> a) versionHelper progName =-  infoOption (printf "%s %s" progName (showVersion version)) $ mconcat+  infoOption (formatToString (s %+ s) progName (showVersion version)) $ mconcat   [ long "version"   , help "Show version information"   , hidden@@ -93,13 +89,13 @@ parseOpts = do   pn <- getProgName   execParser $ info (parser <**> helper <**> versionHelper pn)-    (  header (printf "%s - Pack a haskell project into a deployable directory structure" pn)+    (  header (formatToString (s %+ "- Pack a haskell project into a deployable directory structure") pn)     <> footer'     )   footer' :: InfoMod a-footer' = footerDoc . Just . string . printf content . showVersion $ version+footer' = footerDoc . Just . pretty $ format content (showVersion version)     where content = [here|OVERVIEW  hsinstall is a tool for installing a Haskell software project into a directory structure for deployment. It builds upon the `stack install` and `cabal install` commands and adds these features:@@ -144,6 +140,15 @@  For more info on AppImage: https://appimage.org/ +If you see failure like the following when using the -s,--sign switch:++    [appimage/stderr] [sign] gpgme_op_sign(gpgme_ctx, gpgme_appimage_file_data, gpgme_sig_data, GPGME_SIG_MODE_DETACH): call failed: Inappropriate ioctl for device++What's happening is gpg can't figure out a way to ask for the gpg key passphrase. Try setting the env like this++    $ GPG_TTY=$(tty) hsinstall ...++ TEMPLATE DIRECTORY  If present, hsinstall will copy the contents of the `hsinstall` template directory into `<PREFIX>`. Here's an explanation of the hsinstall directory contents:@@ -163,4 +168,4 @@  In order to locate data files at runtime, including resources, the hsinstall project includes a library to construct the share path relative to the executable. See this source code for help with integrating this into your app: https://github.com/dino-/hsinstall/blob/master/src/lib/HSInstall/Resources.hs -Version %s  Dino Morelli <dino@ui3.info>|]+Version|] %+ s %+ " Dino Morelli <dino@ui3.info>"
src/app/HSInstall/System/Directory.hs view
@@ -1,16 +1,14 @@-{-# LANGUAGE OverloadedStrings #-}- module HSInstall.System.Directory   ( copyTree   )   where -import Control.Monad ( when )-import Data.List ( (\\) )-import System.Directory ( copyFile, createDirectoryIfMissing,-  doesDirectoryExist, getDirectoryContents )-import System.FilePath ( (</>) )-import Text.Printf ( printf )+import Control.Monad (when)+import Data.List ((\\))+import Formatting ((%+), fprintLn, string)+import System.Directory (copyFile, createDirectoryIfMissing,+  doesDirectoryExist, getDirectoryContents)+import System.FilePath ((</>))   {-@@ -52,7 +50,7 @@   let targetPath = baseTargetPath </> relativePath    when chatty $-    printf "Copying %s to %s\n" sourcePath targetPath+    fprintLn ("Copying" %+ string %+ "to" %+ string) sourcePath targetPath    if isDir     then createDirectoryIfMissing False targetPath
src/app/hsinstall.hs view
@@ -1,18 +1,17 @@-{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE OverloadedRecordDot #-} -import Control.Monad ( when )-import Control.Newtype.Generics ( op )+import Control.Monad (when)+import Formatting ((%), (%+), fprintLn, string) import qualified System.Directory as Dir-import System.Exit ( exitSuccess )-import System.FilePath ( (</>) )-import System.IO ( BufferMode (NoBuffering),-  hSetBuffering, stderr, stdout )-import Text.Printf ( printf )+import System.Exit (exitSuccess)+import System.FilePath ((</>))+import System.IO (BufferMode (NoBuffering),+  hSetBuffering, stderr, stdout) -import HSInstall.AppImage ( mkAppImage, prepAppImageFiles )-import HSInstall.Build ( BuildTool, clean,-  determineBuildTool, installBinaries )-import HSInstall.Common ( TmplDir (..), dumpStockIcon, tmplDir )+import HSInstall.AppImage (mkAppImage, prepAppImageFiles)+import HSInstall.Build (BuildTool, clean,+  determineBuildTool, installBinaries)+import HSInstall.Common (TmplDir (v), dumpStockIcon, tmplDir) import HSInstall.DeploymentInfo   ( BinDir (..)   , DeploymentInfo (binDir, docDir, prefixDir)@@ -20,14 +19,14 @@   , PrefixDir (..)   , constructDeploymentInfo   )-import HSInstall.Except ( withExceptionHandling )+import HSInstall.Except (withExceptionHandling) import HSInstall.Opts   ( BuildMode (AppImageExe, Project)   , CleanSwitch (..), DumpIconSwitch (..)   , Options (..)   , parseOpts   )-import HSInstall.System.Directory ( copyTree )+import HSInstall.System.Directory (copyTree)   main :: IO ()@@ -37,23 +36,23 @@     opts <- parseOpts      buildTool <- determineBuildTool-    putStrLn $ "Build tool detected: " <> show buildTool+    fprintLn ("Build tool detected:" %+ string) $ show buildTool -    when (op DumpIconSwitch . optDumpIcon $ opts) $ dumpStockIcon Nothing >> exitSuccess+    when opts.optDumpIcon.v $ dumpStockIcon Nothing >> exitSuccess      di <- constructDeploymentInfo buildTool opts -    when (op CleanSwitch . optClean $ opts) $ clean buildTool+    when opts.optClean.v $ clean buildTool     deployApplication buildTool (optBuildMode opts) di     case optBuildMode opts of-      AppImageExe exePath -> prepAppImageFiles exePath >>= mkAppImage exePath di+      AppImageExe exePath -> prepAppImageFiles exePath >>= mkAppImage (optSigning opts) exePath di       Project             -> return ()   deployApplication :: BuildTool -> BuildMode -> DeploymentInfo -> IO () deployApplication buildTool mode di = do   -- Copy the binaries-  let binFp = op BinDir . binDir $ di+  let binFp = di.binDir.v   Dir.createDirectoryIfMissing True binFp   installBinaries buildTool mode binFp @@ -61,14 +60,14 @@   let licenseFile = "LICENSE"   licenseFileExists <- Dir.doesFileExist licenseFile   when licenseFileExists $ do-    printf "\nCopying %s\n" licenseFile-    let docFp = op DocDir . docDir $ di+    fprintLn ("\nCopying" %+ string) licenseFile+    let docFp = di.docDir.v     Dir.createDirectoryIfMissing True docFp     Dir.copyFile licenseFile (docFp </> licenseFile)    -- Copy the static template directory-  let tmplFp = op TmplDir tmplDir+  let tmplFp = tmplDir.v   tmplExists <- Dir.doesDirectoryExist tmplFp   when tmplExists $ do-    printf "\nCopying distribution files from template dir (%s)\n" tmplFp-    copyTree False tmplFp (op PrefixDir . prefixDir $ di)+    fprintLn ("\nCopying distribution files from template dir (" % string % ")") tmplFp+    copyTree False tmplFp di.prefixDir.v
src/lib/HSInstall/Paths.hs view
@@ -38,7 +38,7 @@   sharePathExists <- doesDirectoryExist sharePath   if sharePathExists     then return sharePath-    else fail $ "Share directory " ++ sharePath ++ " does not exist"+    else fail $ "Share directory " <> sharePath <> " does not exist"   stripVersion :: String -> String
stack.yaml view
@@ -1,4 +1,4 @@-resolver: nightly-2023-01-28+snapshot: lts-22.6  packages: - '.'
stack.yaml.lock view
@@ -1,12 +1,12 @@ # This file was autogenerated by Stack. # You should not edit this file by hand. # For more information, please see the documentation at:-#   https://docs.haskellstack.org/en/stable/lock_files+#   https://docs.haskellstack.org/en/stable/topics/lock_files  packages: [] snapshots: - completed:-    sha256: bd7b6edef8b9ad5efdf118923b9a530b9b8c2236af1b92abc3e5d9416fc1d452-    size: 595944-    url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2023/1/28.yaml-  original: nightly-2023-01-28+    sha256: 1b4c2669e26fa828451830ed4725e4d406acc25a1fa24fcc039465dd13d7a575+    size: 714100+    url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/22/6.yaml+  original: lts-22.6