Skip to content

Commit acd6eea

Browse files
committed
Merge branch 'master' into adaptation-13956
2 parents e2b8c7d + b767a77 commit acd6eea

2,355 files changed

Lines changed: 11979 additions & 2497 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.downstream/build.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ class Args:
6161
lint: bool
6262
report: Path | None
6363
mappings: Path | None
64+
gh_repo: str | None
65+
gh_run_id: str | None
66+
gh_run_attempt: str | None
6467

6568

6669
def main() -> None:
@@ -83,6 +86,19 @@ def main() -> None:
8386
metavar="DIR",
8487
help="write build mappings to DIR",
8588
)
89+
parser.add_argument(
90+
"--gh-repo",
91+
metavar="OWNER/NAME",
92+
help="GitHub repo full name, used in the build report",
93+
)
94+
parser.add_argument(
95+
"--gh-run-id",
96+
help="GitHub Actions run ID, used to link to the run in the build report",
97+
)
98+
parser.add_argument(
99+
"--gh-run-attempt",
100+
help="GitHub Actions run attempt, appended to the run link if given",
101+
)
86102
args = parser.parse_args(namespace=Args())
87103

88104
report_path = None if args.report is None else args.report.resolve()
@@ -96,6 +112,9 @@ def main() -> None:
96112
updater = Updater()
97113
subrepos = updater.topo_subrepos()
98114

115+
commit_sha = run("git", "rev-parse", "HEAD", capture=True).stdout.strip()
116+
commit_message = run("git", "log", "-1", "--format=%s", capture=True).stdout.strip()
117+
99118
run("lake", "--version")
100119

101120
report_build = {}
@@ -116,6 +135,14 @@ def main() -> None:
116135
report = []
117136
report.append("# Build Report")
118137
report.append("")
138+
139+
if args.gh_repo is not None:
140+
commit_url = f"https://github.com/{args.gh_repo}/commit/{commit_sha}"
141+
report.append(f"For commit **[{commit_message}]({commit_url})**")
142+
else:
143+
report.append(f"For commit **{commit_message}** (`{commit_sha}`)")
144+
145+
report.append("")
119146
report.append("| Repo | Critical | Build | Test | Lint |")
120147
report.append("|------|----------|-------|------|------|")
121148
for subrepo in subrepos:
@@ -126,6 +153,13 @@ def main() -> None:
126153
lint = report_lint.get(subrepo.name, Status.SKIPPED)
127154
report.append(f"| {name} | {critical} | {build} | {test} | {lint} |")
128155

156+
if args.gh_run_id is not None:
157+
run_url = f"https://github.com/{args.gh_repo}/actions/runs/{args.gh_run_id}"
158+
if args.gh_run_attempt is not None:
159+
run_url += f"/attempts/{args.gh_run_attempt}"
160+
report.append("")
161+
report.append(f"[View run]({run_url})")
162+
129163
if report_path is not None:
130164
report_path.write_text("\n".join(report) + "\n")
131165

.downstream/downstream/updater.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from subprocess import CalledProcessError
77

88
from downstream.merge_tree_theirs import merge_tree_theirs
9-
from downstream.util import Subrepo, load_subrepos, normalize_url, run
9+
from downstream.util import Subrepo, github_full_name, load_subrepos, normalize_url, run
1010

1111

1212
class Updater:
@@ -22,7 +22,7 @@ def __init__(self) -> None:
2222
self.subrepos_by_name = {r.name: r for r in self.subrepos}
2323
self.subrepos_by_url = {r.url: r for r in self.subrepos}
2424

25-
def topo_subrepos(self) -> list[Subrepo]:
25+
def dep_graph(self, external: bool = False) -> dict[str, set[str]]:
2626
graph: dict[str, set[str]] = {}
2727
for subrepo in self.subrepos:
2828
deps: set[str] = set()
@@ -33,8 +33,13 @@ def topo_subrepos(self) -> list[Subrepo]:
3333
url = normalize_url(package["url"])
3434
if dep := self.subrepos_by_url.get(url):
3535
deps.add(dep.name)
36+
elif external:
37+
deps.add(github_full_name(url) or url)
3638
graph[subrepo.name] = deps
39+
return graph
3740

41+
def topo_subrepos(self) -> list[Subrepo]:
42+
graph = self.dep_graph()
3843
order = TopologicalSorter(graph).static_order()
3944
return [self.subrepos_by_name[name] for name in order]
4045

@@ -65,7 +70,10 @@ def restore_tree_to(self, tree: str, path: Path) -> None:
6570
)
6671

6772
def fixup_subrepo_toolchain(self, subrepo: Subrepo) -> None:
73+
subrepo_toolchain = (subrepo.path / "lean-toolchain").read_text().strip()
6874
for file in subrepo.path.glob("**/lean-toolchain"):
75+
if file.read_text().strip() != subrepo_toolchain:
76+
continue
6977
file.unlink()
7078
relative = Path("lean-toolchain").relative_to(file.parent, walk_up=True)
7179
file.symlink_to(relative)

.downstream/downstream/util.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,18 @@ def run(
2929
)
3030

3131

32-
def normalize_url(url: str) -> str:
33-
# GitHub URLs
34-
if match := re.fullmatch(
32+
def github_full_name(url: str) -> str | None:
33+
if m := re.fullmatch(
3534
r"(?:https://github\.com/|git@github\.com:|ssh://git@github\.com/)([^/]+/[^/.]+?)(?:\.git)?/?",
3635
url,
3736
):
38-
full_name = match.group(1)
39-
return f"https://github.com/{full_name}"
37+
return m.group(1)
38+
return None
39+
4040

41+
def normalize_url(url: str) -> str:
42+
if full_name := github_full_name(url):
43+
return f"https://github.com/{full_name}"
4144
return url
4245

4346

.downstream/graph.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import os
2+
from argparse import ArgumentParser
3+
from pathlib import Path
4+
5+
from downstream.updater import Updater
6+
7+
8+
def transitive_deps(graph: dict[str, set[str]], name: str) -> set[str]:
9+
result: set[str] = set()
10+
for dep in graph.get(name, set()):
11+
result.add(dep)
12+
result |= transitive_deps(graph, dep)
13+
return result
14+
15+
16+
def indirect_deps(graph: dict[str, set[str]], name: str) -> set[str]:
17+
result: set[str] = set()
18+
for dep in graph.get(name, set()):
19+
result |= transitive_deps(graph, dep)
20+
return result
21+
22+
23+
def attrs_str(**kwargs: str) -> str:
24+
if not kwargs:
25+
return ""
26+
return " [" + " ".join(f"{k}=<{v}>" for k, v in kwargs.items()) + "]"
27+
28+
29+
class Args:
30+
downstream: Path
31+
prune: bool
32+
external: bool
33+
34+
35+
def main() -> None:
36+
parser = ArgumentParser()
37+
parser.add_argument("downstream", type=Path)
38+
parser.add_argument(
39+
"-p",
40+
"--prune",
41+
action="store_true",
42+
help="omit edges already implied transitively",
43+
)
44+
parser.add_argument(
45+
"-e",
46+
"--external",
47+
action="store_true",
48+
help="also graph dependencies not listed in repos.toml",
49+
)
50+
args = parser.parse_args(namespace=Args())
51+
52+
os.chdir(args.downstream)
53+
updater = Updater()
54+
graph = updater.dep_graph(external=args.external)
55+
56+
external = {
57+
dep
58+
for deps in graph.values()
59+
for dep in deps
60+
if dep not in updater.subrepos_by_name
61+
}
62+
63+
print("digraph G {")
64+
print(" rankdir=LR;")
65+
for subrepo in sorted(updater.subrepos, key=lambda r: r.name):
66+
indirect = indirect_deps(graph, subrepo.name) if args.prune else set()
67+
68+
label = f'{subrepo.name}<BR/><FONT POINT-SIZE="8">{subrepo.rev}</FONT>'
69+
attrs = {"label": label}
70+
if subrepo.critical:
71+
attrs["style"] = "filled"
72+
attrs["color"] = "pink"
73+
print(f' "{subrepo.name}"{attrs_str(**attrs)};')
74+
75+
for dep in sorted(graph[subrepo.name]):
76+
comment = "// " if dep in indirect else ""
77+
print(f' {comment}"{dep}" -> "{subrepo.name}";')
78+
79+
for name in sorted(external):
80+
attrs = {"label": name, "style": "dashed", "color": "gray", "fontcolor": "gray"}
81+
print(f' "{name}"{attrs_str(**attrs)};')
82+
83+
print("}")
84+
85+
86+
if __name__ == "__main__":
87+
main()

.github/workflows/build-post.yml

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ jobs:
5757
echo "::endgroup::"
5858
done
5959
60-
post-report:
60+
post-report-pr:
6161
if:
6262
${{ github.event.workflow_run.conclusion != 'cancelled' &&
6363
github.event.workflow_run.event == 'push' &&
@@ -90,13 +90,7 @@ jobs:
9090
github-token: ${{ github.token }}
9191
run-id: ${{ github.event.workflow_run.id }}
9292

93-
- name: Add run link to build report
94-
env:
95-
RUN_URL: ${{ github.event.workflow_run.html_url }}
96-
run: |
97-
echo -e "\n[View run]($RUN_URL)" >> "${{ runner.temp }}/report/report.md"
98-
99-
- name: Post build report
93+
- name: Post build report to PR
10094
uses: ./.downstream/actions/status-message
10195
with:
10296
app-token: ${{ steps.app-token.outputs.token }}
@@ -105,6 +99,44 @@ jobs:
10599
body-path: ${{ runner.temp }}/report/report.md
106100
marker: build-report
107101

102+
post-report-zulip:
103+
if:
104+
${{ github.event.workflow_run.conclusion != 'cancelled' &&
105+
github.event.workflow_run.event == 'push' &&
106+
github.event.workflow_run.head_branch == 'master' &&
107+
github.event.workflow_run.run_attempt == 1 }}
108+
runs-on: ubuntu-slim
109+
permissions:
110+
actions: read
111+
steps:
112+
- name: Download build report
113+
uses: actions/download-artifact@v8
114+
with:
115+
name: build-report
116+
path: ${{ runner.temp }}/report
117+
github-token: ${{ github.token }}
118+
run-id: ${{ github.event.workflow_run.id }}
119+
120+
- name: Read build report
121+
id: read-report
122+
run: |
123+
{
124+
echo "content<<REPORT_EOF"
125+
cat "${{ runner.temp }}/report/report.md"
126+
echo "REPORT_EOF"
127+
} >> "$GITHUB_OUTPUT"
128+
129+
- name: Post build report to Zulip
130+
uses: zulip/github-actions-zulip/send-message@v2
131+
with:
132+
api-key: ${{ secrets.ZULIP_API_KEY }}
133+
email: ${{ vars.ZULIP_EMAIL }}
134+
organization-url: "https://leanprover.zulipchat.com"
135+
type: "stream"
136+
to: "nightly-testing"
137+
topic: "downstream-lean4"
138+
content: ${{ steps.read-report.outputs.content }}
139+
108140
update-branches:
109141
if:
110142
${{ github.event.workflow_run.conclusion == 'success' &&

.github/workflows/build.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ jobs:
3939
run: |
4040
python3 .downstream/build.py . -tl \
4141
--report "$RUNNER_TEMP/report.md" \
42-
--mappings "$RUNNER_TEMP/mappings"
42+
--mappings "$RUNNER_TEMP/mappings" \
43+
--gh-repo "${{ github.repository }}" \
44+
--gh-run-id "${{ github.run_id }}" \
45+
--gh-run-attempt "${{ github.run_attempt }}"
4346
4447
- name: Add report to job summary
4548
if: ${{ !cancelled() }} # Even if build fails

ProofWidgets4/ProofWidgets/Component/MakeEditLink.lean

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@ public import ProofWidgets.Component.Basic
44

55
public meta section
66

7+
/-- Returns the number of bytes required to encode this `Char` in UTF-16. -/
8+
private def ProofWidgets.Internal.utf16Size (c : Char) : UInt32 :=
9+
if c.val ≤ 0xFFFF then 1 else 2
10+
711
/-- Assuming that `s` is the content of a file starting at position `p`,
812
advance `p` to the end of `s`. -/
913
def Lean.Lsp.Position.advance (p : Position) (s : Substring.Raw) : Position :=
1014
let (nLinesAfter, lastLineUtf16Sz) := s.foldl
1115
(init := (0, 0))
12-
fun (n, l) c => if c == '\n' then (n + 1, 0) else (n, l + c.utf16Size.toNat)
16+
fun (n, l) c => if c == '\n' then (n + 1, 0) else (n, l + (ProofWidgets.Internal.utf16Size c).toNat)
1317
{
1418
line := p.line + nLinesAfter
1519
character := (if nLinesAfter == 0 then p.character else 0) + lastLineUtf16Sz

batteries/Batteries/Control/AlternativeMonad.lean

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import all Init.Control.Option
1111
import all Init.Control.State
1212
import all Init.Control.Reader
1313
import all Init.Control.StateRef
14+
public import Lean.Meta.Basic
1415

1516
@[expose] public section
1617

@@ -203,3 +204,5 @@ instance [AlternativeMonad m] : LawfulAlternativeLift m (StateRefT' ω σ m) :=
203204
inferInstanceAs (LawfulAlternativeLift m (ReaderT (ST.Ref ω σ) m))
204205

205206
end StateRefT'
207+
208+
instance : AlternativeMonad Lean.Meta.MetaM where

batteries/Batteries/Data/BinaryHeap/Basic.lean

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Mario Carneiro, François G. Dorais
55
-/
66
module
7+
/-
8+
Broken against lean4#13283.
79
810
public section
911
@@ -183,3 +185,4 @@ where
183185
simp; exact Nat.sub_lt (Batteries.BinaryHeap.size_pos_of_max e) Nat.zero_lt_one
184186
loop a.popMax (out.push x)
185187
termination_by a.size
188+
-/

batteries/Batteries/Data/ByteArray.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ theorem get_extract_aux {a : ByteArray} {start stop} (h : i < (a.extract start s
7878

7979
@[simp] theorem get_extract {a : ByteArray} {start stop} (h : i < (a.extract start stop).size) :
8080
(a.extract start stop)[i] = a[start+i]'(get_extract_aux h) := by
81-
simp [getElem_eq_data_getElem]; rfl
81+
simp [getElem_eq_data_getElem]
8282

8383
/-! ### ofFn -/
8484

0 commit comments

Comments
 (0)