mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00
Compare commits
452 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
23c491e5bc | ||
![]() |
cc930ca089 | ||
![]() |
b631179579 | ||
![]() |
c1818fd099 | ||
![]() |
343748f601 | ||
![]() |
4aee877f04 | ||
![]() |
a7d986c6c2 | ||
![]() |
837bb29607 | ||
![]() |
11b3bd91c9 | ||
![]() |
6b5d6c5333 | ||
![]() |
8856a609d6 | ||
![]() |
eec800149f | ||
![]() |
82914cafb1 | ||
![]() |
370ce002e9 | ||
![]() |
7f333ab6ec | ||
![]() |
607ffafd9f | ||
![]() |
26bb16e26d | ||
![]() |
36a4cb42ed | ||
![]() |
d4d1b4a22a | ||
![]() |
3e0b0c1b32 | ||
![]() |
d57efd9ea2 | ||
![]() |
71bab462e1 | ||
![]() |
5692ea6c17 | ||
![]() |
8efb804e4e | ||
![]() |
a65b9d0128 | ||
![]() |
e4893037ae | ||
![]() |
a2bf23ef70 | ||
![]() |
0b99d57621 | ||
![]() |
69ce5edd14 | ||
![]() |
b53f3b570c | ||
![]() |
5bc5d53a23 | ||
![]() |
17762fa77a | ||
![]() |
e8bfa23877 | ||
![]() |
b7b369270e | ||
![]() |
d46d315cc1 | ||
![]() |
455a461406 | ||
![]() |
6141c6a181 | ||
![]() |
ab3955209e | ||
![]() |
50c3181cdb | ||
![]() |
700d67a85e | ||
![]() |
0f2131484d | ||
![]() |
5ec756e0ca | ||
![]() |
d88a0e46fc | ||
![]() |
2dfb8c0b76 | ||
![]() |
114d66082d | ||
![]() |
d010adb903 | ||
![]() |
43b72d3633 | ||
![]() |
1286a3676c | ||
![]() |
ce8bf906c1 | ||
![]() |
e78cc286e0 | ||
![]() |
f4bcda325a | ||
![]() |
495b5bedde | ||
![]() |
990c1efc16 | ||
![]() |
b57557dc3d | ||
![]() |
bb372b2665 | ||
![]() |
727804bb08 | ||
![]() |
5c8fe3a339 | ||
![]() |
37f1e48538 | ||
![]() |
be6c62b1d9 | ||
![]() |
a7471e449e | ||
![]() |
a36f8af593 | ||
![]() |
998470f4a5 | ||
![]() |
4f677e72d4 | ||
![]() |
94606f343a | ||
![]() |
eff4523074 | ||
![]() |
0b7c57af3b | ||
![]() |
836d85277f | ||
![]() |
f5c5d26173 | ||
![]() |
57024a9f2d | ||
![]() |
4b85b24531 | ||
![]() |
c7af63488d | ||
![]() |
ea240e5aad | ||
![]() |
23742f3500 | ||
![]() |
09cec91b28 | ||
![]() |
ec9c0d65fd | ||
![]() |
2e963b2e06 | ||
![]() |
5310c5e730 | ||
![]() |
8520539312 | ||
![]() |
f92e961ff1 | ||
![]() |
a6aad3d12f | ||
![]() |
006d3779f3 | ||
![]() |
e3cc36a8b9 | ||
![]() |
c7f7ab5631 | ||
![]() |
c5036f3bba | ||
![]() |
dfab4bbab2 | ||
![]() |
019a799fae | ||
![]() |
bcab2ae500 | ||
![]() |
fb01c0fa96 | ||
![]() |
004c0a2a6c | ||
![]() |
52d66f206a | ||
![]() |
ba178a8f10 | ||
![]() |
fe4f472c8d | ||
![]() |
01c8e42ea8 | ||
![]() |
c3ec61b7cd | ||
![]() |
98b7bc8d11 | ||
![]() |
a2e39c4814 | ||
![]() |
4dabf8da16 | ||
![]() |
5627a90652 | ||
![]() |
7f3f3c2d55 | ||
![]() |
a83a71ab5f | ||
![]() |
7019df7481 | ||
![]() |
c9d3df2e54 | ||
![]() |
c8585134b4 | ||
![]() |
53bb328cbc | ||
![]() |
e731b572f3 | ||
![]() |
fbab2caec3 | ||
![]() |
e3e8ccef0a | ||
![]() |
f9dab1561a | ||
![]() |
9e131d0794 | ||
![]() |
5fed8f4210 | ||
![]() |
0d40f48e8d | ||
![]() |
415c0de6b2 | ||
![]() |
06cb0cd197 | ||
![]() |
4fd7c6fa8d | ||
![]() |
66c11afa7c | ||
![]() |
29122c0008 | ||
![]() |
c86a5a1b74 | ||
![]() |
3e36e98db3 | ||
![]() |
aa596d3e6b | ||
![]() |
f649587d51 | ||
![]() |
b87d2887fe | ||
![]() |
dfe8fde704 | ||
![]() |
db45e81d88 | ||
![]() |
c36389165c | ||
![]() |
f1e458a36a | ||
![]() |
505428e03b | ||
![]() |
9fa50e5e12 | ||
![]() |
a85a9b84bb | ||
![]() |
0fb87af72c | ||
![]() |
75146e032c | ||
![]() |
b63ad37eeb | ||
![]() |
ec61b49ee9 | ||
![]() |
e11952a2e0 | ||
![]() |
ca510da620 | ||
![]() |
048f58123f | ||
![]() |
36ae1ee429 | ||
![]() |
71d788e156 | ||
![]() |
2c89b70f28 | ||
![]() |
f32f391fc4 | ||
![]() |
f4491e0c8f | ||
![]() |
f34f1c4a33 | ||
![]() |
28753ef002 | ||
![]() |
3495ea576c | ||
![]() |
b391d6f366 | ||
![]() |
f89387ac39 | ||
![]() |
05c7b65f54 | ||
![]() |
1ecd060b38 | ||
![]() |
f83c5ee2ed | ||
![]() |
d661cffc1f | ||
![]() |
e42084dc6f | ||
![]() |
426da94cc9 | ||
![]() |
27b9bf2377 | ||
![]() |
2c16fe9184 | ||
![]() |
818662352c | ||
![]() |
af14bcb69b | ||
![]() |
4759ca9430 | ||
![]() |
55f65ec375 | ||
![]() |
a9faa2cd8e | ||
![]() |
0dc48348af | ||
![]() |
c19f08b3e8 | ||
![]() |
d590e398fc | ||
![]() |
68dbf12220 | ||
![]() |
6a7416c296 | ||
![]() |
cfede01ea9 | ||
![]() |
984273be76 | ||
![]() |
afa5d50b36 | ||
![]() |
a6b1d42488 | ||
![]() |
2703f12875 | ||
![]() |
2acd4e4293 | ||
![]() |
8a4cac0238 | ||
![]() |
7e79232512 | ||
![]() |
12e5e24ce3 | ||
![]() |
84505c714d | ||
![]() |
eca98d036c | ||
![]() |
f238d3b494 | ||
![]() |
44dcb58f9e | ||
![]() |
431d8f1ff7 | ||
![]() |
267afac198 | ||
![]() |
508c8b606c | ||
![]() |
2a7fbd00a9 | ||
![]() |
ff79015373 | ||
![]() |
e1873d30d4 | ||
![]() |
031160936f | ||
![]() |
2d39c7feb5 | ||
![]() |
f674a3ac03 | ||
![]() |
a16129fc59 | ||
![]() |
6d0a77fc79 | ||
![]() |
7d7d04bdf5 | ||
![]() |
2fb6105f26 | ||
![]() |
90b697995f | ||
![]() |
0db36b57c8 | ||
![]() |
052c0ae2cd | ||
![]() |
0800faf093 | ||
![]() |
bcc7f0f796 | ||
![]() |
dd04fb5ab6 | ||
![]() |
d0a144520d | ||
![]() |
d961c4772a | ||
![]() |
68596ec720 | ||
![]() |
9d357b57d1 | ||
![]() |
e6d4db8d6f | ||
![]() |
dce285458e | ||
![]() |
cf2e20d586 | ||
![]() |
f77c9861de | ||
![]() |
2cd7a32660 | ||
![]() |
3964186bec | ||
![]() |
9f5286f3d7 | ||
![]() |
6bfcd62c7c | ||
![]() |
4ce9faf294 | ||
![]() |
4c18ff443c | ||
![]() |
19901b5332 | ||
![]() |
99a8e3a288 | ||
![]() |
ccb3543c6c | ||
![]() |
62cff0e852 | ||
![]() |
aecdcd4840 | ||
![]() |
d0345513e2 | ||
![]() |
f738fce3d9 | ||
![]() |
76470c0d8a | ||
![]() |
43a72a1a03 | ||
![]() |
989032b703 | ||
![]() |
7da83ee19c | ||
![]() |
fe06e04e28 | ||
![]() |
27a040cc32 | ||
![]() |
1b0e79121a | ||
![]() |
ea7d441370 | ||
![]() |
fc18956eeb | ||
![]() |
971a8b40e6 | ||
![]() |
8c203df671 | ||
![]() |
aeed5eb57a | ||
![]() |
f71287c4a9 | ||
![]() |
5ff58d2df0 | ||
![]() |
fb9d1c5a1c | ||
![]() |
77321d6f8b | ||
![]() |
e1fc5a2784 | ||
![]() |
2916610699 | ||
![]() |
9375fc21f4 | ||
![]() |
ca1e08c7a8 | ||
![]() |
85c5f8f3a5 | ||
![]() |
c4c66d41ef | ||
![]() |
3c30845240 | ||
![]() |
2ad0fed872 | ||
![]() |
dfa79bf981 | ||
![]() |
f2103c7138 | ||
![]() |
35407ab556 | ||
![]() |
1f29f51654 | ||
![]() |
09eaf1495a | ||
![]() |
c5d091af21 | ||
![]() |
768c10c6fb | ||
![]() |
85d48da364 | ||
![]() |
d7d8c61f00 | ||
![]() |
7345607ca0 | ||
![]() |
9c69859f99 | ||
![]() |
ab4acd655a | ||
![]() |
95f0e76154 | ||
![]() |
b5d4bc56fc | ||
![]() |
e694e76857 | ||
![]() |
9ac306e464 | ||
![]() |
b6167f6024 | ||
![]() |
ad28cc7cf5 | ||
![]() |
62ca1323df | ||
![]() |
b6f3b0439b | ||
![]() |
7656fee22d | ||
![]() |
ea57773327 | ||
![]() |
00249bda44 | ||
![]() |
d2b6531f01 | ||
![]() |
764d2b2dcc | ||
![]() |
6301c2d31f | ||
![]() |
82eaabf7fe | ||
![]() |
f59624623c | ||
![]() |
4f072136d5 | ||
![]() |
e3ae002054 | ||
![]() |
d2269c5b30 | ||
![]() |
66621b56c9 | ||
![]() |
6fb115d342 | ||
![]() |
08eae94955 | ||
![]() |
dfd0cc8d85 | ||
![]() |
c15dec7821 | ||
![]() |
cf2d4a5676 | ||
![]() |
f154eb2812 | ||
![]() |
1cdbc38802 | ||
![]() |
9494385745 | ||
![]() |
3cb4ba8c26 | ||
![]() |
a0d1e1d9d6 | ||
![]() |
6105a241f8 | ||
![]() |
be6cee3006 | ||
![]() |
cba6ecce92 | ||
![]() |
4a4f7a541a | ||
![]() |
af997ea2ad | ||
![]() |
e049ee3d3b | ||
![]() |
c8213558ef | ||
![]() |
5fc7a225c1 | ||
![]() |
29e7229463 | ||
![]() |
22dfe9267e | ||
![]() |
35962a447d | ||
![]() |
d428e832ee | ||
![]() |
ac6a7b476b | ||
![]() |
e66bb7ece5 | ||
![]() |
ec539147a7 | ||
![]() |
fca5630b23 | ||
![]() |
54b349bb89 | ||
![]() |
f234423913 | ||
![]() |
9541ad8931 | ||
![]() |
577f01c30e | ||
![]() |
8063291f7c | ||
![]() |
1a5afaf739 | ||
![]() |
50bdb40efb | ||
![]() |
efa0c9554a | ||
![]() |
d68b890d61 | ||
![]() |
770335f72e | ||
![]() |
bf6f813492 | ||
![]() |
a63baa62d2 | ||
![]() |
d525e25e99 | ||
![]() |
fb5ddde5ad | ||
![]() |
7e876e4681 | ||
![]() |
498ab9e4b7 | ||
![]() |
bb0bb27591 | ||
![]() |
e5667cb5ae | ||
![]() |
7a806ac1bd | ||
![]() |
5831783a85 | ||
![]() |
728440df3a | ||
![]() |
e5495d097e | ||
![]() |
b242abfdf0 | ||
![]() |
ce72e34b19 | ||
![]() |
689ff373d8 | ||
![]() |
4e0e5782ec | ||
![]() |
1857fe4670 | ||
![]() |
755353570d | ||
![]() |
7bd8642bfc | ||
![]() |
dffa42839c | ||
![]() |
8aeb93ec98 | ||
![]() |
837b28ba79 | ||
![]() |
11f4d304ad | ||
![]() |
347b287967 | ||
![]() |
721def31a5 | ||
![]() |
9540bfe5c4 | ||
![]() |
ea8152757e | ||
![]() |
8d4395118c | ||
![]() |
324762b895 | ||
![]() |
0af29dec14 | ||
![]() |
144113318e | ||
![]() |
724c10962e | ||
![]() |
d2f9677cde | ||
![]() |
e9f55a8f71 | ||
![]() |
3c9a7332d4 | ||
![]() |
c086bdcbba | ||
![]() |
7b4ef99fed | ||
![]() |
b8e2cddbbd | ||
![]() |
ecd0d99001 | ||
![]() |
cfdc6fd3fe | ||
![]() |
57ed94c421 | ||
![]() |
dc71b7c8f6 | ||
![]() |
8ebb2cd65b | ||
![]() |
63abe0bebf | ||
![]() |
97bc7b1661 | ||
![]() |
cc03340af3 | ||
![]() |
32a53ab285 | ||
![]() |
d39bded2f1 | ||
![]() |
aa47105d2a | ||
![]() |
a8638270f2 | ||
![]() |
8222b192ec | ||
![]() |
a5251b2fb6 | ||
![]() |
fd159ed32c | ||
![]() |
628d265d7a | ||
![]() |
27f7f282be | ||
![]() |
1f37a11b79 | ||
![]() |
fda164535e | ||
![]() |
ff710f8191 | ||
![]() |
dd7b95439a | ||
![]() |
e7f667c198 | ||
![]() |
b23bc5e0fe | ||
![]() |
08e9a4365f | ||
![]() |
73b64390b3 | ||
![]() |
e83dc1cb3c | ||
![]() |
0c4672a323 | ||
![]() |
1d2f045ecf | ||
![]() |
c75122c694 | ||
![]() |
5fe43ed3f2 | ||
![]() |
485f1abbee | ||
![]() |
916c25ef18 | ||
![]() |
e47bc2fb86 | ||
![]() |
b44ec56267 | ||
![]() |
0b67caf718 | ||
![]() |
71c8174136 | ||
![]() |
6f8d31d698 | ||
![]() |
da624601bb | ||
![]() |
68ef29fb5c | ||
![]() |
e825ceea0a | ||
![]() |
ab1c3ed5f8 | ||
![]() |
fa45209f09 | ||
![]() |
3dc9e88542 | ||
![]() |
317110f6f4 | ||
![]() |
c03f70f1dc | ||
![]() |
21e3621132 | ||
![]() |
76c4eb60ee | ||
![]() |
f9471f9591 | ||
![]() |
89739ac615 | ||
![]() |
29ffef482c | ||
![]() |
175eb65073 | ||
![]() |
0f03757e8f | ||
![]() |
a0c89e4a7f | ||
![]() |
7c5affa824 | ||
![]() |
d914a72122 | ||
![]() |
7c3281f51e | ||
![]() |
01ad6b53d3 | ||
![]() |
ab3b2736b5 | ||
![]() |
326376ef44 | ||
![]() |
b1c8567977 | ||
![]() |
b0b29f9b53 | ||
![]() |
960b4343cc | ||
![]() |
fbd13203d8 | ||
![]() |
19134b3005 | ||
![]() |
3f1341eb6a | ||
![]() |
3963af774a | ||
![]() |
cd6777fc73 | ||
![]() |
54c8b127ea | ||
![]() |
bdbd80671a | ||
![]() |
e71b1473b8 | ||
![]() |
8c6b3db1cd | ||
![]() |
5805e9d597 | ||
![]() |
87e57368d4 | ||
![]() |
d860fa1fa8 | ||
![]() |
3c693459bd | ||
![]() |
e6377ed0c1 | ||
![]() |
6278ac1801 | ||
![]() |
0cd1e6ca5b | ||
![]() |
493f2aa9f0 | ||
![]() |
f3c79353be | ||
![]() |
9425734b4f | ||
![]() |
fe3783d711 | ||
![]() |
972414cec7 | ||
![]() |
7476f09672 | ||
![]() |
0480411c6f | ||
![]() |
24d9524bbd | ||
![]() |
9e05995299 | ||
![]() |
0e14dd8d3a | ||
![]() |
ff568c2179 | ||
![]() |
e6aed19670 | ||
![]() |
8fe9691b13 | ||
![]() |
9d949f3f2f | ||
![]() |
214074cf02 | ||
![]() |
600cb4544d | ||
![]() |
2131d70265 | ||
![]() |
171fba9c84 | ||
![]() |
1035024b83 | ||
![]() |
f420f0f63d | ||
![]() |
81ea767ea3 | ||
![]() |
d416755560 | ||
![]() |
a2894caceb | ||
![]() |
3f15e0eef0 | ||
![]() |
97acfb94ce | ||
![]() |
5ee4e609ac | ||
![]() |
92832c258c | ||
![]() |
ca911fb446 |
@ -1,7 +1,7 @@
|
||||
// For format details, see https://aka.ms/devcontainer.json.
|
||||
{
|
||||
"name": "Homebrew/brew",
|
||||
"image": "ghcr.io/homebrew/brew:master",
|
||||
"image": "ghcr.io/homebrew/brew:main",
|
||||
"workspaceFolder": "/home/linuxbrew/.linuxbrew/Homebrew",
|
||||
"workspaceMount": "source=${localWorkspaceFolder},target=/home/linuxbrew/.linuxbrew/Homebrew,type=bind,consistency=cached",
|
||||
"onCreateCommand": ".devcontainer/on-create-command.sh",
|
||||
|
6
.github/ISSUE_TEMPLATE/bug.yml
vendored
6
.github/ISSUE_TEMPLATE/bug.yml
vendored
@ -4,7 +4,7 @@ type: "Bug"
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: Please note we will close your issue without comment if you do not correctly fill out the issue checklist below and provide ALL the requested information. If you repeatedly fail to use the issue template, we will block you from ever submitting issues to Homebrew again.
|
||||
value: Please note we may close your issue without comment if you do not fill out the issue checklist below and provide ALL the requested information (even if you consider them irrelevant). If you are unwilling to use the issue template, we may block you from ever submitting future issues to Homebrew.
|
||||
- type: textarea
|
||||
attributes:
|
||||
render: shell
|
||||
@ -16,10 +16,10 @@ body:
|
||||
label: Verification
|
||||
description: Please verify that you've followed these steps. If you cannot truthfully check these boxes, open a discussion at https://github.com/orgs/Homebrew/discussions instead.
|
||||
options:
|
||||
- label: My "`brew doctor` output" above says `Your system is ready to brew.` and am still able to reproduce my issue.
|
||||
required: true
|
||||
- label: I ran `brew update` twice and am still able to reproduce my issue.
|
||||
required: true
|
||||
- label: My "`brew doctor` output" above says `Your system is ready to brew` or a definitely unrelated `Tier` message.
|
||||
required: true
|
||||
- label: This issue's title and/or description do not reference a single formula e.g. `brew install wget`. If they do, open an issue at https://github.com/Homebrew/homebrew-core/issues/new/choose instead.
|
||||
required: true
|
||||
- type: textarea
|
||||
|
7
.github/codeql/extensions/homebrew-actions.yml
vendored
Normal file
7
.github/codeql/extensions/homebrew-actions.yml
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
# This file is synced from the `.github` repository, do not modify it directly.
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/actions-all
|
||||
extensible: trustedActionsOwnerDataModel
|
||||
data:
|
||||
- ["Homebrew"]
|
178
.github/dependabot.yml
vendored
178
.github/dependabot.yml
vendored
@ -1,90 +1,94 @@
|
||||
# This file is synced from the `.github` repository, do not modify it directly.
|
||||
---
|
||||
version: 2
|
||||
|
||||
updates:
|
||||
- package-ecosystem: github-actions
|
||||
directory: /
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: "friday"
|
||||
time: "08:00"
|
||||
timezone: "Etc/UTC"
|
||||
allow:
|
||||
- dependency-type: all
|
||||
groups:
|
||||
github-actions:
|
||||
patterns:
|
||||
- "*"
|
||||
- package-ecosystem: github-actions
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: friday
|
||||
time: '08:00'
|
||||
timezone: Etc/UTC
|
||||
allow:
|
||||
- dependency-type: all
|
||||
groups:
|
||||
dependabot:
|
||||
patterns:
|
||||
- "*"
|
||||
cooldown:
|
||||
default-days: 1
|
||||
include:
|
||||
- "*"
|
||||
- package-ecosystem: bundler
|
||||
directories:
|
||||
- "/Library/Homebrew"
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: friday
|
||||
time: '08:00'
|
||||
timezone: Etc/UTC
|
||||
allow:
|
||||
- dependency-type: all
|
||||
groups:
|
||||
dependabot:
|
||||
patterns:
|
||||
- "*"
|
||||
cooldown:
|
||||
default-days: 1
|
||||
semver-major-days: 14
|
||||
semver-minor-days: 7
|
||||
semver-patch-days: 1
|
||||
include:
|
||||
- "*"
|
||||
- package-ecosystem: docker
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: friday
|
||||
time: '08:00'
|
||||
timezone: Etc/UTC
|
||||
allow:
|
||||
- dependency-type: all
|
||||
groups:
|
||||
dependabot:
|
||||
patterns:
|
||||
- "*"
|
||||
- package-ecosystem: devcontainers
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: friday
|
||||
time: '08:00'
|
||||
timezone: Etc/UTC
|
||||
allow:
|
||||
- dependency-type: all
|
||||
groups:
|
||||
dependabot:
|
||||
patterns:
|
||||
- "*"
|
||||
cooldown:
|
||||
default-days: 1
|
||||
include:
|
||||
- "*"
|
||||
- package-ecosystem: pip
|
||||
directories:
|
||||
- "/Library/Homebrew/formula-analytics/"
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: friday
|
||||
time: '08:00'
|
||||
timezone: Etc/UTC
|
||||
allow:
|
||||
- dependency-type: all
|
||||
groups:
|
||||
dependabot:
|
||||
patterns:
|
||||
- "*"
|
||||
cooldown:
|
||||
default-days: 1
|
||||
semver-major-days: 14
|
||||
semver-minor-days: 7
|
||||
semver-patch-days: 1
|
||||
include:
|
||||
- "*"
|
||||
|
||||
- package-ecosystem: bundler
|
||||
directories:
|
||||
- /
|
||||
- /Library/Homebrew
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: "friday"
|
||||
time: "08:00"
|
||||
timezone: "Etc/UTC"
|
||||
allow:
|
||||
- dependency-type: all
|
||||
groups:
|
||||
bundler:
|
||||
patterns:
|
||||
- "*"
|
||||
|
||||
- package-ecosystem: npm
|
||||
directory: /
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: "friday"
|
||||
time: "08:00"
|
||||
timezone: "Etc/UTC"
|
||||
allow:
|
||||
- dependency-type: all
|
||||
groups:
|
||||
npm:
|
||||
patterns:
|
||||
- "*"
|
||||
|
||||
- package-ecosystem: docker
|
||||
directory: /
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: "friday"
|
||||
time: "08:00"
|
||||
timezone: "Etc/UTC"
|
||||
allow:
|
||||
- dependency-type: all
|
||||
groups:
|
||||
docker:
|
||||
patterns:
|
||||
- "*"
|
||||
|
||||
- package-ecosystem: devcontainers
|
||||
directory: /
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: "friday"
|
||||
time: "08:00"
|
||||
timezone: "Etc/UTC"
|
||||
allow:
|
||||
- dependency-type: all
|
||||
groups:
|
||||
devcontainers:
|
||||
patterns:
|
||||
- "*"
|
||||
|
||||
- package-ecosystem: pip
|
||||
directories:
|
||||
- /
|
||||
- /Library/Homebrew/formula-analytics/
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: "friday"
|
||||
time: "08:00"
|
||||
timezone: "Etc/UTC"
|
||||
allow:
|
||||
- dependency-type: all
|
||||
groups:
|
||||
pip:
|
||||
patterns:
|
||||
- "*"
|
||||
|
64
.github/workflows/actionlint.yml
vendored
64
.github/workflows/actionlint.yml
vendored
@ -1,18 +1,12 @@
|
||||
name: actionlint
|
||||
# This file is synced from the `.github` repository, do not modify it directly.
|
||||
name: Actionlint
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/*.ya?ml'
|
||||
- '.github/actionlint.yaml'
|
||||
|
||||
env:
|
||||
HOMEBREW_DEVELOPER: 1
|
||||
HOMEBREW_NO_AUTO_UPDATE: 1
|
||||
HOMEBREW_NO_ENV_HINTS: 1
|
||||
|
||||
defaults:
|
||||
run:
|
||||
@ -22,16 +16,25 @@ concurrency:
|
||||
group: "actionlint-${{ github.ref }}"
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
env:
|
||||
HOMEBREW_DEVELOPER: 1
|
||||
HOMEBREW_NO_AUTO_UPDATE: 1
|
||||
HOMEBREW_NO_ENV_HINTS: 1
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
workflow_syntax:
|
||||
if: github.repository_owner == 'Homebrew'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
container:
|
||||
image: ghcr.io/homebrew/ubuntu22.04:main
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
id: setup-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
uses: Homebrew/actions/setup-homebrew@main
|
||||
with:
|
||||
core: false
|
||||
cask: false
|
||||
@ -40,31 +43,44 @@ jobs:
|
||||
- name: Install tools
|
||||
run: brew install actionlint shellcheck zizmor
|
||||
|
||||
- name: Set up GITHUB_WORKSPACE
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- run: zizmor --format sarif . > results.sarif
|
||||
env:
|
||||
HOMEBREW_REPOSITORY: ${{ steps.setup-homebrew.outputs.repository-path }}
|
||||
run: |
|
||||
# Annotations work only relative to GITHUB_WORKSPACE
|
||||
(shopt -s dotglob; rm -rf "${GITHUB_WORKSPACE:?}"/*; mv "${HOMEBREW_REPOSITORY:?}"/* "$GITHUB_WORKSPACE")
|
||||
rmdir "$HOMEBREW_REPOSITORY"
|
||||
ln -vs "$GITHUB_WORKSPACE" "$HOMEBREW_REPOSITORY"
|
||||
|
||||
echo "::add-matcher::.github/actionlint-matcher.json"
|
||||
|
||||
- run: |
|
||||
# NOTE: exit code intentionally suppressed here
|
||||
zizmor --format sarif . > results.sarif || true
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Upload SARIF file
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
# We can't use the SARIF file when triggered by `merge_group` so we don't upload it.
|
||||
if: always() && github.event_name != 'merge_group'
|
||||
with:
|
||||
name: results.sarif
|
||||
path: results.sarif
|
||||
|
||||
- name: Set up actionlint
|
||||
run: |
|
||||
# In homebrew-core, setting `shell: /bin/bash` prevents shellcheck from running on
|
||||
# those steps, so let's change them to `shell: bash` temporarily for better linting.
|
||||
sed -i 's|shell: /bin/bash -x|shell: bash -x|' .github/workflows/*.y*ml
|
||||
|
||||
# In homebrew-core, the JSON matcher needs to be accessible to the container host.
|
||||
cp "$(brew --repository)/.github/actionlint-matcher.json" "$HOME"
|
||||
|
||||
echo "::add-matcher::$HOME/actionlint-matcher.json"
|
||||
|
||||
- run: actionlint
|
||||
|
||||
upload_sarif:
|
||||
needs: workflow_syntax
|
||||
# We want to always upload this even if `actionlint` failed.
|
||||
# This is only available on public repositories.
|
||||
if: >
|
||||
always() &&
|
||||
!contains(fromJSON('["cancelled", "skipped"]'), needs.workflow_syntax.result) &&
|
||||
!github.event.repository.private &&
|
||||
github.event_name != 'merge_group'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
@ -77,7 +93,7 @@ jobs:
|
||||
path: results.sarif
|
||||
|
||||
- name: Upload SARIF file
|
||||
uses: github/codeql-action/upload-sarif@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
|
||||
uses: github/codeql-action/upload-sarif@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
category: zizmor
|
||||
|
2
.github/workflows/autogenerated-files.yml
vendored
2
.github/workflows/autogenerated-files.yml
vendored
@ -27,7 +27,7 @@ jobs:
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
uses: Homebrew/actions/setup-homebrew@main
|
||||
with:
|
||||
core: false
|
||||
cask: false
|
||||
|
7
.github/workflows/codeql-analysis.yml
vendored
7
.github/workflows/codeql-analysis.yml
vendored
@ -3,10 +3,9 @@ name: "CodeQL"
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
defaults:
|
||||
run:
|
||||
@ -28,7 +27,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
|
||||
uses: github/codeql-action/init@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
|
||||
with:
|
||||
languages: ruby
|
||||
config: |
|
||||
@ -36,4 +35,4 @@ jobs:
|
||||
- Library/Homebrew/vendor
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
|
||||
uses: github/codeql-action/analyze@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
|
||||
|
23
.github/workflows/docker.yml
vendored
23
.github/workflows/docker.yml
vendored
@ -4,6 +4,7 @@ on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
merge_group:
|
||||
release:
|
||||
@ -38,8 +39,8 @@ jobs:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Fetch origin/master from Git
|
||||
run: git fetch origin master
|
||||
- name: Fetch origin/HEAD from Git
|
||||
run: git fetch origin HEAD
|
||||
|
||||
- name: Determine build attributes
|
||||
id: attributes
|
||||
@ -83,12 +84,16 @@ jobs:
|
||||
)
|
||||
fi
|
||||
elif [[ "${GITHUB_EVENT_NAME}" == "push" &&
|
||||
"${GITHUB_REF}" == "refs/heads/master" &&
|
||||
("${GITHUB_REF}" == "refs/heads/master" || "${GITHUB_REF}" == "refs/heads/main") &&
|
||||
"${version}" == "22.04" ]]; then
|
||||
tags+=(
|
||||
"ghcr.io/homebrew/brew:main"
|
||||
"ghcr.io/homebrew/brew:master"
|
||||
"ghcr.io/homebrew/ubuntu${version}:main"
|
||||
"ghcr.io/homebrew/ubuntu${version}:master"
|
||||
"homebrew/brew:main"
|
||||
"homebrew/brew:master"
|
||||
"homebrew/ubuntu${version}:main"
|
||||
"homebrew/ubuntu${version}:master"
|
||||
)
|
||||
fi
|
||||
@ -160,11 +165,11 @@ jobs:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Fetch origin/master from Git
|
||||
run: git fetch origin master
|
||||
- name: Fetch origin/HEAD from Git
|
||||
run: git fetch origin HEAD
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
with:
|
||||
cache-binary: false
|
||||
|
||||
@ -190,7 +195,7 @@ jobs:
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build Docker image
|
||||
uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||
with:
|
||||
context: .
|
||||
load: true
|
||||
@ -227,7 +232,7 @@ jobs:
|
||||
- name: Deploy the Docker image by digest
|
||||
id: digest
|
||||
if: fromJSON(steps.attributes.outputs.push)
|
||||
uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||
with:
|
||||
context: .
|
||||
cache-from: type=registry,ref=ghcr.io/homebrew/ubuntu${{ matrix.version }}:cache
|
||||
@ -263,7 +268,7 @@ jobs:
|
||||
version: ${{ fromJSON(needs.generate-tags.outputs.matrix) }}
|
||||
steps:
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
with:
|
||||
cache-binary: false
|
||||
|
||||
|
12
.github/workflows/docs.yml
vendored
12
.github/workflows/docs.yml
vendored
@ -24,7 +24,7 @@ jobs:
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
uses: Homebrew/actions/setup-homebrew@main
|
||||
with:
|
||||
core: false
|
||||
cask: false
|
||||
@ -52,7 +52,7 @@ jobs:
|
||||
run: vale docs/
|
||||
|
||||
- name: Install Ruby
|
||||
uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0
|
||||
uses: ruby/setup-ruby@a4effe49ee8ee5b8b5091268c473a4628afb5651 # v1.245.0
|
||||
with:
|
||||
bundler-cache: true
|
||||
working-directory: docs
|
||||
@ -67,7 +67,13 @@ jobs:
|
||||
- name: Generate formulae.brew.sh API samples
|
||||
if: github.repository == 'Homebrew/formulae.brew.sh'
|
||||
working-directory: docs
|
||||
run: ../script/generate-api-samples.rb
|
||||
run: ../script/generate-api-samples.rb --template
|
||||
|
||||
- name: Cache HTML Proofer
|
||||
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
||||
with:
|
||||
path: tmp/.htmlproofer
|
||||
key: ${{ runner.os }}-htmlproofer
|
||||
|
||||
- name: Build the site and check for broken links
|
||||
working-directory: docs
|
||||
|
4
.github/workflows/doctor.yml
vendored
4
.github/workflows/doctor.yml
vendored
@ -28,7 +28,7 @@ jobs:
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
uses: Homebrew/actions/setup-homebrew@main
|
||||
with:
|
||||
core: false
|
||||
cask: false
|
||||
@ -55,7 +55,7 @@ jobs:
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
uses: Homebrew/actions/setup-homebrew@main
|
||||
with:
|
||||
core: false
|
||||
cask: false
|
||||
|
20
.github/workflows/pkg-installer.yml
vendored
20
.github/workflows/pkg-installer.yml
vendored
@ -43,7 +43,7 @@ jobs:
|
||||
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
uses: Homebrew/actions/setup-homebrew@main
|
||||
with:
|
||||
core: false
|
||||
cask: false
|
||||
@ -135,7 +135,7 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Generate build provenance
|
||||
uses: actions/attest-build-provenance@db473fddc028af60658334401dc6fa3ffd8669fd # v2.3.0
|
||||
uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2.4.0
|
||||
with:
|
||||
subject-path: Homebrew-${{ steps.homebrew-version.outputs.version }}.pkg
|
||||
|
||||
@ -230,17 +230,15 @@ jobs:
|
||||
--password "${PKG_APPLE_ID_APP_SPECIFIC_PASSWORD}"
|
||||
--wait
|
||||
|
||||
- name: Install gh
|
||||
run: brew install gh
|
||||
|
||||
- name: Upload installer to GitHub release
|
||||
if: github.event_name == 'release'
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
INSTALLER_PATH: ${{ needs.build.outputs.installer_path }}
|
||||
run: gh release upload --repo Homebrew/brew
|
||||
"${GITHUB_REF//refs\/tags\//}"
|
||||
"${INSTALLER_PATH}"
|
||||
run: |
|
||||
VERSION="${INSTALLER_PATH#Homebrew-}"
|
||||
VERSION="${VERSION%.pkg}"
|
||||
gh release upload --repo Homebrew/brew "${VERSION}" "${INSTALLER_PATH}"
|
||||
|
||||
issue:
|
||||
needs: [build, test, upload]
|
||||
@ -253,7 +251,7 @@ jobs:
|
||||
issues: write
|
||||
steps:
|
||||
- name: Open, update, or close pkg installer issue
|
||||
uses: Homebrew/actions/create-or-update-issue@master
|
||||
uses: Homebrew/actions/create-or-update-issue@main
|
||||
with:
|
||||
title: Failed to publish pkg installer
|
||||
body: >
|
||||
@ -261,7 +259,7 @@ jobs:
|
||||
${{ github.ref_name }}. No pkg installer was uploaded to the GitHub
|
||||
release.
|
||||
labels: bug,release blocker
|
||||
update-existing: ${{ contains(needs.*.result, 'failure') }}
|
||||
update-existing: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'skipped') }}
|
||||
close-existing: ${{ needs.upload.result == 'success' }}
|
||||
close-from-author: github-actions[bot]
|
||||
close-comment: >
|
||||
|
5
.github/workflows/rubydoc.yml
vendored
5
.github/workflows/rubydoc.yml
vendored
@ -3,6 +3,7 @@ name: Ruby Documentation CI
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
pull_request:
|
||||
|
||||
@ -28,7 +29,7 @@ jobs:
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
uses: Homebrew/actions/setup-homebrew@main
|
||||
with:
|
||||
core: false
|
||||
cask: false
|
||||
@ -42,7 +43,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install Ruby
|
||||
uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0
|
||||
uses: ruby/setup-ruby@a4effe49ee8ee5b8b5091268c473a4628afb5651 # v1.245.0
|
||||
with:
|
||||
bundler-cache: true
|
||||
working-directory: rubydoc
|
||||
|
@ -1,9 +1,10 @@
|
||||
name: Update schema data
|
||||
name: Update SBOM schema
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- .github/workflows/schemas.yml
|
||||
- .github/workflows/sbom.yml
|
||||
branches-ignore:
|
||||
- main
|
||||
- master
|
||||
schedule:
|
||||
- cron: "0 0 * * *"
|
||||
@ -17,25 +18,25 @@ defaults:
|
||||
shell: bash -xeuo pipefail {0}
|
||||
|
||||
jobs:
|
||||
spdx:
|
||||
sbom:
|
||||
if: github.repository == 'Homebrew/brew'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
uses: Homebrew/actions/setup-homebrew@main
|
||||
with:
|
||||
core: false
|
||||
cask: false
|
||||
test-bot: false
|
||||
|
||||
- name: Configure Git user
|
||||
uses: Homebrew/actions/git-user-config@master
|
||||
uses: Homebrew/actions/git-user-config@main
|
||||
with:
|
||||
username: BrewTestBot
|
||||
|
||||
- name: Set up commit signing
|
||||
uses: Homebrew/actions/setup-commit-signing@master
|
||||
uses: Homebrew/actions/setup-commit-signing@main
|
||||
with:
|
||||
signing_key: ${{ secrets.BREWTESTBOT_SSH_SIGNING_KEY }}
|
||||
|
||||
@ -55,7 +56,7 @@ jobs:
|
||||
git checkout "${BRANCH}"
|
||||
git checkout "Library/Homebrew/data/schemas"
|
||||
else
|
||||
git checkout --no-track -B "${BRANCH}" origin/master
|
||||
git checkout --no-track -B "${BRANCH}" origin/HEAD
|
||||
fi
|
||||
|
||||
# Intentionally tracking 2.3.x to match what we output in sbom.rb. 3.0 also doesn't have a JSON Schema.
|
||||
@ -67,9 +68,10 @@ jobs:
|
||||
if ! git diff --exit-code Library/Homebrew/data/schemas
|
||||
then
|
||||
git add "Library/Homebrew/data/schemas"
|
||||
git commit -m "data/schemas: update schema data." -m "Autogenerated by [a scheduled GitHub Action](https://github.com/Homebrew/brew/blob/master/.github/workflows/schemas.yml)."
|
||||
git commit -m "data/schemas: update schema data." -m "Autogenerated by [a scheduled GitHub Action](https://github.com/Homebrew/brew/blob/HEAD/.github/workflows/schemas.yml)."
|
||||
|
||||
echo "committed=true" >> "$GITHUB_OUTPUT"
|
||||
PULL_REQUEST_STATE="$(gh pr view --json=state | jq -r ".state")"
|
||||
PULL_REQUEST_STATE="$(gh pr view --json=state | jq -r ".state" || true)"
|
||||
if [[ "${PULL_REQUEST_STATE}" != "OPEN" ]]
|
||||
then
|
||||
echo "pull_request=true" >> "$GITHUB_OUTPUT"
|
||||
@ -78,13 +80,13 @@ jobs:
|
||||
|
||||
- name: Push commits
|
||||
if: steps.update.outputs.committed == 'true'
|
||||
uses: Homebrew/actions/git-try-push@master
|
||||
uses: Homebrew/actions/git-try-push@main
|
||||
with:
|
||||
token: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
||||
directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||
branch: ${{ steps.update.outputs.branch }}
|
||||
force: true
|
||||
origin_branch: "master"
|
||||
origin_branch: "HEAD"
|
||||
|
||||
- name: Open a pull request
|
||||
if: steps.update.outputs.pull_request == 'true'
|
||||
@ -92,3 +94,26 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
||||
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||
|
||||
issue:
|
||||
needs: sbom
|
||||
if: always() && github.event_name == 'schedule'
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
permissions:
|
||||
# To create or update issues
|
||||
issues: write
|
||||
steps:
|
||||
- name: Open, update, or close schema issue
|
||||
uses: Homebrew/actions/create-or-update-issue@main
|
||||
with:
|
||||
title: Failed to update SBOM schema
|
||||
body: >
|
||||
The SBOM schema workflow [failed](${{ env.RUN_URL }}). No SBOM schema was updated.
|
||||
labels: bug
|
||||
update-existing: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'skipped') }}
|
||||
close-existing: ${{ needs.sbom.result == 'success' }}
|
||||
close-from-author: github-actions[bot]
|
||||
close-comment: >
|
||||
The SBOM schema workflow [succeeded](${{ env.RUN_URL }}). Closing this issue.
|
42
.github/workflows/sorbet.yml
vendored
42
.github/workflows/sorbet.yml
vendored
@ -10,6 +10,7 @@ on:
|
||||
paths:
|
||||
- .github/workflows/sorbet.yml
|
||||
branches-ignore:
|
||||
- main
|
||||
- master
|
||||
schedule:
|
||||
- cron: "0 0 * * *"
|
||||
@ -29,7 +30,7 @@ jobs:
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
uses: Homebrew/actions/setup-homebrew@main
|
||||
with:
|
||||
core: false
|
||||
cask: false
|
||||
@ -37,13 +38,13 @@ jobs:
|
||||
|
||||
- name: Configure Git user
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: Homebrew/actions/git-user-config@master
|
||||
uses: Homebrew/actions/git-user-config@main
|
||||
with:
|
||||
username: BrewTestBot
|
||||
|
||||
- name: Set up commit signing
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: Homebrew/actions/setup-commit-signing@master
|
||||
uses: Homebrew/actions/setup-commit-signing@main
|
||||
with:
|
||||
signing_key: ${{ secrets.BREWTESTBOT_SSH_SIGNING_KEY }}
|
||||
|
||||
@ -63,7 +64,7 @@ jobs:
|
||||
git checkout "${BRANCH}"
|
||||
git checkout "Library/Homebrew/sorbet"
|
||||
else
|
||||
git checkout --no-track -B "${BRANCH}" origin/master
|
||||
git checkout --no-track -B "${BRANCH}" origin/HEAD
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -80,17 +81,17 @@ jobs:
|
||||
then
|
||||
git add "Library/Homebrew/sorbet"
|
||||
git commit -m "sorbet: Update RBI files." \
|
||||
-m "Autogenerated by the [sorbet](https://github.com/Homebrew/brew/blob/master/.github/workflows/sorbet.yml) workflow."
|
||||
-m "Autogenerated by the [sorbet](https://github.com/Homebrew/brew/blob/HEAD/.github/workflows/sorbet.yml) workflow."
|
||||
|
||||
if ! git diff --stat --exit-code "Library/Homebrew"
|
||||
then
|
||||
git add "Library/Homebrew/"
|
||||
git commit -m "sorbet: Autobump sigils via Spoom" \
|
||||
-m "Autogenerated by the [sorbet](https://github.com/Homebrew/brew/blob/master/.github/workflows/sorbet.yml) workflow."
|
||||
-m "Autogenerated by the [sorbet](https://github.com/Homebrew/brew/blob/HEAD/.github/workflows/sorbet.yml) workflow."
|
||||
fi
|
||||
|
||||
echo "committed=true" >> "$GITHUB_OUTPUT"
|
||||
PULL_REQUEST_STATE="$(gh pr view --json=state | jq -r ".state")"
|
||||
PULL_REQUEST_STATE="$(gh pr view --json=state | jq -r ".state" || true)"
|
||||
if [[ "${PULL_REQUEST_STATE}" != "OPEN" ]]
|
||||
then
|
||||
echo "pull_request=true" >> "$GITHUB_OUTPUT"
|
||||
@ -99,13 +100,13 @@ jobs:
|
||||
|
||||
- name: Push commits
|
||||
if: steps.commit.outputs.committed == 'true'
|
||||
uses: Homebrew/actions/git-try-push@master
|
||||
uses: Homebrew/actions/git-try-push@main
|
||||
with:
|
||||
token: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
||||
directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||
branch: ${{ steps.update.outputs.branch }}
|
||||
force: true
|
||||
origin_branch: "master"
|
||||
origin_branch: "HEAD"
|
||||
|
||||
- name: Open a pull request
|
||||
if: steps.commit.outputs.pull_request == 'true'
|
||||
@ -113,3 +114,26 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
||||
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||
|
||||
issue:
|
||||
needs: tapioca
|
||||
if: always() && github.event_name == 'schedule'
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
permissions:
|
||||
# To create or update issues
|
||||
issues: write
|
||||
steps:
|
||||
- name: Open, update, or close Sorbet issue
|
||||
uses: Homebrew/actions/create-or-update-issue@main
|
||||
with:
|
||||
title: Failed to update RBI files
|
||||
body: >
|
||||
The Sorbet workflow [failed](${{ env.RUN_URL }}). No RBI files were updated.
|
||||
labels: bug
|
||||
update-existing: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'skipped') }}
|
||||
close-existing: ${{ needs.tapioca.result == 'success' }}
|
||||
close-from-author: github-actions[bot]
|
||||
close-comment: >
|
||||
The Sorbet workflow [succeeded](${{ env.RUN_URL }}). Closing this issue.
|
||||
|
41
.github/workflows/spdx.yml
vendored
41
.github/workflows/spdx.yml
vendored
@ -4,6 +4,7 @@ on:
|
||||
paths:
|
||||
- .github/workflows/spdx.yml
|
||||
branches-ignore:
|
||||
- main
|
||||
- master
|
||||
schedule:
|
||||
- cron: "0 0 * * *"
|
||||
@ -23,19 +24,19 @@ jobs:
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
uses: Homebrew/actions/setup-homebrew@main
|
||||
with:
|
||||
core: false
|
||||
cask: false
|
||||
test-bot: false
|
||||
|
||||
- name: Configure Git user
|
||||
uses: Homebrew/actions/git-user-config@master
|
||||
uses: Homebrew/actions/git-user-config@main
|
||||
with:
|
||||
username: BrewTestBot
|
||||
|
||||
- name: Set up commit signing
|
||||
uses: Homebrew/actions/setup-commit-signing@master
|
||||
uses: Homebrew/actions/setup-commit-signing@main
|
||||
with:
|
||||
signing_key: ${{ secrets.BREWTESTBOT_SSH_SIGNING_KEY }}
|
||||
|
||||
@ -55,15 +56,16 @@ jobs:
|
||||
git checkout "${BRANCH}"
|
||||
git checkout "Library/Homebrew/data/spdx"
|
||||
else
|
||||
git checkout --no-track -B "${BRANCH}" origin/master
|
||||
git checkout --no-track -B "${BRANCH}" origin/HEAD
|
||||
fi
|
||||
|
||||
if brew update-license-data
|
||||
then
|
||||
git add "Library/Homebrew/data/spdx"
|
||||
git commit -m "spdx: update license data." -m "Autogenerated by [a scheduled GitHub Action](https://github.com/Homebrew/brew/blob/master/.github/workflows/spdx.yml)."
|
||||
git commit -m "spdx: update license data." -m "Autogenerated by [a scheduled GitHub Action](https://github.com/Homebrew/brew/blob/HEAD/.github/workflows/spdx.yml)."
|
||||
|
||||
echo "committed=true" >> "$GITHUB_OUTPUT"
|
||||
PULL_REQUEST_STATE="$(gh pr view --json=state | jq -r ".state")"
|
||||
PULL_REQUEST_STATE="$(gh pr view --json=state | jq -r ".state" || true)"
|
||||
if [[ "${PULL_REQUEST_STATE}" != "OPEN" ]]
|
||||
then
|
||||
echo "pull_request=true" >> "$GITHUB_OUTPUT"
|
||||
@ -72,13 +74,13 @@ jobs:
|
||||
|
||||
- name: Push commits
|
||||
if: steps.update.outputs.committed == 'true'
|
||||
uses: Homebrew/actions/git-try-push@master
|
||||
uses: Homebrew/actions/git-try-push@main
|
||||
with:
|
||||
token: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
||||
directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||
branch: ${{ steps.update.outputs.branch }}
|
||||
force: true
|
||||
origin_branch: "master"
|
||||
origin_branch: "HEAD"
|
||||
|
||||
- name: Open a pull request
|
||||
if: steps.update.outputs.pull_request == 'true'
|
||||
@ -86,3 +88,26 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
||||
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||
|
||||
issue:
|
||||
needs: spdx
|
||||
if: always() && github.event_name == 'schedule'
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
permissions:
|
||||
# To create or update issues
|
||||
issues: write
|
||||
steps:
|
||||
- name: Open, update, or close SPDX issue
|
||||
uses: Homebrew/actions/create-or-update-issue@main
|
||||
with:
|
||||
title: Failed to update SPDX license data
|
||||
body: >
|
||||
The SPDX license data workflow [failed](${{ env.RUN_URL }}). No SPDX license data was updated.
|
||||
labels: bug
|
||||
update-existing: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'skipped') }}
|
||||
close-existing: ${{ needs.spdx.result == 'success' }}
|
||||
close-from-author: github-actions[bot]
|
||||
close-comment: >
|
||||
The SPDX license data workflow [succeeded](${{ env.RUN_URL }}). Closing this issue.
|
||||
|
@ -3,6 +3,7 @@ name: Update sponsors, maintainers, manpage and completions
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
paths:
|
||||
- .github/workflows/sponsors-maintainers-man-completions.yml
|
||||
@ -32,19 +33,19 @@ jobs:
|
||||
steps:
|
||||
- name: Setup Homebrew
|
||||
id: set-up-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
uses: Homebrew/actions/setup-homebrew@main
|
||||
with:
|
||||
core: false
|
||||
cask: false
|
||||
test-bot: false
|
||||
|
||||
- name: Configure Git user
|
||||
uses: Homebrew/actions/git-user-config@master
|
||||
uses: Homebrew/actions/git-user-config@main
|
||||
with:
|
||||
username: BrewTestBot
|
||||
|
||||
- name: Set up commit signing
|
||||
uses: Homebrew/actions/setup-commit-signing@master
|
||||
uses: Homebrew/actions/setup-commit-signing@main
|
||||
with:
|
||||
signing_key: ${{ secrets.BREWTESTBOT_SSH_SIGNING_KEY }}
|
||||
|
||||
@ -60,7 +61,7 @@ jobs:
|
||||
run: |
|
||||
git fetch origin
|
||||
|
||||
if [[ -n "$GITHUB_REF_NAME" && "$GITHUB_REF_NAME" != "master" ]]
|
||||
if [[ -n "$GITHUB_REF_NAME" && "$GITHUB_REF_NAME" != "master" && "$GITHUB_REF_NAME" != "main" ]]
|
||||
then
|
||||
BRANCH="$GITHUB_REF_NAME"
|
||||
else
|
||||
@ -76,7 +77,7 @@ jobs:
|
||||
"manpages/brew.1" \
|
||||
"completions"
|
||||
else
|
||||
git checkout --force --no-track -B "${BRANCH}" origin/master
|
||||
git checkout --force --no-track -B "${BRANCH}" origin/HEAD
|
||||
fi
|
||||
|
||||
if brew update-sponsors
|
||||
@ -111,7 +112,7 @@ jobs:
|
||||
if [[ -n "${COMMITTED-}" ]]
|
||||
then
|
||||
echo "committed=true" >> "$GITHUB_OUTPUT"
|
||||
PULL_REQUEST_STATE="$(gh pr view --json=state | jq -r ".state")"
|
||||
PULL_REQUEST_STATE="$(gh pr view --json=state | jq -r ".state" || true)"
|
||||
if [[ "${PULL_REQUEST_STATE}" != "OPEN" ]]
|
||||
then
|
||||
echo "pull_request=true" >> "$GITHUB_OUTPUT"
|
||||
@ -124,7 +125,7 @@ jobs:
|
||||
|
||||
- name: Push commits
|
||||
if: steps.update.outputs.committed == 'true'
|
||||
uses: Homebrew/actions/git-try-push@master
|
||||
uses: Homebrew/actions/git-try-push@main
|
||||
with:
|
||||
token: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
||||
directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||
@ -137,3 +138,26 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
||||
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||
|
||||
issue:
|
||||
needs: updates
|
||||
if: always() && github.event_name == 'schedule'
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
permissions:
|
||||
# To create or update issues
|
||||
issues: write
|
||||
steps:
|
||||
- name: Open, update, or close sponsors, maintainers, manpage and completions issue
|
||||
uses: Homebrew/actions/create-or-update-issue@main
|
||||
with:
|
||||
title: Failed to update sponsors, maintainers, manpage and completions
|
||||
body: >
|
||||
The sponsors, maintainers, manpage and completions workflow [failed](${{ env.RUN_URL }}). No sponsors, maintainers, manpage and completions were updated.
|
||||
labels: bug
|
||||
update-existing: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'skipped') }}
|
||||
close-existing: ${{ needs.updates.result == 'success' }}
|
||||
close-from-author: github-actions[bot]
|
||||
close-comment: >
|
||||
The sponsors, maintainers, manpage and completions workflow [succeeded](${{ env.RUN_URL }}). Closing this issue.
|
||||
|
64
.github/workflows/sync-default-branches.yml
vendored
Normal file
64
.github/workflows/sync-default-branches.yml
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
name: Sync default branches
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
pull_request:
|
||||
paths:
|
||||
- .github/workflows/sync-default-branches.yml
|
||||
|
||||
permissions: {}
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash -xeuo pipefail {0}
|
||||
|
||||
concurrency:
|
||||
group: "sync-default-branches-${{ github.ref }}"
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
sync:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Configure Git user
|
||||
uses: Homebrew/actions/git-user-config@main
|
||||
with:
|
||||
username: github-actions[bot]
|
||||
|
||||
- name: Determine source and target branches
|
||||
id: branches
|
||||
run: |
|
||||
if [[ "${GITHUB_REF_NAME}" == "main" ]]; then
|
||||
target="master"
|
||||
source="main"
|
||||
else
|
||||
target="main"
|
||||
source="master"
|
||||
fi
|
||||
echo "target=${target}" >> "$GITHUB_OUTPUT"
|
||||
echo "source=${source}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
fetch-depth: 1
|
||||
persist-credentials: true
|
||||
|
||||
- name: Get target SHA
|
||||
id: sha
|
||||
run: |
|
||||
TARGET_SHA=$(git ls-remote origin "refs/heads/${SOURCE_BRANCH}" | cut -f1)
|
||||
echo "target=${TARGET_SHA}" >> "$GITHUB_OUTPUT"
|
||||
env:
|
||||
SOURCE_BRANCH: ${{ steps.branches.outputs.source }}
|
||||
|
||||
- name: Push target branch
|
||||
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master'
|
||||
run: git push origin "${TARGET_SHA}:refs/heads/${TARGET_BRANCH}" --force
|
||||
env:
|
||||
TARGET_SHA: ${{ steps.sha.outputs.target }}
|
||||
TARGET_BRANCH: ${{ steps.branches.outputs.target }}
|
132
.github/workflows/tests.yml
vendored
132
.github/workflows/tests.yml
vendored
@ -3,6 +3,7 @@ name: CI
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
pull_request:
|
||||
merge_group:
|
||||
@ -32,7 +33,7 @@ jobs:
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
uses: Homebrew/actions/setup-homebrew@main
|
||||
with:
|
||||
core: false
|
||||
cask: false
|
||||
@ -80,11 +81,11 @@ jobs:
|
||||
name: tap syntax
|
||||
needs: syntax
|
||||
if: github.repository_owner == 'Homebrew'
|
||||
runs-on: macos-14
|
||||
runs-on: macos-15
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
uses: Homebrew/actions/setup-homebrew@main
|
||||
with:
|
||||
core: true
|
||||
cask: true
|
||||
@ -135,13 +136,13 @@ jobs:
|
||||
if: github.repository_owner == 'Homebrew' && github.event_name != 'push'
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ghcr.io/homebrew/brew:master
|
||||
image: ghcr.io/homebrew/brew:main
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
uses: Homebrew/actions/setup-homebrew@main
|
||||
with:
|
||||
core: true
|
||||
core: false
|
||||
cask: false
|
||||
test-bot: false
|
||||
|
||||
@ -162,7 +163,7 @@ jobs:
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
uses: Homebrew/actions/setup-homebrew@main
|
||||
with:
|
||||
core: true
|
||||
cask: true
|
||||
@ -185,14 +186,14 @@ jobs:
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
uses: Homebrew/actions/setup-homebrew@main
|
||||
with:
|
||||
core: false
|
||||
cask: false
|
||||
test-bot: false
|
||||
|
||||
- name: Configure Git user
|
||||
uses: Homebrew/actions/git-user-config@master
|
||||
uses: Homebrew/actions/git-user-config@main
|
||||
with:
|
||||
username: BrewTestBot
|
||||
|
||||
@ -213,14 +214,14 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- name: update-test (Ubuntu)
|
||||
- name: update-test (Linux)
|
||||
runs-on: ubuntu-latest
|
||||
- name: update-test (macOS)
|
||||
runs-on: macos-15
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
uses: Homebrew/actions/setup-homebrew@main
|
||||
with:
|
||||
core: false
|
||||
cask: false
|
||||
@ -237,7 +238,6 @@ jobs:
|
||||
name: ${{ matrix.name }}
|
||||
needs: syntax
|
||||
runs-on: ${{ matrix.runs-on }}
|
||||
container: ${{ matrix.container }}
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
@ -247,23 +247,16 @@ jobs:
|
||||
- name: tests (generic OS)
|
||||
test-flags: --generic --coverage
|
||||
runs-on: ubuntu-latest
|
||||
- name: tests (Ubuntu 24.04)
|
||||
- name: tests (Linux)
|
||||
test-flags: --coverage
|
||||
runs-on: ubuntu-24.04
|
||||
- name: tests (Ubuntu 22.04)
|
||||
test-flags: --coverage
|
||||
runs-on: ubuntu-22.04
|
||||
- name: tests (Ubuntu 20.04)
|
||||
test-flags: --coverage
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/homebrew/ubuntu20.04:latest
|
||||
- name: tests (macOS 15 arm64)
|
||||
- name: tests (macOS)
|
||||
test-flags: --coverage
|
||||
runs-on: macos-15
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
uses: Homebrew/actions/setup-homebrew@main
|
||||
with:
|
||||
# We only test needs_homebrew_core tests on macOS because
|
||||
# homebrew/core is not available by default on GitHub-hosted Ubuntu
|
||||
@ -349,7 +342,7 @@ jobs:
|
||||
disable_search: true
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
test-default-formula:
|
||||
test-bot:
|
||||
name: ${{ matrix.name }}
|
||||
needs: syntax
|
||||
if: github.repository_owner == 'Homebrew' && github.event_name != 'push'
|
||||
@ -358,36 +351,76 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- name: test default formula (Ubuntu 24.04)
|
||||
runs-on: ubuntu-latest
|
||||
- name: test-bot (Linux arm64)
|
||||
runs-on: ubuntu-24.04-arm
|
||||
container: ghcr.io/homebrew/ubuntu24.04:latest
|
||||
- name: test default formula (Ubuntu 22.04)
|
||||
- name: test-bot (Linux x86_64)
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/homebrew/ubuntu22.04:master
|
||||
- name: test default formula (Ubuntu 20.04)
|
||||
container: ghcr.io/homebrew/ubuntu22.04:main
|
||||
# Use Debian Old Stable for testing Homebrew's glibc support.
|
||||
- name: test-bot (Linux Homebrew glibc)
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/homebrew/ubuntu20.04:latest
|
||||
- name: test default formula (macOS 13 x86_64)
|
||||
container: debian:oldstable
|
||||
- name: test-bot (macOS x86_64)
|
||||
runs-on: macos-13
|
||||
- name: test default formula (macOS 15 arm64)
|
||||
- name: test-bot (macOS arm64)
|
||||
runs-on: macos-15
|
||||
env:
|
||||
HOMEBREW_TEST_BOT_ANALYTICS: 1
|
||||
HOMEBREW_ENFORCE_SBOM: 1
|
||||
steps:
|
||||
- name: Install Homebrew and Homebrew's dependencies
|
||||
# All other images are built from our Homebrew Dockerfile.
|
||||
# This is the only one that needs to be set up manually.
|
||||
if: matrix.container == 'debian:oldstable'
|
||||
run: |
|
||||
# Slimmed down version from the Homebrew Dockerfile
|
||||
apt-get update
|
||||
apt-get install -y --no-install-recommends \
|
||||
bzip2 \
|
||||
ca-certificates \
|
||||
curl \
|
||||
file \
|
||||
g++ \
|
||||
git-core \
|
||||
less \
|
||||
locales \
|
||||
make \
|
||||
netbase \
|
||||
patch \
|
||||
procps \
|
||||
sudo \
|
||||
uuid-runtime \
|
||||
tzdata
|
||||
|
||||
# Install Homebrew
|
||||
mkdir -p /home/linuxbrew/.linuxbrew/bin
|
||||
# Don't do shallow clone or it's unshallowed by "Set up Homebrew"
|
||||
git clone https://github.com/Homebrew/brew.git /home/linuxbrew/.linuxbrew/Homebrew
|
||||
cd /home/linuxbrew/.linuxbrew/bin
|
||||
ln -s ../Homebrew/bin/brew brew
|
||||
echo "/home/linuxbrew/.linuxbrew/bin" >>"$GITHUB_PATH"
|
||||
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
uses: Homebrew/actions/setup-homebrew@main
|
||||
with:
|
||||
core: true
|
||||
core: false
|
||||
cask: false
|
||||
test-bot: true
|
||||
|
||||
- run: brew test-bot --only-cleanup-before
|
||||
|
||||
- name: Setup environment variables
|
||||
if: matrix.container == 'ghcr.io/homebrew/ubuntu20.04:latest'
|
||||
run: echo "HOMEBREW_GLIBC_TESTING=1" >> "$GITHUB_ENV"
|
||||
run: |
|
||||
# Set enviroment variables to bypass `brew doctor` failures on Tier >=2 configurations
|
||||
if [[ "${MATRIX_NAME}" == "test-bot (Linux arm64)" ]]; then
|
||||
echo "HOMEBREW_ARM64_TESTING=1" >> "$GITHUB_ENV"
|
||||
elif [[ "${MATRIX_NAME}" == "test-bot (Linux Homebrew glibc)" ]]; then
|
||||
echo "HOMEBREW_GLIBC_TESTING=1" >> "$GITHUB_ENV"
|
||||
fi
|
||||
env:
|
||||
MATRIX_NAME: ${{ matrix.name }}
|
||||
|
||||
- run: brew test-bot --only-setup
|
||||
|
||||
@ -395,7 +428,7 @@ jobs:
|
||||
|
||||
- run: brew test-bot --only-formulae --only-json-tab --test-default-formula
|
||||
|
||||
test-brew-bundle-services:
|
||||
bundle-and-services:
|
||||
name: ${{ matrix.name }}
|
||||
needs: syntax
|
||||
if: github.repository_owner == 'Homebrew' && github.event_name != 'push'
|
||||
@ -403,16 +436,16 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- name: test brew bundle and brew services (Ubuntu)
|
||||
- name: bundle and services (Linux)
|
||||
runs-on: ubuntu-latest
|
||||
- name: test brew bundle and brew services (macOS)
|
||||
runs-on: macos-15
|
||||
- name: bundle and services (macOS)
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
uses: Homebrew/actions/setup-homebrew@main
|
||||
with:
|
||||
core: true
|
||||
core: false
|
||||
cask: false
|
||||
test-bot: false
|
||||
|
||||
@ -449,19 +482,22 @@ jobs:
|
||||
brew services cleanup
|
||||
brew bundle cleanup --force
|
||||
|
||||
test-analytics:
|
||||
runs-on: ${{ matrix.os }}
|
||||
analytics:
|
||||
name: ${{ matrix.name }}
|
||||
runs-on: ${{ matrix.runs-on }}
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-latest
|
||||
- macos-latest
|
||||
include:
|
||||
- name: analytics (Linux)
|
||||
runs-on: ubuntu-latest
|
||||
- name: analytics (macOS)
|
||||
runs-on: macos-latest
|
||||
needs: syntax
|
||||
if: github.repository_owner == 'Homebrew' && github.event_name != 'push'
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
uses: Homebrew/actions/setup-homebrew@main
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
||||
|
9
.github/workflows/vendor-gems.yml
vendored
9
.github/workflows/vendor-gems.yml
vendored
@ -9,6 +9,7 @@ on:
|
||||
paths:
|
||||
- .github/workflows/vendor-gems.yml
|
||||
branches-ignore:
|
||||
- main
|
||||
- master
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
@ -31,7 +32,7 @@ jobs:
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
uses: Homebrew/actions/setup-homebrew@main
|
||||
with:
|
||||
core: false
|
||||
cask: false
|
||||
@ -39,13 +40,13 @@ jobs:
|
||||
|
||||
- name: Configure Git user
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
uses: Homebrew/actions/git-user-config@master
|
||||
uses: Homebrew/actions/git-user-config@main
|
||||
with:
|
||||
username: BrewTestBot
|
||||
|
||||
- name: Set up commit signing
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
uses: Homebrew/actions/setup-commit-signing@master
|
||||
uses: Homebrew/actions/setup-commit-signing@main
|
||||
with:
|
||||
signing_key: ${{ secrets.BREWTESTBOT_SSH_SIGNING_KEY }}
|
||||
|
||||
@ -100,7 +101,7 @@ jobs:
|
||||
|
||||
- name: Push to pull request
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
uses: Homebrew/actions/git-try-push@master
|
||||
uses: Homebrew/actions/git-try-push@main
|
||||
with:
|
||||
token: ${{ steps.app-token.outputs.token }}
|
||||
directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||
|
2
.github/workflows/vendor-version.yml
vendored
2
.github/workflows/vendor-version.yml
vendored
@ -19,7 +19,7 @@ jobs:
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
uses: Homebrew/actions/setup-homebrew@main
|
||||
with:
|
||||
core: false
|
||||
cask: false
|
||||
|
1
.github/zizmor.yml
vendored
1
.github/zizmor.yml
vendored
@ -1,3 +1,4 @@
|
||||
# This file is synced from the `.github` repository, do not modify it directly.
|
||||
rules:
|
||||
unpinned-uses:
|
||||
config:
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -164,6 +164,7 @@
|
||||
!/completions
|
||||
!/docs
|
||||
!/manpages
|
||||
!/CODEOWNERS
|
||||
|
||||
# Unignore our packaging files
|
||||
!/package
|
||||
|
11
.vscode/mcp.json
vendored
Normal file
11
.vscode/mcp.json
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"servers": {
|
||||
"Homebrew": {
|
||||
"type": "stdio",
|
||||
"command": "brew",
|
||||
"args": [
|
||||
"mcp-server"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
9
.vscode/ruby-lsp-activate.sh
vendored
9
.vscode/ruby-lsp-activate.sh
vendored
@ -1,5 +1,12 @@
|
||||
#!/bin/bash
|
||||
HOMEBREW_PREFIX="$(cd "$(dirname "$0")"/../ && pwd)"
|
||||
if [[ -n "${BASH_SOURCE[0]}" ]]; then
|
||||
SCRIPT_PATH="${BASH_SOURCE[0]}"
|
||||
elif [[ -n "${ZSH_VERSION}" ]]; then
|
||||
SCRIPT_PATH="${(%):-%x}"
|
||||
else
|
||||
SCRIPT_PATH="$0"
|
||||
fi
|
||||
HOMEBREW_PREFIX="$(cd "$(dirname "${SCRIPT_PATH}")"/../ && pwd)"
|
||||
|
||||
"${HOMEBREW_PREFIX}/bin/brew" install-bundler-gems --add-groups=style,typecheck,vscode >/dev/null 2>&1
|
||||
|
||||
|
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -40,7 +40,6 @@
|
||||
"id": "default",
|
||||
"name": "Brew Typecheck",
|
||||
"description": "Default configuration",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"command": [
|
||||
"./bin/brew",
|
||||
"typecheck",
|
||||
|
11
CODEOWNERS
Normal file
11
CODEOWNERS
Normal file
@ -0,0 +1,11 @@
|
||||
# Note that the naming of this file is incorrect for our case: these people do not "own" the provided files but are
|
||||
# people with write-access to this repository who wish to approve changes to these files.
|
||||
#
|
||||
# Their review is required to merge PRs that change these files.
|
||||
#
|
||||
# To be explicit: we will never accept changes to this file adding people from outside the Homebrew GitHub
|
||||
# organisation. If you are not a Homebrew maintainer: you do not personally "own" or "maintain" any files.
|
||||
#
|
||||
# Note: @Homebrew/plc does not have write-access to this repository, and therefore cannot be listed in this file.
|
||||
|
||||
docs/Support-Tiers.md @Homebrew/tsc @MikeMcQuaid
|
@ -304,7 +304,7 @@ Sorbet/StrictSigil:
|
||||
- "Homebrew/utils/ruby_check_version_script.rb" # A standalone script.
|
||||
- "Homebrew/{standalone,startup}/*.rb" # These are loaded before sorbet-runtime
|
||||
- "Homebrew/test/**/*.rb"
|
||||
- "Homebrew/bundle/{brew_dumper,checker,commands/exec}.rb" # These aren't typed: true yet.
|
||||
- "Homebrew/bundle/{formula_dumper,checker,commands/exec}.rb" # These aren't typed: true yet.
|
||||
|
||||
Sorbet/TrueSigil:
|
||||
Enabled: true
|
||||
|
@ -25,6 +25,7 @@ Style/Documentation:
|
||||
- Homebrew
|
||||
Include:
|
||||
- abstract_command.rb
|
||||
- autobump_constants.rb
|
||||
- cask/cask.rb
|
||||
- cask/dsl.rb
|
||||
- cask/dsl/version.rb
|
||||
|
@ -39,12 +39,12 @@ class PATH
|
||||
self
|
||||
end
|
||||
|
||||
sig { params(block: T.proc.params(arg0: String).returns(T::Boolean)).returns(T.self_type) }
|
||||
sig { params(block: T.proc.params(arg0: String).returns(BasicObject)).returns(T.self_type) }
|
||||
def select(&block)
|
||||
self.class.new(@paths.select(&block))
|
||||
end
|
||||
|
||||
sig { params(block: T.proc.params(arg0: String).returns(T::Boolean)).returns(T.self_type) }
|
||||
sig { params(block: T.proc.params(arg0: String).returns(BasicObject)).returns(T.self_type) }
|
||||
def reject(&block)
|
||||
self.class.new(@paths.reject(&block))
|
||||
end
|
||||
|
@ -29,36 +29,36 @@ module Homebrew
|
||||
Alias.new(name).remove
|
||||
end
|
||||
|
||||
sig { params(only: T::Array[String], block: T.proc.params(target: String, cmd: String).void).void }
|
||||
sig { params(only: T::Array[String], block: T.proc.params(name: String, command: String).void).void }
|
||||
def self.each(only, &block)
|
||||
Dir["#{HOMEBREW_ALIASES}/*"].each do |path|
|
||||
next if path.end_with? "~" # skip Emacs-like backup files
|
||||
next if File.directory?(path)
|
||||
|
||||
_shebang, _meta, *lines = File.readlines(path)
|
||||
target = File.basename(path)
|
||||
next if !only.empty? && only.exclude?(target)
|
||||
_shebang, meta, *lines = File.readlines(path)
|
||||
name = T.must(meta)[/alias: brew (\S+)/, 1] || File.basename(path)
|
||||
next if !only.empty? && only.exclude?(name)
|
||||
|
||||
lines.reject! { |line| line.start_with?("#") || line =~ /^\s*$/ }
|
||||
first_line = T.must(lines.first)
|
||||
cmd = first_line.chomp
|
||||
cmd.sub!(/ \$\*$/, "")
|
||||
command = first_line.chomp
|
||||
command.sub!(/ \$\*$/, "")
|
||||
|
||||
if cmd.start_with? "brew "
|
||||
cmd.sub!(/^brew /, "")
|
||||
if command.start_with? "brew "
|
||||
command.sub!(/^brew /, "")
|
||||
else
|
||||
cmd = "!#{cmd}"
|
||||
command = "!#{command}"
|
||||
end
|
||||
|
||||
yield target, cmd if block.present?
|
||||
yield name, command if block.present?
|
||||
end
|
||||
end
|
||||
|
||||
sig { params(aliases: String).void }
|
||||
def self.show(*aliases)
|
||||
each([*aliases]) do |target, cmd|
|
||||
puts "brew alias #{target}='#{cmd}'"
|
||||
existing_alias = Alias.new(target, cmd)
|
||||
each([*aliases]) do |name, command|
|
||||
puts "brew alias #{name}='#{command}'"
|
||||
existing_alias = Alias.new(name, command)
|
||||
existing_alias.link unless existing_alias.symlink.exist?
|
||||
end
|
||||
end
|
||||
|
@ -1,4 +1,4 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "api/analytics"
|
||||
@ -11,10 +11,10 @@ module Homebrew
|
||||
module API
|
||||
extend Cachable
|
||||
|
||||
HOMEBREW_CACHE_API = (HOMEBREW_CACHE/"api").freeze
|
||||
HOMEBREW_CACHE_API_SOURCE = (HOMEBREW_CACHE/"api-source").freeze
|
||||
HOMEBREW_CACHE_API = T.let((HOMEBREW_CACHE/"api").freeze, Pathname)
|
||||
HOMEBREW_CACHE_API_SOURCE = T.let((HOMEBREW_CACHE/"api-source").freeze, Pathname)
|
||||
|
||||
sig { params(endpoint: String).returns(Hash) }
|
||||
sig { params(endpoint: String).returns(T::Hash[String, T.untyped]) }
|
||||
def self.fetch(endpoint)
|
||||
return cache[endpoint] if cache.present? && cache.key?(endpoint)
|
||||
|
||||
@ -33,7 +33,8 @@ module Homebrew
|
||||
end
|
||||
|
||||
sig {
|
||||
params(endpoint: String, target: Pathname, stale_seconds: Integer).returns([T.any(Array, Hash), T::Boolean])
|
||||
params(endpoint: String, target: Pathname,
|
||||
stale_seconds: Integer).returns([T.any(T::Array[T.untyped], T::Hash[String, T.untyped]), T::Boolean])
|
||||
}
|
||||
def self.fetch_json_api_file(endpoint, target: HOMEBREW_CACHE_API/endpoint,
|
||||
stale_seconds: Homebrew::EnvConfig.api_auto_update_secs.to_i)
|
||||
@ -96,7 +97,8 @@ module Homebrew
|
||||
|
||||
mtime = insecure_download ? Time.new(1970, 1, 1) : Time.now
|
||||
FileUtils.touch(target, mtime:) unless skip_download
|
||||
JSON.parse(target.read(encoding: Encoding::UTF_8), freeze: true)
|
||||
# Can use `target.read` again when/if https://github.com/sorbet/sorbet/pull/8999 is merged/released.
|
||||
JSON.parse(File.read(target, encoding: Encoding::UTF_8), freeze: true)
|
||||
rescue JSON::ParserError
|
||||
target.unlink
|
||||
retry_count += 1
|
||||
@ -122,14 +124,17 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
sig { params(json: Hash).returns(Hash) }
|
||||
def self.merge_variations(json)
|
||||
sig {
|
||||
params(json: T::Hash[String, T.untyped],
|
||||
bottle_tag: ::Utils::Bottles::Tag).returns(T::Hash[String, T.untyped])
|
||||
}
|
||||
def self.merge_variations(json, bottle_tag: T.unsafe(nil))
|
||||
return json unless json.key?("variations")
|
||||
|
||||
bottle_tag = ::Utils::Bottles::Tag.new(system: Homebrew::SimulateSystem.current_os,
|
||||
arch: Homebrew::SimulateSystem.current_arch)
|
||||
bottle_tag ||= Homebrew::SimulateSystem.current_tag
|
||||
|
||||
if (variation = json.dig("variations", bottle_tag.to_s).presence)
|
||||
if (variation = json.dig("variations", bottle_tag.to_s).presence) ||
|
||||
(variation = json.dig("variations", bottle_tag.to_sym).presence)
|
||||
json = json.merge(variation)
|
||||
end
|
||||
|
||||
@ -147,7 +152,10 @@ module Homebrew
|
||||
false
|
||||
end
|
||||
|
||||
sig { params(json_data: Hash).returns([T::Boolean, T.any(String, Array, Hash)]) }
|
||||
sig {
|
||||
params(json_data: T::Hash[String, T.untyped])
|
||||
.returns([T::Boolean, T.any(String, T::Array[T.untyped], T::Hash[String, T.untyped])])
|
||||
}
|
||||
private_class_method def self.verify_and_parse_jws(json_data)
|
||||
signatures = json_data["signatures"]
|
||||
homebrew_signature = signatures&.find { |sig| sig.dig("header", "kid") == "homebrew-1" }
|
||||
|
@ -10,7 +10,6 @@ module Homebrew
|
||||
def analytics_api_path
|
||||
"analytics"
|
||||
end
|
||||
alias generic_analytics_api_path analytics_api_path
|
||||
|
||||
sig { params(category: String, days: T.any(Integer, String)).returns(T::Hash[String, T.untyped]) }
|
||||
def fetch(category, days)
|
||||
|
@ -1,7 +1,7 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "extend/cachable"
|
||||
require "cachable"
|
||||
require "api/download"
|
||||
|
||||
module Homebrew
|
||||
@ -12,9 +12,16 @@ module Homebrew
|
||||
|
||||
DEFAULT_API_FILENAME = "cask.jws.json"
|
||||
|
||||
sig { returns(String) }
|
||||
def self.api_filename
|
||||
return DEFAULT_API_FILENAME unless ENV.fetch("HOMEBREW_USE_INTERNAL_API", false)
|
||||
|
||||
"cask.#{SimulateSystem.current_tag}.jws.json"
|
||||
end
|
||||
|
||||
private_class_method :cache
|
||||
|
||||
sig { params(token: String).returns(Hash) }
|
||||
sig { params(token: String).returns(T::Hash[String, T.untyped]) }
|
||||
def self.fetch(token)
|
||||
Homebrew::API.fetch "cask/#{token}.json"
|
||||
end
|
||||
@ -40,13 +47,14 @@ module Homebrew
|
||||
.load(config: cask.config)
|
||||
end
|
||||
|
||||
sig { returns(Pathname) }
|
||||
def self.cached_json_file_path
|
||||
HOMEBREW_CACHE_API/DEFAULT_API_FILENAME
|
||||
HOMEBREW_CACHE_API/api_filename
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def self.download_and_cache_data!
|
||||
json_casks, updated = Homebrew::API.fetch_json_api_file DEFAULT_API_FILENAME
|
||||
json_casks, updated = Homebrew::API.fetch_json_api_file api_filename
|
||||
|
||||
cache["renames"] = {}
|
||||
cache["casks"] = json_casks.to_h do |json_cask|
|
||||
@ -63,7 +71,7 @@ module Homebrew
|
||||
end
|
||||
private_class_method :download_and_cache_data!
|
||||
|
||||
sig { returns(T::Hash[String, Hash]) }
|
||||
sig { returns(T::Hash[String, T::Hash[String, T.untyped]]) }
|
||||
def self.all_casks
|
||||
unless cache.key?("casks")
|
||||
json_updated = download_and_cache_data!
|
||||
|
@ -1,7 +1,7 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "extend/cachable"
|
||||
require "cachable"
|
||||
require "api/download"
|
||||
|
||||
module Homebrew
|
||||
@ -12,6 +12,13 @@ module Homebrew
|
||||
|
||||
DEFAULT_API_FILENAME = "formula.jws.json"
|
||||
|
||||
sig { returns(String) }
|
||||
def self.api_filename
|
||||
return DEFAULT_API_FILENAME unless ENV.fetch("HOMEBREW_USE_INTERNAL_API", false)
|
||||
|
||||
"internal/formula.#{SimulateSystem.current_tag}.jws.json"
|
||||
end
|
||||
|
||||
private_class_method :cache
|
||||
|
||||
sig { params(name: String).returns(T::Hash[String, T.untyped]) }
|
||||
@ -42,12 +49,12 @@ module Homebrew
|
||||
|
||||
sig { returns(Pathname) }
|
||||
def self.cached_json_file_path
|
||||
HOMEBREW_CACHE_API/DEFAULT_API_FILENAME
|
||||
HOMEBREW_CACHE_API/api_filename
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def self.download_and_cache_data!
|
||||
json_formulae, updated = Homebrew::API.fetch_json_api_file DEFAULT_API_FILENAME
|
||||
json_formulae, updated = Homebrew::API.fetch_json_api_file api_filename
|
||||
|
||||
cache["aliases"] = {}
|
||||
cache["renames"] = {}
|
||||
|
@ -1,22 +1,26 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Used to substitute common paths with generic placeholders when generating JSON for the API.
|
||||
module APIHashable
|
||||
sig { void }
|
||||
def generating_hash!
|
||||
return if generating_hash?
|
||||
|
||||
# Apply monkeypatches for API generation
|
||||
@old_homebrew_prefix = HOMEBREW_PREFIX
|
||||
@old_homebrew_cellar = HOMEBREW_CELLAR
|
||||
@old_home = Dir.home
|
||||
@old_homebrew_prefix = T.let(HOMEBREW_PREFIX, T.nilable(Pathname))
|
||||
@old_homebrew_cellar = T.let(HOMEBREW_CELLAR, T.nilable(Pathname))
|
||||
@old_home = T.let(Dir.home, T.nilable(String))
|
||||
@old_git_config_global = T.let(ENV.fetch("GIT_CONFIG_GLOBAL", nil), T.nilable(String))
|
||||
Object.send(:remove_const, :HOMEBREW_PREFIX)
|
||||
Object.const_set(:HOMEBREW_PREFIX, Pathname.new(HOMEBREW_PREFIX_PLACEHOLDER))
|
||||
ENV["HOME"] = HOMEBREW_HOME_PLACEHOLDER
|
||||
ENV["GIT_CONFIG_GLOBAL"] = File.join(@old_home, ".gitconfig")
|
||||
|
||||
@generating_hash = true
|
||||
@generating_hash = T.let(true, T.nilable(T::Boolean))
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def generated_hash!
|
||||
return unless generating_hash?
|
||||
|
||||
@ -24,10 +28,12 @@ module APIHashable
|
||||
Object.send(:remove_const, :HOMEBREW_PREFIX)
|
||||
Object.const_set(:HOMEBREW_PREFIX, @old_homebrew_prefix)
|
||||
ENV["HOME"] = @old_home
|
||||
ENV["GIT_CONFIG_GLOBAL"] = @old_git_config_global
|
||||
|
||||
@generating_hash = false
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def generating_hash?
|
||||
@generating_hash ||= false
|
||||
@generating_hash == true
|
@ -52,4 +52,4 @@ FORMULA_COMPONENT_PRECEDENCE_LIST = T.let([
|
||||
[{ name: :caveats, type: :method_definition }],
|
||||
[{ name: :plist_options, type: :method_call }, { name: :plist, type: :method_definition }],
|
||||
[{ name: :test, type: :block_call }],
|
||||
].freeze, T::Array[[{ name: Symbol, type: Symbol }]])
|
||||
].freeze, T::Array[T::Array[{ name: Symbol, type: Symbol }]])
|
||||
|
@ -64,12 +64,8 @@ module Homebrew
|
||||
sig { returns(T::Boolean) }
|
||||
def self.enabled?
|
||||
return false if Homebrew::EnvConfig.no_verify_attestations?
|
||||
return true if Homebrew::EnvConfig.verify_attestations?
|
||||
return false if ENV.fetch("CI", false)
|
||||
return false if OS.not_tier_one_configuration?
|
||||
|
||||
# Always check credentials last to avoid unnecessary credential extraction.
|
||||
(Homebrew::EnvConfig.developer? || Homebrew::EnvConfig.devcmdrun?) && GitHub::API.credentials.present?
|
||||
Homebrew::EnvConfig.verify_attestations?
|
||||
end
|
||||
|
||||
# Returns a path to a suitable `gh` executable for attestation verification.
|
||||
|
@ -1,10 +1,15 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
# TODO: add more reasons here
|
||||
NO_AUTOBUMP_REASONS_INTERNAL = T.let({
|
||||
extract_plist: "livecheck uses `:extract_plist` strategy",
|
||||
latest_version: "`version` is set to `:latest`",
|
||||
}.freeze, T::Hash[Symbol, String])
|
||||
|
||||
# The valid symbols for passing to `no_autobump!` in a `Formula` or `Cask`.
|
||||
# @api public
|
||||
NO_AUTOBUMP_REASONS_LIST = T.let({
|
||||
incompatible_version_format: "incompatible version format",
|
||||
bumped_by_upstream: "bumped by upstream",
|
||||
extract_plist: "livecheck uses `:extract_plist` strategy",
|
||||
latest_version: "`version` is set to `:latest`",
|
||||
}.freeze, T::Hash[Symbol, String])
|
||||
requires_manual_review: "a manual review of this package is required for inclusion in autobump",
|
||||
}.merge(NO_AUTOBUMP_REASONS_INTERNAL).freeze, T::Hash[Symbol, String])
|
||||
|
@ -531,9 +531,9 @@ GIT_REVISION=$("${HOMEBREW_GIT}" -C "${HOMEBREW_REPOSITORY}" rev-parse HEAD 2>/d
|
||||
if [[ -z "${GIT_REVISION}" ]]
|
||||
then
|
||||
read -r GIT_HEAD 2>/dev/null <"${HOMEBREW_REPOSITORY}/.git/HEAD"
|
||||
if [[ "${GIT_HEAD}" == "ref: refs/heads/master" ]]
|
||||
if [[ "${GIT_HEAD}" == "ref: refs/heads/main" ]]
|
||||
then
|
||||
read -r GIT_REVISION 2>/dev/null <"${HOMEBREW_REPOSITORY}/.git/refs/heads/master"
|
||||
read -r GIT_REVISION 2>/dev/null <"${HOMEBREW_REPOSITORY}/.git/refs/heads/main"
|
||||
elif [[ "${GIT_HEAD}" == "ref: refs/heads/stable" ]]
|
||||
then
|
||||
read -r GIT_REVISION 2>/dev/null <"${HOMEBREW_REPOSITORY}/.git/refs/heads/stable"
|
||||
@ -600,6 +600,11 @@ case "$1" in
|
||||
homebrew-version
|
||||
exit 0
|
||||
;;
|
||||
mcp-server)
|
||||
source "${HOMEBREW_LIBRARY}/Homebrew/cmd/mcp-server.sh"
|
||||
homebrew-mcp-server "$@"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
# TODO: bump version when new macOS is released or announced and update references in:
|
||||
@ -609,6 +614,8 @@ esac
|
||||
# and, if needed:
|
||||
# - MacOSVersion::SYMBOLS
|
||||
HOMEBREW_MACOS_NEWEST_UNSUPPORTED="16"
|
||||
# TODO: bump version when new macOS is released
|
||||
HOMEBREW_MACOS_NEWEST_SUPPORTED="15"
|
||||
# TODO: bump version when new macOS is released and update references in:
|
||||
# - docs/Installation.md
|
||||
# - HOMEBREW_MACOS_OLDEST_SUPPORTED in .github/workflows/pkg-installer.yml
|
||||
@ -836,6 +843,7 @@ export HOMEBREW_OS_VERSION
|
||||
export HOMEBREW_MACOS_VERSION
|
||||
export HOMEBREW_MACOS_VERSION_NUMERIC
|
||||
export HOMEBREW_MACOS_NEWEST_UNSUPPORTED
|
||||
export HOMEBREW_MACOS_NEWEST_SUPPORTED
|
||||
export HOMEBREW_MACOS_OLDEST_SUPPORTED
|
||||
export HOMEBREW_MACOS_OLDEST_ALLOWED
|
||||
export HOMEBREW_USER_AGENT
|
||||
@ -1078,6 +1086,22 @@ else
|
||||
export HOMEBREW_GITHUB_PACKAGES_AUTH="Bearer QQ=="
|
||||
fi
|
||||
|
||||
# Avoid picking up any random `sudo` in `PATH`.
|
||||
if [[ -x /usr/bin/sudo ]]
|
||||
then
|
||||
SUDO=/usr/bin/sudo
|
||||
else
|
||||
# Do this after ensuring we're using default Bash builtins.
|
||||
SUDO="$(command -v sudo 2>/dev/null)"
|
||||
fi
|
||||
|
||||
# Reset sudo timestamp to avoid running unauthorized sudo commands
|
||||
if [[ -n "${SUDO}" ]]
|
||||
then
|
||||
"${SUDO}" --reset-timestamp 2>/dev/null || true
|
||||
fi
|
||||
unset SUDO
|
||||
|
||||
if [[ -n "${HOMEBREW_BASH_COMMAND}" ]]
|
||||
then
|
||||
# source rather than executing directly to ensure the entire file is read into
|
||||
|
@ -130,6 +130,9 @@ module Homebrew
|
||||
@formula_versions_from_env[formula_env_name]
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def prepend_pkgconf_path_if_needed!; end
|
||||
|
||||
sig { void }
|
||||
def reset!
|
||||
@mas_installed = T.let(nil, T.nilable(T::Boolean))
|
||||
|
@ -1,7 +1,7 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "bundle/brew_installer"
|
||||
require "bundle/formula_installer"
|
||||
|
||||
module Homebrew
|
||||
module Bundle
|
||||
@ -11,7 +11,7 @@ module Homebrew
|
||||
PACKAGE_TYPE_NAME = "Formula"
|
||||
|
||||
def installed_and_up_to_date?(formula, no_upgrade: false)
|
||||
Homebrew::Bundle::BrewInstaller.formula_installed_and_up_to_date?(formula, no_upgrade:)
|
||||
Homebrew::Bundle::FormulaInstaller.formula_installed_and_up_to_date?(formula, no_upgrade:)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -24,8 +24,8 @@ module Homebrew
|
||||
end
|
||||
|
||||
def entry_to_formula(entry)
|
||||
require "bundle/brew_installer"
|
||||
Homebrew::Bundle::BrewInstaller.new(entry.name, entry.options)
|
||||
require "bundle/formula_installer"
|
||||
Homebrew::Bundle::FormulaInstaller.new(entry.name, entry.options)
|
||||
end
|
||||
|
||||
def formula_needs_to_start?(formula)
|
||||
@ -38,8 +38,8 @@ module Homebrew
|
||||
end
|
||||
|
||||
def lookup_old_name(service_name)
|
||||
require "bundle/brew_dumper"
|
||||
@old_names ||= Homebrew::Bundle::BrewDumper.formula_oldnames
|
||||
require "bundle/formula_dumper"
|
||||
@old_names ||= Homebrew::Bundle::FormulaDumper.formula_oldnames
|
||||
old_name = @old_names[service_name]
|
||||
old_name ||= @old_names[service_name.split("/").last]
|
||||
old_name
|
||||
|
@ -8,6 +8,7 @@ module Homebrew
|
||||
@casks = nil
|
||||
@cask_names = nil
|
||||
@cask_hash = nil
|
||||
@cask_oldnames = nil
|
||||
end
|
||||
|
||||
def self.cask_names
|
||||
@ -38,6 +39,25 @@ module Homebrew
|
||||
end.join("\n")
|
||||
end
|
||||
|
||||
def self.cask_oldnames
|
||||
return @cask_oldnames if @cask_oldnames
|
||||
|
||||
@cask_oldnames = {}
|
||||
casks.each do |c|
|
||||
oldnames = c.old_tokens
|
||||
next if oldnames.blank?
|
||||
|
||||
oldnames.each do |oldname|
|
||||
@cask_oldnames[oldname] = c.full_name
|
||||
if c.full_name.include? "/" # tap cask
|
||||
tap_name = c.full_name.rpartition("/").first
|
||||
@cask_oldnames["#{tap_name}/#{oldname}"] = c.full_name
|
||||
end
|
||||
end
|
||||
end
|
||||
@cask_oldnames
|
||||
end
|
||||
|
||||
def self.formula_dependencies(cask_list)
|
||||
return [] unless Bundle.cask_installed?
|
||||
return [] if cask_list.blank?
|
||||
|
@ -87,12 +87,25 @@ module Homebrew
|
||||
!cask_upgradable?(cask)
|
||||
end
|
||||
|
||||
def self.cask_in_array?(cask, array)
|
||||
return true if array.include?(cask)
|
||||
return true if array.include?(cask.split("/").last)
|
||||
|
||||
require "bundle/cask_dumper"
|
||||
old_names = Homebrew::Bundle::CaskDumper.cask_oldnames
|
||||
old_name = old_names[cask]
|
||||
old_name ||= old_names[cask.split("/").last]
|
||||
return true if old_name && array.include?(old_name)
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
def self.cask_installed?(cask)
|
||||
installed_casks.include? cask
|
||||
cask_in_array?(cask, installed_casks)
|
||||
end
|
||||
|
||||
def self.cask_upgradable?(cask)
|
||||
outdated_casks.include? cask
|
||||
cask_in_array?(cask, outdated_casks)
|
||||
end
|
||||
|
||||
def self.installed_casks
|
||||
|
@ -1,4 +1,4 @@
|
||||
# typed: false # rubocop:todo Sorbet/TrueSigil
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Homebrew
|
||||
@ -23,7 +23,7 @@ module Homebrew
|
||||
else
|
||||
"needs to be installed or updated."
|
||||
end
|
||||
"#{self.class::PACKAGE_TYPE_NAME} #{name} #{reason}"
|
||||
"#{self.class.const_get(:PACKAGE_TYPE_NAME)} #{name} #{reason}"
|
||||
end
|
||||
|
||||
def full_check(packages, no_upgrade:)
|
||||
@ -33,7 +33,7 @@ module Homebrew
|
||||
|
||||
def checkable_entries(all_entries)
|
||||
require "bundle/skipper"
|
||||
all_entries.select { |e| e.type == self.class::PACKAGE_TYPE }
|
||||
all_entries.select { |e| e.type == self.class.const_get(:PACKAGE_TYPE) }
|
||||
.reject(&Bundle::Skipper.method(:skip?))
|
||||
end
|
||||
|
||||
@ -139,14 +139,14 @@ module Homebrew
|
||||
|
||||
def self.reset!
|
||||
require "bundle/cask_dumper"
|
||||
require "bundle/brew_dumper"
|
||||
require "bundle/formula_dumper"
|
||||
require "bundle/mac_app_store_dumper"
|
||||
require "bundle/tap_dumper"
|
||||
require "bundle/brew_services"
|
||||
|
||||
@dsl = nil
|
||||
Homebrew::Bundle::CaskDumper.reset!
|
||||
Homebrew::Bundle::BrewDumper.reset!
|
||||
Homebrew::Bundle::FormulaDumper.reset!
|
||||
Homebrew::Bundle::MacAppStoreDumper.reset!
|
||||
Homebrew::Bundle::TapDumper.reset!
|
||||
Homebrew::Bundle::BrewServices.reset!
|
||||
|
@ -1,4 +1,4 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "bundle/adder"
|
||||
@ -7,6 +7,7 @@ module Homebrew
|
||||
module Bundle
|
||||
module Commands
|
||||
module Add
|
||||
sig { params(args: String, type: Symbol, global: T::Boolean, file: T.nilable(String)).void }
|
||||
def self.run(*args, type:, global:, file:)
|
||||
Homebrew::Bundle::Adder.add(*args, type:, global:, file:)
|
||||
end
|
||||
|
@ -10,7 +10,7 @@ module Homebrew
|
||||
module Cleanup
|
||||
def self.reset!
|
||||
require "bundle/cask_dumper"
|
||||
require "bundle/brew_dumper"
|
||||
require "bundle/formula_dumper"
|
||||
require "bundle/tap_dumper"
|
||||
require "bundle/vscode_extension_dumper"
|
||||
require "bundle/brew_services"
|
||||
@ -19,18 +19,18 @@ module Homebrew
|
||||
@kept_casks = nil
|
||||
@kept_formulae = nil
|
||||
Homebrew::Bundle::CaskDumper.reset!
|
||||
Homebrew::Bundle::BrewDumper.reset!
|
||||
Homebrew::Bundle::FormulaDumper.reset!
|
||||
Homebrew::Bundle::TapDumper.reset!
|
||||
Homebrew::Bundle::VscodeExtensionDumper.reset!
|
||||
Homebrew::Bundle::BrewServices.reset!
|
||||
end
|
||||
|
||||
def self.run(global: false, file: nil, force: false, zap: false, dsl: nil,
|
||||
brews: true, casks: true, taps: true, vscode: true)
|
||||
formulae: true, casks: true, taps: true, vscode: true)
|
||||
@dsl ||= dsl
|
||||
|
||||
casks = casks ? casks_to_uninstall(global:, file:) : []
|
||||
formulae = brews ? formulae_to_uninstall(global:, file:) : []
|
||||
formulae = formulae ? formulae_to_uninstall(global:, file:) : []
|
||||
taps = taps ? taps_to_untap(global:, file:) : []
|
||||
vscode_extensions = vscode ? vscode_extensions_to_uninstall(global:, file:) : []
|
||||
if force
|
||||
@ -101,11 +101,11 @@ module Homebrew
|
||||
def self.formulae_to_uninstall(global: false, file: nil)
|
||||
kept_formulae = self.kept_formulae(global:, file:)
|
||||
|
||||
require "bundle/brew_dumper"
|
||||
require "bundle/brew_installer"
|
||||
current_formulae = Homebrew::Bundle::BrewDumper.formulae
|
||||
require "bundle/formula_dumper"
|
||||
require "bundle/formula_installer"
|
||||
current_formulae = Homebrew::Bundle::FormulaDumper.formulae
|
||||
current_formulae.reject! do |f|
|
||||
Homebrew::Bundle::BrewInstaller.formula_in_array?(f[:full_name], kept_formulae)
|
||||
Homebrew::Bundle::FormulaInstaller.formula_in_array?(f[:full_name], kept_formulae)
|
||||
end
|
||||
|
||||
# Don't try to uninstall formulae with keepme references
|
||||
@ -119,7 +119,7 @@ module Homebrew
|
||||
|
||||
private_class_method def self.kept_formulae(global: false, file: nil)
|
||||
require "bundle/brewfile"
|
||||
require "bundle/brew_dumper"
|
||||
require "bundle/formula_dumper"
|
||||
require "bundle/cask_dumper"
|
||||
|
||||
@kept_formulae ||= begin
|
||||
@ -128,12 +128,13 @@ module Homebrew
|
||||
kept_formulae = @dsl.entries.select { |e| e.type == :brew }.map(&:name)
|
||||
kept_formulae += Homebrew::Bundle::CaskDumper.formula_dependencies(kept_casks)
|
||||
kept_formulae.map! do |f|
|
||||
Homebrew::Bundle::BrewDumper.formula_aliases[f] ||
|
||||
Homebrew::Bundle::BrewDumper.formula_oldnames[f] ||
|
||||
f
|
||||
Homebrew::Bundle::FormulaDumper.formula_aliases.fetch(
|
||||
f,
|
||||
Homebrew::Bundle::FormulaDumper.formula_oldnames.fetch(f, f),
|
||||
)
|
||||
end
|
||||
|
||||
kept_formulae + recursive_dependencies(Homebrew::Bundle::BrewDumper.formulae, kept_formulae)
|
||||
kept_formulae + recursive_dependencies(Homebrew::Bundle::FormulaDumper.formulae, kept_formulae)
|
||||
end
|
||||
end
|
||||
|
||||
@ -142,7 +143,11 @@ module Homebrew
|
||||
return @kept_casks if @kept_casks
|
||||
|
||||
@dsl ||= Brewfile.read(global:, file:)
|
||||
@kept_casks = @dsl.entries.select { |e| e.type == :cask }.map(&:name)
|
||||
kept_casks = @dsl.entries.select { |e| e.type == :cask }.flat_map(&:name)
|
||||
kept_casks.map! do |c|
|
||||
Homebrew::Bundle::CaskDumper.cask_oldnames.fetch(c, c)
|
||||
end
|
||||
@kept_casks = kept_casks
|
||||
end
|
||||
|
||||
private_class_method def self.recursive_dependencies(current_formulae, formulae_names, top_level: true)
|
||||
|
@ -7,9 +7,10 @@ module Homebrew
|
||||
module Bundle
|
||||
module Commands
|
||||
module Dump
|
||||
def self.run(global:, file:, describe:, force:, no_restart:, taps:, brews:, casks:, mas:, whalebrew:, vscode:)
|
||||
def self.run(global:, file:, describe:, force:, no_restart:, taps:, formulae:, casks:, mas:, whalebrew:,
|
||||
vscode:)
|
||||
Homebrew::Bundle::Dumper.dump_brewfile(
|
||||
global:, file:, describe:, force:, no_restart:, taps:, brews:, casks:, mas:, whalebrew:, vscode:,
|
||||
global:, file:, describe:, force:, no_restart:, taps:, formulae:, casks:, mas:, whalebrew:, vscode:,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
@ -1,4 +1,4 @@
|
||||
# typed: false # rubocop:todo Sorbet/TrueSigil
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "English"
|
||||
@ -13,6 +13,16 @@ module Homebrew
|
||||
module Exec
|
||||
PATH_LIKE_ENV_REGEX = /.+#{File::PATH_SEPARATOR}/
|
||||
|
||||
sig {
|
||||
params(
|
||||
args: String,
|
||||
global: T::Boolean,
|
||||
file: T.nilable(String),
|
||||
subcommand: String,
|
||||
services: T::Boolean,
|
||||
check: T::Boolean,
|
||||
).void
|
||||
}
|
||||
def self.run(*args, global: false, file: nil, subcommand: "", services: false, check: false)
|
||||
if check
|
||||
require "bundle/commands/check"
|
||||
@ -25,9 +35,9 @@ module Homebrew
|
||||
|
||||
# Setup Homebrew's ENV extensions
|
||||
ENV.activate_extensions!
|
||||
raise UsageError, "No command to execute was specified!" if args.blank?
|
||||
|
||||
command = args.first
|
||||
raise UsageError, "No command to execute was specified!" if command.blank?
|
||||
|
||||
require "bundle/brewfile"
|
||||
@dsl = Brewfile.read(global:, file:)
|
||||
@ -64,14 +74,8 @@ module Homebrew
|
||||
ENV.prepend_path "PATH", Pathname.new(dep_root)/"shims"
|
||||
end
|
||||
|
||||
# Setup pkg-config, if present, to help locate packages
|
||||
# Only need this on Linux as Homebrew provides a shim on macOS
|
||||
# TODO: use extend/OS here
|
||||
# rubocop:todo Homebrew/MoveToExtendOS
|
||||
if OS.linux? && (pkgconf = Formulary.factory("pkgconf")) && pkgconf.any_version_installed?
|
||||
ENV.prepend_path "PATH", pkgconf.opt_bin.to_s
|
||||
end
|
||||
# rubocop:enable Homebrew/MoveToExtendOS
|
||||
# Setup pkgconf, if needed, to help locate packages
|
||||
Bundle.prepend_pkgconf_path_if_needed!
|
||||
|
||||
# For commands which aren't either absolute or relative
|
||||
# Add the command directory to PATH, since it may get blown away by superenv
|
||||
@ -170,12 +174,24 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
return
|
||||
elsif subcommand == "sh"
|
||||
preferred_path = Utils::Shell.preferred_path(default: "/bin/bash")
|
||||
notice = unless Homebrew::EnvConfig.no_env_hints?
|
||||
<<~EOS
|
||||
Your shell has been configured to use a build environment from your `Brewfile`.
|
||||
This should help you build stuff.
|
||||
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
|
||||
When done, type `exit`.
|
||||
EOS
|
||||
end
|
||||
ENV["HOMEBREW_FORCE_API_AUTO_UPDATE"] = nil
|
||||
args = [Utils::Shell.shell_with_prompt("brew bundle", preferred_path:, notice:)]
|
||||
end
|
||||
|
||||
if services
|
||||
require "bundle/brew_services"
|
||||
|
||||
exit_code = 0
|
||||
exit_code = T.let(0, Integer)
|
||||
run_services(@dsl.entries) do
|
||||
Kernel.system(*args)
|
||||
if (system_exit_code = $CHILD_STATUS&.exitstatus)
|
||||
@ -193,7 +209,7 @@ module Homebrew
|
||||
entries: T::Array[Homebrew::Bundle::Dsl::Entry],
|
||||
_block: T.proc.params(
|
||||
entry: Homebrew::Bundle::Dsl::Entry,
|
||||
info: T::Hash[String, T.anything],
|
||||
info: T::Hash[String, T.untyped],
|
||||
service_file: Pathname,
|
||||
conflicting_services: T::Array[T::Hash[String, T.anything]],
|
||||
).void,
|
||||
@ -273,7 +289,7 @@ module Homebrew
|
||||
map_service_info(entries) do |entry, info, service_file, conflicting_services|
|
||||
# Don't restart if already running this version
|
||||
loaded_file = Pathname.new(info["loaded_file"].to_s)
|
||||
next if info["running"] && loaded_file&.file? && loaded_file&.realpath == service_file.realpath
|
||||
next if info["running"] && loaded_file.file? && loaded_file.realpath == service_file.realpath
|
||||
|
||||
if info["running"] && !Bundle::BrewServices.stop(info["name"], keep: true)
|
||||
opoo "Failed to stop #{info["name"]} service"
|
||||
|
@ -8,11 +8,11 @@ module Homebrew
|
||||
module Bundle
|
||||
module Commands
|
||||
module List
|
||||
def self.run(global:, file:, brews:, casks:, taps:, mas:, whalebrew:, vscode:)
|
||||
def self.run(global:, file:, formulae:, casks:, taps:, mas:, whalebrew:, vscode:)
|
||||
parsed_entries = Brewfile.read(global:, file:).entries
|
||||
Homebrew::Bundle::Lister.list(
|
||||
parsed_entries,
|
||||
brews:, casks:, taps:, mas:, whalebrew:, vscode:,
|
||||
formulae:, casks:, taps:, mas:, whalebrew:, vscode:,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
@ -13,9 +13,9 @@ module Homebrew
|
||||
true
|
||||
end
|
||||
|
||||
def self.build_brewfile(describe:, no_restart:, brews:, taps:, casks:, mas:, whalebrew:, vscode:)
|
||||
def self.build_brewfile(describe:, no_restart:, formulae:, taps:, casks:, mas:, whalebrew:, vscode:)
|
||||
require "bundle/tap_dumper"
|
||||
require "bundle/brew_dumper"
|
||||
require "bundle/formula_dumper"
|
||||
require "bundle/cask_dumper"
|
||||
require "bundle/mac_app_store_dumper"
|
||||
require "bundle/whalebrew_dumper"
|
||||
@ -23,7 +23,7 @@ module Homebrew
|
||||
|
||||
content = []
|
||||
content << TapDumper.dump if taps
|
||||
content << BrewDumper.dump(describe:, no_restart:) if brews
|
||||
content << FormulaDumper.dump(describe:, no_restart:) if formulae
|
||||
content << CaskDumper.dump(describe:) if casks
|
||||
content << MacAppStoreDumper.dump if mas
|
||||
content << WhalebrewDumper.dump if whalebrew
|
||||
@ -31,11 +31,11 @@ module Homebrew
|
||||
"#{content.reject(&:empty?).join("\n")}\n"
|
||||
end
|
||||
|
||||
def self.dump_brewfile(global:, file:, describe:, force:, no_restart:, brews:, taps:, casks:, mas:, whalebrew:,
|
||||
vscode:)
|
||||
def self.dump_brewfile(global:, file:, describe:, force:, no_restart:, formulae:, taps:, casks:, mas:,
|
||||
whalebrew:, vscode:)
|
||||
path = brewfile_path(global:, file:)
|
||||
can_write_to_brewfile?(path, force:)
|
||||
content = build_brewfile(describe:, no_restart:, taps:, brews:, casks:, mas:, whalebrew:, vscode:)
|
||||
content = build_brewfile(describe:, no_restart:, taps:, formulae:, casks:, mas:, whalebrew:, vscode:)
|
||||
write_file path, content
|
||||
end
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# typed: false # rubocop:todo Sorbet/TrueSigil
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "json"
|
||||
@ -7,10 +7,8 @@ require "tsort"
|
||||
module Homebrew
|
||||
module Bundle
|
||||
# TODO: refactor into multiple modules
|
||||
module BrewDumper
|
||||
module_function
|
||||
|
||||
def reset!
|
||||
module FormulaDumper
|
||||
def self.reset!
|
||||
require "bundle/brew_services"
|
||||
|
||||
Homebrew::Bundle::BrewServices.reset!
|
||||
@ -21,14 +19,14 @@ module Homebrew
|
||||
@formula_oldnames = nil
|
||||
end
|
||||
|
||||
def formulae
|
||||
def self.formulae
|
||||
return @formulae if @formulae
|
||||
|
||||
formulae_by_full_name
|
||||
@formulae
|
||||
end
|
||||
|
||||
def formulae_by_full_name(name = nil)
|
||||
def self.formulae_by_full_name(name = nil)
|
||||
return @formulae_by_full_name[name] if name.present? && @formulae_by_full_name&.key?(name)
|
||||
|
||||
require "formula"
|
||||
@ -51,11 +49,11 @@ module Homebrew
|
||||
{}
|
||||
end
|
||||
|
||||
def formulae_by_name(name)
|
||||
def self.formulae_by_name(name)
|
||||
formulae_by_full_name(name) || @formulae_by_name[name]
|
||||
end
|
||||
|
||||
def dump(describe: false, no_restart: false)
|
||||
def self.dump(describe: false, no_restart: false)
|
||||
require "bundle/brew_services"
|
||||
|
||||
requested_formula = formulae.select do |f|
|
||||
@ -77,7 +75,7 @@ module Homebrew
|
||||
end.join("\n")
|
||||
end
|
||||
|
||||
def formula_aliases
|
||||
def self.formula_aliases
|
||||
return @formula_aliases if @formula_aliases
|
||||
|
||||
@formula_aliases = {}
|
||||
@ -96,7 +94,7 @@ module Homebrew
|
||||
@formula_aliases
|
||||
end
|
||||
|
||||
def formula_oldnames
|
||||
def self.formula_oldnames
|
||||
return @formula_oldnames if @formula_oldnames
|
||||
|
||||
@formula_oldnames = {}
|
||||
@ -115,7 +113,7 @@ module Homebrew
|
||||
@formula_oldnames
|
||||
end
|
||||
|
||||
def add_formula(formula)
|
||||
private_class_method def self.add_formula(formula)
|
||||
hash = formula_to_hash formula
|
||||
|
||||
@formulae_by_name[hash[:name]] = hash
|
||||
@ -123,9 +121,8 @@ module Homebrew
|
||||
|
||||
hash
|
||||
end
|
||||
private_class_method :add_formula
|
||||
|
||||
def formula_to_hash(formula)
|
||||
private_class_method def self.formula_to_hash(formula)
|
||||
keg = if formula.linked?
|
||||
link = true if formula.keg_only?
|
||||
formula.linked_keg
|
||||
@ -185,17 +182,21 @@ module Homebrew
|
||||
official_tap: formula.tap&.official? || false,
|
||||
}
|
||||
end
|
||||
private_class_method :formula_to_hash
|
||||
|
||||
class Topo < Hash
|
||||
include TSort
|
||||
|
||||
def each_key(&block)
|
||||
keys.each(&block)
|
||||
end
|
||||
alias tsort_each_node each_key
|
||||
|
||||
def tsort_each_child(node, &block)
|
||||
fetch(node.downcase).sort.each(&block)
|
||||
end
|
||||
end
|
||||
|
||||
def sort!(formulae)
|
||||
private_class_method def self.sort!(formulae)
|
||||
# Step 1: Sort by formula full name while putting tap formulae behind core formulae.
|
||||
# So we can have a nicer output.
|
||||
formulae = formulae.sort do |a, b|
|
||||
@ -230,15 +231,14 @@ module Homebrew
|
||||
|
||||
odie <<~EOS
|
||||
Formulae dependency graph sorting failed (likely due to a circular dependency):
|
||||
#{cycle_first}: #{topo[cycle_first]}
|
||||
#{cycle_last}: #{topo[cycle_last]}
|
||||
#{cycle_first}: #{topo[cycle_first] if topo}
|
||||
#{cycle_last}: #{topo[cycle_last] if topo}
|
||||
Please run the following commands and try again:
|
||||
brew update
|
||||
brew uninstall --ignore-dependencies --force #{cycle_first} #{cycle_last}
|
||||
brew install #{cycle_first} #{cycle_last}
|
||||
EOS
|
||||
end
|
||||
private_class_method :sort!
|
||||
end
|
||||
end
|
||||
end
|
@ -3,7 +3,7 @@
|
||||
|
||||
module Homebrew
|
||||
module Bundle
|
||||
class BrewInstaller
|
||||
class FormulaInstaller
|
||||
def self.reset!
|
||||
@installed_formulae = nil
|
||||
@outdated_formulae = nil
|
||||
@ -179,13 +179,13 @@ module Homebrew
|
||||
return true if array.include?(formula)
|
||||
return true if array.include?(formula.split("/").last)
|
||||
|
||||
require "bundle/brew_dumper"
|
||||
old_names = Homebrew::Bundle::BrewDumper.formula_oldnames
|
||||
require "bundle/formula_dumper"
|
||||
old_names = Homebrew::Bundle::FormulaDumper.formula_oldnames
|
||||
old_name = old_names[formula]
|
||||
old_name ||= old_names[formula.split("/").last]
|
||||
return true if old_name && array.include?(old_name)
|
||||
|
||||
resolved_full_name = Homebrew::Bundle::BrewDumper.formula_aliases[formula]
|
||||
resolved_full_name = Homebrew::Bundle::FormulaDumper.formula_aliases[formula]
|
||||
return false unless resolved_full_name
|
||||
return true if array.include?(resolved_full_name)
|
||||
return true if array.include?(resolved_full_name.split("/").last)
|
||||
@ -219,14 +219,14 @@ module Homebrew
|
||||
end
|
||||
|
||||
def self.formulae
|
||||
require "bundle/brew_dumper"
|
||||
Homebrew::Bundle::BrewDumper.formulae
|
||||
require "bundle/formula_dumper"
|
||||
Homebrew::Bundle::FormulaDumper.formulae
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def installed?
|
||||
BrewInstaller.formula_installed?(@name)
|
||||
FormulaInstaller.formula_installed?(@name)
|
||||
end
|
||||
|
||||
def linked?
|
||||
@ -242,7 +242,7 @@ module Homebrew
|
||||
end
|
||||
|
||||
def upgradable?
|
||||
BrewInstaller.formula_upgradable?(@name)
|
||||
FormulaInstaller.formula_upgradable?(@name)
|
||||
end
|
||||
|
||||
def conflicts_with
|
||||
@ -250,8 +250,8 @@ module Homebrew
|
||||
conflicts_with = Set.new
|
||||
conflicts_with += @conflicts_with_arg
|
||||
|
||||
require "bundle/brew_dumper"
|
||||
if (formula = Homebrew::Bundle::BrewDumper.formulae_by_full_name(@full_name)) &&
|
||||
require "bundle/formula_dumper"
|
||||
if (formula = Homebrew::Bundle::FormulaDumper.formulae_by_full_name(@full_name)) &&
|
||||
(formula_conflicts_with = formula[:conflicts_with])
|
||||
conflicts_with += formula_conflicts_with
|
||||
end
|
||||
@ -262,7 +262,7 @@ module Homebrew
|
||||
|
||||
def resolve_conflicts!(verbose:)
|
||||
conflicts_with.each do |conflict|
|
||||
next unless BrewInstaller.formula_installed?(conflict)
|
||||
next unless FormulaInstaller.formula_installed?(conflict)
|
||||
|
||||
if verbose
|
||||
puts <<~EOS
|
||||
@ -293,7 +293,7 @@ module Homebrew
|
||||
return false
|
||||
end
|
||||
|
||||
BrewInstaller.installed_formulae << @name
|
||||
FormulaInstaller.installed_formulae << @name
|
||||
@changed = true
|
||||
true
|
||||
end
|
@ -2,7 +2,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "bundle/dsl"
|
||||
require "bundle/brew_installer"
|
||||
require "bundle/formula_installer"
|
||||
require "bundle/cask_installer"
|
||||
require "bundle/mac_app_store_installer"
|
||||
require "bundle/whalebrew_installer"
|
||||
@ -27,8 +27,8 @@ module Homebrew
|
||||
cls = case type
|
||||
when :brew
|
||||
options = entry.options
|
||||
verb = "Upgrading" if Homebrew::Bundle::BrewInstaller.formula_upgradable?(name)
|
||||
Homebrew::Bundle::BrewInstaller
|
||||
verb = "Upgrading" if Homebrew::Bundle::FormulaInstaller.formula_upgradable?(name)
|
||||
Homebrew::Bundle::FormulaInstaller
|
||||
when :cask
|
||||
options = entry.options
|
||||
verb = "Upgrading" if Homebrew::Bundle::CaskInstaller.cask_upgradable?(name)
|
||||
|
@ -4,14 +4,14 @@
|
||||
module Homebrew
|
||||
module Bundle
|
||||
module Lister
|
||||
def self.list(entries, brews:, casks:, taps:, mas:, whalebrew:, vscode:)
|
||||
def self.list(entries, formulae:, casks:, taps:, mas:, whalebrew:, vscode:)
|
||||
entries.each do |entry|
|
||||
puts entry.name if show?(entry.type, brews:, casks:, taps:, mas:, whalebrew:, vscode:)
|
||||
puts entry.name if show?(entry.type, formulae:, casks:, taps:, mas:, whalebrew:, vscode:)
|
||||
end
|
||||
end
|
||||
|
||||
private_class_method def self.show?(type, brews:, casks:, taps:, mas:, whalebrew:, vscode:)
|
||||
return true if brews && type == :brew
|
||||
private_class_method def self.show?(type, formulae:, casks:, taps:, mas:, whalebrew:, vscode:)
|
||||
return true if formulae && type == :brew
|
||||
return true if casks && type == :cask
|
||||
return true if taps && type == :tap
|
||||
return true if mas && type == :mas
|
||||
|
@ -9,21 +9,8 @@ module Homebrew
|
||||
class << self
|
||||
sig { params(entry: Dsl::Entry, silent: T::Boolean).returns(T::Boolean) }
|
||||
def skip?(entry, silent: false)
|
||||
require "bundle/brew_dumper"
|
||||
require "bundle/formula_dumper"
|
||||
|
||||
# TODO: use extend/OS here
|
||||
# rubocop:todo Homebrew/MoveToExtendOS
|
||||
if (Hardware::CPU.arm? || OS.linux?) &&
|
||||
Homebrew.default_prefix? &&
|
||||
entry.type == :brew && entry.name.exclude?("/") &&
|
||||
(formula = BrewDumper.formulae_by_full_name(entry.name)) &&
|
||||
formula[:official_tap] &&
|
||||
!formula[:bottled]
|
||||
reason = Hardware::CPU.arm? ? "Apple Silicon" : "Linux"
|
||||
puts Formatter.warning "Skipping #{entry.name} (no bottle for #{reason})" unless silent
|
||||
return true
|
||||
end
|
||||
# rubocop:enable Homebrew/MoveToExtendOS
|
||||
return true if @failed_taps&.any? do |tap|
|
||||
prefix = "#{tap}/"
|
||||
entry.name.start_with?(prefix) || entry.options[:full_name]&.start_with?(prefix)
|
||||
|
@ -19,7 +19,6 @@ module Homebrew
|
||||
puts "Installing #{name} tap. It is not currently installed." if verbose
|
||||
args = []
|
||||
args << "--force" if force
|
||||
args.append("--force-auto-update") if options[:force_auto_update]
|
||||
|
||||
success = if options[:clone_target]
|
||||
Bundle.brew("tap", name, options[:clone_target], *args, verbose:)
|
||||
|
@ -139,7 +139,11 @@ module Cask
|
||||
|
||||
def initialize(cask, *dsl_args)
|
||||
@cask = cask
|
||||
@dirmethod = nil
|
||||
@dsl_args = dsl_args.deep_dup
|
||||
@dsl_key = nil
|
||||
@english_article = nil
|
||||
@english_name = nil
|
||||
end
|
||||
|
||||
def config
|
||||
|
@ -41,7 +41,9 @@ module Cask
|
||||
super
|
||||
|
||||
target = target_hash[:target]
|
||||
@source = nil
|
||||
@source_string = source.to_s
|
||||
@target = nil
|
||||
@target_string = target.to_s
|
||||
end
|
||||
|
||||
|
@ -1,9 +1,14 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Cask
|
||||
# Sorted set containing all cask artifacts.
|
||||
class ArtifactSet < ::Set
|
||||
extend T::Generic
|
||||
|
||||
Elem = type_member(:out) { { fixed: Artifact::AbstractArtifact } }
|
||||
|
||||
sig { params(block: T.nilable(T.proc.params(arg0: Elem).returns(T.untyped))).void }
|
||||
def each(&block)
|
||||
return enum_for(T.must(__method__)) { size } unless block
|
||||
|
||||
@ -11,6 +16,7 @@ module Cask
|
||||
self
|
||||
end
|
||||
|
||||
sig { returns(T::Array[Artifact::AbstractArtifact]) }
|
||||
def to_a
|
||||
super.sort
|
||||
end
|
||||
|
@ -27,7 +27,7 @@ module Cask
|
||||
|
||||
sig {
|
||||
params(
|
||||
cask: ::Cask::Cask, download: T::Boolean, quarantine: T::Boolean, token_conflicts: T.nilable(T::Boolean),
|
||||
cask: ::Cask::Cask, download: T::Boolean, quarantine: T::Boolean,
|
||||
online: T.nilable(T::Boolean), strict: T.nilable(T::Boolean), signing: T.nilable(T::Boolean),
|
||||
new_cask: T.nilable(T::Boolean), only: T::Array[String], except: T::Array[String]
|
||||
).void
|
||||
@ -35,14 +35,13 @@ module Cask
|
||||
def initialize(
|
||||
cask,
|
||||
download: false, quarantine: false,
|
||||
token_conflicts: nil, online: nil, strict: nil, signing: nil,
|
||||
online: nil, strict: nil, signing: nil,
|
||||
new_cask: nil, only: [], except: []
|
||||
)
|
||||
# `new_cask` implies `online`, `token_conflicts`, `strict` and `signing`
|
||||
# `new_cask` implies `online`, `strict` and `signing`
|
||||
online = new_cask if online.nil?
|
||||
strict = new_cask if strict.nil?
|
||||
signing = new_cask if signing.nil?
|
||||
token_conflicts = new_cask if token_conflicts.nil?
|
||||
|
||||
# `online` and `signing` imply `download`
|
||||
download ||= online || signing
|
||||
@ -53,7 +52,6 @@ module Cask
|
||||
@strict = strict
|
||||
@signing = signing
|
||||
@new_cask = new_cask
|
||||
@token_conflicts = token_conflicts
|
||||
@only = only
|
||||
@except = except
|
||||
end
|
||||
@ -70,9 +68,6 @@ module Cask
|
||||
sig { returns(T::Boolean) }
|
||||
def strict? = !!@strict
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def token_conflicts? = !!@token_conflicts
|
||||
|
||||
sig { returns(::Cask::Audit) }
|
||||
def run!
|
||||
only_audits = @only
|
||||
@ -430,15 +425,10 @@ module Cask
|
||||
|
||||
sig { void }
|
||||
def audit_token_conflicts
|
||||
return unless token_conflicts?
|
||||
|
||||
Homebrew.with_no_api_env do
|
||||
return unless core_formula_names.include?(cask.token)
|
||||
|
||||
add_error(
|
||||
"possible duplicate, cask token conflicts with Homebrew core formula: #{Formatter.url(core_formula_url)}",
|
||||
strict_only: true,
|
||||
)
|
||||
add_error("cask token conflicts with an existing homebrew/core formula: #{Formatter.url(core_formula_url)}")
|
||||
end
|
||||
end
|
||||
|
||||
@ -653,11 +643,12 @@ module Cask
|
||||
|
||||
supports_arm = result.merged_output.include?("arm64")
|
||||
mentions_rosetta = cask.caveats.include?("requires Rosetta 2")
|
||||
requires_intel = cask.depends_on.arch&.any? { |arch| arch[:type] == :intel }
|
||||
|
||||
if supports_arm && mentions_rosetta
|
||||
add_error "Artifacts do not require Rosetta 2 but the caveats say otherwise!",
|
||||
location: url.location
|
||||
elsif !supports_arm && !mentions_rosetta
|
||||
elsif !supports_arm && !mentions_rosetta && !requires_intel
|
||||
add_error "Artifacts require Rosetta 2 but this is not indicated by the caveats!",
|
||||
location: url.location
|
||||
end
|
||||
@ -701,45 +692,53 @@ module Cask
|
||||
return unless online?
|
||||
return unless strict?
|
||||
|
||||
odebug "Auditing minimum OS version"
|
||||
odebug "Auditing minimum macOS version"
|
||||
|
||||
plist_min_os = cask_plist_min_os
|
||||
sparkle_min_os = livecheck_min_os
|
||||
bundle_min_os = cask_bundle_min_os
|
||||
sparkle_min_os = cask_sparkle_min_os
|
||||
|
||||
app_min_os = [bundle_min_os, sparkle_min_os].compact.max
|
||||
debug_messages = []
|
||||
debug_messages << "Plist #{plist_min_os}" if plist_min_os
|
||||
debug_messages << "Sparkle #{sparkle_min_os}" if sparkle_min_os
|
||||
odebug "Detected minimum OS version: #{debug_messages.join(" | ")}" unless debug_messages.empty?
|
||||
min_os = [plist_min_os, sparkle_min_os].compact.max
|
||||
|
||||
return if min_os.nil? || min_os <= HOMEBREW_MACOS_OLDEST_ALLOWED
|
||||
debug_messages << "from artifact: #{bundle_min_os.to_sym}" if bundle_min_os
|
||||
debug_messages << "from upstream: #{sparkle_min_os.to_sym}" if sparkle_min_os
|
||||
odebug "Detected minimum macOS: #{app_min_os.to_sym} (#{debug_messages.join(" | ")})" if app_min_os
|
||||
return if app_min_os.nil? || app_min_os <= HOMEBREW_MACOS_OLDEST_ALLOWED
|
||||
|
||||
on_system_block_min_os = cask.on_system_block_min_os
|
||||
cask_min_os = [on_system_block_min_os, cask.depends_on.macos&.minimum_version].compact.max
|
||||
odebug "Declared minimum OS version: #{cask_min_os&.to_sym}"
|
||||
return if cask_min_os&.to_sym == min_os.to_sym
|
||||
return if cask.on_system_blocks_exist? &&
|
||||
OnSystem.arch_condition_met?(:arm) &&
|
||||
depends_on_min_os = cask.depends_on.macos&.minimum_version
|
||||
|
||||
cask_min_os = [on_system_block_min_os, depends_on_min_os].compact.max
|
||||
debug_messages = []
|
||||
debug_messages << "from on_system block: #{on_system_block_min_os.to_sym}" if on_system_block_min_os
|
||||
if depends_on_min_os > HOMEBREW_MACOS_OLDEST_ALLOWED
|
||||
debug_messages << "from depends_on stanza: #{depends_on_min_os.to_sym}"
|
||||
end
|
||||
odebug "Declared minimum macOS: #{cask_min_os.to_sym} (#{debug_messages.join(" | ").presence || "default"})"
|
||||
return if cask_min_os.to_sym == app_min_os.to_sym
|
||||
# ignore declared minimum OS < 11.x when auditing as ARM a cask with arch-specific artifacts
|
||||
return if OnSystem.arch_condition_met?(:arm) &&
|
||||
cask.on_system_blocks_exist? &&
|
||||
cask_min_os.present? &&
|
||||
cask_min_os < MacOSVersion.new("11")
|
||||
|
||||
min_os_definition = if cask_min_os.present?
|
||||
if on_system_block_min_os.present? &&
|
||||
on_system_block_min_os > cask.depends_on.macos&.minimum_version
|
||||
"a block with a minimum OS version of #{cask_min_os.to_sym.inspect}"
|
||||
min_os_definition = if cask_min_os > HOMEBREW_MACOS_OLDEST_ALLOWED
|
||||
definition = if T.must(on_system_block_min_os.to_s <=> depends_on_min_os.to_s).positive?
|
||||
"an on_system block"
|
||||
else
|
||||
cask_min_os.to_sym.inspect
|
||||
"a depends_on stanza"
|
||||
end
|
||||
"#{definition} with a minimum macOS version of #{cask_min_os.to_sym.inspect}"
|
||||
else
|
||||
"no minimum OS version"
|
||||
"no minimum macOS version"
|
||||
end
|
||||
add_error "Upstream defined #{min_os.to_sym.inspect} as the minimum OS version " \
|
||||
source = T.must(bundle_min_os.to_s <=> sparkle_min_os.to_s).positive? ? "Artifact" : "Upstream"
|
||||
add_error "#{source} defined #{app_min_os.to_sym.inspect} as the minimum macOS version " \
|
||||
"but the cask declared #{min_os_definition}",
|
||||
strict_only: true
|
||||
end
|
||||
|
||||
sig { returns(T.nilable(MacOSVersion)) }
|
||||
def livecheck_min_os
|
||||
def cask_sparkle_min_os
|
||||
return unless online?
|
||||
return unless cask.livecheck_defined?
|
||||
return if cask.livecheck.strategy != :sparkle
|
||||
@ -772,10 +771,10 @@ module Cask
|
||||
end
|
||||
|
||||
sig { returns(T.nilable(MacOSVersion)) }
|
||||
def cask_plist_min_os
|
||||
def cask_bundle_min_os
|
||||
return unless online?
|
||||
|
||||
plist_min_os = T.let(nil, T.untyped)
|
||||
min_os = T.let(nil, T.untyped)
|
||||
@staged_path ||= cask.staged_path
|
||||
|
||||
extract_artifacts do |artifacts, tmpdir|
|
||||
@ -786,13 +785,33 @@ module Cask
|
||||
next unless File.exist?(plist_path)
|
||||
|
||||
plist = system_command!("plutil", args: ["-convert", "xml1", "-o", "-", plist_path]).plist
|
||||
plist_min_os = plist["LSMinimumSystemVersion"].presence
|
||||
break if plist_min_os
|
||||
min_os = plist["LSMinimumSystemVersion"].presence
|
||||
break if min_os
|
||||
|
||||
next unless (main_binary = get_plist_main_binary(path))
|
||||
next if !File.exist?(main_binary) || File.open(main_binary, "rb") { |f| f.read(2) == "#!" }
|
||||
|
||||
macho = MachO.open(main_binary)
|
||||
min_os = case macho
|
||||
when MachO::MachOFile
|
||||
[
|
||||
macho[:LC_VERSION_MIN_MACOSX].first&.version_string,
|
||||
macho[:LC_BUILD_VERSION].first&.minos_string,
|
||||
]
|
||||
when MachO::FatFile
|
||||
macho.machos.map do |slice|
|
||||
[
|
||||
slice[:LC_VERSION_MIN_MACOSX].first&.version_string,
|
||||
slice[:LC_BUILD_VERSION].first&.minos_string,
|
||||
]
|
||||
end.flatten
|
||||
end.compact.min
|
||||
break if min_os
|
||||
end
|
||||
end
|
||||
|
||||
begin
|
||||
MacOSVersion.new(plist_min_os).strip_patch
|
||||
MacOSVersion.new(min_os).strip_patch
|
||||
rescue MacOSVersion::Error
|
||||
nil
|
||||
end
|
||||
|
@ -11,17 +11,17 @@ module Cask
|
||||
params(
|
||||
cask: ::Cask::Cask, audit_download: T::Boolean, audit_online: T.nilable(T::Boolean),
|
||||
audit_strict: T.nilable(T::Boolean), audit_signing: T.nilable(T::Boolean),
|
||||
audit_token_conflicts: T.nilable(T::Boolean), audit_new_cask: T.nilable(T::Boolean), quarantine: T::Boolean,
|
||||
audit_new_cask: T.nilable(T::Boolean), quarantine: T::Boolean,
|
||||
any_named_args: T::Boolean, language: T.nilable(String), only: T::Array[String], except: T::Array[String]
|
||||
).returns(T::Set[String])
|
||||
}
|
||||
def self.audit(
|
||||
cask, audit_download: false, audit_online: nil, audit_strict: nil, audit_signing: nil,
|
||||
audit_token_conflicts: nil, audit_new_cask: nil, quarantine: false, any_named_args: false, language: nil,
|
||||
audit_new_cask: nil, quarantine: false, any_named_args: false, language: nil,
|
||||
only: [], except: []
|
||||
)
|
||||
new(
|
||||
cask, audit_download:, audit_online:, audit_strict:, audit_signing:, audit_token_conflicts:,
|
||||
cask, audit_download:, audit_online:, audit_strict:, audit_signing:,
|
||||
audit_new_cask:, quarantine:, any_named_args:, language:, only:, except:
|
||||
).audit
|
||||
end
|
||||
@ -36,7 +36,7 @@ module Cask
|
||||
params(
|
||||
cask: ::Cask::Cask, audit_download: T::Boolean, audit_online: T.nilable(T::Boolean),
|
||||
audit_strict: T.nilable(T::Boolean), audit_signing: T.nilable(T::Boolean),
|
||||
audit_token_conflicts: T.nilable(T::Boolean), audit_new_cask: T.nilable(T::Boolean), quarantine: T::Boolean,
|
||||
audit_new_cask: T.nilable(T::Boolean), quarantine: T::Boolean,
|
||||
any_named_args: T::Boolean, language: T.nilable(String), only: T::Array[String], except: T::Array[String]
|
||||
).void
|
||||
}
|
||||
@ -46,7 +46,6 @@ module Cask
|
||||
audit_online: nil,
|
||||
audit_strict: nil,
|
||||
audit_signing: nil,
|
||||
audit_token_conflicts: nil,
|
||||
audit_new_cask: nil,
|
||||
quarantine: false,
|
||||
any_named_args: false,
|
||||
@ -61,7 +60,6 @@ module Cask
|
||||
@audit_strict = audit_strict
|
||||
@audit_signing = audit_signing
|
||||
@quarantine = quarantine
|
||||
@audit_token_conflicts = audit_token_conflicts
|
||||
@any_named_args = any_named_args
|
||||
@language = language
|
||||
@only = only
|
||||
@ -127,15 +125,14 @@ module Cask
|
||||
def audit_cask_instance(cask)
|
||||
audit = Audit.new(
|
||||
cask,
|
||||
online: @audit_online,
|
||||
strict: @audit_strict,
|
||||
signing: @audit_signing,
|
||||
new_cask: @audit_new_cask,
|
||||
token_conflicts: @audit_token_conflicts,
|
||||
download: @audit_download,
|
||||
quarantine: @quarantine,
|
||||
only: @only,
|
||||
except: @except,
|
||||
online: @audit_online,
|
||||
strict: @audit_strict,
|
||||
signing: @audit_signing,
|
||||
new_cask: @audit_new_cask,
|
||||
download: @audit_download,
|
||||
quarantine: @quarantine,
|
||||
only: @only,
|
||||
except: @except,
|
||||
)
|
||||
audit.run!
|
||||
end
|
||||
|
@ -8,7 +8,7 @@ require "cask/dsl"
|
||||
require "cask/metadata"
|
||||
require "cask/tab"
|
||||
require "utils/bottles"
|
||||
require "extend/api_hashable"
|
||||
require "api_hashable"
|
||||
|
||||
module Cask
|
||||
# An instance of a cask.
|
||||
@ -416,16 +416,14 @@ module Cask
|
||||
|
||||
if @dsl.on_system_blocks_exist?
|
||||
begin
|
||||
OnSystem::ALL_OS_ARCH_COMBINATIONS.each do |os, arch|
|
||||
bottle_tag = ::Utils::Bottles::Tag.new(system: os, arch:)
|
||||
next unless bottle_tag.valid_combination?
|
||||
OnSystem::VALID_OS_ARCH_TAGS.each do |bottle_tag|
|
||||
next if bottle_tag.linux? && @dsl.os.nil?
|
||||
next if bottle_tag.macos? &&
|
||||
depends_on.macos &&
|
||||
!@dsl.depends_on_set_in_block? &&
|
||||
!depends_on.macos.allows?(bottle_tag.to_macos_version)
|
||||
|
||||
Homebrew::SimulateSystem.with(os:, arch:) do
|
||||
Homebrew::SimulateSystem.with_tag(bottle_tag) do
|
||||
refresh
|
||||
|
||||
to_h.each do |key, value|
|
||||
|
@ -6,6 +6,7 @@ require "cask/cask"
|
||||
require "uri"
|
||||
require "utils/curl"
|
||||
require "extend/hash/keys"
|
||||
require "api"
|
||||
|
||||
module Cask
|
||||
# Loads a cask from various sources.
|
||||
@ -104,8 +105,8 @@ module Cask
|
||||
return
|
||||
end
|
||||
|
||||
return if %w[.rb .json].exclude?(path.extname)
|
||||
return unless path.expand_path.exist?
|
||||
return if invalid_path?(path)
|
||||
|
||||
return if Homebrew::EnvConfig.forbid_packages_from_paths? &&
|
||||
!path.realpath.to_s.start_with?("#{Caskroom.path}/", "#{HOMEBREW_LIBRARY}/Taps/")
|
||||
@ -113,6 +114,14 @@ module Cask
|
||||
new(path)
|
||||
end
|
||||
|
||||
sig { params(pathname: Pathname, valid_extnames: T::Array[String]).returns(T::Boolean) }
|
||||
def self.invalid_path?(pathname, valid_extnames: %w[.rb .json])
|
||||
return true if valid_extnames.exclude?(pathname.extname)
|
||||
|
||||
@invalid_basenames ||= %w[INSTALL_RECEIPT.json sbom.spdx.json].freeze
|
||||
@invalid_basenames.include?(pathname.basename.to_s)
|
||||
end
|
||||
|
||||
attr_reader :token, :path
|
||||
|
||||
sig { params(path: T.any(Pathname, String), token: String).void }
|
||||
@ -135,8 +144,10 @@ module Cask
|
||||
@content = path.read(encoding: "UTF-8")
|
||||
@config = config
|
||||
|
||||
if path.extname == ".json"
|
||||
return FromAPILoader.new(token, from_json: JSON.parse(@content), path:).load(config:)
|
||||
if !self.class.invalid_path?(path, valid_extnames: %w[.json]) &&
|
||||
(from_json = JSON.parse(@content).presence) &&
|
||||
from_json.is_a?(Hash)
|
||||
return FromAPILoader.new(token, from_json:, path:).load(config:)
|
||||
end
|
||||
|
||||
begin
|
||||
@ -284,7 +295,7 @@ module Cask
|
||||
sig { returns(Pathname) }
|
||||
attr_reader :path
|
||||
|
||||
sig { returns(T.nilable(Hash)) }
|
||||
sig { returns(T.nilable(T::Hash[String, T.untyped])) }
|
||||
attr_reader :from_json
|
||||
|
||||
sig {
|
||||
@ -306,7 +317,13 @@ module Cask
|
||||
new("#{tap}/#{token}")
|
||||
end
|
||||
|
||||
sig { params(token: String, from_json: Hash, path: T.nilable(Pathname)).void }
|
||||
sig {
|
||||
params(
|
||||
token: String,
|
||||
from_json: T.nilable(T::Hash[String, T.untyped]),
|
||||
path: T.nilable(Pathname),
|
||||
).void
|
||||
}
|
||||
def initialize(token, from_json: T.unsafe(nil), path: nil)
|
||||
@token = token.sub(%r{^homebrew/(?:homebrew-)?cask/}i, "")
|
||||
@sourcefile_path = path || Homebrew::API::Cask.cached_json_file_path
|
||||
@ -400,7 +417,7 @@ module Cask
|
||||
container(**container_hash)
|
||||
end
|
||||
|
||||
json_cask[:artifacts].each do |artifact|
|
||||
json_cask[:artifacts]&.each do |artifact|
|
||||
# convert generic string replacements into actual ones
|
||||
artifact = cask.loader.from_h_gsubs(artifact, appdir)
|
||||
key = artifact.keys.first
|
||||
|
@ -26,7 +26,7 @@ require "cask/dsl/version"
|
||||
require "cask/url"
|
||||
require "cask/utils"
|
||||
|
||||
require "extend/on_system"
|
||||
require "on_system"
|
||||
|
||||
module Cask
|
||||
# Class representing the domain-specific language used for casks.
|
||||
@ -69,7 +69,6 @@ module Cask
|
||||
].freeze
|
||||
|
||||
DSL_METHODS = Set.new([
|
||||
:appcast,
|
||||
:arch,
|
||||
:artifacts,
|
||||
:auto_updates,
|
||||
@ -123,15 +122,21 @@ module Cask
|
||||
|
||||
sig { params(cask: Cask).void }
|
||||
def initialize(cask)
|
||||
# NOTE: Variables set by `set_unique_stanza` must be initialized to `nil`.
|
||||
@auto_updates = T.let(nil, T.nilable(T::Boolean))
|
||||
# NOTE: `:"@#{stanza}"` variables set by `set_unique_stanza` must be
|
||||
# initialized to `nil`.
|
||||
@arch = T.let(nil, T.nilable(String))
|
||||
@arch_set_in_block = T.let(false, T::Boolean)
|
||||
@artifacts = T.let(ArtifactSet.new, ArtifactSet)
|
||||
@auto_updates = T.let(nil, T.nilable(T::Boolean))
|
||||
@auto_updates_set_in_block = T.let(false, T::Boolean)
|
||||
@autobump = T.let(true, T::Boolean)
|
||||
@called_in_on_system_block = T.let(false, T::Boolean)
|
||||
@cask = T.let(cask, Cask)
|
||||
@caveats = T.let(DSL::Caveats.new(cask), DSL::Caveats)
|
||||
@conflicts_with = T.let(nil, T.nilable(DSL::ConflictsWith))
|
||||
@conflicts_with_set_in_block = T.let(false, T::Boolean)
|
||||
@container = T.let(nil, T.nilable(DSL::Container))
|
||||
@container_set_in_block = T.let(false, T::Boolean)
|
||||
@depends_on = T.let(DSL::DependsOn.new, DSL::DependsOn)
|
||||
@depends_on_set_in_block = T.let(false, T::Boolean)
|
||||
@deprecated = T.let(false, T::Boolean)
|
||||
@ -140,27 +145,32 @@ module Cask
|
||||
@deprecation_replacement_cask = T.let(nil, T.nilable(String))
|
||||
@deprecation_replacement_formula = T.let(nil, T.nilable(String))
|
||||
@desc = T.let(nil, T.nilable(String))
|
||||
@desc_set_in_block = T.let(false, T::Boolean)
|
||||
@disable_date = T.let(nil, T.nilable(Date))
|
||||
@disable_reason = T.let(nil, T.nilable(T.any(String, Symbol)))
|
||||
@disable_replacement_cask = T.let(nil, T.nilable(String))
|
||||
@disable_replacement_formula = T.let(nil, T.nilable(String))
|
||||
@disabled = T.let(false, T::Boolean)
|
||||
@homepage = T.let(nil, T.nilable(String))
|
||||
@homepage_set_in_block = T.let(false, T::Boolean)
|
||||
@language_blocks = T.let({}, T::Hash[T::Array[String], Proc])
|
||||
@language_eval = T.let(nil, T.nilable(String))
|
||||
@livecheck = T.let(Livecheck.new(cask), Livecheck)
|
||||
@livecheck_defined = T.let(false, T::Boolean)
|
||||
@name = T.let([], T::Array[String])
|
||||
@autobump = T.let(true, T::Boolean)
|
||||
@no_autobump_defined = T.let(false, T::Boolean)
|
||||
@on_system_blocks_exist = T.let(false, T::Boolean)
|
||||
@os = T.let(nil, T.nilable(String))
|
||||
@on_system_block_min_os = T.let(nil, T.nilable(MacOSVersion))
|
||||
@os = T.let(nil, T.nilable(String))
|
||||
@os_set_in_block = T.let(false, T::Boolean)
|
||||
@sha256 = T.let(nil, T.nilable(T.any(Checksum, Symbol)))
|
||||
@sha256_set_in_block = T.let(false, T::Boolean)
|
||||
@staged_path = T.let(nil, T.nilable(Pathname))
|
||||
@token = T.let(cask.token, String)
|
||||
@url = T.let(nil, T.nilable(URL))
|
||||
@url_set_in_block = T.let(false, T::Boolean)
|
||||
@version = T.let(nil, T.nilable(DSL::Version))
|
||||
@version_set_in_block = T.let(false, T::Boolean)
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
@ -216,7 +226,7 @@ module Cask
|
||||
raise CaskInvalidError.new(cask, "'#{stanza}' stanza may only appear once.")
|
||||
end
|
||||
|
||||
if instance_variable_defined?(:"@#{stanza}_set_in_block") && @called_in_on_system_block
|
||||
if instance_variable_get(:"@#{stanza}_set_in_block") && @called_in_on_system_block
|
||||
raise CaskInvalidError.new(cask, "'#{stanza}' stanza may only be overridden once.")
|
||||
end
|
||||
end
|
||||
@ -476,7 +486,7 @@ module Cask
|
||||
def add_implicit_macos_dependency
|
||||
return if (cask_depends_on = @depends_on).present? && cask_depends_on.macos.present?
|
||||
|
||||
depends_on macos: ">= :#{MacOSVersion::SYMBOLS.key MacOSVersion::SYMBOLS.values.min}"
|
||||
depends_on macos: ">= #{MacOSVersion.new(HOMEBREW_MACOS_OLDEST_ALLOWED).to_sym.inspect}"
|
||||
end
|
||||
|
||||
# Declare conflicts that keep a cask from installing or working correctly.
|
||||
|
@ -2,7 +2,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "cask/utils"
|
||||
require "extend/on_system"
|
||||
require "on_system"
|
||||
|
||||
module Cask
|
||||
class DSL
|
||||
|
@ -52,16 +52,17 @@ module Cask
|
||||
raise "Only a single 'depends_on macos' is allowed." if defined?(@macos)
|
||||
|
||||
# workaround for https://github.com/sorbet/sorbet/issues/6860
|
||||
first_arg = args.first&.to_s
|
||||
first_arg = args.first
|
||||
first_arg_s = first_arg&.to_s
|
||||
|
||||
begin
|
||||
@macos = if args.count > 1
|
||||
MacOSRequirement.new([args], comparator: "==")
|
||||
elsif MacOSVersion::SYMBOLS.key?(args.first)
|
||||
elsif first_arg.is_a?(Symbol) && MacOSVersion::SYMBOLS.key?(first_arg)
|
||||
MacOSRequirement.new([args.first], comparator: "==")
|
||||
elsif (md = /^\s*(?<comparator><|>|[=<>]=)\s*:(?<version>\S+)\s*$/.match(first_arg))
|
||||
elsif (md = /^\s*(?<comparator><|>|[=<>]=)\s*:(?<version>\S+)\s*$/.match(first_arg_s))
|
||||
MacOSRequirement.new([T.must(md[:version]).to_sym], comparator: md[:comparator])
|
||||
elsif (md = /^\s*(?<comparator><|>|[=<>]=)\s*(?<version>\S+)\s*$/.match(first_arg))
|
||||
elsif (md = /^\s*(?<comparator><|>|[=<>]=)\s*(?<version>\S+)\s*$/.match(first_arg_s))
|
||||
MacOSRequirement.new([md[:version]], comparator: md[:comparator])
|
||||
# This is not duplicate of the first case: see `args.first` and a different comparator.
|
||||
else # rubocop:disable Lint/DuplicateBranch
|
||||
|
@ -4,6 +4,7 @@
|
||||
require "formula_installer"
|
||||
require "unpack_strategy"
|
||||
require "utils/topological_hash"
|
||||
require "utils/analytics"
|
||||
|
||||
require "cask/config"
|
||||
require "cask/download"
|
||||
@ -149,7 +150,7 @@ module Cask
|
||||
|
||||
oh1 "Installing Cask #{Formatter.identifier(@cask)}"
|
||||
# GitHub Actions globally disables Gatekeeper.
|
||||
opoo "macOS's Gatekeeper has been disabled for this Cask" if !quarantine? && !GitHub::Actions.env_set?
|
||||
opoo_outside_github_actions "macOS's Gatekeeper has been disabled for this Cask" unless quarantine?
|
||||
stage
|
||||
|
||||
@cask.config = @cask.default_config.merge(old_config)
|
||||
@ -303,6 +304,20 @@ on_request: true)
|
||||
|
||||
next if artifact.is_a?(Artifact::Binary) && !binaries?
|
||||
|
||||
artifact = T.cast(
|
||||
artifact,
|
||||
T.any(
|
||||
Artifact::AbstractFlightBlock,
|
||||
Artifact::Installer,
|
||||
Artifact::KeyboardLayout,
|
||||
Artifact::Mdimporter,
|
||||
Artifact::Moved,
|
||||
Artifact::Pkg,
|
||||
Artifact::Qlplugin,
|
||||
Artifact::Symlinked,
|
||||
),
|
||||
)
|
||||
|
||||
artifact.install_phase(
|
||||
command: @command, verbose: verbose?, adopt: adopt?, auto_updates: @cask.auto_updates,
|
||||
force: force?, predecessor:
|
||||
@ -548,6 +563,18 @@ on_request: true)
|
||||
|
||||
artifacts.each do |artifact|
|
||||
if artifact.respond_to?(:uninstall_phase)
|
||||
artifact = T.cast(
|
||||
artifact,
|
||||
T.any(
|
||||
Artifact::AbstractFlightBlock,
|
||||
Artifact::KeyboardLayout,
|
||||
Artifact::Moved,
|
||||
Artifact::Qlplugin,
|
||||
Artifact::Symlinked,
|
||||
Artifact::Uninstall,
|
||||
),
|
||||
)
|
||||
|
||||
odebug "Uninstalling artifact of class #{artifact.class}"
|
||||
artifact.uninstall_phase(
|
||||
command: @command,
|
||||
@ -562,6 +589,8 @@ on_request: true)
|
||||
|
||||
next unless artifact.respond_to?(:post_uninstall_phase)
|
||||
|
||||
artifact = T.cast(artifact, Artifact::Uninstall)
|
||||
|
||||
odebug "Post-uninstalling artifact of class #{artifact.class}"
|
||||
artifact.post_uninstall_phase(
|
||||
command: @command,
|
||||
@ -575,7 +604,6 @@ on_request: true)
|
||||
|
||||
def zap
|
||||
load_installed_caskfile!
|
||||
ohai "Implied `brew uninstall --cask #{@cask}`"
|
||||
uninstall_artifacts
|
||||
if (zap_stanzas = @cask.artifacts.select { |a| a.is_a?(Artifact::Zap) }).empty?
|
||||
opoo "No zap stanza present for Cask '#{@cask}'"
|
||||
@ -764,10 +792,10 @@ on_request: true)
|
||||
|
||||
if installed_caskfile&.exist?
|
||||
begin
|
||||
@cask = CaskLoader.load(installed_caskfile)
|
||||
@cask = CaskLoader.load_from_installed_caskfile(installed_caskfile)
|
||||
return
|
||||
rescue CaskInvalidError
|
||||
# could be caused by trying to load outdated caskfile
|
||||
rescue CaskInvalidError, CaskUnavailableError
|
||||
# could be caused by trying to load outdated or deleted caskfile
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -5,10 +5,24 @@ require "tab"
|
||||
|
||||
module Cask
|
||||
class Tab < ::AbstractTab
|
||||
attr_accessor :uninstall_flight_blocks, :uninstall_artifacts
|
||||
sig { returns(T.nilable(T::Boolean)) }
|
||||
attr_accessor :uninstall_flight_blocks
|
||||
|
||||
sig { returns(T.nilable(T::Array[T.untyped])) }
|
||||
attr_accessor :uninstall_artifacts
|
||||
|
||||
sig { params(attributes: T::Hash[String, T.untyped]).void }
|
||||
def initialize(attributes = {})
|
||||
@uninstall_flight_blocks = T.let(nil, T.nilable(T::Boolean))
|
||||
@uninstall_artifacts = T.let(nil, T.nilable(T::Array[T.untyped]))
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
# Instantiates a {Tab} for a new installation of a cask.
|
||||
def self.create(cask)
|
||||
sig { override.params(formula_or_cask: T.any(Formula, Cask)).returns(T.attached_class) }
|
||||
def self.create(formula_or_cask)
|
||||
cask = T.cast(formula_or_cask, Cask)
|
||||
tab = super
|
||||
|
||||
tab.tabfile = cask.metadata_main_container_path/FILENAME
|
||||
@ -23,6 +37,7 @@ module Cask
|
||||
|
||||
# Returns a {Tab} for an already installed cask,
|
||||
# or a fake one if the cask is not installed.
|
||||
sig { params(cask: Cask).returns(T.attached_class) }
|
||||
def self.for_cask(cask)
|
||||
path = cask.metadata_main_container_path/FILENAME
|
||||
|
||||
@ -40,6 +55,7 @@ module Cask
|
||||
tab
|
||||
end
|
||||
|
||||
sig { returns(T.attached_class) }
|
||||
def self.empty
|
||||
tab = super
|
||||
tab.uninstall_flight_blocks = false
|
||||
@ -76,10 +92,12 @@ module Cask
|
||||
runtime_deps
|
||||
end
|
||||
|
||||
sig { returns(T.nilable(String)) }
|
||||
def version
|
||||
source["version"]
|
||||
end
|
||||
|
||||
sig { params(_args: T.untyped).returns(String) }
|
||||
def to_json(*_args)
|
||||
attributes = {
|
||||
"homebrew_version" => homebrew_version,
|
||||
@ -98,6 +116,7 @@ module Cask
|
||||
JSON.pretty_generate(attributes)
|
||||
end
|
||||
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
s = ["Installed"]
|
||||
s << "using the formulae.brew.sh API" if loaded_from_api
|
||||
|
@ -11,11 +11,12 @@ module Cask
|
||||
T.any(URI::Generic, String, [T.any(URI::Generic, String), T::Hash[Symbol, T.untyped]])
|
||||
end
|
||||
|
||||
# Methods for the `url` stanza.
|
||||
class DSL
|
||||
sig { returns(T.any(URI::Generic, String)) }
|
||||
attr_reader :uri
|
||||
|
||||
sig { returns(T.nilable(T::Array[String])) }
|
||||
sig { returns(T.nilable(T::Hash[T.any(Symbol, String), String])) }
|
||||
attr_reader :revisions
|
||||
|
||||
sig { returns(T.nilable(T::Boolean)) }
|
||||
@ -57,7 +58,7 @@ module Cask
|
||||
# @api public
|
||||
branch: T.nilable(String),
|
||||
# @api public
|
||||
revisions: T.nilable(T::Array[String]),
|
||||
revisions: T.nilable(T::Hash[T.any(Symbol, String), String]),
|
||||
# @api public
|
||||
revision: T.nilable(String),
|
||||
# @api public
|
||||
@ -87,7 +88,7 @@ module Cask
|
||||
specs[:using] = @using = T.let(using, T.any(T::Class[AbstractDownloadStrategy], Symbol, NilClass))
|
||||
specs[:tag] = @tag = T.let(tag, T.nilable(String))
|
||||
specs[:branch] = @branch = T.let(branch, T.nilable(String))
|
||||
specs[:revisions] = @revisions = T.let(revisions, T.nilable(T::Array[String]))
|
||||
specs[:revisions] = @revisions = T.let(revisions, T.nilable(T::Hash[T.any(Symbol, String), String]))
|
||||
specs[:revision] = @revision = T.let(revision, T.nilable(String))
|
||||
specs[:trust_cert] = @trust_cert = T.let(trust_cert, T.nilable(T::Boolean))
|
||||
specs[:cookies] = @cookies = T.let(cookies, T.nilable(T::Hash[String, String]))
|
||||
@ -101,6 +102,7 @@ module Cask
|
||||
end
|
||||
end
|
||||
|
||||
# Allow passing a block to the `url` stanza.
|
||||
class BlockDSL
|
||||
# Allow accessing the URL associated with page contents.
|
||||
class PageWithURL < SimpleDelegator
|
||||
@ -197,7 +199,7 @@ module Cask
|
||||
using: T.any(T::Class[AbstractDownloadStrategy], Symbol, NilClass),
|
||||
tag: T.nilable(String),
|
||||
branch: T.nilable(String),
|
||||
revisions: T.nilable(T::Array[String]),
|
||||
revisions: T.nilable(T::Hash[T.any(Symbol, String), String]),
|
||||
revision: T.nilable(String),
|
||||
trust_cert: T.nilable(T::Boolean),
|
||||
cookies: T.nilable(T::Hash[String, String]),
|
||||
|
@ -14,40 +14,54 @@ class Caveats
|
||||
sig { params(formula: Formula).void }
|
||||
def initialize(formula)
|
||||
@formula = formula
|
||||
@caveats = T.let(nil, T.nilable(String))
|
||||
@completions_and_elisp = T.let(nil, T.nilable(T::Array[String]))
|
||||
end
|
||||
|
||||
sig { returns(String) }
|
||||
def caveats
|
||||
caveats = []
|
||||
build = formula.build
|
||||
begin
|
||||
formula.build = Tab.for_formula(formula)
|
||||
string = formula.caveats.to_s
|
||||
caveats << "#{string.chomp}\n" unless string.empty?
|
||||
ensure
|
||||
formula.build = build
|
||||
@caveats ||= begin
|
||||
caveats = []
|
||||
build = formula.build
|
||||
begin
|
||||
formula.build = Tab.for_formula(formula)
|
||||
string = formula.caveats.to_s
|
||||
caveats << "#{string.chomp}\n" unless string.empty?
|
||||
ensure
|
||||
formula.build = build
|
||||
end
|
||||
caveats << keg_only_text
|
||||
caveats << service_caveats
|
||||
caveats.compact.join("\n")
|
||||
end
|
||||
caveats << keg_only_text
|
||||
|
||||
valid_shells = [:bash, :zsh, :fish, :pwsh].freeze
|
||||
current_shell = Utils::Shell.preferred || Utils::Shell.parent
|
||||
shells = if current_shell.present? &&
|
||||
(shell_sym = current_shell.to_sym) &&
|
||||
valid_shells.include?(shell_sym)
|
||||
[shell_sym]
|
||||
else
|
||||
valid_shells
|
||||
end
|
||||
shells.each do |shell|
|
||||
caveats << function_completion_caveats(shell)
|
||||
end
|
||||
|
||||
caveats << service_caveats
|
||||
caveats << elisp_caveats
|
||||
caveats.compact.join("\n")
|
||||
end
|
||||
|
||||
delegate [:empty?, :to_s] => :caveats
|
||||
sig { returns(T::Boolean) }
|
||||
def empty?
|
||||
caveats.blank? && completions_and_elisp.blank?
|
||||
end
|
||||
|
||||
delegate [:to_s] => :caveats
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def completions_and_elisp
|
||||
@completions_and_elisp ||= begin
|
||||
valid_shells = [:bash, :zsh, :fish, :pwsh].freeze
|
||||
current_shell = Utils::Shell.preferred || Utils::Shell.parent
|
||||
shells = if current_shell.present? &&
|
||||
(shell_sym = current_shell.to_sym) &&
|
||||
valid_shells.include?(shell_sym)
|
||||
[shell_sym]
|
||||
else
|
||||
valid_shells
|
||||
end
|
||||
completions_and_elisp = shells.map do |shell|
|
||||
function_completion_caveats(shell)
|
||||
end
|
||||
completions_and_elisp << elisp_caveats
|
||||
completions_and_elisp.compact
|
||||
end
|
||||
end
|
||||
|
||||
sig { params(skip_reason: T::Boolean).returns(T.nilable(String)) }
|
||||
def keg_only_text(skip_reason: false)
|
||||
|
@ -571,6 +571,7 @@ module Homebrew
|
||||
end
|
||||
return unless available
|
||||
return if Context.current.quiet?
|
||||
return if cask&.old_tokens&.include?(ref)
|
||||
|
||||
opoo package_conflicts_message(ref, loaded_type, cask)
|
||||
end
|
||||
|
@ -208,11 +208,15 @@ module Homebrew
|
||||
return if global_switch
|
||||
|
||||
description = option_description(description, *names, hidden:)
|
||||
process_option(*names, description, type: :switch, hidden:) unless disable
|
||||
|
||||
env, counterpart = env
|
||||
if env && @non_global_processed_options.any?
|
||||
affix = counterpart ? " and `#{counterpart}` is passed." : "."
|
||||
description += " Enabled by default if `$HOMEBREW_#{env.upcase}` is set#{affix}"
|
||||
end
|
||||
if replacement || disable
|
||||
description += " (#{disable ? "disabled" : "deprecated"}#{"; replaced by #{replacement}" if replacement})"
|
||||
end
|
||||
process_option(*names, description, type: :switch, hidden:) unless disable
|
||||
|
||||
@parser.public_send(method, *names, *wrap_option_desc(description)) do |value|
|
||||
# This odeprecated should stick around indefinitely.
|
||||
|
@ -31,7 +31,7 @@ module Homebrew
|
||||
sig { override.void }
|
||||
def run
|
||||
ENV.activate_extensions!
|
||||
T.cast(ENV, Superenv).deps = args.named.to_formulae if superenv?(nil)
|
||||
ENV.deps = args.named.to_formulae if superenv?(nil)
|
||||
ENV.setup_build_environment
|
||||
|
||||
shell = if args.plain?
|
||||
|
@ -73,11 +73,10 @@ module Homebrew
|
||||
description: "`install` prints output from commands as they are run. " \
|
||||
"`check` lists all missing dependencies."
|
||||
switch "--no-upgrade",
|
||||
env: :bundle_no_upgrade,
|
||||
description: "`install` does not run `brew upgrade` on outdated dependencies. " \
|
||||
"`check` does not check for outdated dependencies. " \
|
||||
"Note they may still be upgraded by `brew install` if needed. " \
|
||||
"This is enabled by default if `$HOMEBREW_BUNDLE_NO_UPGRADE` is set."
|
||||
"Note they may still be upgraded by `brew install` if needed.",
|
||||
env: :bundle_no_upgrade
|
||||
switch "--upgrade",
|
||||
description: "`install` runs `brew upgrade` on outdated dependencies, " \
|
||||
"even if `$HOMEBREW_BUNDLE_NO_UPGRADE` is set."
|
||||
@ -87,21 +86,18 @@ module Homebrew
|
||||
switch "--install",
|
||||
description: "Run `install` before continuing to other operations e.g. `exec`."
|
||||
switch "--services",
|
||||
env: :bundle_services,
|
||||
description: "Temporarily start services while running the `exec` or `sh` command. " \
|
||||
"This is enabled by default if `$HOMEBREW_BUNDLE_SERVICES` is set."
|
||||
description: "Temporarily start services while running the `exec` or `sh` command.",
|
||||
env: :bundle_services
|
||||
switch "-f", "--force",
|
||||
description: "`install` runs with `--force`/`--overwrite`. " \
|
||||
"`dump` overwrites an existing `Brewfile`. " \
|
||||
"`cleanup` actually performs its cleanup operations."
|
||||
switch "--cleanup",
|
||||
env: :bundle_install_cleanup,
|
||||
description: "`install` performs cleanup operation, same as running `cleanup --force`. " \
|
||||
"This is enabled by default if `$HOMEBREW_BUNDLE_INSTALL_CLEANUP` is set and " \
|
||||
"`--global` is passed."
|
||||
description: "`install` performs cleanup operation, same as running `cleanup --force`.",
|
||||
env: [:bundle_install_cleanup, "--global"]
|
||||
switch "--all",
|
||||
description: "`list` all dependencies."
|
||||
switch "--formula", "--brews",
|
||||
switch "--formula", "--formulae", "--brews",
|
||||
description: "`list`, `dump` or `cleanup` Homebrew formula dependencies."
|
||||
switch "--cask", "--casks",
|
||||
description: "`list`, `dump` or `cleanup` Homebrew cask dependencies."
|
||||
@ -114,14 +110,12 @@ module Homebrew
|
||||
switch "--vscode",
|
||||
description: "`list`, `dump` or `cleanup` VSCode (and forks/variants) extensions."
|
||||
switch "--no-vscode",
|
||||
env: :bundle_dump_no_vscode,
|
||||
description: "`dump` without VSCode (and forks/variants) extensions. " \
|
||||
"This is enabled by default if `$HOMEBREW_BUNDLE_DUMP_NO_VSCODE` is set."
|
||||
description: "`dump` without VSCode (and forks/variants) extensions.",
|
||||
env: :bundle_dump_no_vscode
|
||||
switch "--describe",
|
||||
env: :bundle_dump_describe,
|
||||
description: "`dump` adds a description comment above each line, unless the " \
|
||||
"dependency does not have a description. " \
|
||||
"This is enabled by default if `$HOMEBREW_BUNDLE_DUMP_DESCRIBE` is set."
|
||||
"dependency does not have a description.",
|
||||
env: :bundle_dump_describe
|
||||
switch "--no-restart",
|
||||
description: "`dump` does not add `restart_service` to formula lines."
|
||||
switch "--zap",
|
||||
@ -168,7 +162,7 @@ module Homebrew
|
||||
zap = args.zap?
|
||||
Homebrew::Bundle.upgrade_formulae = args.upgrade_formulae
|
||||
|
||||
no_type_args = !args.brews? && !args.casks? && !args.taps? && !args.mas? && !args.whalebrew? && !args.vscode?
|
||||
no_type_args = [args.formulae?, args.casks?, args.taps?, args.mas?, args.whalebrew?, args.vscode?].none?
|
||||
|
||||
if args.install?
|
||||
if [nil, "install", "upgrade"].include?(subcommand)
|
||||
@ -215,7 +209,7 @@ module Homebrew
|
||||
describe: args.describe?,
|
||||
no_restart: args.no_restart?,
|
||||
taps: args.taps? || no_type_args,
|
||||
brews: args.brews? || no_type_args,
|
||||
formulae: args.formulae? || no_type_args,
|
||||
casks: args.casks? || no_type_args,
|
||||
mas: args.mas? || no_type_args,
|
||||
whalebrew: args.whalebrew? || no_type_args,
|
||||
@ -228,7 +222,7 @@ module Homebrew
|
||||
require "bundle/commands/cleanup"
|
||||
Homebrew::Bundle::Commands::Cleanup.run(
|
||||
global:, file:, force:, zap:,
|
||||
brews: args.brews? || no_type_args,
|
||||
formulae: args.formulae? || no_type_args,
|
||||
casks: args.casks? || no_type_args,
|
||||
taps: args.taps? || no_type_args,
|
||||
vscode: args.vscode? || no_type_args
|
||||
@ -241,7 +235,7 @@ module Homebrew
|
||||
Homebrew::Bundle::Commands::List.run(
|
||||
global:,
|
||||
file:,
|
||||
brews: args.brews? || args.all? || no_type_args,
|
||||
formulae: args.formulae? || args.all? || no_type_args,
|
||||
casks: args.casks? || args.all?,
|
||||
taps: args.taps? || args.all?,
|
||||
mas: args.mas? || args.all?,
|
||||
@ -249,9 +243,9 @@ module Homebrew
|
||||
vscode: args.vscode? || args.all?,
|
||||
)
|
||||
when "add", "remove"
|
||||
# We intentionally omit the `s` from `brews`, `casks`, and `taps` for ease of handling later.
|
||||
# We intentionally omit the s from `brews`, `casks`, and `taps` for ease of handling later.
|
||||
type_hash = {
|
||||
brew: args.brews?,
|
||||
brew: args.formulae?,
|
||||
cask: args.casks?,
|
||||
tap: args.taps?,
|
||||
mas: args.mas?,
|
||||
@ -282,17 +276,7 @@ module Homebrew
|
||||
_subcommand, *named_args = args.named
|
||||
named_args
|
||||
when "sh"
|
||||
preferred_path = Utils::Shell.preferred_path(default: "/bin/bash")
|
||||
notice = unless Homebrew::EnvConfig.no_env_hints?
|
||||
<<~EOS
|
||||
Your shell has been configured to use a build environment from your `Brewfile`.
|
||||
This should help you build stuff.
|
||||
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
|
||||
When done, type `exit`.
|
||||
EOS
|
||||
end
|
||||
ENV["HOMEBREW_FORCE_API_AUTO_UPDATE"] = nil
|
||||
[Utils::Shell.shell_with_prompt("brew bundle", preferred_path:, notice:)]
|
||||
["sh"]
|
||||
when "env"
|
||||
["env"]
|
||||
end
|
||||
|
@ -18,8 +18,7 @@ module Homebrew
|
||||
|
||||
If any version of each formula argument is installed and no other options
|
||||
are passed, this command displays their actual runtime dependencies (similar
|
||||
to `brew linkage`), which may differ from the current versions' stated
|
||||
dependencies if the installed versions are outdated.
|
||||
to `brew linkage`), which may differ from a formula's declared dependencies.
|
||||
|
||||
*Note:* `--missing` and `--skip-recommended` have precedence over `--include-*`.
|
||||
EOS
|
||||
@ -92,26 +91,50 @@ module Homebrew
|
||||
raise UsageError, "`brew deps --arch=all` is not supported" if args.arch == "all"
|
||||
|
||||
os, arch = T.must(args.os_arch_combinations.first)
|
||||
all = args.eval_all?
|
||||
eval_all = args.eval_all?
|
||||
|
||||
Formulary.enable_factory_cache!
|
||||
|
||||
SimulateSystem.with(os:, arch:) do
|
||||
recursive = !args.direct?
|
||||
installed = args.installed? || dependents(args.named.to_formulae_and_casks).all?(&:any_version_installed?)
|
||||
@use_runtime_dependencies = true
|
||||
|
||||
@use_runtime_dependencies = installed && recursive &&
|
||||
!args.tree? &&
|
||||
!args.graph? &&
|
||||
!args.HEAD? &&
|
||||
!args.include_implicit? &&
|
||||
!args.include_build? &&
|
||||
!args.include_test? &&
|
||||
!args.include_optional? &&
|
||||
!args.skip_recommended? &&
|
||||
!args.missing? &&
|
||||
args.os.nil? &&
|
||||
args.arch.nil?
|
||||
installed = args.installed? || dependents(args.named.to_formulae_and_casks).all?(&:any_version_installed?)
|
||||
unless installed
|
||||
not_using_runtime_dependencies_reason = if args.installed?
|
||||
"not all the named formulae were installed"
|
||||
else
|
||||
"`--installed` was not passed"
|
||||
end
|
||||
|
||||
@use_runtime_dependencies = false
|
||||
end
|
||||
|
||||
%w[direct tree graph HEAD skip_recommended missing
|
||||
include_implicit include_build include_test include_optional].each do |arg|
|
||||
next unless args.public_send("#{arg}?")
|
||||
|
||||
not_using_runtime_dependencies_reason = "--#{arg.tr("_", "-")} was passed"
|
||||
|
||||
@use_runtime_dependencies = false
|
||||
end
|
||||
|
||||
%w[os arch].each do |arg|
|
||||
next if args.public_send(arg).nil?
|
||||
|
||||
not_using_runtime_dependencies_reason = "--#{arg.tr("_", "-")} was passed"
|
||||
|
||||
@use_runtime_dependencies = false
|
||||
end
|
||||
|
||||
if !@use_runtime_dependencies && !Homebrew::EnvConfig.no_env_hints?
|
||||
opoo <<~EOS
|
||||
`brew deps` is not the actual runtime dependencies because #{not_using_runtime_dependencies_reason}!
|
||||
This means dependencies may differ from a formula's declared dependencies.
|
||||
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
|
||||
EOS
|
||||
end
|
||||
|
||||
recursive = !args.direct?
|
||||
|
||||
if args.tree? || args.graph?
|
||||
dependents = if args.named.present?
|
||||
@ -141,9 +164,9 @@ module Homebrew
|
||||
|
||||
puts_deps_tree(dependents, recursive:)
|
||||
return
|
||||
elsif all
|
||||
elsif eval_all
|
||||
puts_deps(sorted_dependents(
|
||||
Formula.all(eval_all: args.eval_all?) + Cask::Cask.all(eval_all: args.eval_all?),
|
||||
Formula.all(eval_all:) + Cask::Cask.all(eval_all:),
|
||||
), recursive:)
|
||||
return
|
||||
elsif !args.no_named? && args.for_each?
|
||||
|
@ -25,7 +25,8 @@ module Homebrew
|
||||
"it is interpreted as a regular expression."
|
||||
switch "--eval-all",
|
||||
description: "Evaluate all available formulae and casks, whether installed or not, to search their " \
|
||||
"descriptions. Implied if `$HOMEBREW_EVAL_ALL` is set."
|
||||
"descriptions.",
|
||||
env: :eval_all
|
||||
switch "--formula", "--formulae",
|
||||
description: "Treat all named arguments as formulae."
|
||||
switch "--cask", "--casks",
|
||||
@ -47,7 +48,7 @@ module Homebrew
|
||||
end
|
||||
|
||||
if search_type.present?
|
||||
if !args.eval_all? && !Homebrew::EnvConfig.eval_all? && Homebrew::EnvConfig.no_install_from_api?
|
||||
if !args.eval_all? && Homebrew::EnvConfig.no_install_from_api?
|
||||
raise UsageError, "`brew desc --search` needs `--eval-all` passed or `$HOMEBREW_EVAL_ALL` set!"
|
||||
end
|
||||
|
||||
|
@ -9,7 +9,7 @@ module Homebrew
|
||||
cmd_args do
|
||||
description <<~EOS
|
||||
Control Homebrew's developer mode. When developer mode is enabled,
|
||||
`brew update` will update Homebrew to the latest commit on the `master`
|
||||
`brew update` will update Homebrew to the latest commit on the `main`
|
||||
branch instead of the latest stable version along with some other behaviour changes.
|
||||
|
||||
`brew developer` [`state`]:
|
||||
@ -38,7 +38,7 @@ module Homebrew
|
||||
puts "However, `brew update` will update to the latest stable tag because " \
|
||||
"#{Tty.bold}HOMEBREW_UPDATE_TO_TAG#{Tty.reset} is set."
|
||||
else
|
||||
puts "`brew update` will update to the latest commit on the `master` branch."
|
||||
puts "`brew update` will update to the latest commit on the `main` branch."
|
||||
end
|
||||
else
|
||||
puts "`brew update` will update to the latest stable tag."
|
||||
|
@ -1,4 +1,4 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "abstract_command"
|
||||
@ -6,6 +6,7 @@ require "formula"
|
||||
require "fetch"
|
||||
require "cask/download"
|
||||
require "retryable_download"
|
||||
require "download_queue"
|
||||
|
||||
module Homebrew
|
||||
module Cmd
|
||||
@ -69,15 +70,16 @@ module Homebrew
|
||||
named_args [:formula, :cask], min: 1
|
||||
end
|
||||
|
||||
sig { returns(Integer) }
|
||||
def concurrency
|
||||
@concurrency ||= args.concurrency&.to_i || 1
|
||||
@concurrency ||= T.let(args.concurrency&.to_i || 1, T.nilable(Integer))
|
||||
end
|
||||
|
||||
sig { returns(DownloadQueue) }
|
||||
def download_queue
|
||||
@download_queue ||= begin
|
||||
require "download_queue"
|
||||
@download_queue ||= T.let(begin
|
||||
DownloadQueue.new(concurrency)
|
||||
end
|
||||
end, T.nilable(DownloadQueue))
|
||||
end
|
||||
|
||||
class Spinner
|
||||
@ -96,8 +98,8 @@ module Homebrew
|
||||
|
||||
sig { void }
|
||||
def initialize
|
||||
@start = Time.now
|
||||
@i = 0
|
||||
@start = T.let(Time.now, Time)
|
||||
@i = T.let(0, Integer)
|
||||
end
|
||||
|
||||
sig { returns(String) }
|
||||
@ -136,7 +138,7 @@ module Homebrew
|
||||
bucket.each do |formula_or_cask|
|
||||
case formula_or_cask
|
||||
when Formula
|
||||
formula = T.cast(formula_or_cask, Formula)
|
||||
formula = formula_or_cask
|
||||
ref = formula.loaded_from_api? ? formula.full_name : formula.path
|
||||
|
||||
os_arch_combinations.each do |os, arch|
|
||||
@ -189,7 +191,9 @@ module Homebrew
|
||||
|
||||
next if fetched_bottle
|
||||
|
||||
fetch_downloadable(formula.resource)
|
||||
if (resource = formula.resource)
|
||||
fetch_downloadable(resource)
|
||||
end
|
||||
|
||||
formula.resources.each do |r|
|
||||
fetch_downloadable(r)
|
||||
@ -231,7 +235,7 @@ module Homebrew
|
||||
end
|
||||
else
|
||||
spinner = Spinner.new
|
||||
remaining_downloads = downloads.dup
|
||||
remaining_downloads = downloads.dup.to_a
|
||||
previous_pending_line_count = 0
|
||||
|
||||
begin
|
||||
@ -332,10 +336,13 @@ module Homebrew
|
||||
|
||||
private
|
||||
|
||||
sig { returns(T::Hash[T.any(Resource, Bottle, Cask::Download), Concurrent::Promises::Future]) }
|
||||
def downloads
|
||||
@downloads ||= {}
|
||||
@downloads ||= T.let({}, T.nilable(T::Hash[T.any(Resource, Bottle, Cask::Download),
|
||||
Concurrent::Promises::Future]))
|
||||
end
|
||||
|
||||
sig { params(downloadable: T.any(Resource, Bottle, Cask::Download)).void }
|
||||
def fetch_downloadable(downloadable)
|
||||
downloads[downloadable] ||= begin
|
||||
tries = args.retry? ? {} : { tries: 1 }
|
||||
|
@ -1,4 +1,4 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "abstract_command"
|
||||
@ -18,7 +18,7 @@ module Homebrew
|
||||
class Info < AbstractCommand
|
||||
VALID_DAYS = %w[30 90 365].freeze
|
||||
VALID_FORMULA_CATEGORIES = %w[install install-on-request build-error].freeze
|
||||
VALID_CATEGORIES = (VALID_FORMULA_CATEGORIES + %w[cask-install os-version]).freeze
|
||||
VALID_CATEGORIES = T.let((VALID_FORMULA_CATEGORIES + %w[cask-install os-version]).freeze, T::Array[String])
|
||||
|
||||
cmd_args do
|
||||
description <<~EOS
|
||||
@ -57,7 +57,7 @@ module Homebrew
|
||||
switch "--eval-all",
|
||||
depends_on: "--json",
|
||||
description: "Evaluate all available formulae and casks, whether installed or not, to print their " \
|
||||
"JSON. Implied if `$HOMEBREW_EVAL_ALL` is set."
|
||||
"JSON."
|
||||
switch "--variations",
|
||||
depends_on: "--json",
|
||||
description: "Include the variations hash in each formula's JSON output."
|
||||
@ -96,14 +96,15 @@ module Homebrew
|
||||
end
|
||||
|
||||
print_analytics
|
||||
elsif args.json
|
||||
all = args.eval_all?
|
||||
|
||||
print_json(all)
|
||||
elsif (json = args.json)
|
||||
print_json(json, args.eval_all?)
|
||||
elsif args.github?
|
||||
raise FormulaOrCaskUnspecifiedError if args.no_named?
|
||||
|
||||
exec_browser(*args.named.to_formulae_and_casks.map { |f| github_info(f) })
|
||||
exec_browser(*args.named.to_formulae_and_casks.map do |formula_keg_or_cask|
|
||||
formula_or_cask = T.cast(formula_keg_or_cask, T.any(Formula, Cask::Cask))
|
||||
github_info(formula_or_cask)
|
||||
end)
|
||||
elsif args.no_named?
|
||||
print_statistics
|
||||
else
|
||||
@ -111,6 +112,7 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
sig { params(remote: String, path: String).returns(String) }
|
||||
def github_remote_path(remote, path)
|
||||
if remote =~ %r{^(?:https?://|git(?:@|://))github\.com[:/](.+)/(.+?)(?:\.git)?$}
|
||||
"https://github.com/#{Regexp.last_match(1)}/#{Regexp.last_match(2)}/blob/HEAD/#{path}"
|
||||
@ -175,6 +177,7 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
sig { params(version: T.any(T::Boolean, String)).returns(Symbol) }
|
||||
def json_version(version)
|
||||
version_hash = {
|
||||
true => :default,
|
||||
@ -187,16 +190,16 @@ module Homebrew
|
||||
version_hash[version]
|
||||
end
|
||||
|
||||
sig { params(all: T::Boolean).void }
|
||||
def print_json(all)
|
||||
raise FormulaOrCaskUnspecifiedError if !(all || args.installed?) && args.no_named?
|
||||
sig { params(json: T.any(T::Boolean, String), eval_all: T::Boolean).void }
|
||||
def print_json(json, eval_all)
|
||||
raise FormulaOrCaskUnspecifiedError if !(eval_all || args.installed?) && args.no_named?
|
||||
|
||||
json = case json_version(args.json)
|
||||
json = case json_version(json)
|
||||
when :v1, :default
|
||||
raise UsageError, "Cannot specify `--cask` when using `--json=v1`!" if args.cask?
|
||||
|
||||
formulae = if all
|
||||
Formula.all(eval_all: args.eval_all?).sort
|
||||
formulae = if eval_all
|
||||
Formula.all(eval_all:).sort
|
||||
elsif args.installed?
|
||||
Formula.installed.sort
|
||||
else
|
||||
@ -210,10 +213,10 @@ module Homebrew
|
||||
end
|
||||
when :v2
|
||||
formulae, casks = T.let(
|
||||
if all
|
||||
if eval_all
|
||||
[
|
||||
Formula.all(eval_all: args.eval_all?).sort,
|
||||
Cask::Cask.all(eval_all: args.eval_all?).sort_by(&:full_name),
|
||||
Formula.all(eval_all:).sort,
|
||||
Cask::Cask.all(eval_all:).sort_by(&:full_name),
|
||||
]
|
||||
elsif args.installed?
|
||||
[Formula.installed.sort, Cask::Caskroom.casks.sort_by(&:full_name)]
|
||||
@ -240,25 +243,31 @@ module Homebrew
|
||||
puts JSON.pretty_generate(json)
|
||||
end
|
||||
|
||||
sig { params(formula_or_cask: T.any(Formula, Cask::Cask)).returns(String) }
|
||||
def github_info(formula_or_cask)
|
||||
return formula_or_cask.path if formula_or_cask.tap.blank? || formula_or_cask.tap.remote.blank?
|
||||
|
||||
path = case formula_or_cask
|
||||
when Formula
|
||||
formula = formula_or_cask
|
||||
formula.path.relative_path_from(T.must(formula.tap).path)
|
||||
tap = formula.tap
|
||||
return formula.path.to_s if tap.blank? || tap.remote.blank?
|
||||
|
||||
formula.path.relative_path_from(tap.path)
|
||||
when Cask::Cask
|
||||
cask = formula_or_cask
|
||||
tap = cask.tap
|
||||
return cask.sourcefile_path.to_s if tap.blank? || tap.remote.blank?
|
||||
|
||||
if cask.sourcefile_path.blank? || cask.sourcefile_path.extname != ".rb"
|
||||
return "#{cask.tap.default_remote}/blob/HEAD/#{cask.tap.relative_cask_path(cask.token)}"
|
||||
return "#{tap.default_remote}/blob/HEAD/#{tap.relative_cask_path(cask.token)}"
|
||||
end
|
||||
|
||||
cask.sourcefile_path.relative_path_from(cask.tap.path)
|
||||
cask.sourcefile_path.relative_path_from(tap.path)
|
||||
end
|
||||
|
||||
github_remote_path(formula_or_cask.tap.remote, path)
|
||||
github_remote_path(tap.remote, path.to_s)
|
||||
end
|
||||
|
||||
sig { params(formula: Formula).void }
|
||||
def info_formula(formula)
|
||||
specs = []
|
||||
|
||||
@ -356,6 +365,7 @@ module Homebrew
|
||||
Utils::Analytics.formula_output(formula, args:)
|
||||
end
|
||||
|
||||
sig { params(dependencies: T::Array[Dependency]).returns(String) }
|
||||
def decorate_dependencies(dependencies)
|
||||
deps_status = dependencies.map do |dep|
|
||||
if dep.satisfied?([])
|
||||
@ -367,6 +377,7 @@ module Homebrew
|
||||
deps_status.join(", ")
|
||||
end
|
||||
|
||||
sig { params(requirements: T::Array[Requirement]).returns(String) }
|
||||
def decorate_requirements(requirements)
|
||||
req_status = requirements.map do |req|
|
||||
req_s = req.display_s
|
||||
@ -375,12 +386,14 @@ module Homebrew
|
||||
req_status.join(", ")
|
||||
end
|
||||
|
||||
sig { params(dep: Dependency).returns(String) }
|
||||
def dep_display_s(dep)
|
||||
return dep.name if dep.option_tags.empty?
|
||||
|
||||
"#{dep.name} #{dep.option_tags.map { |o| "--#{o}" }.join(" ")}"
|
||||
end
|
||||
|
||||
sig { params(cask: Cask::Cask).void }
|
||||
def info_cask(cask)
|
||||
require "cask/info"
|
||||
|
||||
|
@ -33,8 +33,8 @@ module Homebrew
|
||||
description: "If brewing fails, open an interactive debugging session with access to IRB " \
|
||||
"or a shell inside the temporary build directory."
|
||||
switch "--display-times",
|
||||
env: :display_install_times,
|
||||
description: "Print install times for each package at the end of the run."
|
||||
description: "Print install times for each package at the end of the run.",
|
||||
env: :display_install_times
|
||||
switch "-f", "--force",
|
||||
description: "Install formulae without checking for previously installed keg-only or " \
|
||||
"non-migrated versions. When installing casks, overwrite existing files " \
|
||||
@ -44,9 +44,9 @@ module Homebrew
|
||||
switch "-n", "--dry-run",
|
||||
description: "Show what would be installed, but do not actually install anything."
|
||||
switch "--ask",
|
||||
env: :ask,
|
||||
description: "Ask for confirmation before downloading and installing formulae. " \
|
||||
"Print bottles and dependencies download size and install size."
|
||||
"Print download and install sizes of bottles and dependencies.",
|
||||
env: :ask
|
||||
[
|
||||
[:switch, "--formula", "--formulae", {
|
||||
description: "Treat all named arguments as formulae.",
|
||||
@ -310,9 +310,7 @@ module Homebrew
|
||||
Install.perform_preinstall_checks_once
|
||||
Install.check_cc_argv(args.cc)
|
||||
|
||||
Install.ask_formulae(installed_formulae, args: args) if args.ask?
|
||||
|
||||
Install.install_formulae(
|
||||
formulae_installer = Install.formula_installers(
|
||||
installed_formulae,
|
||||
installed_on_request: !args.as_dependency?,
|
||||
installed_as_dependency: args.as_dependency?,
|
||||
@ -338,9 +336,10 @@ module Homebrew
|
||||
skip_link: args.skip_link?,
|
||||
)
|
||||
|
||||
Upgrade.check_installed_dependents(
|
||||
dependants = Upgrade.dependants(
|
||||
installed_formulae,
|
||||
flags: args.flags_only,
|
||||
ask: args.ask?,
|
||||
installed_on_request: !args.as_dependency?,
|
||||
force_bottle: args.force_bottle?,
|
||||
build_from_source_formulae: args.build_from_source_formulae,
|
||||
@ -354,6 +353,28 @@ module Homebrew
|
||||
dry_run: args.dry_run?,
|
||||
)
|
||||
|
||||
# Main block: if asking the user is enabled, show dependency and size information.
|
||||
Install.ask_formulae(formulae_installer, dependants, args: args) if args.ask?
|
||||
|
||||
Install.install_formulae(formulae_installer,
|
||||
dry_run: args.dry_run?,
|
||||
verbose: args.verbose?)
|
||||
|
||||
Upgrade.upgrade_dependents(
|
||||
dependants, installed_formulae,
|
||||
flags: args.flags_only,
|
||||
dry_run: args.dry_run?,
|
||||
force_bottle: args.force_bottle?,
|
||||
build_from_source_formulae: args.build_from_source_formulae,
|
||||
interactive: args.interactive?,
|
||||
keep_tmp: args.keep_tmp?,
|
||||
debug_symbols: args.debug_symbols?,
|
||||
force: args.force?,
|
||||
debug: args.debug?,
|
||||
quiet: args.quiet?,
|
||||
verbose: args.verbose?
|
||||
)
|
||||
|
||||
Cleanup.periodic_clean!(dry_run: args.dry_run?)
|
||||
|
||||
Homebrew.messages.display_messages(display_times: args.display_times?)
|
||||
|
23
Library/Homebrew/cmd/mcp-server.rb
Normal file
23
Library/Homebrew/cmd/mcp-server.rb
Normal file
@ -0,0 +1,23 @@
|
||||
# typed: strong
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "abstract_command"
|
||||
require "shell_command"
|
||||
|
||||
module Homebrew
|
||||
module Cmd
|
||||
class McpServerCmd < AbstractCommand
|
||||
# This is a shell command as MCP servers need a faster startup time
|
||||
# than a normal Homebrew Ruby command allows.
|
||||
include ShellCommand
|
||||
|
||||
cmd_args do
|
||||
description <<~EOS
|
||||
Starts the Homebrew MCP (Model Context Protocol) server.
|
||||
EOS
|
||||
switch "-d", "--debug", description: "Enable debug logging to stderr."
|
||||
switch "--ping", description: "Start the server, act as if receiving a ping and then exit.", hidden: true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
14
Library/Homebrew/cmd/mcp-server.sh
Normal file
14
Library/Homebrew/cmd/mcp-server.sh
Normal file
@ -0,0 +1,14 @@
|
||||
# Documentation defined in Library/Homebrew/cmd/mcp-server.rb
|
||||
|
||||
# This is a shell command as MCP servers need a faster startup time
|
||||
# than a normal Homebrew Ruby command allows.
|
||||
|
||||
# HOMEBREW_LIBRARY is set by brew.sh
|
||||
# HOMEBREW_BREW_FILE is set by extend/ENV/super.rb
|
||||
# shellcheck disable=SC2154
|
||||
homebrew-mcp-server() {
|
||||
source "${HOMEBREW_LIBRARY}/Homebrew/utils/ruby.sh"
|
||||
setup-ruby-path
|
||||
export HOMEBREW_VERSION
|
||||
"${HOMEBREW_RUBY_PATH}" "-r${HOMEBREW_LIBRARY}/Homebrew/mcp_server.rb" -e "Homebrew::McpServer.new.run" "$@"
|
||||
}
|
@ -18,7 +18,8 @@ module Homebrew
|
||||
description: "Show options for formulae that are currently installed."
|
||||
switch "--eval-all",
|
||||
description: "Evaluate all available formulae and casks, whether installed or not, to show their " \
|
||||
"options."
|
||||
"options.",
|
||||
env: :eval_all
|
||||
flag "--command=",
|
||||
description: "Show options for the specified <command>."
|
||||
|
||||
@ -29,10 +30,10 @@ module Homebrew
|
||||
|
||||
sig { override.void }
|
||||
def run
|
||||
all = args.eval_all?
|
||||
eval_all = args.eval_all?
|
||||
|
||||
if all
|
||||
puts_options(Formula.all(eval_all: args.eval_all?).sort)
|
||||
if eval_all
|
||||
puts_options(Formula.all(eval_all:).sort)
|
||||
elsif args.installed?
|
||||
puts_options(Formula.installed.sort)
|
||||
elsif args.command.present?
|
||||
|
@ -32,12 +32,10 @@ module Homebrew
|
||||
"formula is outdated. Otherwise, the repository's HEAD will only be checked for " \
|
||||
"updates when a new stable or development version has been released."
|
||||
switch "-g", "--greedy",
|
||||
env: :upgrade_greedy,
|
||||
description: "Also include outdated casks with `auto_updates true` or `version :latest`."
|
||||
|
||||
description: "Also include outdated casks with `auto_updates true` or `version :latest`.",
|
||||
env: :upgrade_greedy
|
||||
switch "--greedy-latest",
|
||||
description: "Also include outdated casks including those with `version :latest`."
|
||||
|
||||
switch "--greedy-auto-updates",
|
||||
description: "Also include outdated casks including those with `auto_updates true`."
|
||||
|
||||
|
@ -25,7 +25,7 @@ module Homebrew
|
||||
if f.pinned?
|
||||
opoo "#{f.name} already pinned"
|
||||
elsif !f.pinnable?
|
||||
onoe "#{f.name} not installed"
|
||||
ofail "#{f.name} not installed"
|
||||
else
|
||||
f.pin
|
||||
end
|
||||
|
@ -24,8 +24,8 @@ module Homebrew
|
||||
switch "--syntax",
|
||||
description: "Syntax-check all of Homebrew's Ruby files (if no <tap> is passed)."
|
||||
switch "--eval-all",
|
||||
description: "Evaluate all available formulae and casks, whether installed or not. " \
|
||||
"Implied if `$HOMEBREW_EVAL_ALL` is set."
|
||||
description: "Evaluate all available formulae and casks, whether installed or not.",
|
||||
env: :eval_all
|
||||
switch "--no-simulate",
|
||||
description: "Don't simulate other system configurations when checking formulae and casks."
|
||||
|
||||
@ -49,7 +49,7 @@ module Homebrew
|
||||
options[:os_arch_combinations] = args.os_arch_combinations if args.os || args.arch
|
||||
|
||||
taps = if args.no_named?
|
||||
if !args.eval_all? && !Homebrew::EnvConfig.eval_all?
|
||||
unless args.eval_all?
|
||||
raise UsageError, "`brew readall` needs a tap or `--eval-all` passed or `$HOMEBREW_EVAL_ALL` set!"
|
||||
end
|
||||
|
||||
|
@ -32,8 +32,8 @@ module Homebrew
|
||||
description: "If brewing fails, open an interactive debugging session with access to IRB " \
|
||||
"or a shell inside the temporary build directory."
|
||||
switch "--display-times",
|
||||
env: :display_install_times,
|
||||
description: "Print install times for each package at the end of the run."
|
||||
description: "Print install times for each package at the end of the run.",
|
||||
env: :display_install_times
|
||||
switch "-f", "--force",
|
||||
description: "Install without checking for previously installed keg-only or " \
|
||||
"non-migrated versions."
|
||||
@ -41,7 +41,7 @@ module Homebrew
|
||||
description: "Print the verification and post-install steps."
|
||||
switch "--ask",
|
||||
description: "Ask for confirmation before downloading and upgrading formulae. " \
|
||||
"Print bottles and dependencies download size, install and net install size.",
|
||||
"Print download, install and net install sizes of bottles and dependencies.",
|
||||
env: :ask
|
||||
[
|
||||
[:switch, "--formula", "--formulae", { description: "Treat all named arguments as formulae." }],
|
||||
@ -130,16 +130,13 @@ module Homebrew
|
||||
unless formulae.empty?
|
||||
Install.perform_preinstall_checks_once
|
||||
|
||||
# If asking the user is enabled, show dependency and size information.
|
||||
Install.ask_formulae(formulae, args: args) if args.ask?
|
||||
|
||||
formulae.each do |formula|
|
||||
install_context = formulae.map do |formula|
|
||||
if formula.pinned?
|
||||
onoe "#{formula.full_name} is pinned. You must unpin it to reinstall."
|
||||
next
|
||||
end
|
||||
Migrator.migrate_if_needed(formula, force: args.force?)
|
||||
Homebrew::Reinstall.reinstall_formula(
|
||||
Homebrew::Reinstall.build_install_context(
|
||||
formula,
|
||||
flags: args.flags_only,
|
||||
force_bottle: args.force_bottle?,
|
||||
@ -153,12 +150,12 @@ module Homebrew
|
||||
verbose: args.verbose?,
|
||||
git: args.git?,
|
||||
)
|
||||
Cleanup.install_formula_clean!(formula)
|
||||
end
|
||||
|
||||
Upgrade.check_installed_dependents(
|
||||
dependants = Upgrade.dependants(
|
||||
formulae,
|
||||
flags: args.flags_only,
|
||||
ask: args.ask?,
|
||||
force_bottle: args.force_bottle?,
|
||||
build_from_source_formulae: args.build_from_source_formulae,
|
||||
interactive: args.interactive?,
|
||||
@ -169,6 +166,43 @@ module Homebrew
|
||||
quiet: args.quiet?,
|
||||
verbose: args.verbose?,
|
||||
)
|
||||
|
||||
formulae_installer = install_context.map(&:formula_installer)
|
||||
|
||||
# Main block: if asking the user is enabled, show dependency and size information.
|
||||
Install.ask_formulae(formulae_installer, dependants, args: args) if args.ask?
|
||||
|
||||
install_context.each do |f|
|
||||
Homebrew::Reinstall.reinstall_formula(
|
||||
f,
|
||||
flags: args.flags_only,
|
||||
force_bottle: args.force_bottle?,
|
||||
build_from_source_formulae: args.build_from_source_formulae,
|
||||
interactive: args.interactive?,
|
||||
keep_tmp: args.keep_tmp?,
|
||||
debug_symbols: args.debug_symbols?,
|
||||
force: args.force?,
|
||||
debug: args.debug?,
|
||||
quiet: args.quiet?,
|
||||
verbose: args.verbose?,
|
||||
git: args.git?,
|
||||
)
|
||||
Cleanup.install_formula_clean!(f.formula)
|
||||
end
|
||||
|
||||
Upgrade.upgrade_dependents(
|
||||
dependants, formulae,
|
||||
flags: args.flags_only,
|
||||
force_bottle: args.force_bottle?,
|
||||
build_from_source_formulae: args.build_from_source_formulae,
|
||||
interactive: args.interactive?,
|
||||
keep_tmp: args.keep_tmp?,
|
||||
debug_symbols: args.debug_symbols?,
|
||||
force: args.force?,
|
||||
debug: args.debug?,
|
||||
quiet: args.quiet?,
|
||||
verbose: args.verbose?
|
||||
)
|
||||
end
|
||||
|
||||
if casks.any?
|
||||
|
@ -40,7 +40,8 @@ module Homebrew
|
||||
switch "--eval-all",
|
||||
depends_on: "--desc",
|
||||
description: "Evaluate all available formulae and casks, whether installed or not, to search their " \
|
||||
"descriptions. Implied if `$HOMEBREW_EVAL_ALL` is set."
|
||||
"descriptions.",
|
||||
env: :eval_all
|
||||
switch "--pull-request",
|
||||
description: "Search for GitHub pull requests containing <text>."
|
||||
switch "--open",
|
||||
@ -70,7 +71,7 @@ module Homebrew
|
||||
string_or_regex = Search.query_regexp(query)
|
||||
|
||||
if args.desc?
|
||||
if !args.eval_all? && !Homebrew::EnvConfig.eval_all? && Homebrew::EnvConfig.no_install_from_api?
|
||||
if !args.eval_all? && Homebrew::EnvConfig.no_install_from_api?
|
||||
raise UsageError, "`brew search --desc` needs `--eval-all` passed or `$HOMEBREW_EVAL_ALL` set!"
|
||||
end
|
||||
|
||||
|
@ -13,18 +13,20 @@ module Homebrew
|
||||
description <<~EOS
|
||||
Valid shells: bash|csh|fish|pwsh|sh|tcsh|zsh
|
||||
|
||||
Print export statements. When run in a shell, this installation of Homebrew will be added to your `PATH`, `MANPATH`, and `INFOPATH`.
|
||||
Print export statements. When run in a shell, this installation of Homebrew will be added to your
|
||||
`$PATH`, `$MANPATH`, and `$INFOPATH`.
|
||||
|
||||
The variables `$HOMEBREW_PREFIX`, `$HOMEBREW_CELLAR` and `$HOMEBREW_REPOSITORY` are also exported to avoid
|
||||
querying them multiple times.
|
||||
To help guarantee idempotence, this command produces no output when Homebrew's `bin` and `sbin` directories
|
||||
are first and second respectively in your `PATH`. Consider adding evaluation of this command's output to
|
||||
are first and second respectively in your `$PATH`. Consider adding evaluation of this command's output to
|
||||
your dotfiles (e.g. `~/.bash_profile` or ~/.zprofile` on macOS and ~/.bashrc` or ~/.zshrc` on Linux) with:
|
||||
`eval "$(brew shellenv)"`
|
||||
|
||||
The shell can be specified explicitly with a supported shell name parameter. Unknown shells will output
|
||||
POSIX exports.
|
||||
EOS
|
||||
|
||||
named_args :shell
|
||||
end
|
||||
end
|
||||
|
@ -63,6 +63,8 @@ module Homebrew
|
||||
puts info
|
||||
else
|
||||
info = ""
|
||||
default_branches = %w[main master].freeze
|
||||
|
||||
taps.each_with_index do |tap, i|
|
||||
puts unless i.zero?
|
||||
info = "#{tap}: "
|
||||
@ -79,7 +81,7 @@ module Homebrew
|
||||
info += "\norigin: #{tap.remote}" if tap.remote != tap.default_remote
|
||||
info += "\nHEAD: #{tap.git_head || "(none)"}"
|
||||
info += "\nlast commit: #{tap.git_last_commit || "never"}"
|
||||
info += "\nbranch: #{tap.git_branch || "(none)"}" if tap.git_branch != "master"
|
||||
info += "\nbranch: #{tap.git_branch || "(none)"}" if default_branches.exclude?(tap.git_branch)
|
||||
else
|
||||
info += "Not installed"
|
||||
end
|
||||
|
@ -33,16 +33,14 @@ module Homebrew
|
||||
"integration.",
|
||||
replacement: false,
|
||||
disable: true
|
||||
switch "--[no-]force-auto-update",
|
||||
hidden: true
|
||||
switch "--custom-remote",
|
||||
description: "Install or change a tap with a custom remote. Useful for mirrors."
|
||||
switch "--repair",
|
||||
description: "Add missing symlinks to tap manpages and shell completions. Correct git remote " \
|
||||
"refs for any taps where upstream HEAD branch has been renamed."
|
||||
switch "--eval-all",
|
||||
description: "Evaluate all the formulae, casks and aliases in the new tap to check validity. " \
|
||||
"Implied if `$HOMEBREW_EVAL_ALL` is set."
|
||||
description: "Evaluate all formulae, casks and aliases in the new tap to check their validity.",
|
||||
env: :eval_all
|
||||
switch "-f", "--force",
|
||||
description: "Force install core taps even under API mode."
|
||||
|
||||
@ -64,7 +62,7 @@ module Homebrew
|
||||
tap.install clone_target: args.named.second,
|
||||
custom_remote: args.custom_remote?,
|
||||
quiet: args.quiet?,
|
||||
verify: args.eval_all? || Homebrew::EnvConfig.eval_all?,
|
||||
verify: args.eval_all?,
|
||||
force: args.force?
|
||||
rescue Tap::InvalidNameError, TapRemoteMismatchError, TapNoCustomRemoteError => e
|
||||
odie e
|
||||
|
@ -1,4 +1,4 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "abstract_command"
|
||||
@ -39,13 +39,15 @@ module Homebrew
|
||||
|
||||
private
|
||||
|
||||
sig { void }
|
||||
def auto_update_header
|
||||
@auto_update_header ||= begin
|
||||
@auto_update_header ||= T.let(begin
|
||||
ohai "Auto-updated Homebrew!" if args.auto_update?
|
||||
true
|
||||
end
|
||||
end, T.nilable(T::Boolean))
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def output_update_report
|
||||
# Run `brew update` (again) if we've got a linuxbrew-core CoreTap
|
||||
if CoreTap.instance.installed? && CoreTap.instance.linuxbrew_core? &&
|
||||
@ -293,14 +295,17 @@ module Homebrew
|
||||
EOS
|
||||
end
|
||||
|
||||
sig { returns(String) }
|
||||
def no_changes_message
|
||||
"No changes to formulae or casks."
|
||||
end
|
||||
|
||||
sig { params(revision: String).returns(String) }
|
||||
def shorten_revision(revision)
|
||||
Utils.popen_read("git", "-C", HOMEBREW_REPOSITORY, "rev-parse", "--short", revision).chomp
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def tap_or_untap_core_taps_if_necessary
|
||||
return if ENV["HOMEBREW_UPDATE_TEST"]
|
||||
|
||||
@ -320,10 +325,11 @@ module Homebrew
|
||||
return if (HOMEBREW_PREFIX/".homebrewdocker").exist?
|
||||
|
||||
tap_output_header_printed = T.let(false, T::Boolean)
|
||||
default_branches = %w[main master].freeze
|
||||
[CoreTap.instance, CoreCaskTap.instance].each do |tap|
|
||||
next unless tap.installed?
|
||||
|
||||
if tap.git_branch == "master" &&
|
||||
if default_branches.include?(tap.git_branch) &&
|
||||
(Date.parse(T.must(tap.git_repository.last_commit_date)) <= Date.today.prev_month)
|
||||
ohai "#{tap.name} is old and unneeded, untapping to save space..."
|
||||
tap.uninstall
|
||||
@ -339,6 +345,7 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
sig { params(repository: Pathname).void }
|
||||
def link_completions_manpages_and_docs(repository = HOMEBREW_REPOSITORY)
|
||||
command = "brew update"
|
||||
Utils::Link.link_completions(repository, command)
|
||||
@ -351,10 +358,12 @@ module Homebrew
|
||||
EOS
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def migrate_gcc_dependents_if_needed
|
||||
# do nothing
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def analytics_message
|
||||
return if Utils::Analytics.messages_displayed?
|
||||
return if Utils::Analytics.no_message_output?
|
||||
@ -384,6 +393,7 @@ module Homebrew
|
||||
Utils::Analytics.messages_displayed! if $stdout.tty?
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def donation_message
|
||||
return if Settings.read("donationmessage") == "true"
|
||||
|
||||
@ -394,6 +404,7 @@ module Homebrew
|
||||
Settings.write "donationmessage", true if $stdout.tty?
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def install_from_api_message
|
||||
return if Settings.read("installfromapimessage") == "true"
|
||||
|
||||
@ -418,30 +429,38 @@ require "extend/os/cmd/update-report"
|
||||
|
||||
class Reporter
|
||||
class ReporterRevisionUnsetError < RuntimeError
|
||||
sig { params(var_name: String).void }
|
||||
def initialize(var_name)
|
||||
super "#{var_name} is unset!"
|
||||
end
|
||||
end
|
||||
|
||||
sig {
|
||||
params(tap: Tap, api_names_txt: T.nilable(Pathname), api_names_before_txt: T.nilable(Pathname),
|
||||
api_dir_prefix: T.nilable(Pathname)).void
|
||||
}
|
||||
def initialize(tap, api_names_txt: nil, api_names_before_txt: nil, api_dir_prefix: nil)
|
||||
@tap = tap
|
||||
|
||||
# This is slightly involved/weird but all the #report logic is shared so it's worth it.
|
||||
if installed_from_api?(api_names_txt, api_names_before_txt, api_dir_prefix)
|
||||
@api_names_txt = api_names_txt
|
||||
@api_names_before_txt = api_names_before_txt
|
||||
@api_dir_prefix = api_dir_prefix
|
||||
@api_names_txt = T.let(api_names_txt, T.nilable(Pathname))
|
||||
@api_names_before_txt = T.let(api_names_before_txt, T.nilable(Pathname))
|
||||
@api_dir_prefix = T.let(api_dir_prefix, T.nilable(Pathname))
|
||||
else
|
||||
initial_revision_var = "HOMEBREW_UPDATE_BEFORE#{tap.repository_var_suffix}"
|
||||
@initial_revision = ENV[initial_revision_var].to_s
|
||||
@initial_revision = T.let(ENV[initial_revision_var].to_s, String)
|
||||
raise ReporterRevisionUnsetError, initial_revision_var if @initial_revision.empty?
|
||||
|
||||
current_revision_var = "HOMEBREW_UPDATE_AFTER#{tap.repository_var_suffix}"
|
||||
@current_revision = ENV[current_revision_var].to_s
|
||||
@current_revision = T.let(ENV[current_revision_var].to_s, String)
|
||||
raise ReporterRevisionUnsetError, current_revision_var if @current_revision.empty?
|
||||
end
|
||||
|
||||
@report = T.let(nil, T.nilable(T::Hash[Symbol, T::Array[String]]))
|
||||
end
|
||||
|
||||
sig { params(auto_update: T::Boolean).returns(T::Hash[Symbol, T::Array[String]]) }
|
||||
def report(auto_update: false)
|
||||
return @report if @report
|
||||
|
||||
@ -482,9 +501,9 @@ class Reporter
|
||||
case status
|
||||
when "A", "D"
|
||||
full_name = tap.formula_file_to_name(src)
|
||||
name = full_name.split("/").last
|
||||
name = T.must(full_name.split("/").last)
|
||||
new_tap = tap.tap_migrations[name]
|
||||
@report[status.to_sym] << full_name unless new_tap
|
||||
@report[T.must(status).to_sym] << full_name unless new_tap
|
||||
when "M"
|
||||
name = tap.formula_file_to_name(src)
|
||||
|
||||
@ -584,6 +603,7 @@ class Reporter
|
||||
@report
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def updated?
|
||||
if installed_from_api?
|
||||
diff.present?
|
||||
@ -592,9 +612,10 @@ class Reporter
|
||||
end
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def migrate_tap_migration
|
||||
(report[:D] + report[:DC]).each do |full_name|
|
||||
name = full_name.split("/").last
|
||||
(Array(report[:D]) + Array(report[:DC])).each do |full_name|
|
||||
name = T.must(full_name.split("/").last)
|
||||
new_tap_name = tap.tap_migrations[name]
|
||||
next if new_tap_name.nil? # skip if not in tap_migrations list.
|
||||
|
||||
@ -609,7 +630,7 @@ class Reporter
|
||||
end
|
||||
|
||||
# This means it is a cask
|
||||
if report[:DC].include? full_name
|
||||
if Array(report[:DC]).include? full_name
|
||||
next unless (HOMEBREW_PREFIX/"Caskroom"/new_name).exist?
|
||||
|
||||
new_tap = Tap.fetch(new_tap_name)
|
||||
@ -675,12 +696,14 @@ class Reporter
|
||||
end
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def migrate_cask_rename
|
||||
Cask::Caskroom.casks.each do |cask|
|
||||
Cask::Migrator.migrate_if_needed(cask)
|
||||
end
|
||||
end
|
||||
|
||||
sig { params(force: T::Boolean, verbose: T::Boolean).void }
|
||||
def migrate_formula_rename(force:, verbose:)
|
||||
Formula.installed.each do |formula|
|
||||
next unless Migrator.needs_migration?(formula)
|
||||
@ -704,14 +727,36 @@ class Reporter
|
||||
|
||||
private
|
||||
|
||||
attr_reader :tap, :initial_revision, :current_revision, :api_names_txt, :api_names_before_txt, :api_dir_prefix
|
||||
sig { returns(Tap) }
|
||||
attr_reader :tap
|
||||
|
||||
sig { returns(String) }
|
||||
attr_reader :initial_revision
|
||||
|
||||
sig { returns(String) }
|
||||
attr_reader :current_revision
|
||||
|
||||
sig { returns(T.nilable(Pathname)) }
|
||||
attr_reader :api_names_txt
|
||||
|
||||
sig { returns(T.nilable(Pathname)) }
|
||||
attr_reader :api_names_before_txt
|
||||
|
||||
sig { returns(T.nilable(Pathname)) }
|
||||
attr_reader :api_dir_prefix
|
||||
|
||||
sig {
|
||||
params(api_names_txt: T.nilable(Pathname), api_names_before_txt: T.nilable(Pathname),
|
||||
api_dir_prefix: T.nilable(Pathname)).returns(T::Boolean)
|
||||
}
|
||||
def installed_from_api?(api_names_txt = @api_names_txt, api_names_before_txt = @api_names_before_txt,
|
||||
api_dir_prefix = @api_dir_prefix)
|
||||
!api_names_txt.nil? && !api_names_before_txt.nil? && !api_dir_prefix.nil?
|
||||
end
|
||||
|
||||
sig { returns(String) }
|
||||
def diff
|
||||
@diff ||= T.let(nil, T.nilable(String))
|
||||
@diff ||= if installed_from_api?
|
||||
# Hack `git diff` output with regexes to look like `git diff-tree` output.
|
||||
# Yes, I know this is a bit filthy but it saves duplicating the #report logic.
|
||||
@ -719,12 +764,14 @@ class Reporter
|
||||
header_regex = /^(---|\+\+\+) /
|
||||
add_delete_characters = ["+", "-"].freeze
|
||||
|
||||
api_dir_prefix_basename = T.must(api_dir_prefix).basename
|
||||
|
||||
diff_output.lines.filter_map do |line|
|
||||
next if line.match?(header_regex)
|
||||
next unless add_delete_characters.include?(line[0])
|
||||
|
||||
line.sub(/^\+/, "A #{api_dir_prefix.basename}/")
|
||||
.sub(/^-/, "D #{api_dir_prefix.basename}/")
|
||||
line.sub(/^\+/, "A #{api_dir_prefix_basename}/")
|
||||
.sub(/^-/, "D #{api_dir_prefix_basename}/")
|
||||
.sub(/$/, ".rb")
|
||||
.chomp
|
||||
end.join("\n")
|
||||
@ -738,28 +785,33 @@ class Reporter
|
||||
end
|
||||
|
||||
class ReporterHub
|
||||
sig { returns(T::Array[Reporter]) }
|
||||
attr_reader :reporters
|
||||
|
||||
sig { void }
|
||||
def initialize
|
||||
@hash = {}
|
||||
@reporters = []
|
||||
@hash = T.let({}, T::Hash[Symbol, T::Array[String]])
|
||||
@reporters = T.let([], T::Array[Reporter])
|
||||
end
|
||||
|
||||
sig { params(key: Symbol).returns(T::Array[String]) }
|
||||
def select_formula_or_cask(key)
|
||||
@hash.fetch(key, [])
|
||||
end
|
||||
|
||||
sig { params(reporter: Reporter, auto_update: T::Boolean).void }
|
||||
def add(reporter, auto_update: false)
|
||||
@reporters << reporter
|
||||
report = reporter.report(auto_update:).delete_if { |_k, v| v.empty? }
|
||||
@hash.update(report) { |_key, oldval, newval| oldval.concat(newval) }
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def empty?
|
||||
@hash.empty?
|
||||
end
|
||||
|
||||
sig { params(auto_update: T::Boolean).void }
|
||||
def dump(auto_update: false)
|
||||
unless Homebrew::EnvConfig.no_update_report_new?
|
||||
dump_new_formula_report
|
||||
@ -814,22 +866,41 @@ class ReporterHub
|
||||
|
||||
private
|
||||
|
||||
sig { void }
|
||||
def dump_new_formula_report
|
||||
formulae = select_formula_or_cask(:A).sort.reject { |name| installed?(name) }
|
||||
return if formulae.blank?
|
||||
|
||||
output_dump_formula_or_cask_report "New Formulae", formulae
|
||||
ohai "New Formulae"
|
||||
formulae.each do |formula|
|
||||
if (desc = description(formula))
|
||||
puts "#{formula}: #{desc}"
|
||||
else
|
||||
puts formula
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def dump_new_cask_report
|
||||
return if Homebrew::SimulateSystem.simulating_or_running_on_linux?
|
||||
return unless Cask::Caskroom.any_casks_installed?
|
||||
|
||||
casks = select_formula_or_cask(:AC).sort.filter_map do |name|
|
||||
name.split("/").last unless cask_installed?(name)
|
||||
end
|
||||
return if casks.blank?
|
||||
|
||||
output_dump_formula_or_cask_report "New Casks", casks
|
||||
ohai "New Casks"
|
||||
casks.each do |cask|
|
||||
if (desc = cask_description(cask))
|
||||
puts "#{cask}: #{desc}"
|
||||
else
|
||||
puts cask
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def dump_deleted_formula_report
|
||||
formulae = select_formula_or_cask(:D).sort.filter_map do |name|
|
||||
pretty_uninstalled(name) if installed?(name)
|
||||
@ -838,40 +909,84 @@ class ReporterHub
|
||||
output_dump_formula_or_cask_report "Deleted Installed Formulae", formulae
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def dump_deleted_cask_report
|
||||
return if Homebrew::SimulateSystem.simulating_or_running_on_linux?
|
||||
|
||||
casks = select_formula_or_cask(:DC).sort.filter_map do |name|
|
||||
name = name.split("/").last
|
||||
name = T.must(name.split("/").last)
|
||||
pretty_uninstalled(name) if cask_installed?(name)
|
||||
end
|
||||
|
||||
output_dump_formula_or_cask_report "Deleted Installed Casks", casks
|
||||
end
|
||||
|
||||
sig { params(title: String, formulae_or_casks: T::Array[String]).void }
|
||||
def output_dump_formula_or_cask_report(title, formulae_or_casks)
|
||||
return if formulae_or_casks.blank?
|
||||
|
||||
ohai title, Formatter.columns(formulae_or_casks.sort)
|
||||
end
|
||||
|
||||
sig { params(formula: String).returns(T::Boolean) }
|
||||
def installed?(formula)
|
||||
(HOMEBREW_CELLAR/formula.split("/").last).directory?
|
||||
end
|
||||
|
||||
sig { params(formula: String).returns(T::Boolean) }
|
||||
def outdated?(formula)
|
||||
Formula[formula].outdated?
|
||||
rescue FormulaUnavailableError
|
||||
false
|
||||
end
|
||||
|
||||
sig { params(cask: String).returns(T::Boolean) }
|
||||
def cask_installed?(cask)
|
||||
(Cask::Caskroom.path/cask).directory?
|
||||
end
|
||||
|
||||
sig { params(cask: String).returns(T::Boolean) }
|
||||
def cask_outdated?(cask)
|
||||
Cask::CaskLoader.load(cask).outdated?
|
||||
rescue Cask::CaskError
|
||||
false
|
||||
end
|
||||
|
||||
sig { returns(T::Array[T.untyped]) }
|
||||
def all_formula_json
|
||||
return @all_formula_json if @all_formula_json
|
||||
|
||||
@all_formula_json = T.let(nil, T.nilable(T::Array[T.untyped]))
|
||||
all_formula_json, = Homebrew::API.fetch_json_api_file "formula.jws.json"
|
||||
all_formula_json = T.cast(all_formula_json, T::Array[T.untyped])
|
||||
@all_formula_json = all_formula_json
|
||||
end
|
||||
|
||||
sig { returns(T::Array[T.untyped]) }
|
||||
def all_cask_json
|
||||
return @all_cask_json if @all_cask_json
|
||||
|
||||
@all_cask_json = T.let(nil, T.nilable(T::Array[T.untyped]))
|
||||
all_cask_json, = Homebrew::API.fetch_json_api_file "cask.jws.json"
|
||||
all_cask_json = T.cast(all_cask_json, T::Array[T.untyped])
|
||||
@all_cask_json = all_cask_json
|
||||
end
|
||||
|
||||
sig { params(formula: String).returns(T.nilable(String)) }
|
||||
def description(formula)
|
||||
return if Homebrew::EnvConfig.no_install_from_api?
|
||||
|
||||
all_formula_json.find { |f| f["name"] == formula }
|
||||
&.fetch("desc", nil)
|
||||
&.presence
|
||||
end
|
||||
|
||||
sig { params(cask: String).returns(T.nilable(String)) }
|
||||
def cask_description(cask)
|
||||
return if Homebrew::EnvConfig.no_install_from_api?
|
||||
|
||||
all_cask_json.find { |f| f["token"] == cask }
|
||||
&.fetch("desc", nil)
|
||||
&.presence
|
||||
end
|
||||
end
|
||||
|
@ -54,9 +54,10 @@ git_init_if_necessary() {
|
||||
fi
|
||||
git config remote.origin.url "${HOMEBREW_BREW_GIT_REMOTE}"
|
||||
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
|
||||
git config fetch.prune true
|
||||
git fetch --force --tags origin
|
||||
git remote set-head origin --auto >/dev/null
|
||||
git reset --hard origin/master
|
||||
git reset --hard origin/HEAD
|
||||
SKIP_FETCH_BREW_REPOSITORY=1
|
||||
set +e
|
||||
trap - EXIT
|
||||
@ -77,9 +78,10 @@ git_init_if_necessary() {
|
||||
fi
|
||||
git config remote.origin.url "${HOMEBREW_CORE_GIT_REMOTE}"
|
||||
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
|
||||
git fetch --force origin refs/heads/master:refs/remotes/origin/master
|
||||
git config fetch.prune true
|
||||
git fetch --force origin
|
||||
git remote set-head origin --auto >/dev/null
|
||||
git reset --hard origin/master
|
||||
git reset --hard origin/HEAD
|
||||
SKIP_FETCH_CORE_REPOSITORY=1
|
||||
set +e
|
||||
trap - EXIT
|
||||
@ -110,7 +112,7 @@ upstream_branch() {
|
||||
upstream_branch="$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null)"
|
||||
fi
|
||||
upstream_branch="${upstream_branch#refs/remotes/origin/}"
|
||||
[[ -z "${upstream_branch}" ]] && upstream_branch="master"
|
||||
[[ -z "${upstream_branch}" ]] && upstream_branch="main"
|
||||
echo "${upstream_branch}"
|
||||
}
|
||||
|
||||
@ -242,7 +244,7 @@ merge_or_rebase() {
|
||||
Could not 'git stash' in ${DIR}!
|
||||
Please stash/commit manually if you need to keep your changes or, if not, run:
|
||||
cd ${DIR}
|
||||
git reset --hard origin/master
|
||||
git reset --hard origin/HEAD
|
||||
EOS
|
||||
fi
|
||||
git reset --hard "${QUIET_ARGS[@]}"
|
||||
@ -250,6 +252,14 @@ EOS
|
||||
fi
|
||||
|
||||
INITIAL_BRANCH="$(git symbolic-ref --short HEAD 2>/dev/null)"
|
||||
MAIN_MIGRATION_REQUIRED=
|
||||
if [[ "${INITIAL_BRANCH}" == "master" &&
|
||||
("${DIR}" == "${HOMEBREW_REPOSITORY}" || "${DIR}" == "${HOMEBREW_CORE_REPOSITORY}" || "${DIR}" == "${HOMEBREW_CASK_REPOSITORY}") ]]
|
||||
then
|
||||
# Migrate master to main for Homebrew/brew, homebrew-core or homebrew-cask
|
||||
MAIN_MIGRATION_REQUIRED="1"
|
||||
fi
|
||||
|
||||
if [[ -n "${UPSTREAM_TAG}" ]] ||
|
||||
[[ "${INITIAL_BRANCH}" != "${UPSTREAM_BRANCH}" && -n "${INITIAL_BRANCH}" ]]
|
||||
then
|
||||
@ -260,10 +270,12 @@ EOS
|
||||
then
|
||||
git checkout --force "${UPSTREAM_BRANCH}" "${QUIET_ARGS[@]}"
|
||||
else
|
||||
if [[ -n "${UPSTREAM_TAG}" && "${UPSTREAM_BRANCH}" != "master" ]] &&
|
||||
[[ "${INITIAL_BRANCH}" != "master" ]]
|
||||
if [[ -n "${UPSTREAM_TAG}" && "${UPSTREAM_BRANCH}" != "master" && "${UPSTREAM_BRANCH}" != "main" ]] &&
|
||||
[[ "${INITIAL_BRANCH}" != "master" && "${INITIAL_BRANCH}" != "main" ]]
|
||||
then
|
||||
git branch --force "master" "origin/master" "${QUIET_ARGS[@]}"
|
||||
local detected_upstream_branch
|
||||
detected_upstream_branch="$(upstream_branch)"
|
||||
git branch --force "${detected_upstream_branch}" "origin/${detected_upstream_branch}" "${QUIET_ARGS[@]}"
|
||||
fi
|
||||
|
||||
git checkout --force -B "${UPSTREAM_BRANCH}" "${REMOTE_REF}" "${QUIET_ARGS[@]}"
|
||||
@ -313,7 +325,7 @@ EOS
|
||||
|
||||
if [[ -n "${HOMEBREW_NO_UPDATE_CLEANUP}" ]]
|
||||
then
|
||||
if [[ "${INITIAL_BRANCH}" != "${UPSTREAM_BRANCH}" && -n "${INITIAL_BRANCH}" ]] &&
|
||||
if [[ -z "${MAIN_MIGRATION_REQUIRED}" && "${INITIAL_BRANCH}" != "${UPSTREAM_BRANCH}" && -n "${INITIAL_BRANCH}" ]] &&
|
||||
[[ ! "${INITIAL_BRANCH}" =~ ^v[0-9]+\.[0-9]+\.[0-9]|stable$ ]]
|
||||
then
|
||||
git checkout "${INITIAL_BRANCH}" "${QUIET_ARGS[@]}"
|
||||
@ -324,6 +336,11 @@ EOS
|
||||
pop_stash_message
|
||||
fi
|
||||
|
||||
if [[ -n "${MAIN_MIGRATION_REQUIRED}" && -n "$(git config branch.main.remote 2>/dev/null || true)" ]]
|
||||
then
|
||||
git branch -d "${QUIET_ARGS[@]}" master
|
||||
fi
|
||||
|
||||
trap - SIGINT
|
||||
}
|
||||
|
||||
@ -541,7 +558,8 @@ EOS
|
||||
echo "HOMEBREW_CORE_GIT_REMOTE set: using ${HOMEBREW_CORE_GIT_REMOTE} as the Homebrew/homebrew-core Git remote."
|
||||
git remote set-url origin "${HOMEBREW_CORE_GIT_REMOTE}"
|
||||
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
|
||||
git fetch --force origin refs/heads/master:refs/remotes/origin/master
|
||||
git config fetch.prune true
|
||||
git fetch --force origin
|
||||
SKIP_FETCH_CORE_REPOSITORY=1
|
||||
fi
|
||||
|
||||
@ -642,9 +660,9 @@ EOS
|
||||
UPDATING_MESSAGE_SHOWN=1
|
||||
fi
|
||||
|
||||
# The upstream repository's default branch may not be master;
|
||||
# The upstream repository's default branch may not be main or master;
|
||||
# check refs/remotes/origin/HEAD to see what the default
|
||||
# origin branch name is, and use that. If not set, fall back to "master".
|
||||
# origin branch name is, and use that. If not set, fall back to "main".
|
||||
# the refspec ensures that the default upstream branch gets updated
|
||||
(
|
||||
UPSTREAM_REPOSITORY_URL="$(git config remote.origin.url)"
|
||||
@ -664,6 +682,16 @@ EOS
|
||||
UPSTREAM_REPOSITORY_TOKEN="${BASH_REMATCH[1]#*:}"
|
||||
fi
|
||||
|
||||
MAIN_MIGRATION_REQUIRED=
|
||||
if [[ "${UPSTREAM_BRANCH_DIR}" == "master" &&
|
||||
("${DIR}" == "${HOMEBREW_REPOSITORY}" || "${DIR}" == "${HOMEBREW_CORE_REPOSITORY}" || "${DIR}" == "${HOMEBREW_CASK_REPOSITORY}") ]]
|
||||
then
|
||||
# Migrate master to main for Homebrew/brew, homebrew-core or homebrew-cask
|
||||
MAIN_MIGRATION_REQUIRED=1
|
||||
UPSTREAM_BRANCH_DIR="main"
|
||||
declare UPSTREAM_BRANCH"${TAP_VAR}"="main"
|
||||
fi
|
||||
|
||||
if [[ -n "${UPSTREAM_REPOSITORY}" ]]
|
||||
then
|
||||
# UPSTREAM_REPOSITORY_TOKEN is parsed (if exists) from UPSTREAM_REPOSITORY_URL
|
||||
@ -725,32 +753,59 @@ EOS
|
||||
local tmp_failure_file="${DIR}/.git/TMP_FETCH_FAILURES"
|
||||
rm -f "${tmp_failure_file}"
|
||||
|
||||
if [[ -n "${HOMEBREW_UPDATE_AUTO}" ]]
|
||||
if ! git fetch --tags --force "${QUIET_ARGS[@]}" origin \
|
||||
"refs/heads/${UPSTREAM_BRANCH_DIR}:refs/remotes/origin/${UPSTREAM_BRANCH_DIR}" 2>>"${tmp_failure_file}"
|
||||
then
|
||||
git fetch --tags --force "${QUIET_ARGS[@]}" origin \
|
||||
"refs/heads/${UPSTREAM_BRANCH_DIR}:refs/remotes/origin/${UPSTREAM_BRANCH_DIR}" 2>/dev/null
|
||||
else
|
||||
# Capture stderr to tmp_failure_file
|
||||
if ! git fetch --tags --force "${QUIET_ARGS[@]}" origin \
|
||||
"refs/heads/${UPSTREAM_BRANCH_DIR}:refs/remotes/origin/${UPSTREAM_BRANCH_DIR}" 2>>"${tmp_failure_file}"
|
||||
if [[ -f "${tmp_failure_file}" ]]
|
||||
then
|
||||
# Reprint fetch errors to stderr
|
||||
[[ -f "${tmp_failure_file}" ]] && cat "${tmp_failure_file}" 1>&2
|
||||
|
||||
if [[ "${UPSTREAM_SHA_HTTP_CODE}" == "404" ]]
|
||||
local git_errors
|
||||
git_errors="$(cat "${tmp_failure_file}")"
|
||||
# Attempt migration from master to main branch.
|
||||
if [[ "${git_errors}" == "fatal: couldn't find remote ref refs/heads/master" ]]
|
||||
then
|
||||
TAP="${DIR#"${HOMEBREW_LIBRARY}"/Taps/}"
|
||||
echo "${TAP} does not exist! Run \`brew untap ${TAP}\` to remove it." >>"${update_failed_file}"
|
||||
else
|
||||
echo "Fetching ${DIR} failed!" >>"${update_failed_file}"
|
||||
|
||||
if [[ -f "${tmp_failure_file}" ]] &&
|
||||
[[ "$(cat "${tmp_failure_file}")" == "fatal: couldn't find remote ref refs/heads/${UPSTREAM_BRANCH_DIR}" ]]
|
||||
if git fetch --tags --force "${QUIET_ARGS[@]}" origin \
|
||||
"refs/heads/main:refs/remotes/origin/main" 2>>"${tmp_failure_file}"
|
||||
then
|
||||
echo "${DIR}" >>"${missing_remote_ref_dirs_file}"
|
||||
rm -f "${DIR}/.git/refs/remotes/origin/HEAD" "${DIR}/.git/refs/remotes/origin/master"
|
||||
UPSTREAM_BRANCH_DIR="$(upstream_branch)"
|
||||
declare UPSTREAM_BRANCH"${TAP_VAR}"="${UPSTREAM_BRANCH_DIR}"
|
||||
git branch -m master main "${QUIET_ARGS[@]}"
|
||||
git branch -u origin/main main "${QUIET_ARGS[@]}"
|
||||
rm -f "${tmp_failure_file}"
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -f "${tmp_failure_file}"
|
||||
fi
|
||||
|
||||
# Don't output errors if HOMEBREW_UPDATE_AUTO is set.
|
||||
if [[ -n "${HOMEBREW_UPDATE_AUTO}" ]]
|
||||
then
|
||||
exit
|
||||
fi
|
||||
|
||||
# Reprint fetch errors to stderr
|
||||
[[ -n "${git_errors}" ]] && echo "${git_errors}" 1>&2
|
||||
|
||||
if [[ "${UPSTREAM_SHA_HTTP_CODE}" == "404" ]]
|
||||
then
|
||||
TAP="${DIR#"${HOMEBREW_LIBRARY}"/Taps/}"
|
||||
echo "${TAP} does not exist! Run \`brew untap ${TAP}\` to remove it." >>"${update_failed_file}"
|
||||
else
|
||||
echo "Fetching ${DIR} failed!" >>"${update_failed_file}"
|
||||
|
||||
if [[ -f "${tmp_failure_file}" ]] &&
|
||||
[[ "$(cat "${tmp_failure_file}")" == "fatal: couldn't find remote ref refs/heads/${UPSTREAM_BRANCH_DIR}" ]]
|
||||
then
|
||||
echo "${DIR}" >>"${missing_remote_ref_dirs_file}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n "${MAIN_MIGRATION_REQUIRED}" ]]
|
||||
then
|
||||
git remote set-head origin --auto >/dev/null
|
||||
fi
|
||||
|
||||
rm -f "${tmp_failure_file}"
|
||||
|
@ -29,8 +29,8 @@ module Homebrew
|
||||
description: "If brewing fails, open an interactive debugging session with access to IRB " \
|
||||
"or a shell inside the temporary build directory."
|
||||
switch "--display-times",
|
||||
env: :display_install_times,
|
||||
description: "Print install times for each package at the end of the run."
|
||||
description: "Print install times for each package at the end of the run.",
|
||||
env: :display_install_times
|
||||
switch "-f", "--force",
|
||||
description: "Install formulae without checking for previously installed keg-only or " \
|
||||
"non-migrated versions. When installing casks, overwrite existing files " \
|
||||
@ -41,7 +41,7 @@ module Homebrew
|
||||
description: "Show what would be upgraded, but do not actually upgrade anything."
|
||||
switch "--ask",
|
||||
description: "Ask for confirmation before downloading and upgrading formulae. " \
|
||||
"Print bottles and dependencies download size, install and net install size.",
|
||||
"Print download, install and net install sizes of bottles and dependencies.",
|
||||
env: :ask
|
||||
[
|
||||
[:switch, "--formula", "--formulae", {
|
||||
@ -220,10 +220,7 @@ module Homebrew
|
||||
|
||||
Install.perform_preinstall_checks_once
|
||||
|
||||
# Main block: if asking the user is enabled, show dependency and size information.
|
||||
Install.ask_formulae(formulae_to_install, args: args) if args.ask?
|
||||
|
||||
Upgrade.upgrade_formulae(
|
||||
formulae_installer = Upgrade.formula_installers(
|
||||
formulae_to_install,
|
||||
flags: args.flags_only,
|
||||
dry_run: args.dry_run?,
|
||||
@ -239,10 +236,35 @@ module Homebrew
|
||||
verbose: args.verbose?,
|
||||
)
|
||||
|
||||
Upgrade.check_installed_dependents(
|
||||
return false if formulae_installer.blank?
|
||||
|
||||
dependants = Upgrade.dependants(
|
||||
formulae_to_install,
|
||||
flags: args.flags_only,
|
||||
dry_run: args.dry_run?,
|
||||
ask: args.ask?,
|
||||
force_bottle: args.force_bottle?,
|
||||
build_from_source_formulae: args.build_from_source_formulae,
|
||||
interactive: args.interactive?,
|
||||
keep_tmp: args.keep_tmp?,
|
||||
debug_symbols: args.debug_symbols?,
|
||||
force: args.force?,
|
||||
debug: args.debug?,
|
||||
quiet: args.quiet?,
|
||||
verbose: args.verbose?,
|
||||
)
|
||||
|
||||
# Main block: if asking the user is enabled, show dependency and size information.
|
||||
Install.ask_formulae(formulae_installer, dependants, args: args) if args.ask?
|
||||
|
||||
Upgrade.upgrade_formulae(formulae_installer,
|
||||
dry_run: args.dry_run?,
|
||||
verbose: args.verbose?)
|
||||
|
||||
Upgrade.upgrade_dependents(
|
||||
dependants, formulae_to_install,
|
||||
flags: args.flags_only,
|
||||
dry_run: args.dry_run?,
|
||||
force_bottle: args.force_bottle?,
|
||||
build_from_source_formulae: args.build_from_source_formulae,
|
||||
interactive: args.interactive?,
|
||||
@ -251,7 +273,7 @@ module Homebrew
|
||||
force: args.force?,
|
||||
debug: args.debug?,
|
||||
quiet: args.quiet?,
|
||||
verbose: args.verbose?,
|
||||
verbose: args.verbose?
|
||||
)
|
||||
|
||||
true
|
||||
|
@ -36,7 +36,8 @@ module Homebrew
|
||||
description: "Only list formulae and casks that are not currently installed."
|
||||
switch "--eval-all",
|
||||
description: "Evaluate all available formulae and casks, whether installed or not, to show " \
|
||||
"their dependents."
|
||||
"their dependents.",
|
||||
env: :eval_all
|
||||
switch "--include-implicit",
|
||||
description: "Include formulae that have <formula> as an implicit dependency for " \
|
||||
"downloading and unpacking source files."
|
||||
@ -119,17 +120,17 @@ module Homebrew
|
||||
|
||||
deps
|
||||
else
|
||||
all = args.eval_all?
|
||||
eval_all = args.eval_all?
|
||||
|
||||
if !args.installed? && !(all || Homebrew::EnvConfig.eval_all?)
|
||||
if !args.installed? && !eval_all
|
||||
raise UsageError, "`brew uses` needs `--installed` or `--eval-all` passed or `$HOMEBREW_EVAL_ALL` set!"
|
||||
end
|
||||
|
||||
if show_formulae_and_casks || args.formula?
|
||||
deps += args.installed? ? Formula.installed : Formula.all(eval_all: args.eval_all?)
|
||||
deps += args.installed? ? Formula.installed : Formula.all(eval_all:)
|
||||
end
|
||||
if show_formulae_and_casks || args.cask?
|
||||
deps += args.installed? ? Cask::Caskroom.casks : Cask::Cask.all(eval_all: args.eval_all?)
|
||||
deps += args.installed? ? Cask::Caskroom.casks : Cask::Cask.all(eval_all:)
|
||||
end
|
||||
|
||||
if args.missing?
|
||||
|
@ -101,6 +101,7 @@ fetch() {
|
||||
local first_try=1
|
||||
local vendor_locations
|
||||
local temporary_path
|
||||
local curl_exit_code=0
|
||||
|
||||
curl_args=()
|
||||
|
||||
@ -149,19 +150,27 @@ fetch() {
|
||||
# HOMEBREW_CURL is set by brew.sh (and isn't misspelt here)
|
||||
# shellcheck disable=SC2153
|
||||
"${HOMEBREW_CURL}" "${curl_args[@]}" -C - "${url}" -o "${temporary_path}"
|
||||
if [[ $? -eq 33 ]]
|
||||
curl_exit_code="$?"
|
||||
if [[ "${curl_exit_code}" -eq 33 ]]
|
||||
then
|
||||
[[ -n "${HOMEBREW_QUIET}" ]] || echo "Trying a full download" >&2
|
||||
rm -f "${temporary_path}"
|
||||
"${HOMEBREW_CURL}" "${curl_args[@]}" "${url}" -o "${temporary_path}"
|
||||
curl_exit_code="$?"
|
||||
fi
|
||||
else
|
||||
"${HOMEBREW_CURL}" "${curl_args[@]}" "${url}" -o "${temporary_path}"
|
||||
curl_exit_code="$?"
|
||||
fi
|
||||
|
||||
[[ -f "${temporary_path}" ]] && break
|
||||
done
|
||||
|
||||
if [[ "${curl_exit_code}" -ne 0 ]]
|
||||
then
|
||||
rm -f "${temporary_path}"
|
||||
fi
|
||||
|
||||
if [[ ! -f "${temporary_path}" ]]
|
||||
then
|
||||
vendor_locations="$(printf " - %s\n" "${VENDOR_URLs[@]}")"
|
||||
|
@ -1,12 +1,12 @@
|
||||
{
|
||||
"$schema" : "https://json-schema.org/draft/2019-09/schema",
|
||||
"$id" : "http://spdx.org/rdf/terms/2.3",
|
||||
"title" : "SPDX 2.3",
|
||||
"title" : "SPDX 2.3.1-dev",
|
||||
"type" : "object",
|
||||
"properties" : {
|
||||
"$schema": {
|
||||
"type": "string",
|
||||
"description": "Reference the SPDX 2.3 JSON schema."
|
||||
"description": "Reference the SPDX 2.3.1 JSON schema."
|
||||
},
|
||||
"SPDXID" : {
|
||||
"type" : "string",
|
||||
@ -90,7 +90,7 @@
|
||||
"enum" : [ "SHA1", "BLAKE3", "SHA3-384", "SHA256", "SHA384", "BLAKE2b-512", "BLAKE2b-256", "SHA3-512", "MD2", "ADLER32", "MD4", "SHA3-256", "BLAKE2b-384", "SHA512", "MD6", "MD5", "SHA224" ]
|
||||
},
|
||||
"checksumValue" : {
|
||||
"description" : "The checksumValue property provides a lower case hexidecimal encoded digest value produced using a specific algorithm.",
|
||||
"description" : "The checksumValue property provides a lower case hexadecimal encoded digest value produced using a specific algorithm.",
|
||||
"type" : "string"
|
||||
}
|
||||
},
|
||||
@ -270,10 +270,10 @@
|
||||
}
|
||||
},
|
||||
"attributionTexts" : {
|
||||
"description" : "This field provides a place for the SPDX data creator to record acknowledgements that may be required to be communicated in some contexts. This is not meant to include the actual complete license text (see licenseConculded and licenseDeclared), and may or may not include copyright notices (see also copyrightText). The SPDX data creator may use this field to record other acknowledgements, such as particular clauses from license texts, which may be necessary or desirable to reproduce.",
|
||||
"description" : "This field provides a place for the SPDX data creator to record acknowledgements that may be required to be communicated in some contexts. This is not meant to include the actual complete license text (see licenseConcluded and licenseDeclared), and may or may not include copyright notices (see also copyrightText). The SPDX data creator may use this field to record other acknowledgements, such as particular clauses from license texts, which may be necessary or desirable to reproduce.",
|
||||
"type" : "array",
|
||||
"items" : {
|
||||
"description" : "This field provides a place for the SPDX data creator to record acknowledgements that may be required to be communicated in some contexts. This is not meant to include the actual complete license text (see licenseConculded and licenseDeclared), and may or may not include copyright notices (see also copyrightText). The SPDX data creator may use this field to record other acknowledgements, such as particular clauses from license texts, which may be necessary or desirable to reproduce.",
|
||||
"description" : "This field provides a place for the SPDX data creator to record acknowledgements that may be required to be communicated in some contexts. This is not meant to include the actual complete license text (see licenseConcluded and licenseDeclared), and may or may not include copyright notices (see also copyrightText). The SPDX data creator may use this field to record other acknowledgements, such as particular clauses from license texts, which may be necessary or desirable to reproduce.",
|
||||
"type" : "string"
|
||||
}
|
||||
},
|
||||
@ -293,7 +293,7 @@
|
||||
"enum" : [ "SHA1", "BLAKE3", "SHA3-384", "SHA256", "SHA384", "BLAKE2b-512", "BLAKE2b-256", "SHA3-512", "MD2", "ADLER32", "MD4", "SHA3-256", "BLAKE2b-384", "SHA512", "MD6", "MD5", "SHA224" ]
|
||||
},
|
||||
"checksumValue" : {
|
||||
"description" : "The checksumValue property provides a lower case hexidecimal encoded digest value produced using a specific algorithm.",
|
||||
"description" : "The checksumValue property provides a lower case hexadecimal encoded digest value produced using a specific algorithm.",
|
||||
"type" : "string"
|
||||
}
|
||||
},
|
||||
@ -375,10 +375,10 @@
|
||||
"type" : "string"
|
||||
},
|
||||
"licenseInfoFromFiles" : {
|
||||
"description" : "The licensing information that was discovered directly within the package. There will be an instance of this property for each distinct value of alllicenseInfoInFile properties of all files contained in the package.\n\nIf the licenseInfoFromFiles field is not present for a package and filesAnalyzed property for that same package is true or omitted, it implies an equivalent meaning to NOASSERTION.",
|
||||
"description" : "The licensing information that was discovered directly within the package. There will be an instance of this property for each distinct value of all licenseInfoInFile properties of all files contained in the package.\n\nIf the licenseInfoFromFiles field is not present for a package and filesAnalyzed property for that same package is true or omitted, it implies an equivalent meaning to NOASSERTION.",
|
||||
"type" : "array",
|
||||
"items" : {
|
||||
"description" : "License expression for licenseInfoFromFiles. See SPDX Annex D for the license expression syntax. The licensing information that was discovered directly within the package. There will be an instance of this property for each distinct value of alllicenseInfoInFile properties of all files contained in the package.\n\nIf the licenseInfoFromFiles field is not present for a package and filesAnalyzed property for that same package is true or omitted, it implies an equivalent meaning to NOASSERTION.",
|
||||
"description" : "License expression for licenseInfoFromFiles. See SPDX Annex D for the license expression syntax. The licensing information that was discovered directly within the package. There will be an instance of this property for each distinct value of all licenseInfoInFile properties of all files contained in the package.\n\nIf the licenseInfoFromFiles field is not present for a package and filesAnalyzed property for that same package is true or omitted, it implies an equivalent meaning to NOASSERTION.",
|
||||
"type" : "string"
|
||||
}
|
||||
},
|
||||
@ -417,7 +417,7 @@
|
||||
"primaryPackagePurpose" : {
|
||||
"description" : "This field provides information about the primary purpose of the identified package. Package Purpose is intrinsic to how the package is being used rather than the content of the package.",
|
||||
"type" : "string",
|
||||
"enum" : [ "OTHER", "INSTALL", "ARCHIVE", "FIRMWARE", "APPLICATION", "FRAMEWORK", "LIBRARY", "CONTAINER", "SOURCE", "DEVICE", "OPERATING_SYSTEM", "FILE" ]
|
||||
"enum" : [ "OTHER", "INSTALL", "ARCHIVE", "FIRMWARE", "APPLICATION", "FRAMEWORK", "LIBRARY", "CONTAINER", "SOURCE", "DEVICE", "OPERATING-SYSTEM", "FILE" ]
|
||||
},
|
||||
"releaseDate" : {
|
||||
"description" : "This field provides a place for recording the date the package was released.",
|
||||
@ -494,10 +494,10 @@
|
||||
}
|
||||
},
|
||||
"attributionTexts" : {
|
||||
"description" : "This field provides a place for the SPDX data creator to record acknowledgements that may be required to be communicated in some contexts. This is not meant to include the actual complete license text (see licenseConculded and licenseDeclared), and may or may not include copyright notices (see also copyrightText). The SPDX data creator may use this field to record other acknowledgements, such as particular clauses from license texts, which may be necessary or desirable to reproduce.",
|
||||
"description" : "This field provides a place for the SPDX data creator to record acknowledgements that may be required to be communicated in some contexts. This is not meant to include the actual complete license text (see licenseConcluded and licenseDeclared), and may or may not include copyright notices (see also copyrightText). The SPDX data creator may use this field to record other acknowledgements, such as particular clauses from license texts, which may be necessary or desirable to reproduce.",
|
||||
"type" : "array",
|
||||
"items" : {
|
||||
"description" : "This field provides a place for the SPDX data creator to record acknowledgements that may be required to be communicated in some contexts. This is not meant to include the actual complete license text (see licenseConculded and licenseDeclared), and may or may not include copyright notices (see also copyrightText). The SPDX data creator may use this field to record other acknowledgements, such as particular clauses from license texts, which may be necessary or desirable to reproduce.",
|
||||
"description" : "This field provides a place for the SPDX data creator to record acknowledgements that may be required to be communicated in some contexts. This is not meant to include the actual complete license text (see licenseConcluded and licenseDeclared), and may or may not include copyright notices (see also copyrightText). The SPDX data creator may use this field to record other acknowledgements, such as particular clauses from license texts, which may be necessary or desirable to reproduce.",
|
||||
"type" : "string"
|
||||
}
|
||||
},
|
||||
@ -514,7 +514,7 @@
|
||||
"enum" : [ "SHA1", "BLAKE3", "SHA3-384", "SHA256", "SHA384", "BLAKE2b-512", "BLAKE2b-256", "SHA3-512", "MD2", "ADLER32", "MD4", "SHA3-256", "BLAKE2b-384", "SHA512", "MD6", "MD5", "SHA224" ]
|
||||
},
|
||||
"checksumValue" : {
|
||||
"description" : "The checksumValue property provides a lower case hexidecimal encoded digest value produced using a specific algorithm.",
|
||||
"description" : "The checksumValue property provides a lower case hexadecimal encoded digest value produced using a specific algorithm.",
|
||||
"type" : "string"
|
||||
}
|
||||
},
|
||||
@ -624,10 +624,10 @@
|
||||
}
|
||||
},
|
||||
"attributionTexts" : {
|
||||
"description" : "This field provides a place for the SPDX data creator to record acknowledgements that may be required to be communicated in some contexts. This is not meant to include the actual complete license text (see licenseConculded and licenseDeclared), and may or may not include copyright notices (see also copyrightText). The SPDX data creator may use this field to record other acknowledgements, such as particular clauses from license texts, which may be necessary or desirable to reproduce.",
|
||||
"description" : "This field provides a place for the SPDX data creator to record acknowledgements that may be required to be communicated in some contexts. This is not meant to include the actual complete license text (see licenseConcluded and licenseDeclared), and may or may not include copyright notices (see also copyrightText). The SPDX data creator may use this field to record other acknowledgements, such as particular clauses from license texts, which may be necessary or desirable to reproduce.",
|
||||
"type" : "array",
|
||||
"items" : {
|
||||
"description" : "This field provides a place for the SPDX data creator to record acknowledgements that may be required to be communicated in some contexts. This is not meant to include the actual complete license text (see licenseConculded and licenseDeclared), and may or may not include copyright notices (see also copyrightText). The SPDX data creator may use this field to record other acknowledgements, such as particular clauses from license texts, which may be necessary or desirable to reproduce.",
|
||||
"description" : "This field provides a place for the SPDX data creator to record acknowledgements that may be required to be communicated in some contexts. This is not meant to include the actual complete license text (see licenseConcluded and licenseDeclared), and may or may not include copyright notices (see also copyrightText). The SPDX data creator may use this field to record other acknowledgements, such as particular clauses from license texts, which may be necessary or desirable to reproduce.",
|
||||
"type" : "string"
|
||||
}
|
||||
},
|
||||
@ -709,7 +709,7 @@
|
||||
}
|
||||
},
|
||||
"snippetFromFile" : {
|
||||
"description" : "SPDX ID for File. File containing the SPDX element (e.g. the file contaning a snippet).",
|
||||
"description" : "SPDX ID for File. File containing the SPDX element (e.g. the file containing a snippet).",
|
||||
"type" : "string"
|
||||
}
|
||||
},
|
||||
|
@ -1,11 +1,11 @@
|
||||
{
|
||||
"licenseListVersion": "3.26.0",
|
||||
"licenseListVersion": "3.27.0",
|
||||
"exceptions": [
|
||||
{
|
||||
"reference": "https://spdx.org/licenses/389-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/389-exception.json",
|
||||
"referenceNumber": 54,
|
||||
"referenceNumber": 36,
|
||||
"name": "389 Directory Server Exception",
|
||||
"licenseExceptionId": "389-exception",
|
||||
"seeAlso": [
|
||||
@ -17,7 +17,7 @@
|
||||
"reference": "https://spdx.org/licenses/Asterisk-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/Asterisk-exception.json",
|
||||
"referenceNumber": 25,
|
||||
"referenceNumber": 16,
|
||||
"name": "Asterisk exception",
|
||||
"licenseExceptionId": "Asterisk-exception",
|
||||
"seeAlso": [
|
||||
@ -29,7 +29,7 @@
|
||||
"reference": "https://spdx.org/licenses/Asterisk-linking-protocols-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/Asterisk-linking-protocols-exception.json",
|
||||
"referenceNumber": 42,
|
||||
"referenceNumber": 22,
|
||||
"name": "Asterisk linking protocols exception",
|
||||
"licenseExceptionId": "Asterisk-linking-protocols-exception",
|
||||
"seeAlso": [
|
||||
@ -40,7 +40,7 @@
|
||||
"reference": "https://spdx.org/licenses/Autoconf-exception-2.0.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/Autoconf-exception-2.0.json",
|
||||
"referenceNumber": 17,
|
||||
"referenceNumber": 2,
|
||||
"name": "Autoconf exception 2.0",
|
||||
"licenseExceptionId": "Autoconf-exception-2.0",
|
||||
"seeAlso": [
|
||||
@ -52,7 +52,7 @@
|
||||
"reference": "https://spdx.org/licenses/Autoconf-exception-3.0.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/Autoconf-exception-3.0.json",
|
||||
"referenceNumber": 20,
|
||||
"referenceNumber": 51,
|
||||
"name": "Autoconf exception 3.0",
|
||||
"licenseExceptionId": "Autoconf-exception-3.0",
|
||||
"seeAlso": [
|
||||
@ -63,7 +63,7 @@
|
||||
"reference": "https://spdx.org/licenses/Autoconf-exception-generic.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/Autoconf-exception-generic.json",
|
||||
"referenceNumber": 66,
|
||||
"referenceNumber": 73,
|
||||
"name": "Autoconf generic exception",
|
||||
"licenseExceptionId": "Autoconf-exception-generic",
|
||||
"seeAlso": [
|
||||
@ -77,7 +77,7 @@
|
||||
"reference": "https://spdx.org/licenses/Autoconf-exception-generic-3.0.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/Autoconf-exception-generic-3.0.json",
|
||||
"referenceNumber": 16,
|
||||
"referenceNumber": 40,
|
||||
"name": "Autoconf generic exception for GPL-3.0",
|
||||
"licenseExceptionId": "Autoconf-exception-generic-3.0",
|
||||
"seeAlso": [
|
||||
@ -88,7 +88,7 @@
|
||||
"reference": "https://spdx.org/licenses/Autoconf-exception-macro.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/Autoconf-exception-macro.json",
|
||||
"referenceNumber": 41,
|
||||
"referenceNumber": 63,
|
||||
"name": "Autoconf macro exception",
|
||||
"licenseExceptionId": "Autoconf-exception-macro",
|
||||
"seeAlso": [
|
||||
@ -101,7 +101,7 @@
|
||||
"reference": "https://spdx.org/licenses/Bison-exception-1.24.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/Bison-exception-1.24.json",
|
||||
"referenceNumber": 34,
|
||||
"referenceNumber": 56,
|
||||
"name": "Bison exception 1.24",
|
||||
"licenseExceptionId": "Bison-exception-1.24",
|
||||
"seeAlso": [
|
||||
@ -112,7 +112,7 @@
|
||||
"reference": "https://spdx.org/licenses/Bison-exception-2.2.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/Bison-exception-2.2.json",
|
||||
"referenceNumber": 50,
|
||||
"referenceNumber": 28,
|
||||
"name": "Bison exception 2.2",
|
||||
"licenseExceptionId": "Bison-exception-2.2",
|
||||
"seeAlso": [
|
||||
@ -123,7 +123,7 @@
|
||||
"reference": "https://spdx.org/licenses/Bootloader-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/Bootloader-exception.json",
|
||||
"referenceNumber": 67,
|
||||
"referenceNumber": 65,
|
||||
"name": "Bootloader Distribution Exception",
|
||||
"licenseExceptionId": "Bootloader-exception",
|
||||
"seeAlso": [
|
||||
@ -134,7 +134,7 @@
|
||||
"reference": "https://spdx.org/licenses/CGAL-linking-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/CGAL-linking-exception.json",
|
||||
"referenceNumber": 43,
|
||||
"referenceNumber": 74,
|
||||
"name": "CGAL Linking Exception",
|
||||
"licenseExceptionId": "CGAL-linking-exception",
|
||||
"seeAlso": [
|
||||
@ -146,7 +146,7 @@
|
||||
"reference": "https://spdx.org/licenses/Classpath-exception-2.0.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/Classpath-exception-2.0.json",
|
||||
"referenceNumber": 69,
|
||||
"referenceNumber": 67,
|
||||
"name": "Classpath exception 2.0",
|
||||
"licenseExceptionId": "Classpath-exception-2.0",
|
||||
"seeAlso": [
|
||||
@ -158,7 +158,7 @@
|
||||
"reference": "https://spdx.org/licenses/CLISP-exception-2.0.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/CLISP-exception-2.0.json",
|
||||
"referenceNumber": 1,
|
||||
"referenceNumber": 10,
|
||||
"name": "CLISP exception 2.0",
|
||||
"licenseExceptionId": "CLISP-exception-2.0",
|
||||
"seeAlso": [
|
||||
@ -169,7 +169,7 @@
|
||||
"reference": "https://spdx.org/licenses/cryptsetup-OpenSSL-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/cryptsetup-OpenSSL-exception.json",
|
||||
"referenceNumber": 53,
|
||||
"referenceNumber": 46,
|
||||
"name": "cryptsetup OpenSSL exception",
|
||||
"licenseExceptionId": "cryptsetup-OpenSSL-exception",
|
||||
"seeAlso": [
|
||||
@ -177,14 +177,26 @@
|
||||
"https://gitlab.nic.cz/datovka/datovka/-/blob/develop/COPYING",
|
||||
"https://github.com/nbs-system/naxsi/blob/951123ad456bdf5ac94e8d8819342fe3d49bc002/naxsi_src/naxsi_raw.c",
|
||||
"http://web.mit.edu/jgross/arch/amd64_deb60/bin/mosh",
|
||||
"https://sourceforge.net/p/linux-ima/ima-evm-utils/ci/master/tree/src/evmctl.c#l30"
|
||||
"https://sourceforge.net/p/linux-ima/ima-evm-utils/ci/master/tree/src/evmctl.c#l30",
|
||||
"https://github.com/ocaml-omake/omake/blob/master/LICENSE.OMake#L20"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "https://spdx.org/licenses/Digia-Qt-LGPL-exception-1.1.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/Digia-Qt-LGPL-exception-1.1.json",
|
||||
"referenceNumber": 48,
|
||||
"name": "Digia Qt LGPL Exception version 1.1",
|
||||
"licenseExceptionId": "Digia-Qt-LGPL-exception-1.1",
|
||||
"seeAlso": [
|
||||
"https://src.fedoraproject.org/rpms/qtlockedfile/blob/rawhide/f/LGPL_EXCEPTION"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "https://spdx.org/licenses/DigiRule-FOSS-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/DigiRule-FOSS-exception.json",
|
||||
"referenceNumber": 13,
|
||||
"referenceNumber": 53,
|
||||
"name": "DigiRule FOSS License Exception",
|
||||
"licenseExceptionId": "DigiRule-FOSS-exception",
|
||||
"seeAlso": [
|
||||
@ -195,7 +207,7 @@
|
||||
"reference": "https://spdx.org/licenses/eCos-exception-2.0.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/eCos-exception-2.0.json",
|
||||
"referenceNumber": 58,
|
||||
"referenceNumber": 61,
|
||||
"name": "eCos exception 2.0",
|
||||
"licenseExceptionId": "eCos-exception-2.0",
|
||||
"seeAlso": [
|
||||
@ -206,7 +218,7 @@
|
||||
"reference": "https://spdx.org/licenses/erlang-otp-linking-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/erlang-otp-linking-exception.json",
|
||||
"referenceNumber": 38,
|
||||
"referenceNumber": 13,
|
||||
"name": "Erlang/OTP Linking Exception",
|
||||
"licenseExceptionId": "erlang-otp-linking-exception",
|
||||
"seeAlso": [
|
||||
@ -219,7 +231,7 @@
|
||||
"reference": "https://spdx.org/licenses/Fawkes-Runtime-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/Fawkes-Runtime-exception.json",
|
||||
"referenceNumber": 12,
|
||||
"referenceNumber": 21,
|
||||
"name": "Fawkes Runtime Exception",
|
||||
"licenseExceptionId": "Fawkes-Runtime-exception",
|
||||
"seeAlso": [
|
||||
@ -230,7 +242,7 @@
|
||||
"reference": "https://spdx.org/licenses/FLTK-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/FLTK-exception.json",
|
||||
"referenceNumber": 8,
|
||||
"referenceNumber": 66,
|
||||
"name": "FLTK exception",
|
||||
"licenseExceptionId": "FLTK-exception",
|
||||
"seeAlso": [
|
||||
@ -241,7 +253,7 @@
|
||||
"reference": "https://spdx.org/licenses/fmt-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/fmt-exception.json",
|
||||
"referenceNumber": 2,
|
||||
"referenceNumber": 77,
|
||||
"name": "fmt exception",
|
||||
"licenseExceptionId": "fmt-exception",
|
||||
"seeAlso": [
|
||||
@ -253,7 +265,7 @@
|
||||
"reference": "https://spdx.org/licenses/Font-exception-2.0.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/Font-exception-2.0.json",
|
||||
"referenceNumber": 59,
|
||||
"referenceNumber": 35,
|
||||
"name": "Font exception 2.0",
|
||||
"licenseExceptionId": "Font-exception-2.0",
|
||||
"seeAlso": [
|
||||
@ -264,7 +276,7 @@
|
||||
"reference": "https://spdx.org/licenses/freertos-exception-2.0.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/freertos-exception-2.0.json",
|
||||
"referenceNumber": 37,
|
||||
"referenceNumber": 23,
|
||||
"name": "FreeRTOS Exception 2.0",
|
||||
"licenseExceptionId": "freertos-exception-2.0",
|
||||
"seeAlso": [
|
||||
@ -275,7 +287,7 @@
|
||||
"reference": "https://spdx.org/licenses/GCC-exception-2.0.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/GCC-exception-2.0.json",
|
||||
"referenceNumber": 27,
|
||||
"referenceNumber": 14,
|
||||
"name": "GCC Runtime Library exception 2.0",
|
||||
"licenseExceptionId": "GCC-exception-2.0",
|
||||
"seeAlso": [
|
||||
@ -287,7 +299,7 @@
|
||||
"reference": "https://spdx.org/licenses/GCC-exception-2.0-note.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/GCC-exception-2.0-note.json",
|
||||
"referenceNumber": 47,
|
||||
"referenceNumber": 20,
|
||||
"name": "GCC Runtime Library exception 2.0 - note variant",
|
||||
"licenseExceptionId": "GCC-exception-2.0-note",
|
||||
"seeAlso": [
|
||||
@ -298,7 +310,7 @@
|
||||
"reference": "https://spdx.org/licenses/GCC-exception-3.1.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/GCC-exception-3.1.json",
|
||||
"referenceNumber": 65,
|
||||
"referenceNumber": 25,
|
||||
"name": "GCC Runtime Library exception 3.1",
|
||||
"licenseExceptionId": "GCC-exception-3.1",
|
||||
"seeAlso": [
|
||||
@ -309,7 +321,7 @@
|
||||
"reference": "https://spdx.org/licenses/Gmsh-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/Gmsh-exception.json",
|
||||
"referenceNumber": 24,
|
||||
"referenceNumber": 26,
|
||||
"name": "Gmsh exception",
|
||||
"licenseExceptionId": "Gmsh-exception",
|
||||
"seeAlso": [
|
||||
@ -320,7 +332,7 @@
|
||||
"reference": "https://spdx.org/licenses/GNAT-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/GNAT-exception.json",
|
||||
"referenceNumber": 14,
|
||||
"referenceNumber": 69,
|
||||
"name": "GNAT exception",
|
||||
"licenseExceptionId": "GNAT-exception",
|
||||
"seeAlso": [
|
||||
@ -331,7 +343,7 @@
|
||||
"reference": "https://spdx.org/licenses/GNOME-examples-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/GNOME-examples-exception.json",
|
||||
"referenceNumber": 19,
|
||||
"referenceNumber": 76,
|
||||
"name": "GNOME examples exception",
|
||||
"licenseExceptionId": "GNOME-examples-exception",
|
||||
"seeAlso": [
|
||||
@ -343,7 +355,7 @@
|
||||
"reference": "https://spdx.org/licenses/GNU-compiler-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/GNU-compiler-exception.json",
|
||||
"referenceNumber": 57,
|
||||
"referenceNumber": 58,
|
||||
"name": "GNU Compiler Exception",
|
||||
"licenseExceptionId": "GNU-compiler-exception",
|
||||
"seeAlso": [
|
||||
@ -354,7 +366,7 @@
|
||||
"reference": "https://spdx.org/licenses/gnu-javamail-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/gnu-javamail-exception.json",
|
||||
"referenceNumber": 63,
|
||||
"referenceNumber": 64,
|
||||
"name": "GNU JavaMail exception",
|
||||
"licenseExceptionId": "gnu-javamail-exception",
|
||||
"seeAlso": [
|
||||
@ -365,7 +377,7 @@
|
||||
"reference": "https://spdx.org/licenses/GPL-3.0-389-ds-base-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/GPL-3.0-389-ds-base-exception.json",
|
||||
"referenceNumber": 64,
|
||||
"referenceNumber": 18,
|
||||
"name": "GPL-3.0 389 DS Base Exception",
|
||||
"licenseExceptionId": "GPL-3.0-389-ds-base-exception",
|
||||
"seeAlso": []
|
||||
@ -374,7 +386,7 @@
|
||||
"reference": "https://spdx.org/licenses/GPL-3.0-interface-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/GPL-3.0-interface-exception.json",
|
||||
"referenceNumber": 44,
|
||||
"referenceNumber": 78,
|
||||
"name": "GPL-3.0 Interface Exception",
|
||||
"licenseExceptionId": "GPL-3.0-interface-exception",
|
||||
"seeAlso": [
|
||||
@ -385,7 +397,7 @@
|
||||
"reference": "https://spdx.org/licenses/GPL-3.0-linking-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/GPL-3.0-linking-exception.json",
|
||||
"referenceNumber": 10,
|
||||
"referenceNumber": 68,
|
||||
"name": "GPL-3.0 Linking Exception",
|
||||
"licenseExceptionId": "GPL-3.0-linking-exception",
|
||||
"seeAlso": [
|
||||
@ -396,7 +408,7 @@
|
||||
"reference": "https://spdx.org/licenses/GPL-3.0-linking-source-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/GPL-3.0-linking-source-exception.json",
|
||||
"referenceNumber": 71,
|
||||
"referenceNumber": 62,
|
||||
"name": "GPL-3.0 Linking Exception (with Corresponding Source)",
|
||||
"licenseExceptionId": "GPL-3.0-linking-source-exception",
|
||||
"seeAlso": [
|
||||
@ -408,7 +420,7 @@
|
||||
"reference": "https://spdx.org/licenses/GPL-CC-1.0.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/GPL-CC-1.0.json",
|
||||
"referenceNumber": 18,
|
||||
"referenceNumber": 33,
|
||||
"name": "GPL Cooperation Commitment 1.0",
|
||||
"licenseExceptionId": "GPL-CC-1.0",
|
||||
"seeAlso": [
|
||||
@ -420,7 +432,7 @@
|
||||
"reference": "https://spdx.org/licenses/GStreamer-exception-2005.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/GStreamer-exception-2005.json",
|
||||
"referenceNumber": 72,
|
||||
"referenceNumber": 4,
|
||||
"name": "GStreamer Exception (2005)",
|
||||
"licenseExceptionId": "GStreamer-exception-2005",
|
||||
"seeAlso": [
|
||||
@ -431,7 +443,7 @@
|
||||
"reference": "https://spdx.org/licenses/GStreamer-exception-2008.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/GStreamer-exception-2008.json",
|
||||
"referenceNumber": 6,
|
||||
"referenceNumber": 41,
|
||||
"name": "GStreamer Exception (2008)",
|
||||
"licenseExceptionId": "GStreamer-exception-2008",
|
||||
"seeAlso": [
|
||||
@ -442,7 +454,7 @@
|
||||
"reference": "https://spdx.org/licenses/harbour-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/harbour-exception.json",
|
||||
"referenceNumber": 7,
|
||||
"referenceNumber": 59,
|
||||
"name": "harbour exception",
|
||||
"licenseExceptionId": "harbour-exception",
|
||||
"seeAlso": [
|
||||
@ -453,7 +465,7 @@
|
||||
"reference": "https://spdx.org/licenses/i2p-gpl-java-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/i2p-gpl-java-exception.json",
|
||||
"referenceNumber": 40,
|
||||
"referenceNumber": 9,
|
||||
"name": "i2p GPL+Java Exception",
|
||||
"licenseExceptionId": "i2p-gpl-java-exception",
|
||||
"seeAlso": [
|
||||
@ -464,7 +476,7 @@
|
||||
"reference": "https://spdx.org/licenses/Independent-modules-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/Independent-modules-exception.json",
|
||||
"referenceNumber": 61,
|
||||
"referenceNumber": 45,
|
||||
"name": "Independent Module Linking exception",
|
||||
"licenseExceptionId": "Independent-modules-exception",
|
||||
"seeAlso": [
|
||||
@ -475,7 +487,7 @@
|
||||
"reference": "https://spdx.org/licenses/KiCad-libraries-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/KiCad-libraries-exception.json",
|
||||
"referenceNumber": 68,
|
||||
"referenceNumber": 44,
|
||||
"name": "KiCad Libraries Exception",
|
||||
"licenseExceptionId": "KiCad-libraries-exception",
|
||||
"seeAlso": [
|
||||
@ -486,7 +498,7 @@
|
||||
"reference": "https://spdx.org/licenses/LGPL-3.0-linking-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/LGPL-3.0-linking-exception.json",
|
||||
"referenceNumber": 33,
|
||||
"referenceNumber": 32,
|
||||
"name": "LGPL-3.0 Linking Exception",
|
||||
"licenseExceptionId": "LGPL-3.0-linking-exception",
|
||||
"seeAlso": [
|
||||
@ -499,7 +511,7 @@
|
||||
"reference": "https://spdx.org/licenses/libpri-OpenH323-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/libpri-OpenH323-exception.json",
|
||||
"referenceNumber": 55,
|
||||
"referenceNumber": 19,
|
||||
"name": "libpri OpenH323 exception",
|
||||
"licenseExceptionId": "libpri-OpenH323-exception",
|
||||
"seeAlso": [
|
||||
@ -510,7 +522,7 @@
|
||||
"reference": "https://spdx.org/licenses/Libtool-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/Libtool-exception.json",
|
||||
"referenceNumber": 15,
|
||||
"referenceNumber": 71,
|
||||
"name": "Libtool Exception",
|
||||
"licenseExceptionId": "Libtool-exception",
|
||||
"seeAlso": [
|
||||
@ -522,7 +534,7 @@
|
||||
"reference": "https://spdx.org/licenses/Linux-syscall-note.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/Linux-syscall-note.json",
|
||||
"referenceNumber": 22,
|
||||
"referenceNumber": 37,
|
||||
"name": "Linux Syscall Note",
|
||||
"licenseExceptionId": "Linux-syscall-note",
|
||||
"seeAlso": [
|
||||
@ -533,7 +545,7 @@
|
||||
"reference": "https://spdx.org/licenses/LLGPL.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/LLGPL.json",
|
||||
"referenceNumber": 3,
|
||||
"referenceNumber": 24,
|
||||
"name": "LLGPL Preamble",
|
||||
"licenseExceptionId": "LLGPL",
|
||||
"seeAlso": [
|
||||
@ -544,7 +556,7 @@
|
||||
"reference": "https://spdx.org/licenses/LLVM-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/LLVM-exception.json",
|
||||
"referenceNumber": 74,
|
||||
"referenceNumber": 72,
|
||||
"name": "LLVM Exception",
|
||||
"licenseExceptionId": "LLVM-exception",
|
||||
"seeAlso": [
|
||||
@ -555,7 +567,7 @@
|
||||
"reference": "https://spdx.org/licenses/LZMA-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/LZMA-exception.json",
|
||||
"referenceNumber": 32,
|
||||
"referenceNumber": 30,
|
||||
"name": "LZMA exception",
|
||||
"licenseExceptionId": "LZMA-exception",
|
||||
"seeAlso": [
|
||||
@ -566,7 +578,7 @@
|
||||
"reference": "https://spdx.org/licenses/mif-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/mif-exception.json",
|
||||
"referenceNumber": 75,
|
||||
"referenceNumber": 29,
|
||||
"name": "Macros and Inline Functions Exception",
|
||||
"licenseExceptionId": "mif-exception",
|
||||
"seeAlso": [
|
||||
@ -579,7 +591,7 @@
|
||||
"reference": "https://spdx.org/licenses/mxml-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/mxml-exception.json",
|
||||
"referenceNumber": 21,
|
||||
"referenceNumber": 38,
|
||||
"name": "mxml Exception",
|
||||
"licenseExceptionId": "mxml-exception",
|
||||
"seeAlso": [
|
||||
@ -591,7 +603,7 @@
|
||||
"reference": "https://spdx.org/licenses/Nokia-Qt-exception-1.1.html",
|
||||
"isDeprecatedLicenseId": true,
|
||||
"detailsUrl": "https://spdx.org/licenses/Nokia-Qt-exception-1.1.json",
|
||||
"referenceNumber": 51,
|
||||
"referenceNumber": 47,
|
||||
"name": "Nokia Qt LGPL exception 1.1",
|
||||
"licenseExceptionId": "Nokia-Qt-exception-1.1",
|
||||
"seeAlso": [
|
||||
@ -602,7 +614,7 @@
|
||||
"reference": "https://spdx.org/licenses/OCaml-LGPL-linking-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/OCaml-LGPL-linking-exception.json",
|
||||
"referenceNumber": 35,
|
||||
"referenceNumber": 42,
|
||||
"name": "OCaml LGPL Linking Exception",
|
||||
"licenseExceptionId": "OCaml-LGPL-linking-exception",
|
||||
"seeAlso": [
|
||||
@ -613,7 +625,7 @@
|
||||
"reference": "https://spdx.org/licenses/OCCT-exception-1.0.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/OCCT-exception-1.0.json",
|
||||
"referenceNumber": 70,
|
||||
"referenceNumber": 17,
|
||||
"name": "Open CASCADE Exception 1.0",
|
||||
"licenseExceptionId": "OCCT-exception-1.0",
|
||||
"seeAlso": [
|
||||
@ -624,7 +636,7 @@
|
||||
"reference": "https://spdx.org/licenses/OpenJDK-assembly-exception-1.0.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/OpenJDK-assembly-exception-1.0.json",
|
||||
"referenceNumber": 77,
|
||||
"referenceNumber": 11,
|
||||
"name": "OpenJDK Assembly exception 1.0",
|
||||
"licenseExceptionId": "OpenJDK-assembly-exception-1.0",
|
||||
"seeAlso": [
|
||||
@ -635,7 +647,7 @@
|
||||
"reference": "https://spdx.org/licenses/openvpn-openssl-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/openvpn-openssl-exception.json",
|
||||
"referenceNumber": 9,
|
||||
"referenceNumber": 3,
|
||||
"name": "OpenVPN OpenSSL Exception",
|
||||
"licenseExceptionId": "openvpn-openssl-exception",
|
||||
"seeAlso": [
|
||||
@ -647,18 +659,29 @@
|
||||
"reference": "https://spdx.org/licenses/PCRE2-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/PCRE2-exception.json",
|
||||
"referenceNumber": 76,
|
||||
"referenceNumber": 12,
|
||||
"name": "PCRE2 exception",
|
||||
"licenseExceptionId": "PCRE2-exception",
|
||||
"seeAlso": [
|
||||
"https://www.pcre.org/licence.txt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "https://spdx.org/licenses/polyparse-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/polyparse-exception.json",
|
||||
"referenceNumber": 54,
|
||||
"name": "Polyparse Exception",
|
||||
"licenseExceptionId": "polyparse-exception",
|
||||
"seeAlso": [
|
||||
"https://hackage.haskell.org/package/polyparse-1.13/src/COPYRIGHT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "https://spdx.org/licenses/PS-or-PDF-font-exception-20170817.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/PS-or-PDF-font-exception-20170817.json",
|
||||
"referenceNumber": 4,
|
||||
"referenceNumber": 43,
|
||||
"name": "PS/PDF font exception (2017-08-17)",
|
||||
"licenseExceptionId": "PS-or-PDF-font-exception-20170817",
|
||||
"seeAlso": [
|
||||
@ -669,7 +692,7 @@
|
||||
"reference": "https://spdx.org/licenses/QPL-1.0-INRIA-2004-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/QPL-1.0-INRIA-2004-exception.json",
|
||||
"referenceNumber": 48,
|
||||
"referenceNumber": 50,
|
||||
"name": "INRIA QPL 1.0 2004 variant exception",
|
||||
"licenseExceptionId": "QPL-1.0-INRIA-2004-exception",
|
||||
"seeAlso": [
|
||||
@ -681,7 +704,7 @@
|
||||
"reference": "https://spdx.org/licenses/Qt-GPL-exception-1.0.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/Qt-GPL-exception-1.0.json",
|
||||
"referenceNumber": 45,
|
||||
"referenceNumber": 34,
|
||||
"name": "Qt GPL exception 1.0",
|
||||
"licenseExceptionId": "Qt-GPL-exception-1.0",
|
||||
"seeAlso": [
|
||||
@ -692,7 +715,7 @@
|
||||
"reference": "https://spdx.org/licenses/Qt-LGPL-exception-1.1.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/Qt-LGPL-exception-1.1.json",
|
||||
"referenceNumber": 73,
|
||||
"referenceNumber": 39,
|
||||
"name": "Qt LGPL exception 1.1",
|
||||
"licenseExceptionId": "Qt-LGPL-exception-1.1",
|
||||
"seeAlso": [
|
||||
@ -703,7 +726,7 @@
|
||||
"reference": "https://spdx.org/licenses/Qwt-exception-1.0.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/Qwt-exception-1.0.json",
|
||||
"referenceNumber": 11,
|
||||
"referenceNumber": 79,
|
||||
"name": "Qwt exception 1.0",
|
||||
"licenseExceptionId": "Qwt-exception-1.0",
|
||||
"seeAlso": [
|
||||
@ -714,7 +737,7 @@
|
||||
"reference": "https://spdx.org/licenses/romic-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/romic-exception.json",
|
||||
"referenceNumber": 28,
|
||||
"referenceNumber": 6,
|
||||
"name": "Romic Exception",
|
||||
"licenseExceptionId": "romic-exception",
|
||||
"seeAlso": [
|
||||
@ -730,7 +753,7 @@
|
||||
"reference": "https://spdx.org/licenses/RRDtool-FLOSS-exception-2.0.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/RRDtool-FLOSS-exception-2.0.json",
|
||||
"referenceNumber": 29,
|
||||
"referenceNumber": 7,
|
||||
"name": "RRDtool FLOSS exception 2.0",
|
||||
"licenseExceptionId": "RRDtool-FLOSS-exception-2.0",
|
||||
"seeAlso": [
|
||||
@ -742,7 +765,7 @@
|
||||
"reference": "https://spdx.org/licenses/SANE-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/SANE-exception.json",
|
||||
"referenceNumber": 26,
|
||||
"referenceNumber": 27,
|
||||
"name": "SANE Exception",
|
||||
"licenseExceptionId": "SANE-exception",
|
||||
"seeAlso": [
|
||||
@ -755,7 +778,7 @@
|
||||
"reference": "https://spdx.org/licenses/SHL-2.0.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/SHL-2.0.json",
|
||||
"referenceNumber": 30,
|
||||
"referenceNumber": 5,
|
||||
"name": "Solderpad Hardware License v2.0",
|
||||
"licenseExceptionId": "SHL-2.0",
|
||||
"seeAlso": [
|
||||
@ -766,7 +789,7 @@
|
||||
"reference": "https://spdx.org/licenses/SHL-2.1.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/SHL-2.1.json",
|
||||
"referenceNumber": 36,
|
||||
"referenceNumber": 1,
|
||||
"name": "Solderpad Hardware License v2.1",
|
||||
"licenseExceptionId": "SHL-2.1",
|
||||
"seeAlso": [
|
||||
@ -777,7 +800,7 @@
|
||||
"reference": "https://spdx.org/licenses/stunnel-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/stunnel-exception.json",
|
||||
"referenceNumber": 60,
|
||||
"referenceNumber": 49,
|
||||
"name": "stunnel Exception",
|
||||
"licenseExceptionId": "stunnel-exception",
|
||||
"seeAlso": [
|
||||
@ -788,7 +811,7 @@
|
||||
"reference": "https://spdx.org/licenses/SWI-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/SWI-exception.json",
|
||||
"referenceNumber": 46,
|
||||
"referenceNumber": 15,
|
||||
"name": "SWI exception",
|
||||
"licenseExceptionId": "SWI-exception",
|
||||
"seeAlso": [
|
||||
@ -799,7 +822,7 @@
|
||||
"reference": "https://spdx.org/licenses/Swift-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/Swift-exception.json",
|
||||
"referenceNumber": 56,
|
||||
"referenceNumber": 52,
|
||||
"name": "Swift Exception",
|
||||
"licenseExceptionId": "Swift-exception",
|
||||
"seeAlso": [
|
||||
@ -811,7 +834,7 @@
|
||||
"reference": "https://spdx.org/licenses/Texinfo-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/Texinfo-exception.json",
|
||||
"referenceNumber": 62,
|
||||
"referenceNumber": 60,
|
||||
"name": "Texinfo exception",
|
||||
"licenseExceptionId": "Texinfo-exception",
|
||||
"seeAlso": [
|
||||
@ -822,7 +845,7 @@
|
||||
"reference": "https://spdx.org/licenses/u-boot-exception-2.0.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/u-boot-exception-2.0.json",
|
||||
"referenceNumber": 5,
|
||||
"referenceNumber": 8,
|
||||
"name": "U-Boot exception 2.0",
|
||||
"licenseExceptionId": "u-boot-exception-2.0",
|
||||
"seeAlso": [
|
||||
@ -833,7 +856,7 @@
|
||||
"reference": "https://spdx.org/licenses/UBDL-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/UBDL-exception.json",
|
||||
"referenceNumber": 23,
|
||||
"referenceNumber": 75,
|
||||
"name": "Unmodified Binary Distribution exception",
|
||||
"licenseExceptionId": "UBDL-exception",
|
||||
"seeAlso": [
|
||||
@ -844,7 +867,7 @@
|
||||
"reference": "https://spdx.org/licenses/Universal-FOSS-exception-1.0.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/Universal-FOSS-exception-1.0.json",
|
||||
"referenceNumber": 52,
|
||||
"referenceNumber": 70,
|
||||
"name": "Universal FOSS Exception, Version 1.0",
|
||||
"licenseExceptionId": "Universal-FOSS-exception-1.0",
|
||||
"seeAlso": [
|
||||
@ -855,7 +878,7 @@
|
||||
"reference": "https://spdx.org/licenses/vsftpd-openssl-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/vsftpd-openssl-exception.json",
|
||||
"referenceNumber": 39,
|
||||
"referenceNumber": 55,
|
||||
"name": "vsftpd OpenSSL exception",
|
||||
"licenseExceptionId": "vsftpd-openssl-exception",
|
||||
"seeAlso": [
|
||||
@ -868,7 +891,7 @@
|
||||
"reference": "https://spdx.org/licenses/WxWindows-exception-3.1.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/WxWindows-exception-3.1.json",
|
||||
"referenceNumber": 49,
|
||||
"referenceNumber": 31,
|
||||
"name": "WxWindows Library Exception 3.1",
|
||||
"licenseExceptionId": "WxWindows-exception-3.1",
|
||||
"seeAlso": [
|
||||
@ -879,7 +902,7 @@
|
||||
"reference": "https://spdx.org/licenses/x11vnc-openssl-exception.html",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "https://spdx.org/licenses/x11vnc-openssl-exception.json",
|
||||
"referenceNumber": 31,
|
||||
"referenceNumber": 57,
|
||||
"name": "x11vnc OpenSSL Exception",
|
||||
"licenseExceptionId": "x11vnc-openssl-exception",
|
||||
"seeAlso": [
|
||||
@ -887,5 +910,5 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"releaseDate": "2024-12-30T00:00:00Z"
|
||||
"releaseDate": "2025-07-01T00:00:00Z"
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user