stack-all 0.6.1 → 0.6.2
raw patch · 4 files changed
+92/−54 lines, 4 files
Files
- ChangeLog.md +8/−3
- README.md +14/−9
- src/Main.hs +69/−41
- stack-all.cabal +1/−1
ChangeLog.md view
@@ -1,12 +1,17 @@ # Release history for stack-all +## 0.6.2 (2024-05-21)+- `--default-resolver` to update stack.yaml resolver+- change `--debug` short option to `-D`+- test for `package.yaml` if no .cabal file+ ## 0.6.1 (2024-05-20)-- fix --create-config and --make-lts failing if no command+- fix `--create-config` and `--make-lts` failing if no command ## 0.6 (2024-05-19) - stack-all now works outside of projects too like stack does-- error when --make-lts combined with a command args-- also error for --create-config with versions or command args+- error when `--make-lts` combined with a command args+- also error for `--create-config` with versions or command args - bump default oldest lts from 16 to 18 (ghc-8.10) ## 0.5.2 (2024-04-18)
README.md view
@@ -1,8 +1,9 @@ # stack-all -A CLI tool for building Haskell projects easily over Stackage major versions.+A CLI tool for building Haskell projects easily+over several Stackage major versions. -This is how I do my Haskell build CI for projects locally with stack.+I use this to do Haskell build CI for projects locally with stack. ## Usage @@ -14,9 +15,10 @@ 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.+`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-quickly experiments to build a package that does not include stack support.+quick experiments to build a package that does not include stack support. Since 0.6, stack-all also works outside projects, like stack itself does. @@ -24,16 +26,18 @@ `$ stack-all --version` ```-0.6.1+0.6.2 ``` `$ stack-all --help` ``` Build over Stackage versions -Usage: stack-all [--version] [(-c|--create-config) | (-s|--make-lts)] - [-k|--keep-going] [-d|--debug] [--refresh-cache] - [-n|--newest MAJOR] [(-o|--oldest MAJOR) | (-a|--all-lts)] +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...]] stack-all builds projects easily across different Stackage versions@@ -42,9 +46,10 @@ -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+ -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
src/Main.hs view
@@ -24,52 +24,68 @@ data VersionLimit = DefaultLimit | Oldest MajorVer | AllVersions -data Command = CreateConfig | MakeStackLTS | DefaultRun+data CommandOpt = CreateConfig | DefaultResolver | MakeStackLTS+ 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 (flagWith' CreateConfig 'c' "create-config" "Create a project .stack-all file" <|>- flagWith DefaultRun MakeStackLTS 's' "make-lts" "Create a stack-ltsXX.yaml 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" <*>+ 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...]") -run :: Command -> Bool ->Bool -> Bool -> Maybe MajorVer+stackYaml :: FilePath+stackYaml = "stack.yaml"++run :: Maybe CommandOpt -> Bool ->Bool -> Bool -> Maybe MajorVer -> VersionLimit -> [String] -> IO ()-run command keepgoing debug refresh mnewest verlimit verscmd = do+run mcommand keepgoing debug refresh mnewest verlimit verscmd = do whenJustM findStackProjectDir setCurrentDirectory (versions, cargs) <- getVersionsCmd- case command of- CreateConfig -> do- unless (null cargs) $- error' $ "cannot combine --create-config with stack commands:" +-+ unwords cargs- unless (null versions) $- error' "cannot combine --create-config with major versions"- case verlimit of- Oldest oldest -> createStackAll (Just oldest) mnewest- _ -> createStackAll Nothing mnewest- MakeStackLTS -> do+ case mcommand of+ Just command -> do unless (null cargs) $- error' $ "cannot combine --make-lts with stack commands:" +-+ unwords cargs- if null versions- then error' "--make-lts needs an LTS major version"- else makeStackLTS refresh versions- DefaultRun -> do+ 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 configs <- readStackConfigs let newestFilter = maybe id (filter . (>=)) mnewest mapM_ (runStack configs keepgoing debug refresh $ if null cargs then ["build"] else cargs) (newestFilter versions) where findStackProjectDir :: IO (Maybe FilePath) findStackProjectDir = do- haveStackYaml <- doesFileExist "stack.yaml"+ haveStackYaml <- doesFileExist stackYaml mcwdir <- Just <$> getCurrentDirectory if haveStackYaml then return mcwdir@@ -77,15 +93,17 @@ if mcwdir /= Just "/" then withCurrentDirectory ".." findStackProjectDir else do- putStrLn "stack.yaml not found"- haveCabalFile <- doesFileExistWithExtension "." ".cabal"- if haveCabalFile+ putStrLn $ stackYaml +-+ "not found"+ haveCabalPackageFile <-+ doesFileExistWithExtension "." ".cabal" ||^+ doesFileExist "package.yaml"+ if haveCabalPackageFile then do -- FIXME take suggested extra-deps into stack.yaml -- FIXME stack init content too verbose unlessM (cmdBool "stack" ["init"]) $ do snap <- latestLtsSnapshot refresh- writeFile "stack.yaml" $ "resolver: " ++ snap ++ "\n"+ writeFile stackYaml $ "resolver: " ++ snap ++ "\n" return mcwdir else do putStrLn "no package/project found"@@ -124,6 +142,22 @@ readStackConf f = stripPrefix "stack-" f >>= stripSuffix ".yaml" >>= readCompactMajor +readNewestOldestLTS :: IO (MajorVer,MajorVer)+readNewestOldestLTS = 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)+ where+ readIniConfig :: FilePath -> IniParser a -> IO a+ readIniConfig inifile iniparser = do+ ini <- T.readFile inifile+ return $ either error id $ parseIniFile ini iniparser+ stackAllFile :: FilePath stackAllFile = ".stack-all" @@ -150,21 +184,15 @@ in maybe "" (\s -> showMajor s ++ " too old") molder in "# " ++ older ++ "\noldest = " ++ showMajor oldest ++ "\n" -readNewestOldestLTS :: IO (MajorVer,MajorVer)-readNewestOldestLTS = 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)- where- readIniConfig :: FilePath -> IniParser a -> IO a- readIniConfig inifile iniparser = do- ini <- T.readFile inifile- return $ either error id $ parseIniFile ini iniparser+stackDefaultResolver :: [MajorVer] -> IO ()+stackDefaultResolver vers = do+ unlessM (doesFileExist stackYaml) $+ error' $ "no" +-+ stackYaml +-+ "present"+ case vers of+ [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@@ -177,7 +205,7 @@ else do let mcurrentconfig = find (ver <=) (delete Nightly configs) case mcurrentconfig of- Nothing -> copyFile "stack.yaml" newfile+ Nothing -> copyFile stackYaml newfile Just conf -> do let origfile = configFile conf copyFile origfile newfile
stack-all.cabal view
@@ -1,5 +1,5 @@ name: stack-all-version: 0.6.1+version: 0.6.2 synopsis: CLI tool for building over Stackage major versions description: Build a Haskell project over one or many Stackage major LTS versions.