summaryrefslogtreecommitdiff
path: root/Omni
diff options
context:
space:
mode:
authorBen Sima <ben@bensima.com>2025-11-26 16:45:41 -0500
committerBen Sima <ben@bensima.com>2025-11-26 16:45:41 -0500
commit0fa8ed4689022cb213de9cfb88a10841c7a03935 (patch)
tree42c564d8e17e9998ebab912b0adc75a9d9867b08 /Omni
parent4082065308d9e7c4c8c2286c08e475ba64ce6a03 (diff)
Unify LineManager for analyze and build phases
- Create single LineManager in move() that spans both phases - Reserve N lines upfront for N build targets - Status progression: [.] pending -> [+] analyzing -> [~] building -> [✓]/[x] done - Remove duplicate LineManager creation from analyzeAll and build - Update both SingleLine and MultiLine modes with proper symbols This fixes the issue where only one line was reserved during analysis and status lines were being duplicated instead of overwritten.
Diffstat (limited to 'Omni')
-rw-r--r--Omni/Bild.hs43
-rw-r--r--Omni/Log/Concurrent.hs6
2 files changed, 20 insertions, 29 deletions
diff --git a/Omni/Bild.hs b/Omni/Bild.hs
index 773aaba..588e7f2 100644
--- a/Omni/Bild.hs
+++ b/Omni/Bild.hs
@@ -228,11 +228,14 @@ move args = do
/> filter isBuildableNs
let isPlanMode = args `Cli.has` Cli.longOption "plan"
-- Wrap entire analyze+build sequence in a single LineManager
- -- to avoid duplicate status line output
+ -- to show all targets upfront and track status through analyze -> build
let runWithManager action = case (isPlanMode, isLoud) of
(True, _) -> action -- Plan mode doesn't need a manager
(_, True) -> action -- Loud mode doesn't need a manager
- _ -> LogC.withLineManager namespaces (const action)
+ _ ->
+ LogC.withLineManager namespaces <| \mgr -> do
+ LogC.initializeLines mgr -- Show all targets as pending upfront
+ action
runWithManager <| do
analysis <- analyzeAll isPlanMode namespaces
printOrBuild root analysis
@@ -560,21 +563,15 @@ removeVersion = takeWhile (/= '.') .> butlast2
type Analysis = Map Namespace Target
analyzeAll :: Bool -> [Namespace] -> IO Analysis
-analyzeAll isPlanMode nss = do
- if isPlanMode
- then do
- -- Plan mode: no logging, just analyze
- targets <- mapConcurrentlyBounded 8 analyzeOne nss
- pure <| Map.fromList <| catMaybes <| zipWith (\ns mt -> (ns,) </ mt) nss targets
- else do
- -- Normal mode: use concurrent logging
- LogC.withLineManager nss <| \lineMgr -> do
- LogC.initializeLines lineMgr
- targets <- mapConcurrentlyBounded 8 analyzeOne nss
- pure <| Map.fromList <| catMaybes <| zipWith (\ns mt -> (ns,) </ mt) nss targets
+analyzeAll _isPlanMode nss = do
+ -- Analysis runs concurrently, updating each namespace's status as it progresses
+ -- LineManager is set up by caller (move), so we just update states here
+ targets <- mapConcurrentlyBounded 8 analyzeOne nss
+ pure <| Map.fromList <| catMaybes <| zipWith (\ns mt -> (ns,) </ mt) nss targets
where
analyzeOne :: Namespace -> IO (Maybe Target)
analyzeOne namespace@(Namespace parts ext) = do
+ LogC.updateLineState namespace LogC.Analyzing
let path = Namespace.toPath namespace
root <- getCoderoot
let abspath = root </> path
@@ -1162,22 +1159,14 @@ build :: Bool -> Bool -> Int -> Int -> Analysis -> IO [Exit.ExitCode]
build andTest loud jobs cpus analysis = do
root <- getCoderoot
let targets = Map.elems analysis
- let namespaces = map (\Target {..} -> namespace) targets
- -- Use adaptive concurrent UI unless --loud is set
- if loud
- then do
- -- Loud mode: simple output, no concurrent UI
- results <- mapConcurrentlyBounded jobs (buildTarget root) targets
- pure (map fst results)
- else -- Adaptive UI based on terminal width
-
- LogC.withLineManager namespaces <| \lineMgr -> do
- LogC.initializeLines lineMgr
- results <- mapConcurrentlyBounded jobs (buildTarget root) targets
- pure (map fst results)
+ -- Build runs concurrently with --jobs parallelism
+ -- LineManager is set up by caller (move), so we just update states here
+ results <- mapConcurrentlyBounded jobs (buildTarget root) targets
+ pure (map fst results)
where
buildTarget :: FilePath -> Target -> IO (Exit.ExitCode, ByteString)
buildTarget root target@Target {..} = do
+ LogC.updateLineState namespace LogC.Building
result <- case compiler of
CPython -> case out of
Just _ ->
diff --git a/Omni/Log/Concurrent.hs b/Omni/Log/Concurrent.hs
index 93f90c1..6dc7297 100644
--- a/Omni/Log/Concurrent.hs
+++ b/Omni/Log/Concurrent.hs
@@ -124,7 +124,7 @@ initializeLines LineManager {..} = do
ANSI.hSetCursorColumn IO.stderr 0
ANSI.hClearLine IO.stderr
let nsText = Text.pack (Namespace.toPath ns)
- let msg = "[+] " <> nsText
+ let msg = "[.] " <> nsText -- Pending state before analysis starts
let truncated = truncateToWidth (tiWidth lmTermInfo - 1) msg
IO.hPutStrLn IO.stderr (Text.unpack truncated)
IO.hFlush IO.stderr
@@ -196,7 +196,9 @@ updateLineState ns buildState = do
let (symbol, color) = case buildState of
Success -> ("✓", green)
Failed -> ("x", red)
- _ -> ("~", white)
+ Analyzing -> ("+", white)
+ Pending -> (".", white)
+ Building -> ("~", white)
let msg = "[" <> symbol <> "] " <> nsText
let truncated = truncateToWidth (tiWidth lmTermInfo - 1) msg