From 2444dbaa079902f243744c0861d33cab9d1e5c4f Mon Sep 17 00:00:00 2001 From: Ben Sima Date: Tue, 30 Mar 2021 16:05:41 -0400 Subject: Move Analysis class instances near type definition --- Biz/Devalloc.hs | 428 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 214 insertions(+), 214 deletions(-) diff --git a/Biz/Devalloc.hs b/Biz/Devalloc.hs index b58068c..7112020 100644 --- a/Biz/Devalloc.hs +++ b/Biz/Devalloc.hs @@ -348,6 +348,220 @@ instance Indexable Analysis where ixFun <| \Analysis {..} -> [repoVisibility] ] +instance App.HasCss Analysis where + cssFor _ = do + "#analysis > *" ? do + Biz.Look.marginAll (rem 2) + ".score" ? do + Clay.display Clay.grid + Biz.Look.gridTemplateAreas + [ "title quantity details-collapsed", + "preview-chart preview-chart preview-chart", + "details details details" + ] + Clay.alignItems Clay.baseline + Clay.gridTemplateColumns [pct 30, 40, 30] + Biz.Look.gridTemplateRows ["auto"] + ".title" ? do + Biz.Look.gridArea "title" + Clay.fontSize (rem 1.4) + Clay.lineHeight (rem 2.4) + ".percentage" ? do + Biz.Look.gridArea "quantity" + Clay.display Clay.flex + Clay.alignItems Clay.baseline + ".centum" ? do + Clay.fontSize (rem 1.2) + Clay.lineHeight (rem 1.2) + ".quantity" ? do + Biz.Look.gridArea "quantity" + Clay.fontSize (rem 3) + Clay.lineHeight (rem 3) + ".preview-chart" ? do + Biz.Look.gridArea "preview-chart" + "details" ? do + Biz.Look.gridArea "details-collapsed" + Biz.Look.justifySelf <| Clay.JustifyContentValue "self-end" + "details[open]" ? do + Biz.Look.gridArea "details" + Biz.Look.justifySelf <| Clay.JustifyContentValue "auto" + ".preview-chart" ? do + Clay.height (px 2) + Clay.maxWidth (pct 100) + "table" ? do + Biz.Look.marginAll (px 0) + Clay.maxWidth (pct 100) + "#hotspots" ? do + ".preview-chart" ? do + Clay.height (rem 1) + "table" ? do + Clay.height (rem 4) + Clay.marginTop (rem (-3)) + Clay.zIndex (-1) + ".bar" ? do + Clay.height (px 800) + +instance Lucid.ToHtml Analysis where + toHtmlRaw = Lucid.toHtml + toHtml Analysis {..} = + Lucid.div_ [Lucid.id_ "analysis"] <| do + Lucid.p_ [Lucid.class_ "analysisFor"] <| do + "Analysis for " + Lucid.a_ [Lucid.href_ <| (\(URL txt) -> txt) <| url] <| do + Lucid.toHtml url + + score_ <| do + title_ "Total Score" + percentage_ <| do + 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" + quantity_ <| Lucid.toHtml <| tshow totalFiles + + score_ <| do + title_ "Active authors" + quantity_ <| Lucid.toHtml <| slen activeAuthors + Lucid.details_ <| do + Lucid.summary_ "Details" + Lucid.ul_ <| forM_ activeAuthors <| \author -> do + Lucid.li_ <| Lucid.toHtml author + + score_ <| do + title_ "Blackholes" + quantity_ <| Lucid.toHtml <| slen blackholes + 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 + + score_ <| do + title_ "Liabilities" + quantity_ <| Lucid.toHtml <| slen liabilities + 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 + + score_ <| do + title_ "Stale files" + quantity_ <| Lucid.toHtml <| slen stale + 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)" + + Lucid.with score_ [Lucid.id_ "hotspots"] <| do + title_ "Hotspots" + quantity_ "" -- TODO + previewChart <| do + Lucid.table_ [Lucid.class_ "charts-css column"] <| do + Lucid.tr_ <| do + forM_ (Map.toList hotspotMap) <| \(_, n) -> do + 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 + Lucid.td_ [Lucid.style_ <| size n totalCommits] <| do + Lucid.span_ [Lucid.class_ "tooltip"] + <| Lucid.toHtml + <| path <> ": " <> show n <> " commits" + where + simpleBar :: Monad m => Integer -> Integer -> Lucid.HtmlT m () + simpleBar n total = do + Lucid.table_ [Lucid.class_ "charts-css bar stacked multiple"] <| do + Lucid.tr_ <| do + Lucid.td_ [Lucid.style_ <| size n total] "" + <> Lucid.td_ [Lucid.style_ <| size total total] "" + + len = toInteger <. length + slen = tshow <. length + div_ c = Lucid.with Lucid.div_ [Lucid.class_ c] + score_ = div_ "score" + title_ = div_ "title" + quantity_ = div_ "quantity" + centum_ = div_ "centum" + 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 [] + -- | The database. data Keep = Keep { users :: IxSet User, @@ -1411,220 +1625,6 @@ instance Lucid.ToHtml AnalysisDisplay where Lucid.toHtml anal footer -instance App.HasCss Analysis where - cssFor _ = do - "#analysis > *" ? do - Biz.Look.marginAll (rem 2) - ".score" ? do - Clay.display Clay.grid - Biz.Look.gridTemplateAreas - [ "title quantity details-collapsed", - "preview-chart preview-chart preview-chart", - "details details details" - ] - Clay.alignItems Clay.baseline - Clay.gridTemplateColumns [pct 30, 40, 30] - Biz.Look.gridTemplateRows ["auto"] - ".title" ? do - Biz.Look.gridArea "title" - Clay.fontSize (rem 1.4) - Clay.lineHeight (rem 2.4) - ".percentage" ? do - Biz.Look.gridArea "quantity" - Clay.display Clay.flex - Clay.alignItems Clay.baseline - ".centum" ? do - Clay.fontSize (rem 1.2) - Clay.lineHeight (rem 1.2) - ".quantity" ? do - Biz.Look.gridArea "quantity" - Clay.fontSize (rem 3) - Clay.lineHeight (rem 3) - ".preview-chart" ? do - Biz.Look.gridArea "preview-chart" - "details" ? do - Biz.Look.gridArea "details-collapsed" - Biz.Look.justifySelf <| Clay.JustifyContentValue "self-end" - "details[open]" ? do - Biz.Look.gridArea "details" - Biz.Look.justifySelf <| Clay.JustifyContentValue "auto" - ".preview-chart" ? do - Clay.height (px 2) - Clay.maxWidth (pct 100) - "table" ? do - Biz.Look.marginAll (px 0) - Clay.maxWidth (pct 100) - "#hotspots" ? do - ".preview-chart" ? do - Clay.height (rem 1) - "table" ? do - Clay.height (rem 4) - Clay.marginTop (rem (-3)) - Clay.zIndex (-1) - ".bar" ? do - Clay.height (px 800) - -instance Lucid.ToHtml Analysis where - toHtmlRaw = Lucid.toHtml - toHtml Analysis {..} = - Lucid.div_ [Lucid.id_ "analysis"] <| do - Lucid.p_ [Lucid.class_ "analysisFor"] <| do - "Analysis for " - Lucid.a_ [Lucid.href_ <| (\(URL txt) -> txt) <| url] <| do - Lucid.toHtml url - - score_ <| do - title_ "Total Score" - percentage_ <| do - 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" - quantity_ <| Lucid.toHtml <| tshow totalFiles - - score_ <| do - title_ "Active authors" - quantity_ <| Lucid.toHtml <| slen activeAuthors - Lucid.details_ <| do - Lucid.summary_ "Details" - Lucid.ul_ <| forM_ activeAuthors <| \author -> do - Lucid.li_ <| Lucid.toHtml author - - score_ <| do - title_ "Blackholes" - quantity_ <| Lucid.toHtml <| slen blackholes - 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 - - score_ <| do - title_ "Liabilities" - quantity_ <| Lucid.toHtml <| slen liabilities - 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 - - score_ <| do - title_ "Stale files" - quantity_ <| Lucid.toHtml <| slen stale - 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)" - - Lucid.with score_ [Lucid.id_ "hotspots"] <| do - title_ "Hotspots" - quantity_ "" -- TODO - previewChart <| do - Lucid.table_ [Lucid.class_ "charts-css column"] <| do - Lucid.tr_ <| do - forM_ (Map.toList hotspotMap) <| \(_, n) -> do - 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 - Lucid.td_ [Lucid.style_ <| size n totalCommits] <| do - Lucid.span_ [Lucid.class_ "tooltip"] - <| Lucid.toHtml - <| path <> ": " <> show n <> " commits" - where - simpleBar :: Monad m => Integer -> Integer -> Lucid.HtmlT m () - simpleBar n total = do - Lucid.table_ [Lucid.class_ "charts-css bar stacked multiple"] <| do - Lucid.tr_ <| do - Lucid.td_ [Lucid.style_ <| size n total] "" - <> Lucid.td_ [Lucid.style_ <| size total total] "" - - len = toInteger <. length - slen = tshow <. length - div_ c = Lucid.with Lucid.div_ [Lucid.class_ c] - score_ = div_ "score" - title_ = div_ "title" - quantity_ = div_ "quantity" - centum_ = div_ "centum" - 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 analyze keep askedBy activeAuthors url bareRepo repoPrivate = do -- cgit v1.2.3