github-security-report 0.20.0__tar.gz → 0.21.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {github_security_report-0.20.0 → github_security_report-0.21.0}/PKG-INFO +18 -17
- {github_security_report-0.20.0 → github_security_report-0.21.0}/README.md +17 -16
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/_version.py +2 -2
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/cli/progress.py +62 -42
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/cli/serialise.py +2 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/malware.py +4 -2
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/render/html.py +2 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/render/markdown.py +3 -1
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/render/terminal.py +6 -1
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/templates/report.html.j2 +1 -1
- {github_security_report-0.20.0 → github_security_report-0.21.0}/.gitignore +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/LICENSE +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/LICENSES/Apache-2.0.txt +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/pyproject.toml +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/scripts/README.md +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/__init__.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/authors.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/categories/__init__.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/categories/keys.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/categories/signals.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/categories/tables.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/classify.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/cli/__init__.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/cli/__main__.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/cli/app.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/cli/boundary.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/cli/modes.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/cli/options.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/cli/outputs.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/cli/publish.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/cli/remediation.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/cli/summary.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/client/__init__.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/client/accounting.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/client/alerts.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/client/analyses.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/client/batch_errors.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/client/codeql_parsers.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/client/copilot.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/client/endpoints.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/client/errors.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/client/events.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/client/failures.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/client/org_reads.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/client/paging.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/client/parsers.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/client/queries.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/client/reads.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/client/repo_parser.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/client/reviews.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/client/transport.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/client/workflow_runs.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/client/writes.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/code_quality.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/codeql/__init__.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/codeql/cleanup.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/codeql/facts.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/codeql/tables.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/collect/__init__.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/collect/codeql.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/collect/context.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/collect/extras.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/collect/graph.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/collect/org.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/collect/protocols.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/collect/repo.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/collect/run_sync.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/collect/scoping.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/collect/workflow_runs.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/config/__init__.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/config/blocks.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/config/loader.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/config/models.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/config/order.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/config/schema.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/gating.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/gitctx.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/issue_presentation.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/issues.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/layout.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/models.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/ordering.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/posture/__init__.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/posture/enablement.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/posture/facts.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/posture/quality.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/posture/releases.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/pulls/__init__.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/pulls/columns.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/pulls/counting.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/pulls/presentation.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/pulls/table.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/py.typed +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/ranking.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/remediate/__init__.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/remediate/codeql.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/remediate/model.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/render/__init__.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/render/slack.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/render/slack_limits.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/render/slack_text.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/render/terminal_notices.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/report/__init__.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/report/aggregate.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/report/display.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/report/signals.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/report/tables.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/rulesets.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/runner.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/scope.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/secret_patterns.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/severity.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/summary.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/templates/index.html.j2 +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/workflow_runs/__init__.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/workflow_runs/aggregate.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/workflow_runs/models.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/workflow_runs/store.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/workflow_runs/store_codec.py +0 -0
- {github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/workflow_runs/tables.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: github-security-report
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.21.0
|
|
4
4
|
Summary: Security and quality reporting across GitHub organisations
|
|
5
5
|
Project-URL: Homepage, https://github.com/lfreleng-actions/github-security-report-action
|
|
6
6
|
Project-URL: Repository, https://github.com/lfreleng-actions/github-security-report-action
|
|
@@ -1850,24 +1850,25 @@ Repo mode leaves nothing behind.
|
|
|
1850
1850
|
|
|
1851
1851
|
### Progress and run summary
|
|
1852
1852
|
|
|
1853
|
-
On an interactive terminal an org-mode run keeps
|
|
1854
|
-
of the screen while it collects
|
|
1855
|
-
|
|
1856
|
-
request counts with how many are in flight, and
|
|
1857
|
-
|
|
1853
|
+
On an interactive terminal an org-mode run keeps three live lines at the
|
|
1854
|
+
bottom of the screen while it collects, one kind of information each: where
|
|
1855
|
+
the run is (the organisation and the phase it is in), its API traffic (the
|
|
1856
|
+
REST and GraphQL request counts with how many are in flight, and external
|
|
1857
|
+
requests once there are any), and its progress (the elapsed time, the
|
|
1858
|
+
repository count where the phase works per repository, and a countdown while
|
|
1859
|
+
GitHub has the run paused for a rate limit). A fourth line appears while the
|
|
1858
1860
|
workflow-run store is being built for the first time, since that one-off
|
|
1859
|
-
dominates a cold run.
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1861
|
+
dominates a cold run. Each line stays one line: on a terminal too narrow for
|
|
1862
|
+
it, it is cut short with an ellipsis rather than wrapped, and the elapsed
|
|
1863
|
+
time, leading its line, is the last thing to go. Warnings logged in the
|
|
1864
|
+
meantime are held and replayed, in order, once the display comes down.
|
|
1863
1865
|
|
|
1864
1866
|
```text
|
|
1865
|
-
⠧ lfreleng-actions · probing repositories
|
|
1866
|
-
|
|
1867
|
+
⠧ lfreleng-actions · probing repositories
|
|
1868
|
+
REST 812 (9 in flight) · GraphQL 24
|
|
1869
|
+
38.2 s · 41/120 repos · ⏳ rate limited by GitHub (core); resuming in 42 s
|
|
1867
1870
|
```
|
|
1868
1871
|
|
|
1869
|
-
<!-- markdownlint-enable MD013 -->
|
|
1870
|
-
|
|
1871
1872
|
Before each organisation's report, a dim three-line summary says what the
|
|
1872
1873
|
run cost and what the store holds, so a slow run explains itself without
|
|
1873
1874
|
`--verbose`:
|
|
@@ -1890,9 +1891,9 @@ reads `in memory (not cached)` and, since its store is empty every time, is
|
|
|
1890
1891
|
never a first run. The summary is for the terminal only: nothing of it
|
|
1891
1892
|
reaches the Markdown, HTML, JSON or Slack output.
|
|
1892
1893
|
|
|
1893
|
-
The live
|
|
1894
|
-
not a terminal, and with `--verbose`, whose log lines would fight it for
|
|
1895
|
-
screen. The summary prints in every case. The same figures reach the log at
|
|
1894
|
+
The live display is off under `--no-progress`, when `CI` is set, when stdout
|
|
1895
|
+
is not a terminal, and with `--verbose`, whose log lines would fight it for
|
|
1896
|
+
the screen. The summary prints in every case. The same figures reach the log at
|
|
1896
1897
|
`INFO` under `--verbose`.
|
|
1897
1898
|
|
|
1898
1899
|
### GitHub Enterprise Server
|
|
@@ -1806,24 +1806,25 @@ Repo mode leaves nothing behind.
|
|
|
1806
1806
|
|
|
1807
1807
|
### Progress and run summary
|
|
1808
1808
|
|
|
1809
|
-
On an interactive terminal an org-mode run keeps
|
|
1810
|
-
of the screen while it collects
|
|
1811
|
-
|
|
1812
|
-
request counts with how many are in flight, and
|
|
1813
|
-
|
|
1809
|
+
On an interactive terminal an org-mode run keeps three live lines at the
|
|
1810
|
+
bottom of the screen while it collects, one kind of information each: where
|
|
1811
|
+
the run is (the organisation and the phase it is in), its API traffic (the
|
|
1812
|
+
REST and GraphQL request counts with how many are in flight, and external
|
|
1813
|
+
requests once there are any), and its progress (the elapsed time, the
|
|
1814
|
+
repository count where the phase works per repository, and a countdown while
|
|
1815
|
+
GitHub has the run paused for a rate limit). A fourth line appears while the
|
|
1814
1816
|
workflow-run store is being built for the first time, since that one-off
|
|
1815
|
-
dominates a cold run.
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1817
|
+
dominates a cold run. Each line stays one line: on a terminal too narrow for
|
|
1818
|
+
it, it is cut short with an ellipsis rather than wrapped, and the elapsed
|
|
1819
|
+
time, leading its line, is the last thing to go. Warnings logged in the
|
|
1820
|
+
meantime are held and replayed, in order, once the display comes down.
|
|
1819
1821
|
|
|
1820
1822
|
```text
|
|
1821
|
-
⠧ lfreleng-actions · probing repositories
|
|
1822
|
-
|
|
1823
|
+
⠧ lfreleng-actions · probing repositories
|
|
1824
|
+
REST 812 (9 in flight) · GraphQL 24
|
|
1825
|
+
38.2 s · 41/120 repos · ⏳ rate limited by GitHub (core); resuming in 42 s
|
|
1823
1826
|
```
|
|
1824
1827
|
|
|
1825
|
-
<!-- markdownlint-enable MD013 -->
|
|
1826
|
-
|
|
1827
1828
|
Before each organisation's report, a dim three-line summary says what the
|
|
1828
1829
|
run cost and what the store holds, so a slow run explains itself without
|
|
1829
1830
|
`--verbose`:
|
|
@@ -1846,9 +1847,9 @@ reads `in memory (not cached)` and, since its store is empty every time, is
|
|
|
1846
1847
|
never a first run. The summary is for the terminal only: nothing of it
|
|
1847
1848
|
reaches the Markdown, HTML, JSON or Slack output.
|
|
1848
1849
|
|
|
1849
|
-
The live
|
|
1850
|
-
not a terminal, and with `--verbose`, whose log lines would fight it for
|
|
1851
|
-
screen. The summary prints in every case. The same figures reach the log at
|
|
1850
|
+
The live display is off under `--no-progress`, when `CI` is set, when stdout
|
|
1851
|
+
is not a terminal, and with `--verbose`, whose log lines would fight it for
|
|
1852
|
+
the screen. The summary prints in every case. The same figures reach the log at
|
|
1852
1853
|
`INFO` under `--verbose`.
|
|
1853
1854
|
|
|
1854
1855
|
### GitHub Enterprise Server
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.
|
|
22
|
-
__version_tuple__ = version_tuple = (0,
|
|
21
|
+
__version__ = version = '0.21.0'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 21, 0)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -6,14 +6,20 @@
|
|
|
6
6
|
:class:`~github_security_report.client.events.ProgressSink` the transport
|
|
7
7
|
reports requests to and the
|
|
8
8
|
:class:`~github_security_report.collect.context.CollectProgress` the
|
|
9
|
-
collectors name their phases through, and renders what it hears as
|
|
10
|
-
``Live``
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
the
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
collectors name their phases through, and renders what it hears as a Rich
|
|
10
|
+
``Live`` display of three lines per organisation, one category each so none
|
|
11
|
+
is cut short on an 80-column terminal:
|
|
12
|
+
|
|
13
|
+
1. where the run is: a spinner, the organisation and the phase;
|
|
14
|
+
2. API traffic: the REST and GraphQL request counts with how many are in
|
|
15
|
+
flight, and the external count once one has been made;
|
|
16
|
+
3. progress: the clock, the repository count where the phase is
|
|
17
|
+
per-repository, and a rate-limit backoff's countdown while it lasts.
|
|
18
|
+
|
|
19
|
+
A fourth line appears only while the workflow-run store is built for the
|
|
20
|
+
first time, a notice too long to share the third.
|
|
21
|
+
|
|
22
|
+
While the display is on screen, WARNINGs bound for the terminal are held and
|
|
17
23
|
replayed once it stops, so a transport warning cannot tear through it and the
|
|
18
24
|
operator still reads every one, in order, in a single block before the run
|
|
19
25
|
summary. Off (a :class:`NullTracker`) in CI, when stdout is not a terminal,
|
|
@@ -167,7 +173,7 @@ class _LogHold:
|
|
|
167
173
|
|
|
168
174
|
|
|
169
175
|
class RunTracker:
|
|
170
|
-
"""One organisation's live progress
|
|
176
|
+
"""One organisation's live progress display (see the module docstring)."""
|
|
171
177
|
|
|
172
178
|
def __init__(
|
|
173
179
|
self, console: Console, *, clock: Callable[[], float] = time.monotonic
|
|
@@ -193,7 +199,7 @@ class RunTracker:
|
|
|
193
199
|
|
|
194
200
|
# -- lifecycle ----------------------------------------------------------
|
|
195
201
|
def start(self, org: str) -> None:
|
|
196
|
-
"""Reset the counters for ``org`` and put the
|
|
202
|
+
"""Reset the counters for ``org`` and put the display on screen."""
|
|
197
203
|
self._org = org
|
|
198
204
|
self._started = self._clock()
|
|
199
205
|
self._stopped = None
|
|
@@ -221,7 +227,7 @@ class RunTracker:
|
|
|
221
227
|
self._live = live
|
|
222
228
|
|
|
223
229
|
def stop(self) -> None:
|
|
224
|
-
"""Freeze the
|
|
230
|
+
"""Freeze the display, take it down and replay held warnings.
|
|
225
231
|
|
|
226
232
|
Best effort: callers run this from ``finally``, so a display that
|
|
227
233
|
fails to draw its last frame must neither replace the error the run
|
|
@@ -294,56 +300,70 @@ class RunTracker:
|
|
|
294
300
|
def _clock_text(self) -> str:
|
|
295
301
|
return f"{self._elapsed():.1f} s"
|
|
296
302
|
|
|
297
|
-
def
|
|
298
|
-
"""The line
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
303
|
+
def _where(self) -> str:
|
|
304
|
+
"""The first line's text: the organisation and the phase."""
|
|
305
|
+
phase = self._phase if self._stopped is None else "done"
|
|
306
|
+
return f"{self._org} · {phase}"
|
|
307
|
+
|
|
308
|
+
def _traffic(self) -> str:
|
|
309
|
+
"""The second line: the request counts by kind."""
|
|
310
|
+
parts = [self._count("REST", "rest"), self._count("GraphQL", "graphql")]
|
|
304
311
|
if self._requests.get("external"):
|
|
305
312
|
parts.append(self._count("external", "external"))
|
|
306
313
|
return " · ".join(parts)
|
|
307
314
|
|
|
308
|
-
def
|
|
309
|
-
"""The
|
|
310
|
-
|
|
315
|
+
def _backoff(self) -> str | None:
|
|
316
|
+
"""The rate-limit countdown, while a backoff is in progress."""
|
|
317
|
+
if not self._backoffs:
|
|
318
|
+
return None
|
|
319
|
+
wait = max(0.0, self._resume_at - self._clock())
|
|
320
|
+
where = f" ({self._limited_resource})" if self._limited_resource else ""
|
|
321
|
+
return f"⏳ rate limited by GitHub{where}; resuming in {wait:.0f} s"
|
|
322
|
+
|
|
323
|
+
def _progress(self) -> str:
|
|
324
|
+
"""The third line, clock first so truncation takes it last."""
|
|
325
|
+
parts = [self._clock_text()]
|
|
326
|
+
if self._repos_total is not None:
|
|
327
|
+
parts.append(f"{self._repos_done}/{self._repos_total} repos")
|
|
328
|
+
backoff = self._backoff()
|
|
329
|
+
if backoff is not None:
|
|
330
|
+
parts.append(backoff)
|
|
331
|
+
return " · ".join(parts)
|
|
311
332
|
|
|
312
|
-
def
|
|
313
|
-
"""The
|
|
314
|
-
|
|
315
|
-
wait = max(0.0, self._resume_at - self._clock())
|
|
316
|
-
where = f" ({self._limited_resource})" if self._limited_resource else ""
|
|
317
|
-
return "⏳", f"rate limited by GitHub{where}; resuming in {wait:.0f} s"
|
|
333
|
+
def lines(self) -> list[str]:
|
|
334
|
+
"""The display as plain text, one string per row, without the spinner."""
|
|
335
|
+
rows = [self._where(), self._traffic(), self._progress()]
|
|
318
336
|
if self._notice:
|
|
319
|
-
|
|
320
|
-
return
|
|
337
|
+
rows.append(f"📦 {self._notice}")
|
|
338
|
+
return rows
|
|
321
339
|
|
|
322
340
|
@staticmethod
|
|
323
341
|
def _cell(text: str, style: str = "") -> Text:
|
|
324
342
|
return Text(text, style=style, no_wrap=True, overflow="ellipsis")
|
|
325
343
|
|
|
326
344
|
def render(self) -> RenderableType:
|
|
327
|
-
"""
|
|
328
|
-
|
|
329
|
-
Each row is one line:
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
345
|
+
"""Three or four physical lines, however narrow the terminal.
|
|
346
|
+
|
|
347
|
+
Each row is one line: its text truncates with an ellipsis rather than
|
|
348
|
+
wrapping, since a wrapped line is as unreadable as a torn one. The
|
|
349
|
+
clock leads the third row so it is the last thing on it to go: it is
|
|
350
|
+
what tells a stalled run from a slow one. The rows after the first
|
|
351
|
+
leave the spinner's column empty, so their text aligns under the
|
|
352
|
+
first row's.
|
|
334
353
|
"""
|
|
335
354
|
grid = Table.grid(padding=(0, 1))
|
|
336
355
|
grid.add_column(no_wrap=True)
|
|
337
356
|
grid.add_column()
|
|
338
|
-
grid.add_column(no_wrap=True)
|
|
339
357
|
marker: RenderableType = (
|
|
340
358
|
self._spinner if self._stopped is None else Text("✓", style="green")
|
|
341
359
|
)
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
360
|
+
where, traffic, progress, *notice = self.lines()
|
|
361
|
+
grid.add_row(marker, self._cell(where))
|
|
362
|
+
grid.add_row("", self._cell(traffic))
|
|
363
|
+
style = "yellow" if self._backoffs else ""
|
|
364
|
+
grid.add_row("", self._cell(progress, style))
|
|
365
|
+
for text in notice:
|
|
366
|
+
grid.add_row("", self._cell(text, "yellow"))
|
|
347
367
|
return grid
|
|
348
368
|
|
|
349
369
|
|
|
@@ -40,6 +40,8 @@ def _table_to_dict(section: TableSection) -> dict:
|
|
|
40
40
|
"fail_count": section.fail_count,
|
|
41
41
|
"unknown_count": section.unknown_count,
|
|
42
42
|
"not_applicable_count": section.not_applicable_count,
|
|
43
|
+
# One string per note; a note with a detail line carries it after a
|
|
44
|
+
# newline (the malware coverage note's headline and detail).
|
|
43
45
|
"notes": list(section.notes),
|
|
44
46
|
"description": section.resolved_description(),
|
|
45
47
|
# Aggregate rows beneath the totals, over every row (report.json is the
|
|
@@ -26,9 +26,11 @@ _COLUMNS = ("Repository", "Package", "Ecosystem", "Manifest", "Severity", "Age")
|
|
|
26
26
|
# Severity and Age sort on numbers (the severity rung, the days), so a
|
|
27
27
|
# configured sort on either defaults to worst or oldest first.
|
|
28
28
|
_NUMERIC_COLUMNS = frozenset({4, 5})
|
|
29
|
+
# A headline and its detail, split by a newline: each surface sets the detail
|
|
30
|
+
# on a line of its own under the headline (see the summary renderers).
|
|
29
31
|
COVERAGE_NOTE = (
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
+
"Malware alert enablement/status NOT currently available through APIs\n"
|
|
33
|
+
"Repositories without findings may have the feature off so coverage unknown"
|
|
32
34
|
)
|
|
33
35
|
|
|
34
36
|
|
|
@@ -139,6 +139,8 @@ def _summary_context(
|
|
|
139
139
|
"kind": line.kind,
|
|
140
140
|
"emoji": SUMMARY_EMOJI[line.kind],
|
|
141
141
|
"text": line.text,
|
|
142
|
+
# A multi-line note: the template breaks between the parts.
|
|
143
|
+
"parts": line.text.split("\n"),
|
|
142
144
|
"label": line.names_label,
|
|
143
145
|
"names": names,
|
|
144
146
|
"names_hidden": hidden,
|
|
@@ -185,7 +185,9 @@ def _summary_lines(
|
|
|
185
185
|
"""
|
|
186
186
|
out: list[str] = []
|
|
187
187
|
for line in lines:
|
|
188
|
-
|
|
188
|
+
# A multi-line note keeps its detail on a line of its own.
|
|
189
|
+
text = line.text.replace("\n", "<br>\n")
|
|
190
|
+
out.append(f"{SUMMARY_EMOJI[line.kind]} {text}")
|
|
189
191
|
out.append("")
|
|
190
192
|
for line in lines:
|
|
191
193
|
if not line.listed:
|
|
@@ -13,6 +13,7 @@ from __future__ import annotations
|
|
|
13
13
|
from collections.abc import Callable, Sequence
|
|
14
14
|
from pathlib import Path
|
|
15
15
|
|
|
16
|
+
from rich.cells import cell_len
|
|
16
17
|
from rich.console import Console
|
|
17
18
|
from rich.markup import escape
|
|
18
19
|
from rich.table import Table
|
|
@@ -140,7 +141,11 @@ def _render_summary(
|
|
|
140
141
|
"""
|
|
141
142
|
for line in lines:
|
|
142
143
|
style = _SUMMARY_STYLE[line.kind]
|
|
143
|
-
|
|
144
|
+
emoji = SUMMARY_EMOJI[line.kind]
|
|
145
|
+
# A multi-line note's detail aligns under its headline's text.
|
|
146
|
+
indent = " " * (2 + cell_len(emoji) + 1)
|
|
147
|
+
text = line.text.replace("\n", f"\n{indent}")
|
|
148
|
+
console.print(f" [{style}]{emoji} {text}[/{style}]")
|
|
144
149
|
for line in lines:
|
|
145
150
|
if line.listed:
|
|
146
151
|
style = _SUMMARY_STYLE[line.kind]
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
{%- macro render_summary(summary) -%}
|
|
57
57
|
{% if summary %}
|
|
58
58
|
<ul class="summary">
|
|
59
|
-
{% for line in summary %}<li class="kind-{{ line.kind }}"><span aria-hidden="true">{{ line.emoji }}</span> {
|
|
59
|
+
{% for line in summary %}<li class="kind-{{ line.kind }}"><span aria-hidden="true">{{ line.emoji }}</span> {% for part in line.parts %}{% if not loop.first %}<br>{% endif %}{{ part }}{% endfor %}</li>{% endfor %}
|
|
60
60
|
{% for line in summary %}{% if line.label and line.names %}<li class="names"><strong>{{ line.label }}:</strong> {% for r in line.names %}{% if r.url %}<a href="{{ r.url }}">{{ r.name }}</a>{% else %}{{ r.name }}{% endif %}{% if not loop.last %}, {% endif %}{% endfor %}{% if line.names_hidden %} … (+{{ line.names_hidden }} more){% endif %}</li>{% endif %}{% endfor %}
|
|
61
61
|
</ul>
|
|
62
62
|
{% endif %}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/gating.py
RENAMED
|
File without changes
|
{github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/gitctx.py
RENAMED
|
File without changes
|
|
File without changes
|
{github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/issues.py
RENAMED
|
File without changes
|
{github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/layout.py
RENAMED
|
File without changes
|
{github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/models.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/py.typed
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/runner.py
RENAMED
|
File without changes
|
{github_security_report-0.20.0 → github_security_report-0.21.0}/src/github_security_report/scope.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|