3-- NB: This code deliberately avoids relying on non-standard packages
8import System.Environment
12import Distribution.PackageDescription.Parse (readPackageDescription)
13import Distribution.PackageDescription (packageDescription, testedWith)
14import Distribution.Compiler (CompilerFlavor(..))
15import Distribution.Version
16import Distribution.Text
18putStrLnErr :: String -> IO ()
19putStrLnErr m = hPutStrLn stderr ("*ERROR* " ++ m) >> exitFailure
21putStrLnWarn :: String -> IO ()
22putStrLnWarn m = hPutStrLn stderr ("*WARNING* " ++ m)
24putStrLnInfo :: String -> IO ()
25putStrLnInfo m = hPutStrLn stderr ("*INFO* " ++ m)
31 (cabfn:xpkgs) -> do genTravisFromCabalFile cabfn xpkgs
32 _ -> putStrLnErr (unlines $ [ "expected .cabal file as command-line argument"
33 , "Usage: make_travis_yml.hs <cabal-file> <extra-apt-packages...>"
35 , "Example: make_travis_yml.hs someProject.cabal alex-3.1.4 liblzma-dev > .travis.yml"
38genTravisFromCabalFile :: FilePath -> [String] -> IO ()
39genTravisFromCabalFile fn xpkgs = do
40 gpd <- readPackageDescription maxBound fn
42 let compilers = testedWith $ packageDescription $ gpd
44 let unknownComps = nub [ c | (c,_) <- compilers, c /= GHC ]
45 ghcVerConstrs = [ vc | (GHC,vc) <- compilers ]
46 ghcVerConstrs' = simplifyVersionRange $ foldr unionVersionRanges noVersion ghcVerConstrs
48 when (null compilers) $ do
49 putStrLnErr "empty or missing 'tested-with:' definition in .cabal file"
51 unless (null unknownComps) $ do
52 putStrLnWarn $ "ignoring unsupported compilers mentioned in tested-with: " ++ show unknownComps
54 when (null ghcVerConstrs) $ do
55 putStrLnErr "'tested-with:' doesn't mention any 'GHC' version"
57 when (isNoVersion ghcVerConstrs') $ do
58 putStrLnErr "'tested-with:' describes an empty version range for 'GHC'"
60 when (isAnyVersion ghcVerConstrs') $ do
61 putStrLnErr "'tested-with:' allows /any/ 'GHC' version"
63 let testedGhcVersions = filter (`withinRange` ghcVerConstrs') knownGhcVersions
65 when (null testedGhcVersions) $ do
66 putStrLnErr "no known GHC version is allowed by the 'tested-with' specification"
68 putStrLnInfo $ "Generating Travis-CI config for testing for GHC versions: " ++ (unwords $ map disp' $ testedGhcVersions)
70 ----------------------------------------------------------------------------
71 -- travis.yml generation starts here
73 putStrLn "# This file has been generated -- see https://github.com/hvr/multi-ghc-travis"
74 putStrLn "language: c"
75 putStrLn "sudo: false"
78 putStrLn " directories:"
79 putStrLn " - $HOME/.cabsnap"
80 putStrLn " - $HOME/.cabal/packages"
82 putStrLn "before_cache:"
83 putStrLn " - rm -fv $HOME/.cabal/packages/hackage.haskell.org/build-reports.log"
84 putStrLn " - rm -fv $HOME/.cabal/packages/hackage.haskell.org/00-index.tar"
89 forM_ testedGhcVersions $ \gv -> do
90 let cvs = disp' (lookupCabVer gv)
92 ghcopts = if gv >= Version [7,10,0] []
96 xpkgs' = concatMap (',':) xpkgs
98 putStrLn $ concat [ " - env: CABALVER=", cvs, " GHCVER=", gvs,
100 putStrLn $ concat [ " compiler: \": #GHC ", gvs, "\"" ]
101 putStrLn $ concat [ " addons: {apt: {packages: [cabal-install-", cvs, ",ghc-", gvs, xpkgs'
102 , "], sources: [hvr-ghc]}}" ]
105 let headGhcVers = filter isHead testedGhcVersions
107 unless (null headGhcVers) $ do
109 putStrLn " allow_failures:"
111 forM_ headGhcVers $ \gv -> do
112 let cvs = disp' (lookupCabVer gv)
114 putStrLn $ concat [ " - env: CABALVER=", cvs, " GHCVER=", gvs ]
117 putStrLn "before_install:"
118 putStrLn " - unset CC"
119 putStrLn " - export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$PATH"
125 , " - cabal --version"
126 , " - echo \"$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || echo '?')]\""
127 , " - if [ -f $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz ];"
129 , " zcat $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz >"
130 , " $HOME/.cabal/packages/hackage.haskell.org/00-index.tar;"
132 , " - travis_retry cabal update -v"
133 , " - sed -i 's/^jobs:/-- jobs:/' ${HOME}/.cabal/config"
134 , " - cabal install --only-dependencies --enable-tests --enable-benchmarks --dry -v > installplan.txt"
135 , " - sed -i -e '1,/^Resolving /d' installplan.txt; cat installplan.txt"
137 , "# check whether current requested install-plan matches cached package-db snapshot"
138 , " - if diff -u installplan.txt $HOME/.cabsnap/installplan.txt;"
140 , " echo \"cabal build-cache HIT\";"
142 , " cp -a $HOME/.cabsnap/ghc $HOME/.ghc;"
143 , " cp -a $HOME/.cabsnap/lib $HOME/.cabsnap/share $HOME/.cabsnap/bin $HOME/.cabal/;"
145 , " echo \"cabal build-cache MISS\";"
146 , " rm -rf $HOME/.cabsnap;"
147 , " mkdir -p $HOME/.ghc $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin;"
148 , " cabal install --only-dependencies --enable-tests --enable-benchmarks;"
151 , "# snapshot package-db on cache miss"
152 , " - if [ ! -d $HOME/.cabsnap ];"
154 , " echo \"snapshotting package-db to build-cache\";"
155 , " mkdir $HOME/.cabsnap;"
156 , " cp -a $HOME/.ghc $HOME/.cabsnap/ghc;"
157 , " cp -a $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin installplan.txt $HOME/.cabsnap/;"
160 , "# Here starts the actual work to be performed for the package under test;"
161 , "# any command which exits with a non-zero exit code causes the build to fail."
163 , " - if [ -f configure.ac ]; then autoreconf -i; fi"
164 , " - cabal configure --enable-tests --enable-benchmarks -v2 # -v2 provides useful information for debugging"
165 , " - cabal build --ghc-options=$GHCOPTS # this builds all libraries and executables (including tests/benchmarks)"
168 , "# Test that a source-distribution can be generated"
169 , "# (with cabal >= 1.18 'cabal sdist' would work too):"
170 , " - ./dist/setup/setup sdist"
172 , "# Check that the resulting source distribution can be built & installed."
173 , "# If there are no other `.tar.gz` files in `dist`, this can be even simpler:"
174 , "# `cabal install --force-reinstalls dist/*-*.tar.gz`"
175 , " - SRC_TGZ=$(cabal info . | awk '{print $2;exit}').tar.gz &&"
176 , " (cd dist && cabal install --force-reinstalls \"$SRC_TGZ\")"
183 knownGhcVersions :: [Version]
184 knownGhcVersions = fmap (`Version` [])
185 [ [7,0,1], [7,0,2], [7,0,3], [7,0,4]
188 , [7,6,1], [7,6,2], [7,6,3]
189 , [7,8,1], [7,8,2], [7,8,3], [7,8,4]
194 lookupCabVer :: Version -> Version
195 lookupCabVer (Version (x:y:_) _) = maybe (error "internal error") id $ lookup (x,y) cabalVerMap
197 cabalVerMap = fmap (fmap (`Version` []))
204 , ((7,11), [1,23]) -- HEAD
207 isHead (Version (_:y:_) _) = odd (y :: Int)
209 disp' v | isHead v = "head"
210 | otherwise = display v
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list