Skip to content

Commit

Permalink
Better messages for invalid cabal file names #895
Browse files Browse the repository at this point in the history
  • Loading branch information
snoyberg committed Sep 2, 2015
1 parent 154fd25 commit 7153be8
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 13 deletions.
1 change: 1 addition & 0 deletions ChangeLog.md
Expand Up @@ -29,6 +29,7 @@ Bug fixes:
* `stack solver` and `stack init --solver` check for test suite and benchmark dependencies [#862](https://github.com/commercialhaskell/stack/issues/862)
* More intelligent logic for setting UTF-8 locale environment variables [#856](https://github.com/commercialhaskell/stack/issues/856)
* Create missing directories for `stack sdist`
* Don't ignore .cabal files with extra periods [#895](https://github.com/commercialhaskell/stack/issues/895)

## 0.1.3.1

Expand Down
5 changes: 2 additions & 3 deletions src/Stack/Build/Source.hs
Expand Up @@ -226,9 +226,8 @@ getLocalPackageViews = do
cabalfp <- getCabalFileName dir
gpkg <- readPackageUnresolved cabalfp
let cabalID = package $ packageDescription gpkg
name <- parsePackageNameFromFilePath cabalfp
when (fromCabalPackageName (pkgName $ cabalID) /= name)
$ throwM $ MismatchedCabalName cabalfp name
name = fromCabalPackageName $ pkgName $ cabalID
checkCabalFileName name cabalfp
let lpv = LocalPackageView
{ lpvVersion = fromCabalVersion $ pkgVersion cabalID
, lpvRoot = dir
Expand Down
20 changes: 15 additions & 5 deletions src/Stack/Package.hs
Expand Up @@ -30,7 +30,8 @@ module Stack.Package
,packageToolDependencies
,packageDependencies
,packageIdentifier
,autogenDir)
,autogenDir
,checkCabalFileName)
where

import Control.Exception hiding (try,catch)
Expand Down Expand Up @@ -133,11 +134,20 @@ readPackageDir :: (MonadLogger m, MonadIO m, MonadThrow m, MonadCatch m)
readPackageDir packageConfig dir = do
cabalfp <- getCabalFileName dir
pkg <- readPackage packageConfig cabalfp
name <- parsePackageNameFromFilePath cabalfp
when (packageName pkg /= name)
$ throwM $ MismatchedCabalName cabalfp name
checkCabalFileName (packageName pkg) cabalfp

return (cabalfp, pkg)

-- | Check if the given name in the @Package@ matches the name of the .cabal file
checkCabalFileName :: MonadThrow m => PackageName -> Path Abs File -> m ()
checkCabalFileName name cabalfp = do
-- Previously, we just use parsePackageNameFromFilePath. However, that can
-- lead to confusing error messages. See:
-- https://github.com/commercialhaskell/stack/issues/895
let expected = packageNameString name ++ ".cabal"
when (expected /= toFilePath (filename cabalfp))
$ throwM $ MismatchedCabalName cabalfp name

-- | Resolve a parsed cabal file into a 'Package'.
resolvePackage :: PackageConfig
-> GenericPackageDescription
Expand Down Expand Up @@ -922,7 +932,7 @@ getCabalFileName pkgDir = do
[] -> throwM $ PackageNoCabalFileFound pkgDir
[x] -> return x
_:_ -> throwM $ PackageMultipleCabalFilesFound pkgDir files
where hasExtension fp x = FilePath.takeExtensions fp == "." ++ x
where hasExtension fp x = FilePath.takeExtension fp == "." ++ x

-- | Path for the package's build log.
buildLogPath :: (MonadReader env m, HasBuildConfig env, MonadThrow m)
Expand Down
7 changes: 5 additions & 2 deletions src/Stack/Types/Package.hs
Expand Up @@ -63,10 +63,13 @@ instance Show PackageException where
": " ++
intercalate ", " (map (toFilePath . filename) files)
show (MismatchedCabalName fp name) = concat
[ "cabal file "
[ "cabal file path "
, toFilePath fp
, " has a mismatched package name: "
, " does not match the package name it defines.\n"
, "Please rename the file to: "
, packageNameString name
, ".cabal\n"
, "For more information, see: https://github.com/commercialhaskell/stack/issues/317"
]

-- | Some package info.
Expand Down
11 changes: 8 additions & 3 deletions src/Stack/Types/PackageName.hs
Expand Up @@ -52,11 +52,13 @@ import qualified Options.Applicative as O
data PackageNameParseFail
= PackageNameParseFail ByteString
| CabalFileNameParseFail FilePath
| CabalFileNameInvalidPackageName FilePath
deriving (Typeable)
instance Exception PackageNameParseFail
instance Show PackageNameParseFail where
show (PackageNameParseFail bs) = "Invalid package name: " ++ show bs
show (CabalFileNameParseFail fp) = "Invalid file path for cabal file: " ++ fp
show (CabalFileNameParseFail fp) = "Invalid file path for cabal file, must have a .cabal extension: " ++ fp
show (CabalFileNameInvalidPackageName fp) = "cabal file names must use valid package names followed by a .cabal extension, the following is invalid: " ++ fp

-- | A package name.
newtype PackageName =
Expand Down Expand Up @@ -138,8 +140,11 @@ toCabalPackageName (PackageName name) =

-- | Parse a package name from a file path.
parsePackageNameFromFilePath :: MonadThrow m => Path a File -> m PackageName
parsePackageNameFromFilePath fp =
clean (toFilePath (filename fp)) >>= parsePackageNameFromString
parsePackageNameFromFilePath fp = do
base <- clean $ toFilePath $ filename fp
case parsePackageNameFromString base of
Nothing -> throwM $ CabalFileNameInvalidPackageName $ toFilePath fp
Just x -> return x
where clean = liftM reverse . strip . reverse
strip ('l':'a':'b':'a':'c':'.':xs) = return xs
strip _ = throwM (CabalFileNameParseFail (toFilePath fp))
Expand Down

0 comments on commit 7153be8

Please sign in to comment.