Queried and rendered on 2025-03-04T03:30:48.711137+00:00
Last active
April 9, 2025 22:19
-
-
Save ErichDonGubler/a18524d827950b64d98c51caf26fc0d3 to your computer and use it in GitHub Desktop.
Analysis of `webgpu-apps`' current blockers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cache/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# README: Use [Nushell] to run this script, like so: | |
# | |
# ``` | |
# nu ./analyze-webgpu-apps-blockers.nu | |
# ``` | |
# | |
# This will regenerate or create `summary-rendered.nu` in the CWD. | |
# | |
# [Nushell]: https://www.nushell.sh/ | |
const OPEN_STATUSES = [UNCONFIRMED NEW ASSIGNED REOPENED] | |
def query [ | |
--cache-dir: directory | null = null, | |
] { | |
print --stderr "Getting broken page bug reports blocking `webgpu-apps`…" | |
let bugs = cache --dir $cache_dir --query-name "webgpu-apps-blockers" { | |
query-bugs { | |
resolution: '---' | |
component: 'Graphics: WebGPU' | |
f1: blocked | |
o1: casesubstring | |
v1: "1849916" # webgpu-apps | |
bug_status: $OPEN_STATUSES | |
} | |
} | |
print --stderr "Querying info about broken pages' individual blockers…" | |
let bugs_by_blocker_id = $bugs | |
| insert deps_flattened { $in.depends_on } | |
| flatten deps_flattened | |
| group-by --to-table deps_flattened | |
| sort-by deps_flattened | |
| rename --column { deps_flattened: dependency items: blocks } | |
| sort-by --reverse { $in.blocks | length } | |
| update blocks { select id summary } | |
let blocker_ids = ($bugs_by_blocker_id | get dependency) | |
let blockers_by_id = cache --dir $cache_dir --query-name "webgpu-apps-blockers-blockers" { | |
query-bugs { id: $blocker_ids } | |
} | |
| select id summary status assigned_to_detail.nick | |
print --stderr "Analyzing relationships between broken pages and their blockers…" | |
let blockers_by_id = $blockers_by_id | |
| select id summary status "assigned_to_detail.nick" | |
| reduce --fold {} {|entry, acc| | |
$acc | insert ($entry.id | into string) { $entry | reject id } | |
} | |
let blocking_relationships = $bugs_by_blocker_id | |
| update dependency { | |
let id = $in | |
let entry = $blockers_by_id | get $id | |
{ | |
id: $id | |
...$entry | |
} | |
} | |
| flatten --all dependency | |
let bugs_with_no_open_blockers = $bugs | |
| filter {|bug| | |
$bug.depends_on | all {|id| | |
let status = $blockers_by_id | get ($id | into string) | get status | |
$status not-in $OPEN_STATUSES | |
} | |
} | |
| update id { into string } | |
| select id priority severity summary product component status assigned_to_detail.nick | |
| sort-by { get priority | priority-ordinal } { get severity | severity-ordinal } | |
let bug_ids_with_no_open_blockers = $bugs_with_no_open_blockers | get id | |
let blockers = $blocking_relationships | where status in $OPEN_STATUSES | |
{ | |
blockers: $blockers | |
bugs_with_no_open_blockers: $bugs_with_no_open_blockers | |
} | |
} | |
# Reports blockers on Firefox's # [`webgpu-apps`] issue tracking in `./summary-rendered.md`. | |
# | |
# [`webgpu-apps`]: https://bugzilla.mozilla.org/show_bug.cgi?id=webgpu-apps | |
export def main [ | |
--blockers-limit: int = 10, | |
# How many rows to populate in the unresolved blockers table. | |
--cache-dir: directory | null = null, | |
# Cache responses to a single directory. WARNING: _very_ basic (and error-prone) | |
] { | |
let report_start_datetime = cache --dir $cache_dir --query-name "current-time" { | |
date now | date to-timezone '+0000' | |
} | |
let queried = query --cache-dir $cache_dir | |
let merge_id_and_summary = {|entry| | |
$entry | |
# NOTE: work around `|`s needing escape in Markdown tables | |
| update summary { str replace '|' '\|' } | |
| insert bug { | |
$"[Bug ($in.id) - ($in.summary)]\(https://bugzilla.mozilla.org/show_bug.cgi?id=($in.id)\)" | |
} | |
| move --first bug | |
| reject id | |
| reject summary | |
| rename --column { "assigned_to_detail.nick": "assignee" } | |
} | |
let blockers = $queried | |
| get blockers | |
| update blocks { length } | |
| each $merge_id_and_summary | |
let blockers = if $blockers_limit > 0 { | |
$blockers | first $blockers_limit | |
} else { | |
$blockers | |
} | |
let bugs_with_no_open_blockers = $queried | |
| get bugs_with_no_open_blockers | |
| each $merge_id_and_summary | |
| move priority severity --first | |
let report_path = "./summary-rendered.md" | |
print --stderr $"Rendering to `($report_path)`…" | |
let rendered = [ | |
$"Queried and rendered on ($report_start_datetime | format date '%+')" | |
"## Top blockers" | |
($blockers | to md --pretty) | |
"## Bugs with no open blockers" | |
($bugs_with_no_open_blockers | to md --pretty) | |
] | str join "\n\n" | $"($in)\n" | |
$rendered o> $report_path | |
} | |
def query-bugs [ | |
bug_search_criteria, | |
] { | |
let query_params = ($bug_search_criteria | url build-query) | |
http get $"https:/bugzilla.mozilla.org/rest/bug?($query_params)" | get bugs | |
} | |
export def cache [ | |
f: closure, | |
--dir: directory | null = null, | |
--query-name: string | null = null, | |
] { | |
let cache_path = if ($dir != null) and ($query_name != null) { | |
[$dir $"($query_name).json"] | path join | |
} else { | |
null | |
} | |
if ($cache_path != null) and ($cache_path | path exists) { | |
return (open $cache_path) | |
} | |
let output = do $f | |
if $cache_path != null { | |
mkdir ($cache_path | path dirname) | |
$output | save $cache_path | |
} | |
$output | |
} | |
def priority-ordinal []: string -> int { | |
let priority = $in | |
let parsed = $priority | parse "P{num}" | |
if ($parsed | is-not-empty) { | |
$parsed | first | |
} else { | |
match $priority { | |
"N/A" => 10, | |
"---" => 11, | |
} | |
} | |
} | |
def severity-ordinal []: string -> int { | |
let sev = $in | |
let parsed = $sev | parse "S{num}" | |
if ($parsed | is-not-empty) { | |
$parsed | first | |
} else { | |
match $sev { | |
"N/A" => 10, | |
"---" => 11, | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Known issues: