diff options
| author | Ben Sima <ben@bensima.com> | 2025-11-26 16:45:41 -0500 |
|---|---|---|
| committer | Ben Sima <ben@bensima.com> | 2025-11-26 16:45:41 -0500 |
| commit | 0fa8ed4689022cb213de9cfb88a10841c7a03935 (patch) | |
| tree | 42c564d8e17e9998ebab912b0adc75a9d9867b08 /Omni | |
| parent | 4082065308d9e7c4c8c2286c08e475ba64ce6a03 (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.hs | 43 | ||||
| -rw-r--r-- | Omni/Log/Concurrent.hs | 6 |
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 |
