stack-2.11.1: src/Stack/Types/Config/Exception.hs
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeFamilies #-}
module Stack.Types.Config.Exception
( ConfigException (..)
, ConfigPrettyException (..)
, ParseAbsolutePathException (..)
, packageIndicesWarning
) where
import qualified Data.Text as T
import Data.Yaml ( ParseException )
import qualified Data.Yaml as Yaml
import Path( dirname, filename )
import Stack.Prelude
import Stack.Types.ConfigMonoid
( configMonoidAllowDifferentUserName
, configMonoidGHCVariantName, configMonoidSystemGHCName
)
import Stack.Types.Version
( VersionRange, stackVersion, versionRangeText )
-- | Type representing exceptions thrown by functions exported by the
-- "Stack.Config" module.
data ConfigException
= ParseCustomSnapshotException Text ParseException
| NoProjectConfigFound (Path Abs Dir) (Maybe Text)
| UnexpectedArchiveContents [Path Abs Dir] [Path Abs File]
| UnableToExtractArchive Text (Path Abs File)
| BadStackVersionException VersionRange
| NoSuchDirectory FilePath
| ParseGHCVariantException String
| BadStackRoot (Path Abs Dir)
| Won'tCreateStackRootInDirectoryOwnedByDifferentUser
(Path Abs Dir)
(Path Abs Dir)
-- ^ @$STACK_ROOT@, parent dir
| UserDoesn'tOwnDirectory (Path Abs Dir)
| ManualGHCVariantSettingsAreIncompatibleWithSystemGHC
| NixRequiresSystemGhc
| NoResolverWhenUsingNoProject
| NoLTSWithMajorVersion Int
| NoLTSFound
deriving (Show, Typeable)
instance Exception ConfigException where
displayException (ParseCustomSnapshotException url exception) = concat
[ "Error: [S-8981]\n"
, "Could not parse '"
, T.unpack url
, "':\n"
, Yaml.prettyPrintParseException exception
, "\nSee https://docs.haskellstack.org/en/stable/custom_snapshot/"
]
displayException (NoProjectConfigFound dir mcmd) = concat
[ "Error: [S-2206]\n"
, "Unable to find a stack.yaml file in the current directory ("
, toFilePath dir
, ") or its ancestors"
, case mcmd of
Nothing -> ""
Just cmd -> "\nRecommended action: stack " ++ T.unpack cmd
]
displayException (UnexpectedArchiveContents dirs files) = concat
[ "Error: [S-4964]\n"
, "When unpacking an archive specified in your stack.yaml file, "
, "did not find expected contents. Expected: a single directory. Found: "
, show ( map (toFilePath . dirname) dirs
, map (toFilePath . filename) files
)
]
displayException (UnableToExtractArchive url file) = concat
[ "Error: [S-2040]\n"
, "Archive extraction failed. Tarballs and zip archives are supported, \
\couldn't handle the following URL, "
, T.unpack url
, " downloaded to the file "
, toFilePath $ filename file
]
displayException (BadStackVersionException requiredRange) = concat
[ "Error: [S-1641]\n"
, "The version of Stack you are using ("
, show stackVersion
, ") is outside the required\n"
,"version range specified in stack.yaml ("
, T.unpack (versionRangeText requiredRange)
, ").\n"
, "You can upgrade Stack by running:\n\n"
, "stack upgrade"
]
displayException (NoSuchDirectory dir) = concat
[ "Error: [S-8773]\n"
, "No directory could be located matching the supplied path: "
, dir
]
displayException (ParseGHCVariantException v) = concat
[ "Error: [S-3938]\n"
, "Invalid ghc-variant value: "
, v
]
displayException (BadStackRoot stackRoot) = concat
[ "Error: [S-8530]\n"
, "Invalid Stack root: '"
, toFilePath stackRoot
, "'. Please provide a valid absolute path."
]
displayException (Won'tCreateStackRootInDirectoryOwnedByDifferentUser envStackRoot parentDir) = concat
[ "Error: [S-7613]\n"
, "Preventing creation of Stack root '"
, toFilePath envStackRoot
, "'. Parent directory '"
, toFilePath parentDir
, "' is owned by someone else."
]
displayException (UserDoesn'tOwnDirectory dir) = concat
[ "Error: [S-8707]\n"
, "You are not the owner of '"
, toFilePath dir
, "'. Aborting to protect file permissions."
, "\nRetry with '--"
, T.unpack configMonoidAllowDifferentUserName
, "' to disable this precaution."
]
displayException ManualGHCVariantSettingsAreIncompatibleWithSystemGHC = T.unpack $ T.concat
[ "Error: [S-3605]\n"
, "Stack can only control the "
, configMonoidGHCVariantName
, " of its own GHC installations. Please use '--no-"
, configMonoidSystemGHCName
, "'."
]
displayException NixRequiresSystemGhc = T.unpack $ T.concat
[ "Error: [S-6816]\n"
, "Stack's Nix integration is incompatible with '--no-system-ghc'. "
, "Please use '--"
, configMonoidSystemGHCName
, "' or disable the Nix integration."
]
displayException NoResolverWhenUsingNoProject =
"Error: [S-5027]\n"
++ "When using the script command, you must provide a resolver argument"
displayException (NoLTSWithMajorVersion n) = concat
[ "Error: [S-3803]\n"
, "No LTS release found with major version "
, show n
, "."
]
displayException NoLTSFound =
"Error: [S-5472]\n"
++ "No LTS releases found."
-- | Type representing \'pretty\' exceptions thrown by functions exported by the
-- "Stack.Config" module.
data ConfigPrettyException
= ParseConfigFileException !(Path Abs File) !ParseException
| StackWorkEnvNotRelativeDir !String
| MultiplePackageIndices [PackageIndexConfig]
| DuplicateLocalPackageNames ![(PackageName, [PackageLocation])]
deriving (Show, Typeable)
instance Pretty ConfigPrettyException where
pretty (ParseConfigFileException configFile exception) =
"[S-6602]"
<> line
<> fillSep
[ flow "Stack could not load and parse"
, pretty configFile
, flow "as a YAML configuraton file."
]
<> blankLine
<> flow "While loading and parsing, Stack encountered the following \
\error:"
<> blankLine
<> string (Yaml.prettyPrintParseException exception)
<> blankLine
<> fillSep
[ flow "For help about the content of Stack's YAML configuration \
\files, see (for the most recent release of Stack)"
, style
Url
"http://docs.haskellstack.org/en/stable/yaml_configuration/"
<> "."
]
pretty (StackWorkEnvNotRelativeDir x) =
"[S-7462]"
<> line
<> flow "Stack failed to interpret the value of the STACK_WORK \
\environment variable as a valid relative path to a directory. \
\Stack will not accept an absolute path. A path containing a \
\.. (parent directory) component is not valid."
<> blankLine
<> fillSep
[ flow "If set, Stack expects the value to identify the location \
\of Stack's work directory, relative to the root directory \
\of the project or package. Stack encountered the value:"
, style Error (fromString x) <> "."
]
pretty (MultiplePackageIndices pics) =
"[S-3251]"
<> line
<> fillSep
[ flow "When using the"
, style Shell "package-indices"
, flow "key to override the default package index, you must \
\provide exactly one value, received:"
, bulletedList (map (string . show) pics)
]
<> blankLine
<> packageIndicesWarning
pretty (DuplicateLocalPackageNames pairs) =
"[S-5470]"
<> line
<> fillSep
[ flow "The same package name is used in more than one local package or"
, style Shell "extra-deps" <> "."
]
<> mconcat (map go pairs)
where
go (name, dirs) =
blankLine
<> fillSep
[ style Error (fromString $ packageNameString name)
, flow "used in:"
]
<> line
<> bulletedList (map (fromString . T.unpack . textDisplay) dirs)
instance Exception ConfigPrettyException
data ParseAbsolutePathException
= ParseAbsolutePathException String String
deriving (Show, Typeable)
instance Exception ParseAbsolutePathException where
displayException (ParseAbsolutePathException envVar dir) = concat
[ "Error: [S-9437]\n"
, "Failed to parse "
, envVar
, " environment variable (expected absolute directory): "
, dir
]
packageIndicesWarning :: StyleDoc
packageIndicesWarning =
fillSep
[ "The"
, style Shell "package-indices"
, flow "key is deprecated in favour of"
, style Shell "package-index" <> "."
]