Skip to content

Commit

Permalink
feat: add version/build information command
Browse files Browse the repository at this point in the history
Added version command that prints meta information (in plain text or
JSON), such as application name/title/version, build time, VCS and
compiler information etc...
  • Loading branch information
vst committed Apr 3, 2024
1 parent 9e9f6df commit 386ce83
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 0 deletions.
1 change: 1 addition & 0 deletions .hlint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
- DerivingVia
- FlexibleContexts
- OverloadedStrings
- QuasiQuotes
- RecordWildCards
- TemplateHaskell
- TypeApplications
Expand Down
3 changes: 3 additions & 0 deletions build-static.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ cabal freeze
## Run the Docker container:
docker run -i --detach -v "$(pwd):/app" --name "${CONTAINER_NAME}" "${DOCKER_IMAGE}" /bin/bash

## Whitelist codebase directory for Git queries:
docker exec "${CONTAINER_NAME}" git config --global --add safe.directory /app

## Update cabal database:
docker exec "${CONTAINER_NAME}" cabal update

Expand Down
3 changes: 3 additions & 0 deletions package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,14 @@ library:
- autodocodec-schema
- bytestring
- file-embed
- githash
- monad-parallel
- mtl
- optparse-applicative
- path
- scientific
- string-interpolate
- template-haskell
- text
- time
- typed-process
Expand Down
20 changes: 20 additions & 0 deletions src/Lhp/Cli.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import Control.Monad.Except (runExceptT)
import qualified Data.Aeson as Aeson
import qualified Data.ByteString.Lazy.Char8 as BLC
import qualified Data.Text as T
import qualified Data.Text.IO as TIO
import qualified Lhp.Config as Config
import qualified Lhp.Meta as Meta
import Lhp.Remote (compileReport)
Expand Down Expand Up @@ -46,6 +47,7 @@ optProgram :: OA.Parser (IO ExitCode)
optProgram =
commandCompile
<|> commandSchema
<|> commandVersion


-- * Commands
Expand Down Expand Up @@ -93,6 +95,24 @@ commandSchema = OA.hsubparser (OA.command "schema" (OA.info parser infomod) <> O
parser = pure (BLC.putStrLn (Aeson.encode (ADC.Schema.jsonSchemaViaCodec @Report)) >> pure ExitSuccess)


-- ** version


-- | Definition for @version@ CLI command.
commandVersion :: OA.Parser (IO ExitCode)
commandVersion = OA.hsubparser (OA.command "version" (OA.info parser infomod) <> OA.metavar "version")
where
infomod = OA.fullDesc <> infoModHeader <> OA.progDesc "Show version and build information." <> OA.footer "This command shows version and build information."
parser =
doVersion
<$> OA.switch (OA.short 'j' <> OA.long "json" <> OA.help "Format output in JSON.")
doVersion json = do
if json
then BLC.putStrLn (Aeson.encode Meta.buildInfo)
else TIO.putStrLn (Meta.prettyBuildInfo Meta.buildInfo)
pure ExitSuccess


-- * Helpers


Expand Down
87 changes: 87 additions & 0 deletions src/Lhp/Meta.hs
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TemplateHaskell #-}

-- | This module provides project metadata information definitions.
module Lhp.Meta where

import Data.Aeson (ToJSON (toEncoding))
import qualified Data.Aeson as Aeson
import Data.Maybe (fromMaybe)
import Data.String.Interpolate (__i)
import qualified Data.Text as T
import qualified Data.Time as Time
import Data.Version (Version, showVersion)
import qualified GitHash as Githash
import qualified Language.Haskell.TH as TH
import qualified Paths_lhp as Paths
import qualified System.Info


-- | Application name.
Expand Down Expand Up @@ -46,3 +57,79 @@ versionString = showVersion version
-- "0.0.0"
versionText :: T.Text
versionText = T.pack versionString


-- | Data definition for build information.
data BuildInfo = BuildInfo
{ _buildInfoName :: !T.Text
, _buildInfoTitle :: !T.Text
, _buildInfoVersion :: !T.Text
, _buildInfoTimestamp :: !T.Text
, _buildInfoGitTag :: !(Maybe T.Text)
, _buildInfoGitHash :: !(Maybe T.Text)
, _buildInfoCompilerName :: !T.Text
, _buildInfoCompilerVersion :: !T.Text
}
deriving (Eq, Show)


instance Aeson.ToJSON BuildInfo where
toJSON BuildInfo {..} =
Aeson.object
[ "name" Aeson..= _buildInfoName
, "title" Aeson..= _buildInfoTitle
, "version" Aeson..= _buildInfoVersion
, "timestamp" Aeson..= _buildInfoTimestamp
, "gitTag" Aeson..= _buildInfoGitTag
, "gitHash" Aeson..= _buildInfoGitHash
, "compilerName" Aeson..= _buildInfoCompilerName
, "compilerVersion" Aeson..= _buildInfoCompilerVersion
]


toEncoding BuildInfo {..} =
Aeson.pairs
( "name" Aeson..= _buildInfoName
<> "title" Aeson..= _buildInfoTitle
<> "version" Aeson..= _buildInfoVersion
<> "timestamp" Aeson..= _buildInfoTimestamp
<> "gitTag" Aeson..= _buildInfoGitTag
<> "gitHash" Aeson..= _buildInfoGitHash
<> "compilerName" Aeson..= _buildInfoCompilerName
<> "compilerVersion" Aeson..= _buildInfoCompilerVersion
)


-- | Returns the build information generated as per compile time.
buildInfo :: BuildInfo
buildInfo =
BuildInfo
{ _buildInfoName = name
, _buildInfoTitle = title
, _buildInfoVersion = versionText
, _buildInfoTimestamp = $(TH.stringE . Time.formatTime Time.defaultTimeLocale "%Y-%m-%dT%H:%M:%SZ" =<< TH.runIO Time.getCurrentTime)
, _buildInfoGitTag = either (const Nothing) (Just . T.pack . Githash.giTag) gitInfo
, _buildInfoGitHash = either (const Nothing) (Just . T.pack . Githash.giHash) gitInfo
, _buildInfoCompilerName = T.pack System.Info.compilerName
, _buildInfoCompilerVersion = T.pack (showVersion System.Info.fullCompilerVersion)
}


-- | Builds a pretty text from a given 'BuildInfo' value.
prettyBuildInfo :: BuildInfo -> T.Text
prettyBuildInfo BuildInfo {..} =
[__i|
Name: #{_buildInfoName}
Title: #{_buildInfoTitle}
Version: #{_buildInfoVersion}
Timestamp: #{_buildInfoTimestamp}
Git Tag: #{fromMaybe "N/A" _buildInfoGitTag}
Git Hash: #{fromMaybe "N/A" _buildInfoGitHash}
Compiler Name: #{_buildInfoCompilerName}
Compiler Version: #{_buildInfoCompilerVersion}
|]


-- | Git information if any.
gitInfo :: Either String Githash.GitInfo
gitInfo = $$Githash.tGitInfoCwdTry

0 comments on commit 386ce83

Please sign in to comment.