From 2e667b6b3acb07f585449ab970ebdbc376ec1a87 Mon Sep 17 00:00:00 2001 From: Ben Sima Date: Mon, 22 Mar 2021 10:54:30 -0400 Subject: Add descriptions to report details --- Biz/Bild/Deps/Haskell.nix | 1 + Biz/Devalloc.hs | 75 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/Biz/Bild/Deps/Haskell.nix b/Biz/Bild/Deps/Haskell.nix index 4434cb3..4fd2d85 100644 --- a/Biz/Bild/Deps/Haskell.nix +++ b/Biz/Bild/Deps/Haskell.nix @@ -33,6 +33,7 @@ with hpkgs; monad-logger monad-metrics mtl + neat-interpolation network-uri optparse-simple parsec diff --git a/Biz/Devalloc.hs b/Biz/Devalloc.hs index 0f6bf94..4e2efdb 100644 --- a/Biz/Devalloc.hs +++ b/Biz/Devalloc.hs @@ -34,6 +34,7 @@ -- : dep http-api-data -- : dep ixset -- : dep lucid +-- : dep neat-interpolation -- : dep protolude -- : dep rainbow -- : dep req @@ -101,6 +102,7 @@ import qualified GitHub import qualified Lucid import qualified Lucid.Base as Lucid import qualified Lucid.Servant as Lucid +import NeatInterpolation import Network.HTTP.Req ((/:), (=:)) import qualified Network.HTTP.Req as Req import qualified Network.Wai as Wai @@ -1073,10 +1075,10 @@ instance Lucid.ToHtml Home where \ This happens too often with legacy code, and then it turns into a huge source of tech debt. \ \ Devalloc finds these \"blackholes\" and warns you about them so you can be proactive in eliminating tech debt." section <| do - h2 "Find developer hot spots" + h2 "Find developer hotspots" p "Which pieces of code get continually rewritten, taking up valuable dev time? \ - \ Find these module hot spots before they become a costly time-sink." + \ Find these module hotspots before they become a costly time-sink." section <| do h2 "See an example analysis" maybe @@ -1411,6 +1413,20 @@ instance Lucid.ToHtml Analysis where quantity_ <| Lucid.toHtml <| tshow score centum_ "/100" previewChart <| simpleBar score 100 + Lucid.details_ <| do + Lucid.summary_ "Details" + desc + [text| + Your score is a weighted composite of the below metrics. + What your score means: + - 0-30: very high risk, most of your codebase is unknown or ephemeral + - 30-60: medium-high risk, tasks that involve working on this + codebase will take longer than they should, and we should expect + a few unforeseen bugs + - 60-80: medium-low risk, tasks in this codebase can be expected to + complete in the estimated time, and it probably doesn't have many bugs + - 80+: low risk, your codebase is super clean, give your devs a raise + |] score_ <| do title_ "Total Files" @@ -1430,6 +1446,19 @@ instance Lucid.ToHtml Analysis where previewChart <| simpleBar (len blackholes) totalFiles Lucid.details_ <| do Lucid.summary_ "Details" + desc + [text| + A blackhole has zero active contributors, so none of your current team + members have touched this code. These are very high risk. If there is + a problem with this area of the codebase, it will take longer for your + team to diagnose and fix the root cause; new features that interact + with a blackhole will take longer to deploy. + + **What you can do:** Start a project to ensure these blackholes are + well-defined and documented. If anything is completely unknown, write + tests against that part of the code as it currently stands, then decide + if a rewrite is necessary. + |] Lucid.ul_ <| do traverse_ (Lucid.toHtml .> Lucid.li_) blackholes @@ -1439,6 +1468,20 @@ instance Lucid.ToHtml Analysis where previewChart <| simpleBar (len liabilities) totalFiles Lucid.details_ <| do Lucid.summary_ "Details" + desc + [text| + Files with < 3 active contributors. These are at risk of becoming + blackholes if contributors change teams or leave the company. + + **What you can do:** Next time a task involves one of these files, + pull in some team members that haven't worked on this area of the + codebase. + + In general, when assigning tasks, ensure developers are occasionally + working on areas of the codebase that are new to them. Not only will + this decrease your liability, it will also improve your developers + by helping them learn new areas of the code and share techniques. + |] Lucid.ul_ <| do traverse_ (Lucid.toHtml .> Lucid.li_) liabilities @@ -1448,6 +1491,18 @@ instance Lucid.ToHtml Analysis where previewChart <| simpleBar (len stale) totalFiles Lucid.details_ <| do Lucid.summary_ "Details" + desc + [text| + Files that haven't been touched in 6 months. These aren't necessarily + a risk: unchanging files could just be really well-defined and stable. + On the other hand, they could also be places that nobody wants to go + because nobody knows how they work. + + **What you can do:** Run this list by your team and find out who has + knowledge of this area. If nobody does, start a project to + investigate and re-define this part of the codebase, ensuring good + documentation practices along the way. + |] Lucid.ul_ <| do forM_ stale <| \(path, days) -> Lucid.li_ <| Lucid.toHtml <| path <> " (" <> show days <> " days)" @@ -1462,6 +1517,20 @@ instance Lucid.ToHtml Analysis where Lucid.td_ [Lucid.style_ <| size n totalCommits] "" Lucid.details_ <| do Lucid.summary_ "Details" + desc + [text| + A hotspot is an over-active code module: developers are continually + reworking this part of the code, wasting time redoing work instead + of progressing. + The flamegraph below plots files by how often they are changed, a + longer horizontal line means more changes. Hover over the bars to + see filenames and change count. + + **What you can do:** After identifying the hotspots, discuss with your + team how to improve the code. Why does the code change so often? Does + it need a more well-defined spec? Does it need a deep refactor? Maybe + part of it can be abstracted into a more solid module? + |] Lucid.table_ [Lucid.class_ "charts-css bar"] <| do Lucid.tr_ <| do forM_ (Map.toList hotspotMap) <| \(path, n) -> do @@ -1487,6 +1556,8 @@ instance Lucid.ToHtml Analysis where percentage_ = div_ "percentage" size n total = "--size: calc(" <> show n <> "/" <> show total <> ")" previewChart = div_ "preview-chart" + desc :: Monad m => Text -> Lucid.HtmlT m () + desc = Lucid.p_ <. Cmark.renderNode [] <. Cmark.commonmarkToNode [] -- | Run a full analysis on a git repo analyze :: Acid.AcidState Keep -> Id.Id User -> [Text] -> URL -> FilePath -> Bool -> IO Analysis -- cgit v1.2.3