Skip to content

Commit 1fe9ed6

Browse files
committed
Merge branch 'master' of github.com:The-OpenROAD-Project-private/OpenROAD
2 parents 9977972 + 2e6fbf3 commit 1fe9ed6

746 files changed

Lines changed: 77774 additions & 29735 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.

.bant-macros

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# -*- Python -*-
2+
# https://github.com/hzeller/bant#macros
3+
#
4+
# Tell bant (that is not looking at *.bzl files) how custom rules behave, just
5+
# enough for it to see through them to provide features such as dwyu.
6+
#
7+
# To print a rule and apply the macro transformations, use the `-m` option
8+
# to bant. e.g.
9+
# bant print //src/gui:gui_qt -m
10+
#
11+
# If bant is not installed locally, use
12+
# $(etc/get-bant-path.sh) //src/gui:gui_qt -m
13+
#
14+
# File can be formatted using regular buildifier.
15+
16+
python_wrap_cc = genrule(
17+
name = name,
18+
outs = [
19+
out, # if defined
20+
name + ".cc",
21+
module + ".py",
22+
],
23+
)
24+
25+
tcl_wrap_cc = genrule(
26+
name = name,
27+
outs = [
28+
out, # if defined
29+
runtime_header, # if defined
30+
name + ".cc",
31+
],
32+
)
33+
34+
tcl_encode = genrule(
35+
name = name,
36+
outs = [
37+
out,
38+
name + ".cc",
39+
],
40+
)
41+
42+
tcl_encode_sta = genrule(
43+
name = name,
44+
outs = [
45+
out,
46+
name + ".cc",
47+
],
48+
)
49+
50+
# gist extracted from @qt-bazel//:build_defs.bzl
51+
qt6_library = (
52+
[
53+
genrule(
54+
name = uisrc.rsplit("/", 1)[0].replace("/", "_") + "_ui_" + uisrc.rsplit("/", 1)[1][0:-3],
55+
srcs = [uisrc],
56+
outs = [uisrc.rsplit("/", 1)[0] + "/ui_" + uisrc.rsplit("/", 1)[1][0:-3] + ".h"],
57+
)
58+
for uisrc in uic_srcs
59+
],
60+
cc_library(
61+
name = name,
62+
srcs = srcs,
63+
hdrs = hdrs + moc_hdrs + [
64+
uisrc.rsplit("/", 1)[0] + "/ui_" + uisrc.rsplit("/", 1)[1][0:-3] + ".h"
65+
for uisrc in uic_srcs
66+
],
67+
includes = includes,
68+
deps = deps,
69+
),
70+
)
71+
72+
genlex = genrule(
73+
name = name,
74+
srcs = [src],
75+
outs = [out],
76+
)
77+
78+
genyacc = genrule(
79+
name = name,
80+
srcs = [src],
81+
outs = [header_out, source_out] + extra_outs,
82+
)

.gemini/commands/add-test.toml

Lines changed: 0 additions & 2 deletions
This file was deleted.

.gemini/commands/fix-bug.toml

Lines changed: 0 additions & 2 deletions
This file was deleted.

.gemini/commands/review-pr.toml

Lines changed: 0 additions & 2 deletions
This file was deleted.

.gemini/commands/triage-issue.toml

Lines changed: 0 additions & 2 deletions
This file was deleted.

.github/CODEOWNERS

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# OpenROAD code owners
2+
#
3+
# Order matters: later rules override earlier ones for the same path.
4+
# The '*' fallback applies to anything not matched by a more specific rule.
5+
#
6+
# Fallback owner for everything (docs, CI, bazel, top-level files, src/ root files)
7+
# and a few misc modules commented below
8+
* @The-OpenROAD-Project/openroad-maintainers
9+
10+
# Per-module owners
11+
/src/ant/ @The-OpenROAD-Project/openroad-ant
12+
/src/cgt/ @The-OpenROAD-Project/openroad-cgt
13+
#/src/cmake/
14+
/src/cts/ @The-OpenROAD-Project/openroad-cts
15+
/src/cut/ @The-OpenROAD-Project/openroad-cut
16+
/src/dbSta/ @The-OpenROAD-Project/openroad-dbsta
17+
/src/dft/ @The-OpenROAD-Project/openroad-dft
18+
/src/dpl/ @The-OpenROAD-Project/openroad-dpl
19+
/src/drt/ @The-OpenROAD-Project/openroad-drt
20+
/src/dst/ @The-OpenROAD-Project/openroad-dst
21+
/src/est/ @The-OpenROAD-Project/openroad-est
22+
#/src/exa/
23+
#/src/fin/
24+
/src/gpl/ @The-OpenROAD-Project/openroad-gpl
25+
/src/grt/ @The-OpenROAD-Project/openroad-grt
26+
/src/gui/ @The-OpenROAD-Project/openroad-gui
27+
/src/ifp/ @The-OpenROAD-Project/openroad-ifp
28+
/src/mpl/ @The-OpenROAD-Project/openroad-mpl
29+
/src/odb/ @The-OpenROAD-Project/openroad-odb
30+
/src/pad/ @The-OpenROAD-Project/openroad-pad
31+
/src/par/ @The-OpenROAD-Project/openroad-par
32+
/src/pdn/ @The-OpenROAD-Project/openroad-pdn
33+
/src/ppl/ @The-OpenROAD-Project/openroad-ppl
34+
/src/psm/ @The-OpenROAD-Project/openroad-psm
35+
#/src/ram/
36+
/src/rcx/ @The-OpenROAD-Project/openroad-rcx
37+
/src/rmp/ @The-OpenROAD-Project/openroad-rmp
38+
/src/rsz/ @The-OpenROAD-Project/openroad-rsz
39+
/src/sta/ @The-OpenROAD-Project/openroad-sta
40+
/src/stt/ @The-OpenROAD-Project/openroad-stt
41+
/src/syn/ @The-OpenROAD-Project/openroad-syn
42+
/src/tap/ @The-OpenROAD-Project/openroad-tap
43+
/src/tst/ @The-OpenROAD-Project/openroad-tst
44+
/src/upf/ @The-OpenROAD-Project/openroad-upf
45+
/src/utl/ @The-OpenROAD-Project/openroad-utl
46+
/src/web/ @The-OpenROAD-Project/openroad-web

.github/workflows/github-actions-clang-tidy-post.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,5 @@ jobs:
3333
const fs = require('fs');
3434
fs.writeFileSync('${{github.workspace}}/clang-tidy-review.zip', Buffer.from(download.data));
3535
- name: 'Unzip artifact'
36-
run: unzip clang-tidy-review.zip
36+
run: unzip -o clang-tidy-review.zip
3737
- uses: The-OpenROAD-Project/clang-tidy-review/post@master

.github/workflows/github-actions-on-label-create.yml

Lines changed: 174 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,187 @@ jobs:
5151
deployToken: ${{ secrets.STAGING_GITHUB_TOKEN }}
5252
force: true
5353

54+
- id: resolve_key
55+
name: Compute per-user secret key
56+
env:
57+
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
58+
run: |
59+
key=$(echo "$PR_AUTHOR" | tr 'a-z-' 'A-Z_')
60+
echo "key=$key" >> "$GITHUB_OUTPUT"
61+
62+
- id: resolve_token
63+
name: Pick per-user PAT or fall back to bot token
64+
env:
65+
USER_PAT: ${{ secrets[format('PAT_{0}', steps.resolve_key.outputs.key)] }}
66+
BOT_TOKEN: ${{ secrets.STAGING_GITHUB_TOKEN }}
67+
run: |
68+
if [ -n "$USER_PAT" ]; then
69+
echo "::add-mask::$USER_PAT"
70+
echo "token=$USER_PAT" >> "$GITHUB_OUTPUT"
71+
echo "source=user-pat" >> "$GITHUB_OUTPUT"
72+
echo "Using per-user PAT for PR creation"
73+
else
74+
echo "::add-mask::$BOT_TOKEN"
75+
echo "token=$BOT_TOKEN" >> "$GITHUB_OUTPUT"
76+
echo "source=bot-fallback" >> "$GITHUB_OUTPUT"
77+
echo "No per-user PAT found; falling back to bot token"
78+
fi
79+
5480
- id: send_pr
5581
name: Create PR if needed.
5682
uses: The-OpenROAD-Project/actions/send_pr@main
5783
env:
58-
STAGING_GITHUB_TOKEN: ${{ secrets.STAGING_GITHUB_TOKEN }}
84+
STAGING_GITHUB_TOKEN: ${{ steps.resolve_token.outputs.token }}
5985

6086
- name: Linking to PR using deployment.
6187
uses: The-OpenROAD-Project/actions/link_pr@main
6288
env:
6389
GITHUB_TOKEN: ${{ github.token }}
6490
UPSTREAM_PR: ${{ steps.send_pr.outputs.pr }}
91+
92+
- name: Request CODEOWNERS reviewers on upstream PR
93+
if: steps.send_pr.outputs.pr != ''
94+
env:
95+
GH_TOKEN: ${{ steps.resolve_token.outputs.token }}
96+
PR: ${{ steps.send_pr.outputs.pr }}
97+
UPSTREAM: ${{ env.UPSTREAM_OWNER }}/${{ env.UPSTREAM_REPO }}
98+
run: |
99+
set -euo pipefail
100+
# System Python on the runner is PEP 668 externally-managed; use a venv.
101+
python3 -m venv /tmp/codeowners-venv
102+
/tmp/codeowners-venv/bin/pip install --quiet pathspec
103+
/tmp/codeowners-venv/bin/python <<'PY'
104+
import base64, json, os, subprocess, sys, time
105+
from pathspec import GitIgnoreSpec
106+
107+
pr = os.environ["PR"]
108+
upstream = os.environ["UPSTREAM"]
109+
110+
# GitHub computes PR mergeability asynchronously, so `mergeable` and
111+
# `merge_commit_sha` are often null on the first read after PR
112+
# creation. Poll until the background job finishes.
113+
attempts = 10
114+
delay = 3
115+
for attempt in range(1, attempts + 1):
116+
pr_json = subprocess.check_output(
117+
["gh", "api", f"repos/{upstream}/pulls/{pr}"], text=True)
118+
pr_data = json.loads(pr_json)
119+
if pr_data.get("mergeable") is not None \
120+
and pr_data.get("merge_commit_sha"):
121+
break
122+
print(f"Mergeability not yet computed "
123+
f"(attempt {attempt}/{attempts}); sleeping {delay}s")
124+
time.sleep(delay)
125+
else:
126+
raise RuntimeError(
127+
"PR merge commit SHA is unavailable after polling; refusing "
128+
"to request CODEOWNERS reviewers from an incomplete "
129+
"effective diff.")
130+
131+
author = pr_data["user"]["login"]
132+
base_ref = pr_data["base"]["ref"]
133+
base_repo = pr_data["base"]["repo"]["full_name"]
134+
base_sha = pr_data["base"]["sha"]
135+
head_repo = pr_data["head"]["repo"]["full_name"]
136+
head_sha = pr_data["head"]["sha"]
137+
merge_sha = pr_data["merge_commit_sha"]
138+
139+
print(f"Computing effective PR merge diff: {base_repo}@{base_sha}.."
140+
f"{base_repo}@{merge_sha} (head {head_repo}@{head_sha})")
141+
142+
# Authoritative CODEOWNERS is the one on the PR base branch.
143+
raw = subprocess.check_output(
144+
["gh", "api", "--method", "GET",
145+
f"repos/{upstream}/contents/.github/CODEOWNERS",
146+
"-f", f"ref={base_ref}", "--jq", ".content"], text=True).strip()
147+
codeowners = base64.b64decode(raw).decode()
148+
149+
rules = []
150+
for line in codeowners.splitlines():
151+
line = line.split("#", 1)[0].strip()
152+
if not line:
153+
continue
154+
pattern, *rule_owners = line.split()
155+
rules.append((GitIgnoreSpec.from_lines([pattern]), rule_owners))
156+
157+
def commit_tree(repo, sha):
158+
commit_json = subprocess.check_output(
159+
["gh", "api", f"repos/{repo}/git/commits/{sha}"],
160+
text=True)
161+
commit_data = json.loads(commit_json)
162+
tree_sha = commit_data["tree"]["sha"]
163+
tree_json = subprocess.check_output(
164+
["gh", "api",
165+
f"repos/{repo}/git/trees/{tree_sha}?recursive=1"],
166+
text=True)
167+
tree_data = json.loads(tree_json)
168+
if tree_data.get("truncated"):
169+
raise RuntimeError(
170+
f"Recursive tree for {repo}@{sha} was truncated; "
171+
"refusing to request partial CODEOWNERS reviewers.")
172+
173+
entries = {}
174+
for entry in tree_data["tree"]:
175+
if entry["type"] == "tree":
176+
continue
177+
entries[entry["path"]] = (
178+
entry.get("sha"), entry.get("mode"), entry.get("type"))
179+
return entries
180+
181+
# Use the effective merge-result delta rather than GitHub's PR file
182+
# list or a direct base -> head tree comparison. The PR file list is
183+
# merge-base based, so it can include already-landed upstream changes
184+
# brought in by a merge from the base branch. A direct base -> head
185+
# comparison has the opposite problem when the PR branch is behind the
186+
# base branch: it reports base-only changes as if the PR changed them.
187+
# Comparing base -> test-merge tree matches the content that would land
188+
# if this PR merged now, including real conflict-resolution edits.
189+
base_tree = commit_tree(base_repo, base_sha)
190+
merge_tree = commit_tree(base_repo, merge_sha)
191+
files = sorted(path for path in set(base_tree) | set(merge_tree)
192+
if base_tree.get(path) != merge_tree.get(path))
193+
194+
print("Effective changed files:")
195+
for path in files:
196+
print(f" {path}")
197+
198+
owners = set()
199+
for path in files:
200+
matched = None
201+
for spec, rule_owners in rules:
202+
if spec.match_file(path):
203+
matched = rule_owners # last match wins
204+
if matched:
205+
owners.update(o.lstrip("@") for o in matched)
206+
207+
# CODEOWNERS lists teams as "org/slug"; the REST endpoint wants the
208+
# bare slug in team_reviewers.
209+
team_slugs = sorted(t.split("/", 1)[1] for t in owners if "/" in t)
210+
users = sorted(o for o in owners
211+
if "/" not in o and o.lower() != author.lower())
212+
213+
print("Matched CODEOWNERS teams:", ", ".join(team_slugs) or "<none>")
214+
print("Matched CODEOWNERS users:", ", ".join(users) or "<none>")
215+
216+
if not (team_slugs or users):
217+
print("No CODEOWNERS-matched reviewers.")
218+
sys.exit(0)
219+
220+
# Use the REST POST endpoint directly: `gh pr edit --add-reviewer`
221+
# runs a GraphQL query that needs read:org, which our tokens don't
222+
# have. POST /pulls/{n}/requested_reviewers only writes, so the
223+
# existing repo / pull-requests:write scope is enough. Each array
224+
# is capped at 15 per call.
225+
def request(body):
226+
print("Requesting:", body)
227+
subprocess.run(
228+
["gh", "api", "--method", "POST",
229+
f"repos/{upstream}/pulls/{pr}/requested_reviewers",
230+
"--input", "-"],
231+
input=json.dumps(body), text=True, check=True)
232+
233+
for i in range(0, len(team_slugs), 15):
234+
request({"team_reviewers": team_slugs[i:i + 15]})
235+
for i in range(0, len(users), 15):
236+
request({"reviewers": users[i:i + 15]})
237+
PY

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ coverage-output
4747
etc/openroad_deps_prefixes.txt
4848
etc/run-clang-tidy-cached
4949
OpenROAD_clang-tidy.*
50+
compile_flags.txt
5051

5152
*debhelper*
5253
debian/changelog

BUILD.bazel

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ load("//bazel:tcl_wrap_cc.bzl", "tcl_wrap_cc")
1414

1515
package(
1616
features = [
17-
"-parse_headers",
17+
"parse_headers",
1818
"layering_check",
1919
# TODO(b/299593765): Fix strict ordering.
2020
"-libcxx_assertions",
@@ -80,7 +80,6 @@ OPENROAD_LIBRARY_DEPS = [
8080
"//src/dbSta",
8181
"//src/dbSta:dbNetwork",
8282
"//src/dbSta:dbReadVerilog",
83-
"//src/dbSta:dbSdcNetwork",
8483
"//src/dbSta:IpChecker",
8584
"//src/dbSta:SpefWriter",
8685
"//src/dbSta:ui",
@@ -104,7 +103,14 @@ OPENROAD_LIBRARY_DEPS = [
104103
"//src/ifp:ui",
105104
"//src/mpl",
106105
"//src/mpl:ui",
107-
"//src/odb",
106+
"//src/odb/src/3dblox",
107+
"//src/odb/src/cdl",
108+
"//src/odb/src/db",
109+
"//src/odb/src/defin",
110+
"//src/odb/src/defout",
111+
"//src/odb/src/lefin",
112+
"//src/odb/src/lefout",
113+
"//src/odb/src/swig:swig_common",
108114
"//src/odb:ui",
109115
"//src/pad",
110116
"//src/par",
@@ -331,7 +337,7 @@ cc_binary(
331337
"//src/grt",
332338
"//src/gui",
333339
"//src/ifp",
334-
"//src/odb",
340+
"//src/odb/src/db",
335341
"//src/par",
336342
"//src/pdn",
337343
"//src/ppl",

0 commit comments

Comments
 (0)