@@ -23,6 +23,7 @@ import Control.DeepSeq (force)
2323import Control.Exception (evaluate )
2424import Control.Monad
2525import Data.Char (isAsciiLower , isAsciiUpper , isSpace )
26+ import Data.Either (partitionEithers )
2627import qualified Data.Foldable as F
2728import Data.Function
2829import Data.List
@@ -191,6 +192,7 @@ data Options = Options
191192 , optOnlyBranches :: [String ]
192193 , optOutput :: Maybe FilePath
193194 , optRegenerate :: Maybe FilePath
195+ , optOsx :: [String ]
194196 } deriving Show
195197
196198defOptions :: Options
@@ -203,6 +205,7 @@ defOptions = Options
203205 , optOnlyBranches = []
204206 , optOutput = Nothing
205207 , optRegenerate = Nothing
208+ , optOsx = []
206209 }
207210
208211possibleFolds :: [String ]
@@ -251,6 +254,9 @@ options =
251254 , Option [' r' ] [" regerate" ]
252255 (ReqArg (\ arg opts -> opts { optRegenerate = Just arg }) " INPUTOUTPUT" )
253256 " regenerate the file using the magic command in output file"
257+ , Option [] [" osx" ]
258+ (ReqArg (\ arg opts -> opts { optOsx = arg : optOsx opts }) " GHC" )
259+ " generate osx build job with ghc version"
254260 ]
255261
256262main :: IO ()
@@ -497,6 +503,11 @@ genTravisFromConfigs (argv,opts) xpkgs isCabalProject (versions,cfg,pkgs) = do
497503 putStrLnInfo $
498504 " Generating Travis-CI config for testing for GHC versions: " ++ ghcVersions
499505
506+ unless (null $ optOsx opts) $ do
507+ putStrLnInfo $ " Also OSX jobs for: " ++ ghcOsxVersions
508+ unless (S. null omittedOsxVersions) $
509+ putStrLnWarn $ " Not all GHC versions specified with --osx are generated: " ++ ghcOmittedOsxVersions
510+
500511 ---------------------------------------------------------------------------
501512 -- travis.yml generation starts here
502513
@@ -543,7 +554,16 @@ genTravisFromConfigs (argv,opts) xpkgs isCabalProject (versions,cfg,pkgs) = do
543554 , " directories:"
544555 , " - $HOME/.cabal/packages"
545556 , " - $HOME/.cabal/store"
546- , " "
557+ ]
558+
559+ -- on OSX ghc is installed in $HOME so we can cache it
560+ -- independently of linux
561+ unless (optNoCache opts || null (optOsx opts)) $ tellStrLns
562+ [ " - $HOME/.ghc-install"
563+ ]
564+
565+ unless (optNoCache opts) $ tellStrLns
566+ [ " "
547567 , " before_cache:"
548568 , " - rm -fv $HOME/.cabal/packages/hackage.haskell.org/build-reports.log"
549569 , " # remove files that are regenerated by 'cabal update'"
@@ -560,23 +580,29 @@ genTravisFromConfigs (argv,opts) xpkgs isCabalProject (versions,cfg,pkgs) = do
560580
561581 let colls = [ (collToGhcVer cid,cid) | cid <- reverse $ optCollections opts ]
562582
563- F. forM_ versions $ \ gv -> do
564- let cvs = dispGhcVersion (lookupCabVer gv)
565- gvs = dispGhcVersion gv
583+ let tellJob osx gv = do
584+ let cvs = dispGhcVersion (lookupCabVer gv)
585+ gvs = dispGhcVersion gv
566586
567- xpkgs' = concatMap (' ,' : ) xpkgs
587+ xpkgs' = concatMap (' ,' : ) xpkgs
568588
569- colls' = [ cid | (v,cid) <- colls, v == gv ]
589+ colls' = [ cid | (v,cid) <- colls, v == gv ]
570590
571- tellStrLns
572- [ concat [ " - compiler: \" ghc-" , gvs, " \" " ]
573- , if null colls' then
574- " # env: TEST=--disable-tests BENCH=--disable-benchmarks"
575- else
576- (" env: 'COLLECTIONS=" ++ intercalate " ," colls' ++ " '" )
577- , concat [ " addons: {apt: {packages: [ghc-ppa-tools,cabal-install-" , cvs, " ,ghc-" , gvs, xpkgs', " ], sources: [hvr-ghc]}}" ]
578- ]
579- return ()
591+ tellStrLns
592+ [ concat [ " - compiler: \" ghc-" , gvs, " \" " ]
593+ , if null colls' then
594+ " # env: TEST=--disable-tests BENCH=--disable-benchmarks"
595+ else
596+ (" env: 'COLLECTIONS=" ++ intercalate " ," colls' ++ " '" )
597+ , concat [ " addons: {apt: {packages: [ghc-ppa-tools,cabal-install-" , cvs, " ,ghc-" , gvs, xpkgs', " ], sources: [hvr-ghc]}}" ]
598+ ]
599+
600+ when osx $ tellStrLns
601+ [ " os: osx"
602+ ]
603+
604+ F. forM_ versions $ tellJob False
605+ F. forM_ osxVersions $ tellJob True
580606
581607 let headGhcVers = S. filter isGhcHead versions
582608
@@ -592,9 +618,19 @@ genTravisFromConfigs (argv,opts) xpkgs isCabalProject (versions,cfg,pkgs) = do
592618 [ " "
593619 , " before_install:"
594620 , sh " HC=${CC}"
595- , " - HCPKG=${HC/ghc/ghc-pkg}"
596- , " - unset CC"
597- , " - PATH=/opt/ghc/bin:/opt/ghc-ppa-tools/bin:$PATH"
621+ , sh' [2034 ,2039 ] " HCPKG=${HC/ghc/ghc-pkg}" -- SC2039. In POSIX sh, string replacement is undefined.
622+ , sh " unset CC"
623+ ]
624+
625+ let haskellOnMacos = " https://haskell.futurice.com/haskell-on-macos.py"
626+
627+ if null (optOsx opts)
628+ then tellStrLns
629+ [ sh " PATH=/opt/ghc/bin:/opt/ghc-ppa-tools/bin:$PATH"
630+ ]
631+ else tellStrLns
632+ [ sh $ " if [ \" $(uname)\" = \" Darwin\" ]; then brew update; brew install python3; curl " ++ haskellOnMacos ++ " | python3 - --make-dirs --install-dir=$HOME/.ghc-install --cabal-alias=head install cabal-install-head ${HC}; fi"
633+ , sh $ " if [ \" $(uname)\" = \" Darwin\" ]; then PATH=$HOME/.ghc-install/ghc/bin:$PATH; else PATH=/opt/ghc/bin:/opt/ghc-ppa-tools/bin:$PATH; fi"
598634 ]
599635
600636 unless (null colls) $
@@ -749,8 +785,24 @@ genTravisFromConfigs (argv,opts) xpkgs isCabalProject (versions,cfg,pkgs) = do
749785 where
750786 quote pkg = pkg{ pkgDir = " \" " ++ pkgDir pkg ++ " \" " }
751787
788+ showVersions :: Set Version -> String
789+ showVersions = unwords . map dispGhcVersion . S. toList
790+
791+ -- specified ersions
792+ osxVersions' :: Set Version
793+ osxVersions' = S. fromList $ mapMaybe simpleParse $ optOsx opts
794+
752795 ghcVersions :: String
753- ghcVersions = unwords $ map dispGhcVersion $ S. toList $ versions
796+ ghcVersions = showVersions versions
797+
798+ osxVersions , omittedOsxVersions :: Set Version
799+ (osxVersions, omittedOsxVersions) = S. partition (`S.member` versions) osxVersions'
800+
801+ ghcOsxVersions :: String
802+ ghcOsxVersions = showVersions osxVersions
803+
804+ ghcOmittedOsxVersions :: String
805+ ghcOmittedOsxVersions = showVersions omittedOsxVersions
754806
755807 lookupCabVer :: Version -> Version
756808 lookupCabVer v = maybe (error " internal error" ) id $ lookup (x,y) cabalVerMap
0 commit comments