From 0fa8ed4689022cb213de9cfb88a10841c7a03935 Mon Sep 17 00:00:00 2001 From: Ben Sima Date: Wed, 26 Nov 2025 16:45:41 -0500 Subject: Unify LineManager for analyze and build phases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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. --- Omni/Bild.hs | 43 ++++++++++++++++--------------------------- Omni/Log/Concurrent.hs | 6 ++++-- 2 files changed, 20 insertions(+), 29 deletions(-) (limited to 'Omni') 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,) do - LogC.initializeLines lineMgr - targets <- mapConcurrentlyBounded 8 analyzeOne nss - pure <| Map.fromList <| catMaybes <| zipWith (\ns mt -> (ns,) (ns,) 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 -- cgit v1.2.3