stack-all 0.6.2 → 0.6.3
raw patch · 5 files changed
+113/−95 lines, 5 filesdep +yaml
Dependencies added: yaml
Files
- ChangeLog.md +4/−0
- README.md +24/−20
- src/Main.hs +66/−73
- src/StackYaml.hs +14/−0
- stack-all.cabal +5/−2
ChangeLog.md view
@@ -1,5 +1,9 @@ # Release history for stack-all +## 0.6.3 (2024-06-10)+- `--default-resolver` version is now optional for easy minor updating+- command option args are now handled more precisely with an ADT+ ## 0.6.2 (2024-05-21) - `--default-resolver` to update stack.yaml resolver - change `--debug` short option to `-D`
README.md view
@@ -9,16 +9,15 @@ `stack-all` by default runs `stack build` over Stackage Nightly and LTS major versions-(current default is nightly & major LTS versions back to lts-18)+(the current default range is nightly & major LTS versions back to lts-18) corresponding to latest major ghc minor versions,-with appropriate stack `--resolver` options.+using appropriate stack `--resolver` options. Note that `stack` only works in a project if a `stack.yaml` file exists. If no `stack.yaml` file is found in a .cabal project,-`stack-all` will create one,-if there is a .cabal or "package.yaml" file.-Of course it may still fail to build, but this allows for-quick experiments to build a package that does not include stack support.+`stack-all` will create one if there is a .cabal or "package.yaml" file.+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. @@ -26,34 +25,35 @@ `$ stack-all --version` ```-0.6.2+0.6.3 ``` `$ stack-all --help` ```-Build over Stackage versions+Build project over Stackage major versions -Usage: stack-all [--version] - [(-c|--create-config) | (-d|--default-resolver) | - (-s|--make-lts)] [-k|--keep-going] [-D|--debug] - [--refresh-cache] [-n|--newest MAJOR] - [(-o|--oldest MAJOR) | (-a|--all-lts)] - [MAJORVER... [COMMAND...]]+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...]] - stack-all builds projects easily across different Stackage versions+ https://github.com/juhp/stack-all#readme Available options: -h,--help Show this help text --version Show version- -c,--create-config Create a project .stack-all file- -d,--default-resolver Update stack.yaml resolver- -s,--make-lts Create a stack-ltsXX.yaml file -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 -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+ Set stack.yaml resolver+ -u,--update-resolver Update stack.yaml resolver+ -s,--make-lts MAJOR Create a stack-ltsXX.yaml file ``` ### Overriding stack.yaml@@ -81,7 +81,7 @@ ### Specifying LTS versions You can abbreviate `lts-XX` args to `ltsXX` on the commandline.-`lts` is also accepted and resolved to the latest major LTS version.+`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`.@@ -124,12 +124,16 @@ ``` will run `stack test` over the LTS versions instead. ++Any stack command can be used, possibly outside a project,+eg: `stack-all list aeson`+ Happy stack building! ## Install The project is released on Hackage. -You can also build from git source with `stack install` or `cabal install`.+You can also build from a git clone with `stack install` or `cabal install`. ## Collaboration The project is hosted at https://github.com/juhp/stack-all under a BSD license.
src/Main.hs view
@@ -18,67 +18,56 @@ import MajorVer import Paths_stack_all (version) import Snapshots+import StackYaml (readStackYaml) defaultOldestLTS :: MajorVer defaultOldestLTS = LTS 18 data VersionLimit = DefaultLimit | Oldest MajorVer | AllVersions -data CommandOpt = CreateConfig | DefaultResolver | MakeStackLTS+data Command = CreateConfig+ | SetDefaultResolver MajorVer+ | UpdateDefaultResolver+ | MakeStackLTS MajorVer+ | RunCmd [String] deriving Eq -showOpt :: CommandOpt -> String-showOpt c =- "--" ++- case c of- CreateConfig -> "create-config"- DefaultResolver -> "default-resolver"- MakeStackLTS -> "make-lts"- main :: IO () main = do hSetBuffering stdout NoBuffering- simpleCmdArgs' (Just version) "Build over Stackage versions"- "stack-all builds projects easily across different Stackage versions" $- run <$>- optional+ simpleCmdArgs' (Just version) "Build project over Stackage major versions"+ "https://github.com/juhp/stack-all#readme" $+ run+ <$> 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"+ <*> 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" <|>- flagWith' DefaultResolver 'd' "default-resolver" ("Update" +-+ stackYaml +-+ "resolver") <|>- flagWith' MakeStackLTS 's' "make-lts" "Create a stack-ltsXX.yaml file") <*>- 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" <*>- 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") <*>- many (strArg "MAJORVER... [COMMAND...]")+ (SetDefaultResolver . readMajor <$> strOptionWith 'd' "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") <|>+ RunCmd <$> many (strArg "MAJORVER... COMMAND...")) stackYaml :: FilePath stackYaml = "stack.yaml" -run :: Maybe CommandOpt -> Bool ->Bool -> Bool -> Maybe MajorVer- -> VersionLimit -> [String] -> IO ()-run mcommand keepgoing debug refresh mnewest verlimit verscmd = do+run :: Bool ->Bool -> Bool -> Maybe MajorVer -> VersionLimit -> Command+ -> IO ()+run keepgoing debug refresh mnewest verlimit com = do whenJustM findStackProjectDir setCurrentDirectory- (versions, cargs) <- getVersionsCmd- case mcommand of- Just command -> do- unless (null cargs) $- error' $ "cannot combine" +-+ showOpt command +-+ "with stack commands:" +-+ unwords cargs- case command of- CreateConfig -> do- unless (null versions) $- error' "cannot combine --create-config with major versions"- case verlimit of- Oldest oldest -> createStackAll (Just oldest) mnewest- _ -> createStackAll Nothing mnewest- DefaultResolver ->- stackDefaultResolver versions- MakeStackLTS ->- if null versions- then error' "--make-lts needs an LTS major version"- else makeStackLTS refresh versions- Nothing -> do+ case com of+ CreateConfig ->+ case verlimit of+ Oldest oldest -> createStackAll (Just oldest) mnewest+ _ -> createStackAll Nothing mnewest+ SetDefaultResolver ver -> stackDefaultResolver $ Just ver+ UpdateDefaultResolver -> stackDefaultResolver Nothing+ MakeStackLTS ver -> makeStackLTS refresh ver+ RunCmd verscmd -> do+ (versions, cargs) <- getVersionsCmd verscmd configs <- readStackConfigs let newestFilter = maybe id (filter . (>=)) mnewest mapM_ (runStack configs keepgoing debug refresh $ if null cargs then ["build"] else cargs) (newestFilter versions)@@ -109,8 +98,8 @@ putStrLn "no package/project found" return Nothing - getVersionsCmd :: IO ([MajorVer],[String])- getVersionsCmd = do+ getVersionsCmd :: [String] -> IO ([MajorVer],[String])+ getVersionsCmd verscmd = do let partitionMajors = swap . partitionEithers . map eitherReadMajorAlias (verlist,cmds) = partitionMajors verscmd allMajors <- getMajorVers@@ -135,12 +124,13 @@ 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+ 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@@ -184,33 +174,36 @@ in maybe "" (\s -> showMajor s ++ " too old") molder in "# " ++ older ++ "\noldest = " ++ showMajor oldest ++ "\n" -stackDefaultResolver :: [MajorVer] -> IO ()-stackDefaultResolver vers = do+stackDefaultResolver :: Maybe MajorVer -> IO ()+stackDefaultResolver mver = do unlessM (doesFileExist stackYaml) $ error' $ "no" +-+ stackYaml +-+ "present"- case vers of- [ver] ->+ case mver of+ Nothing -> do+ mdef <- readStackYaml stackYaml+ 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]- _ -> error' "only specify one major version for default resolver" -makeStackLTS :: Bool -> [MajorVer] -> IO ()-makeStackLTS refresh vers = do+makeStackLTS :: Bool -> MajorVer -> IO ()+makeStackLTS refresh ver = do configs <- readStackConfigs- forM_ vers $ \ver -> do- 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]+ 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"
+ src/StackYaml.hs view
@@ -0,0 +1,14 @@+{-# LANGUAGE OverloadedStrings #-}++module StackYaml (readStackYaml)+where++import Data.Yaml (decodeFileThrow)+import Network.HTTP.Query (lookupKey)++import MajorVer (MajorVer, snapMajorVer)++readStackYaml :: FilePath -> IO (Maybe MajorVer)+readStackYaml file = do+ yaml <- decodeFileThrow file+ return $ snapMajorVer <$> lookupKey "resolver" yaml
stack-all.cabal view
@@ -1,8 +1,9 @@ name: stack-all-version: 0.6.2+version: 0.6.3 synopsis: CLI tool for building over Stackage major versions description:- Build a Haskell project over one or many Stackage major LTS versions.+ Stack-all is a tool for stack building of a Haskell project+ across multiple Stackage major LTS versions. license: BSD3 license-file: LICENSE author: Jens Petersen <juhpetersen@gmail.com>@@ -33,6 +34,7 @@ other-modules: Paths_stack_all MajorVer Snapshots+ StackYaml hs-source-dirs: src build-depends: base < 5 , aeson@@ -46,6 +48,7 @@ , simple-cmd >= 0.1.4 , simple-cmd-args >= 0.1.8 , text+ , yaml if flag(aeson1) build-depends: unordered-containers default-language: Haskell2010