mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00
Compare commits
635 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 | ||
![]() |
dc0f9d50fd | ||
![]() |
9acd68b8c1 | ||
![]() |
24cd62140d | ||
![]() |
e76a02eadd | ||
![]() |
97acfb94ce | ||
![]() |
5ee4e609ac | ||
![]() |
f4375b0750 | ||
![]() |
90323ffc3c | ||
![]() |
51dc147d90 | ||
![]() |
34b22000d6 | ||
![]() |
418a771d12 | ||
![]() |
2457fb123f | ||
![]() |
241dbba55c | ||
![]() |
6a07851c46 | ||
![]() |
3f450e5f10 | ||
![]() |
8d30251f9f | ||
![]() |
ac2d167ffc | ||
![]() |
4887d58826 | ||
![]() |
77c7587d77 | ||
![]() |
e5f844ec86 | ||
![]() |
4aa7f83954 | ||
![]() |
2f10b1cd6e | ||
![]() |
daeb5b1dfe | ||
![]() |
e8e8fcea02 | ||
![]() |
83db7a31ec | ||
![]() |
85bd5af800 | ||
![]() |
3dad44c9f3 | ||
![]() |
01e0d4b311 | ||
![]() |
8f3315bff5 | ||
![]() |
5027a9d2f2 | ||
![]() |
63cdd0723c | ||
![]() |
8097268267 | ||
![]() |
6527fc1bf3 | ||
![]() |
b826bbf23e | ||
![]() |
8b32d019d4 | ||
![]() |
3482655284 | ||
![]() |
ee15435a90 | ||
![]() |
c1a2f94e01 | ||
![]() |
a94037a6ff | ||
![]() |
e1c6513562 | ||
![]() |
d5b3ae095c | ||
![]() |
33a6d21eef | ||
![]() |
cd86e43fb1 | ||
![]() |
1d4f1481ae | ||
![]() |
38bad25a86 | ||
![]() |
cdf3964753 | ||
![]() |
df306e1426 | ||
![]() |
c2abb473bf | ||
![]() |
436eec1923 | ||
![]() |
ce7256b154 | ||
![]() |
8e58386539 | ||
![]() |
303e4e4784 | ||
![]() |
fe91ec3dbb | ||
![]() |
33284e2a00 | ||
![]() |
87e4dfcd9f | ||
![]() |
8b643d7acf | ||
![]() |
c2fac2047d | ||
![]() |
c0f4e11370 | ||
![]() |
8b22e8a95f | ||
![]() |
2decd2158d | ||
![]() |
bfc36c00d8 | ||
![]() |
bdbd39bb09 | ||
![]() |
83249ef6ea | ||
![]() |
d4c02e64e5 | ||
![]() |
e8a0142150 | ||
![]() |
2b25f34e85 | ||
![]() |
3320d7ee3e | ||
![]() |
ad5e03279b | ||
![]() |
713289e2eb | ||
![]() |
f051510e67 | ||
![]() |
2bc642d501 | ||
![]() |
8282ffa658 | ||
![]() |
effb07ee76 | ||
![]() |
7173f1fb60 | ||
![]() |
28eab5c9a0 | ||
![]() |
14fbd47808 | ||
![]() |
6a23486dd5 | ||
![]() |
b371b6eb59 | ||
![]() |
a063889303 | ||
![]() |
b554839ed9 | ||
![]() |
5f037232c7 | ||
![]() |
95abc7360b | ||
![]() |
92832c258c | ||
![]() |
69667974bc | ||
![]() |
efc91b27fb | ||
![]() |
c75d06881a | ||
![]() |
1cfc303969 | ||
![]() |
7ce8b5a4ca | ||
![]() |
a760645936 | ||
![]() |
bd232b1e65 | ||
![]() |
cf26ec1b3d | ||
![]() |
3f69fabbf0 | ||
![]() |
2358748321 | ||
![]() |
a2f86b685d | ||
![]() |
98ad7e3aa3 | ||
![]() |
f53c125c0c | ||
![]() |
1dc2e07c3d | ||
![]() |
e271c89ee9 | ||
![]() |
19d20a740a | ||
![]() |
2723620d85 | ||
![]() |
85aed4c430 | ||
![]() |
888dd7992e | ||
![]() |
d227f494ed | ||
![]() |
e4e75f5474 | ||
![]() |
ce0ef75e33 | ||
![]() |
12882a2942 | ||
![]() |
e9edb7da20 | ||
![]() |
736517cbdb | ||
![]() |
b1ec1e908b | ||
![]() |
b58b8d5d77 | ||
![]() |
9a7835c9fd | ||
![]() |
00aed74cf0 | ||
![]() |
aea920b3bb | ||
![]() |
f1552bf3ec | ||
![]() |
ba9984cfd0 | ||
![]() |
91aa9a4856 | ||
![]() |
a2b91764cf | ||
![]() |
bdf738ef10 | ||
![]() |
28b1b74607 | ||
![]() |
ef314d9435 | ||
![]() |
2b8d104281 | ||
![]() |
107120e4d8 | ||
![]() |
32366b7e01 | ||
![]() |
63bc6477b5 | ||
![]() |
e354d6f07f | ||
![]() |
19c4d129a5 | ||
![]() |
c5fd8e586f | ||
![]() |
ca911fb446 | ||
![]() |
1399d2e98a | ||
![]() |
13d9d9803f | ||
![]() |
7bd41e7c19 | ||
![]() |
5b6dbafb4c | ||
![]() |
a6fa333524 | ||
![]() |
dafc62904e | ||
![]() |
f39cb527fd | ||
![]() |
7cd1972f39 | ||
![]() |
17de33e9ef | ||
![]() |
923be69785 | ||
![]() |
75a5f03f75 | ||
![]() |
088bd26f5d | ||
![]() |
0461237c03 | ||
![]() |
47a2497202 | ||
![]() |
e08aa7dd02 | ||
![]() |
892d408f58 | ||
![]() |
241f74a797 | ||
![]() |
2d188a3071 | ||
![]() |
9272ac9668 | ||
![]() |
ef9751b040 | ||
![]() |
d7010dce07 | ||
![]() |
9686d7063c | ||
![]() |
68443f61a8 | ||
![]() |
0b4e885434 | ||
![]() |
ed913ae061 | ||
![]() |
8b6183c7db | ||
![]() |
c9f58f83a4 | ||
![]() |
c25244a0f2 | ||
![]() |
b0c5f613b9 | ||
![]() |
bb33840924 | ||
![]() |
8253e89eea | ||
![]() |
c089d8b9da | ||
![]() |
bf0e09c847 | ||
![]() |
0ceeb934d5 | ||
![]() |
40c31c69f6 | ||
![]() |
4c393ffe40 | ||
![]() |
59296b855f | ||
![]() |
5b68c3d6b6 | ||
![]() |
9b94404891 | ||
![]() |
f4c6dd282d | ||
![]() |
b8639a5f48 | ||
![]() |
58004e6ffb | ||
![]() |
e402ad336e | ||
![]() |
9fa7da4db8 | ||
![]() |
af6de739ca | ||
![]() |
f4bc811a1c | ||
![]() |
becc36a6da | ||
![]() |
ea8cc264b2 | ||
![]() |
0838ceda90 | ||
![]() |
b30a0c69b5 | ||
![]() |
5e931071f8 | ||
![]() |
a4cf69f261 | ||
![]() |
56d91aaf28 | ||
![]() |
6cea5ef4f0 | ||
![]() |
4373aad153 | ||
![]() |
efa2786732 | ||
![]() |
3761d70785 | ||
![]() |
d73b0079e9 | ||
![]() |
84704c5587 |
@ -1,7 +1,7 @@
|
|||||||
// For format details, see https://aka.ms/devcontainer.json.
|
// For format details, see https://aka.ms/devcontainer.json.
|
||||||
{
|
{
|
||||||
"name": "Homebrew/brew",
|
"name": "Homebrew/brew",
|
||||||
"image": "ghcr.io/homebrew/brew:master",
|
"image": "ghcr.io/homebrew/brew:main",
|
||||||
"workspaceFolder": "/home/linuxbrew/.linuxbrew/Homebrew",
|
"workspaceFolder": "/home/linuxbrew/.linuxbrew/Homebrew",
|
||||||
"workspaceMount": "source=${localWorkspaceFolder},target=/home/linuxbrew/.linuxbrew/Homebrew,type=bind,consistency=cached",
|
"workspaceMount": "source=${localWorkspaceFolder},target=/home/linuxbrew/.linuxbrew/Homebrew,type=bind,consistency=cached",
|
||||||
"onCreateCommand": ".devcontainer/on-create-command.sh",
|
"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:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
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
|
- type: textarea
|
||||||
attributes:
|
attributes:
|
||||||
render: shell
|
render: shell
|
||||||
@ -16,10 +16,10 @@ body:
|
|||||||
label: Verification
|
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.
|
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:
|
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.
|
- label: I ran `brew update` twice and am still able to reproduce my issue.
|
||||||
required: true
|
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.
|
- 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
|
required: true
|
||||||
- type: textarea
|
- 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"]
|
128
.github/dependabot.yml
vendored
128
.github/dependabot.yml
vendored
@ -1,72 +1,94 @@
|
|||||||
|
# This file is synced from the `.github` repository, do not modify it directly.
|
||||||
|
---
|
||||||
version: 2
|
version: 2
|
||||||
|
|
||||||
updates:
|
updates:
|
||||||
- package-ecosystem: github-actions
|
- package-ecosystem: github-actions
|
||||||
directory: /
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: weekly
|
interval: weekly
|
||||||
allow:
|
day: friday
|
||||||
- dependency-type: all
|
time: '08:00'
|
||||||
# The actions in triage-issues.yml are updated in the Homebrew/.github repo
|
timezone: Etc/UTC
|
||||||
ignore:
|
|
||||||
- dependency-name: actions/stale
|
|
||||||
groups:
|
|
||||||
artifacts:
|
|
||||||
patterns:
|
|
||||||
- actions/*-artifact
|
|
||||||
open-pull-requests-limit: 10
|
|
||||||
|
|
||||||
- package-ecosystem: bundler
|
|
||||||
directory: /Library/Homebrew
|
|
||||||
schedule:
|
|
||||||
interval: daily
|
|
||||||
allow:
|
allow:
|
||||||
- dependency-type: all
|
- dependency-type: all
|
||||||
groups:
|
groups:
|
||||||
rspec:
|
dependabot:
|
||||||
patterns:
|
patterns:
|
||||||
- "rspec*"
|
- "*"
|
||||||
sorbet:
|
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:
|
patterns:
|
||||||
- "sorbet*"
|
- "*"
|
||||||
open-pull-requests-limit: 10
|
cooldown:
|
||||||
|
default-days: 1
|
||||||
- package-ecosystem: npm
|
semver-major-days: 14
|
||||||
directory: /
|
semver-minor-days: 7
|
||||||
|
semver-patch-days: 1
|
||||||
|
include:
|
||||||
|
- "*"
|
||||||
|
- package-ecosystem: docker
|
||||||
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: daily
|
interval: weekly
|
||||||
|
day: friday
|
||||||
|
time: '08:00'
|
||||||
|
timezone: Etc/UTC
|
||||||
allow:
|
allow:
|
||||||
- dependency-type: all
|
- dependency-type: all
|
||||||
open-pull-requests-limit: 10
|
groups:
|
||||||
|
dependabot:
|
||||||
- package-ecosystem: docker
|
patterns:
|
||||||
directory: /
|
- "*"
|
||||||
|
- package-ecosystem: devcontainers
|
||||||
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: daily
|
interval: weekly
|
||||||
|
day: friday
|
||||||
|
time: '08:00'
|
||||||
|
timezone: Etc/UTC
|
||||||
allow:
|
allow:
|
||||||
- dependency-type: all
|
- dependency-type: all
|
||||||
open-pull-requests-limit: 10
|
groups:
|
||||||
|
dependabot:
|
||||||
- package-ecosystem: devcontainers
|
patterns:
|
||||||
directory: /
|
- "*"
|
||||||
|
cooldown:
|
||||||
|
default-days: 1
|
||||||
|
include:
|
||||||
|
- "*"
|
||||||
|
- package-ecosystem: pip
|
||||||
|
directories:
|
||||||
|
- "/Library/Homebrew/formula-analytics/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: daily
|
interval: weekly
|
||||||
|
day: friday
|
||||||
|
time: '08:00'
|
||||||
|
timezone: Etc/UTC
|
||||||
allow:
|
allow:
|
||||||
- dependency-type: all
|
- dependency-type: all
|
||||||
open-pull-requests-limit: 10
|
groups:
|
||||||
|
dependabot:
|
||||||
|
patterns:
|
||||||
|
- "*"
|
||||||
|
cooldown:
|
||||||
|
default-days: 1
|
||||||
|
semver-major-days: 14
|
||||||
|
semver-minor-days: 7
|
||||||
|
semver-patch-days: 1
|
||||||
|
include:
|
||||||
|
- "*"
|
||||||
|
|
||||||
- package-ecosystem: pip
|
|
||||||
directory: /
|
|
||||||
schedule:
|
|
||||||
interval: daily
|
|
||||||
allow:
|
|
||||||
- dependency-type: all
|
|
||||||
open-pull-requests-limit: 10
|
|
||||||
|
|
||||||
- package-ecosystem: pip
|
|
||||||
directory: /Library/Homebrew/formula-analytics/
|
|
||||||
schedule:
|
|
||||||
interval: daily
|
|
||||||
allow:
|
|
||||||
- dependency-type: all
|
|
||||||
open-pull-requests-limit: 10
|
|
||||||
|
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:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
|
- main
|
||||||
- master
|
- master
|
||||||
pull_request:
|
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:
|
defaults:
|
||||||
run:
|
run:
|
||||||
@ -22,16 +16,25 @@ concurrency:
|
|||||||
group: "actionlint-${{ github.ref }}"
|
group: "actionlint-${{ github.ref }}"
|
||||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||||
|
|
||||||
|
env:
|
||||||
|
HOMEBREW_DEVELOPER: 1
|
||||||
|
HOMEBREW_NO_AUTO_UPDATE: 1
|
||||||
|
HOMEBREW_NO_ENV_HINTS: 1
|
||||||
|
|
||||||
permissions: {}
|
permissions: {}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
workflow_syntax:
|
workflow_syntax:
|
||||||
if: github.repository_owner == 'Homebrew'
|
if: github.repository_owner == 'Homebrew'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
container:
|
||||||
|
image: ghcr.io/homebrew/ubuntu22.04:main
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: setup-homebrew
|
id: setup-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
@ -40,31 +43,44 @@ jobs:
|
|||||||
- name: Install tools
|
- name: Install tools
|
||||||
run: brew install actionlint shellcheck zizmor
|
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:
|
env:
|
||||||
HOMEBREW_REPOSITORY: ${{ steps.setup-homebrew.outputs.repository-path }}
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
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
|
|
||||||
|
|
||||||
- name: Upload SARIF file
|
- name: Upload SARIF file
|
||||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
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:
|
with:
|
||||||
name: results.sarif
|
name: results.sarif
|
||||||
path: 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
|
- run: actionlint
|
||||||
|
|
||||||
upload_sarif:
|
upload_sarif:
|
||||||
needs: workflow_syntax
|
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
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
@ -77,7 +93,7 @@ jobs:
|
|||||||
path: results.sarif
|
path: results.sarif
|
||||||
|
|
||||||
- name: Upload SARIF file
|
- name: Upload SARIF file
|
||||||
uses: github/codeql-action/upload-sarif@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3.28.17
|
uses: github/codeql-action/upload-sarif@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
|
||||||
with:
|
with:
|
||||||
sarif_file: results.sarif
|
sarif_file: results.sarif
|
||||||
category: zizmor
|
category: zizmor
|
||||||
|
2
.github/workflows/autogenerated-files.yml
vendored
2
.github/workflows/autogenerated-files.yml
vendored
@ -27,7 +27,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
|
7
.github/workflows/codeql-analysis.yml
vendored
7
.github/workflows/codeql-analysis.yml
vendored
@ -3,10 +3,9 @@ name: "CodeQL"
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
|
- main
|
||||||
- master
|
- master
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
|
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
@ -28,7 +27,7 @@ jobs:
|
|||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3.28.17
|
uses: github/codeql-action/init@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
|
||||||
with:
|
with:
|
||||||
languages: ruby
|
languages: ruby
|
||||||
config: |
|
config: |
|
||||||
@ -36,4 +35,4 @@ jobs:
|
|||||||
- Library/Homebrew/vendor
|
- Library/Homebrew/vendor
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3.28.17
|
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:
|
pull_request:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
|
- main
|
||||||
- master
|
- master
|
||||||
merge_group:
|
merge_group:
|
||||||
release:
|
release:
|
||||||
@ -38,8 +39,8 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Fetch origin/master from Git
|
- name: Fetch origin/HEAD from Git
|
||||||
run: git fetch origin master
|
run: git fetch origin HEAD
|
||||||
|
|
||||||
- name: Determine build attributes
|
- name: Determine build attributes
|
||||||
id: attributes
|
id: attributes
|
||||||
@ -83,12 +84,16 @@ jobs:
|
|||||||
)
|
)
|
||||||
fi
|
fi
|
||||||
elif [[ "${GITHUB_EVENT_NAME}" == "push" &&
|
elif [[ "${GITHUB_EVENT_NAME}" == "push" &&
|
||||||
"${GITHUB_REF}" == "refs/heads/master" &&
|
("${GITHUB_REF}" == "refs/heads/master" || "${GITHUB_REF}" == "refs/heads/main") &&
|
||||||
"${version}" == "22.04" ]]; then
|
"${version}" == "22.04" ]]; then
|
||||||
tags+=(
|
tags+=(
|
||||||
|
"ghcr.io/homebrew/brew:main"
|
||||||
"ghcr.io/homebrew/brew:master"
|
"ghcr.io/homebrew/brew:master"
|
||||||
|
"ghcr.io/homebrew/ubuntu${version}:main"
|
||||||
"ghcr.io/homebrew/ubuntu${version}:master"
|
"ghcr.io/homebrew/ubuntu${version}:master"
|
||||||
|
"homebrew/brew:main"
|
||||||
"homebrew/brew:master"
|
"homebrew/brew:master"
|
||||||
|
"homebrew/ubuntu${version}:main"
|
||||||
"homebrew/ubuntu${version}:master"
|
"homebrew/ubuntu${version}:master"
|
||||||
)
|
)
|
||||||
fi
|
fi
|
||||||
@ -160,11 +165,11 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Fetch origin/master from Git
|
- name: Fetch origin/HEAD from Git
|
||||||
run: git fetch origin master
|
run: git fetch origin HEAD
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
|
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||||
with:
|
with:
|
||||||
cache-binary: false
|
cache-binary: false
|
||||||
|
|
||||||
@ -190,7 +195,7 @@ jobs:
|
|||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Build Docker image
|
- name: Build Docker image
|
||||||
uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 # v6.16.0
|
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
load: true
|
load: true
|
||||||
@ -227,7 +232,7 @@ jobs:
|
|||||||
- name: Deploy the Docker image by digest
|
- name: Deploy the Docker image by digest
|
||||||
id: digest
|
id: digest
|
||||||
if: fromJSON(steps.attributes.outputs.push)
|
if: fromJSON(steps.attributes.outputs.push)
|
||||||
uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 # v6.16.0
|
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
cache-from: type=registry,ref=ghcr.io/homebrew/ubuntu${{ matrix.version }}:cache
|
cache-from: type=registry,ref=ghcr.io/homebrew/ubuntu${{ matrix.version }}:cache
|
||||||
@ -263,7 +268,7 @@ jobs:
|
|||||||
version: ${{ fromJSON(needs.generate-tags.outputs.matrix) }}
|
version: ${{ fromJSON(needs.generate-tags.outputs.matrix) }}
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
|
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||||
with:
|
with:
|
||||||
cache-binary: false
|
cache-binary: false
|
||||||
|
|
||||||
|
12
.github/workflows/docs.yml
vendored
12
.github/workflows/docs.yml
vendored
@ -24,7 +24,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
@ -52,7 +52,7 @@ jobs:
|
|||||||
run: vale docs/
|
run: vale docs/
|
||||||
|
|
||||||
- name: Install Ruby
|
- name: Install Ruby
|
||||||
uses: ruby/setup-ruby@eaecf785f6a34567a6d97f686bbb7bccc1ac1e5c # v1.237.0
|
uses: ruby/setup-ruby@a4effe49ee8ee5b8b5091268c473a4628afb5651 # v1.245.0
|
||||||
with:
|
with:
|
||||||
bundler-cache: true
|
bundler-cache: true
|
||||||
working-directory: docs
|
working-directory: docs
|
||||||
@ -67,7 +67,13 @@ jobs:
|
|||||||
- name: Generate formulae.brew.sh API samples
|
- name: Generate formulae.brew.sh API samples
|
||||||
if: github.repository == 'Homebrew/formulae.brew.sh'
|
if: github.repository == 'Homebrew/formulae.brew.sh'
|
||||||
working-directory: docs
|
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
|
- name: Build the site and check for broken links
|
||||||
working-directory: docs
|
working-directory: docs
|
||||||
|
4
.github/workflows/doctor.yml
vendored
4
.github/workflows/doctor.yml
vendored
@ -28,7 +28,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
@ -55,7 +55,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: 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
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
@ -135,7 +135,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Generate build provenance
|
- name: Generate build provenance
|
||||||
uses: actions/attest-build-provenance@db473fddc028af60658334401dc6fa3ffd8669fd # v2.3.0
|
uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2.4.0
|
||||||
with:
|
with:
|
||||||
subject-path: Homebrew-${{ steps.homebrew-version.outputs.version }}.pkg
|
subject-path: Homebrew-${{ steps.homebrew-version.outputs.version }}.pkg
|
||||||
|
|
||||||
@ -230,17 +230,15 @@ jobs:
|
|||||||
--password "${PKG_APPLE_ID_APP_SPECIFIC_PASSWORD}"
|
--password "${PKG_APPLE_ID_APP_SPECIFIC_PASSWORD}"
|
||||||
--wait
|
--wait
|
||||||
|
|
||||||
- name: Install gh
|
|
||||||
run: brew install gh
|
|
||||||
|
|
||||||
- name: Upload installer to GitHub release
|
- name: Upload installer to GitHub release
|
||||||
if: github.event_name == 'release'
|
if: github.event_name == 'release'
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ github.token }}
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
INSTALLER_PATH: ${{ needs.build.outputs.installer_path }}
|
INSTALLER_PATH: ${{ needs.build.outputs.installer_path }}
|
||||||
run: gh release upload --repo Homebrew/brew
|
run: |
|
||||||
"${GITHUB_REF//refs\/tags\//}"
|
VERSION="${INSTALLER_PATH#Homebrew-}"
|
||||||
"${INSTALLER_PATH}"
|
VERSION="${VERSION%.pkg}"
|
||||||
|
gh release upload --repo Homebrew/brew "${VERSION}" "${INSTALLER_PATH}"
|
||||||
|
|
||||||
issue:
|
issue:
|
||||||
needs: [build, test, upload]
|
needs: [build, test, upload]
|
||||||
@ -253,7 +251,7 @@ jobs:
|
|||||||
issues: write
|
issues: write
|
||||||
steps:
|
steps:
|
||||||
- name: Open, update, or close pkg installer issue
|
- 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:
|
with:
|
||||||
title: Failed to publish pkg installer
|
title: Failed to publish pkg installer
|
||||||
body: >
|
body: >
|
||||||
@ -261,7 +259,7 @@ jobs:
|
|||||||
${{ github.ref_name }}. No pkg installer was uploaded to the GitHub
|
${{ github.ref_name }}. No pkg installer was uploaded to the GitHub
|
||||||
release.
|
release.
|
||||||
labels: bug,release blocker
|
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-existing: ${{ needs.upload.result == 'success' }}
|
||||||
close-from-author: github-actions[bot]
|
close-from-author: github-actions[bot]
|
||||||
close-comment: >
|
close-comment: >
|
||||||
|
5
.github/workflows/rubydoc.yml
vendored
5
.github/workflows/rubydoc.yml
vendored
@ -3,6 +3,7 @@ name: Ruby Documentation CI
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
|
- main
|
||||||
- master
|
- master
|
||||||
pull_request:
|
pull_request:
|
||||||
|
|
||||||
@ -28,7 +29,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
@ -42,7 +43,7 @@ jobs:
|
|||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Install Ruby
|
- name: Install Ruby
|
||||||
uses: ruby/setup-ruby@eaecf785f6a34567a6d97f686bbb7bccc1ac1e5c # v1.237.0
|
uses: ruby/setup-ruby@a4effe49ee8ee5b8b5091268c473a4628afb5651 # v1.245.0
|
||||||
with:
|
with:
|
||||||
bundler-cache: true
|
bundler-cache: true
|
||||||
working-directory: rubydoc
|
working-directory: rubydoc
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
name: Update schema data
|
name: Update SBOM schema
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
paths:
|
paths:
|
||||||
- .github/workflows/schemas.yml
|
- .github/workflows/sbom.yml
|
||||||
branches-ignore:
|
branches-ignore:
|
||||||
|
- main
|
||||||
- master
|
- master
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "0 0 * * *"
|
- cron: "0 0 * * *"
|
||||||
@ -17,25 +18,25 @@ defaults:
|
|||||||
shell: bash -xeuo pipefail {0}
|
shell: bash -xeuo pipefail {0}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
spdx:
|
sbom:
|
||||||
if: github.repository == 'Homebrew/brew'
|
if: github.repository == 'Homebrew/brew'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
test-bot: false
|
test-bot: false
|
||||||
|
|
||||||
- name: Configure Git user
|
- name: Configure Git user
|
||||||
uses: Homebrew/actions/git-user-config@master
|
uses: Homebrew/actions/git-user-config@main
|
||||||
with:
|
with:
|
||||||
username: BrewTestBot
|
username: BrewTestBot
|
||||||
|
|
||||||
- name: Set up commit signing
|
- name: Set up commit signing
|
||||||
uses: Homebrew/actions/setup-commit-signing@master
|
uses: Homebrew/actions/setup-commit-signing@main
|
||||||
with:
|
with:
|
||||||
signing_key: ${{ secrets.BREWTESTBOT_SSH_SIGNING_KEY }}
|
signing_key: ${{ secrets.BREWTESTBOT_SSH_SIGNING_KEY }}
|
||||||
|
|
||||||
@ -55,7 +56,7 @@ jobs:
|
|||||||
git checkout "${BRANCH}"
|
git checkout "${BRANCH}"
|
||||||
git checkout "Library/Homebrew/data/schemas"
|
git checkout "Library/Homebrew/data/schemas"
|
||||||
else
|
else
|
||||||
git checkout --no-track -B "${BRANCH}" origin/master
|
git checkout --no-track -B "${BRANCH}" origin/HEAD
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Intentionally tracking 2.3.x to match what we output in sbom.rb. 3.0 also doesn't have a JSON Schema.
|
# 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
|
if ! git diff --exit-code Library/Homebrew/data/schemas
|
||||||
then
|
then
|
||||||
git add "Library/Homebrew/data/schemas"
|
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"
|
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" ]]
|
if [[ "${PULL_REQUEST_STATE}" != "OPEN" ]]
|
||||||
then
|
then
|
||||||
echo "pull_request=true" >> "$GITHUB_OUTPUT"
|
echo "pull_request=true" >> "$GITHUB_OUTPUT"
|
||||||
@ -78,13 +80,13 @@ jobs:
|
|||||||
|
|
||||||
- name: Push commits
|
- name: Push commits
|
||||||
if: steps.update.outputs.committed == 'true'
|
if: steps.update.outputs.committed == 'true'
|
||||||
uses: Homebrew/actions/git-try-push@master
|
uses: Homebrew/actions/git-try-push@main
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
token: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
||||||
directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||||
branch: ${{ steps.update.outputs.branch }}
|
branch: ${{ steps.update.outputs.branch }}
|
||||||
force: true
|
force: true
|
||||||
origin_branch: "master"
|
origin_branch: "HEAD"
|
||||||
|
|
||||||
- name: Open a pull request
|
- name: Open a pull request
|
||||||
if: steps.update.outputs.pull_request == 'true'
|
if: steps.update.outputs.pull_request == 'true'
|
||||||
@ -92,3 +94,26 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
||||||
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
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:
|
paths:
|
||||||
- .github/workflows/sorbet.yml
|
- .github/workflows/sorbet.yml
|
||||||
branches-ignore:
|
branches-ignore:
|
||||||
|
- main
|
||||||
- master
|
- master
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "0 0 * * *"
|
- cron: "0 0 * * *"
|
||||||
@ -29,7 +30,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
@ -37,13 +38,13 @@ jobs:
|
|||||||
|
|
||||||
- name: Configure Git user
|
- name: Configure Git user
|
||||||
if: github.event_name != 'pull_request'
|
if: github.event_name != 'pull_request'
|
||||||
uses: Homebrew/actions/git-user-config@master
|
uses: Homebrew/actions/git-user-config@main
|
||||||
with:
|
with:
|
||||||
username: BrewTestBot
|
username: BrewTestBot
|
||||||
|
|
||||||
- name: Set up commit signing
|
- name: Set up commit signing
|
||||||
if: github.event_name != 'pull_request'
|
if: github.event_name != 'pull_request'
|
||||||
uses: Homebrew/actions/setup-commit-signing@master
|
uses: Homebrew/actions/setup-commit-signing@main
|
||||||
with:
|
with:
|
||||||
signing_key: ${{ secrets.BREWTESTBOT_SSH_SIGNING_KEY }}
|
signing_key: ${{ secrets.BREWTESTBOT_SSH_SIGNING_KEY }}
|
||||||
|
|
||||||
@ -63,7 +64,7 @@ jobs:
|
|||||||
git checkout "${BRANCH}"
|
git checkout "${BRANCH}"
|
||||||
git checkout "Library/Homebrew/sorbet"
|
git checkout "Library/Homebrew/sorbet"
|
||||||
else
|
else
|
||||||
git checkout --no-track -B "${BRANCH}" origin/master
|
git checkout --no-track -B "${BRANCH}" origin/HEAD
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -80,17 +81,17 @@ jobs:
|
|||||||
then
|
then
|
||||||
git add "Library/Homebrew/sorbet"
|
git add "Library/Homebrew/sorbet"
|
||||||
git commit -m "sorbet: Update RBI files." \
|
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"
|
if ! git diff --stat --exit-code "Library/Homebrew"
|
||||||
then
|
then
|
||||||
git add "Library/Homebrew/"
|
git add "Library/Homebrew/"
|
||||||
git commit -m "sorbet: Autobump sigils via Spoom" \
|
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
|
fi
|
||||||
|
|
||||||
echo "committed=true" >> "$GITHUB_OUTPUT"
|
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" ]]
|
if [[ "${PULL_REQUEST_STATE}" != "OPEN" ]]
|
||||||
then
|
then
|
||||||
echo "pull_request=true" >> "$GITHUB_OUTPUT"
|
echo "pull_request=true" >> "$GITHUB_OUTPUT"
|
||||||
@ -99,13 +100,13 @@ jobs:
|
|||||||
|
|
||||||
- name: Push commits
|
- name: Push commits
|
||||||
if: steps.commit.outputs.committed == 'true'
|
if: steps.commit.outputs.committed == 'true'
|
||||||
uses: Homebrew/actions/git-try-push@master
|
uses: Homebrew/actions/git-try-push@main
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
token: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
||||||
directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||||
branch: ${{ steps.update.outputs.branch }}
|
branch: ${{ steps.update.outputs.branch }}
|
||||||
force: true
|
force: true
|
||||||
origin_branch: "master"
|
origin_branch: "HEAD"
|
||||||
|
|
||||||
- name: Open a pull request
|
- name: Open a pull request
|
||||||
if: steps.commit.outputs.pull_request == 'true'
|
if: steps.commit.outputs.pull_request == 'true'
|
||||||
@ -113,3 +114,26 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
||||||
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
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:
|
paths:
|
||||||
- .github/workflows/spdx.yml
|
- .github/workflows/spdx.yml
|
||||||
branches-ignore:
|
branches-ignore:
|
||||||
|
- main
|
||||||
- master
|
- master
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "0 0 * * *"
|
- cron: "0 0 * * *"
|
||||||
@ -23,19 +24,19 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
test-bot: false
|
test-bot: false
|
||||||
|
|
||||||
- name: Configure Git user
|
- name: Configure Git user
|
||||||
uses: Homebrew/actions/git-user-config@master
|
uses: Homebrew/actions/git-user-config@main
|
||||||
with:
|
with:
|
||||||
username: BrewTestBot
|
username: BrewTestBot
|
||||||
|
|
||||||
- name: Set up commit signing
|
- name: Set up commit signing
|
||||||
uses: Homebrew/actions/setup-commit-signing@master
|
uses: Homebrew/actions/setup-commit-signing@main
|
||||||
with:
|
with:
|
||||||
signing_key: ${{ secrets.BREWTESTBOT_SSH_SIGNING_KEY }}
|
signing_key: ${{ secrets.BREWTESTBOT_SSH_SIGNING_KEY }}
|
||||||
|
|
||||||
@ -55,15 +56,16 @@ jobs:
|
|||||||
git checkout "${BRANCH}"
|
git checkout "${BRANCH}"
|
||||||
git checkout "Library/Homebrew/data/spdx"
|
git checkout "Library/Homebrew/data/spdx"
|
||||||
else
|
else
|
||||||
git checkout --no-track -B "${BRANCH}" origin/master
|
git checkout --no-track -B "${BRANCH}" origin/HEAD
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if brew update-license-data
|
if brew update-license-data
|
||||||
then
|
then
|
||||||
git add "Library/Homebrew/data/spdx"
|
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"
|
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" ]]
|
if [[ "${PULL_REQUEST_STATE}" != "OPEN" ]]
|
||||||
then
|
then
|
||||||
echo "pull_request=true" >> "$GITHUB_OUTPUT"
|
echo "pull_request=true" >> "$GITHUB_OUTPUT"
|
||||||
@ -72,13 +74,13 @@ jobs:
|
|||||||
|
|
||||||
- name: Push commits
|
- name: Push commits
|
||||||
if: steps.update.outputs.committed == 'true'
|
if: steps.update.outputs.committed == 'true'
|
||||||
uses: Homebrew/actions/git-try-push@master
|
uses: Homebrew/actions/git-try-push@main
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
token: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
||||||
directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||||
branch: ${{ steps.update.outputs.branch }}
|
branch: ${{ steps.update.outputs.branch }}
|
||||||
force: true
|
force: true
|
||||||
origin_branch: "master"
|
origin_branch: "HEAD"
|
||||||
|
|
||||||
- name: Open a pull request
|
- name: Open a pull request
|
||||||
if: steps.update.outputs.pull_request == 'true'
|
if: steps.update.outputs.pull_request == 'true'
|
||||||
@ -86,3 +88,26 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
||||||
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
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:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
|
- main
|
||||||
- master
|
- master
|
||||||
paths:
|
paths:
|
||||||
- .github/workflows/sponsors-maintainers-man-completions.yml
|
- .github/workflows/sponsors-maintainers-man-completions.yml
|
||||||
@ -32,19 +33,19 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Setup Homebrew
|
- name: Setup Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
test-bot: false
|
test-bot: false
|
||||||
|
|
||||||
- name: Configure Git user
|
- name: Configure Git user
|
||||||
uses: Homebrew/actions/git-user-config@master
|
uses: Homebrew/actions/git-user-config@main
|
||||||
with:
|
with:
|
||||||
username: BrewTestBot
|
username: BrewTestBot
|
||||||
|
|
||||||
- name: Set up commit signing
|
- name: Set up commit signing
|
||||||
uses: Homebrew/actions/setup-commit-signing@master
|
uses: Homebrew/actions/setup-commit-signing@main
|
||||||
with:
|
with:
|
||||||
signing_key: ${{ secrets.BREWTESTBOT_SSH_SIGNING_KEY }}
|
signing_key: ${{ secrets.BREWTESTBOT_SSH_SIGNING_KEY }}
|
||||||
|
|
||||||
@ -60,7 +61,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
git fetch origin
|
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
|
then
|
||||||
BRANCH="$GITHUB_REF_NAME"
|
BRANCH="$GITHUB_REF_NAME"
|
||||||
else
|
else
|
||||||
@ -76,7 +77,7 @@ jobs:
|
|||||||
"manpages/brew.1" \
|
"manpages/brew.1" \
|
||||||
"completions"
|
"completions"
|
||||||
else
|
else
|
||||||
git checkout --force --no-track -B "${BRANCH}" origin/master
|
git checkout --force --no-track -B "${BRANCH}" origin/HEAD
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if brew update-sponsors
|
if brew update-sponsors
|
||||||
@ -111,7 +112,7 @@ jobs:
|
|||||||
if [[ -n "${COMMITTED-}" ]]
|
if [[ -n "${COMMITTED-}" ]]
|
||||||
then
|
then
|
||||||
echo "committed=true" >> "$GITHUB_OUTPUT"
|
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" ]]
|
if [[ "${PULL_REQUEST_STATE}" != "OPEN" ]]
|
||||||
then
|
then
|
||||||
echo "pull_request=true" >> "$GITHUB_OUTPUT"
|
echo "pull_request=true" >> "$GITHUB_OUTPUT"
|
||||||
@ -124,7 +125,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Push commits
|
- name: Push commits
|
||||||
if: steps.update.outputs.committed == 'true'
|
if: steps.update.outputs.committed == 'true'
|
||||||
uses: Homebrew/actions/git-try-push@master
|
uses: Homebrew/actions/git-try-push@main
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
token: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
||||||
directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||||
@ -137,3 +138,26 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
||||||
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
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.
|
||||||
|
4
.github/workflows/stale-issues.yml
vendored
4
.github/workflows/stale-issues.yml
vendored
@ -38,7 +38,7 @@ jobs:
|
|||||||
pull-requests: write
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- name: Mark/Close Stale Issues and Pull Requests
|
- name: Mark/Close Stale Issues and Pull Requests
|
||||||
uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e # v9.0.0
|
uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
days-before-stale: 21
|
days-before-stale: 21
|
||||||
@ -68,7 +68,7 @@ jobs:
|
|||||||
pull-requests: write
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- name: Mark/Close Stale `bump-formula-pr` and `bump-cask-pr` Pull Requests
|
- name: Mark/Close Stale `bump-formula-pr` and `bump-cask-pr` Pull Requests
|
||||||
uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e # v9.0.0
|
uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
days-before-stale: 2
|
days-before-stale: 2
|
||||||
|
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 }}
|
136
.github/workflows/tests.yml
vendored
136
.github/workflows/tests.yml
vendored
@ -3,6 +3,7 @@ name: CI
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
|
- main
|
||||||
- master
|
- master
|
||||||
pull_request:
|
pull_request:
|
||||||
merge_group:
|
merge_group:
|
||||||
@ -32,7 +33,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
@ -80,11 +81,11 @@ jobs:
|
|||||||
name: tap syntax
|
name: tap syntax
|
||||||
needs: syntax
|
needs: syntax
|
||||||
if: github.repository_owner == 'Homebrew'
|
if: github.repository_owner == 'Homebrew'
|
||||||
runs-on: macos-14
|
runs-on: macos-15
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: true
|
core: true
|
||||||
cask: true
|
cask: true
|
||||||
@ -135,13 +136,13 @@ jobs:
|
|||||||
if: github.repository_owner == 'Homebrew' && github.event_name != 'push'
|
if: github.repository_owner == 'Homebrew' && github.event_name != 'push'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: ghcr.io/homebrew/brew:master
|
image: ghcr.io/homebrew/brew:main
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: true
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
test-bot: false
|
test-bot: false
|
||||||
|
|
||||||
@ -162,7 +163,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: true
|
core: true
|
||||||
cask: true
|
cask: true
|
||||||
@ -185,14 +186,14 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
test-bot: false
|
test-bot: false
|
||||||
|
|
||||||
- name: Configure Git user
|
- name: Configure Git user
|
||||||
uses: Homebrew/actions/git-user-config@master
|
uses: Homebrew/actions/git-user-config@main
|
||||||
with:
|
with:
|
||||||
username: BrewTestBot
|
username: BrewTestBot
|
||||||
|
|
||||||
@ -213,14 +214,14 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- name: update-test (Ubuntu)
|
- name: update-test (Linux)
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
- name: update-test (macOS)
|
- name: update-test (macOS)
|
||||||
runs-on: macos-15
|
runs-on: macos-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
@ -237,7 +238,6 @@ jobs:
|
|||||||
name: ${{ matrix.name }}
|
name: ${{ matrix.name }}
|
||||||
needs: syntax
|
needs: syntax
|
||||||
runs-on: ${{ matrix.runs-on }}
|
runs-on: ${{ matrix.runs-on }}
|
||||||
container: ${{ matrix.container }}
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
@ -247,23 +247,16 @@ jobs:
|
|||||||
- name: tests (generic OS)
|
- name: tests (generic OS)
|
||||||
test-flags: --generic --coverage
|
test-flags: --generic --coverage
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
- name: tests (Ubuntu 24.04)
|
- name: tests (Linux)
|
||||||
test-flags: --coverage
|
test-flags: --coverage
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
- name: tests (Ubuntu 22.04)
|
- name: tests (macOS)
|
||||||
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)
|
|
||||||
test-flags: --coverage
|
test-flags: --coverage
|
||||||
runs-on: macos-15
|
runs-on: macos-15
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
# We only test needs_homebrew_core tests on macOS because
|
# We only test needs_homebrew_core tests on macOS because
|
||||||
# homebrew/core is not available by default on GitHub-hosted Ubuntu
|
# homebrew/core is not available by default on GitHub-hosted Ubuntu
|
||||||
@ -335,21 +328,21 @@ jobs:
|
|||||||
filenames=$(find Library/Homebrew/test/junit -name 'rspec*.xml' -print | tr '\n' ',')
|
filenames=$(find Library/Homebrew/test/junit -name 'rspec*.xml' -print | tr '\n' ',')
|
||||||
echo "filenames=${filenames%,}" >> "$GITHUB_OUTPUT"
|
echo "filenames=${filenames%,}" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
- uses: codecov/test-results-action@f2dba722c67b86c6caa034178c6e4d35335f6706 # v1.1.0
|
- uses: codecov/test-results-action@47f89e9acb64b76debcd5ea40642d25a4adced9f # v1.1.1
|
||||||
with:
|
with:
|
||||||
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||||
files: ${{ steps.junit_xml.outputs.filenames }}
|
files: ${{ steps.junit_xml.outputs.filenames }}
|
||||||
disable_search: true
|
disable_search: true
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
|
||||||
- uses: codecov/codecov-action@ad3126e916f78f00edff4ed0317cf185271ccc2d # v5.4.2
|
- uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
|
||||||
with:
|
with:
|
||||||
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||||
files: Library/Homebrew/test/coverage/coverage.xml
|
files: Library/Homebrew/test/coverage/coverage.xml
|
||||||
disable_search: true
|
disable_search: true
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
|
||||||
test-default-formula:
|
test-bot:
|
||||||
name: ${{ matrix.name }}
|
name: ${{ matrix.name }}
|
||||||
needs: syntax
|
needs: syntax
|
||||||
if: github.repository_owner == 'Homebrew' && github.event_name != 'push'
|
if: github.repository_owner == 'Homebrew' && github.event_name != 'push'
|
||||||
@ -358,36 +351,76 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- name: test default formula (Ubuntu 24.04)
|
- name: test-bot (Linux arm64)
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-24.04-arm
|
||||||
container: ghcr.io/homebrew/ubuntu24.04:latest
|
container: ghcr.io/homebrew/ubuntu24.04:latest
|
||||||
- name: test default formula (Ubuntu 22.04)
|
- name: test-bot (Linux x86_64)
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container: ghcr.io/homebrew/ubuntu22.04:master
|
container: ghcr.io/homebrew/ubuntu22.04:main
|
||||||
- name: test default formula (Ubuntu 20.04)
|
# Use Debian Old Stable for testing Homebrew's glibc support.
|
||||||
|
- name: test-bot (Linux Homebrew glibc)
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container: ghcr.io/homebrew/ubuntu20.04:latest
|
container: debian:oldstable
|
||||||
- name: test default formula (macOS 13 x86_64)
|
- name: test-bot (macOS x86_64)
|
||||||
runs-on: macos-13
|
runs-on: macos-13
|
||||||
- name: test default formula (macOS 15 arm64)
|
- name: test-bot (macOS arm64)
|
||||||
runs-on: macos-15
|
runs-on: macos-15
|
||||||
env:
|
env:
|
||||||
HOMEBREW_TEST_BOT_ANALYTICS: 1
|
HOMEBREW_TEST_BOT_ANALYTICS: 1
|
||||||
HOMEBREW_ENFORCE_SBOM: 1
|
HOMEBREW_ENFORCE_SBOM: 1
|
||||||
steps:
|
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
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: true
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
test-bot: true
|
test-bot: true
|
||||||
|
|
||||||
- run: brew test-bot --only-cleanup-before
|
- run: brew test-bot --only-cleanup-before
|
||||||
|
|
||||||
- name: Setup environment variables
|
- name: Setup environment variables
|
||||||
if: matrix.container == 'ghcr.io/homebrew/ubuntu20.04:latest'
|
run: |
|
||||||
run: echo "HOMEBREW_GLIBC_TESTING=1" >> "$GITHUB_ENV"
|
# 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
|
- run: brew test-bot --only-setup
|
||||||
|
|
||||||
@ -395,7 +428,7 @@ jobs:
|
|||||||
|
|
||||||
- run: brew test-bot --only-formulae --only-json-tab --test-default-formula
|
- run: brew test-bot --only-formulae --only-json-tab --test-default-formula
|
||||||
|
|
||||||
test-brew-bundle-services:
|
bundle-and-services:
|
||||||
name: ${{ matrix.name }}
|
name: ${{ matrix.name }}
|
||||||
needs: syntax
|
needs: syntax
|
||||||
if: github.repository_owner == 'Homebrew' && github.event_name != 'push'
|
if: github.repository_owner == 'Homebrew' && github.event_name != 'push'
|
||||||
@ -403,16 +436,16 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- name: test brew bundle and brew services (Ubuntu)
|
- name: bundle and services (Linux)
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
- name: test brew bundle and brew services (macOS)
|
- name: bundle and services (macOS)
|
||||||
runs-on: macos-15
|
runs-on: macos-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: true
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
test-bot: false
|
test-bot: false
|
||||||
|
|
||||||
@ -449,19 +482,22 @@ jobs:
|
|||||||
brew services cleanup
|
brew services cleanup
|
||||||
brew bundle cleanup --force
|
brew bundle cleanup --force
|
||||||
|
|
||||||
test-analytics:
|
analytics:
|
||||||
runs-on: ${{ matrix.os }}
|
name: ${{ matrix.name }}
|
||||||
|
runs-on: ${{ matrix.runs-on }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os:
|
include:
|
||||||
- ubuntu-latest
|
- name: analytics (Linux)
|
||||||
- macos-latest
|
runs-on: ubuntu-latest
|
||||||
|
- name: analytics (macOS)
|
||||||
|
runs-on: macos-latest
|
||||||
needs: syntax
|
needs: syntax
|
||||||
if: github.repository_owner == 'Homebrew' && github.event_name != 'push'
|
if: github.repository_owner == 'Homebrew' && github.event_name != 'push'
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
|
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
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:
|
paths:
|
||||||
- .github/workflows/vendor-gems.yml
|
- .github/workflows/vendor-gems.yml
|
||||||
branches-ignore:
|
branches-ignore:
|
||||||
|
- main
|
||||||
- master
|
- master
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
inputs:
|
||||||
@ -31,7 +32,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
@ -39,13 +40,13 @@ jobs:
|
|||||||
|
|
||||||
- name: Configure Git user
|
- name: Configure Git user
|
||||||
if: github.event_name == 'workflow_dispatch'
|
if: github.event_name == 'workflow_dispatch'
|
||||||
uses: Homebrew/actions/git-user-config@master
|
uses: Homebrew/actions/git-user-config@main
|
||||||
with:
|
with:
|
||||||
username: BrewTestBot
|
username: BrewTestBot
|
||||||
|
|
||||||
- name: Set up commit signing
|
- name: Set up commit signing
|
||||||
if: github.event_name == 'workflow_dispatch'
|
if: github.event_name == 'workflow_dispatch'
|
||||||
uses: Homebrew/actions/setup-commit-signing@master
|
uses: Homebrew/actions/setup-commit-signing@main
|
||||||
with:
|
with:
|
||||||
signing_key: ${{ secrets.BREWTESTBOT_SSH_SIGNING_KEY }}
|
signing_key: ${{ secrets.BREWTESTBOT_SSH_SIGNING_KEY }}
|
||||||
|
|
||||||
@ -100,7 +101,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Push to pull request
|
- name: Push to pull request
|
||||||
if: github.event_name == 'workflow_dispatch'
|
if: github.event_name == 'workflow_dispatch'
|
||||||
uses: Homebrew/actions/git-try-push@master
|
uses: Homebrew/actions/git-try-push@main
|
||||||
with:
|
with:
|
||||||
token: ${{ steps.app-token.outputs.token }}
|
token: ${{ steps.app-token.outputs.token }}
|
||||||
directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
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:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: 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:
|
rules:
|
||||||
unpinned-uses:
|
unpinned-uses:
|
||||||
config:
|
config:
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -164,6 +164,7 @@
|
|||||||
!/completions
|
!/completions
|
||||||
!/docs
|
!/docs
|
||||||
!/manpages
|
!/manpages
|
||||||
|
!/CODEOWNERS
|
||||||
|
|
||||||
# Unignore our packaging files
|
# Unignore our packaging files
|
||||||
!/package
|
!/package
|
||||||
@ -172,6 +173,7 @@
|
|||||||
# Ignore generated documentation site
|
# Ignore generated documentation site
|
||||||
/docs/_site
|
/docs/_site
|
||||||
/docs/.jekyll-metadata
|
/docs/.jekyll-metadata
|
||||||
|
/docs/tmp/.htmlproofer
|
||||||
/docs/vendor
|
/docs/vendor
|
||||||
/docs/Gemfile.lock
|
/docs/Gemfile.lock
|
||||||
|
|
||||||
|
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
|
#!/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
|
"${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",
|
"id": "default",
|
||||||
"name": "Brew Typecheck",
|
"name": "Brew Typecheck",
|
||||||
"description": "Default configuration",
|
"description": "Default configuration",
|
||||||
"cwd": "${workspaceFolder}",
|
|
||||||
"command": [
|
"command": [
|
||||||
"./bin/brew",
|
"./bin/brew",
|
||||||
"typecheck",
|
"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
|
@ -26,7 +26,7 @@ AllCops:
|
|||||||
Include:
|
Include:
|
||||||
- "**/*.rbi"
|
- "**/*.rbi"
|
||||||
Exclude:
|
Exclude:
|
||||||
- "Homebrew/sorbet/rbi/{dsl,gems}/**/*.rbi"
|
- "Homebrew/sorbet/rbi/{annotations,dsl,gems}/**/*.rbi"
|
||||||
- "Homebrew/sorbet/rbi/parser*.rbi"
|
- "Homebrew/sorbet/rbi/parser*.rbi"
|
||||||
- "Homebrew/bin/*"
|
- "Homebrew/bin/*"
|
||||||
- "Homebrew/vendor/**/*"
|
- "Homebrew/vendor/**/*"
|
||||||
@ -304,7 +304,7 @@ Sorbet/StrictSigil:
|
|||||||
- "Homebrew/utils/ruby_check_version_script.rb" # A standalone script.
|
- "Homebrew/utils/ruby_check_version_script.rb" # A standalone script.
|
||||||
- "Homebrew/{standalone,startup}/*.rb" # These are loaded before sorbet-runtime
|
- "Homebrew/{standalone,startup}/*.rb" # These are loaded before sorbet-runtime
|
||||||
- "Homebrew/test/**/*.rb"
|
- "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:
|
Sorbet/TrueSigil:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
@ -25,6 +25,7 @@ Style/Documentation:
|
|||||||
- Homebrew
|
- Homebrew
|
||||||
Include:
|
Include:
|
||||||
- abstract_command.rb
|
- abstract_command.rb
|
||||||
|
- autobump_constants.rb
|
||||||
- cask/cask.rb
|
- cask/cask.rb
|
||||||
- cask/dsl.rb
|
- cask/dsl.rb
|
||||||
- cask/dsl/version.rb
|
- cask/dsl/version.rb
|
||||||
|
@ -1 +1 @@
|
|||||||
3.4.3
|
3.4.4
|
||||||
|
@ -11,13 +11,13 @@ GEM
|
|||||||
coderay (1.1.3)
|
coderay (1.1.3)
|
||||||
concurrent-ruby (1.3.5)
|
concurrent-ruby (1.3.5)
|
||||||
csv (3.3.4)
|
csv (3.3.4)
|
||||||
diff-lcs (1.6.1)
|
diff-lcs (1.6.2)
|
||||||
docile (1.4.1)
|
docile (1.4.1)
|
||||||
elftools (1.3.1)
|
elftools (1.3.1)
|
||||||
bindata (~> 2)
|
bindata (~> 2)
|
||||||
erubi (1.13.1)
|
erubi (1.13.1)
|
||||||
hana (1.3.7)
|
hana (1.3.7)
|
||||||
json (2.11.3)
|
json (2.12.0)
|
||||||
json_schemer (2.4.0)
|
json_schemer (2.4.0)
|
||||||
bigdecimal
|
bigdecimal
|
||||||
hana (~> 1.3)
|
hana (~> 1.3)
|
||||||
@ -25,14 +25,14 @@ GEM
|
|||||||
simpleidn (~> 0.2)
|
simpleidn (~> 0.2)
|
||||||
kramdown (2.5.1)
|
kramdown (2.5.1)
|
||||||
rexml (>= 3.3.9)
|
rexml (>= 3.3.9)
|
||||||
language_server-protocol (3.17.0.4)
|
language_server-protocol (3.17.0.5)
|
||||||
lint_roller (1.1.0)
|
lint_roller (1.1.0)
|
||||||
logger (1.7.0)
|
logger (1.7.0)
|
||||||
method_source (1.1.0)
|
method_source (1.1.0)
|
||||||
minitest (5.25.5)
|
minitest (5.25.5)
|
||||||
netrc (0.11.0)
|
netrc (0.11.0)
|
||||||
parallel (1.27.0)
|
parallel (1.27.0)
|
||||||
parallel_tests (5.1.0)
|
parallel_tests (5.2.0)
|
||||||
parallel
|
parallel
|
||||||
parser (3.3.8.0)
|
parser (3.3.8.0)
|
||||||
ast (~> 2.4.1)
|
ast (~> 2.4.1)
|
||||||
@ -48,11 +48,11 @@ GEM
|
|||||||
pycall (1.5.2)
|
pycall (1.5.2)
|
||||||
racc (1.8.1)
|
racc (1.8.1)
|
||||||
rainbow (3.1.1)
|
rainbow (3.1.1)
|
||||||
rbi (0.3.2)
|
rbi (0.3.3)
|
||||||
prism (~> 1.0)
|
prism (~> 1.0)
|
||||||
rbs (>= 3.4.4)
|
rbs (>= 3.4.4)
|
||||||
sorbet-runtime (>= 0.5.9204)
|
sorbet-runtime (>= 0.5.9204)
|
||||||
rbs (3.9.2)
|
rbs (3.9.4)
|
||||||
logger
|
logger
|
||||||
redcarpet (3.6.1)
|
redcarpet (3.6.1)
|
||||||
regexp_parser (2.10.0)
|
regexp_parser (2.10.0)
|
||||||
@ -78,7 +78,7 @@ GEM
|
|||||||
rspec-support (3.13.3)
|
rspec-support (3.13.3)
|
||||||
rspec_junit_formatter (0.6.0)
|
rspec_junit_formatter (0.6.0)
|
||||||
rspec-core (>= 2, < 4, != 2.12.0)
|
rspec-core (>= 2, < 4, != 2.12.0)
|
||||||
rubocop (1.75.5)
|
rubocop (1.75.6)
|
||||||
json (~> 2.3)
|
json (~> 2.3)
|
||||||
language_server-protocol (~> 3.17.0.2)
|
language_server-protocol (~> 3.17.0.2)
|
||||||
lint_roller (~> 1.1.0)
|
lint_roller (~> 1.1.0)
|
||||||
@ -104,7 +104,7 @@ GEM
|
|||||||
rubocop (~> 1.72, >= 1.72.1)
|
rubocop (~> 1.72, >= 1.72.1)
|
||||||
rubocop-sorbet (0.10.0)
|
rubocop-sorbet (0.10.0)
|
||||||
rubocop (>= 1)
|
rubocop (>= 1)
|
||||||
ruby-lsp (0.23.17)
|
ruby-lsp (0.23.21)
|
||||||
language_server-protocol (~> 3.17.0)
|
language_server-protocol (~> 3.17.0)
|
||||||
prism (>= 1.2, < 2.0)
|
prism (>= 1.2, < 2.0)
|
||||||
rbs (>= 3, < 4)
|
rbs (>= 3, < 4)
|
||||||
@ -122,19 +122,19 @@ GEM
|
|||||||
simplecov-html (0.13.1)
|
simplecov-html (0.13.1)
|
||||||
simplecov_json_formatter (0.1.4)
|
simplecov_json_formatter (0.1.4)
|
||||||
simpleidn (0.2.3)
|
simpleidn (0.2.3)
|
||||||
sorbet (0.5.12079)
|
sorbet (0.5.12117)
|
||||||
sorbet-static (= 0.5.12079)
|
sorbet-static (= 0.5.12117)
|
||||||
sorbet-runtime (0.5.12079)
|
sorbet-runtime (0.5.12117)
|
||||||
sorbet-static (0.5.12079-aarch64-linux)
|
sorbet-static (0.5.12117-aarch64-linux)
|
||||||
sorbet-static (0.5.12079-universal-darwin)
|
sorbet-static (0.5.12117-universal-darwin)
|
||||||
sorbet-static (0.5.12079-x86_64-linux)
|
sorbet-static (0.5.12117-x86_64-linux)
|
||||||
sorbet-static-and-runtime (0.5.12079)
|
sorbet-static-and-runtime (0.5.12117)
|
||||||
sorbet (= 0.5.12079)
|
sorbet (= 0.5.12117)
|
||||||
sorbet-runtime (= 0.5.12079)
|
sorbet-runtime (= 0.5.12117)
|
||||||
spoom (1.6.2)
|
spoom (1.6.3)
|
||||||
erubi (>= 1.10.0)
|
erubi (>= 1.10.0)
|
||||||
prism (>= 0.28.0)
|
prism (>= 0.28.0)
|
||||||
rbi (>= 0.3.1)
|
rbi (>= 0.3.3)
|
||||||
rexml (>= 3.2.6)
|
rexml (>= 3.2.6)
|
||||||
sorbet-static-and-runtime (>= 0.5.10187)
|
sorbet-static-and-runtime (>= 0.5.10187)
|
||||||
thor (>= 0.19.2)
|
thor (>= 0.19.2)
|
||||||
@ -153,7 +153,7 @@ GEM
|
|||||||
unicode-display_width (3.1.4)
|
unicode-display_width (3.1.4)
|
||||||
unicode-emoji (~> 4.0, >= 4.0.4)
|
unicode-emoji (~> 4.0, >= 4.0.4)
|
||||||
unicode-emoji (4.0.4)
|
unicode-emoji (4.0.4)
|
||||||
vernier (1.7.0)
|
vernier (1.7.1)
|
||||||
warning (1.5.0)
|
warning (1.5.0)
|
||||||
yard (0.9.37)
|
yard (0.9.37)
|
||||||
yard-sorbet (0.9.0)
|
yard-sorbet (0.9.0)
|
||||||
@ -213,7 +213,7 @@ DEPENDENCIES
|
|||||||
yard-sorbet
|
yard-sorbet
|
||||||
|
|
||||||
RUBY VERSION
|
RUBY VERSION
|
||||||
ruby 3.4.3p32
|
ruby 3.4.4p34
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
2.6.7
|
2.6.7
|
||||||
|
@ -39,12 +39,12 @@ class PATH
|
|||||||
self
|
self
|
||||||
end
|
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)
|
def select(&block)
|
||||||
self.class.new(@paths.select(&block))
|
self.class.new(@paths.select(&block))
|
||||||
end
|
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)
|
def reject(&block)
|
||||||
self.class.new(@paths.reject(&block))
|
self.class.new(@paths.reject(&block))
|
||||||
end
|
end
|
||||||
|
@ -29,36 +29,36 @@ module Homebrew
|
|||||||
Alias.new(name).remove
|
Alias.new(name).remove
|
||||||
end
|
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)
|
def self.each(only, &block)
|
||||||
Dir["#{HOMEBREW_ALIASES}/*"].each do |path|
|
Dir["#{HOMEBREW_ALIASES}/*"].each do |path|
|
||||||
next if path.end_with? "~" # skip Emacs-like backup files
|
next if path.end_with? "~" # skip Emacs-like backup files
|
||||||
next if File.directory?(path)
|
next if File.directory?(path)
|
||||||
|
|
||||||
_shebang, _meta, *lines = File.readlines(path)
|
_shebang, meta, *lines = File.readlines(path)
|
||||||
target = File.basename(path)
|
name = T.must(meta)[/alias: brew (\S+)/, 1] || File.basename(path)
|
||||||
next if !only.empty? && only.exclude?(target)
|
next if !only.empty? && only.exclude?(name)
|
||||||
|
|
||||||
lines.reject! { |line| line.start_with?("#") || line =~ /^\s*$/ }
|
lines.reject! { |line| line.start_with?("#") || line =~ /^\s*$/ }
|
||||||
first_line = T.must(lines.first)
|
first_line = T.must(lines.first)
|
||||||
cmd = first_line.chomp
|
command = first_line.chomp
|
||||||
cmd.sub!(/ \$\*$/, "")
|
command.sub!(/ \$\*$/, "")
|
||||||
|
|
||||||
if cmd.start_with? "brew "
|
if command.start_with? "brew "
|
||||||
cmd.sub!(/^brew /, "")
|
command.sub!(/^brew /, "")
|
||||||
else
|
else
|
||||||
cmd = "!#{cmd}"
|
command = "!#{command}"
|
||||||
end
|
end
|
||||||
|
|
||||||
yield target, cmd if block.present?
|
yield name, command if block.present?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { params(aliases: String).void }
|
sig { params(aliases: String).void }
|
||||||
def self.show(*aliases)
|
def self.show(*aliases)
|
||||||
each([*aliases]) do |target, cmd|
|
each([*aliases]) do |name, command|
|
||||||
puts "brew alias #{target}='#{cmd}'"
|
puts "brew alias #{name}='#{command}'"
|
||||||
existing_alias = Alias.new(target, cmd)
|
existing_alias = Alias.new(name, command)
|
||||||
existing_alias.link unless existing_alias.symlink.exist?
|
existing_alias.link unless existing_alias.symlink.exist?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "api/analytics"
|
require "api/analytics"
|
||||||
@ -11,10 +11,10 @@ module Homebrew
|
|||||||
module API
|
module API
|
||||||
extend Cachable
|
extend Cachable
|
||||||
|
|
||||||
HOMEBREW_CACHE_API = (HOMEBREW_CACHE/"api").freeze
|
HOMEBREW_CACHE_API = T.let((HOMEBREW_CACHE/"api").freeze, Pathname)
|
||||||
HOMEBREW_CACHE_API_SOURCE = (HOMEBREW_CACHE/"api-source").freeze
|
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)
|
def self.fetch(endpoint)
|
||||||
return cache[endpoint] if cache.present? && cache.key?(endpoint)
|
return cache[endpoint] if cache.present? && cache.key?(endpoint)
|
||||||
|
|
||||||
@ -33,7 +33,8 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
|
|
||||||
sig {
|
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,
|
def self.fetch_json_api_file(endpoint, target: HOMEBREW_CACHE_API/endpoint,
|
||||||
stale_seconds: Homebrew::EnvConfig.api_auto_update_secs.to_i)
|
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
|
mtime = insecure_download ? Time.new(1970, 1, 1) : Time.now
|
||||||
FileUtils.touch(target, mtime:) unless skip_download
|
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
|
rescue JSON::ParserError
|
||||||
target.unlink
|
target.unlink
|
||||||
retry_count += 1
|
retry_count += 1
|
||||||
@ -122,14 +124,17 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { params(json: Hash).returns(Hash) }
|
sig {
|
||||||
def self.merge_variations(json)
|
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")
|
return json unless json.key?("variations")
|
||||||
|
|
||||||
bottle_tag = ::Utils::Bottles::Tag.new(system: Homebrew::SimulateSystem.current_os,
|
bottle_tag ||= Homebrew::SimulateSystem.current_tag
|
||||||
arch: Homebrew::SimulateSystem.current_arch)
|
|
||||||
|
|
||||||
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)
|
json = json.merge(variation)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -147,7 +152,10 @@ module Homebrew
|
|||||||
false
|
false
|
||||||
end
|
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)
|
private_class_method def self.verify_and_parse_jws(json_data)
|
||||||
signatures = json_data["signatures"]
|
signatures = json_data["signatures"]
|
||||||
homebrew_signature = signatures&.find { |sig| sig.dig("header", "kid") == "homebrew-1" }
|
homebrew_signature = signatures&.find { |sig| sig.dig("header", "kid") == "homebrew-1" }
|
||||||
|
@ -10,7 +10,6 @@ module Homebrew
|
|||||||
def analytics_api_path
|
def analytics_api_path
|
||||||
"analytics"
|
"analytics"
|
||||||
end
|
end
|
||||||
alias generic_analytics_api_path analytics_api_path
|
|
||||||
|
|
||||||
sig { params(category: String, days: T.any(Integer, String)).returns(T::Hash[String, T.untyped]) }
|
sig { params(category: String, days: T.any(Integer, String)).returns(T::Hash[String, T.untyped]) }
|
||||||
def fetch(category, days)
|
def fetch(category, days)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "extend/cachable"
|
require "cachable"
|
||||||
require "api/download"
|
require "api/download"
|
||||||
|
|
||||||
module Homebrew
|
module Homebrew
|
||||||
@ -12,9 +12,16 @@ module Homebrew
|
|||||||
|
|
||||||
DEFAULT_API_FILENAME = "cask.jws.json"
|
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
|
private_class_method :cache
|
||||||
|
|
||||||
sig { params(token: String).returns(Hash) }
|
sig { params(token: String).returns(T::Hash[String, T.untyped]) }
|
||||||
def self.fetch(token)
|
def self.fetch(token)
|
||||||
Homebrew::API.fetch "cask/#{token}.json"
|
Homebrew::API.fetch "cask/#{token}.json"
|
||||||
end
|
end
|
||||||
@ -40,13 +47,14 @@ module Homebrew
|
|||||||
.load(config: cask.config)
|
.load(config: cask.config)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(Pathname) }
|
||||||
def self.cached_json_file_path
|
def self.cached_json_file_path
|
||||||
HOMEBREW_CACHE_API/DEFAULT_API_FILENAME
|
HOMEBREW_CACHE_API/api_filename
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { returns(T::Boolean) }
|
sig { returns(T::Boolean) }
|
||||||
def self.download_and_cache_data!
|
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["renames"] = {}
|
||||||
cache["casks"] = json_casks.to_h do |json_cask|
|
cache["casks"] = json_casks.to_h do |json_cask|
|
||||||
@ -63,7 +71,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
private_class_method :download_and_cache_data!
|
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
|
def self.all_casks
|
||||||
unless cache.key?("casks")
|
unless cache.key?("casks")
|
||||||
json_updated = download_and_cache_data!
|
json_updated = download_and_cache_data!
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# typed: strict
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "extend/cachable"
|
require "cachable"
|
||||||
require "api/download"
|
require "api/download"
|
||||||
|
|
||||||
module Homebrew
|
module Homebrew
|
||||||
@ -12,6 +12,13 @@ module Homebrew
|
|||||||
|
|
||||||
DEFAULT_API_FILENAME = "formula.jws.json"
|
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
|
private_class_method :cache
|
||||||
|
|
||||||
sig { params(name: String).returns(T::Hash[String, T.untyped]) }
|
sig { params(name: String).returns(T::Hash[String, T.untyped]) }
|
||||||
@ -42,12 +49,12 @@ module Homebrew
|
|||||||
|
|
||||||
sig { returns(Pathname) }
|
sig { returns(Pathname) }
|
||||||
def self.cached_json_file_path
|
def self.cached_json_file_path
|
||||||
HOMEBREW_CACHE_API/DEFAULT_API_FILENAME
|
HOMEBREW_CACHE_API/api_filename
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { returns(T::Boolean) }
|
sig { returns(T::Boolean) }
|
||||||
def self.download_and_cache_data!
|
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["aliases"] = {}
|
||||||
cache["renames"] = {}
|
cache["renames"] = {}
|
||||||
|
@ -1,22 +1,26 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
# Used to substitute common paths with generic placeholders when generating JSON for the API.
|
# Used to substitute common paths with generic placeholders when generating JSON for the API.
|
||||||
module APIHashable
|
module APIHashable
|
||||||
|
sig { void }
|
||||||
def generating_hash!
|
def generating_hash!
|
||||||
return if generating_hash?
|
return if generating_hash?
|
||||||
|
|
||||||
# Apply monkeypatches for API generation
|
# Apply monkeypatches for API generation
|
||||||
@old_homebrew_prefix = HOMEBREW_PREFIX
|
@old_homebrew_prefix = T.let(HOMEBREW_PREFIX, T.nilable(Pathname))
|
||||||
@old_homebrew_cellar = HOMEBREW_CELLAR
|
@old_homebrew_cellar = T.let(HOMEBREW_CELLAR, T.nilable(Pathname))
|
||||||
@old_home = Dir.home
|
@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.send(:remove_const, :HOMEBREW_PREFIX)
|
||||||
Object.const_set(:HOMEBREW_PREFIX, Pathname.new(HOMEBREW_PREFIX_PLACEHOLDER))
|
Object.const_set(:HOMEBREW_PREFIX, Pathname.new(HOMEBREW_PREFIX_PLACEHOLDER))
|
||||||
ENV["HOME"] = HOMEBREW_HOME_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
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def generated_hash!
|
def generated_hash!
|
||||||
return unless generating_hash?
|
return unless generating_hash?
|
||||||
|
|
||||||
@ -24,10 +28,12 @@ module APIHashable
|
|||||||
Object.send(:remove_const, :HOMEBREW_PREFIX)
|
Object.send(:remove_const, :HOMEBREW_PREFIX)
|
||||||
Object.const_set(:HOMEBREW_PREFIX, @old_homebrew_prefix)
|
Object.const_set(:HOMEBREW_PREFIX, @old_homebrew_prefix)
|
||||||
ENV["HOME"] = @old_home
|
ENV["HOME"] = @old_home
|
||||||
|
ENV["GIT_CONFIG_GLOBAL"] = @old_git_config_global
|
||||||
|
|
||||||
@generating_hash = false
|
@generating_hash = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(T::Boolean) }
|
||||||
def generating_hash?
|
def generating_hash?
|
||||||
@generating_hash ||= false
|
@generating_hash ||= false
|
||||||
@generating_hash == true
|
@generating_hash == true
|
@ -52,4 +52,4 @@ FORMULA_COMPONENT_PRECEDENCE_LIST = T.let([
|
|||||||
[{ name: :caveats, type: :method_definition }],
|
[{ name: :caveats, type: :method_definition }],
|
||||||
[{ name: :plist_options, type: :method_call }, { name: :plist, type: :method_definition }],
|
[{ name: :plist_options, type: :method_call }, { name: :plist, type: :method_definition }],
|
||||||
[{ name: :test, type: :block_call }],
|
[{ 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) }
|
sig { returns(T::Boolean) }
|
||||||
def self.enabled?
|
def self.enabled?
|
||||||
return false if Homebrew::EnvConfig.no_verify_attestations?
|
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.verify_attestations?
|
||||||
(Homebrew::EnvConfig.developer? || Homebrew::EnvConfig.devcmdrun?) && GitHub::API.credentials.present?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns a path to a suitable `gh` executable for attestation verification.
|
# Returns a path to a suitable `gh` executable for attestation verification.
|
||||||
|
@ -1,8 +1,15 @@
|
|||||||
# typed: strict
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# 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({
|
NO_AUTOBUMP_REASONS_LIST = T.let({
|
||||||
incompatible_version_format: "incompatible version format",
|
incompatible_version_format: "incompatible version format",
|
||||||
bumped_by_upstream: "bumped by upstream",
|
bumped_by_upstream: "bumped by upstream",
|
||||||
}.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}" ]]
|
if [[ -z "${GIT_REVISION}" ]]
|
||||||
then
|
then
|
||||||
read -r GIT_HEAD 2>/dev/null <"${HOMEBREW_REPOSITORY}/.git/HEAD"
|
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
|
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" ]]
|
elif [[ "${GIT_HEAD}" == "ref: refs/heads/stable" ]]
|
||||||
then
|
then
|
||||||
read -r GIT_REVISION 2>/dev/null <"${HOMEBREW_REPOSITORY}/.git/refs/heads/stable"
|
read -r GIT_REVISION 2>/dev/null <"${HOMEBREW_REPOSITORY}/.git/refs/heads/stable"
|
||||||
@ -600,6 +600,11 @@ case "$1" in
|
|||||||
homebrew-version
|
homebrew-version
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
|
mcp-server)
|
||||||
|
source "${HOMEBREW_LIBRARY}/Homebrew/cmd/mcp-server.sh"
|
||||||
|
homebrew-mcp-server "$@"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# TODO: bump version when new macOS is released or announced and update references in:
|
# TODO: bump version when new macOS is released or announced and update references in:
|
||||||
@ -609,6 +614,8 @@ esac
|
|||||||
# and, if needed:
|
# and, if needed:
|
||||||
# - MacOSVersion::SYMBOLS
|
# - MacOSVersion::SYMBOLS
|
||||||
HOMEBREW_MACOS_NEWEST_UNSUPPORTED="16"
|
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:
|
# TODO: bump version when new macOS is released and update references in:
|
||||||
# - docs/Installation.md
|
# - docs/Installation.md
|
||||||
# - HOMEBREW_MACOS_OLDEST_SUPPORTED in .github/workflows/pkg-installer.yml
|
# - 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
|
||||||
export HOMEBREW_MACOS_VERSION_NUMERIC
|
export HOMEBREW_MACOS_VERSION_NUMERIC
|
||||||
export HOMEBREW_MACOS_NEWEST_UNSUPPORTED
|
export HOMEBREW_MACOS_NEWEST_UNSUPPORTED
|
||||||
|
export HOMEBREW_MACOS_NEWEST_SUPPORTED
|
||||||
export HOMEBREW_MACOS_OLDEST_SUPPORTED
|
export HOMEBREW_MACOS_OLDEST_SUPPORTED
|
||||||
export HOMEBREW_MACOS_OLDEST_ALLOWED
|
export HOMEBREW_MACOS_OLDEST_ALLOWED
|
||||||
export HOMEBREW_USER_AGENT
|
export HOMEBREW_USER_AGENT
|
||||||
@ -1078,6 +1086,22 @@ else
|
|||||||
export HOMEBREW_GITHUB_PACKAGES_AUTH="Bearer QQ=="
|
export HOMEBREW_GITHUB_PACKAGES_AUTH="Bearer QQ=="
|
||||||
fi
|
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}" ]]
|
if [[ -n "${HOMEBREW_BASH_COMMAND}" ]]
|
||||||
then
|
then
|
||||||
# source rather than executing directly to ensure the entire file is read into
|
# 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]
|
@formula_versions_from_env[formula_env_name]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
|
def prepend_pkgconf_path_if_needed!; end
|
||||||
|
|
||||||
sig { void }
|
sig { void }
|
||||||
def reset!
|
def reset!
|
||||||
@mas_installed = T.let(nil, T.nilable(T::Boolean))
|
@mas_installed = T.let(nil, T.nilable(T::Boolean))
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "bundle/brew_installer"
|
require "bundle/formula_installer"
|
||||||
|
|
||||||
module Homebrew
|
module Homebrew
|
||||||
module Bundle
|
module Bundle
|
||||||
@ -11,7 +11,7 @@ module Homebrew
|
|||||||
PACKAGE_TYPE_NAME = "Formula"
|
PACKAGE_TYPE_NAME = "Formula"
|
||||||
|
|
||||||
def installed_and_up_to_date?(formula, no_upgrade: false)
|
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -24,8 +24,8 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
|
|
||||||
def entry_to_formula(entry)
|
def entry_to_formula(entry)
|
||||||
require "bundle/brew_installer"
|
require "bundle/formula_installer"
|
||||||
Homebrew::Bundle::BrewInstaller.new(entry.name, entry.options)
|
Homebrew::Bundle::FormulaInstaller.new(entry.name, entry.options)
|
||||||
end
|
end
|
||||||
|
|
||||||
def formula_needs_to_start?(formula)
|
def formula_needs_to_start?(formula)
|
||||||
@ -38,8 +38,8 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
|
|
||||||
def lookup_old_name(service_name)
|
def lookup_old_name(service_name)
|
||||||
require "bundle/brew_dumper"
|
require "bundle/formula_dumper"
|
||||||
@old_names ||= Homebrew::Bundle::BrewDumper.formula_oldnames
|
@old_names ||= Homebrew::Bundle::FormulaDumper.formula_oldnames
|
||||||
old_name = @old_names[service_name]
|
old_name = @old_names[service_name]
|
||||||
old_name ||= @old_names[service_name.split("/").last]
|
old_name ||= @old_names[service_name.split("/").last]
|
||||||
old_name
|
old_name
|
||||||
|
@ -8,6 +8,7 @@ module Homebrew
|
|||||||
@casks = nil
|
@casks = nil
|
||||||
@cask_names = nil
|
@cask_names = nil
|
||||||
@cask_hash = nil
|
@cask_hash = nil
|
||||||
|
@cask_oldnames = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.cask_names
|
def self.cask_names
|
||||||
@ -38,6 +39,25 @@ module Homebrew
|
|||||||
end.join("\n")
|
end.join("\n")
|
||||||
end
|
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)
|
def self.formula_dependencies(cask_list)
|
||||||
return [] unless Bundle.cask_installed?
|
return [] unless Bundle.cask_installed?
|
||||||
return [] if cask_list.blank?
|
return [] if cask_list.blank?
|
||||||
|
@ -87,12 +87,25 @@ module Homebrew
|
|||||||
!cask_upgradable?(cask)
|
!cask_upgradable?(cask)
|
||||||
end
|
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)
|
def self.cask_installed?(cask)
|
||||||
installed_casks.include? cask
|
cask_in_array?(cask, installed_casks)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.cask_upgradable?(cask)
|
def self.cask_upgradable?(cask)
|
||||||
outdated_casks.include? cask
|
cask_in_array?(cask, outdated_casks)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.installed_casks
|
def self.installed_casks
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: false # rubocop:todo Sorbet/TrueSigil
|
# typed: true
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Homebrew
|
module Homebrew
|
||||||
@ -23,7 +23,7 @@ module Homebrew
|
|||||||
else
|
else
|
||||||
"needs to be installed or updated."
|
"needs to be installed or updated."
|
||||||
end
|
end
|
||||||
"#{self.class::PACKAGE_TYPE_NAME} #{name} #{reason}"
|
"#{self.class.const_get(:PACKAGE_TYPE_NAME)} #{name} #{reason}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def full_check(packages, no_upgrade:)
|
def full_check(packages, no_upgrade:)
|
||||||
@ -33,7 +33,7 @@ module Homebrew
|
|||||||
|
|
||||||
def checkable_entries(all_entries)
|
def checkable_entries(all_entries)
|
||||||
require "bundle/skipper"
|
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?))
|
.reject(&Bundle::Skipper.method(:skip?))
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -139,14 +139,14 @@ module Homebrew
|
|||||||
|
|
||||||
def self.reset!
|
def self.reset!
|
||||||
require "bundle/cask_dumper"
|
require "bundle/cask_dumper"
|
||||||
require "bundle/brew_dumper"
|
require "bundle/formula_dumper"
|
||||||
require "bundle/mac_app_store_dumper"
|
require "bundle/mac_app_store_dumper"
|
||||||
require "bundle/tap_dumper"
|
require "bundle/tap_dumper"
|
||||||
require "bundle/brew_services"
|
require "bundle/brew_services"
|
||||||
|
|
||||||
@dsl = nil
|
@dsl = nil
|
||||||
Homebrew::Bundle::CaskDumper.reset!
|
Homebrew::Bundle::CaskDumper.reset!
|
||||||
Homebrew::Bundle::BrewDumper.reset!
|
Homebrew::Bundle::FormulaDumper.reset!
|
||||||
Homebrew::Bundle::MacAppStoreDumper.reset!
|
Homebrew::Bundle::MacAppStoreDumper.reset!
|
||||||
Homebrew::Bundle::TapDumper.reset!
|
Homebrew::Bundle::TapDumper.reset!
|
||||||
Homebrew::Bundle::BrewServices.reset!
|
Homebrew::Bundle::BrewServices.reset!
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "bundle/adder"
|
require "bundle/adder"
|
||||||
@ -7,6 +7,7 @@ module Homebrew
|
|||||||
module Bundle
|
module Bundle
|
||||||
module Commands
|
module Commands
|
||||||
module Add
|
module Add
|
||||||
|
sig { params(args: String, type: Symbol, global: T::Boolean, file: T.nilable(String)).void }
|
||||||
def self.run(*args, type:, global:, file:)
|
def self.run(*args, type:, global:, file:)
|
||||||
Homebrew::Bundle::Adder.add(*args, type:, global:, file:)
|
Homebrew::Bundle::Adder.add(*args, type:, global:, file:)
|
||||||
end
|
end
|
||||||
|
@ -10,7 +10,7 @@ module Homebrew
|
|||||||
module Cleanup
|
module Cleanup
|
||||||
def self.reset!
|
def self.reset!
|
||||||
require "bundle/cask_dumper"
|
require "bundle/cask_dumper"
|
||||||
require "bundle/brew_dumper"
|
require "bundle/formula_dumper"
|
||||||
require "bundle/tap_dumper"
|
require "bundle/tap_dumper"
|
||||||
require "bundle/vscode_extension_dumper"
|
require "bundle/vscode_extension_dumper"
|
||||||
require "bundle/brew_services"
|
require "bundle/brew_services"
|
||||||
@ -19,19 +19,20 @@ module Homebrew
|
|||||||
@kept_casks = nil
|
@kept_casks = nil
|
||||||
@kept_formulae = nil
|
@kept_formulae = nil
|
||||||
Homebrew::Bundle::CaskDumper.reset!
|
Homebrew::Bundle::CaskDumper.reset!
|
||||||
Homebrew::Bundle::BrewDumper.reset!
|
Homebrew::Bundle::FormulaDumper.reset!
|
||||||
Homebrew::Bundle::TapDumper.reset!
|
Homebrew::Bundle::TapDumper.reset!
|
||||||
Homebrew::Bundle::VscodeExtensionDumper.reset!
|
Homebrew::Bundle::VscodeExtensionDumper.reset!
|
||||||
Homebrew::Bundle::BrewServices.reset!
|
Homebrew::Bundle::BrewServices.reset!
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.run(global: false, file: nil, force: false, zap: false, dsl: nil)
|
def self.run(global: false, file: nil, force: false, zap: false, dsl: nil,
|
||||||
|
formulae: true, casks: true, taps: true, vscode: true)
|
||||||
@dsl ||= dsl
|
@dsl ||= dsl
|
||||||
|
|
||||||
casks = casks_to_uninstall(global:, file:)
|
casks = casks ? casks_to_uninstall(global:, file:) : []
|
||||||
formulae = formulae_to_uninstall(global:, file:)
|
formulae = formulae ? formulae_to_uninstall(global:, file:) : []
|
||||||
taps = taps_to_untap(global:, file:)
|
taps = taps ? taps_to_untap(global:, file:) : []
|
||||||
vscode_extensions = vscode_extensions_to_uninstall(global:, file:)
|
vscode_extensions = vscode ? vscode_extensions_to_uninstall(global:, file:) : []
|
||||||
if force
|
if force
|
||||||
if casks.any?
|
if casks.any?
|
||||||
args = zap ? ["--zap"] : []
|
args = zap ? ["--zap"] : []
|
||||||
@ -100,11 +101,11 @@ module Homebrew
|
|||||||
def self.formulae_to_uninstall(global: false, file: nil)
|
def self.formulae_to_uninstall(global: false, file: nil)
|
||||||
kept_formulae = self.kept_formulae(global:, file:)
|
kept_formulae = self.kept_formulae(global:, file:)
|
||||||
|
|
||||||
require "bundle/brew_dumper"
|
require "bundle/formula_dumper"
|
||||||
require "bundle/brew_installer"
|
require "bundle/formula_installer"
|
||||||
current_formulae = Homebrew::Bundle::BrewDumper.formulae
|
current_formulae = Homebrew::Bundle::FormulaDumper.formulae
|
||||||
current_formulae.reject! do |f|
|
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
|
end
|
||||||
|
|
||||||
# Don't try to uninstall formulae with keepme references
|
# Don't try to uninstall formulae with keepme references
|
||||||
@ -118,7 +119,7 @@ module Homebrew
|
|||||||
|
|
||||||
private_class_method def self.kept_formulae(global: false, file: nil)
|
private_class_method def self.kept_formulae(global: false, file: nil)
|
||||||
require "bundle/brewfile"
|
require "bundle/brewfile"
|
||||||
require "bundle/brew_dumper"
|
require "bundle/formula_dumper"
|
||||||
require "bundle/cask_dumper"
|
require "bundle/cask_dumper"
|
||||||
|
|
||||||
@kept_formulae ||= begin
|
@kept_formulae ||= begin
|
||||||
@ -127,12 +128,13 @@ module Homebrew
|
|||||||
kept_formulae = @dsl.entries.select { |e| e.type == :brew }.map(&:name)
|
kept_formulae = @dsl.entries.select { |e| e.type == :brew }.map(&:name)
|
||||||
kept_formulae += Homebrew::Bundle::CaskDumper.formula_dependencies(kept_casks)
|
kept_formulae += Homebrew::Bundle::CaskDumper.formula_dependencies(kept_casks)
|
||||||
kept_formulae.map! do |f|
|
kept_formulae.map! do |f|
|
||||||
Homebrew::Bundle::BrewDumper.formula_aliases[f] ||
|
Homebrew::Bundle::FormulaDumper.formula_aliases.fetch(
|
||||||
Homebrew::Bundle::BrewDumper.formula_oldnames[f] ||
|
f,
|
||||||
f
|
Homebrew::Bundle::FormulaDumper.formula_oldnames.fetch(f, f),
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
kept_formulae + recursive_dependencies(Homebrew::Bundle::BrewDumper.formulae, kept_formulae)
|
kept_formulae + recursive_dependencies(Homebrew::Bundle::FormulaDumper.formulae, kept_formulae)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -141,7 +143,11 @@ module Homebrew
|
|||||||
return @kept_casks if @kept_casks
|
return @kept_casks if @kept_casks
|
||||||
|
|
||||||
@dsl ||= Brewfile.read(global:, file:)
|
@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
|
end
|
||||||
|
|
||||||
private_class_method def self.recursive_dependencies(current_formulae, formulae_names, top_level: true)
|
private_class_method def self.recursive_dependencies(current_formulae, formulae_names, top_level: true)
|
||||||
|
@ -7,9 +7,10 @@ module Homebrew
|
|||||||
module Bundle
|
module Bundle
|
||||||
module Commands
|
module Commands
|
||||||
module Dump
|
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(
|
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
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: false # rubocop:todo Sorbet/TrueSigil
|
# typed: true
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "English"
|
require "English"
|
||||||
@ -13,6 +13,16 @@ module Homebrew
|
|||||||
module Exec
|
module Exec
|
||||||
PATH_LIKE_ENV_REGEX = /.+#{File::PATH_SEPARATOR}/
|
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)
|
def self.run(*args, global: false, file: nil, subcommand: "", services: false, check: false)
|
||||||
if check
|
if check
|
||||||
require "bundle/commands/check"
|
require "bundle/commands/check"
|
||||||
@ -25,9 +35,9 @@ module Homebrew
|
|||||||
|
|
||||||
# Setup Homebrew's ENV extensions
|
# Setup Homebrew's ENV extensions
|
||||||
ENV.activate_extensions!
|
ENV.activate_extensions!
|
||||||
raise UsageError, "No command to execute was specified!" if args.blank?
|
|
||||||
|
|
||||||
command = args.first
|
command = args.first
|
||||||
|
raise UsageError, "No command to execute was specified!" if command.blank?
|
||||||
|
|
||||||
require "bundle/brewfile"
|
require "bundle/brewfile"
|
||||||
@dsl = Brewfile.read(global:, file:)
|
@dsl = Brewfile.read(global:, file:)
|
||||||
@ -64,14 +74,8 @@ module Homebrew
|
|||||||
ENV.prepend_path "PATH", Pathname.new(dep_root)/"shims"
|
ENV.prepend_path "PATH", Pathname.new(dep_root)/"shims"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Setup pkg-config, if present, to help locate packages
|
# Setup pkgconf, if needed, to help locate packages
|
||||||
# Only need this on Linux as Homebrew provides a shim on macOS
|
Bundle.prepend_pkgconf_path_if_needed!
|
||||||
# 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
|
|
||||||
|
|
||||||
# For commands which aren't either absolute or relative
|
# For commands which aren't either absolute or relative
|
||||||
# Add the command directory to PATH, since it may get blown away by superenv
|
# Add the command directory to PATH, since it may get blown away by superenv
|
||||||
@ -170,15 +174,29 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
return
|
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
|
end
|
||||||
|
|
||||||
if services
|
if services
|
||||||
require "bundle/brew_services"
|
require "bundle/brew_services"
|
||||||
|
|
||||||
exit_code = 0
|
exit_code = T.let(0, Integer)
|
||||||
run_services(@dsl.entries) do
|
run_services(@dsl.entries) do
|
||||||
Kernel.system(*args)
|
Kernel.system(*args)
|
||||||
exit_code = $CHILD_STATUS.exitstatus
|
if (system_exit_code = $CHILD_STATUS&.exitstatus)
|
||||||
|
exit_code = system_exit_code
|
||||||
|
end
|
||||||
end
|
end
|
||||||
exit!(exit_code)
|
exit!(exit_code)
|
||||||
else
|
else
|
||||||
@ -191,7 +209,7 @@ module Homebrew
|
|||||||
entries: T::Array[Homebrew::Bundle::Dsl::Entry],
|
entries: T::Array[Homebrew::Bundle::Dsl::Entry],
|
||||||
_block: T.proc.params(
|
_block: T.proc.params(
|
||||||
entry: Homebrew::Bundle::Dsl::Entry,
|
entry: Homebrew::Bundle::Dsl::Entry,
|
||||||
info: T::Hash[String, T.anything],
|
info: T::Hash[String, T.untyped],
|
||||||
service_file: Pathname,
|
service_file: Pathname,
|
||||||
conflicting_services: T::Array[T::Hash[String, T.anything]],
|
conflicting_services: T::Array[T::Hash[String, T.anything]],
|
||||||
).void,
|
).void,
|
||||||
@ -271,7 +289,7 @@ module Homebrew
|
|||||||
map_service_info(entries) do |entry, info, service_file, conflicting_services|
|
map_service_info(entries) do |entry, info, service_file, conflicting_services|
|
||||||
# Don't restart if already running this version
|
# Don't restart if already running this version
|
||||||
loaded_file = Pathname.new(info["loaded_file"].to_s)
|
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)
|
if info["running"] && !Bundle::BrewServices.stop(info["name"], keep: true)
|
||||||
opoo "Failed to stop #{info["name"]} service"
|
opoo "Failed to stop #{info["name"]} service"
|
||||||
|
@ -8,11 +8,11 @@ module Homebrew
|
|||||||
module Bundle
|
module Bundle
|
||||||
module Commands
|
module Commands
|
||||||
module List
|
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
|
parsed_entries = Brewfile.read(global:, file:).entries
|
||||||
Homebrew::Bundle::Lister.list(
|
Homebrew::Bundle::Lister.list(
|
||||||
parsed_entries,
|
parsed_entries,
|
||||||
brews:, casks:, taps:, mas:, whalebrew:, vscode:,
|
formulae:, casks:, taps:, mas:, whalebrew:, vscode:,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -13,9 +13,9 @@ module Homebrew
|
|||||||
true
|
true
|
||||||
end
|
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/tap_dumper"
|
||||||
require "bundle/brew_dumper"
|
require "bundle/formula_dumper"
|
||||||
require "bundle/cask_dumper"
|
require "bundle/cask_dumper"
|
||||||
require "bundle/mac_app_store_dumper"
|
require "bundle/mac_app_store_dumper"
|
||||||
require "bundle/whalebrew_dumper"
|
require "bundle/whalebrew_dumper"
|
||||||
@ -23,7 +23,7 @@ module Homebrew
|
|||||||
|
|
||||||
content = []
|
content = []
|
||||||
content << TapDumper.dump if taps
|
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 << CaskDumper.dump(describe:) if casks
|
||||||
content << MacAppStoreDumper.dump if mas
|
content << MacAppStoreDumper.dump if mas
|
||||||
content << WhalebrewDumper.dump if whalebrew
|
content << WhalebrewDumper.dump if whalebrew
|
||||||
@ -31,11 +31,11 @@ module Homebrew
|
|||||||
"#{content.reject(&:empty?).join("\n")}\n"
|
"#{content.reject(&:empty?).join("\n")}\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.dump_brewfile(global:, file:, describe:, force:, no_restart:, brews:, taps:, casks:, mas:, whalebrew:,
|
def self.dump_brewfile(global:, file:, describe:, force:, no_restart:, formulae:, taps:, casks:, mas:,
|
||||||
vscode:)
|
whalebrew:, vscode:)
|
||||||
path = brewfile_path(global:, file:)
|
path = brewfile_path(global:, file:)
|
||||||
can_write_to_brewfile?(path, force:)
|
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
|
write_file path, content
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: false # rubocop:todo Sorbet/TrueSigil
|
# typed: true
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "json"
|
require "json"
|
||||||
@ -7,10 +7,8 @@ require "tsort"
|
|||||||
module Homebrew
|
module Homebrew
|
||||||
module Bundle
|
module Bundle
|
||||||
# TODO: refactor into multiple modules
|
# TODO: refactor into multiple modules
|
||||||
module BrewDumper
|
module FormulaDumper
|
||||||
module_function
|
def self.reset!
|
||||||
|
|
||||||
def reset!
|
|
||||||
require "bundle/brew_services"
|
require "bundle/brew_services"
|
||||||
|
|
||||||
Homebrew::Bundle::BrewServices.reset!
|
Homebrew::Bundle::BrewServices.reset!
|
||||||
@ -21,14 +19,14 @@ module Homebrew
|
|||||||
@formula_oldnames = nil
|
@formula_oldnames = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def formulae
|
def self.formulae
|
||||||
return @formulae if @formulae
|
return @formulae if @formulae
|
||||||
|
|
||||||
formulae_by_full_name
|
formulae_by_full_name
|
||||||
@formulae
|
@formulae
|
||||||
end
|
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)
|
return @formulae_by_full_name[name] if name.present? && @formulae_by_full_name&.key?(name)
|
||||||
|
|
||||||
require "formula"
|
require "formula"
|
||||||
@ -51,11 +49,11 @@ module Homebrew
|
|||||||
{}
|
{}
|
||||||
end
|
end
|
||||||
|
|
||||||
def formulae_by_name(name)
|
def self.formulae_by_name(name)
|
||||||
formulae_by_full_name(name) || @formulae_by_name[name]
|
formulae_by_full_name(name) || @formulae_by_name[name]
|
||||||
end
|
end
|
||||||
|
|
||||||
def dump(describe: false, no_restart: false)
|
def self.dump(describe: false, no_restart: false)
|
||||||
require "bundle/brew_services"
|
require "bundle/brew_services"
|
||||||
|
|
||||||
requested_formula = formulae.select do |f|
|
requested_formula = formulae.select do |f|
|
||||||
@ -77,7 +75,7 @@ module Homebrew
|
|||||||
end.join("\n")
|
end.join("\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
def formula_aliases
|
def self.formula_aliases
|
||||||
return @formula_aliases if @formula_aliases
|
return @formula_aliases if @formula_aliases
|
||||||
|
|
||||||
@formula_aliases = {}
|
@formula_aliases = {}
|
||||||
@ -96,7 +94,7 @@ module Homebrew
|
|||||||
@formula_aliases
|
@formula_aliases
|
||||||
end
|
end
|
||||||
|
|
||||||
def formula_oldnames
|
def self.formula_oldnames
|
||||||
return @formula_oldnames if @formula_oldnames
|
return @formula_oldnames if @formula_oldnames
|
||||||
|
|
||||||
@formula_oldnames = {}
|
@formula_oldnames = {}
|
||||||
@ -115,7 +113,7 @@ module Homebrew
|
|||||||
@formula_oldnames
|
@formula_oldnames
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_formula(formula)
|
private_class_method def self.add_formula(formula)
|
||||||
hash = formula_to_hash formula
|
hash = formula_to_hash formula
|
||||||
|
|
||||||
@formulae_by_name[hash[:name]] = hash
|
@formulae_by_name[hash[:name]] = hash
|
||||||
@ -123,9 +121,8 @@ module Homebrew
|
|||||||
|
|
||||||
hash
|
hash
|
||||||
end
|
end
|
||||||
private_class_method :add_formula
|
|
||||||
|
|
||||||
def formula_to_hash(formula)
|
private_class_method def self.formula_to_hash(formula)
|
||||||
keg = if formula.linked?
|
keg = if formula.linked?
|
||||||
link = true if formula.keg_only?
|
link = true if formula.keg_only?
|
||||||
formula.linked_keg
|
formula.linked_keg
|
||||||
@ -185,17 +182,21 @@ module Homebrew
|
|||||||
official_tap: formula.tap&.official? || false,
|
official_tap: formula.tap&.official? || false,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
private_class_method :formula_to_hash
|
|
||||||
|
|
||||||
class Topo < Hash
|
class Topo < Hash
|
||||||
include TSort
|
include TSort
|
||||||
|
|
||||||
|
def each_key(&block)
|
||||||
|
keys.each(&block)
|
||||||
|
end
|
||||||
alias tsort_each_node each_key
|
alias tsort_each_node each_key
|
||||||
|
|
||||||
def tsort_each_child(node, &block)
|
def tsort_each_child(node, &block)
|
||||||
fetch(node.downcase).sort.each(&block)
|
fetch(node.downcase).sort.each(&block)
|
||||||
end
|
end
|
||||||
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.
|
# Step 1: Sort by formula full name while putting tap formulae behind core formulae.
|
||||||
# So we can have a nicer output.
|
# So we can have a nicer output.
|
||||||
formulae = formulae.sort do |a, b|
|
formulae = formulae.sort do |a, b|
|
||||||
@ -230,15 +231,14 @@ module Homebrew
|
|||||||
|
|
||||||
odie <<~EOS
|
odie <<~EOS
|
||||||
Formulae dependency graph sorting failed (likely due to a circular dependency):
|
Formulae dependency graph sorting failed (likely due to a circular dependency):
|
||||||
#{cycle_first}: #{topo[cycle_first]}
|
#{cycle_first}: #{topo[cycle_first] if topo}
|
||||||
#{cycle_last}: #{topo[cycle_last]}
|
#{cycle_last}: #{topo[cycle_last] if topo}
|
||||||
Please run the following commands and try again:
|
Please run the following commands and try again:
|
||||||
brew update
|
brew update
|
||||||
brew uninstall --ignore-dependencies --force #{cycle_first} #{cycle_last}
|
brew uninstall --ignore-dependencies --force #{cycle_first} #{cycle_last}
|
||||||
brew install #{cycle_first} #{cycle_last}
|
brew install #{cycle_first} #{cycle_last}
|
||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
private_class_method :sort!
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
module Homebrew
|
module Homebrew
|
||||||
module Bundle
|
module Bundle
|
||||||
class BrewInstaller
|
class FormulaInstaller
|
||||||
def self.reset!
|
def self.reset!
|
||||||
@installed_formulae = nil
|
@installed_formulae = nil
|
||||||
@outdated_formulae = nil
|
@outdated_formulae = nil
|
||||||
@ -179,13 +179,13 @@ module Homebrew
|
|||||||
return true if array.include?(formula)
|
return true if array.include?(formula)
|
||||||
return true if array.include?(formula.split("/").last)
|
return true if array.include?(formula.split("/").last)
|
||||||
|
|
||||||
require "bundle/brew_dumper"
|
require "bundle/formula_dumper"
|
||||||
old_names = Homebrew::Bundle::BrewDumper.formula_oldnames
|
old_names = Homebrew::Bundle::FormulaDumper.formula_oldnames
|
||||||
old_name = old_names[formula]
|
old_name = old_names[formula]
|
||||||
old_name ||= old_names[formula.split("/").last]
|
old_name ||= old_names[formula.split("/").last]
|
||||||
return true if old_name && array.include?(old_name)
|
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 false unless resolved_full_name
|
||||||
return true if array.include?(resolved_full_name)
|
return true if array.include?(resolved_full_name)
|
||||||
return true if array.include?(resolved_full_name.split("/").last)
|
return true if array.include?(resolved_full_name.split("/").last)
|
||||||
@ -219,14 +219,14 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
|
|
||||||
def self.formulae
|
def self.formulae
|
||||||
require "bundle/brew_dumper"
|
require "bundle/formula_dumper"
|
||||||
Homebrew::Bundle::BrewDumper.formulae
|
Homebrew::Bundle::FormulaDumper.formulae
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def installed?
|
def installed?
|
||||||
BrewInstaller.formula_installed?(@name)
|
FormulaInstaller.formula_installed?(@name)
|
||||||
end
|
end
|
||||||
|
|
||||||
def linked?
|
def linked?
|
||||||
@ -242,7 +242,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
|
|
||||||
def upgradable?
|
def upgradable?
|
||||||
BrewInstaller.formula_upgradable?(@name)
|
FormulaInstaller.formula_upgradable?(@name)
|
||||||
end
|
end
|
||||||
|
|
||||||
def conflicts_with
|
def conflicts_with
|
||||||
@ -250,8 +250,8 @@ module Homebrew
|
|||||||
conflicts_with = Set.new
|
conflicts_with = Set.new
|
||||||
conflicts_with += @conflicts_with_arg
|
conflicts_with += @conflicts_with_arg
|
||||||
|
|
||||||
require "bundle/brew_dumper"
|
require "bundle/formula_dumper"
|
||||||
if (formula = Homebrew::Bundle::BrewDumper.formulae_by_full_name(@full_name)) &&
|
if (formula = Homebrew::Bundle::FormulaDumper.formulae_by_full_name(@full_name)) &&
|
||||||
(formula_conflicts_with = formula[:conflicts_with])
|
(formula_conflicts_with = formula[:conflicts_with])
|
||||||
conflicts_with += formula_conflicts_with
|
conflicts_with += formula_conflicts_with
|
||||||
end
|
end
|
||||||
@ -262,7 +262,7 @@ module Homebrew
|
|||||||
|
|
||||||
def resolve_conflicts!(verbose:)
|
def resolve_conflicts!(verbose:)
|
||||||
conflicts_with.each do |conflict|
|
conflicts_with.each do |conflict|
|
||||||
next unless BrewInstaller.formula_installed?(conflict)
|
next unless FormulaInstaller.formula_installed?(conflict)
|
||||||
|
|
||||||
if verbose
|
if verbose
|
||||||
puts <<~EOS
|
puts <<~EOS
|
||||||
@ -293,7 +293,7 @@ module Homebrew
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
BrewInstaller.installed_formulae << @name
|
FormulaInstaller.installed_formulae << @name
|
||||||
@changed = true
|
@changed = true
|
||||||
true
|
true
|
||||||
end
|
end
|
@ -2,7 +2,7 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "bundle/dsl"
|
require "bundle/dsl"
|
||||||
require "bundle/brew_installer"
|
require "bundle/formula_installer"
|
||||||
require "bundle/cask_installer"
|
require "bundle/cask_installer"
|
||||||
require "bundle/mac_app_store_installer"
|
require "bundle/mac_app_store_installer"
|
||||||
require "bundle/whalebrew_installer"
|
require "bundle/whalebrew_installer"
|
||||||
@ -27,8 +27,8 @@ module Homebrew
|
|||||||
cls = case type
|
cls = case type
|
||||||
when :brew
|
when :brew
|
||||||
options = entry.options
|
options = entry.options
|
||||||
verb = "Upgrading" if Homebrew::Bundle::BrewInstaller.formula_upgradable?(name)
|
verb = "Upgrading" if Homebrew::Bundle::FormulaInstaller.formula_upgradable?(name)
|
||||||
Homebrew::Bundle::BrewInstaller
|
Homebrew::Bundle::FormulaInstaller
|
||||||
when :cask
|
when :cask
|
||||||
options = entry.options
|
options = entry.options
|
||||||
verb = "Upgrading" if Homebrew::Bundle::CaskInstaller.cask_upgradable?(name)
|
verb = "Upgrading" if Homebrew::Bundle::CaskInstaller.cask_upgradable?(name)
|
||||||
|
@ -4,14 +4,14 @@
|
|||||||
module Homebrew
|
module Homebrew
|
||||||
module Bundle
|
module Bundle
|
||||||
module Lister
|
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|
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
private_class_method def self.show?(type, brews:, casks:, taps:, mas:, whalebrew:, vscode:)
|
private_class_method def self.show?(type, formulae:, casks:, taps:, mas:, whalebrew:, vscode:)
|
||||||
return true if brews && type == :brew
|
return true if formulae && type == :brew
|
||||||
return true if casks && type == :cask
|
return true if casks && type == :cask
|
||||||
return true if taps && type == :tap
|
return true if taps && type == :tap
|
||||||
return true if mas && type == :mas
|
return true if mas && type == :mas
|
||||||
|
@ -9,21 +9,8 @@ module Homebrew
|
|||||||
class << self
|
class << self
|
||||||
sig { params(entry: Dsl::Entry, silent: T::Boolean).returns(T::Boolean) }
|
sig { params(entry: Dsl::Entry, silent: T::Boolean).returns(T::Boolean) }
|
||||||
def skip?(entry, silent: false)
|
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|
|
return true if @failed_taps&.any? do |tap|
|
||||||
prefix = "#{tap}/"
|
prefix = "#{tap}/"
|
||||||
entry.name.start_with?(prefix) || entry.options[:full_name]&.start_with?(prefix)
|
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
|
puts "Installing #{name} tap. It is not currently installed." if verbose
|
||||||
args = []
|
args = []
|
||||||
args << "--force" if force
|
args << "--force" if force
|
||||||
args.append("--force-auto-update") if options[:force_auto_update]
|
|
||||||
|
|
||||||
success = if options[:clone_target]
|
success = if options[:clone_target]
|
||||||
Bundle.brew("tap", name, options[:clone_target], *args, verbose:)
|
Bundle.brew("tap", name, options[:clone_target], *args, verbose:)
|
||||||
|
@ -139,7 +139,11 @@ module Cask
|
|||||||
|
|
||||||
def initialize(cask, *dsl_args)
|
def initialize(cask, *dsl_args)
|
||||||
@cask = cask
|
@cask = cask
|
||||||
|
@dirmethod = nil
|
||||||
@dsl_args = dsl_args.deep_dup
|
@dsl_args = dsl_args.deep_dup
|
||||||
|
@dsl_key = nil
|
||||||
|
@english_article = nil
|
||||||
|
@english_name = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def config
|
def config
|
||||||
|
@ -464,9 +464,9 @@ module Cask
|
|||||||
args: paths,
|
args: paths,
|
||||||
print_stderr: Homebrew::EnvConfig.developer?
|
print_stderr: Homebrew::EnvConfig.developer?
|
||||||
|
|
||||||
trashed, = stdout.partition("\n")
|
trashed, _, untrashable = stdout.partition("\n")
|
||||||
trashed = trashed.split(":") & paths
|
trashed = trashed.split(":")
|
||||||
untrashable = paths - trashed
|
untrashable = untrashable.split(":")
|
||||||
|
|
||||||
trashed_with_permissions, untrashable = untrashable.partition do |path|
|
trashed_with_permissions, untrashable = untrashable.partition do |path|
|
||||||
Utils.gain_permissions(path, ["-R"], SystemCommand) do
|
Utils.gain_permissions(path, ["-R"], SystemCommand) do
|
||||||
|
@ -41,7 +41,9 @@ module Cask
|
|||||||
super
|
super
|
||||||
|
|
||||||
target = target_hash[:target]
|
target = target_hash[:target]
|
||||||
|
@source = nil
|
||||||
@source_string = source.to_s
|
@source_string = source.to_s
|
||||||
|
@target = nil
|
||||||
@target_string = target.to_s
|
@target_string = target.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -6,11 +6,6 @@ require "cask/artifact/symlinked"
|
|||||||
module Cask
|
module Cask
|
||||||
module Artifact
|
module Artifact
|
||||||
class ShellCompletion < Symlinked
|
class ShellCompletion < Symlinked
|
||||||
sig { params(cask: Cask, source: T.any(String, Pathname)).returns(ShellCompletion) }
|
|
||||||
def self.from_args(cask, source)
|
|
||||||
new(cask, source)
|
|
||||||
end
|
|
||||||
|
|
||||||
sig { params(_: T.any(String, Pathname)).returns(Pathname) }
|
sig { params(_: T.any(String, Pathname)).returns(Pathname) }
|
||||||
def resolve_target(_)
|
def resolve_target(_)
|
||||||
raise CaskInvalidError, "Shell completion without shell info"
|
raise CaskInvalidError, "Shell completion without shell info"
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Cask
|
module Cask
|
||||||
# Sorted set containing all cask artifacts.
|
# Sorted set containing all cask artifacts.
|
||||||
class ArtifactSet < ::Set
|
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)
|
def each(&block)
|
||||||
return enum_for(T.must(__method__)) { size } unless block
|
return enum_for(T.must(__method__)) { size } unless block
|
||||||
|
|
||||||
@ -11,6 +16,7 @@ module Cask
|
|||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(T::Array[Artifact::AbstractArtifact]) }
|
||||||
def to_a
|
def to_a
|
||||||
super.sort
|
super.sort
|
||||||
end
|
end
|
||||||
|
@ -27,7 +27,7 @@ module Cask
|
|||||||
|
|
||||||
sig {
|
sig {
|
||||||
params(
|
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),
|
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]
|
new_cask: T.nilable(T::Boolean), only: T::Array[String], except: T::Array[String]
|
||||||
).void
|
).void
|
||||||
@ -35,14 +35,13 @@ module Cask
|
|||||||
def initialize(
|
def initialize(
|
||||||
cask,
|
cask,
|
||||||
download: false, quarantine: false,
|
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: 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?
|
online = new_cask if online.nil?
|
||||||
strict = new_cask if strict.nil?
|
strict = new_cask if strict.nil?
|
||||||
signing = new_cask if signing.nil?
|
signing = new_cask if signing.nil?
|
||||||
token_conflicts = new_cask if token_conflicts.nil?
|
|
||||||
|
|
||||||
# `online` and `signing` imply `download`
|
# `online` and `signing` imply `download`
|
||||||
download ||= online || signing
|
download ||= online || signing
|
||||||
@ -53,7 +52,6 @@ module Cask
|
|||||||
@strict = strict
|
@strict = strict
|
||||||
@signing = signing
|
@signing = signing
|
||||||
@new_cask = new_cask
|
@new_cask = new_cask
|
||||||
@token_conflicts = token_conflicts
|
|
||||||
@only = only
|
@only = only
|
||||||
@except = except
|
@except = except
|
||||||
end
|
end
|
||||||
@ -70,9 +68,6 @@ module Cask
|
|||||||
sig { returns(T::Boolean) }
|
sig { returns(T::Boolean) }
|
||||||
def strict? = !!@strict
|
def strict? = !!@strict
|
||||||
|
|
||||||
sig { returns(T::Boolean) }
|
|
||||||
def token_conflicts? = !!@token_conflicts
|
|
||||||
|
|
||||||
sig { returns(::Cask::Audit) }
|
sig { returns(::Cask::Audit) }
|
||||||
def run!
|
def run!
|
||||||
only_audits = @only
|
only_audits = @only
|
||||||
@ -430,15 +425,10 @@ module Cask
|
|||||||
|
|
||||||
sig { void }
|
sig { void }
|
||||||
def audit_token_conflicts
|
def audit_token_conflicts
|
||||||
return unless token_conflicts?
|
|
||||||
|
|
||||||
Homebrew.with_no_api_env do
|
Homebrew.with_no_api_env do
|
||||||
return unless core_formula_names.include?(cask.token)
|
return unless core_formula_names.include?(cask.token)
|
||||||
|
|
||||||
add_error(
|
add_error("cask token conflicts with an existing homebrew/core formula: #{Formatter.url(core_formula_url)}")
|
||||||
"possible duplicate, cask token conflicts with Homebrew core formula: #{Formatter.url(core_formula_url)}",
|
|
||||||
strict_only: true,
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -606,7 +596,10 @@ module Cask
|
|||||||
def audit_rosetta
|
def audit_rosetta
|
||||||
return if (url = cask.url).nil?
|
return if (url = cask.url).nil?
|
||||||
return unless online?
|
return unless online?
|
||||||
|
# Rosetta 2 is only for ARM-capable macOS versions, which are Big Sur (11.x) and later
|
||||||
return if Homebrew::SimulateSystem.current_arch != :arm
|
return if Homebrew::SimulateSystem.current_arch != :arm
|
||||||
|
return if MacOSVersion::SYMBOLS.fetch(Homebrew::SimulateSystem.current_os, "10") < "11"
|
||||||
|
return if cask.depends_on.macos&.maximum_version.to_s < "11"
|
||||||
|
|
||||||
odebug "Auditing Rosetta 2 requirement"
|
odebug "Auditing Rosetta 2 requirement"
|
||||||
|
|
||||||
@ -640,7 +633,7 @@ module Cask
|
|||||||
# binary stanza can contain shell scripts, so we just continue if lipo fails.
|
# binary stanza can contain shell scripts, so we just continue if lipo fails.
|
||||||
next unless result.success?
|
next unless result.success?
|
||||||
|
|
||||||
odebug result.merged_output
|
odebug "Architectures: #{result.merged_output}"
|
||||||
|
|
||||||
unless /arm64|x86_64/.match?(result.merged_output)
|
unless /arm64|x86_64/.match?(result.merged_output)
|
||||||
add_error "Artifacts architecture is no longer supported by macOS!",
|
add_error "Artifacts architecture is no longer supported by macOS!",
|
||||||
@ -650,11 +643,12 @@ module Cask
|
|||||||
|
|
||||||
supports_arm = result.merged_output.include?("arm64")
|
supports_arm = result.merged_output.include?("arm64")
|
||||||
mentions_rosetta = cask.caveats.include?("requires Rosetta 2")
|
mentions_rosetta = cask.caveats.include?("requires Rosetta 2")
|
||||||
|
requires_intel = cask.depends_on.arch&.any? { |arch| arch[:type] == :intel }
|
||||||
|
|
||||||
if supports_arm && mentions_rosetta
|
if supports_arm && mentions_rosetta
|
||||||
add_error "Artifacts does not require Rosetta 2 but the caveats say otherwise!",
|
add_error "Artifacts do not require Rosetta 2 but the caveats say otherwise!",
|
||||||
location: url.location
|
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!",
|
add_error "Artifacts require Rosetta 2 but this is not indicated by the caveats!",
|
||||||
location: url.location
|
location: url.location
|
||||||
end
|
end
|
||||||
@ -698,45 +692,53 @@ module Cask
|
|||||||
return unless online?
|
return unless online?
|
||||||
return unless strict?
|
return unless strict?
|
||||||
|
|
||||||
odebug "Auditing minimum OS version"
|
odebug "Auditing minimum macOS version"
|
||||||
|
|
||||||
plist_min_os = cask_plist_min_os
|
bundle_min_os = cask_bundle_min_os
|
||||||
sparkle_min_os = livecheck_min_os
|
sparkle_min_os = cask_sparkle_min_os
|
||||||
|
|
||||||
|
app_min_os = [bundle_min_os, sparkle_min_os].compact.max
|
||||||
debug_messages = []
|
debug_messages = []
|
||||||
debug_messages << "Plist #{plist_min_os}" if plist_min_os
|
debug_messages << "from artifact: #{bundle_min_os.to_sym}" if bundle_min_os
|
||||||
debug_messages << "Sparkle #{sparkle_min_os}" if sparkle_min_os
|
debug_messages << "from upstream: #{sparkle_min_os.to_sym}" if sparkle_min_os
|
||||||
odebug "Detected minimum OS version: #{debug_messages.join(" | ")}" unless debug_messages.empty?
|
odebug "Detected minimum macOS: #{app_min_os.to_sym} (#{debug_messages.join(" | ")})" if app_min_os
|
||||||
min_os = [plist_min_os, sparkle_min_os].compact.max
|
return if app_min_os.nil? || app_min_os <= HOMEBREW_MACOS_OLDEST_ALLOWED
|
||||||
|
|
||||||
return if min_os.nil? || min_os <= HOMEBREW_MACOS_OLDEST_ALLOWED
|
|
||||||
|
|
||||||
on_system_block_min_os = cask.on_system_block_min_os
|
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
|
depends_on_min_os = cask.depends_on.macos&.minimum_version
|
||||||
odebug "Declared minimum OS version: #{cask_min_os&.to_sym}"
|
|
||||||
return if cask_min_os&.to_sym == min_os.to_sym
|
cask_min_os = [on_system_block_min_os, depends_on_min_os].compact.max
|
||||||
return if cask.on_system_blocks_exist? &&
|
debug_messages = []
|
||||||
OnSystem.arch_condition_met?(:arm) &&
|
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.present? &&
|
||||||
cask_min_os < MacOSVersion.new("11")
|
cask_min_os < MacOSVersion.new("11")
|
||||||
|
|
||||||
min_os_definition = if cask_min_os.present?
|
min_os_definition = if cask_min_os > HOMEBREW_MACOS_OLDEST_ALLOWED
|
||||||
if on_system_block_min_os.present? &&
|
definition = if T.must(on_system_block_min_os.to_s <=> depends_on_min_os.to_s).positive?
|
||||||
on_system_block_min_os > cask.depends_on.macos&.minimum_version
|
"an on_system block"
|
||||||
"a block with a minimum OS version of #{cask_min_os.to_sym.inspect}"
|
|
||||||
else
|
else
|
||||||
cask_min_os.to_sym.inspect
|
"a depends_on stanza"
|
||||||
end
|
end
|
||||||
|
"#{definition} with a minimum macOS version of #{cask_min_os.to_sym.inspect}"
|
||||||
else
|
else
|
||||||
"no minimum OS version"
|
"no minimum macOS version"
|
||||||
end
|
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}",
|
"but the cask declared #{min_os_definition}",
|
||||||
strict_only: true
|
strict_only: true
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { returns(T.nilable(MacOSVersion)) }
|
sig { returns(T.nilable(MacOSVersion)) }
|
||||||
def livecheck_min_os
|
def cask_sparkle_min_os
|
||||||
return unless online?
|
return unless online?
|
||||||
return unless cask.livecheck_defined?
|
return unless cask.livecheck_defined?
|
||||||
return if cask.livecheck.strategy != :sparkle
|
return if cask.livecheck.strategy != :sparkle
|
||||||
@ -769,10 +771,10 @@ module Cask
|
|||||||
end
|
end
|
||||||
|
|
||||||
sig { returns(T.nilable(MacOSVersion)) }
|
sig { returns(T.nilable(MacOSVersion)) }
|
||||||
def cask_plist_min_os
|
def cask_bundle_min_os
|
||||||
return unless online?
|
return unless online?
|
||||||
|
|
||||||
plist_min_os = T.let(nil, T.untyped)
|
min_os = T.let(nil, T.untyped)
|
||||||
@staged_path ||= cask.staged_path
|
@staged_path ||= cask.staged_path
|
||||||
|
|
||||||
extract_artifacts do |artifacts, tmpdir|
|
extract_artifacts do |artifacts, tmpdir|
|
||||||
@ -783,13 +785,33 @@ module Cask
|
|||||||
next unless File.exist?(plist_path)
|
next unless File.exist?(plist_path)
|
||||||
|
|
||||||
plist = system_command!("plutil", args: ["-convert", "xml1", "-o", "-", plist_path]).plist
|
plist = system_command!("plutil", args: ["-convert", "xml1", "-o", "-", plist_path]).plist
|
||||||
plist_min_os = plist["LSMinimumSystemVersion"].presence
|
min_os = plist["LSMinimumSystemVersion"].presence
|
||||||
break if plist_min_os
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
begin
|
begin
|
||||||
MacOSVersion.new(plist_min_os).strip_patch
|
MacOSVersion.new(min_os).strip_patch
|
||||||
rescue MacOSVersion::Error
|
rescue MacOSVersion::Error
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
@ -11,17 +11,17 @@ module Cask
|
|||||||
params(
|
params(
|
||||||
cask: ::Cask::Cask, audit_download: T::Boolean, audit_online: T.nilable(T::Boolean),
|
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_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]
|
any_named_args: T::Boolean, language: T.nilable(String), only: T::Array[String], except: T::Array[String]
|
||||||
).returns(T::Set[String])
|
).returns(T::Set[String])
|
||||||
}
|
}
|
||||||
def self.audit(
|
def self.audit(
|
||||||
cask, audit_download: false, audit_online: nil, audit_strict: nil, audit_signing: nil,
|
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: []
|
only: [], except: []
|
||||||
)
|
)
|
||||||
new(
|
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_new_cask:, quarantine:, any_named_args:, language:, only:, except:
|
||||||
).audit
|
).audit
|
||||||
end
|
end
|
||||||
@ -36,7 +36,7 @@ module Cask
|
|||||||
params(
|
params(
|
||||||
cask: ::Cask::Cask, audit_download: T::Boolean, audit_online: T.nilable(T::Boolean),
|
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_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]
|
any_named_args: T::Boolean, language: T.nilable(String), only: T::Array[String], except: T::Array[String]
|
||||||
).void
|
).void
|
||||||
}
|
}
|
||||||
@ -46,7 +46,6 @@ module Cask
|
|||||||
audit_online: nil,
|
audit_online: nil,
|
||||||
audit_strict: nil,
|
audit_strict: nil,
|
||||||
audit_signing: nil,
|
audit_signing: nil,
|
||||||
audit_token_conflicts: nil,
|
|
||||||
audit_new_cask: nil,
|
audit_new_cask: nil,
|
||||||
quarantine: false,
|
quarantine: false,
|
||||||
any_named_args: false,
|
any_named_args: false,
|
||||||
@ -61,7 +60,6 @@ module Cask
|
|||||||
@audit_strict = audit_strict
|
@audit_strict = audit_strict
|
||||||
@audit_signing = audit_signing
|
@audit_signing = audit_signing
|
||||||
@quarantine = quarantine
|
@quarantine = quarantine
|
||||||
@audit_token_conflicts = audit_token_conflicts
|
|
||||||
@any_named_args = any_named_args
|
@any_named_args = any_named_args
|
||||||
@language = language
|
@language = language
|
||||||
@only = only
|
@only = only
|
||||||
@ -131,7 +129,6 @@ module Cask
|
|||||||
strict: @audit_strict,
|
strict: @audit_strict,
|
||||||
signing: @audit_signing,
|
signing: @audit_signing,
|
||||||
new_cask: @audit_new_cask,
|
new_cask: @audit_new_cask,
|
||||||
token_conflicts: @audit_token_conflicts,
|
|
||||||
download: @audit_download,
|
download: @audit_download,
|
||||||
quarantine: @quarantine,
|
quarantine: @quarantine,
|
||||||
only: @only,
|
only: @only,
|
||||||
|
@ -8,7 +8,7 @@ require "cask/dsl"
|
|||||||
require "cask/metadata"
|
require "cask/metadata"
|
||||||
require "cask/tab"
|
require "cask/tab"
|
||||||
require "utils/bottles"
|
require "utils/bottles"
|
||||||
require "extend/api_hashable"
|
require "api_hashable"
|
||||||
|
|
||||||
module Cask
|
module Cask
|
||||||
# An instance of a cask.
|
# An instance of a cask.
|
||||||
@ -416,16 +416,14 @@ module Cask
|
|||||||
|
|
||||||
if @dsl.on_system_blocks_exist?
|
if @dsl.on_system_blocks_exist?
|
||||||
begin
|
begin
|
||||||
OnSystem::ALL_OS_ARCH_COMBINATIONS.each do |os, arch|
|
OnSystem::VALID_OS_ARCH_TAGS.each do |bottle_tag|
|
||||||
bottle_tag = ::Utils::Bottles::Tag.new(system: os, arch:)
|
|
||||||
next unless bottle_tag.valid_combination?
|
|
||||||
next if bottle_tag.linux? && @dsl.os.nil?
|
next if bottle_tag.linux? && @dsl.os.nil?
|
||||||
next if bottle_tag.macos? &&
|
next if bottle_tag.macos? &&
|
||||||
depends_on.macos &&
|
depends_on.macos &&
|
||||||
!@dsl.depends_on_set_in_block? &&
|
!@dsl.depends_on_set_in_block? &&
|
||||||
!depends_on.macos.allows?(bottle_tag.to_macos_version)
|
!depends_on.macos.allows?(bottle_tag.to_macos_version)
|
||||||
|
|
||||||
Homebrew::SimulateSystem.with(os:, arch:) do
|
Homebrew::SimulateSystem.with_tag(bottle_tag) do
|
||||||
refresh
|
refresh
|
||||||
|
|
||||||
to_h.each do |key, value|
|
to_h.each do |key, value|
|
||||||
|
@ -6,6 +6,7 @@ require "cask/cask"
|
|||||||
require "uri"
|
require "uri"
|
||||||
require "utils/curl"
|
require "utils/curl"
|
||||||
require "extend/hash/keys"
|
require "extend/hash/keys"
|
||||||
|
require "api"
|
||||||
|
|
||||||
module Cask
|
module Cask
|
||||||
# Loads a cask from various sources.
|
# Loads a cask from various sources.
|
||||||
@ -104,8 +105,8 @@ module Cask
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
return if %w[.rb .json].exclude?(path.extname)
|
|
||||||
return unless path.expand_path.exist?
|
return unless path.expand_path.exist?
|
||||||
|
return if invalid_path?(path)
|
||||||
|
|
||||||
return if Homebrew::EnvConfig.forbid_packages_from_paths? &&
|
return if Homebrew::EnvConfig.forbid_packages_from_paths? &&
|
||||||
!path.realpath.to_s.start_with?("#{Caskroom.path}/", "#{HOMEBREW_LIBRARY}/Taps/")
|
!path.realpath.to_s.start_with?("#{Caskroom.path}/", "#{HOMEBREW_LIBRARY}/Taps/")
|
||||||
@ -113,6 +114,14 @@ module Cask
|
|||||||
new(path)
|
new(path)
|
||||||
end
|
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
|
attr_reader :token, :path
|
||||||
|
|
||||||
sig { params(path: T.any(Pathname, String), token: String).void }
|
sig { params(path: T.any(Pathname, String), token: String).void }
|
||||||
@ -135,8 +144,10 @@ module Cask
|
|||||||
@content = path.read(encoding: "UTF-8")
|
@content = path.read(encoding: "UTF-8")
|
||||||
@config = config
|
@config = config
|
||||||
|
|
||||||
if path.extname == ".json"
|
if !self.class.invalid_path?(path, valid_extnames: %w[.json]) &&
|
||||||
return FromAPILoader.new(token, from_json: JSON.parse(@content), path:).load(config:)
|
(from_json = JSON.parse(@content).presence) &&
|
||||||
|
from_json.is_a?(Hash)
|
||||||
|
return FromAPILoader.new(token, from_json:, path:).load(config:)
|
||||||
end
|
end
|
||||||
|
|
||||||
begin
|
begin
|
||||||
@ -284,7 +295,7 @@ module Cask
|
|||||||
sig { returns(Pathname) }
|
sig { returns(Pathname) }
|
||||||
attr_reader :path
|
attr_reader :path
|
||||||
|
|
||||||
sig { returns(T.nilable(Hash)) }
|
sig { returns(T.nilable(T::Hash[String, T.untyped])) }
|
||||||
attr_reader :from_json
|
attr_reader :from_json
|
||||||
|
|
||||||
sig {
|
sig {
|
||||||
@ -306,7 +317,13 @@ module Cask
|
|||||||
new("#{tap}/#{token}")
|
new("#{tap}/#{token}")
|
||||||
end
|
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)
|
def initialize(token, from_json: T.unsafe(nil), path: nil)
|
||||||
@token = token.sub(%r{^homebrew/(?:homebrew-)?cask/}i, "")
|
@token = token.sub(%r{^homebrew/(?:homebrew-)?cask/}i, "")
|
||||||
@sourcefile_path = path || Homebrew::API::Cask.cached_json_file_path
|
@sourcefile_path = path || Homebrew::API::Cask.cached_json_file_path
|
||||||
@ -400,7 +417,7 @@ module Cask
|
|||||||
container(**container_hash)
|
container(**container_hash)
|
||||||
end
|
end
|
||||||
|
|
||||||
json_cask[:artifacts].each do |artifact|
|
json_cask[:artifacts]&.each do |artifact|
|
||||||
# convert generic string replacements into actual ones
|
# convert generic string replacements into actual ones
|
||||||
artifact = cask.loader.from_h_gsubs(artifact, appdir)
|
artifact = cask.loader.from_h_gsubs(artifact, appdir)
|
||||||
key = artifact.keys.first
|
key = artifact.keys.first
|
||||||
|
@ -26,7 +26,7 @@ require "cask/dsl/version"
|
|||||||
require "cask/url"
|
require "cask/url"
|
||||||
require "cask/utils"
|
require "cask/utils"
|
||||||
|
|
||||||
require "extend/on_system"
|
require "on_system"
|
||||||
|
|
||||||
module Cask
|
module Cask
|
||||||
# Class representing the domain-specific language used for casks.
|
# Class representing the domain-specific language used for casks.
|
||||||
@ -69,7 +69,6 @@ module Cask
|
|||||||
].freeze
|
].freeze
|
||||||
|
|
||||||
DSL_METHODS = Set.new([
|
DSL_METHODS = Set.new([
|
||||||
:appcast,
|
|
||||||
:arch,
|
:arch,
|
||||||
:artifacts,
|
:artifacts,
|
||||||
:auto_updates,
|
:auto_updates,
|
||||||
@ -123,15 +122,21 @@ module Cask
|
|||||||
|
|
||||||
sig { params(cask: Cask).void }
|
sig { params(cask: Cask).void }
|
||||||
def initialize(cask)
|
def initialize(cask)
|
||||||
# NOTE: Variables set by `set_unique_stanza` must be initialized to `nil`.
|
# NOTE: `:"@#{stanza}"` variables set by `set_unique_stanza` must be
|
||||||
@auto_updates = T.let(nil, T.nilable(T::Boolean))
|
# initialized to `nil`.
|
||||||
@arch = T.let(nil, T.nilable(String))
|
@arch = T.let(nil, T.nilable(String))
|
||||||
|
@arch_set_in_block = T.let(false, T::Boolean)
|
||||||
@artifacts = T.let(ArtifactSet.new, ArtifactSet)
|
@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)
|
@called_in_on_system_block = T.let(false, T::Boolean)
|
||||||
@cask = T.let(cask, Cask)
|
@cask = T.let(cask, Cask)
|
||||||
@caveats = T.let(DSL::Caveats.new(cask), DSL::Caveats)
|
@caveats = T.let(DSL::Caveats.new(cask), DSL::Caveats)
|
||||||
@conflicts_with = T.let(nil, T.nilable(DSL::ConflictsWith))
|
@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 = 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 = T.let(DSL::DependsOn.new, DSL::DependsOn)
|
||||||
@depends_on_set_in_block = T.let(false, T::Boolean)
|
@depends_on_set_in_block = T.let(false, T::Boolean)
|
||||||
@deprecated = 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_cask = T.let(nil, T.nilable(String))
|
||||||
@deprecation_replacement_formula = T.let(nil, T.nilable(String))
|
@deprecation_replacement_formula = T.let(nil, T.nilable(String))
|
||||||
@desc = 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_date = T.let(nil, T.nilable(Date))
|
||||||
@disable_reason = T.let(nil, T.nilable(T.any(String, Symbol)))
|
@disable_reason = T.let(nil, T.nilable(T.any(String, Symbol)))
|
||||||
@disable_replacement_cask = T.let(nil, T.nilable(String))
|
@disable_replacement_cask = T.let(nil, T.nilable(String))
|
||||||
@disable_replacement_formula = T.let(nil, T.nilable(String))
|
@disable_replacement_formula = T.let(nil, T.nilable(String))
|
||||||
@disabled = T.let(false, T::Boolean)
|
@disabled = T.let(false, T::Boolean)
|
||||||
@homepage = T.let(nil, T.nilable(String))
|
@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_blocks = T.let({}, T::Hash[T::Array[String], Proc])
|
||||||
@language_eval = T.let(nil, T.nilable(String))
|
@language_eval = T.let(nil, T.nilable(String))
|
||||||
@livecheck = T.let(Livecheck.new(cask), Livecheck)
|
@livecheck = T.let(Livecheck.new(cask), Livecheck)
|
||||||
@livecheck_defined = T.let(false, T::Boolean)
|
@livecheck_defined = T.let(false, T::Boolean)
|
||||||
@name = T.let([], T::Array[String])
|
@name = T.let([], T::Array[String])
|
||||||
@autobump = T.let(true, T::Boolean)
|
|
||||||
@no_autobump_defined = T.let(false, T::Boolean)
|
@no_autobump_defined = T.let(false, T::Boolean)
|
||||||
@on_system_blocks_exist = 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))
|
@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 = 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))
|
@staged_path = T.let(nil, T.nilable(Pathname))
|
||||||
@token = T.let(cask.token, String)
|
@token = T.let(cask.token, String)
|
||||||
@url = T.let(nil, T.nilable(URL))
|
@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 = T.let(nil, T.nilable(DSL::Version))
|
||||||
|
@version_set_in_block = T.let(false, T::Boolean)
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { returns(T::Boolean) }
|
sig { returns(T::Boolean) }
|
||||||
@ -216,7 +226,7 @@ module Cask
|
|||||||
raise CaskInvalidError.new(cask, "'#{stanza}' stanza may only appear once.")
|
raise CaskInvalidError.new(cask, "'#{stanza}' stanza may only appear once.")
|
||||||
end
|
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.")
|
raise CaskInvalidError.new(cask, "'#{stanza}' stanza may only be overridden once.")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -351,6 +361,8 @@ module Cask
|
|||||||
raise CaskInvalidError.new(cask, "invalid 'version' value: #{arg.inspect}")
|
raise CaskInvalidError.new(cask, "invalid 'version' value: #{arg.inspect}")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
no_autobump! because: :latest_version if arg == :latest
|
||||||
|
|
||||||
DSL::Version.new(arg)
|
DSL::Version.new(arg)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -474,7 +486,7 @@ module Cask
|
|||||||
def add_implicit_macos_dependency
|
def add_implicit_macos_dependency
|
||||||
return if (cask_depends_on = @depends_on).present? && cask_depends_on.macos.present?
|
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
|
end
|
||||||
|
|
||||||
# Declare conflicts that keep a cask from installing or working correctly.
|
# Declare conflicts that keep a cask from installing or working correctly.
|
||||||
@ -536,6 +548,8 @@ module Cask
|
|||||||
|
|
||||||
@livecheck_defined = true
|
@livecheck_defined = true
|
||||||
@livecheck.instance_eval(&block)
|
@livecheck.instance_eval(&block)
|
||||||
|
no_autobump! because: :extract_plist if @livecheck.strategy == :extract_plist
|
||||||
|
@livecheck
|
||||||
end
|
end
|
||||||
|
|
||||||
# Whether the cask contains a `livecheck` block. This is a legacy alias
|
# Whether the cask contains a `livecheck` block. This is a legacy alias
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "cask/utils"
|
require "cask/utils"
|
||||||
require "extend/on_system"
|
require "on_system"
|
||||||
|
|
||||||
module Cask
|
module Cask
|
||||||
class DSL
|
class DSL
|
||||||
|
@ -52,16 +52,17 @@ module Cask
|
|||||||
raise "Only a single 'depends_on macos' is allowed." if defined?(@macos)
|
raise "Only a single 'depends_on macos' is allowed." if defined?(@macos)
|
||||||
|
|
||||||
# workaround for https://github.com/sorbet/sorbet/issues/6860
|
# 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
|
begin
|
||||||
@macos = if args.count > 1
|
@macos = if args.count > 1
|
||||||
MacOSRequirement.new([args], comparator: "==")
|
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: "==")
|
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])
|
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])
|
MacOSRequirement.new([md[:version]], comparator: md[:comparator])
|
||||||
# This is not duplicate of the first case: see `args.first` and a different comparator.
|
# This is not duplicate of the first case: see `args.first` and a different comparator.
|
||||||
else # rubocop:disable Lint/DuplicateBranch
|
else # rubocop:disable Lint/DuplicateBranch
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
require "formula_installer"
|
require "formula_installer"
|
||||||
require "unpack_strategy"
|
require "unpack_strategy"
|
||||||
require "utils/topological_hash"
|
require "utils/topological_hash"
|
||||||
|
require "utils/analytics"
|
||||||
|
|
||||||
require "cask/config"
|
require "cask/config"
|
||||||
require "cask/download"
|
require "cask/download"
|
||||||
@ -11,8 +12,6 @@ require "cask/migrator"
|
|||||||
require "cask/quarantine"
|
require "cask/quarantine"
|
||||||
require "cask/tab"
|
require "cask/tab"
|
||||||
|
|
||||||
require "cgi"
|
|
||||||
|
|
||||||
module Cask
|
module Cask
|
||||||
# Installer for a {Cask}.
|
# Installer for a {Cask}.
|
||||||
class Installer
|
class Installer
|
||||||
@ -151,7 +150,7 @@ module Cask
|
|||||||
|
|
||||||
oh1 "Installing Cask #{Formatter.identifier(@cask)}"
|
oh1 "Installing Cask #{Formatter.identifier(@cask)}"
|
||||||
# GitHub Actions globally disables Gatekeeper.
|
# 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
|
stage
|
||||||
|
|
||||||
@cask.config = @cask.default_config.merge(old_config)
|
@cask.config = @cask.default_config.merge(old_config)
|
||||||
@ -305,6 +304,20 @@ on_request: true)
|
|||||||
|
|
||||||
next if artifact.is_a?(Artifact::Binary) && !binaries?
|
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(
|
artifact.install_phase(
|
||||||
command: @command, verbose: verbose?, adopt: adopt?, auto_updates: @cask.auto_updates,
|
command: @command, verbose: verbose?, adopt: adopt?, auto_updates: @cask.auto_updates,
|
||||||
force: force?, predecessor:
|
force: force?, predecessor:
|
||||||
@ -550,6 +563,18 @@ on_request: true)
|
|||||||
|
|
||||||
artifacts.each do |artifact|
|
artifacts.each do |artifact|
|
||||||
if artifact.respond_to?(:uninstall_phase)
|
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}"
|
odebug "Uninstalling artifact of class #{artifact.class}"
|
||||||
artifact.uninstall_phase(
|
artifact.uninstall_phase(
|
||||||
command: @command,
|
command: @command,
|
||||||
@ -564,6 +589,8 @@ on_request: true)
|
|||||||
|
|
||||||
next unless artifact.respond_to?(:post_uninstall_phase)
|
next unless artifact.respond_to?(:post_uninstall_phase)
|
||||||
|
|
||||||
|
artifact = T.cast(artifact, Artifact::Uninstall)
|
||||||
|
|
||||||
odebug "Post-uninstalling artifact of class #{artifact.class}"
|
odebug "Post-uninstalling artifact of class #{artifact.class}"
|
||||||
artifact.post_uninstall_phase(
|
artifact.post_uninstall_phase(
|
||||||
command: @command,
|
command: @command,
|
||||||
@ -577,7 +604,6 @@ on_request: true)
|
|||||||
|
|
||||||
def zap
|
def zap
|
||||||
load_installed_caskfile!
|
load_installed_caskfile!
|
||||||
ohai "Implied `brew uninstall --cask #{@cask}`"
|
|
||||||
uninstall_artifacts
|
uninstall_artifacts
|
||||||
if (zap_stanzas = @cask.artifacts.select { |a| a.is_a?(Artifact::Zap) }).empty?
|
if (zap_stanzas = @cask.artifacts.select { |a| a.is_a?(Artifact::Zap) }).empty?
|
||||||
opoo "No zap stanza present for Cask '#{@cask}'"
|
opoo "No zap stanza present for Cask '#{@cask}'"
|
||||||
@ -766,10 +792,10 @@ on_request: true)
|
|||||||
|
|
||||||
if installed_caskfile&.exist?
|
if installed_caskfile&.exist?
|
||||||
begin
|
begin
|
||||||
@cask = CaskLoader.load(installed_caskfile)
|
@cask = CaskLoader.load_from_installed_caskfile(installed_caskfile)
|
||||||
return
|
return
|
||||||
rescue CaskInvalidError
|
rescue CaskInvalidError, CaskUnavailableError
|
||||||
# could be caused by trying to load outdated caskfile
|
# could be caused by trying to load outdated or deleted caskfile
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -5,10 +5,24 @@ require "tab"
|
|||||||
|
|
||||||
module Cask
|
module Cask
|
||||||
class Tab < ::AbstractTab
|
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.
|
# 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 = super
|
||||||
|
|
||||||
tab.tabfile = cask.metadata_main_container_path/FILENAME
|
tab.tabfile = cask.metadata_main_container_path/FILENAME
|
||||||
@ -23,6 +37,7 @@ module Cask
|
|||||||
|
|
||||||
# Returns a {Tab} for an already installed cask,
|
# Returns a {Tab} for an already installed cask,
|
||||||
# or a fake one if the cask is not installed.
|
# or a fake one if the cask is not installed.
|
||||||
|
sig { params(cask: Cask).returns(T.attached_class) }
|
||||||
def self.for_cask(cask)
|
def self.for_cask(cask)
|
||||||
path = cask.metadata_main_container_path/FILENAME
|
path = cask.metadata_main_container_path/FILENAME
|
||||||
|
|
||||||
@ -40,6 +55,7 @@ module Cask
|
|||||||
tab
|
tab
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(T.attached_class) }
|
||||||
def self.empty
|
def self.empty
|
||||||
tab = super
|
tab = super
|
||||||
tab.uninstall_flight_blocks = false
|
tab.uninstall_flight_blocks = false
|
||||||
@ -76,10 +92,12 @@ module Cask
|
|||||||
runtime_deps
|
runtime_deps
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(T.nilable(String)) }
|
||||||
def version
|
def version
|
||||||
source["version"]
|
source["version"]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(_args: T.untyped).returns(String) }
|
||||||
def to_json(*_args)
|
def to_json(*_args)
|
||||||
attributes = {
|
attributes = {
|
||||||
"homebrew_version" => homebrew_version,
|
"homebrew_version" => homebrew_version,
|
||||||
@ -98,6 +116,7 @@ module Cask
|
|||||||
JSON.pretty_generate(attributes)
|
JSON.pretty_generate(attributes)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
s = ["Installed"]
|
s = ["Installed"]
|
||||||
s << "using the formulae.brew.sh API" if loaded_from_api
|
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]])
|
T.any(URI::Generic, String, [T.any(URI::Generic, String), T::Hash[Symbol, T.untyped]])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Methods for the `url` stanza.
|
||||||
class DSL
|
class DSL
|
||||||
sig { returns(T.any(URI::Generic, String)) }
|
sig { returns(T.any(URI::Generic, String)) }
|
||||||
attr_reader :uri
|
attr_reader :uri
|
||||||
|
|
||||||
sig { returns(T.nilable(T::Array[String])) }
|
sig { returns(T.nilable(T::Hash[T.any(Symbol, String), String])) }
|
||||||
attr_reader :revisions
|
attr_reader :revisions
|
||||||
|
|
||||||
sig { returns(T.nilable(T::Boolean)) }
|
sig { returns(T.nilable(T::Boolean)) }
|
||||||
@ -57,7 +58,7 @@ module Cask
|
|||||||
# @api public
|
# @api public
|
||||||
branch: T.nilable(String),
|
branch: T.nilable(String),
|
||||||
# @api public
|
# @api public
|
||||||
revisions: T.nilable(T::Array[String]),
|
revisions: T.nilable(T::Hash[T.any(Symbol, String), String]),
|
||||||
# @api public
|
# @api public
|
||||||
revision: T.nilable(String),
|
revision: T.nilable(String),
|
||||||
# @api public
|
# @api public
|
||||||
@ -87,7 +88,7 @@ module Cask
|
|||||||
specs[:using] = @using = T.let(using, T.any(T::Class[AbstractDownloadStrategy], Symbol, NilClass))
|
specs[:using] = @using = T.let(using, T.any(T::Class[AbstractDownloadStrategy], Symbol, NilClass))
|
||||||
specs[:tag] = @tag = T.let(tag, T.nilable(String))
|
specs[:tag] = @tag = T.let(tag, T.nilable(String))
|
||||||
specs[:branch] = @branch = T.let(branch, 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[:revision] = @revision = T.let(revision, T.nilable(String))
|
||||||
specs[:trust_cert] = @trust_cert = T.let(trust_cert, T.nilable(T::Boolean))
|
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]))
|
specs[:cookies] = @cookies = T.let(cookies, T.nilable(T::Hash[String, String]))
|
||||||
@ -101,6 +102,7 @@ module Cask
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Allow passing a block to the `url` stanza.
|
||||||
class BlockDSL
|
class BlockDSL
|
||||||
# Allow accessing the URL associated with page contents.
|
# Allow accessing the URL associated with page contents.
|
||||||
class PageWithURL < SimpleDelegator
|
class PageWithURL < SimpleDelegator
|
||||||
@ -197,7 +199,7 @@ module Cask
|
|||||||
using: T.any(T::Class[AbstractDownloadStrategy], Symbol, NilClass),
|
using: T.any(T::Class[AbstractDownloadStrategy], Symbol, NilClass),
|
||||||
tag: T.nilable(String),
|
tag: T.nilable(String),
|
||||||
branch: 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),
|
revision: T.nilable(String),
|
||||||
trust_cert: T.nilable(T::Boolean),
|
trust_cert: T.nilable(T::Boolean),
|
||||||
cookies: T.nilable(T::Hash[String, String]),
|
cookies: T.nilable(T::Hash[String, String]),
|
||||||
|
@ -14,10 +14,13 @@ class Caveats
|
|||||||
sig { params(formula: Formula).void }
|
sig { params(formula: Formula).void }
|
||||||
def initialize(formula)
|
def initialize(formula)
|
||||||
@formula = formula
|
@formula = formula
|
||||||
|
@caveats = T.let(nil, T.nilable(String))
|
||||||
|
@completions_and_elisp = T.let(nil, T.nilable(T::Array[String]))
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def caveats
|
def caveats
|
||||||
|
@caveats ||= begin
|
||||||
caveats = []
|
caveats = []
|
||||||
build = formula.build
|
build = formula.build
|
||||||
begin
|
begin
|
||||||
@ -28,7 +31,21 @@ class Caveats
|
|||||||
formula.build = build
|
formula.build = build
|
||||||
end
|
end
|
||||||
caveats << keg_only_text
|
caveats << keg_only_text
|
||||||
|
caveats << service_caveats
|
||||||
|
caveats.compact.join("\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
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
|
valid_shells = [:bash, :zsh, :fish, :pwsh].freeze
|
||||||
current_shell = Utils::Shell.preferred || Utils::Shell.parent
|
current_shell = Utils::Shell.preferred || Utils::Shell.parent
|
||||||
shells = if current_shell.present? &&
|
shells = if current_shell.present? &&
|
||||||
@ -38,16 +55,13 @@ class Caveats
|
|||||||
else
|
else
|
||||||
valid_shells
|
valid_shells
|
||||||
end
|
end
|
||||||
shells.each do |shell|
|
completions_and_elisp = shells.map do |shell|
|
||||||
caveats << function_completion_caveats(shell)
|
function_completion_caveats(shell)
|
||||||
|
end
|
||||||
|
completions_and_elisp << elisp_caveats
|
||||||
|
completions_and_elisp.compact
|
||||||
end
|
end
|
||||||
|
|
||||||
caveats << service_caveats
|
|
||||||
caveats << elisp_caveats
|
|
||||||
caveats.compact.join("\n")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
delegate [:empty?, :to_s] => :caveats
|
|
||||||
|
|
||||||
sig { params(skip_reason: T::Boolean).returns(T.nilable(String)) }
|
sig { params(skip_reason: T::Boolean).returns(T.nilable(String)) }
|
||||||
def keg_only_text(skip_reason: false)
|
def keg_only_text(skip_reason: false)
|
||||||
|
@ -571,6 +571,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
return unless available
|
return unless available
|
||||||
return if Context.current.quiet?
|
return if Context.current.quiet?
|
||||||
|
return if cask&.old_tokens&.include?(ref)
|
||||||
|
|
||||||
opoo package_conflicts_message(ref, loaded_type, cask)
|
opoo package_conflicts_message(ref, loaded_type, cask)
|
||||||
end
|
end
|
||||||
|
@ -169,7 +169,7 @@ module Homebrew
|
|||||||
T::Boolean)
|
T::Boolean)
|
||||||
odisabled(
|
odisabled(
|
||||||
"`brew #{@command_name}'. This command needs to be refactored, as it is written in a style that",
|
"`brew #{@command_name}'. This command needs to be refactored, as it is written in a style that",
|
||||||
"inherits from `Homebrew::AbstractCommand' ( see https://docs.brew.sh/External-Commands )",
|
"subclassing of `Homebrew::AbstractCommand' ( see https://docs.brew.sh/External-Commands )",
|
||||||
disable_for_developers: false,
|
disable_for_developers: false,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
@ -208,11 +208,15 @@ module Homebrew
|
|||||||
return if global_switch
|
return if global_switch
|
||||||
|
|
||||||
description = option_description(description, *names, hidden:)
|
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
|
if replacement || disable
|
||||||
description += " (#{disable ? "disabled" : "deprecated"}#{"; replaced by #{replacement}" if replacement})"
|
description += " (#{disable ? "disabled" : "deprecated"}#{"; replaced by #{replacement}" if replacement})"
|
||||||
end
|
end
|
||||||
|
process_option(*names, description, type: :switch, hidden:) unless disable
|
||||||
|
|
||||||
@parser.public_send(method, *names, *wrap_option_desc(description)) do |value|
|
@parser.public_send(method, *names, *wrap_option_desc(description)) do |value|
|
||||||
# This odeprecated should stick around indefinitely.
|
# This odeprecated should stick around indefinitely.
|
||||||
|
@ -31,7 +31,7 @@ module Homebrew
|
|||||||
sig { override.void }
|
sig { override.void }
|
||||||
def run
|
def run
|
||||||
ENV.activate_extensions!
|
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
|
ENV.setup_build_environment
|
||||||
|
|
||||||
shell = if args.plain?
|
shell = if args.plain?
|
||||||
|
@ -73,11 +73,10 @@ module Homebrew
|
|||||||
description: "`install` prints output from commands as they are run. " \
|
description: "`install` prints output from commands as they are run. " \
|
||||||
"`check` lists all missing dependencies."
|
"`check` lists all missing dependencies."
|
||||||
switch "--no-upgrade",
|
switch "--no-upgrade",
|
||||||
env: :bundle_no_upgrade,
|
|
||||||
description: "`install` does not run `brew upgrade` on outdated dependencies. " \
|
description: "`install` does not run `brew upgrade` on outdated dependencies. " \
|
||||||
"`check` does not check for outdated dependencies. " \
|
"`check` does not check for outdated dependencies. " \
|
||||||
"Note they may still be upgraded by `brew install` if needed. " \
|
"Note they may still be upgraded by `brew install` if needed.",
|
||||||
"This is enabled by default if `$HOMEBREW_BUNDLE_NO_UPGRADE` is set."
|
env: :bundle_no_upgrade
|
||||||
switch "--upgrade",
|
switch "--upgrade",
|
||||||
description: "`install` runs `brew upgrade` on outdated dependencies, " \
|
description: "`install` runs `brew upgrade` on outdated dependencies, " \
|
||||||
"even if `$HOMEBREW_BUNDLE_NO_UPGRADE` is set."
|
"even if `$HOMEBREW_BUNDLE_NO_UPGRADE` is set."
|
||||||
@ -87,41 +86,36 @@ module Homebrew
|
|||||||
switch "--install",
|
switch "--install",
|
||||||
description: "Run `install` before continuing to other operations e.g. `exec`."
|
description: "Run `install` before continuing to other operations e.g. `exec`."
|
||||||
switch "--services",
|
switch "--services",
|
||||||
env: :bundle_services,
|
description: "Temporarily start services while running the `exec` or `sh` command.",
|
||||||
description: "Temporarily start services while running the `exec` or `sh` command. " \
|
env: :bundle_services
|
||||||
"This is enabled by default if `$HOMEBREW_BUNDLE_SERVICES` is set."
|
|
||||||
switch "-f", "--force",
|
switch "-f", "--force",
|
||||||
description: "`install` runs with `--force`/`--overwrite`. " \
|
description: "`install` runs with `--force`/`--overwrite`. " \
|
||||||
"`dump` overwrites an existing `Brewfile`. " \
|
"`dump` overwrites an existing `Brewfile`. " \
|
||||||
"`cleanup` actually performs its cleanup operations."
|
"`cleanup` actually performs its cleanup operations."
|
||||||
switch "--cleanup",
|
switch "--cleanup",
|
||||||
env: :bundle_install_cleanup,
|
description: "`install` performs cleanup operation, same as running `cleanup --force`.",
|
||||||
description: "`install` performs cleanup operation, same as running `cleanup --force`. " \
|
env: [:bundle_install_cleanup, "--global"]
|
||||||
"This is enabled by default if `$HOMEBREW_BUNDLE_INSTALL_CLEANUP` is set and " \
|
|
||||||
"`--global` is passed."
|
|
||||||
switch "--all",
|
switch "--all",
|
||||||
description: "`list` all dependencies."
|
description: "`list` all dependencies."
|
||||||
switch "--formula", "--brews",
|
switch "--formula", "--formulae", "--brews",
|
||||||
description: "`list` or `dump` Homebrew formula dependencies."
|
description: "`list`, `dump` or `cleanup` Homebrew formula dependencies."
|
||||||
switch "--cask", "--casks",
|
switch "--cask", "--casks",
|
||||||
description: "`list` or `dump` Homebrew cask dependencies."
|
description: "`list`, `dump` or `cleanup` Homebrew cask dependencies."
|
||||||
switch "--tap", "--taps",
|
switch "--tap", "--taps",
|
||||||
description: "`list` or `dump` Homebrew tap dependencies."
|
description: "`list`, `dump` or `cleanup` Homebrew tap dependencies."
|
||||||
switch "--mas",
|
switch "--mas",
|
||||||
description: "`list` or `dump` Mac App Store dependencies."
|
description: "`list` or `dump` Mac App Store dependencies."
|
||||||
switch "--whalebrew",
|
switch "--whalebrew",
|
||||||
description: "`list` or `dump` Whalebrew dependencies."
|
description: "`list` or `dump` Whalebrew dependencies."
|
||||||
switch "--vscode",
|
switch "--vscode",
|
||||||
description: "`list` or `dump` VSCode (and forks/variants) extensions."
|
description: "`list`, `dump` or `cleanup` VSCode (and forks/variants) extensions."
|
||||||
switch "--no-vscode",
|
switch "--no-vscode",
|
||||||
env: :bundle_dump_no_vscode,
|
description: "`dump` without VSCode (and forks/variants) extensions.",
|
||||||
description: "`dump` without VSCode (and forks/variants) extensions. " \
|
env: :bundle_dump_no_vscode
|
||||||
"This is enabled by default if `$HOMEBREW_BUNDLE_DUMP_NO_VSCODE` is set."
|
|
||||||
switch "--describe",
|
switch "--describe",
|
||||||
env: :bundle_dump_describe,
|
|
||||||
description: "`dump` adds a description comment above each line, unless the " \
|
description: "`dump` adds a description comment above each line, unless the " \
|
||||||
"dependency does not have a description. " \
|
"dependency does not have a description.",
|
||||||
"This is enabled by default if `$HOMEBREW_BUNDLE_DUMP_DESCRIBE` is set."
|
env: :bundle_dump_describe
|
||||||
switch "--no-restart",
|
switch "--no-restart",
|
||||||
description: "`dump` does not add `restart_service` to formula lines."
|
description: "`dump` does not add `restart_service` to formula lines."
|
||||||
switch "--zap",
|
switch "--zap",
|
||||||
@ -168,7 +162,7 @@ module Homebrew
|
|||||||
zap = args.zap?
|
zap = args.zap?
|
||||||
Homebrew::Bundle.upgrade_formulae = args.upgrade_formulae
|
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 args.install?
|
||||||
if [nil, "install", "upgrade"].include?(subcommand)
|
if [nil, "install", "upgrade"].include?(subcommand)
|
||||||
@ -215,7 +209,7 @@ module Homebrew
|
|||||||
describe: args.describe?,
|
describe: args.describe?,
|
||||||
no_restart: args.no_restart?,
|
no_restart: args.no_restart?,
|
||||||
taps: args.taps? || no_type_args,
|
taps: args.taps? || no_type_args,
|
||||||
brews: args.brews? || no_type_args,
|
formulae: args.formulae? || no_type_args,
|
||||||
casks: args.casks? || no_type_args,
|
casks: args.casks? || no_type_args,
|
||||||
mas: args.mas? || no_type_args,
|
mas: args.mas? || no_type_args,
|
||||||
whalebrew: args.whalebrew? || no_type_args,
|
whalebrew: args.whalebrew? || no_type_args,
|
||||||
@ -226,7 +220,13 @@ module Homebrew
|
|||||||
exec_editor(Homebrew::Bundle::Brewfile.path(global:, file:))
|
exec_editor(Homebrew::Bundle::Brewfile.path(global:, file:))
|
||||||
when "cleanup"
|
when "cleanup"
|
||||||
require "bundle/commands/cleanup"
|
require "bundle/commands/cleanup"
|
||||||
Homebrew::Bundle::Commands::Cleanup.run(global:, file:, force:, zap:)
|
Homebrew::Bundle::Commands::Cleanup.run(
|
||||||
|
global:, file:, force:, zap:,
|
||||||
|
formulae: args.formulae? || no_type_args,
|
||||||
|
casks: args.casks? || no_type_args,
|
||||||
|
taps: args.taps? || no_type_args,
|
||||||
|
vscode: args.vscode? || no_type_args
|
||||||
|
)
|
||||||
when "check"
|
when "check"
|
||||||
require "bundle/commands/check"
|
require "bundle/commands/check"
|
||||||
Homebrew::Bundle::Commands::Check.run(global:, file:, no_upgrade:, verbose:)
|
Homebrew::Bundle::Commands::Check.run(global:, file:, no_upgrade:, verbose:)
|
||||||
@ -235,7 +235,7 @@ module Homebrew
|
|||||||
Homebrew::Bundle::Commands::List.run(
|
Homebrew::Bundle::Commands::List.run(
|
||||||
global:,
|
global:,
|
||||||
file:,
|
file:,
|
||||||
brews: args.brews? || args.all? || no_type_args,
|
formulae: args.formulae? || args.all? || no_type_args,
|
||||||
casks: args.casks? || args.all?,
|
casks: args.casks? || args.all?,
|
||||||
taps: args.taps? || args.all?,
|
taps: args.taps? || args.all?,
|
||||||
mas: args.mas? || args.all?,
|
mas: args.mas? || args.all?,
|
||||||
@ -243,9 +243,9 @@ module Homebrew
|
|||||||
vscode: args.vscode? || args.all?,
|
vscode: args.vscode? || args.all?,
|
||||||
)
|
)
|
||||||
when "add", "remove"
|
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 = {
|
type_hash = {
|
||||||
brew: args.brews?,
|
brew: args.formulae?,
|
||||||
cask: args.casks?,
|
cask: args.casks?,
|
||||||
tap: args.taps?,
|
tap: args.taps?,
|
||||||
mas: args.mas?,
|
mas: args.mas?,
|
||||||
@ -276,17 +276,7 @@ module Homebrew
|
|||||||
_subcommand, *named_args = args.named
|
_subcommand, *named_args = args.named
|
||||||
named_args
|
named_args
|
||||||
when "sh"
|
when "sh"
|
||||||
preferred_path = Utils::Shell.preferred_path(default: "/bin/bash")
|
["sh"]
|
||||||
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:)]
|
|
||||||
when "env"
|
when "env"
|
||||||
["env"]
|
["env"]
|
||||||
end
|
end
|
||||||
|
@ -18,8 +18,7 @@ module Homebrew
|
|||||||
|
|
||||||
If any version of each formula argument is installed and no other options
|
If any version of each formula argument is installed and no other options
|
||||||
are passed, this command displays their actual runtime dependencies (similar
|
are passed, this command displays their actual runtime dependencies (similar
|
||||||
to `brew linkage`), which may differ from the current versions' stated
|
to `brew linkage`), which may differ from a formula's declared dependencies.
|
||||||
dependencies if the installed versions are outdated.
|
|
||||||
|
|
||||||
*Note:* `--missing` and `--skip-recommended` have precedence over `--include-*`.
|
*Note:* `--missing` and `--skip-recommended` have precedence over `--include-*`.
|
||||||
EOS
|
EOS
|
||||||
@ -92,26 +91,50 @@ module Homebrew
|
|||||||
raise UsageError, "`brew deps --arch=all` is not supported" if args.arch == "all"
|
raise UsageError, "`brew deps --arch=all` is not supported" if args.arch == "all"
|
||||||
|
|
||||||
os, arch = T.must(args.os_arch_combinations.first)
|
os, arch = T.must(args.os_arch_combinations.first)
|
||||||
all = args.eval_all?
|
eval_all = args.eval_all?
|
||||||
|
|
||||||
Formulary.enable_factory_cache!
|
Formulary.enable_factory_cache!
|
||||||
|
|
||||||
SimulateSystem.with(os:, arch:) do
|
SimulateSystem.with(os:, arch:) do
|
||||||
recursive = !args.direct?
|
@use_runtime_dependencies = true
|
||||||
installed = args.installed? || dependents(args.named.to_formulae_and_casks).all?(&:any_version_installed?)
|
|
||||||
|
|
||||||
@use_runtime_dependencies = installed && recursive &&
|
installed = args.installed? || dependents(args.named.to_formulae_and_casks).all?(&:any_version_installed?)
|
||||||
!args.tree? &&
|
unless installed
|
||||||
!args.graph? &&
|
not_using_runtime_dependencies_reason = if args.installed?
|
||||||
!args.HEAD? &&
|
"not all the named formulae were installed"
|
||||||
!args.include_implicit? &&
|
else
|
||||||
!args.include_build? &&
|
"`--installed` was not passed"
|
||||||
!args.include_test? &&
|
end
|
||||||
!args.include_optional? &&
|
|
||||||
!args.skip_recommended? &&
|
@use_runtime_dependencies = false
|
||||||
!args.missing? &&
|
end
|
||||||
args.os.nil? &&
|
|
||||||
args.arch.nil?
|
%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?
|
if args.tree? || args.graph?
|
||||||
dependents = if args.named.present?
|
dependents = if args.named.present?
|
||||||
@ -141,9 +164,9 @@ module Homebrew
|
|||||||
|
|
||||||
puts_deps_tree(dependents, recursive:)
|
puts_deps_tree(dependents, recursive:)
|
||||||
return
|
return
|
||||||
elsif all
|
elsif eval_all
|
||||||
puts_deps(sorted_dependents(
|
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:)
|
), recursive:)
|
||||||
return
|
return
|
||||||
elsif !args.no_named? && args.for_each?
|
elsif !args.no_named? && args.for_each?
|
||||||
|
@ -25,7 +25,8 @@ module Homebrew
|
|||||||
"it is interpreted as a regular expression."
|
"it is interpreted as a regular expression."
|
||||||
switch "--eval-all",
|
switch "--eval-all",
|
||||||
description: "Evaluate all available formulae and casks, whether installed or not, to search their " \
|
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",
|
switch "--formula", "--formulae",
|
||||||
description: "Treat all named arguments as formulae."
|
description: "Treat all named arguments as formulae."
|
||||||
switch "--cask", "--casks",
|
switch "--cask", "--casks",
|
||||||
@ -47,7 +48,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
|
|
||||||
if search_type.present?
|
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!"
|
raise UsageError, "`brew desc --search` needs `--eval-all` passed or `$HOMEBREW_EVAL_ALL` set!"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ module Homebrew
|
|||||||
cmd_args do
|
cmd_args do
|
||||||
description <<~EOS
|
description <<~EOS
|
||||||
Control Homebrew's developer mode. When developer mode is enabled,
|
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.
|
branch instead of the latest stable version along with some other behaviour changes.
|
||||||
|
|
||||||
`brew developer` [`state`]:
|
`brew developer` [`state`]:
|
||||||
@ -38,7 +38,7 @@ module Homebrew
|
|||||||
puts "However, `brew update` will update to the latest stable tag because " \
|
puts "However, `brew update` will update to the latest stable tag because " \
|
||||||
"#{Tty.bold}HOMEBREW_UPDATE_TO_TAG#{Tty.reset} is set."
|
"#{Tty.bold}HOMEBREW_UPDATE_TO_TAG#{Tty.reset} is set."
|
||||||
else
|
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
|
end
|
||||||
else
|
else
|
||||||
puts "`brew update` will update to the latest stable tag."
|
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
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "abstract_command"
|
require "abstract_command"
|
||||||
@ -6,6 +6,7 @@ require "formula"
|
|||||||
require "fetch"
|
require "fetch"
|
||||||
require "cask/download"
|
require "cask/download"
|
||||||
require "retryable_download"
|
require "retryable_download"
|
||||||
|
require "download_queue"
|
||||||
|
|
||||||
module Homebrew
|
module Homebrew
|
||||||
module Cmd
|
module Cmd
|
||||||
@ -69,15 +70,16 @@ module Homebrew
|
|||||||
named_args [:formula, :cask], min: 1
|
named_args [:formula, :cask], min: 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(Integer) }
|
||||||
def concurrency
|
def concurrency
|
||||||
@concurrency ||= args.concurrency&.to_i || 1
|
@concurrency ||= T.let(args.concurrency&.to_i || 1, T.nilable(Integer))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(DownloadQueue) }
|
||||||
def download_queue
|
def download_queue
|
||||||
@download_queue ||= begin
|
@download_queue ||= T.let(begin
|
||||||
require "download_queue"
|
|
||||||
DownloadQueue.new(concurrency)
|
DownloadQueue.new(concurrency)
|
||||||
end
|
end, T.nilable(DownloadQueue))
|
||||||
end
|
end
|
||||||
|
|
||||||
class Spinner
|
class Spinner
|
||||||
@ -96,8 +98,8 @@ module Homebrew
|
|||||||
|
|
||||||
sig { void }
|
sig { void }
|
||||||
def initialize
|
def initialize
|
||||||
@start = Time.now
|
@start = T.let(Time.now, Time)
|
||||||
@i = 0
|
@i = T.let(0, Integer)
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
@ -136,7 +138,7 @@ module Homebrew
|
|||||||
bucket.each do |formula_or_cask|
|
bucket.each do |formula_or_cask|
|
||||||
case formula_or_cask
|
case formula_or_cask
|
||||||
when Formula
|
when Formula
|
||||||
formula = T.cast(formula_or_cask, Formula)
|
formula = formula_or_cask
|
||||||
ref = formula.loaded_from_api? ? formula.full_name : formula.path
|
ref = formula.loaded_from_api? ? formula.full_name : formula.path
|
||||||
|
|
||||||
os_arch_combinations.each do |os, arch|
|
os_arch_combinations.each do |os, arch|
|
||||||
@ -189,7 +191,9 @@ module Homebrew
|
|||||||
|
|
||||||
next if fetched_bottle
|
next if fetched_bottle
|
||||||
|
|
||||||
fetch_downloadable(formula.resource)
|
if (resource = formula.resource)
|
||||||
|
fetch_downloadable(resource)
|
||||||
|
end
|
||||||
|
|
||||||
formula.resources.each do |r|
|
formula.resources.each do |r|
|
||||||
fetch_downloadable(r)
|
fetch_downloadable(r)
|
||||||
@ -231,7 +235,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
spinner = Spinner.new
|
spinner = Spinner.new
|
||||||
remaining_downloads = downloads.dup
|
remaining_downloads = downloads.dup.to_a
|
||||||
previous_pending_line_count = 0
|
previous_pending_line_count = 0
|
||||||
|
|
||||||
begin
|
begin
|
||||||
@ -332,10 +336,13 @@ module Homebrew
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
sig { returns(T::Hash[T.any(Resource, Bottle, Cask::Download), Concurrent::Promises::Future]) }
|
||||||
def downloads
|
def downloads
|
||||||
@downloads ||= {}
|
@downloads ||= T.let({}, T.nilable(T::Hash[T.any(Resource, Bottle, Cask::Download),
|
||||||
|
Concurrent::Promises::Future]))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(downloadable: T.any(Resource, Bottle, Cask::Download)).void }
|
||||||
def fetch_downloadable(downloadable)
|
def fetch_downloadable(downloadable)
|
||||||
downloads[downloadable] ||= begin
|
downloads[downloadable] ||= begin
|
||||||
tries = args.retry? ? {} : { tries: 1 }
|
tries = args.retry? ? {} : { tries: 1 }
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "abstract_command"
|
require "abstract_command"
|
||||||
@ -18,7 +18,7 @@ module Homebrew
|
|||||||
class Info < AbstractCommand
|
class Info < AbstractCommand
|
||||||
VALID_DAYS = %w[30 90 365].freeze
|
VALID_DAYS = %w[30 90 365].freeze
|
||||||
VALID_FORMULA_CATEGORIES = %w[install install-on-request build-error].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
|
cmd_args do
|
||||||
description <<~EOS
|
description <<~EOS
|
||||||
@ -57,7 +57,7 @@ module Homebrew
|
|||||||
switch "--eval-all",
|
switch "--eval-all",
|
||||||
depends_on: "--json",
|
depends_on: "--json",
|
||||||
description: "Evaluate all available formulae and casks, whether installed or not, to print their " \
|
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",
|
switch "--variations",
|
||||||
depends_on: "--json",
|
depends_on: "--json",
|
||||||
description: "Include the variations hash in each formula's JSON output."
|
description: "Include the variations hash in each formula's JSON output."
|
||||||
@ -96,14 +96,15 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
|
|
||||||
print_analytics
|
print_analytics
|
||||||
elsif args.json
|
elsif (json = args.json)
|
||||||
all = args.eval_all?
|
print_json(json, args.eval_all?)
|
||||||
|
|
||||||
print_json(all)
|
|
||||||
elsif args.github?
|
elsif args.github?
|
||||||
raise FormulaOrCaskUnspecifiedError if args.no_named?
|
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?
|
elsif args.no_named?
|
||||||
print_statistics
|
print_statistics
|
||||||
else
|
else
|
||||||
@ -111,6 +112,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(remote: String, path: String).returns(String) }
|
||||||
def github_remote_path(remote, path)
|
def github_remote_path(remote, path)
|
||||||
if remote =~ %r{^(?:https?://|git(?:@|://))github\.com[:/](.+)/(.+?)(?:\.git)?$}
|
if remote =~ %r{^(?:https?://|git(?:@|://))github\.com[:/](.+)/(.+?)(?:\.git)?$}
|
||||||
"https://github.com/#{Regexp.last_match(1)}/#{Regexp.last_match(2)}/blob/HEAD/#{path}"
|
"https://github.com/#{Regexp.last_match(1)}/#{Regexp.last_match(2)}/blob/HEAD/#{path}"
|
||||||
@ -175,6 +177,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(version: T.any(T::Boolean, String)).returns(Symbol) }
|
||||||
def json_version(version)
|
def json_version(version)
|
||||||
version_hash = {
|
version_hash = {
|
||||||
true => :default,
|
true => :default,
|
||||||
@ -187,16 +190,16 @@ module Homebrew
|
|||||||
version_hash[version]
|
version_hash[version]
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { params(all: T::Boolean).void }
|
sig { params(json: T.any(T::Boolean, String), eval_all: T::Boolean).void }
|
||||||
def print_json(all)
|
def print_json(json, eval_all)
|
||||||
raise FormulaOrCaskUnspecifiedError if !(all || args.installed?) && args.no_named?
|
raise FormulaOrCaskUnspecifiedError if !(eval_all || args.installed?) && args.no_named?
|
||||||
|
|
||||||
json = case json_version(args.json)
|
json = case json_version(json)
|
||||||
when :v1, :default
|
when :v1, :default
|
||||||
raise UsageError, "Cannot specify `--cask` when using `--json=v1`!" if args.cask?
|
raise UsageError, "Cannot specify `--cask` when using `--json=v1`!" if args.cask?
|
||||||
|
|
||||||
formulae = if all
|
formulae = if eval_all
|
||||||
Formula.all(eval_all: args.eval_all?).sort
|
Formula.all(eval_all:).sort
|
||||||
elsif args.installed?
|
elsif args.installed?
|
||||||
Formula.installed.sort
|
Formula.installed.sort
|
||||||
else
|
else
|
||||||
@ -210,10 +213,10 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
when :v2
|
when :v2
|
||||||
formulae, casks = T.let(
|
formulae, casks = T.let(
|
||||||
if all
|
if eval_all
|
||||||
[
|
[
|
||||||
Formula.all(eval_all: args.eval_all?).sort,
|
Formula.all(eval_all:).sort,
|
||||||
Cask::Cask.all(eval_all: args.eval_all?).sort_by(&:full_name),
|
Cask::Cask.all(eval_all:).sort_by(&:full_name),
|
||||||
]
|
]
|
||||||
elsif args.installed?
|
elsif args.installed?
|
||||||
[Formula.installed.sort, Cask::Caskroom.casks.sort_by(&:full_name)]
|
[Formula.installed.sort, Cask::Caskroom.casks.sort_by(&:full_name)]
|
||||||
@ -240,25 +243,31 @@ module Homebrew
|
|||||||
puts JSON.pretty_generate(json)
|
puts JSON.pretty_generate(json)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(formula_or_cask: T.any(Formula, Cask::Cask)).returns(String) }
|
||||||
def github_info(formula_or_cask)
|
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
|
path = case formula_or_cask
|
||||||
when Formula
|
when Formula
|
||||||
formula = formula_or_cask
|
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
|
when Cask::Cask
|
||||||
cask = formula_or_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"
|
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
|
end
|
||||||
|
|
||||||
cask.sourcefile_path.relative_path_from(cask.tap.path)
|
cask.sourcefile_path.relative_path_from(tap.path)
|
||||||
end
|
end
|
||||||
|
|
||||||
github_remote_path(formula_or_cask.tap.remote, path)
|
github_remote_path(tap.remote, path.to_s)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(formula: Formula).void }
|
||||||
def info_formula(formula)
|
def info_formula(formula)
|
||||||
specs = []
|
specs = []
|
||||||
|
|
||||||
@ -356,6 +365,7 @@ module Homebrew
|
|||||||
Utils::Analytics.formula_output(formula, args:)
|
Utils::Analytics.formula_output(formula, args:)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(dependencies: T::Array[Dependency]).returns(String) }
|
||||||
def decorate_dependencies(dependencies)
|
def decorate_dependencies(dependencies)
|
||||||
deps_status = dependencies.map do |dep|
|
deps_status = dependencies.map do |dep|
|
||||||
if dep.satisfied?([])
|
if dep.satisfied?([])
|
||||||
@ -367,6 +377,7 @@ module Homebrew
|
|||||||
deps_status.join(", ")
|
deps_status.join(", ")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(requirements: T::Array[Requirement]).returns(String) }
|
||||||
def decorate_requirements(requirements)
|
def decorate_requirements(requirements)
|
||||||
req_status = requirements.map do |req|
|
req_status = requirements.map do |req|
|
||||||
req_s = req.display_s
|
req_s = req.display_s
|
||||||
@ -375,12 +386,14 @@ module Homebrew
|
|||||||
req_status.join(", ")
|
req_status.join(", ")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(dep: Dependency).returns(String) }
|
||||||
def dep_display_s(dep)
|
def dep_display_s(dep)
|
||||||
return dep.name if dep.option_tags.empty?
|
return dep.name if dep.option_tags.empty?
|
||||||
|
|
||||||
"#{dep.name} #{dep.option_tags.map { |o| "--#{o}" }.join(" ")}"
|
"#{dep.name} #{dep.option_tags.map { |o| "--#{o}" }.join(" ")}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(cask: Cask::Cask).void }
|
||||||
def info_cask(cask)
|
def info_cask(cask)
|
||||||
require "cask/info"
|
require "cask/info"
|
||||||
|
|
||||||
|
@ -33,8 +33,8 @@ module Homebrew
|
|||||||
description: "If brewing fails, open an interactive debugging session with access to IRB " \
|
description: "If brewing fails, open an interactive debugging session with access to IRB " \
|
||||||
"or a shell inside the temporary build directory."
|
"or a shell inside the temporary build directory."
|
||||||
switch "--display-times",
|
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",
|
switch "-f", "--force",
|
||||||
description: "Install formulae without checking for previously installed keg-only or " \
|
description: "Install formulae without checking for previously installed keg-only or " \
|
||||||
"non-migrated versions. When installing casks, overwrite existing files " \
|
"non-migrated versions. When installing casks, overwrite existing files " \
|
||||||
@ -44,9 +44,9 @@ module Homebrew
|
|||||||
switch "-n", "--dry-run",
|
switch "-n", "--dry-run",
|
||||||
description: "Show what would be installed, but do not actually install anything."
|
description: "Show what would be installed, but do not actually install anything."
|
||||||
switch "--ask",
|
switch "--ask",
|
||||||
env: :ask,
|
|
||||||
description: "Ask for confirmation before downloading and installing formulae. " \
|
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", {
|
[:switch, "--formula", "--formulae", {
|
||||||
description: "Treat all named arguments as formulae.",
|
description: "Treat all named arguments as formulae.",
|
||||||
@ -310,9 +310,7 @@ module Homebrew
|
|||||||
Install.perform_preinstall_checks_once
|
Install.perform_preinstall_checks_once
|
||||||
Install.check_cc_argv(args.cc)
|
Install.check_cc_argv(args.cc)
|
||||||
|
|
||||||
Install.ask_formulae(installed_formulae, args: args) if args.ask?
|
formulae_installer = Install.formula_installers(
|
||||||
|
|
||||||
Install.install_formulae(
|
|
||||||
installed_formulae,
|
installed_formulae,
|
||||||
installed_on_request: !args.as_dependency?,
|
installed_on_request: !args.as_dependency?,
|
||||||
installed_as_dependency: args.as_dependency?,
|
installed_as_dependency: args.as_dependency?,
|
||||||
@ -338,9 +336,10 @@ module Homebrew
|
|||||||
skip_link: args.skip_link?,
|
skip_link: args.skip_link?,
|
||||||
)
|
)
|
||||||
|
|
||||||
Upgrade.check_installed_dependents(
|
dependants = Upgrade.dependants(
|
||||||
installed_formulae,
|
installed_formulae,
|
||||||
flags: args.flags_only,
|
flags: args.flags_only,
|
||||||
|
ask: args.ask?,
|
||||||
installed_on_request: !args.as_dependency?,
|
installed_on_request: !args.as_dependency?,
|
||||||
force_bottle: args.force_bottle?,
|
force_bottle: args.force_bottle?,
|
||||||
build_from_source_formulae: args.build_from_source_formulae,
|
build_from_source_formulae: args.build_from_source_formulae,
|
||||||
@ -354,6 +353,28 @@ module Homebrew
|
|||||||
dry_run: args.dry_run?,
|
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?)
|
Cleanup.periodic_clean!(dry_run: args.dry_run?)
|
||||||
|
|
||||||
Homebrew.messages.display_messages(display_times: args.display_times?)
|
Homebrew.messages.display_messages(display_times: args.display_times?)
|
||||||
|
@ -215,7 +215,7 @@ module Homebrew
|
|||||||
sig { void }
|
sig { void }
|
||||||
def list_casks
|
def list_casks
|
||||||
casks = if args.no_named?
|
casks = if args.no_named?
|
||||||
cask_paths = Cask::Caskroom.path.children.map do |path|
|
cask_paths = Cask::Caskroom.path.children.reject(&:file?).map do |path|
|
||||||
if path.symlink?
|
if path.symlink?
|
||||||
real_path = path.realpath
|
real_path = path.realpath
|
||||||
real_path.basename.to_s
|
real_path.basename.to_s
|
||||||
|
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."
|
description: "Show options for formulae that are currently installed."
|
||||||
switch "--eval-all",
|
switch "--eval-all",
|
||||||
description: "Evaluate all available formulae and casks, whether installed or not, to show their " \
|
description: "Evaluate all available formulae and casks, whether installed or not, to show their " \
|
||||||
"options."
|
"options.",
|
||||||
|
env: :eval_all
|
||||||
flag "--command=",
|
flag "--command=",
|
||||||
description: "Show options for the specified <command>."
|
description: "Show options for the specified <command>."
|
||||||
|
|
||||||
@ -29,10 +30,10 @@ module Homebrew
|
|||||||
|
|
||||||
sig { override.void }
|
sig { override.void }
|
||||||
def run
|
def run
|
||||||
all = args.eval_all?
|
eval_all = args.eval_all?
|
||||||
|
|
||||||
if all
|
if eval_all
|
||||||
puts_options(Formula.all(eval_all: args.eval_all?).sort)
|
puts_options(Formula.all(eval_all:).sort)
|
||||||
elsif args.installed?
|
elsif args.installed?
|
||||||
puts_options(Formula.installed.sort)
|
puts_options(Formula.installed.sort)
|
||||||
elsif args.command.present?
|
elsif args.command.present?
|
||||||
|
@ -32,12 +32,10 @@ module Homebrew
|
|||||||
"formula is outdated. Otherwise, the repository's HEAD will only be checked for " \
|
"formula is outdated. Otherwise, the repository's HEAD will only be checked for " \
|
||||||
"updates when a new stable or development version has been released."
|
"updates when a new stable or development version has been released."
|
||||||
switch "-g", "--greedy",
|
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",
|
switch "--greedy-latest",
|
||||||
description: "Also include outdated casks including those with `version :latest`."
|
description: "Also include outdated casks including those with `version :latest`."
|
||||||
|
|
||||||
switch "--greedy-auto-updates",
|
switch "--greedy-auto-updates",
|
||||||
description: "Also include outdated casks including those with `auto_updates true`."
|
description: "Also include outdated casks including those with `auto_updates true`."
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ module Homebrew
|
|||||||
if f.pinned?
|
if f.pinned?
|
||||||
opoo "#{f.name} already pinned"
|
opoo "#{f.name} already pinned"
|
||||||
elsif !f.pinnable?
|
elsif !f.pinnable?
|
||||||
onoe "#{f.name} not installed"
|
ofail "#{f.name} not installed"
|
||||||
else
|
else
|
||||||
f.pin
|
f.pin
|
||||||
end
|
end
|
||||||
|
@ -24,8 +24,8 @@ module Homebrew
|
|||||||
switch "--syntax",
|
switch "--syntax",
|
||||||
description: "Syntax-check all of Homebrew's Ruby files (if no <tap> is passed)."
|
description: "Syntax-check all of Homebrew's Ruby files (if no <tap> is passed)."
|
||||||
switch "--eval-all",
|
switch "--eval-all",
|
||||||
description: "Evaluate all available formulae and casks, whether installed or not. " \
|
description: "Evaluate all available formulae and casks, whether installed or not.",
|
||||||
"Implied if `$HOMEBREW_EVAL_ALL` is set."
|
env: :eval_all
|
||||||
switch "--no-simulate",
|
switch "--no-simulate",
|
||||||
description: "Don't simulate other system configurations when checking formulae and casks."
|
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
|
options[:os_arch_combinations] = args.os_arch_combinations if args.os || args.arch
|
||||||
|
|
||||||
taps = if args.no_named?
|
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!"
|
raise UsageError, "`brew readall` needs a tap or `--eval-all` passed or `$HOMEBREW_EVAL_ALL` set!"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -32,8 +32,8 @@ module Homebrew
|
|||||||
description: "If brewing fails, open an interactive debugging session with access to IRB " \
|
description: "If brewing fails, open an interactive debugging session with access to IRB " \
|
||||||
"or a shell inside the temporary build directory."
|
"or a shell inside the temporary build directory."
|
||||||
switch "--display-times",
|
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",
|
switch "-f", "--force",
|
||||||
description: "Install without checking for previously installed keg-only or " \
|
description: "Install without checking for previously installed keg-only or " \
|
||||||
"non-migrated versions."
|
"non-migrated versions."
|
||||||
@ -41,7 +41,7 @@ module Homebrew
|
|||||||
description: "Print the verification and post-install steps."
|
description: "Print the verification and post-install steps."
|
||||||
switch "--ask",
|
switch "--ask",
|
||||||
description: "Ask for confirmation before downloading and upgrading formulae. " \
|
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
|
env: :ask
|
||||||
[
|
[
|
||||||
[:switch, "--formula", "--formulae", { description: "Treat all named arguments as formulae." }],
|
[:switch, "--formula", "--formulae", { description: "Treat all named arguments as formulae." }],
|
||||||
@ -130,16 +130,13 @@ module Homebrew
|
|||||||
unless formulae.empty?
|
unless formulae.empty?
|
||||||
Install.perform_preinstall_checks_once
|
Install.perform_preinstall_checks_once
|
||||||
|
|
||||||
# If asking the user is enabled, show dependency and size information.
|
install_context = formulae.map do |formula|
|
||||||
Install.ask_formulae(formulae, args: args) if args.ask?
|
|
||||||
|
|
||||||
formulae.each do |formula|
|
|
||||||
if formula.pinned?
|
if formula.pinned?
|
||||||
onoe "#{formula.full_name} is pinned. You must unpin it to reinstall."
|
onoe "#{formula.full_name} is pinned. You must unpin it to reinstall."
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
Migrator.migrate_if_needed(formula, force: args.force?)
|
Migrator.migrate_if_needed(formula, force: args.force?)
|
||||||
Homebrew::Reinstall.reinstall_formula(
|
Homebrew::Reinstall.build_install_context(
|
||||||
formula,
|
formula,
|
||||||
flags: args.flags_only,
|
flags: args.flags_only,
|
||||||
force_bottle: args.force_bottle?,
|
force_bottle: args.force_bottle?,
|
||||||
@ -153,12 +150,32 @@ module Homebrew
|
|||||||
verbose: args.verbose?,
|
verbose: args.verbose?,
|
||||||
git: args.git?,
|
git: args.git?,
|
||||||
)
|
)
|
||||||
Cleanup.install_formula_clean!(formula)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
Upgrade.check_installed_dependents(
|
dependants = Upgrade.dependants(
|
||||||
formulae,
|
formulae,
|
||||||
flags: args.flags_only,
|
flags: args.flags_only,
|
||||||
|
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?,
|
||||||
|
)
|
||||||
|
|
||||||
|
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?,
|
force_bottle: args.force_bottle?,
|
||||||
build_from_source_formulae: args.build_from_source_formulae,
|
build_from_source_formulae: args.build_from_source_formulae,
|
||||||
interactive: args.interactive?,
|
interactive: args.interactive?,
|
||||||
@ -168,6 +185,23 @@ module Homebrew
|
|||||||
debug: args.debug?,
|
debug: args.debug?,
|
||||||
quiet: args.quiet?,
|
quiet: args.quiet?,
|
||||||
verbose: args.verbose?,
|
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
|
end
|
||||||
|
|
||||||
|
@ -40,7 +40,8 @@ module Homebrew
|
|||||||
switch "--eval-all",
|
switch "--eval-all",
|
||||||
depends_on: "--desc",
|
depends_on: "--desc",
|
||||||
description: "Evaluate all available formulae and casks, whether installed or not, to search their " \
|
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",
|
switch "--pull-request",
|
||||||
description: "Search for GitHub pull requests containing <text>."
|
description: "Search for GitHub pull requests containing <text>."
|
||||||
switch "--open",
|
switch "--open",
|
||||||
@ -70,7 +71,7 @@ module Homebrew
|
|||||||
string_or_regex = Search.query_regexp(query)
|
string_or_regex = Search.query_regexp(query)
|
||||||
|
|
||||||
if args.desc?
|
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!"
|
raise UsageError, "`brew search --desc` needs `--eval-all` passed or `$HOMEBREW_EVAL_ALL` set!"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -13,18 +13,20 @@ module Homebrew
|
|||||||
description <<~EOS
|
description <<~EOS
|
||||||
Valid shells: bash|csh|fish|pwsh|sh|tcsh|zsh
|
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
|
The variables `$HOMEBREW_PREFIX`, `$HOMEBREW_CELLAR` and `$HOMEBREW_REPOSITORY` are also exported to avoid
|
||||||
querying them multiple times.
|
querying them multiple times.
|
||||||
To help guarantee idempotence, this command produces no output when Homebrew's `bin` and `sbin` directories
|
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:
|
your dotfiles (e.g. `~/.bash_profile` or ~/.zprofile` on macOS and ~/.bashrc` or ~/.zshrc` on Linux) with:
|
||||||
`eval "$(brew shellenv)"`
|
`eval "$(brew shellenv)"`
|
||||||
|
|
||||||
The shell can be specified explicitly with a supported shell name parameter. Unknown shells will output
|
The shell can be specified explicitly with a supported shell name parameter. Unknown shells will output
|
||||||
POSIX exports.
|
POSIX exports.
|
||||||
EOS
|
EOS
|
||||||
|
|
||||||
named_args :shell
|
named_args :shell
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -63,6 +63,8 @@ module Homebrew
|
|||||||
puts info
|
puts info
|
||||||
else
|
else
|
||||||
info = ""
|
info = ""
|
||||||
|
default_branches = %w[main master].freeze
|
||||||
|
|
||||||
taps.each_with_index do |tap, i|
|
taps.each_with_index do |tap, i|
|
||||||
puts unless i.zero?
|
puts unless i.zero?
|
||||||
info = "#{tap}: "
|
info = "#{tap}: "
|
||||||
@ -79,7 +81,7 @@ module Homebrew
|
|||||||
info += "\norigin: #{tap.remote}" if tap.remote != tap.default_remote
|
info += "\norigin: #{tap.remote}" if tap.remote != tap.default_remote
|
||||||
info += "\nHEAD: #{tap.git_head || "(none)"}"
|
info += "\nHEAD: #{tap.git_head || "(none)"}"
|
||||||
info += "\nlast commit: #{tap.git_last_commit || "never"}"
|
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
|
else
|
||||||
info += "Not installed"
|
info += "Not installed"
|
||||||
end
|
end
|
||||||
|
@ -33,16 +33,14 @@ module Homebrew
|
|||||||
"integration.",
|
"integration.",
|
||||||
replacement: false,
|
replacement: false,
|
||||||
disable: true
|
disable: true
|
||||||
switch "--[no-]force-auto-update",
|
|
||||||
hidden: true
|
|
||||||
switch "--custom-remote",
|
switch "--custom-remote",
|
||||||
description: "Install or change a tap with a custom remote. Useful for mirrors."
|
description: "Install or change a tap with a custom remote. Useful for mirrors."
|
||||||
switch "--repair",
|
switch "--repair",
|
||||||
description: "Add missing symlinks to tap manpages and shell completions. Correct git remote " \
|
description: "Add missing symlinks to tap manpages and shell completions. Correct git remote " \
|
||||||
"refs for any taps where upstream HEAD branch has been renamed."
|
"refs for any taps where upstream HEAD branch has been renamed."
|
||||||
switch "--eval-all",
|
switch "--eval-all",
|
||||||
description: "Evaluate all the formulae, casks and aliases in the new tap to check validity. " \
|
description: "Evaluate all formulae, casks and aliases in the new tap to check their validity.",
|
||||||
"Implied if `$HOMEBREW_EVAL_ALL` is set."
|
env: :eval_all
|
||||||
switch "-f", "--force",
|
switch "-f", "--force",
|
||||||
description: "Force install core taps even under API mode."
|
description: "Force install core taps even under API mode."
|
||||||
|
|
||||||
@ -64,7 +62,7 @@ module Homebrew
|
|||||||
tap.install clone_target: args.named.second,
|
tap.install clone_target: args.named.second,
|
||||||
custom_remote: args.custom_remote?,
|
custom_remote: args.custom_remote?,
|
||||||
quiet: args.quiet?,
|
quiet: args.quiet?,
|
||||||
verify: args.eval_all? || Homebrew::EnvConfig.eval_all?,
|
verify: args.eval_all?,
|
||||||
force: args.force?
|
force: args.force?
|
||||||
rescue Tap::InvalidNameError, TapRemoteMismatchError, TapNoCustomRemoteError => e
|
rescue Tap::InvalidNameError, TapRemoteMismatchError, TapNoCustomRemoteError => e
|
||||||
odie e
|
odie e
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "abstract_command"
|
require "abstract_command"
|
||||||
@ -39,13 +39,15 @@ module Homebrew
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def auto_update_header
|
def auto_update_header
|
||||||
@auto_update_header ||= begin
|
@auto_update_header ||= T.let(begin
|
||||||
ohai "Auto-updated Homebrew!" if args.auto_update?
|
ohai "Auto-updated Homebrew!" if args.auto_update?
|
||||||
true
|
true
|
||||||
end
|
end, T.nilable(T::Boolean))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def output_update_report
|
def output_update_report
|
||||||
# Run `brew update` (again) if we've got a linuxbrew-core CoreTap
|
# Run `brew update` (again) if we've got a linuxbrew-core CoreTap
|
||||||
if CoreTap.instance.installed? && CoreTap.instance.linuxbrew_core? &&
|
if CoreTap.instance.installed? && CoreTap.instance.linuxbrew_core? &&
|
||||||
@ -293,14 +295,17 @@ module Homebrew
|
|||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(String) }
|
||||||
def no_changes_message
|
def no_changes_message
|
||||||
"No changes to formulae or casks."
|
"No changes to formulae or casks."
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(revision: String).returns(String) }
|
||||||
def shorten_revision(revision)
|
def shorten_revision(revision)
|
||||||
Utils.popen_read("git", "-C", HOMEBREW_REPOSITORY, "rev-parse", "--short", revision).chomp
|
Utils.popen_read("git", "-C", HOMEBREW_REPOSITORY, "rev-parse", "--short", revision).chomp
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def tap_or_untap_core_taps_if_necessary
|
def tap_or_untap_core_taps_if_necessary
|
||||||
return if ENV["HOMEBREW_UPDATE_TEST"]
|
return if ENV["HOMEBREW_UPDATE_TEST"]
|
||||||
|
|
||||||
@ -320,10 +325,11 @@ module Homebrew
|
|||||||
return if (HOMEBREW_PREFIX/".homebrewdocker").exist?
|
return if (HOMEBREW_PREFIX/".homebrewdocker").exist?
|
||||||
|
|
||||||
tap_output_header_printed = T.let(false, T::Boolean)
|
tap_output_header_printed = T.let(false, T::Boolean)
|
||||||
|
default_branches = %w[main master].freeze
|
||||||
[CoreTap.instance, CoreCaskTap.instance].each do |tap|
|
[CoreTap.instance, CoreCaskTap.instance].each do |tap|
|
||||||
next unless tap.installed?
|
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)
|
(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..."
|
ohai "#{tap.name} is old and unneeded, untapping to save space..."
|
||||||
tap.uninstall
|
tap.uninstall
|
||||||
@ -339,6 +345,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(repository: Pathname).void }
|
||||||
def link_completions_manpages_and_docs(repository = HOMEBREW_REPOSITORY)
|
def link_completions_manpages_and_docs(repository = HOMEBREW_REPOSITORY)
|
||||||
command = "brew update"
|
command = "brew update"
|
||||||
Utils::Link.link_completions(repository, command)
|
Utils::Link.link_completions(repository, command)
|
||||||
@ -351,10 +358,12 @@ module Homebrew
|
|||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def migrate_gcc_dependents_if_needed
|
def migrate_gcc_dependents_if_needed
|
||||||
# do nothing
|
# do nothing
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def analytics_message
|
def analytics_message
|
||||||
return if Utils::Analytics.messages_displayed?
|
return if Utils::Analytics.messages_displayed?
|
||||||
return if Utils::Analytics.no_message_output?
|
return if Utils::Analytics.no_message_output?
|
||||||
@ -384,6 +393,7 @@ module Homebrew
|
|||||||
Utils::Analytics.messages_displayed! if $stdout.tty?
|
Utils::Analytics.messages_displayed! if $stdout.tty?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def donation_message
|
def donation_message
|
||||||
return if Settings.read("donationmessage") == "true"
|
return if Settings.read("donationmessage") == "true"
|
||||||
|
|
||||||
@ -394,6 +404,7 @@ module Homebrew
|
|||||||
Settings.write "donationmessage", true if $stdout.tty?
|
Settings.write "donationmessage", true if $stdout.tty?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def install_from_api_message
|
def install_from_api_message
|
||||||
return if Settings.read("installfromapimessage") == "true"
|
return if Settings.read("installfromapimessage") == "true"
|
||||||
|
|
||||||
@ -418,30 +429,38 @@ require "extend/os/cmd/update-report"
|
|||||||
|
|
||||||
class Reporter
|
class Reporter
|
||||||
class ReporterRevisionUnsetError < RuntimeError
|
class ReporterRevisionUnsetError < RuntimeError
|
||||||
|
sig { params(var_name: String).void }
|
||||||
def initialize(var_name)
|
def initialize(var_name)
|
||||||
super "#{var_name} is unset!"
|
super "#{var_name} is unset!"
|
||||||
end
|
end
|
||||||
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)
|
def initialize(tap, api_names_txt: nil, api_names_before_txt: nil, api_dir_prefix: nil)
|
||||||
@tap = tap
|
@tap = tap
|
||||||
|
|
||||||
# This is slightly involved/weird but all the #report logic is shared so it's worth it.
|
# 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)
|
if installed_from_api?(api_names_txt, api_names_before_txt, api_dir_prefix)
|
||||||
@api_names_txt = api_names_txt
|
@api_names_txt = T.let(api_names_txt, T.nilable(Pathname))
|
||||||
@api_names_before_txt = api_names_before_txt
|
@api_names_before_txt = T.let(api_names_before_txt, T.nilable(Pathname))
|
||||||
@api_dir_prefix = api_dir_prefix
|
@api_dir_prefix = T.let(api_dir_prefix, T.nilable(Pathname))
|
||||||
else
|
else
|
||||||
initial_revision_var = "HOMEBREW_UPDATE_BEFORE#{tap.repository_var_suffix}"
|
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?
|
raise ReporterRevisionUnsetError, initial_revision_var if @initial_revision.empty?
|
||||||
|
|
||||||
current_revision_var = "HOMEBREW_UPDATE_AFTER#{tap.repository_var_suffix}"
|
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?
|
raise ReporterRevisionUnsetError, current_revision_var if @current_revision.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@report = T.let(nil, T.nilable(T::Hash[Symbol, T::Array[String]]))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(auto_update: T::Boolean).returns(T::Hash[Symbol, T::Array[String]]) }
|
||||||
def report(auto_update: false)
|
def report(auto_update: false)
|
||||||
return @report if @report
|
return @report if @report
|
||||||
|
|
||||||
@ -482,9 +501,9 @@ class Reporter
|
|||||||
case status
|
case status
|
||||||
when "A", "D"
|
when "A", "D"
|
||||||
full_name = tap.formula_file_to_name(src)
|
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]
|
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"
|
when "M"
|
||||||
name = tap.formula_file_to_name(src)
|
name = tap.formula_file_to_name(src)
|
||||||
|
|
||||||
@ -584,6 +603,7 @@ class Reporter
|
|||||||
@report
|
@report
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(T::Boolean) }
|
||||||
def updated?
|
def updated?
|
||||||
if installed_from_api?
|
if installed_from_api?
|
||||||
diff.present?
|
diff.present?
|
||||||
@ -592,9 +612,10 @@ class Reporter
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def migrate_tap_migration
|
def migrate_tap_migration
|
||||||
(report[:D] + report[:DC]).each do |full_name|
|
(Array(report[:D]) + Array(report[:DC])).each do |full_name|
|
||||||
name = full_name.split("/").last
|
name = T.must(full_name.split("/").last)
|
||||||
new_tap_name = tap.tap_migrations[name]
|
new_tap_name = tap.tap_migrations[name]
|
||||||
next if new_tap_name.nil? # skip if not in tap_migrations list.
|
next if new_tap_name.nil? # skip if not in tap_migrations list.
|
||||||
|
|
||||||
@ -609,7 +630,7 @@ class Reporter
|
|||||||
end
|
end
|
||||||
|
|
||||||
# This means it is a cask
|
# 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?
|
next unless (HOMEBREW_PREFIX/"Caskroom"/new_name).exist?
|
||||||
|
|
||||||
new_tap = Tap.fetch(new_tap_name)
|
new_tap = Tap.fetch(new_tap_name)
|
||||||
@ -675,12 +696,14 @@ class Reporter
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def migrate_cask_rename
|
def migrate_cask_rename
|
||||||
Cask::Caskroom.casks.each do |cask|
|
Cask::Caskroom.casks.each do |cask|
|
||||||
Cask::Migrator.migrate_if_needed(cask)
|
Cask::Migrator.migrate_if_needed(cask)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(force: T::Boolean, verbose: T::Boolean).void }
|
||||||
def migrate_formula_rename(force:, verbose:)
|
def migrate_formula_rename(force:, verbose:)
|
||||||
Formula.installed.each do |formula|
|
Formula.installed.each do |formula|
|
||||||
next unless Migrator.needs_migration?(formula)
|
next unless Migrator.needs_migration?(formula)
|
||||||
@ -704,14 +727,36 @@ class Reporter
|
|||||||
|
|
||||||
private
|
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,
|
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_dir_prefix = @api_dir_prefix)
|
||||||
!api_names_txt.nil? && !api_names_before_txt.nil? && !api_dir_prefix.nil?
|
!api_names_txt.nil? && !api_names_before_txt.nil? && !api_dir_prefix.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(String) }
|
||||||
def diff
|
def diff
|
||||||
|
@diff ||= T.let(nil, T.nilable(String))
|
||||||
@diff ||= if installed_from_api?
|
@diff ||= if installed_from_api?
|
||||||
# Hack `git diff` output with regexes to look like `git diff-tree` output.
|
# 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.
|
# Yes, I know this is a bit filthy but it saves duplicating the #report logic.
|
||||||
@ -719,12 +764,14 @@ class Reporter
|
|||||||
header_regex = /^(---|\+\+\+) /
|
header_regex = /^(---|\+\+\+) /
|
||||||
add_delete_characters = ["+", "-"].freeze
|
add_delete_characters = ["+", "-"].freeze
|
||||||
|
|
||||||
|
api_dir_prefix_basename = T.must(api_dir_prefix).basename
|
||||||
|
|
||||||
diff_output.lines.filter_map do |line|
|
diff_output.lines.filter_map do |line|
|
||||||
next if line.match?(header_regex)
|
next if line.match?(header_regex)
|
||||||
next unless add_delete_characters.include?(line[0])
|
next unless add_delete_characters.include?(line[0])
|
||||||
|
|
||||||
line.sub(/^\+/, "A #{api_dir_prefix.basename}/")
|
line.sub(/^\+/, "A #{api_dir_prefix_basename}/")
|
||||||
.sub(/^-/, "D #{api_dir_prefix.basename}/")
|
.sub(/^-/, "D #{api_dir_prefix_basename}/")
|
||||||
.sub(/$/, ".rb")
|
.sub(/$/, ".rb")
|
||||||
.chomp
|
.chomp
|
||||||
end.join("\n")
|
end.join("\n")
|
||||||
@ -738,28 +785,33 @@ class Reporter
|
|||||||
end
|
end
|
||||||
|
|
||||||
class ReporterHub
|
class ReporterHub
|
||||||
|
sig { returns(T::Array[Reporter]) }
|
||||||
attr_reader :reporters
|
attr_reader :reporters
|
||||||
|
|
||||||
sig { void }
|
sig { void }
|
||||||
def initialize
|
def initialize
|
||||||
@hash = {}
|
@hash = T.let({}, T::Hash[Symbol, T::Array[String]])
|
||||||
@reporters = []
|
@reporters = T.let([], T::Array[Reporter])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(key: Symbol).returns(T::Array[String]) }
|
||||||
def select_formula_or_cask(key)
|
def select_formula_or_cask(key)
|
||||||
@hash.fetch(key, [])
|
@hash.fetch(key, [])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(reporter: Reporter, auto_update: T::Boolean).void }
|
||||||
def add(reporter, auto_update: false)
|
def add(reporter, auto_update: false)
|
||||||
@reporters << reporter
|
@reporters << reporter
|
||||||
report = reporter.report(auto_update:).delete_if { |_k, v| v.empty? }
|
report = reporter.report(auto_update:).delete_if { |_k, v| v.empty? }
|
||||||
@hash.update(report) { |_key, oldval, newval| oldval.concat(newval) }
|
@hash.update(report) { |_key, oldval, newval| oldval.concat(newval) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(T::Boolean) }
|
||||||
def empty?
|
def empty?
|
||||||
@hash.empty?
|
@hash.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(auto_update: T::Boolean).void }
|
||||||
def dump(auto_update: false)
|
def dump(auto_update: false)
|
||||||
unless Homebrew::EnvConfig.no_update_report_new?
|
unless Homebrew::EnvConfig.no_update_report_new?
|
||||||
dump_new_formula_report
|
dump_new_formula_report
|
||||||
@ -814,22 +866,41 @@ class ReporterHub
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def dump_new_formula_report
|
def dump_new_formula_report
|
||||||
formulae = select_formula_or_cask(:A).sort.reject { |name| installed?(name) }
|
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
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def dump_new_cask_report
|
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|
|
casks = select_formula_or_cask(:AC).sort.filter_map do |name|
|
||||||
name.split("/").last unless cask_installed?(name)
|
name.split("/").last unless cask_installed?(name)
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def dump_deleted_formula_report
|
def dump_deleted_formula_report
|
||||||
formulae = select_formula_or_cask(:D).sort.filter_map do |name|
|
formulae = select_formula_or_cask(:D).sort.filter_map do |name|
|
||||||
pretty_uninstalled(name) if installed?(name)
|
pretty_uninstalled(name) if installed?(name)
|
||||||
@ -838,40 +909,84 @@ class ReporterHub
|
|||||||
output_dump_formula_or_cask_report "Deleted Installed Formulae", formulae
|
output_dump_formula_or_cask_report "Deleted Installed Formulae", formulae
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def dump_deleted_cask_report
|
def dump_deleted_cask_report
|
||||||
return if Homebrew::SimulateSystem.simulating_or_running_on_linux?
|
return if Homebrew::SimulateSystem.simulating_or_running_on_linux?
|
||||||
|
|
||||||
casks = select_formula_or_cask(:DC).sort.filter_map do |name|
|
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)
|
pretty_uninstalled(name) if cask_installed?(name)
|
||||||
end
|
end
|
||||||
|
|
||||||
output_dump_formula_or_cask_report "Deleted Installed Casks", casks
|
output_dump_formula_or_cask_report "Deleted Installed Casks", casks
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(title: String, formulae_or_casks: T::Array[String]).void }
|
||||||
def output_dump_formula_or_cask_report(title, formulae_or_casks)
|
def output_dump_formula_or_cask_report(title, formulae_or_casks)
|
||||||
return if formulae_or_casks.blank?
|
return if formulae_or_casks.blank?
|
||||||
|
|
||||||
ohai title, Formatter.columns(formulae_or_casks.sort)
|
ohai title, Formatter.columns(formulae_or_casks.sort)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(formula: String).returns(T::Boolean) }
|
||||||
def installed?(formula)
|
def installed?(formula)
|
||||||
(HOMEBREW_CELLAR/formula.split("/").last).directory?
|
(HOMEBREW_CELLAR/formula.split("/").last).directory?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(formula: String).returns(T::Boolean) }
|
||||||
def outdated?(formula)
|
def outdated?(formula)
|
||||||
Formula[formula].outdated?
|
Formula[formula].outdated?
|
||||||
rescue FormulaUnavailableError
|
rescue FormulaUnavailableError
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(cask: String).returns(T::Boolean) }
|
||||||
def cask_installed?(cask)
|
def cask_installed?(cask)
|
||||||
(Cask::Caskroom.path/cask).directory?
|
(Cask::Caskroom.path/cask).directory?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(cask: String).returns(T::Boolean) }
|
||||||
def cask_outdated?(cask)
|
def cask_outdated?(cask)
|
||||||
Cask::CaskLoader.load(cask).outdated?
|
Cask::CaskLoader.load(cask).outdated?
|
||||||
rescue Cask::CaskError
|
rescue Cask::CaskError
|
||||||
false
|
false
|
||||||
end
|
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
|
end
|
||||||
|
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