stack-all 0.6.4 → 0.7
raw patch · 6 files changed
+270/−133 lines, 6 files
Files
- ChangeLog.md +11/−0
- README.md +36/−25
- src/Main.hs +127/−94
- src/MajorVer.hs +14/−6
- src/StackYaml.hs +79/−5
- stack-all.cabal +3/−3
ChangeLog.md view
@@ -1,5 +1,16 @@ # Release history for stack-all +## 0.7 (2025-05-25)+- complete rework of stack*.yaml config file logic+- add --stack option to specify stack program (eg stack-2)+- support "snapshot:" as well as "resolver:"+- add -S,--make-all-lts flag (pbrisbin,#4)+- bump default oldest major version from LTS 18 to 20+- error for lts11 with stack > 3+- fix --update-resolver for nightly snapshot+- change --default-resolver short option from -d to -r+- add ghc9.8 alias for lts23+ ## 0.6.4 (2024-10-13) - Fix the missing stack.yaml logic to first check for a .cabal file before trying parent directory
README.md view
@@ -8,8 +8,7 @@ ## Usage `stack-all` by default runs `stack build` over Stackage Nightly and-LTS major versions-(the current default range is nightly & major LTS versions back to lts-18)+LTS major versions (the current default range is LTS versions back to lts-20) corresponding to latest major ghc minor versions, using appropriate stack `--resolver` options. @@ -19,24 +18,26 @@ Of course it may still fail to build, but this allows for quick attempts to build a package that does not include a stack.yaml file. -Since 0.6, stack-all also works outside projects, like stack itself does.+Since 0.6, stack-all also works outside projects, like stack itself does+(for commands that do not need a project). ### Help output `$ stack-all --version` ```-0.6.4+0.7 ``` `$ stack-all --help` ``` Build project over Stackage major versions -Usage: stack-all [--version] [-k|--keep-going] [-D|--debug] [--refresh-cache] - [-n|--newest MAJOR] [(-o|--oldest MAJOR) | (-a|--all-lts)] - [(-c|--create-config) | (-d|--default-resolver MAJOR) | - (-u|--update-resolver) | (-s|--make-lts MAJOR) | - [MAJORVER... COMMAND...]]+Usage: stack-all [--version] [-k|--keep-going] [-D|--debug] [--refresh-cache]+ [--stack STACKPROG] [-n|--newest MAJOR]+ [(-o|--oldest MAJOR) | (-a|--all-lts)]+ [(-c|--create-config) | (-r|--default-resolver MAJOR) |+ (-u|--update-resolver) | (-s|--make-lts MAJOR) |+ (-S|--make-all-lts) | [MAJORVER... COMMAND...]] https://github.com/juhp/stack-all#readme @@ -46,14 +47,16 @@ -k,--keep-going Keep going even if an LTS fails -D,--debug Verbose stack build output on error --refresh-cache Force refresh of stackage snapshots.json cache+ --stack STACKPROG stack program [default: "stack"] -n,--newest MAJOR Newest LTS release to build from -o,--oldest MAJOR Oldest compatible LTS release -a,--all-lts Try to build back to LTS 1 even -c,--create-config Create a project .stack-all file- -d,--default-resolver MAJOR+ -r,--default-resolver MAJOR Set stack.yaml resolver -u,--update-resolver Update stack.yaml resolver -s,--make-lts MAJOR Create a stack-ltsXX.yaml file+ -S,--make-all-lts Create all stack-ltsXX.yaml files ``` ### Overriding stack.yaml@@ -63,11 +66,11 @@ older LTS major versions until another `stack-ltsYY.yaml` file is found. `stack-nightly.yaml` is also supported, but used only for nightly. -For example if you have `stack-lts20.yaml` and `stack-lts18.yaml` files+For example if you have `stack-lts22.yaml` and `stack-lts20.yaml` files in your project,-then `stack.yaml` will be used as normal to build nightly, lts-22 and lts-21,-but `stack-lts20.yaml` will be used for building lts-20 and lts-19,-and `stack-lts18.yaml` will be used for lts-18, lts-16 (and older).+then `stack.yaml` will be used as normal to build nightly and lts-23,+but `stack-lts22.yaml` will be used for building lts-22 and lts-21,+and `stack-lts20.yaml` will be used for lts-20 (and older). Since `stack-all` overrides the exact resolver with the latest minor snapshot, the exact minor Stackage version specified in the `stack*.yaml` files doesn't actually matter: `stack-all` always uses the latest published@@ -79,39 +82,47 @@ (Other versioned stack.yaml filenames like stack-ghc-8.8.yaml are not currently supported.) +If you wish you can create `stack-ltsXX.yaml` for all lts versions using+`--make-all-lts` (`-S`), but it is recommended to create only needed files.++Since 0.7, a `stack-ltsXX.yaml` conflicting (overlapping in major version)+with `stack.yaml` gives an error, and stack-all will also refuse to generate+such a file.+ ### Specifying LTS versions You can abbreviate `lts-XX` args to `ltsXX` on the commandline. `lts` is also accepted and resolves to the latest major LTS version. -You can also use ghc major version aliases:-eg `ghc9.6` corresponds to `lts22` or `ghc-9.2` to `lts-20`.+You can also use (hardcoded) ghc major version aliases:+eg `ghc9.8` corresponds to `lts23` or `ghc-9.2` to `lts-20`,+though not for `nightly` currently. There are `--oldest` and `--newest` options to specify the range of lts versions to build over: -You can specify the oldest major LTS to build for with eg `stack-all -o lts16`.-Otherwise if not configured the default oldest LTS is currently `lts-18`.+You can specify the oldest major LTS to build for with eg `stack-all -o lts18`.+Otherwise if not configured the default oldest LTS is currently `lts-20`. Similarly you can specify the newest LTS version to build from with-eg `stack-all -n lts20`. (The default is to build from nightly.)+eg `stack-all -n lts21`. (The default is to build from nightly.) Alternatively, one can give one or more explicit LTS major versions to build-for as arguments: eg `stack-all lts19` if you only wish to build that version.+for as arguments: eg `stack-all lts22` if you only wish to build that version. ### Configuring the oldest and/or newest LTS to build You can configure the oldest working LTS major version for your project-by running for example `stack-all -c -o lts-19` which generates a `.stack-all`+by running for example `stack-all -c -o lts-21` which generates a `.stack-all` project config file like this: ``` [versions]-# lts-18 too old-oldest = lts-19+# lts-20 too old+oldest = lts-21 ``` (the comment line can be used to document why the older LTS doesn't work).-This specifies that the oldest LTS version to build for is lts-19.+This specifies that the oldest LTS version to build for is lts-21. The newest LTS to build with stack-all can similarly be configured:-`stack-all -c -n lts21` or setting `newest = lts-21`.+`stack-all -c -n lts22` or inserting `newest = lts-22`. ### Running other stack commands By default `stack-all` just runs the stack `build` command over
src/Main.hs view
@@ -1,16 +1,27 @@-{-# LANGUAGE OverloadedStrings, CPP #-}+{-# LANGUAGE BangPatterns, OverloadedStrings, CPP #-} -import Control.Monad.Extra+import Control.Monad.Extra (unless, unlessM, when, whenJustM, (||^)) import Data.Either import Data.Ini.Config-import Data.List.Extra-import Data.Maybe+import Data.List.Extra -- not explicit to avoid awkward CPP+import Data.Maybe (fromMaybe, listToMaybe) import Data.Tuple (swap)-import SimpleCmd+import Data.Version.Extra+import SimpleCmd ((+-+), cmdBool, cmd, cmd_, error',+#if MIN_VERSION_simple_cmd(0,2,4)+ fileWithExtension+#endif+ ) import SimpleCmdArgs-import System.Directory+import System.Directory (copyFile, doesFileExist, getCurrentDirectory,+#if !MIN_VERSION_simple_cmd(0,2,4)+ listDirectory,+#endif+ setCurrentDirectory, withCurrentDirectory) import System.Exit-import System.FilePath+#if !MIN_VERSION_simple_cmd(0,2,4)+import System.FilePath -- not explicit to avoid awkward CPP+#endif import System.IO import System.Process import qualified Data.Text.IO as T@@ -18,10 +29,10 @@ import MajorVer import Paths_stack_all (version) import Snapshots-import StackYaml (readStackYaml)+import StackYaml defaultOldestLTS :: MajorVer-defaultOldestLTS = LTS 18+defaultOldestLTS = LTS 20 data VersionLimit = DefaultLimit | Oldest MajorVer | AllVersions @@ -29,6 +40,7 @@ | SetDefaultResolver MajorVer | UpdateDefaultResolver | MakeStackLTS MajorVer+ | MakeAllLTS | RunCmd [String] deriving Eq @@ -41,22 +53,21 @@ <$> switchWith 'k' "keep-going" "Keep going even if an LTS fails" <*> switchWith 'D' "debug" "Verbose stack build output on error" <*> switchLongWith "refresh-cache" "Force refresh of stackage snapshots.json cache"+ <*> strOptionalLongWith "stack" "STACKPROG" "stack program to use" "stack" <*> optional (readMajor <$> strOptionWith 'n' "newest" "MAJOR" "Newest LTS release to build from") <*> (Oldest . readMajor <$> strOptionWith 'o' "oldest" "MAJOR" "Oldest compatible LTS release" <|> flagWith DefaultLimit AllVersions 'a' "all-lts" "Try to build back to LTS 1 even") <*> (flagWith' CreateConfig 'c' "create-config" "Create a project .stack-all file" <|>- (SetDefaultResolver . readMajor <$> strOptionWith 'd' "default-resolver" "MAJOR" ("Set" +-+ stackYaml +-+ "resolver")) <|>+ (SetDefaultResolver . readMajor <$> strOptionWith 'r' "default-resolver" "MAJOR" ("Set" +-+ stackYaml +-+ "resolver")) <|> flagWith' UpdateDefaultResolver 'u' "update-resolver" ("Update" +-+ stackYaml +-+ "resolver") <|> (MakeStackLTS . readMajor <$> strOptionWith 's' "make-lts" "MAJOR" "Create a stack-ltsXX.yaml file") <|>+ flagWith' MakeAllLTS 'S' "make-all-lts" "Create all stack-ltsXX.yaml files" <|> RunCmd <$> many (strArg "MAJORVER... COMMAND...")) -stackYaml :: FilePath-stackYaml = "stack.yaml"--run :: Bool ->Bool -> Bool -> Maybe MajorVer -> VersionLimit -> Command- -> IO ()-run keepgoing debug refresh mnewest verlimit com = do+run :: Bool ->Bool -> Bool -> FilePath -> Maybe MajorVer -> VersionLimit+ -> Command -> IO ()+run keepgoing debug refresh stack mnewest verlimit com = do whenJustM findStackProjectDir setCurrentDirectory case com of CreateConfig ->@@ -65,12 +76,15 @@ _ -> createStackAll Nothing mnewest SetDefaultResolver ver -> stackDefaultResolver $ Just ver UpdateDefaultResolver -> stackDefaultResolver Nothing- MakeStackLTS ver -> makeStackLTS refresh ver+ MakeStackLTS ver -> makeStackLTS False refresh ver+ MakeAllLTS -> do+ vers <- determineVersions mnewest verlimit []+ mapM_ (makeStackLTS (length vers > 1) refresh) vers RunCmd verscmd -> do- (versions, cargs) <- getVersionsCmd verscmd+ (versions, cargs) <- getVersionsAndCmd verscmd configs <- readStackConfigs- let newestFilter = maybe id (filter . (>=)) mnewest- mapM_ (runStack configs keepgoing debug refresh $ if null cargs then ["build"] else cargs) (newestFilter versions)+ let finalvers = maybe id (filter . (>=)) mnewest versions+ mapM_ (runStack configs keepgoing debug refresh stack $ if null cargs then ["build"] else cargs) finalvers where findStackProjectDir :: IO (Maybe FilePath) findStackProjectDir = do@@ -88,7 +102,7 @@ putStrLn $ "creating" +-+ stackYaml +-+ "in" +-+ cwdir -- FIXME take suggested extra-deps into stack.yaml -- FIXME stack init content too verbose- unlessM (cmdBool "stack" ["init"]) $ do+ unlessM (cmdBool stack ["init"]) $ do snap <- latestLtsSnapshot refresh writeFile stackYaml $ "resolver: " ++ snap ++ "\n" return $ Just cwdir@@ -99,50 +113,50 @@ putStrLn "no package/project found" return Nothing - getVersionsCmd :: [String] -> IO ([MajorVer],[String])- getVersionsCmd verscmd = do+ getVersionsAndCmd :: [String] -> IO ([MajorVer],[String])+ getVersionsAndCmd verscmd = do let partitionMajors = swap . partitionEithers . map eitherReadMajorAlias (verlist,cmds) = partitionMajors verscmd- allMajors <- getMajorVers- versions <-- if null verlist then+ versions <- determineVersions mnewest verlimit verlist+ return (versions,cmds)++inRange :: MajorVer -> MajorVer -> MajorVer -> Bool+inRange newest oldest v = v >= oldest && v <= newest++determineVersions :: Maybe MajorVer -> VersionLimit -> [MajorVerAlias]+ -> IO [MajorVer]+determineVersions mnewest verlimit verlist = do+ if null verlist then do+ allMajors <- getMajorVers case verlimit of DefaultLimit -> do- (newestLTS, oldestLTS) <- readNewestOldestLTS- return $ case mnewest of- Just newest ->- if newest < oldestLTS- then filter (inRange newest (LTS 1)) allMajors- else filter (inRange newest oldestLTS) allMajors- Nothing -> filter (inRange newestLTS oldestLTS) allMajors+ (newestLTS, oldestLTS) <- readNewestOldestLTS mnewest+ return $+ case mnewest of+ Just newest ->+ if newest < oldestLTS+ then filter (inRange newest (LTS 1)) allMajors+ else filter (inRange newest oldestLTS) allMajors+ Nothing -> filter (inRange newestLTS oldestLTS) allMajors AllVersions -> return allMajors- Oldest ver -> return $ filter (inRange Nightly ver) allMajors+ Oldest ver ->+ return $+ filter (inRange (fromMaybe Nightly mnewest) ver) allMajors else nub <$> mapM resolveMajor verlist- return (versions,cmds)- where- inRange :: MajorVer -> MajorVer -> MajorVer -> Bool- inRange newest oldest v = v >= oldest && v <= newest -readStackConfigs :: IO [MajorVer]-readStackConfigs = do- sort . mapMaybe readStackConf <$> listDirectory "."- where- readStackConf :: FilePath -> Maybe MajorVer- readStackConf "stack-lts.yaml" =- error' "unversioned stack-lts.yaml is unsupported"- readStackConf f =- stripPrefix "stack-" f >>= stripSuffix ".yaml" >>= readCompactMajor--readNewestOldestLTS :: IO (MajorVer,MajorVer)-readNewestOldestLTS = do+readNewestOldestLTS :: Maybe MajorVer -> IO (MajorVer,MajorVer)+readNewestOldestLTS mnewest = do haveConfig <- doesFileExist stackAllFile if haveConfig then readIniConfig stackAllFile $ section "versions" $ do- mnewest <- fmap readMajor <$> fieldMbOf "newest" string- moldest <- fmap readMajor <$> fieldMbOf "oldest" string- return (fromMaybe Nightly mnewest, fromMaybe defaultOldestLTS moldest)- else return (Nightly, defaultOldestLTS)+ mnewest' <-+ case mnewest of+ Nothing -> fmap readMajor <$> fieldMbOf "newest" string+ _ -> return mnewest+ moldest' <- fmap readMajor <$> fieldMbOf "oldest" string+ return (fromMaybe Nightly mnewest', fromMaybe defaultOldestLTS moldest')+ else return (fromMaybe Nightly mnewest, defaultOldestLTS) where readIniConfig :: FilePath -> IniParser a -> IO a readIniConfig inifile iniparser = do@@ -175,71 +189,90 @@ in maybe "" (\s -> showMajor s ++ " too old") molder in "# " ++ older ++ "\noldest = " ++ showMajor oldest ++ "\n" +updateResolver :: String -> FilePath -> IO ()+updateResolver snapshot stackfile =+ cmd_ "sed" ["-i", "-e", "s/\\(resolver:\\|snapshot:\\) .*/\\1 " ++ snapshot ++ "/", stackfile]+ stackDefaultResolver :: Maybe MajorVer -> IO () stackDefaultResolver mver = do unlessM (doesFileExist stackYaml) $ error' $ "no" +-+ stackYaml +-+ "present" case mver of Nothing -> do- mdef <- readStackYaml stackYaml+ mdef <- readDefaultStackYaml case mdef of Nothing -> error' $ "could not determine major version of" +-+ stackYaml Just ver -> stackDefaultResolver $ Just ver Just ver -> whenJustM (latestMajorSnapshot False ver) $ \latest ->- cmd_ "sed" ["-i", "-e", "s/\\(resolver:\\) .*/\\1 " ++ latest ++ "/", stackYaml]+ updateResolver latest stackYaml -makeStackLTS :: Bool -> MajorVer -> IO ()-makeStackLTS refresh ver = do+makeStackLTS :: Bool -> Bool -> MajorVer -> IO ()+makeStackLTS multiple refresh ver = do configs <- readStackConfigs- let newfile = configFile ver- if ver `elem` configs- then do- error' $ newfile ++ " already exists!"- else do- let mcurrentconfig = find (ver <=) (delete Nightly configs)- case mcurrentconfig of- Nothing -> copyFile stackYaml newfile- Just conf -> do- let origfile = configFile conf- copyFile origfile newfile- whenJustM (latestMajorSnapshot refresh ver) $ \latest ->- cmd_ "sed" ["-i", "-e", "s/\\(resolver:\\) .*/\\1 " ++ latest ++ "/", newfile]--configFile :: MajorVer -> FilePath-configFile ver = "stack-" ++ showCompact ver <.> "yaml"+ case filter (isVersion ver) configs of+ [] -> do+ let newfile = configFile $ Config ver+ mcurrentconfig = find ((ver <) . configVersion) configs+ when multiple $ putStrLn $ "creating" +-+ newfile+ case mcurrentconfig of+ Nothing -> copyFile stackYaml newfile+ Just conf -> do+ let origfile = configFile conf+ copyFile origfile newfile+ whenJustM (latestMajorSnapshot refresh ver) $ \latest ->+ updateResolver latest newfile+ [c] ->+ let msg =+ configFile c +-+ "already" +-++ case c of+ Config _ -> "exists"+ ConfigDefault v -> "has" +-+ showMajor v+ in if multiple+ then putStrLn msg+ else error' $ msg ++ "!"+ cs ->+ (if multiple then putStrLn else error') $ "overlapping major versions:" +-++ unwords (map configFile cs) -runStack :: [MajorVer] -> Bool -> Bool -> Bool -> [String]- -> MajorVer -> IO ()-runStack configs keepgoing debug refresh command ver = do- let mcfgver =- case ver of- Nightly | Nightly `elem` configs -> Just Nightly- _ ->- case sort (filter (ver <=) (delete Nightly configs)) of+runStack :: [ConfigVersion] -> Bool -> Bool -> Bool -> FilePath -> [String]+ -> MajorVer -> IO ()+runStack configs keepgoing debug refresh stack command ver = do+ -- FIXME add --stack or STACK envvar or look for stack-<VERSION>+ when (ver <= LTS 11) $ do+ stackver <- readVersion <$> cmd stack ["--numeric-version"]+ when (stackver >= makeVersion [3]) $+ error' $ "stack-" ++ showVersion stackver +-+ "no longer supports lts < 12"+ let !mconfig =+ case filter (isVersion ver) configs of+ [] ->+ case sort (filter (Config ver <) $ delete (Config Nightly) configs) of [] -> Nothing- (cfg:_) -> Just cfg+ (c:_) -> nonDefaultConfig c+ [c] -> nonDefaultConfig c+ cs -> error' $ "overlapping major versions:" +-++ unwords (map configFile cs) latest <- latestMajorSnapshot refresh ver case latest of Nothing -> error' $ "no snapshot not found for " ++ showMajor ver Just minor -> do let opts = ["-v" | debug] ++ ["--resolver", minor] ++- maybe [] (\f -> ["--stack-yaml", configFile f]) mcfgver+ maybe [] (\f -> ["--stack-yaml", configFile f]) mconfig putStrLn $ "# " ++ minor if debug then debugBuild $ opts ++ command else do- ok <- cmdBool "stack" $ opts ++ command+ ok <- cmdBool stack $ opts ++ command unless (ok || keepgoing) $ do putStr "\nsnapshot-pkg-db: "- cmd_ "stack" $ "--silent" : opts ++ ["path", "--snapshot-pkg-db"]+ cmd_ stack $ "--silent" : opts ++ ["path", "--snapshot-pkg-db"] error' $ "failed for " ++ showMajor ver putStrLn "" where debugBuild :: [String] -> IO () debugBuild args = do- putStr $ "stack " ++ unwords args- (ret,out,err) <- readProcessWithExitCode "stack" args ""+ putStr $ stack +-+ unwords args+ (ret,out,err) <- readProcessWithExitCode stack args "" putStrLn "\n" unless (null out) $ putStrLn out unless (ret == ExitSuccess) $ do@@ -249,6 +282,12 @@ #if !MIN_VERSION_simple_cmd(0,2,4)+#if !MIN_VERSION_filepath(1,4,2)+isExtensionOf :: String -> FilePath -> Bool+isExtensionOf ext@('.':_) = isSuffixOf ext . takeExtensions+isExtensionOf ext = isSuffixOf ('.':ext) . takeExtensions+#endif+ filesWithExtension :: FilePath -- directory -> String -- file extension -> IO [FilePath]@@ -274,9 +313,3 @@ case mf of Nothing -> return False Just f -> doesFileExist f--#if !MIN_VERSION_filepath(1,4,2)-isExtensionOf :: String -> FilePath -> Bool-isExtensionOf ext@('.':_) = isSuffixOf ext . takeExtensions-isExtensionOf ext = isSuffixOf ('.':ext) . takeExtensions-#endif
src/MajorVer.hs view
@@ -10,23 +10,33 @@ ) where +import Data.Char (isDigit) import Data.List.Extra+import Numeric.Natural (Natural) import SimpleCmd (error') import Text.Read (readMaybe) -- FIXME allow specific snapshots?-data MajorVer = LTS Int | LTSLatest | Nightly+data MajorVer = LTS Natural | Nightly deriving (Eq, Ord) maybeReadMajor :: String -> Maybe MajorVer-maybeReadMajor "nightly" = Just Nightly maybeReadMajor ver+ | "nightly" `isPrefixOf` ver =+ case dropPrefix "-" $ dropPrefix "nightly" ver of+ "" -> Just Nightly+ ds ->+ if all (\d -> isDigit d || d == '-') ds+ then Just Nightly+ else Nothing+maybeReadMajor ver | "lts" `isPrefixOf` ver = case readMaybe (dropPrefix "-" (dropPrefix "lts" ver)) of Just major -> Just (LTS major) Nothing -> Nothing | "ghc" `isPrefixOf` ver = case dropPrefix "-" (dropPrefix "ghc" ver) of+ "9.8" -> Just (LTS 23) "9.6" -> Just (LTS 22) "9.4" -> Just (LTS 21) "9.2" -> Just (LTS 20)@@ -45,15 +55,14 @@ -- readMajor "lts-16" readMajor :: String -> MajorVer readMajor "nightly" = Nightly-readMajor "lts" = LTSLatest readMajor ver = case maybeReadMajor ver of Just s -> s Nothing ->- error' $! "couldn't parse " ++ ver ++ " (expected lts-XX, ltsXX, ghc-X.Y or ghcX.Y)"+ error' $! "couldn't parse " ++ ver ++ " (expected lts*, nightly*, ghc-X.Y or ghcX.Y)" -- readCompactMajor "lts16"--- Should we support "stack-lts.yaml"?+-- Should we support stack-lts.yaml or even stack-<minor>.yaml? readCompactMajor :: String -> Maybe MajorVer readCompactMajor "nightly" = Just Nightly readCompactMajor ver =@@ -65,7 +74,6 @@ showMajor :: MajorVer -> String showMajor Nightly = "nightly"-showMajor LTSLatest = "lts" showMajor (LTS ver) = "lts-" ++ show ver showCompact :: MajorVer -> String
src/StackYaml.hs view
@@ -1,14 +1,88 @@ {-# LANGUAGE OverloadedStrings #-} -module StackYaml (readStackYaml)+module StackYaml (+ readDefaultStackYaml,+ stackYaml,+ readStackConfigs,+ ConfigVersion(..),+ configVersion,+ configFile,+ isVersion,+ nonDefaultConfig+ ) where +import Control.Applicative ((<|>))+import Control.Monad.Extra (mapMaybeM, unless)+import Data.List.Extra+import Data.Maybe (mapMaybe) import Data.Yaml (decodeFileThrow) import Network.HTTP.Query (lookupKey)+import SimpleCmd ((+-+))+import System.Directory (listDirectory)+import System.FilePath ((<.>)) -import MajorVer (MajorVer, snapMajorVer)+import MajorVer (MajorVer, readCompactMajor, showCompact, showMajor,+ snapMajorVer) -readStackYaml :: FilePath -> IO (Maybe MajorVer)-readStackYaml file = do+stackYaml :: FilePath+stackYaml = "stack.yaml"++data ConfigVersion = Config MajorVer | ConfigDefault MajorVer+ deriving Eq++instance Ord ConfigVersion where+ compare (Config v1) (Config v2) = compare v1 v2+ compare (ConfigDefault v1) (Config v2) = compare v1 v2+ compare (Config v1) (ConfigDefault v2) = compare v1 v2+ compare (ConfigDefault v1) (ConfigDefault v2) = compare v1 v2++isVersion :: MajorVer -> ConfigVersion -> Bool+isVersion v cfg = configVersion cfg == v++nonDefaultConfig :: ConfigVersion -> Maybe ConfigVersion+nonDefaultConfig (ConfigDefault _) = Nothing+nonDefaultConfig c = Just c++configVersion :: ConfigVersion -> MajorVer+configVersion (Config v) = v+configVersion (ConfigDefault v) = v++configFile :: ConfigVersion -> FilePath+configFile (ConfigDefault _) = stackYaml+configFile (Config ver) = "stack-" ++ showCompact ver <.> "yaml"++data ConfigFile = ConfigFileDefault | ConfigFile MajorVer++-- FIXME error "unversioned stack-lts.yaml is unsupported"+readConfigFile :: FilePath -> Maybe ConfigFile+readConfigFile file =+ if file == stackYaml+ then Just ConfigFileDefault+ else+ ConfigFile <$>+ (stripPrefix "stack-" file >>= stripSuffix ".yaml" >>= readCompactMajor)++readStackYamlFile :: FilePath -> IO (Maybe MajorVer)+readStackYamlFile file = do yaml <- decodeFileThrow file- return $ snapMajorVer <$> lookupKey "resolver" yaml+ return $ snapMajorVer <$>+ (lookupKey "resolver" yaml <|> lookupKey "snapshot" yaml)++readDefaultStackYaml :: IO (Maybe MajorVer)+readDefaultStackYaml = readStackYamlFile stackYaml++readStackYaml :: ConfigFile -> IO (Maybe ConfigVersion)+readStackYaml ConfigFileDefault =+ fmap ConfigDefault <$> readDefaultStackYaml+readStackYaml (ConfigFile ver) = do+ let file = configFile $ Config ver+ mactual <- readStackYamlFile file+ unless (mactual == Just ver) $+ putStrLn $ configFile (Config ver) +-+ "has" +-+ maybe "undefined" showMajor mactual +-+ "resolver"+ return $ Just $ Config ver++readStackConfigs :: IO [ConfigVersion]+readStackConfigs =+ listDirectory "." >>=+ fmap sort . mapMaybeM readStackYaml . mapMaybe readConfigFile
stack-all.cabal view
@@ -1,5 +1,5 @@ name: stack-all-version: 0.6.4+version: 0.7 synopsis: CLI tool for building over Stackage major versions description: Stack-all is a tool for stack building of a Haskell project@@ -8,7 +8,7 @@ license-file: LICENSE author: Jens Petersen <juhpetersen@gmail.com> maintainer: Jens Petersen <juhpetersen@gmail.com>-copyright: 2020-2024 Jens Petersen <juhpetersen@gmail.com>+copyright: 2020-2025 Jens Petersen <juhpetersen@gmail.com> category: Distribution homepage: https://github.com/juhp/stack-all bug-reports: https://github.com/juhp/stack-all/issues@@ -18,7 +18,7 @@ cabal-version: 1.18 tested-with: GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.4, GHC == 8.6.5, GHC == 8.8.4, GHC == 8.10.7, GHC == 9.0.2, GHC == 9.2.8,- GHC == 9.4.8, GHC == 9.6.6, GHC == 9.8.2+ GHC == 9.4.8, GHC == 9.6.7, GHC == 9.8.4, GHC == 9.10.2 source-repository head type: git