From 262231a8f28feb711a8b164c62d9b89bcc11df47 Mon Sep 17 00:00:00 2001 From: Daniel Gröber Date: Wed, 25 Mar 2020 18:40:15 +0100 Subject: Fix cabal projects using source-repository-package Apparently we can get source-repo-packages in plan.json even when filtering for `"style": "local"`(`UnitTypeLocal`). It's possible the root cause here is a cabal bug as source-repository-package should really be treated more like a tarball than a local package. Regardless we simply filter units by actually checking for `uPkgSrc=Just LocalUnpackedPackage` instead of relying on "style". This fixes #99 --- cabal-helper.cabal | 5 +++ scripts/ci/steps/20-sdist.sh | 6 +++ .../Compiletime/Program/CabalInstall.hs | 47 +++++++++++----------- tests/GhcSession.hs | 23 ++++++----- tests/src-repo/Exe.hs | 5 +++ tests/src-repo/Setup.hs | 2 + tests/src-repo/cabal.project | 7 ++++ tests/src-repo/packages.list | 1 + tests/src-repo/src-repo.cabal | 19 +++++++++ 9 files changed, 81 insertions(+), 34 deletions(-) create mode 100644 tests/src-repo/Exe.hs create mode 100644 tests/src-repo/Setup.hs create mode 100644 tests/src-repo/cabal.project create mode 100644 tests/src-repo/packages.list create mode 100644 tests/src-repo/src-repo.cabal diff --git a/cabal-helper.cabal b/cabal-helper.cabal index 3c24b86..6a035c4 100644 --- a/cabal-helper.cabal +++ b/cabal-helper.cabal @@ -49,6 +49,11 @@ extra-source-files: README.md tests/bkpregex/regex-types/Regex/*.hs tests/bkpregex/str-impls/Str/*.hs + tests/src-repo/*.hs + tests/src-repo/*.cabal + tests/src-repo/packages.list + tests/src-repo/cabal.project + tests/multipkg/packages.list tests/multipkg/pkg-oot/*.cabal tests/multipkg/pkg-oot/*.hs diff --git a/scripts/ci/steps/20-sdist.sh b/scripts/ci/steps/20-sdist.sh index 329aa86..8424608 100644 --- a/scripts/ci/steps/20-sdist.sh +++ b/scripts/ci/steps/20-sdist.sh @@ -12,3 +12,9 @@ if [ -d cabal-plan/ ]; then fi cd "$source_dir" + +git init +git config --local user.email "$USER@$(hostname)" +git config --local user.name "cabal-helper CI" +git add --all +git commit -m . diff --git a/src/CabalHelper/Compiletime/Program/CabalInstall.hs b/src/CabalHelper/Compiletime/Program/CabalInstall.hs index 6af8e0f..d5ed15e 100644 --- a/src/CabalHelper/Compiletime/Program/CabalInstall.hs +++ b/src/CabalHelper/Compiletime/Program/CabalInstall.hs @@ -35,7 +35,6 @@ import System.FilePath import Text.Printf import Text.Read -import Data.Map.Strict (Map) import qualified Data.Map.Strict as Map import qualified Data.Set as Set import qualified Data.Text as Text @@ -50,7 +49,7 @@ import CabalHelper.Compiletime.Process import CabalHelper.Shared.InterfaceTypes ( ChComponentName(..), ChLibraryName(..) ) import CabalHelper.Shared.Common - ( parseVer, trim, appCacheDir, panicIO ) + ( parseVer, trim, appCacheDir ) newtype CabalInstallVersion = CabalInstallVersion { cabalInstallVer :: Version } @@ -250,32 +249,33 @@ cabalV2WithGHCProgOpts = concat planPackages :: CP.PlanJson -> IO [Package ('Cabal 'CV2)] planPackages plan = do - fmap Map.elems $ - mapM mkPackage $ - groupByMap $ Map.elems $ - Map.filter ((==CP.UnitTypeLocal) . CP.uType) $ + sequence $ + Map.elems $ + Map.mapWithKey mkPackage $ + Map.mapMaybe packagesWithSourceDir $ + groupByMap $ + Map.elems $ CP.pjUnits plan where groupByMap = Map.fromListWith (<>) . map (CP.uPId &&& (:|[])) - mkPackage :: NonEmpty CP.Unit -> IO (Package ('Cabal 'CV2)) - mkPackage units@(unit :| _) = + packagesWithSourceDir units@(unit :| _) = case unit of - CP.Unit - { uPkgSrc=Just (CP.LocalUnpackedPackage pkgdir) - } -> do - cabal_file <- Cabal.complainIfNoCabalFile pkgdir =<< Cabal.findCabalFile pkgdir - let pkg = Package - { pPackageName = - let CP.PkgId (CP.PkgName pkg_name) _ = CP.uPId unit - in Text.unpack pkg_name - , pSourceDir = pkgdir - , pCabalFile = CabalFile cabal_file - , pFlags = [] - , pUnits = fmap (\u -> fixBackpackUnit u $ mkUnit pkg { pUnits = () } u) units - } - return pkg - _ -> panicIO "planPackages.mkPackage: Got non-unpacked package src!" + CP.Unit { uPkgSrc=Just (CP.LocalUnpackedPackage pkgdir) } + -> Just (pkgdir, units) + _ -> Nothing + + mkPackage :: CP.PkgId -> (FilePath, NonEmpty CP.Unit) -> IO (Package ('Cabal 'CV2)) + mkPackage (CP.PkgId (CP.PkgName pkg_name) _) (pkgdir, units) = do + cabal_file <- Cabal.complainIfNoCabalFile pkgdir =<< Cabal.findCabalFile pkgdir + let pkg = Package + { pPackageName = Text.unpack pkg_name + , pSourceDir = pkgdir + , pCabalFile = CabalFile cabal_file + , pFlags = [] + , pUnits = fmap (\u -> fixBackpackUnit u $ mkUnit pkg { pUnits = () } u) units + } + return pkg takeBackpackIndefUnitId :: CP.Unit -> Maybe CP.UnitId takeBackpackIndefUnitId CP.Unit {uId=CP.UnitId uid} @@ -307,7 +307,6 @@ planPackages plan = do mkUnit pkg u@CP.Unit { uDistDir=Just distdirv1 , uComps=comps - , uPId=CP.PkgId pkg_name _ , uId } = Unit diff --git a/tests/GhcSession.hs b/tests/GhcSession.hs index f9f4e04..d05a0a3 100644 --- a/tests/GhcSession.hs +++ b/tests/GhcSession.hs @@ -63,7 +63,7 @@ testConfigToTestSpec (TC loc _ _ _) pt = main :: IO () main = do (modProgs, args) <- testOpts =<< getArgs --- topdir <- getCurrentDirectory + topdir <- getCurrentDirectory let withEnv :: (Env => a) -> a withEnv action = @@ -107,7 +107,7 @@ main = do proj_impls = -- V2 is sorted before the others here so helper compilation always -- uses v2-build caching! - [ (Cabal CV2, newBuildProjSetup) + [ (Cabal CV2, newBuildProjSetup topdir) , (Cabal CV1, oldBuildProjSetup) , (Stack, stackProjSetup g_ver) ] @@ -130,6 +130,7 @@ main = do , TC (TN "exeintlib") (parseVer "2.0") (parseVer "0") [] , TC (TN "fliblib") (parseVer "2.0") (parseVer "0") [] , TC (TN "bkpregex") (parseVer "2.0") (parseVer "8.1") [Cabal CV2, Cabal CV1] + , TC (TN "src-repo") (parseVer "2.4") (parseVer "0") [Cabal CV2] , let multipkg_loc = TF "tests/multipkg/" "proj/" "proj/proj.cabal" in TC multipkg_loc (parseVer "1.10") (parseVer "0") [Cabal CV2, Stack] -- min Cabal lib ver -^ min GHC ver -^ @@ -428,8 +429,9 @@ oldBuildProjSetup = ProjSetupDescr "cabal-v1" $ Right $ Ex $ ProjSetupImpl , psiQEmod = id } -newBuildProjSetup :: ProjSetup0 -newBuildProjSetup = ProjSetupDescr "cabal-v2" $ Right $ Ex $ ProjSetupImpl +newBuildProjSetup :: FilePath -> ProjSetup0 +newBuildProjSetup topdir + = ProjSetupDescr "cabal-v2" $ Right $ Ex $ ProjSetupImpl { psiProjType = SCabal SCV2 , psiDistDir = \dir -> DistDirCabal SCV2 (dir "dist-newstyle") , psiProjLoc = \_cabal_file projdir -> ProjLocV2File (projdir "cabal.project") projdir @@ -440,7 +442,7 @@ newBuildProjSetup = ProjSetupDescr "cabal-v2" $ Right $ Ex $ ProjSetupImpl copyMuliPackageProject progs srcdir destdir $ \pkgsrc pkgdest -> do exists <- doesFileExist (pkgsrc "cabal.project") if exists then - copyFile (pkgsrc "cabal.project") (pkgdest "cabal.project") + writeFile (pkgdest "cabal.project") =<< replaceStrings [("${topdir}", topdir)] <$> readFile (pkgsrc "cabal.project") else addCabalProject pkgdest , psiQEmod = id @@ -525,16 +527,17 @@ cabalInstallBuiltinCabalVersion = parseVer . trim <$> readProcess (cabalProgram ?progs) ["act-as-setup", "--", "--numeric-version"] "" -normalizeOutputWithVars :: [(String, String)] -> String -> String -normalizeOutputWithVars ts str = +normalizeOutputWithVars = replaceStrings +replaceStrings :: [(String, String)] -> String -> String +replaceStrings ts str = case filter (isJust . fst) $ map (first (flip stripPrefix str)) ts of - (Just rest, replacemnet) : _ -> - replacemnet ++ normalizeOutputWithVars ts rest + (Just rest, replacement) : _ -> + replacement ++ replaceStrings ts rest _ -> cont where cont = case str of - s:ss -> s : normalizeOutputWithVars ts ss + s:ss -> s : replaceStrings ts ss [] -> [] -- --------------------------------------------------------------------- -- | Create and use a temporary directory in the system standard temporary directory. diff --git a/tests/src-repo/Exe.hs b/tests/src-repo/Exe.hs new file mode 100644 index 0000000..7655927 --- /dev/null +++ b/tests/src-repo/Exe.hs @@ -0,0 +1,5 @@ +module Main where + +import Lib + +main = print foo diff --git a/tests/src-repo/Setup.hs b/tests/src-repo/Setup.hs new file mode 100644 index 0000000..9a994af --- /dev/null +++ b/tests/src-repo/Setup.hs @@ -0,0 +1,2 @@ +import Distribution.Simple +main = defaultMain diff --git a/tests/src-repo/cabal.project b/tests/src-repo/cabal.project new file mode 100644 index 0000000..8c4d704 --- /dev/null +++ b/tests/src-repo/cabal.project @@ -0,0 +1,7 @@ +packages: . + +source-repository-package + type: git + location: ${topdir} + tag: HEAD + subdir: tests/exelib diff --git a/tests/src-repo/packages.list b/tests/src-repo/packages.list new file mode 100644 index 0000000..80e52ce --- /dev/null +++ b/tests/src-repo/packages.list @@ -0,0 +1 @@ +./ diff --git a/tests/src-repo/src-repo.cabal b/tests/src-repo/src-repo.cabal new file mode 100644 index 0000000..086a696 --- /dev/null +++ b/tests/src-repo/src-repo.cabal @@ -0,0 +1,19 @@ +name: src-repo +version: 0 +build-type: Simple +cabal-version: >=1.10 + +executable src-repo + main-is: Exe.hs + build-depends: base, exelib + default-language: Haskell2010 + +test-suite exe-test + type: exitcode-stdio-1.0 + main-is: Exe.hs + build-depends: base, exelib + +benchmark exe-bench + type: exitcode-stdio-1.0 + main-is: Exe.hs + build-depends: base, exelib -- cgit v1.2.3