feat: setup: first setup check: is hledger in PATH ?

This commit is contained in:
Simon Michael 2025-04-17 01:26:11 -10:00
parent cff831c3c0
commit 69232cae7a
5 changed files with 138 additions and 38 deletions

View File

@ -421,7 +421,7 @@ main = exitOnExceptions $ withGhcDebug' $ do
| manFlag -> runManForTopic "hledger" mmodecmdname | manFlag -> runManForTopic "hledger" mmodecmdname
-- 6.5.2. builtin command which should not require or read the journal - run it -- 6.5.2. builtin command which should not require or read the journal - run it
| cmdname `elem` ["commands","demo","help","test"] -> | cmdname `elem` ["commands","demo","help","setup","test"] ->
cmdaction opts (ignoredjournal cmdname) cmdaction opts (ignoredjournal cmdname)
-- 6.5.3. builtin command which should create the journal if missing - do that and run it -- 6.5.3. builtin command which should create the journal if missing - do that and run it

View File

@ -295,7 +295,7 @@ commandsList progversion othercmds =
," diff compare an account's transactions in two journals" ," diff compare an account's transactions in two journals"
,"+git save or view journal file history simply in git" -- hledger-git ,"+git save or view journal file history simply in git" -- hledger-git
,"+pijul save or view journal file history simply in pijul" -- hledger-pijul ,"+pijul save or view journal file history simply in pijul" -- hledger-pijul
," setup check and help set up various installation things" ," setup check and show the status of the hledger installation"
," test run some self tests" ," test run some self tests"
,"" ,""
-----------------------------------------80------------------------------------- -----------------------------------------80-------------------------------------

View File

@ -1,6 +1,8 @@
{-| {-|
Check and help set up various installation things. Check and show the status of the hledger installation,
show extra info and hints,
and offer to fix problems where possible.
-} -}
@ -15,27 +17,18 @@ module Hledger.Cli.Commands.Setup (
) )
where where
-- import Data.Default (def) import System.FilePath
-- import System.FilePath (takeFileName) import Data.Text (Text)
-- import Data.List (intercalate, nub, sortOn) import qualified Data.Text as T
-- import Data.List.Extra (nubSort) import qualified Data.Text.IO as T
-- import qualified Data.Map as Map
-- import Data.Maybe (fromMaybe)
-- import Data.HashSet (size, fromList)
-- import qualified Data.Text as T
-- import qualified Data.Text.Lazy as TL
-- import qualified Data.Text.Lazy.Builder as TB
-- import Data.Time.Calendar (Day, addDays, diffDays)
-- import Data.Time.Clock.POSIX (getPOSIXTime)
-- import GHC.Stats
-- -- import System.Console.CmdArgs.Explicit hiding (Group)
-- import System.Mem (performMajorGC)
-- import Text.Printf (printf)
-- import Text.Tabular.AsciiWide
import Hledger import Hledger
import Hledger.Cli.CliOptions import Hledger.Cli.CliOptions
-- import Hledger.Cli.Utils (writeOutputLazyText) import Control.Monad
import System.Info
import System.Directory
import System.IO
import Safe
-- import Text.Printf (printf)
setupmode = hledgerCommandMode setupmode = hledgerCommandMode
@ -45,20 +38,127 @@ setupmode = hledgerCommandMode
hiddenflags hiddenflags
([], Just $ argsFlag "[QUERY]") ([], Just $ argsFlag "[QUERY]")
-- like Register.summarisePostings -- | 1. Check and show the status of various aspects of the hledger installation.
-- | Print various statistics for the journal. -- 2. Show extra info and hints on how to fix problems.
-- 3. When possible, offer to help fix problems, interactively.
setup :: CliOpts -> Journal -> IO () setup :: CliOpts -> Journal -> IO ()
setup _opts@CliOpts{rawopts_=_rawopts, reportspec_=_rspec} _j = do setup _opts@CliOpts{rawopts_=_rawopts, reportspec_=_rspec} _ignoredj = do
print "setup" -- This command is not given a journal and should not use _ignoredj;
-- instead detect it ourselves when we are ready.
let
p ok ymsg nmsg =
putStrLn $ unwords $ if ok then ["", y, "", ymsg] else ["", n, "", nmsg]
where
y = "yes ✅"
n = "no ❌"
putStrLn "hledger:"
-- let today = _rsDay rspec putStr "- in PATH ?"
-- verbose = boolopt "verbose" rawopts pathexes <- findExecutables progname
-- q = _rsQuery rspec home <- getHomeDirectory
-- l = ledgerFromJournal q j appdata <- getXdgDirectory XdgData ""
-- intervalspans = snd $ reportSpanBothDates j rspec otherexes <- flip findExecutablesInDirectories progname $
-- ismultiperiod = length intervalspans > 1 [home </> ".local/bin"
-- (ls, txncounts) = unzip $ map (showLedgerStats verbose l today) intervalspans ,home </> ".cabal/bin"
-- numtxns = sum txncounts ,home </> ".nix-profile/bin"
-- txt = (if ismultiperiod then id else TL.init) $ TB.toLazyText $ unlinesB ls ,"/opt/homebrew/bin"
-- writeOutputLazyText opts txt ,"/usr/local/bin"
,"/usr/bin"
]
++ [appdata </> "local/bin" | os == "mingw32"]
++ [appdata </> "cabal/bin" | os == "mingw32"]
let
ok = not $ null pathexes
pathexe = quoteIfNeeded $ headDef (error' "showing nonexistent executable") pathexes
otherexe = quoteIfNeeded $ headDef (error' "showing nonexistent executable") otherexes
otherdir = takeDirectory otherexe
hint = if null otherexes
then ("Add " <> progname <> "'s directory to your shell's PATH.")
else unlines
["Add " <> otherdir <> " to PATH in your shell config."
," Eg on unix: echo 'export PATH=" <> otherdir <> ":$PATH' >> ~/.profile"
," and start a new shell session."
]
p ok pathexe hint
-- putStr "- runnable ?"
-- putStr "- up to date ?"
-- putStr "- native binary ?"
-- putStr "- eget installed ?"
putStr "\n"
-- putStrLn "config:"
-- putStr "- user config file exists ?"
-- putStr "\n"
-- putStr "- local config masking user config ?"
-- putStr "\n"
-- putStr "- config file readable ?"
-- putStr "\n"
-- putStr "- common general options configured ?"
-- putStr "\n"
-- putStr " --pretty --ignore-assertions --infer-costs"
-- putStr "\n"
-- putStr " print --explicit --show-costs"
-- putStr "\n"
-- putStr "\n"
-- putStrLn "files:"
-- putStr "- default journal file exists ?"
-- putStr "\n"
-- putStr "- default journal file readable ?"
-- putStr "\n"
-- putStr "\n"
-- putStrLn "accounts:"
-- putStr "- all account types declared or detected ?"
-- putStr "\n"
-- putStr " asset, liability, equity, revenue, expense, cash, conversion"
-- putStr "\n"
-- putStr "- untyped accounts ?"
-- putStr "\n"
-- putStr "- all used accounts declared ?"
-- putStr "\n"
-- putStr "\n"
-- putStrLn "commodities:"
-- putStr "- all used commodities declared ?"
-- putStr "\n"
-- putStr "\n"
-- putStrLn "tags:"
-- putStr "- all used tags declared ?"
-- putStr "\n"
-- putStr "\n"
{- | Ensure there is a journal file at the given path, creating an empty one if needed.
On Windows, also ensure that the path contains no trailing dots
which could cause data loss (see 'isWindowsUnsafeDotPath').
-}
_ensureJournalFileExists :: FilePath -> IO ()
_ensureJournalFileExists f = do
when (os == "mingw32" && isWindowsUnsafeDotPath f) $
error' $
"Part of file path \"" <> show f <> "\"\n ends with a dot, which is unsafe on Windows; please use a different path.\n"
exists <- doesFileExist f
unless exists $ do
hPutStrLn stderr $ "Creating hledger journal file " <> show f
-- note Hledger.Utils.UTF8.* do no line ending conversion on windows,
-- we currently require unix line endings on all platforms.
newJournalContent >>= T.writeFile f
{- | Does any part of this path contain non-. characters and end with a . ?
Such paths are not safe to use on Windows (cf #1056).
-}
isWindowsUnsafeDotPath :: FilePath -> Bool
isWindowsUnsafeDotPath = any (\x -> last x == '.' && any (/= '.') x) . splitDirectories
-- | Give the content for a new auto-created journal file.
newJournalContent :: IO Text
newJournalContent = do
d <- getCurrentDay
return $ "; journal created " <> T.pack (show d) <> " by hledger\n"

View File

@ -1,6 +1,6 @@
## setup ## setup
Check and help set up various installation things. Check and show the status of the hledger installation.
```flags ```flags
Flags: Flags:

View File

@ -6515,7 +6515,7 @@ If you have installed more [add-on commands](../scripts.md), they also will be l
- [check](#check) - check for various kinds of error in the data - [check](#check) - check for various kinds of error in the data
- [diff](#diff) - compare account transactions in two journal files - [diff](#diff) - compare account transactions in two journal files
- [setup](#setup) - check and help set up various installation things - [setup](#setup) - check and show the status of the hledger installation
- [test](#test) - run self tests - [test](#test) - run self tests