#!/usr/bin/env cabal {- cabal: build-depends: base == 4.* , turtle == 1.5.* , regex-tdfa == 1.3.* , text == 1.2.* -} {-# LANGUAGE OverloadedStrings #-} import Control.Monad (when) import qualified Data.Text as T import qualified Data.Text.IO as T.IO import System.Environment (getArgs) import System.Exit (ExitCode (..)) import qualified Text.Regex.TDFA as TR import Turtle (empty, shell, shellStrict) main = do args <- getArgs case args of [version] -> makeNewRelease version _ -> putStrLn "Usage: new-release " makeNewRelease :: String -> IO () makeNewRelease newVersion = do (ExitSuccess, branchName) <- shellStrict "git rev-parse --abbrev-ref HEAD" empty when (T.strip branchName /= "release") $ error "You must run this script from the release branch!" let cabalFileName = "waspc.cabal" oldCabalFileContents <- T.unpack <$> T.IO.readFile cabalFileName (newCabalFileContents, oldVersion) <- updateCabalFile oldCabalFileContents newVersion let tag = "v" ++ newVersion when (newVersion == oldVersion) $ error "Version you provided is the current version!" putStrLn $ unlines [ "This will update wasp version from " ++ oldVersion ++ " to " ++ newVersion, cabalFileName ++ " will be updated, and this change will be commited and pushed.", "Also, tag " ++ tag ++ " will be created and pushed, triggering CI to" ++ " create new release on Github.", "Are you sure you want to proceed (y/n)?" ] confirmation <- getLine when (confirmation /= "y") $ error "Aborting" T.IO.writeFile cabalFileName $ T.pack newCabalFileContents -- TODO: Print what I am doing for each step. putStrLn $ "\nCreating new commit with updated " ++ cabalFileName ++ " and pushing it.\n" ExitSuccess <- shell (T.pack $ "git add " ++ cabalFileName) empty ExitSuccess <- shell (T.pack $ "git commit -m \"Updated wasp version to " ++ newVersion ++ ".\"") empty gitPushExitCode <- shell "git push" empty case gitPushExitCode of ExitSuccess -> return () ExitFailure _ -> do ExitSuccess <- shell "git reset --hard HEAD~1" empty error "Failed to do `git push`, reverted changes." putStrLn $ "\nCreating tag " ++ tag ++ " and pushing it.\n" ExitSuccess <- shell (T.pack $ "git tag " ++ tag) empty ExitSuccess <- shell (T.pack $ "git push origin " ++ tag) empty return () updateCabalFile :: String -> String -> IO (String, String) -- Returns (updated cabal file contents, old version) updateCabalFile cabalFileContents newVersion = do let (beforeMatch, match, afterMatch, submatches) = cabalFileContents TR.=~ ("^(version: *)([0-9]+\\.[0-9]+\\.[0-9]+)" :: String) :: (String, String, String, [String]) when (null match) $ error "Couldn't locate version in cabal file!?" let [matchBeforeVersion, oldVersion] = submatches let newContents = beforeMatch ++ matchBeforeVersion ++ newVersion ++ afterMatch return (newContents, oldVersion)