From 78baaee6c5bea99647d49123e36f052d64fb66ef Mon Sep 17 00:00:00 2001 From: Simon Michael Date: Fri, 25 Apr 2025 09:36:38 -1000 Subject: [PATCH] lib: more version helpers, rename to HledgerBinaryInfo, silence warnings --- hledger-ui/Hledger/UI/UIOptions.hs | 5 +++-- hledger-web/Hledger/Web/WebOptions.hs | 5 +++-- hledger/Hledger/Cli/CliOptions.hs | 6 +++++- hledger/Hledger/Cli/Version.hs | 30 ++++++++++++++++++++++----- 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/hledger-ui/Hledger/UI/UIOptions.hs b/hledger-ui/Hledger/UI/UIOptions.hs index 3eccd7a6c..6b0129513 100644 --- a/hledger-ui/Hledger/UI/UIOptions.hs +++ b/hledger-ui/Hledger/UI/UIOptions.hs @@ -4,6 +4,7 @@ module Hledger.UI.UIOptions where import Data.Default (def) +import Data.Either (fromRight) import Data.List (intercalate) import qualified Data.Map as M import Data.Maybe (fromMaybe) @@ -41,8 +42,8 @@ prognameandversion = progname packageversion -binaryinfo :: HledgerBinaryVersion -Right binaryinfo = parseHledgerVersion prognameandversion +binaryinfo :: HledgerBinaryInfo +binaryinfo = fromRight nullbinaryinfo $ parseHledgerVersion prognameandversion uiflags = [ diff --git a/hledger-web/Hledger/Web/WebOptions.hs b/hledger-web/Hledger/Web/WebOptions.hs index ab984909a..febfb18ed 100644 --- a/hledger-web/Hledger/Web/WebOptions.hs +++ b/hledger-web/Hledger/Web/WebOptions.hs @@ -23,6 +23,7 @@ import Hledger.Web.Settings (defhost, defport, defbaseurl) import qualified Data.Text as T import Data.Char (toLower) import Data.List (isPrefixOf) +import Data.Either (fromRight) -- cf Hledger.Cli.Version @@ -52,8 +53,8 @@ prognameandversion = progname packageversion -binaryinfo :: HledgerBinaryVersion -Right binaryinfo = parseHledgerVersion prognameandversion +binaryinfo :: HledgerBinaryInfo +binaryinfo = fromRight nullbinaryinfo $ parseHledgerVersion prognameandversion webflags :: [Flag RawOpts] webflags = diff --git a/hledger/Hledger/Cli/CliOptions.hs b/hledger/Hledger/Cli/CliOptions.hs index d7a028d44..581326912 100644 --- a/hledger/Hledger/Cli/CliOptions.hs +++ b/hledger/Hledger/Cli/CliOptions.hs @@ -139,8 +139,12 @@ prognameandversion = progname packageversion -binaryinfo :: HledgerBinaryVersion +binaryinfo :: HledgerBinaryInfo Right binaryinfo = parseHledgerVersion prognameandversion +-- ui and web use nullbinaryinfo for a parse failure here to silence an inexhaustive pattern warning. +-- I can't reproduce that warning right now, so here I've stuck with the original approach, +-- which will force a compile error if prognameandversion is ever malformed, eg from unexpected +-- git output. -- Common options. -- keep synced: the docs macro in doc/common.m4 diff --git a/hledger/Hledger/Cli/Version.hs b/hledger/Hledger/Cli/Version.hs index 86b0391eb..49a7b705d 100644 --- a/hledger/Hledger/Cli/Version.hs +++ b/hledger/Hledger/Cli/Version.hs @@ -6,10 +6,13 @@ Version number-related utilities. See also the Makefile. module Hledger.Cli.Version ( PackageVersionString, Version, + nullversion, toVersion, showVersion, + isReleaseVersion, HledgerVersionString, - HledgerBinaryVersion(..), + HledgerBinaryInfo(..), + nullbinaryinfo, ProgramName, GitHash, ArchName, @@ -36,6 +39,7 @@ import Text.Megaparsec.Char import qualified Text.Megaparsec.Char.Lexer as L import Hledger.Data.Dates (parsedate) import Data.Bifunctor +import qualified Data.List.NonEmpty as NE -- | A Cabal/Hackage-compatible package version string: one or more dot-separated integers. @@ -44,6 +48,8 @@ type PackageVersionString = String -- | The number parts parsed from a PackageVersionString. type Version = NonEmpty Int +nullversion = NE.fromList [0] + showVersion :: Version -> String showVersion = intercalate "." . map show . toList @@ -56,6 +62,9 @@ toVersion s = then Nothing else nonEmpty $ catMaybes parts +isReleaseVersion :: Version -> Bool +isReleaseVersion v = NE.last v < 98 -- .99 and possibly .98 are dev + -- | A hledger version string, as shown by hledger --version. -- This can vary; some examples: -- @@ -88,7 +97,7 @@ type GitHash = String -- and the build's git hash, the release date, and the binary's -- intended operating machine and machine architecture, if we can detect these. -- Also, a copy of the --version output from which it was parsed. -data HledgerBinaryVersion = HledgerBinaryVersion { +data HledgerBinaryInfo = HledgerBinaryInfo { hbinVersionOutput :: String , hbinProgramName :: ProgramName , hbinPackageVersion :: Version @@ -99,6 +108,17 @@ data HledgerBinaryVersion = HledgerBinaryVersion { , hbinArch :: Maybe ArchName } deriving (Show, Eq) +nullbinaryinfo = HledgerBinaryInfo { + hbinVersionOutput = "" + , hbinProgramName = "" + , hbinPackageVersion = nullversion + , hbinPackageVersionStr = "" + , hbinGitHash = Nothing + , hbinReleaseDate = Nothing + , hbinOs = Nothing + , hbinArch = Nothing +} + type Parser = Parsec Void String -- | Parse hledger's --version output. @@ -110,7 +130,7 @@ type Parser = Parsec Void String -- >>> isRight $ parseHledgerVersion "hledger 1.42.99-g2288f5193-20250422, mac-aarch64" -- True -- -parseHledgerVersion :: HledgerVersionString -> Either String HledgerBinaryVersion +parseHledgerVersion :: HledgerVersionString -> Either String HledgerBinaryInfo parseHledgerVersion s = case parse hledgerversionp "" s of Left err -> Left $ errorBundlePretty err @@ -121,7 +141,7 @@ parseHledgerVersion s = -- possibly followed by the binary's intended operating system and architecture -- (see HledgerVersionString and versionStringWith). -- The hbinVersionOutput field is left blank here; parseHledgerVersion sets it. -hledgerversionp :: Parser HledgerBinaryVersion +hledgerversionp :: Parser HledgerBinaryInfo hledgerversionp = do progName <- (<>) <$> string "hledger" <*> many (letterChar <|> char '-') some $ char ' ' @@ -144,7 +164,7 @@ hledgerversionp = do Just osarch -> bimap (Just . reverse) (Just . reverse) $ second (drop 1) $ break (== '-') $ reverse osarch many spaceChar eof - return $ HledgerBinaryVersion + return $ HledgerBinaryInfo { hbinVersionOutput = "" , hbinProgramName = progName , hbinPackageVersion = pkgversion