packages feed

stack-all (empty) → 0.1

raw patch · 5 files changed

+252/−0 lines, 5 filesdep +basedep +config-inidep +directory

Dependencies added: base, config-ini, directory, extra, filepath, process, simple-cmd, simple-cmd-args, text

Files

+ ChangeLog.md view
@@ -0,0 +1,5 @@+# Revision history for stack-all++## 0.1.0 -- 2020-11-14+- initial release with --create-config, --debug, --cmd, --newest+- VersionSpec: --all-lts, --oldest, and lts args
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2020, Jens Petersen++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Jens Petersen nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Main.hs view
@@ -0,0 +1,141 @@+{-# LANGUAGE OverloadedStrings #-}++import Control.Monad.Extra+import Data.Ini.Config+import Data.List.Extra+import qualified Data.Text.IO as T+import SimpleCmd+import SimpleCmdArgs+import System.Directory+import System.Exit+import System.FilePath+import System.IO+import System.Process++import Paths_stack_all (version)++-- FIXME allow specific snapshots?+-- FIXME lts latest+data Snapshot = LTS Int | Nightly+  deriving (Eq, Ord)++readSnap :: String -> Snapshot+readSnap "nightly" = Nightly+readSnap snap =+  if "lts" `isPrefixOf` snap then+    let major = read (dropPrefix "lts-" snap) in LTS major+  else error' $ "malformed snapshot " ++ snap++showSnap :: Snapshot -> String+showSnap Nightly = "nightly"+showSnap (LTS ver) = "lts-" ++ show ver++defaultOldest :: Snapshot+defaultOldest = LTS 11++allSnaps :: [Snapshot]+allSnaps = [Nightly, LTS 16, LTS 14, LTS 13, LTS 12, LTS 11,+            LTS 10, LTS 9, LTS 8, LTS 6, LTS 5, LTS 4, LTS 2, LTS 1]++data VersionSpec = DefaultVersions | Oldest Snapshot | AllVersions | VersionList [Snapshot]++main :: IO ()+main = do+  hSetBuffering stdout NoBuffering+  unlessM (doesFileExist "stack.yaml") $+    error' "no stack.yaml found"+  simpleCmdArgs (Just version) "Build over Stackage versions"+    "stack-all builds projects easily across different Stackage versions" $+    main' <$>+    switchWith 'c' "create-config" "Create a project .stack-all file" <*>+    switchWith 'd' "debug" "Verbose stack build output on error" <*>+    optional (readSnap <$> strOptionWith 'n' "newest" "lts-MAJOR" "Newest LTS release to build from") <*>+    optional (strOptionWith 'C' "cmd" "COMMAND" "Specify a stack command [default: build]") <*>+    versionSpec+  where+    versionSpec =+      Oldest . readSnap <$> strOptionWith 'o' "oldest" "lts-MAJOR" "Oldest compatible LTS release" <|>+      VersionList . map readSnap <$> some (strArg "LTS") <|>+      flagWith DefaultVersions AllVersions 'a' "all-lts" "Try to build back to LTS 1 even"++main' :: Bool -> Bool -> Maybe Snapshot -> Maybe String -> VersionSpec -> IO ()+main' createConfig debug mnewest mcmd versionSpec = do+  if createConfig then+    case versionSpec of+      Oldest oldest -> createStackAll oldest+      _ -> error' "creating .stack-all requires --oldest LTS"+    else do+    versions <-+      case versionSpec of+        DefaultVersions -> do+          oldest <- fromMaybeM (return defaultOldest) getOldestLTS+          return $ filter (>= oldest) allSnaps+        AllVersions -> return allSnaps+        Oldest ver -> return $ filter (>= ver) allSnaps+        VersionList vers -> return vers+    configs <- filter isStackConf <$> listDirectory "."+    let newestFilter = maybe id (filter . (>=)) mnewest+    mapM_ (stackBuild configs debug mcmd) (newestFilter versions)+  where+    isStackConf :: FilePath -> Bool+    isStackConf f = "stack-" `isPrefixOf` f && "yaml" `isExtensionOf` f++stackAllFile :: FilePath+stackAllFile = ".stack-all"++createStackAll :: Snapshot -> IO ()+createStackAll snap = do+  exists <- doesFileExist stackAllFile+  if exists then error' $ stackAllFile ++ " already exists"+    else do+    writeFile stackAllFile $+      "[versions]\n# reason comment\noldest = " ++ showSnap snap ++ "\n"++getOldestLTS :: IO (Maybe Snapshot)+getOldestLTS = do+  haveConfig <- doesFileExist stackAllFile+  if haveConfig then+    Just . readSnap <$> readIniConfig stackAllFile rcParser id+    else return Nothing+  where+    rcParser :: IniParser String+    rcParser =+      section "versions" $+      fieldOf "oldest" string++    readIniConfig :: FilePath -> IniParser a -> (a -> b) -> IO b+    readIniConfig inifile iniparser fn = do+      ini <- T.readFile inifile+      return $ either error fn $ parseIniFile ini iniparser++stackBuild :: [FilePath] -> Bool -> Maybe String -> Snapshot -> IO ()+stackBuild configs debug mcmd snap = do+  let command = maybe ["build"] words mcmd+      config =+        case sort (filter (snapConfig <=) configs) of+          [] -> []+          (cfg:_) -> ["--stack-yaml", cfg]+      args = ["-v" | debug] ++ ["--resolver", showSnap snap] +++             config ++ command+  if debug+    then debugBuild args+    else cmd_ "stack" args+  putStrLn ""+  where+    snapConfig :: FilePath+    snapConfig = "stack-" ++ compactSnap snap <.> "yaml"+      where+        compactSnap :: Snapshot -> String+        compactSnap Nightly = "nightly"+        compactSnap (LTS ver) = "lts" ++ show ver++    debugBuild :: [String] -> IO ()+    debugBuild args = do+      putStr $ "stack " ++ unwords args+      (ret,out,err) <- readProcessWithExitCode "stack" args ""+      putStrLn "\n"+      unless (null out) $ putStrLn out+      unless (ret == ExitSuccess) $ do+        -- stack verbose includes info line with all stackages (> 500kbytes)+        mapM_ putStrLn $ filter ((<10000) . length) . lines $ err+        error' $ showSnap snap ++ " build failed"
+ README.md view
@@ -0,0 +1,28 @@+# stack-all++A CLI tool for building Haskell projects easily over Stackage major versions.++This is how I do my Haskell "build ci" now locally.++## Usage++`stack-all` runs `stack build` over recent Stackage LTS major versions+and Nightly: by default currently: nightly, lts-16, ..., lts-11.++Note that stack-all will automatically use `stack-ltsXX.yaml`, even for older lts releases: eg say you have `stack-lts13.yaml` in your project, then it will also be used for building lts-12 (unless you have a `stack-lts12.yaml` config file of course).++You can specify the oldest working LTS for a project with `stack-all -o lts-13` or set it in a `.stack-all` file containing:+```+[versions]+# lts-12 foo-bar too old+oldest = lts-13+```+which can be created with `stack-all -c -o lts-13`.++Happy stack building!++## Install+Run `stack install` or `cabal install` in the source.++## Contribute+See https://github.com/juhp/stack-all
+ stack-all.cabal view
@@ -0,0 +1,48 @@+name:                stack-all+version:             0.1+synopsis:            CLI tool for building across Stackage major versions+description:+        Build your Haskell project over Stackage major versions.+license:             BSD3+license-file:        LICENSE+author:              Jens Petersen <juhpetersen@gmail.com>+maintainer:          Jens Petersen <juhpetersen@gmail.com>+copyright:           2020  Jens Petersen <juhpetersen@gmail.com>+category:            Distribution+homepage:            https://github.com/juhp/stack-all+bug-reports:         https://github.com/juhp/stack-all/issues+build-type:          Simple+extra-doc-files:     README.md+                     ChangeLog.md+cabal-version:       1.18+tested-with:         GHC == 8.4.4, GHC == 8.6.5,  GHC == 8.8.4, GHC == 8.10.2++source-repository head+  type:                git+  location:            https://github.com/juhp/stack-all.git++executable stack-all+  main-is:             Main.hs+  other-modules:       Paths_stack_all+  build-depends:       base < 5,+                       config-ini,+                       directory,+                       extra >= 1.6.15,+                       filepath,+                       process,+                       simple-cmd >= 0.1.4,+                       simple-cmd-args,+                       text+  default-language:    Haskell2010+  ghc-options:         -Wall+  if impl(ghc >= 8.0)+    ghc-options:       -Wcompat+                       -Widentities+                       -Wincomplete-uni-patterns+                       -Wincomplete-record-updates+                       -Wredundant-constraints+  if impl(ghc >= 8.2)+    ghc-options:       -fhide-source-paths+  if impl(ghc >= 8.4)+    ghc-options:       -Wmissing-export-lists+                       -Wpartial-fields