hkgr 0.4.8 → 0.5
raw patch · 3 files changed
+53/−39 lines, 3 files
Files
- CHANGELOG.md +7/−0
- hkgr.cabal +4/−5
- src/Main.hs +42/−34
CHANGELOG.md view
@@ -1,5 +1,12 @@ # Changelog +## 0.5 (2025-09-18)+- support Cabal's XDG layout (#5, reported by Artem)+ ie check for ~/.config/cabal/config before ~/.cabal/config+- do not prompt for password if there is is 'token' or 'password-command' (#5)+- upload-haddock/publish-haddock: now builds docs first with v2-haddock (#6)+- bump default stack init to lts-23+ ## 0.4.8 (2025-05-23) - bump stack default to lts-22
hkgr.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.0 name: hkgr-version: 0.4.8+version: 0.5 synopsis: Simple Hackage release workflow for package maintainers description: Hkgr (Hackager) is a tool to help make new releases of@@ -20,9 +20,9 @@ data-files: template.cabal.tmpl extra-doc-files: README.md , CHANGELOG.md-tested-with: GHC == 9.10 || == 9.8 || == 9.6 || == 9.4 || == 9.2- || == 9.0 || == 8.10 || == 8.8 || == 8.6 || == 8.4- || == 8.2+tested-with: GHC == 9.12 || == 9.10 || == 9.8 || == 9.6 || == 9.4+ || == 9.2 || == 9.0 || == 8.10 || == 8.8 || == 8.6+ || == 8.4 || == 8.2 source-repository head type: git@@ -61,4 +61,3 @@ ghc-options: -Wunused-packages default-language: Haskell2010- default-extensions: OverloadedStrings
src/Main.hs view
@@ -18,7 +18,7 @@ import SimpleCmdArgs import SimplePrompt (promptNonEmpty, promptPassword) import System.Directory-import System.Environment.XDG.BaseDir+import System.Environment.XDG.BaseDir (getUserConfigFile) import System.Exit (ExitCode (..)) import System.FilePath import System.IO (BufferMode(NoBuffering), hSetBuffering, stdout)@@ -53,11 +53,9 @@ <$> nobuildOpt <*> switchWith 'U' "no-upload" "Do not upload to Hackage" , Subcommand "upload-haddock" "Upload candidate documentation to Hackage" $- upHaddockCmd False- <$> forceOpt "rebuild doc tarball"+ pure (upHaddockCmd False) , Subcommand "publish-haddock" "Publish documentation to Hackage" $- upHaddockCmd True- <$> forceOpt "rebuild doc tarball"+ pure (upHaddockCmd True) , Subcommand "build" "Do a local pristine build from the tarball" $ pure pristineBuildCmd , Subcommand "version" "Show the package version from .cabal file" $@@ -92,11 +90,13 @@ (== ExitSuccess) <$> P.runProcess (git c args) removeTrailingNewline :: B.ByteString -> B.ByteString-removeTrailingNewline "" = "" removeTrailingNewline bs =- if B.last bs == '\n'- then B.init bs- else bs+ case B.unsnoc bs of+ Nothing -> bs+ Just (ini,l) ->+ if l == '\n'+ then ini+ else bs cmd :: String -> [String] -> IO String cmd c args =@@ -285,44 +285,52 @@ getUserPassword = do cabalConfig <- do home <- getHomeDirectory- let cabalConfig = home </> ".cabal/config"- exists <- doesFileExist cabalConfig- if exists- then readFile cabalConfig+ xdgConfig <- getUserConfigFile "cabal" "config"+ have_xdg <- doesFileExist xdgConfig+ if have_xdg+ then readFile xdgConfig else do- putStrLn $ "Warning:" +-+ cabalConfig +-+ "not found!"- return ""- muser <- maybeGetHackage "username" False cabalConfig- mpasswd <- maybeGetHackage "password" True cabalConfig+ let config = home </> ".cabal/config"+ exists <- doesFileExist config+ if exists+ then readFile config+ else do+ putStrLn $ "Warning: no cabal" +-+ show "config" +-+ "file found!"+ return ""+ muser <- maybeGetUsername cabalConfig+ mpasswd <- maybeGetPassword cabalConfig return $ B.pack $ unlines $ catMaybes [muser, mpasswd] where- maybeGetHackage :: String -> Bool -> String -> IO (Maybe String)- maybeGetHackage field hide cabalConfig =- if haveCabalConfigField+ maybeGetUsername :: String -> IO (Maybe String)+ maybeGetUsername config =+ if haveField config "username" then return Nothing- else Just <$> prompt hide ("hackage.haskell.org" +-+ field)- where- haveCabalConfigField :: Bool- haveCabalConfigField =- any ((field ++ ":") `isPrefixOf`) (lines cabalConfig)+ else Just <$> prompt False "hackage.haskell.org username" + maybeGetPassword :: String -> IO (Maybe String)+ maybeGetPassword config =+ if any (haveField config) ["password", "token", "password-command"]+ then return Nothing+ else Just <$> prompt True "hackage.haskell.org password"++ haveField :: String -> String -> Bool+ haveField config field =+ any ((field ++ ":") `isPrefixOf`) (lines config)+ prompt :: Bool -> String -> IO String prompt hide s = do inp <- (if hide then promptPassword else promptNonEmpty) s when hide $ putChar '\n' return inp -upHaddockCmd :: Bool -> Bool -> IO ()-upHaddockCmd publish force = do+upHaddockCmd :: Bool -> IO ()+upHaddockCmd publish = do needProgram "cabal" userpassBS <- getUserPassword pkgid <- getPackageId- when force $ do- let tarball = "dist" </> showPkgId pkgid ++ '-' : "docs" <.> tarGzExt- exists <- doesFileExist tarball- when exists $- removeFile tarball- _out <- P.readProcessInterleaved_ (P.setStdin (P.byteStringInput userpassBS) $ P.proc "cabal" ("upload" : "--documentation" : ["--publish" | publish]))+ let tarball = "dist-newstyle" </> showPkgId pkgid ++ '-' : "docs" <.> tarGzExt+ cabal_ "haddock" ["--haddock-for-hackage"]+ _out <- P.readProcessInterleaved_ (P.setStdin (P.byteStringInput userpassBS) $ P.proc "cabal" ("upload" : "--documentation" : ["--publish" | publish] ++ [tarball])) putStrLn $ (if publish then "Published at" else "Uploaded to") +-+ "https://hackage.haskell.org/package/" ++ showPkgId pkgid ++ if publish then "" else "/candidate" cabal_ :: String -> [String] -> IO ()@@ -395,7 +403,7 @@ -- FIXME add stack.yaml template too when (not haveStackCfg && isJust mstack) $ do -- FIXME determine last lts automatically- cmd_ "stack" ["init", "--verbosity", "warn", "--resolver", "lts-22"]+ cmd_ "stack" ["init", "--verbosity", "warn", "--resolver", "lts-23"] sed ["/^#/d", "/^$/d"] "stack.yaml" haveGit <- doesDirectoryExist ".git" unless haveGit $ do