mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-04-17 11:08:54 +02:00
Compare commits
942 Commits
api-v1.3
...
@tauri-app
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f0e50f396 | ||
|
|
c31c94ceb7 | ||
|
|
6b981d37dc | ||
|
|
2333cd1c83 | ||
|
|
f1d0f452a2 | ||
|
|
ab57f9531a | ||
|
|
88a1dd17c3 | ||
|
|
3364b6727c | ||
|
|
4806f9fc70 | ||
|
|
0cdfda2876 | ||
|
|
63d6d474fd | ||
|
|
1d21446e21 | ||
|
|
0a01b5b720 | ||
|
|
cb613beea6 | ||
|
|
8de308d1bf | ||
|
|
e691208e7b | ||
|
|
791e291a9f | ||
|
|
b09b94204c | ||
|
|
e8d3793c3c | ||
|
|
95da1a2747 | ||
|
|
a35b416e38 | ||
|
|
3e5c28ff4f | ||
|
|
7315189e76 | ||
|
|
f492efd714 | ||
|
|
6639a579c7 | ||
|
|
a093682d2d | ||
|
|
7fcc0bcd34 | ||
|
|
30be0e3057 | ||
|
|
d6c7568c27 | ||
|
|
435d7513e4 | ||
|
|
af61023273 | ||
|
|
aa758a850f | ||
|
|
9eaeb5a8cd | ||
|
|
a2fc3a6357 | ||
|
|
e1eb911f5e | ||
|
|
58fe2e812a | ||
|
|
00e1567584 | ||
|
|
9af90ca7f3 | ||
|
|
38b8e67237 | ||
|
|
57e3d43d96 | ||
|
|
f998fa0ec2 | ||
|
|
11de49788a | ||
|
|
b3209bb28b | ||
|
|
2631e97e2b | ||
|
|
ec9818accb | ||
|
|
9cb9aa7978 | ||
|
|
d70470f868 | ||
|
|
5e1ae87c0c | ||
|
|
fd4bf94d4c | ||
|
|
734d78f736 | ||
|
|
049ca2d54f | ||
|
|
30a64a9cda | ||
|
|
4ca0932572 | ||
|
|
1878766f7f | ||
|
|
c77b40324e | ||
|
|
74a2a6036a | ||
|
|
3c2f79f6f3 | ||
|
|
303708d0aa | ||
|
|
4ca4148e64 | ||
|
|
7f033f6dcd | ||
|
|
9f8037c288 | ||
|
|
e0b38d7434 | ||
|
|
ef9fb982f8 | ||
|
|
8032b22f2a | ||
|
|
d621d3437c | ||
|
|
5cb196976e | ||
|
|
97e3341299 | ||
|
|
0ec28c39f4 | ||
|
|
29ced5ceec | ||
|
|
27bad32d4d | ||
|
|
4f73057e6f | ||
|
|
cb640c8e94 | ||
|
|
af565c2a20 | ||
|
|
3e00116e9f | ||
|
|
0ea1a47254 | ||
|
|
091100acbb | ||
|
|
7e4580afed | ||
|
|
41990cd344 | ||
|
|
6892a8cbc1 | ||
|
|
2032228cad | ||
|
|
a9b87c057d | ||
|
|
6cd6d3fb32 | ||
|
|
30c5d86f88 | ||
|
|
e44b36fea4 | ||
|
|
effe5871af | ||
|
|
b59f2f54e7 | ||
|
|
50a3d170f2 | ||
|
|
11a1529d6a | ||
|
|
ea03adee74 | ||
|
|
9b230de7bc | ||
|
|
50e9caad64 | ||
|
|
31b3545e31 | ||
|
|
428ea6524c | ||
|
|
e5cc72eb40 | ||
|
|
face0b6a89 | ||
|
|
0d0501cb7b | ||
|
|
1c582a942e | ||
|
|
ef21b681e2 | ||
|
|
3c371aa8ee | ||
|
|
db12777742 | ||
|
|
5848b4e8e9 | ||
|
|
c1bc4d2948 | ||
|
|
f9c97b7e5b | ||
|
|
5ff9d4592a | ||
|
|
30adc8d45d | ||
|
|
777ddf434a | ||
|
|
803c3a794d | ||
|
|
f98ce5aa47 | ||
|
|
b6ca8885ff | ||
|
|
327c7aec30 | ||
|
|
14e29f320d | ||
|
|
cf7d584033 | ||
|
|
61cc7d9c5a | ||
|
|
c4b5df12bb | ||
|
|
940ec1dd01 | ||
|
|
977a39f4f7 | ||
|
|
c34710de67 | ||
|
|
f78e5e4d4a | ||
|
|
5e05236b49 | ||
|
|
5ff6a74430 | ||
|
|
ad8836b1d2 | ||
|
|
b3e53e7243 | ||
|
|
4f4313e17a | ||
|
|
ebc3e78e68 | ||
|
|
bf095df55a | ||
|
|
32bf201655 | ||
|
|
b0c5b06d06 | ||
|
|
3b91e236c6 | ||
|
|
46451aee13 | ||
|
|
5046270273 | ||
|
|
b8756bc34e | ||
|
|
c2ad4d28c4 | ||
|
|
618b0d01cb | ||
|
|
3acf0d2ba4 | ||
|
|
f26d9f0884 | ||
|
|
aa1d67ab75 | ||
|
|
8accd6940e | ||
|
|
26ccfef999 | ||
|
|
d8f1b6c59b | ||
|
|
5e84e92e99 | ||
|
|
f93148eac0 | ||
|
|
4b6a602a89 | ||
|
|
92bc7d0e16 | ||
|
|
9e3aff0a3a | ||
|
|
e221aae531 | ||
|
|
626121e7bf | ||
|
|
92b50a3a39 | ||
|
|
977d0e52f1 | ||
|
|
2ba8856343 | ||
|
|
f964cbdb93 | ||
|
|
ecb5b0c21d | ||
|
|
0f7b2c4298 | ||
|
|
b7add750ef | ||
|
|
25e5f91dae | ||
|
|
14544e4b87 | ||
|
|
adc3cc2ffa | ||
|
|
b6ed4ecb37 | ||
|
|
1d5aa38ae4 | ||
|
|
e9aa7276e9 | ||
|
|
88ee0d8a04 | ||
|
|
88dac86f3b | ||
|
|
bfbbefdb9e | ||
|
|
fc571ea2ce | ||
|
|
3ed6b3ef37 | ||
|
|
ec78f1613a | ||
|
|
34196e25c4 | ||
|
|
b5f40ae58d | ||
|
|
04a682beb0 | ||
|
|
50f7ccbbf3 | ||
|
|
416370a627 | ||
|
|
fd532da899 | ||
|
|
a547971209 | ||
|
|
01a7a983ab | ||
|
|
b5e1334149 | ||
|
|
822bf15d6b | ||
|
|
618c4538ea | ||
|
|
b89de9fa43 | ||
|
|
0601d5dddb | ||
|
|
74d2464d0e | ||
|
|
2b6ffe0fd1 | ||
|
|
2c7d683ae3 | ||
|
|
9ed400a85c | ||
|
|
6bc3b0536d | ||
|
|
4077946229 | ||
|
|
b6ef1fab0e | ||
|
|
bf859859d6 | ||
|
|
6e75863041 | ||
|
|
a635ec2345 | ||
|
|
c7c2507da1 | ||
|
|
9580df1d7b | ||
|
|
ae75004cee | ||
|
|
13ce9ac836 | ||
|
|
a0f7b88fd8 | ||
|
|
5264e41db3 | ||
|
|
93c8a77b34 | ||
|
|
198abe3c2c | ||
|
|
a74ff464bb | ||
|
|
fec89434d8 | ||
|
|
31cb582756 | ||
|
|
efe7811804 | ||
|
|
287066b279 | ||
|
|
c6c59cf237 | ||
|
|
5f75ebbbbb | ||
|
|
c982e52eb0 | ||
|
|
78586968a8 | ||
|
|
d4042ebd88 | ||
|
|
10da70307a | ||
|
|
22f26882cf | ||
|
|
cfe6fa6c91 | ||
|
|
ae13be2d17 | ||
|
|
d16206a086 | ||
|
|
3880b42d18 | ||
|
|
9bead42dbc | ||
|
|
c90ee65dbf | ||
|
|
2da043f04d | ||
|
|
ebcc21e4b9 | ||
|
|
117a7dc2bb | ||
|
|
620b7a5d2f | ||
|
|
de985bad18 | ||
|
|
a76588df75 | ||
|
|
be8e5aa307 | ||
|
|
5c0eeb40c1 | ||
|
|
6f23fa302d | ||
|
|
94bef1c705 | ||
|
|
8db26bd3e9 | ||
|
|
c1ec0f1551 | ||
|
|
c085addab5 | ||
|
|
a6ad540696 | ||
|
|
fb10b87970 | ||
|
|
149056746c | ||
|
|
12b8d18bf7 | ||
|
|
99865d9e9a | ||
|
|
550173aaf5 | ||
|
|
ed32257d04 | ||
|
|
880266a7f6 | ||
|
|
f259db3596 | ||
|
|
a5686e1507 | ||
|
|
a63e71f979 | ||
|
|
2b0212af49 | ||
|
|
b89d747705 | ||
|
|
8b166e9bf8 | ||
|
|
c9a9246c37 | ||
|
|
f12306af5f | ||
|
|
2558fab861 | ||
|
|
2fe8782ad4 | ||
|
|
dfe0badf19 | ||
|
|
d6e10e216e | ||
|
|
9d40840299 | ||
|
|
113bcd7b68 | ||
|
|
d0ae67503c | ||
|
|
46dcb94110 | ||
|
|
441eb4f4a5 | ||
|
|
bab05ff607 | ||
|
|
4caa1cca99 | ||
|
|
f552c1796a | ||
|
|
21cdbb41a3 | ||
|
|
1241014a46 | ||
|
|
713f84db2b | ||
|
|
b2f17723a4 | ||
|
|
40d340021c | ||
|
|
1c9f3db916 | ||
|
|
cdd5516f33 | ||
|
|
d735324df0 | ||
|
|
b597aa5f39 | ||
|
|
68e7319305 | ||
|
|
44e8a562a2 | ||
|
|
c0d03af470 | ||
|
|
b7fd88e18d | ||
|
|
19249d78fb | ||
|
|
d6eb46cf11 | ||
|
|
3671edbcff | ||
|
|
a3277a245c | ||
|
|
d1e09da084 | ||
|
|
c001a91d15 | ||
|
|
0af553da72 | ||
|
|
e9e68abb33 | ||
|
|
c68fbfcb2d | ||
|
|
1bce7397a4 | ||
|
|
228e5a4c76 | ||
|
|
d1858de7a0 | ||
|
|
9aa34ada57 | ||
|
|
e8ff6b153e | ||
|
|
5ecb46b341 | ||
|
|
deea943626 | ||
|
|
092a561ca6 | ||
|
|
c3ac1f836b | ||
|
|
a2021c30ba | ||
|
|
d6fd121974 | ||
|
|
dcdbe3eb6c | ||
|
|
990295304f | ||
|
|
2f8881c010 | ||
|
|
995ffc629b | ||
|
|
b3ebe4de3c | ||
|
|
9a2b2f49a5 | ||
|
|
a68ccaf59a | ||
|
|
100d9ede35 | ||
|
|
4bf1e85e6b | ||
|
|
0b0bc81710 | ||
|
|
1945dec81f | ||
|
|
3c66a53a9e | ||
|
|
d5074af562 | ||
|
|
822ba2b121 | ||
|
|
ac065062eb | ||
|
|
47b33e649c | ||
|
|
a6a42f8f0a | ||
|
|
6735994885 | ||
|
|
e1ac45c89f | ||
|
|
4cb51a2d56 | ||
|
|
e3bfb01411 | ||
|
|
dfbbca423b | ||
|
|
0797a002ca | ||
|
|
53ab2042fd | ||
|
|
974e38b4dd | ||
|
|
7db1c31e47 | ||
|
|
8faa5a4a12 | ||
|
|
b7f53d66e8 | ||
|
|
0d63732b96 | ||
|
|
b75a1210be | ||
|
|
964282a267 | ||
|
|
29818de682 | ||
|
|
50878901ba | ||
|
|
e98393e499 | ||
|
|
41067cef00 | ||
|
|
49beb67dab | ||
|
|
e152662687 | ||
|
|
13279917d4 | ||
|
|
85112e7f8f | ||
|
|
09f7f57eea | ||
|
|
f19c7fc5c3 | ||
|
|
8c5fcf41e3 | ||
|
|
58d6b899e2 | ||
|
|
af3268a4be | ||
|
|
5c95152c76 | ||
|
|
6177150b6f | ||
|
|
8a6766173b | ||
|
|
964d81ff01 | ||
|
|
a7777ff485 | ||
|
|
72a3d75e8f | ||
|
|
04949d1658 | ||
|
|
ca977f4b87 | ||
|
|
9308dee0a1 | ||
|
|
7f818384d3 | ||
|
|
3bf1bce9ec | ||
|
|
e27b829b36 | ||
|
|
4af5c5a829 | ||
|
|
560b34dd2a | ||
|
|
28382fdf9e | ||
|
|
02eb08bbd7 | ||
|
|
d928d23cdb | ||
|
|
7fb419c326 | ||
|
|
ec827760ab | ||
|
|
e21a449b27 | ||
|
|
fbeb5b9185 | ||
|
|
10e362d098 | ||
|
|
b420962377 | ||
|
|
85efd0ae43 | ||
|
|
82c3f6be4a | ||
|
|
cca5301b88 | ||
|
|
e1a5e89ac3 | ||
|
|
eeb6be5422 | ||
|
|
a6b52e44f2 | ||
|
|
6a76d0abca | ||
|
|
9edebbba4e | ||
|
|
56714ede4d | ||
|
|
cb1d4164e7 | ||
|
|
6c408b736c | ||
|
|
8af2497496 | ||
|
|
d010bc07b8 | ||
|
|
6c38924aa2 | ||
|
|
c272e4afbf | ||
|
|
4db363a03c | ||
|
|
e374bc130d | ||
|
|
57f73f1b6a | ||
|
|
3a2c3e7471 | ||
|
|
2d35f937de | ||
|
|
b7277357b9 | ||
|
|
3788fb1476 | ||
|
|
339cfa1124 | ||
|
|
c40b8ae15f | ||
|
|
7b45e7fa1b | ||
|
|
ecffaa2524 | ||
|
|
1e1d839e7e | ||
|
|
522de0e788 | ||
|
|
aba04fa823 | ||
|
|
aa94f7197e | ||
|
|
c7dacca466 | ||
|
|
753900dd6e | ||
|
|
a5752db985 | ||
|
|
3b98141aa2 | ||
|
|
4dd4893d7d | ||
|
|
ef962c43af | ||
|
|
290e366ae9 | ||
|
|
c98273387c | ||
|
|
2eab150563 | ||
|
|
84c4159754 | ||
|
|
fdaee9a5ce | ||
|
|
71a0240166 | ||
|
|
f280dcfb7c | ||
|
|
a2be88a21d | ||
|
|
907425df55 | ||
|
|
764968ab38 | ||
|
|
757e959eb2 | ||
|
|
fa7f9b77ab | ||
|
|
eeff1784e1 | ||
|
|
e05cd940d6 | ||
|
|
f6a13f6f23 | ||
|
|
eba8e1315e | ||
|
|
6e36ebbf84 | ||
|
|
74b1f4fc66 | ||
|
|
fd5dc788d1 | ||
|
|
32218a6f8c | ||
|
|
0ae53f4139 | ||
|
|
43c6285e90 | ||
|
|
46df2c9b91 | ||
|
|
23b0e1b9e5 | ||
|
|
f4aedce96c | ||
|
|
539247aacf | ||
|
|
3065c8aea3 | ||
|
|
5eb8554331 | ||
|
|
38d0bed8eb | ||
|
|
0ef9c6b7ec | ||
|
|
dad4f54eec | ||
|
|
df6712cfb3 | ||
|
|
5cbf4df390 | ||
|
|
6db81ec879 | ||
|
|
180eeb7363 | ||
|
|
2a000e150d | ||
|
|
b04444928c | ||
|
|
33f6aa438e | ||
|
|
c4e9740c83 | ||
|
|
c34e37b1f7 | ||
|
|
1a3dcdb830 | ||
|
|
e63111b65a | ||
|
|
d1a6e2f333 | ||
|
|
8c0166f459 | ||
|
|
fdf68405a4 | ||
|
|
be6f4319ff | ||
|
|
7036bc93ed | ||
|
|
bd29b05f15 | ||
|
|
3d707ddf5f | ||
|
|
6252380f44 | ||
|
|
655c714e41 | ||
|
|
1542ad17d6 | ||
|
|
84695cb83b | ||
|
|
1e9c463d12 | ||
|
|
2acc474ccb | ||
|
|
4b3d66c793 | ||
|
|
49dbbbbcdf | ||
|
|
6afd34727f | ||
|
|
066c09a6ea | ||
|
|
c7534e732d | ||
|
|
8922be591c | ||
|
|
4847b87b10 | ||
|
|
535f223eca | ||
|
|
6b81d70a1a | ||
|
|
d0e5dbf33e | ||
|
|
cafaf69fd7 | ||
|
|
93afa71d9a | ||
|
|
7bbc626cc3 | ||
|
|
28921cb8e8 | ||
|
|
2d2fd6abe2 | ||
|
|
2071265fea | ||
|
|
3fb3f11fc8 | ||
|
|
0fa0fa4ccf | ||
|
|
b7ae725c5e | ||
|
|
bd96edd2b9 | ||
|
|
aa94f049c1 | ||
|
|
c1d36e4953 | ||
|
|
4cfb686d2b | ||
|
|
d5769b3bfb | ||
|
|
066417d3f0 | ||
|
|
29a287ee82 | ||
|
|
d75c1b829b | ||
|
|
696d77c3ce | ||
|
|
5d85d0990c | ||
|
|
b66e7d60f2 | ||
|
|
8124145d6c | ||
|
|
6d3f3138b9 | ||
|
|
076e1a81a5 | ||
|
|
fc2e4083b0 | ||
|
|
1d99f8a3c2 | ||
|
|
d33672cffe | ||
|
|
ba6e5813e6 | ||
|
|
bfaf624a4c | ||
|
|
4652c446b3 | ||
|
|
a6da7ef8af | ||
|
|
db7c5fbf2e | ||
|
|
52474e479d | ||
|
|
f2d68cf7d4 | ||
|
|
3480047ec1 | ||
|
|
b41b57ebb2 | ||
|
|
9e3a18e046 | ||
|
|
647800c563 | ||
|
|
3a8bb4c153 | ||
|
|
c2acf96306 | ||
|
|
f8bdc7be62 | ||
|
|
0503eb69ce | ||
|
|
85e77fb797 | ||
|
|
3327dd641d | ||
|
|
c596aaefcf | ||
|
|
4d4b72ba38 | ||
|
|
d7a0a2cd1a | ||
|
|
0ddbb3a1dc | ||
|
|
a50f24b2bd | ||
|
|
3303041c92 | ||
|
|
27c5f364a8 | ||
|
|
1ed2600da6 | ||
|
|
000104bc3b | ||
|
|
735db1ce83 | ||
|
|
7fee3d3a2a | ||
|
|
8fd9cfa1f2 | ||
|
|
17d5a4f51f | ||
|
|
160489454d | ||
|
|
d68a25e32e | ||
|
|
a28fdf7ec7 | ||
|
|
154ccbe503 | ||
|
|
6c5ade08d9 | ||
|
|
1b8001b8b8 | ||
|
|
c4d6fb4b1e | ||
|
|
65fd674f50 | ||
|
|
35cd751adc | ||
|
|
ff5e4dbbb0 | ||
|
|
df89ccc191 | ||
|
|
60334f9e02 | ||
|
|
0f707d2b53 | ||
|
|
2317913b71 | ||
|
|
359058cecc | ||
|
|
45330e3819 | ||
|
|
e0f0dce220 | ||
|
|
17da87d3cd | ||
|
|
8b9f6cf868 | ||
|
|
4c39e46a3b | ||
|
|
43858a3197 | ||
|
|
7e5905ae1d | ||
|
|
3cb7a3e642 | ||
|
|
baa581b814 | ||
|
|
fb7ef8dacd | ||
|
|
1161b6788e | ||
|
|
76714dc628 | ||
|
|
af93729031 | ||
|
|
262776d8d8 | ||
|
|
86d3c0cc0f | ||
|
|
a541820aa8 | ||
|
|
0974ecccd6 | ||
|
|
9770032860 | ||
|
|
3f4c4ce88b | ||
|
|
5ec6353a60 | ||
|
|
9e67ec68ac | ||
|
|
ffd4db5ae4 | ||
|
|
aa6c9164e6 | ||
|
|
ac183948d6 | ||
|
|
0032daf2a3 | ||
|
|
8e85576506 | ||
|
|
5eba069b1d | ||
|
|
3256a37263 | ||
|
|
b0f947752a | ||
|
|
2b487c9467 | ||
|
|
b9eac96cdc | ||
|
|
1253bbf7ae | ||
|
|
61e3ad89e9 | ||
|
|
fc7f9ebada | ||
|
|
0302138f2f | ||
|
|
c7056d1b20 | ||
|
|
acc36fe117 | ||
|
|
cd3846c8ce | ||
|
|
d1304ffa12 | ||
|
|
8ce32e74b5 | ||
|
|
fd3b5a16b1 | ||
|
|
82169e69fc | ||
|
|
aecf146909 | ||
|
|
2344aea176 | ||
|
|
994e4fd6d9 | ||
|
|
e5bd34cb34 | ||
|
|
59db76af4c | ||
|
|
2b26b2e611 | ||
|
|
d2710e9d2e | ||
|
|
3700793a2f | ||
|
|
21d5eb84ab | ||
|
|
46a58afd9e | ||
|
|
3cc295e997 | ||
|
|
2948820579 | ||
|
|
6fb5734d2f | ||
|
|
e0c30a7e8b | ||
|
|
6d25c4d07f | ||
|
|
e1e85dc2a5 | ||
|
|
441f964654 | ||
|
|
2c1fd570f8 | ||
|
|
7c23720920 | ||
|
|
fb485d25a0 | ||
|
|
a08d1b248f | ||
|
|
9a79dc0858 | ||
|
|
5a9307d11c | ||
|
|
dc682155de | ||
|
|
e092f79946 | ||
|
|
39f1b04f7b | ||
|
|
c2b0dab7ef | ||
|
|
0ab5f40d3a | ||
|
|
b257bebf9e | ||
|
|
bf49a7679a | ||
|
|
469d9f8a4a | ||
|
|
41e10b22fa | ||
|
|
96d346222f | ||
|
|
b072daa3bd | ||
|
|
2b47426be8 | ||
|
|
60cf9ed2fc | ||
|
|
aa2a30e96b | ||
|
|
540ddd4e6a | ||
|
|
c4171152c1 | ||
|
|
29ce9ce2ce | ||
|
|
3245d14b9e | ||
|
|
2cc282c129 | ||
|
|
2659ca1ab4 | ||
|
|
24490bca19 | ||
|
|
73a0ad41c7 | ||
|
|
d48aaa150a | ||
|
|
4585a1cbb0 | ||
|
|
5a768d5ce6 | ||
|
|
3188f37649 | ||
|
|
6d1fa49fce | ||
|
|
7a4b1fb96d | ||
|
|
422b481798 | ||
|
|
256c30c72b | ||
|
|
6a6b1388ea | ||
|
|
6788bb4984 | ||
|
|
2915bd068e | ||
|
|
5053a9c4c4 | ||
|
|
20f582f6c3 | ||
|
|
dafdcc9b42 | ||
|
|
73c803a561 | ||
|
|
bb2a8ccf13 | ||
|
|
edb16d13a5 | ||
|
|
e68a08da51 | ||
|
|
19cd0e4960 | ||
|
|
41cb06172a | ||
|
|
124d5c5adf | ||
|
|
942249060e | ||
|
|
ecc9ac9603 | ||
|
|
d693e526e8 | ||
|
|
2a5175a8f8 | ||
|
|
31444ac196 | ||
|
|
cdad6e0837 | ||
|
|
2969d1cbba | ||
|
|
dfa407ffcb | ||
|
|
41f49aeae6 | ||
|
|
96639ca239 | ||
|
|
0c11023bcf | ||
|
|
ae102980fc | ||
|
|
86488a6ad8 | ||
|
|
f78a378344 | ||
|
|
2d5378bfc1 | ||
|
|
3f17ee82f6 | ||
|
|
db9c12c1ad | ||
|
|
8e46695b7e | ||
|
|
cebd75261a | ||
|
|
276e4a3fdb | ||
|
|
e6e586ad75 | ||
|
|
fc4d687ef0 | ||
|
|
22a7633816 | ||
|
|
09376af594 | ||
|
|
34b8f339a4 | ||
|
|
06fdcc0edd | ||
|
|
ee2d3b971d | ||
|
|
9de897919a | ||
|
|
abc5f91fa3 | ||
|
|
57fa569161 | ||
|
|
f3917e7ee8 | ||
|
|
055e9b3997 | ||
|
|
f436cf8609 | ||
|
|
a8153b9ff4 | ||
|
|
f0570d9fee | ||
|
|
be941b9719 | ||
|
|
1eacd51d18 | ||
|
|
db4c9dc655 | ||
|
|
63f088e5fc | ||
|
|
d03e47d141 | ||
|
|
052c5822b5 | ||
|
|
d37808197d | ||
|
|
ec7d24b1ac | ||
|
|
5288a386f1 | ||
|
|
5769ee6d29 | ||
|
|
7fec0f083c | ||
|
|
29ee62342a | ||
|
|
a813792786 | ||
|
|
09d5dd520f | ||
|
|
f6c373e989 | ||
|
|
e9482430ff | ||
|
|
afc3237d0c | ||
|
|
f992e7f58b | ||
|
|
f84fbe459f | ||
|
|
55900a2968 | ||
|
|
4c3b9ecfdc | ||
|
|
509d4678b1 | ||
|
|
adf4627b73 | ||
|
|
56fa900dbe | ||
|
|
cfdee00f2b | ||
|
|
76668b3196 | ||
|
|
249db9e49b | ||
|
|
6b469c40c6 | ||
|
|
1c7e5cae10 | ||
|
|
3ad7414a3e | ||
|
|
39df2c982e | ||
|
|
6e3e4c22be | ||
|
|
332b3fc419 | ||
|
|
a031e4a8a0 | ||
|
|
00241fa92d | ||
|
|
c787f749de | ||
|
|
d5ac76b53c | ||
|
|
8a1b1281ac | ||
|
|
1a24e4cafd | ||
|
|
9c324bae61 | ||
|
|
46e2def0ee | ||
|
|
be12ad3a6f | ||
|
|
bfd97a5802 | ||
|
|
31a205247a | ||
|
|
9c8276fe03 | ||
|
|
6669f1659a | ||
|
|
02b8bfb989 | ||
|
|
56b528e481 | ||
|
|
153b4627e5 | ||
|
|
6a8888dc85 | ||
|
|
88838e2898 | ||
|
|
aefc5bcb08 | ||
|
|
5bc8322f7d | ||
|
|
c88fdbca3a | ||
|
|
a6fea4644e | ||
|
|
22c09871c3 | ||
|
|
7765bbcba1 | ||
|
|
ae296f3de1 | ||
|
|
30e94677b0 | ||
|
|
dddaa943e7 | ||
|
|
1798c5901d | ||
|
|
2ec736721e | ||
|
|
9c1029e11a | ||
|
|
9639caf33f | ||
|
|
8241ef13e9 | ||
|
|
5d94eaa3bc | ||
|
|
1b343bd116 | ||
|
|
4d09074454 | ||
|
|
58d4709f7e | ||
|
|
2b22f64972 | ||
|
|
d1752fb1f6 | ||
|
|
8631eec038 | ||
|
|
971ad7ae06 | ||
|
|
4eae21ffeb | ||
|
|
d11af5be8d | ||
|
|
c4cb609bcd | ||
|
|
105fe3fa24 | ||
|
|
1035a83187 | ||
|
|
9cd8735574 | ||
|
|
ed879513d3 | ||
|
|
12c947632d | ||
|
|
037d488dee | ||
|
|
6fca895695 | ||
|
|
3a8488ddb5 | ||
|
|
dc26cc839a | ||
|
|
1fd329935e | ||
|
|
60a8b07dc7 | ||
|
|
79eb054292 | ||
|
|
dffd8eb5a8 | ||
|
|
897a1547a1 | ||
|
|
2b55f47c2c | ||
|
|
df5766ec2f | ||
|
|
4a82da2919 | ||
|
|
2dc71a4793 | ||
|
|
6aaba83476 | ||
|
|
ec007ef0d0 | ||
|
|
14d03d426e | ||
|
|
f5e272b0ef | ||
|
|
ea7fd016ca | ||
|
|
d42fd0710c | ||
|
|
1b75839701 | ||
|
|
bce87c1a67 | ||
|
|
b9c303a0dc | ||
|
|
5ab78fcafa | ||
|
|
aeade94d5e | ||
|
|
3d5cc7ab86 | ||
|
|
947eb391ca | ||
|
|
65e487f344 | ||
|
|
bef4ef51bc | ||
|
|
7258a64730 | ||
|
|
677554257e | ||
|
|
96b5e92169 | ||
|
|
0b51e2f657 | ||
|
|
98867a9680 | ||
|
|
bfb2ab24e0 | ||
|
|
05dad08768 | ||
|
|
f379e2f3da | ||
|
|
f28a181039 | ||
|
|
9feab904bf | ||
|
|
62f1526592 | ||
|
|
6f8ba2850e | ||
|
|
cab4ff95b9 | ||
|
|
da57e7c087 | ||
|
|
78176edf4a | ||
|
|
f2da21c7b4 | ||
|
|
894a8d060c | ||
|
|
481d9de739 | ||
|
|
a81750d779 | ||
|
|
17f26764c8 | ||
|
|
84998532d6 | ||
|
|
7500a0e23a | ||
|
|
0111b88d75 | ||
|
|
f0a1d9cdbc | ||
|
|
553a81f48c | ||
|
|
7eb9aa75cf | ||
|
|
8835633955 | ||
|
|
1af9be904a | ||
|
|
78eaadae2e | ||
|
|
8cc111494d | ||
|
|
630a7f4b18 | ||
|
|
276a0362de | ||
|
|
c36d451bcd | ||
|
|
50f6dd87b1 | ||
|
|
2c4a0bbd1f | ||
|
|
17d80ab236 | ||
|
|
e873bae09f | ||
|
|
dee9460f9c | ||
|
|
ced8e9a7be | ||
|
|
7945e549b7 | ||
|
|
6999cdf99e | ||
|
|
9ad0a9a0aa | ||
|
|
0189c1dbef | ||
|
|
61af5ce1ed | ||
|
|
d21c4a0a89 | ||
|
|
d600405a10 | ||
|
|
8301d17ab8 | ||
|
|
fc33c4218c | ||
|
|
3ad5e72ff1 | ||
|
|
76204b8938 | ||
|
|
a9b4cf20a3 | ||
|
|
8f47825aac | ||
|
|
1e4a675843 | ||
|
|
2620ab294d | ||
|
|
be446a8665 | ||
|
|
dd65bc99b2 | ||
|
|
1d20db7410 | ||
|
|
25416a64ba | ||
|
|
35040076ea | ||
|
|
fa3a10988a | ||
|
|
1092865e67 | ||
|
|
aa18c7d671 | ||
|
|
02706c92f6 | ||
|
|
1172783506 | ||
|
|
b874d139f9 | ||
|
|
c1cd0f5253 | ||
|
|
626faf9ec1 | ||
|
|
5024f7905c | ||
|
|
ad65b95070 | ||
|
|
debe73ab0e | ||
|
|
fa6d10e39c | ||
|
|
e938c3dff5 | ||
|
|
eca131dfbb | ||
|
|
4a72d5e0ca | ||
|
|
d38204907e | ||
|
|
87e47ce1dc | ||
|
|
d33fcbc81c | ||
|
|
c1f31ebe5e | ||
|
|
8baf20dd34 | ||
|
|
be808a9f5c | ||
|
|
6dcb7fbb81 | ||
|
|
f6f9192aa5 | ||
|
|
03d6c6a68f | ||
|
|
538e21e2e7 | ||
|
|
658bb1165e | ||
|
|
634c6b832c | ||
|
|
8c576222ba | ||
|
|
169d2434ff | ||
|
|
f9b529a96e | ||
|
|
7c26514340 | ||
|
|
69414a487f | ||
|
|
602d3ed3f6 | ||
|
|
348b26ffed | ||
|
|
d0ad0d2f48 | ||
|
|
10ab3e2f5e | ||
|
|
8ea87e9c9c | ||
|
|
c9ad2a73af | ||
|
|
bc1622c5ab | ||
|
|
e1b8ee2b7a | ||
|
|
f333656876 | ||
|
|
4c1c78ebf0 | ||
|
|
610aab7045 | ||
|
|
30d0e190bb | ||
|
|
5643ece77c | ||
|
|
aae91a9b53 | ||
|
|
349895b296 | ||
|
|
5d82357166 | ||
|
|
8f3a9c5cf6 | ||
|
|
6593f267b3 | ||
|
|
5d3242c496 | ||
|
|
68e80ffaa9 | ||
|
|
9f9e3ae54d | ||
|
|
82e8751ae8 | ||
|
|
e22d21beaf | ||
|
|
b36ccb7e99 | ||
|
|
65e7085d2f | ||
|
|
c4d323b70f | ||
|
|
914c5f299f | ||
|
|
1d9226b28c | ||
|
|
8cf9af93eb | ||
|
|
0a203a13ae | ||
|
|
dee19784f9 | ||
|
|
53a3398beb | ||
|
|
69aaff5507 | ||
|
|
80a301ea63 | ||
|
|
badad2b9a1 | ||
|
|
927ccc465d | ||
|
|
4a5f2ec1ae | ||
|
|
752ad3b203 | ||
|
|
ff4cb56b2e | ||
|
|
641d56dcb3 | ||
|
|
0500d3b4b1 | ||
|
|
1f84385e8a | ||
|
|
3668a1fdc8 | ||
|
|
2b846f413c | ||
|
|
4e26b05d20 | ||
|
|
a70f7b26bc | ||
|
|
e56a9dd729 | ||
|
|
403859d47e | ||
|
|
4c9ea450c3 | ||
|
|
b3a3afc7de | ||
|
|
3d992a8899 | ||
|
|
9bb81bc328 | ||
|
|
9890486321 | ||
|
|
16360aed33 | ||
|
|
e55d96acc1 | ||
|
|
8aad710064 | ||
|
|
6f0615044d | ||
|
|
f445f374a3 | ||
|
|
a3680ef2bc | ||
|
|
e20145cccc | ||
|
|
c2b120be51 | ||
|
|
3f655d6280 | ||
|
|
a9c8e565c6 | ||
|
|
a9f8ac7f96 | ||
|
|
d44f67f7af | ||
|
|
d3179b84b5 | ||
|
|
4c9c64c429 | ||
|
|
d14322de68 | ||
|
|
899f9b917a | ||
|
|
11d50e8474 | ||
|
|
6aee91a181 | ||
|
|
b4622ea4d3 |
@@ -1,14 +1,23 @@
|
||||
{
|
||||
"gitSiteUrl": "https://www.github.com/tauri-apps/tauri/",
|
||||
"timeout": 3600000,
|
||||
"changeTags": {
|
||||
"feat": "New Features",
|
||||
"enhance": "Enhancements",
|
||||
"bug": "Bug Fixes",
|
||||
"pref": "Performance Improvements",
|
||||
"changes": "What's Changed",
|
||||
"sec": "Security fixes",
|
||||
"deps": "Dependencies",
|
||||
"breaking": "Breaking Changes"
|
||||
},
|
||||
"defaultChangeTag": "changes",
|
||||
"pkgManagers": {
|
||||
"rust": {
|
||||
"errorOnVersionRange": "^2.0.0-0",
|
||||
"version": true,
|
||||
"getPublishedVersion": "node ../../.scripts/covector/package-latest-version.js cargo ${ pkgFile.pkg.package.name } ${ pkgFile.pkg.package.version }",
|
||||
"prepublish": [
|
||||
"sudo apt-get update",
|
||||
"sudo apt-get install -y webkit2gtk-4.0 libayatana-appindicator3-dev",
|
||||
"sudo apt-get install -y webkit2gtk-4.1 libayatana-appindicator3-dev",
|
||||
"cargo install cargo-audit --features=fix",
|
||||
{
|
||||
"command": "cargo generate-lockfile",
|
||||
@@ -68,7 +77,6 @@
|
||||
]
|
||||
},
|
||||
"javascript": {
|
||||
"errorOnVersionRange": "^2.0.0-0",
|
||||
"version": true,
|
||||
"getPublishedVersion": "node ../../.scripts/covector/package-latest-version.js npm ${ pkgFile.pkg.name } ${ pkgFile.pkg.version }",
|
||||
"prepublish": [
|
||||
@@ -105,7 +113,7 @@
|
||||
"pipe": true
|
||||
},
|
||||
{
|
||||
"command": "yarn publish --access public --loglevel silly",
|
||||
"command": "yarn publish --access public --loglevel silly --tag next",
|
||||
"dryRunCommand": "npm publish --dry-run --access public",
|
||||
"pipe": true
|
||||
},
|
||||
@@ -123,13 +131,13 @@
|
||||
}
|
||||
},
|
||||
"packages": {
|
||||
"api": {
|
||||
"@tauri-apps/api": {
|
||||
"path": "./tooling/api",
|
||||
"manager": "javascript",
|
||||
"assets": [
|
||||
{
|
||||
"path": "./tooling/api/dist/tauri-apps-api-${ pkgFile.version }.tgz",
|
||||
"name": "api-${ pkgFile.version }.tgz"
|
||||
"name": "tauri-apps-api-${ pkgFile.version }.tgz"
|
||||
}
|
||||
],
|
||||
"prepublish": [
|
||||
@@ -205,6 +213,12 @@
|
||||
"manager": "rust",
|
||||
"dependencies": ["tauri-codegen", "tauri-utils"]
|
||||
},
|
||||
"tauri-plugin": {
|
||||
"path": "./core/tauri-plugin",
|
||||
"manager": "rust",
|
||||
"dependencies": ["tauri-utils"],
|
||||
"postversion": "node ../../.scripts/covector/sync-cli-metadata.js ${ pkg.pkg } ${ release.type }"
|
||||
},
|
||||
"tauri-build": {
|
||||
"path": "./core/tauri-build",
|
||||
"manager": "rust",
|
||||
@@ -227,15 +241,16 @@
|
||||
"tauri-macros",
|
||||
"tauri-utils",
|
||||
"tauri-runtime",
|
||||
"tauri-runtime-wry"
|
||||
"tauri-runtime-wry",
|
||||
"tauri-build"
|
||||
],
|
||||
"postversion": "node ../../.scripts/covector/sync-cli-metadata.js ${ pkg.pkg } ${ release.type }"
|
||||
},
|
||||
"cli.js": {
|
||||
"@tauri-apps/cli": {
|
||||
"path": "./tooling/cli/node",
|
||||
"manager": "javascript",
|
||||
"getPublishedVersion": "node ../../../.scripts/covector/package-latest-version.js npm ${ pkgFile.pkg.name } ${ pkgFile.pkg.version }",
|
||||
"dependencies": ["cli.rs"],
|
||||
"dependencies": ["tauri-cli"],
|
||||
"postversion": [
|
||||
"node ../../../.scripts/covector/sync-cli-metadata.js ${ pkg.pkg } ${ release.type }",
|
||||
"cargo build --manifest-path ../../../core/tauri-config-schema/Cargo.toml"
|
||||
@@ -244,7 +259,7 @@
|
||||
"publish": [],
|
||||
"postpublish": []
|
||||
},
|
||||
"cli.rs": {
|
||||
"tauri-cli": {
|
||||
"path": "./tooling/cli",
|
||||
"manager": "rust",
|
||||
"dependencies": ["tauri-bundler", "tauri-utils"],
|
||||
@@ -261,7 +276,8 @@
|
||||
},
|
||||
"tauri-driver": {
|
||||
"path": "./tooling/webdriver",
|
||||
"manager": "rust"
|
||||
"manager": "rust",
|
||||
"postversion": "cargo check"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
4
.changes/pre.json
Normal file
4
.changes/pre.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"tag": "beta",
|
||||
"changes": []
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
# Changes
|
||||
|
||||
##### via https://github.com/jbolda/covector
|
||||
|
||||
As you create PRs and make changes that require a version bump, please add a new markdown file in this folder. You do not note the version _number_, but rather the type of bump that you expect: major, minor, or patch. The filename is not important, as long as it is a `.md`, but we recommend that it represents the overall change for organizational purposes.
|
||||
|
||||
When you select the version bump required, you do _not_ need to consider dependencies. Only note the package with the actual change, and any packages that depend on that package will be bumped automatically in the process.
|
||||
|
||||
Use the following format:
|
||||
|
||||
```md
|
||||
---
|
||||
"package-a": patch
|
||||
"package-b": patch
|
||||
---
|
||||
|
||||
Change summary goes here
|
||||
|
||||
```
|
||||
|
||||
Summaries do not have a specific character limit, but are text only. These summaries are used within the (future implementation of) changelogs. They will give context to the change and also point back to the original PR if more details and context are needed.
|
||||
|
||||
Changes will be designated as a `major`, `minor` or `patch` as further described in [semver](https://semver.org/).
|
||||
|
||||
Given a version number MAJOR.MINOR.PATCH, increment the:
|
||||
|
||||
- MAJOR version when you make incompatible API changes,
|
||||
- MINOR version when you add functionality in a backwards compatible manner, and
|
||||
- PATCH version when you make backwards compatible bug fixes.
|
||||
|
||||
Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format, but will be discussed prior to usage (as extra steps will be necessary in consideration of merging and publishing).
|
||||
@@ -6,7 +6,7 @@ FROM mcr.microsoft.com/vscode/devcontainers/base:0-${VARIANT}
|
||||
# Derived from Tauri contribution and setup guides:
|
||||
# See: https://github.com/tauri-apps/tauri/blob/dev/.github/CONTRIBUTING.md#development-guide
|
||||
# See: https://tauri.app/v1/guides/getting-started/prerequisites/#setting-up-linux
|
||||
ARG TAURI_BUILD_DEPS="build-essential curl libappindicator3-dev libgtk-3-dev librsvg2-dev libssl-dev libwebkit2gtk-4.0-dev wget"
|
||||
ARG TAURI_BUILD_DEPS="build-essential curl libappindicator3-dev libgtk-3-dev librsvg2-dev libssl-dev libwebkit2gtk-4.1-dev wget"
|
||||
|
||||
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||
&& apt-get install -y --no-install-recommends $TAURI_BUILD_DEPS
|
||||
|
||||
@@ -33,6 +33,7 @@ To do this, open your project with VS Code and run **Remote-Containers: Clone Re
|
||||
Docker Desktop provides facilities for [allowing the development container to connect to a service on the Docker host](https://docs.docker.com/desktop/windows/networking/#i-want-to-connect-from-a-container-to-a-service-on-the-host). So long as you have an X window server running on your Docker host, the devcontainer can connect to it and expose your Tauri GUI via an X window.
|
||||
|
||||
**Export the `DISPLAY` variable within the devcontainer terminal you launch your Tauri application from to expose your GUI outside of the devcontainer**.
|
||||
|
||||
```bash
|
||||
export DISPLAY="host.docker.internal:0"
|
||||
```
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM ubuntu:18.04
|
||||
FROM ubuntu:22.04
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
COPY common.sh lib.sh /
|
||||
@@ -41,4 +41,4 @@ ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc \
|
||||
|
||||
RUN dpkg --add-architecture arm64
|
||||
RUN apt-get update
|
||||
RUN apt-get install --assume-yes --no-install-recommends libssl-dev:arm64 libdbus-1-dev:arm64 libsoup2.4-dev:arm64 libssl-dev:arm64 libgtk-3-dev:arm64 webkit2gtk-4.0-dev:arm64 libappindicator3-1:arm64 librsvg2-dev:arm64 patchelf:arm64
|
||||
RUN apt-get install --assume-yes --no-install-recommends libssl-dev:arm64 libdbus-1-dev:arm64 libsoup2.4-dev:arm64 libssl-dev:arm64 libgtk-3-dev:arm64 webkit2gtk-4.1-dev:arm64 libappindicator3-1:arm64 librsvg2-dev:arm64 patchelf:arm64
|
||||
|
||||
24
.github/CONTRIBUTING.md
vendored
24
.github/CONTRIBUTING.md
vendored
@@ -22,7 +22,7 @@ Hi! We, the maintainers, are really excited that you are interested in contribut
|
||||
|
||||
- Issues with no clear repro steps will not be triaged. If an issue labeled "need repro" receives no further input from the issue author for more than 5 days, it will be closed.
|
||||
|
||||
- If your issue is resolved but still open, don’t hesitate to close it. In case you found a solution by yourself, it could be helpful to explain how you fixed it.
|
||||
- If your issue is resolved but still open, don't hesitate to close it. In case you found a solution by yourself, it could be helpful to explain how you fixed it.
|
||||
|
||||
- Most importantly, we beg your patience: the team must balance your request against many other responsibilities — fixing other bugs, answering other questions, new features, new documentation, etc. The issue list is not paid support and we cannot make guarantees about how fast your issue can be resolved.
|
||||
|
||||
@@ -54,31 +54,31 @@ Some Tauri packages will be automatically built when running one of the examples
|
||||
|
||||
### Packages Overview
|
||||
|
||||
- The JS API (`/tooling/api`) contains JS bindings to the builtin Rust functions in the Rust API.
|
||||
- cli.rs (`/tooling/cli`) is the primary CLI for creating and developing Tauri apps.
|
||||
- cli.js (`/tooling/cli/node`) is a Node.js CLI wrapper for `cli.rs`.
|
||||
- Tauri Bundler (`/tooling/bundler`) is used by the Rust CLI to package executables into installers.
|
||||
- Tauri Core (`/core/tauri`) is the heart of Tauri. It contains the code that starts the app, configures communication between Rust and the Webview, and ties all the other packages together.
|
||||
- The Macros (`/core/tauri-macros`) are used by Tauri Core for various functions.
|
||||
|
||||
### Developing The Node.js CLI (cli.js)
|
||||
|
||||
`cli.js` is a wrapper to `cli.rs` so most changes should be written on the Rust CLI. The `[Tauri repo root]/tooling/cli/node` folder contains only packaging scripts to properly publish the Rust CLI binaries to NPM.
|
||||
- Tauri Bundler (`/tooling/bundler`) is used by the Rust CLI to package executables into installers.
|
||||
- The Rust CLI aka `tauri-cli` (`/tooling/cli`) is the primary CLI for creating and developing Tauri apps.
|
||||
- The JS CLI aka `@tauri-apps/cli` (`/tooling/cli/node`) is a Node.js CLI wrapper for `tauri-cli`.
|
||||
- The JS API aka `@tauri-apps/api` (`/tooling/api`) contains JS bindings to the builtin Rust functions in the Rust API.
|
||||
|
||||
### Developing Tauri Bundler and Rust CLI
|
||||
|
||||
The code for the bundler is located in `[Tauri repo root]/tooling/bundler`, and the code for the Rust CLI is located in `[Tauri repo root]/tooling/cli`. If you are using your local copy of cli.js (see above), any changes you make to the bundler and CLI will be automatically built and applied when running the build or dev command. Otherwise, running `cargo install --path .` in the Rust CLI directory will allow you to run `cargo tauri build` and `cargo tauri dev` anywhere, using the updated copy of the bundler and cli. You will have to run this command each time you make a change in either package.
|
||||
The code for the bundler is located in `[Tauri repo root]/tooling/bundler`, and the code for the Rust CLI is located in `[Tauri repo root]/tooling/cli`. If you are using your local copy of `@tauri-apps/cli` (see above), any changes you make to the bundler and CLI will be automatically built and applied when running the build or dev command. Otherwise, running `cargo install --path .` in the Rust CLI directory will allow you to run `cargo tauri build` and `cargo tauri dev` anywhere, using the updated copy of the bundler and cli. You will have to run this command each time you make a change in either package.
|
||||
|
||||
### Developing The Node.js CLI (`@tauri-apps/cli`)
|
||||
|
||||
`@tauri-apps/cli` is a wrapper to `tauri-cli` so most changes should be written on the Rust CLI. The `[Tauri repo root]/tooling/cli/node` folder contains only packaging scripts to properly publish the Rust CLI binaries to NPM.
|
||||
|
||||
### Developing Tauri Core and Related Components (Rust API, Macros, Codegen, and Utils)
|
||||
|
||||
The code for Tauri Core is located in `[Tauri repo root]/core/tauri`, and the Rust API, Macros, and Utils are in `[Tauri repo root]/core/tauri-(api/macros/utils)`. The easiest way to test your changes is to use the `[Tauri repo root]/examples/helloworld` app. It automatically rebuilds and uses your local copy of the Tauri core packages. Just run `yarn tauri build` or `yarn tauri dev` in the helloworld app directory after making changes to test them out. To use your local changes in another project, edit its `src-tauri/Cargo.toml` file so that the `tauri` key looks like `tauri = { path = "PATH", features = [ "api-all", "cli" ] }`, where `PATH` is the relative path to `[Tauri repo root]/core/tauri`. Then, your local copy of the Tauri core packages will be rebuilt and used whenever you build that project.
|
||||
The code for Tauri Core is located in `[Tauri repo root]/core/tauri`, and the Rust API, Macros, and Utils are in `[Tauri repo root]/core/tauri-(api/macros/utils)`. The easiest way to test your changes is to use the `[Tauri repo root]/examples/helloworld` app. It automatically rebuilds and uses your local copy of the Tauri core packages. Just run `yarn tauri build` or `yarn tauri dev` in the helloworld app directory after making changes to test them out. To use your local changes in another project, edit its `src-tauri/Cargo.toml` file so that the `tauri` key looks like `tauri = { path = "PATH" }`, where `PATH` is the relative path to `[Tauri repo root]/core/tauri`. Then, your local copy of the Tauri core packages will be rebuilt and used whenever you build that project.
|
||||
|
||||
#### Building the documentation locally
|
||||
|
||||
You can build the Rust documentation locally running the following script:
|
||||
|
||||
```bash
|
||||
$ RUSTDOCFLAGS="--cfg doc_cfg" cargo +nightly doc --all-features --open
|
||||
$ RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --all-features --open
|
||||
```
|
||||
|
||||
### Developing the JS API
|
||||
|
||||
9
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
9
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -30,11 +30,10 @@ body:
|
||||
id: reproduction
|
||||
attributes:
|
||||
label: Reproduction
|
||||
description: Steps to reproduce the behavior.
|
||||
description: A link to a reproduction repo or steps to reproduce the behaviour.
|
||||
placeholder: |
|
||||
1. Go to ...
|
||||
2. Click on ...
|
||||
3. See error
|
||||
Please provide a minimal reproduction or steps to reproduce, see this guide https://stackoverflow.com/help/minimal-reproducible-example
|
||||
Why reproduction is required? see this article https://antfu.me/posts/why-reproductions-are-required
|
||||
|
||||
- type: textarea
|
||||
id: expected-behavior
|
||||
@@ -45,7 +44,7 @@ body:
|
||||
- type: textarea
|
||||
id: info
|
||||
attributes:
|
||||
label: Platform and versions
|
||||
label: Full `tauri info` output
|
||||
description: "Output of `npm run tauri info` or `cargo tauri info`"
|
||||
render: text
|
||||
validations:
|
||||
|
||||
45
.github/PULL_REQUEST_TEMPLATE.md
vendored
45
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,30 +1,21 @@
|
||||
<!--
|
||||
Update "[ ]" to "[x]" to check a box
|
||||
Before submitting a PR, please read https://github.com/tauri-apps/tauri/blob/dev/.github/CONTRIBUTING.md#pull-request-guidelines
|
||||
|
||||
Please make sure to read the Pull Request Guidelines: https://github.com/tauri-apps/tauri/blob/dev/.github/CONTRIBUTING.md#pull-request-guidelines
|
||||
1. Give the PR a descriptive title.
|
||||
|
||||
Examples of good title:
|
||||
- fix(windows): fix race condition in event loop
|
||||
- docs: update docstrings
|
||||
- feat: add `Window::set_fullscreen`
|
||||
|
||||
Examples of bad title:
|
||||
- fix #7123
|
||||
- update docs
|
||||
- fix bugs
|
||||
|
||||
2. If there is a related issue, reference it in the PR text, e.g. closes #123.
|
||||
3. If this change requires a new version, then add a change file in `.changes` directory with the appropriate bump, see https://github.com/tauri-apps/tauri/blob/dev/.changes/readme.md
|
||||
4. Ensure that all your commits are signed https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits
|
||||
5. Ensure `cargo test` and `cargo clippy` passes.
|
||||
6. Propose your changes as a draft PR if your work is still in progress.
|
||||
-->
|
||||
|
||||
### What kind of change does this PR introduce?
|
||||
<!-- Check at least one. If you are introducing a new binding, you must reference an issue where this binding has been proposed, discussed and approved by the maintainers. -->
|
||||
|
||||
- [ ] Bugfix
|
||||
- [ ] Feature
|
||||
- [ ] Docs
|
||||
- [ ] New Binding issue #___
|
||||
- [ ] Code style update
|
||||
- [ ] Refactor
|
||||
- [ ] Build-related changes
|
||||
- [ ] Other, please describe:
|
||||
|
||||
### Does this PR introduce a breaking change?
|
||||
<!-- If yes, please describe the impact and migration path for existing applications in an attached issue. -->
|
||||
|
||||
- [ ] Yes, and the changes were approved in issue #___
|
||||
- [ ] No
|
||||
|
||||
### Checklist
|
||||
- [ ] When resolving issues, they are referenced in the PR's title (e.g `fix: remove a typo, closes #___, #___`)
|
||||
- [ ] A change file is added if any packages will require a version bump due to this PR per [the instructions in the readme](https://github.com/tauri-apps/tauri/blob/dev/.changes/readme.md).
|
||||
- [ ] I have added a convincing reason for adding this feature, if necessary
|
||||
|
||||
### Other information
|
||||
|
||||
3
.github/config.yml
vendored
3
.github/config.yml
vendored
@@ -1,3 +0,0 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
31
.github/sponsors/crabnebula.svg
vendored
Normal file
31
.github/sponsors/crabnebula.svg
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<svg class="crabnebula-logo" width="100%" height="100%" viewBox="0 0 1204 210" version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xml:space="preserve" xmlns:serif="http://www.serif.com/"
|
||||
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<style>
|
||||
.crabnebula-logo path,
|
||||
.crabnebula-logo rect {
|
||||
fill: #001e42;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.crabnebula-logo path, .crabnebula-logo rect {
|
||||
fill: #fff;
|
||||
}
|
||||
}
|
||||
html[data-color-mode="dark"] .crabnebula-logo path,
|
||||
html[data-color-mode="dark"] .crabnebula-logo rect {
|
||||
fill: #fff;
|
||||
}
|
||||
</style>
|
||||
<path d="M351.903,162.334C344.288,162.334 337.123,160.881 330.41,157.975C323.696,155.069 317.834,151.11 312.824,146.099C307.914,141.089 304.006,135.276 301.101,128.662C298.195,121.948 296.742,114.783 296.742,107.167C296.742,99.55 298.195,92.435 301.101,85.821C304.006,79.107 307.914,73.244 312.824,68.234C317.834,63.223 323.696,59.265 330.41,56.358C337.123,53.452 344.288,51.999 351.903,51.999C357.414,51.999 362.675,52.701 367.685,54.103C372.795,55.507 377.455,57.511 381.663,60.116C385.972,62.622 389.83,65.678 393.237,69.286C396.644,72.793 399.499,76.752 401.804,81.161L380.762,92.586C377.756,87.174 373.848,82.915 369.038,79.808C364.328,76.702 358.617,75.148 351.903,75.148C347.494,75.148 343.386,76 339.578,77.704C335.871,79.407 332.614,81.762 329.809,84.769C327.003,87.675 324.798,91.082 323.195,94.991C321.592,98.799 320.79,102.857 320.79,107.167C320.79,111.476 321.592,115.584 323.195,119.493C324.798,123.301 327.003,126.708 329.809,129.715C332.614,132.621 335.871,134.926 339.578,136.629C343.386,138.333 347.494,139.185 351.903,139.185C358.617,139.185 364.328,137.631 369.038,134.525C373.848,131.418 377.756,127.159 380.762,121.748L401.804,133.172C399.499,137.581 396.644,141.59 393.237,145.198C389.83,148.705 385.972,151.762 381.663,154.367C377.455,156.872 372.795,158.827 367.685,160.23C362.675,161.633 357.414,162.334 351.903,162.334Z" style="fill-rule:nonzero;stroke:black;stroke-width:0.55px;"/>
|
||||
<path d="M413.821,85.37L436.517,85.37L436.517,96.644C437.72,93.337 439.924,90.481 443.131,88.076C446.437,85.671 450.195,84.468 454.403,84.468C455.506,84.468 456.658,84.518 457.86,84.619C459.063,84.719 460.366,84.969 461.768,85.37L461.768,108.369C460.065,107.768 458.412,107.317 456.808,107.016C455.205,106.716 453.502,106.565 451.698,106.565C446.788,106.565 443.03,108.269 440.425,111.676C437.82,115.083 436.517,119.493 436.517,124.904L436.517,160.53L413.821,160.53L413.821,85.37Z" style="fill-rule:nonzero;stroke:black;stroke-width:0.55px;"/>
|
||||
<path d="M502.161,162.184C497.251,162.184 492.642,161.132 488.333,159.027C484.125,156.923 480.467,154.117 477.361,150.609C474.255,147.001 471.8,142.843 469.996,138.133C468.193,133.322 467.291,128.261 467.291,122.95C467.291,117.639 468.193,112.628 469.996,107.918C471.8,103.108 474.255,98.949 477.361,95.442C480.467,91.834 484.125,88.978 488.333,86.873C492.642,84.769 497.251,83.717 502.161,83.717C504.666,83.717 506.971,84.017 509.075,84.619C511.28,85.12 513.234,85.821 514.937,86.723C516.741,87.625 518.244,88.627 519.446,89.729C520.749,90.832 521.801,91.884 522.603,92.886L522.603,85.37L545.299,85.37L545.299,160.53L522.603,160.53L522.603,153.014C521.801,154.016 520.749,155.069 519.446,156.171C518.244,157.273 516.741,158.275 514.937,159.177C513.234,160.079 511.28,160.781 509.075,161.282C506.971,161.883 504.666,162.184 502.161,162.184ZM507.272,141.59C512.382,141.59 516.49,139.836 519.597,136.329C522.803,132.821 524.406,128.362 524.406,122.95C524.406,117.539 522.803,113.079 519.597,109.572C516.49,106.064 512.382,104.31 507.272,104.31C502.161,104.31 498.003,106.064 494.796,109.572C491.69,113.079 490.137,117.539 490.137,122.95C490.137,128.362 491.69,132.821 494.796,136.329C498.003,139.836 502.161,141.59 507.272,141.59Z" style="fill-rule:nonzero;stroke:black;stroke-width:0.55px;"/>
|
||||
<path d="M607.116,162.184C604.611,162.184 602.256,161.883 600.051,161.282C597.947,160.781 595.993,160.079 594.19,159.177C592.486,158.275 590.983,157.273 589.681,156.171C588.378,155.069 587.376,154.016 586.674,153.014L586.674,160.53L563.979,160.53L563.979,47.79L586.674,47.79L586.674,92.886C587.376,91.884 588.378,90.832 589.681,89.729C590.983,88.627 592.486,87.625 594.19,86.723C595.993,85.821 597.947,85.12 600.051,84.619C602.256,84.017 604.611,83.717 607.116,83.717C612.026,83.717 616.585,84.769 620.793,86.873C625.102,88.978 628.81,91.834 631.916,95.442C635.022,98.949 637.477,103.108 639.281,107.918C641.084,112.628 641.986,117.639 641.986,122.95C641.986,128.261 641.084,133.322 639.281,138.133C637.477,142.843 635.022,147.001 631.916,150.609C628.81,154.117 625.102,156.923 620.793,159.027C616.585,161.132 612.026,162.184 607.116,162.184ZM602.005,141.59C607.116,141.59 611.224,139.836 614.33,136.329C617.537,132.821 619.14,128.362 619.14,122.95C619.14,117.539 617.537,113.079 614.33,109.572C611.224,106.064 607.116,104.31 602.005,104.31C596.895,104.31 592.737,106.064 589.53,109.572C586.424,113.079 584.871,117.539 584.871,122.95C584.871,128.362 586.424,132.821 589.53,136.329C592.737,139.836 596.895,141.59 602.005,141.59Z" style="fill-rule:nonzero;stroke:black;stroke-width:0.55px;"/>
|
||||
<path d="M732.106,160.53L680.101,94.54L680.101,160.53L656.203,160.53L656.203,53.803L676.795,53.803L728.649,119.793L728.649,53.803L752.698,53.803L752.698,160.53L732.106,160.53Z" style="fill-rule:nonzero;stroke:black;stroke-width:0.55px;"/>
|
||||
<path d="M806.852,162.184C801.341,162.184 796.13,161.282 791.22,159.478C786.411,157.674 782.202,155.069 778.595,151.661C774.988,148.254 772.132,144.145 770.028,139.335C767.923,134.425 766.871,128.963 766.871,122.95C766.871,117.338 767.823,112.177 769.727,107.467C771.731,102.657 774.487,98.498 777.994,94.991C781.601,91.483 785.809,88.727 790.619,86.723C795.429,84.719 800.69,83.717 806.401,83.717C811.311,83.717 816.021,84.518 820.53,86.122C825.139,87.625 829.147,89.93 832.554,93.036C835.961,96.043 838.666,99.851 840.67,104.461C842.775,108.97 843.827,114.282 843.827,120.395C843.827,121.397 843.777,122.549 843.677,123.852C843.677,125.055 843.576,126.558 843.376,128.362L788.816,128.362C789.517,132.871 791.671,136.228 795.279,138.433C798.886,140.538 802.844,141.59 807.153,141.59C811.562,141.59 815.319,140.738 818.425,139.034C821.632,137.231 823.937,135.226 825.339,133.022L842.173,145.649C838.666,150.659 833.857,154.668 827.744,157.674C821.732,160.681 814.768,162.184 806.852,162.184ZM821.281,113.48C820.279,109.471 818.275,106.615 815.269,104.912C812.263,103.108 809.107,102.206 805.8,102.206C804.096,102.206 802.393,102.406 800.69,102.807C798.986,103.208 797.383,103.859 795.88,104.761C794.377,105.663 793.024,106.816 791.822,108.219C790.719,109.622 789.918,111.376 789.417,113.48L821.281,113.48Z" style="fill-rule:nonzero;stroke:black;stroke-width:0.55px;"/>
|
||||
<path d="M901.265,162.184C898.76,162.184 896.405,161.883 894.201,161.282C892.097,160.781 890.143,160.079 888.339,159.177C886.636,158.275 885.133,157.273 883.83,156.171C882.527,155.069 881.525,154.016 880.824,153.014L880.824,160.53L858.128,160.53L858.128,47.79L880.824,47.79L880.824,92.886C881.525,91.884 882.527,90.832 883.83,89.729C885.133,88.627 886.636,87.625 888.339,86.723C890.143,85.821 892.097,85.12 894.201,84.619C896.405,84.017 898.76,83.717 901.265,83.717C906.175,83.717 910.734,84.769 914.943,86.873C919.252,88.978 922.959,91.834 926.065,95.442C929.172,98.949 931.627,103.108 933.43,107.918C935.234,112.628 936.136,117.639 936.136,122.95C936.136,128.261 935.234,133.322 933.43,138.133C931.627,142.843 929.172,147.001 926.065,150.609C922.959,154.117 919.252,156.923 914.943,159.027C910.734,161.132 906.175,162.184 901.265,162.184ZM896.155,141.59C901.265,141.59 905.374,139.836 908.48,136.329C911.686,132.821 913.29,128.362 913.29,122.95C913.29,117.539 911.686,113.079 908.48,109.572C905.374,106.064 901.265,104.31 896.155,104.31C891.045,104.31 886.886,106.064 883.68,109.572C880.573,113.079 879.02,117.539 879.02,122.95C879.02,128.362 880.573,132.821 883.68,136.329C886.886,139.836 891.045,141.59 896.155,141.59Z" style="fill-rule:nonzero;stroke:black;stroke-width:0.55px;"/>
|
||||
<path d="M977.812,162.184C968.493,162.184 961.429,159.077 956.619,152.864C951.81,146.651 949.405,138.433 949.405,128.211L949.405,85.37L972.101,85.37L972.101,124.303C972.101,129.815 972.952,134.074 974.656,137.08C976.459,140.087 979.466,141.59 983.674,141.59C987.983,141.59 991.39,140.037 993.895,136.93C996.5,133.823 997.803,128.813 997.803,121.898L997.803,85.37L1020.5,85.37L1020.5,160.53L997.803,160.53L997.803,152.864C995.999,155.469 993.444,157.674 990.137,159.478C986.83,161.282 982.722,162.184 977.812,162.184Z" style="fill-rule:nonzero;stroke:black;stroke-width:0.55px;"/>
|
||||
<rect x="1039.11" y="47.79" width="22.701" height="112.74" style="fill-rule:nonzero;stroke:black;stroke-width:0.55px;"/>
|
||||
<path d="M1110.86,162.184C1105.95,162.184 1101.34,161.132 1097.03,159.027C1092.83,156.923 1089.17,154.117 1086.06,150.609C1082.96,147.001 1080.5,142.843 1078.7,138.133C1076.89,133.322 1075.99,128.261 1075.99,122.95C1075.99,117.639 1076.89,112.628 1078.7,107.918C1080.5,103.108 1082.96,98.949 1086.06,95.442C1089.17,91.834 1092.83,88.978 1097.03,86.873C1101.34,84.769 1105.95,83.717 1110.86,83.717C1113.37,83.717 1115.67,84.017 1117.78,84.619C1119.98,85.12 1121.94,85.821 1123.64,86.723C1125.44,87.625 1126.95,88.627 1128.15,89.729C1129.45,90.832 1130.5,91.884 1131.3,92.886L1131.3,85.37L1154,85.37L1154,160.53L1131.3,160.53L1131.3,153.014C1130.5,154.016 1129.45,155.069 1128.15,156.171C1126.95,157.273 1125.44,158.275 1123.64,159.177C1121.94,160.079 1119.98,160.781 1117.78,161.282C1115.67,161.883 1113.37,162.184 1110.86,162.184ZM1115.97,141.59C1121.08,141.59 1125.19,139.836 1128.3,136.329C1131.5,132.821 1133.11,128.362 1133.11,122.95C1133.11,117.539 1131.5,113.079 1128.3,109.572C1125.19,106.064 1121.08,104.31 1115.97,104.31C1110.86,104.31 1106.7,106.064 1103.5,109.572C1100.39,113.079 1098.84,117.539 1098.84,122.95C1098.84,128.362 1100.39,132.821 1103.5,136.329C1106.7,139.836 1110.86,141.59 1115.97,141.59Z" style="fill-rule:nonzero;stroke:black;stroke-width:0.55px;"/>
|
||||
<path d="M146.48,54.585C119.724,89.866 119.878,134.941 146.826,155.264C153.908,160.605 162.136,163.705 170.903,164.732C146.032,184.934 117.382,191.203 98.037,178.045C71.507,160 72.524,112.249 100.309,71.391C123.51,37.273 158.039,18.749 184.247,24.072C170.404,30.195 157.116,40.561 146.48,54.585ZM181.638,99.643C169.141,111.453 154.859,119.304 142.801,121.916C149.921,147.367 177.29,149.323 177.29,149.323C177.29,149.323 193.578,145.578 205.877,117.941C216.005,95.183 215.122,71.668 204.914,59.7C204.065,71.267 195.731,86.324 181.638,99.643Z" style="stroke:black;stroke-width:0.55px;"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 11 KiB |
107
.github/workflows/artifacts-updater.yml
vendored
107
.github/workflows/artifacts-updater.yml
vendored
@@ -1,107 +0,0 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: updater test artifacts
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/artifacts-updater.yml'
|
||||
- 'examples/updater/**'
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
CARGO_PROFILE_DEV_DEBUG: 0 # This would add unnecessary bloat to the target folder, decreasing cache efficiency.
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build-artifacts:
|
||||
runs-on: ${{ matrix.platform }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [ubuntu-latest, macos-latest, windows-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: install stable
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
|
||||
- name: install Linux dependencies
|
||||
if: matrix.platform == 'ubuntu-latest'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y webkit2gtk-4.0 libayatana-appindicator3-dev
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: |
|
||||
core -> ../target
|
||||
tooling/cli
|
||||
|
||||
- name: build and install cli.rs
|
||||
run: cargo install --path tooling/cli --force
|
||||
- name: Check whether code signing should be enabled
|
||||
id: enablecodesigning
|
||||
env:
|
||||
ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }}
|
||||
run: |
|
||||
echo "Enable code signing: ${{ env.ENABLE_CODE_SIGNING != '' }}"
|
||||
echo "::set-output name=enabled::${{ env.ENABLE_CODE_SIGNING != '' }}"
|
||||
|
||||
# run only on tauri-apps/tauri repo (require secrets)
|
||||
- name: build sample artifacts + code signing (updater)
|
||||
if: steps.enablecodesigning.outputs.enabled == 'true'
|
||||
working-directory: ./examples/updater
|
||||
run: |
|
||||
yarn install
|
||||
cargo tauri build --verbose
|
||||
env:
|
||||
# Notarization (disabled)
|
||||
# FIXME: enable only on `dev` push maybe? as it take some times...
|
||||
#
|
||||
# APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
# APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
||||
|
||||
# Apple code signing testing
|
||||
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
||||
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
|
||||
# Updater signature is exposed here to make sure it works in PR's
|
||||
TAURI_PRIVATE_KEY: dW50cnVzdGVkIGNvbW1lbnQ6IHJzaWduIGVuY3J5cHRlZCBzZWNyZXQga2V5ClJXUlRZMEl5YTBGV3JiTy9lRDZVd3NkL0RoQ1htZmExNDd3RmJaNmRMT1ZGVjczWTBKZ0FBQkFBQUFBQUFBQUFBQUlBQUFBQWdMekUzVkE4K0tWQ1hjeGt1Vkx2QnRUR3pzQjVuV0ZpM2czWXNkRm9hVUxrVnB6TUN3K1NheHJMREhQbUVWVFZRK3NIL1VsMDBHNW5ET1EzQno0UStSb21nRW4vZlpTaXIwZFh5ZmRlL1lSN0dKcHdyOUVPclVvdzFhVkxDVnZrbHM2T1o4Tk1NWEU9Cg==
|
||||
TAURI_KEY_PASSWORD:
|
||||
# run on PRs and forks
|
||||
- name: build sample artifacts (updater)
|
||||
if: steps.enablecodesigning.outputs.enabled != 'true'
|
||||
working-directory: ./examples/updater
|
||||
run: |
|
||||
yarn install
|
||||
cargo tauri build --verbose
|
||||
env:
|
||||
TAURI_PRIVATE_KEY: dW50cnVzdGVkIGNvbW1lbnQ6IHJzaWduIGVuY3J5cHRlZCBzZWNyZXQga2V5ClJXUlRZMEl5YTBGV3JiTy9lRDZVd3NkL0RoQ1htZmExNDd3RmJaNmRMT1ZGVjczWTBKZ0FBQkFBQUFBQUFBQUFBQUlBQUFBQWdMekUzVkE4K0tWQ1hjeGt1Vkx2QnRUR3pzQjVuV0ZpM2czWXNkRm9hVUxrVnB6TUN3K1NheHJMREhQbUVWVFZRK3NIL1VsMDBHNW5ET1EzQno0UStSb21nRW4vZlpTaXIwZFh5ZmRlL1lSN0dKcHdyOUVPclVvdzFhVkxDVnZrbHM2T1o4Tk1NWEU9Cg==
|
||||
TAURI_KEY_PASSWORD:
|
||||
# upload assets
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: matrix.platform == 'ubuntu-latest'
|
||||
with:
|
||||
name: linux-updater-artifacts
|
||||
path: ./examples/updater/src-tauri/target/release/bundle/appimage/updater-example_*.AppImage.*
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: matrix.platform == 'windows-latest'
|
||||
with:
|
||||
name: windows-updater-artifacts
|
||||
path: ./examples/updater/src-tauri/target/release/bundle/msi/*
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: matrix.platform == 'macos-latest'
|
||||
with:
|
||||
name: macos-updater-artifacts
|
||||
path: ./examples/updater/src-tauri/target/release/bundle/macos/updater-example.app.tar.*
|
||||
14
.github/workflows/audit.yml
vendored
14
.github/workflows/audit.yml
vendored
@@ -10,6 +10,7 @@ on:
|
||||
- cron: '0 0 * * *'
|
||||
push:
|
||||
paths:
|
||||
- '.github/workflows/audit.yml'
|
||||
- '**/Cargo.lock'
|
||||
- '**/Cargo.toml'
|
||||
- '**/package.json'
|
||||
@@ -23,16 +24,21 @@ jobs:
|
||||
audit-rust:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
- name: rust audit
|
||||
uses: actions-rs/audit-check@v1
|
||||
uses: rustsec/audit-check@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
audit-js:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: yarn audit
|
||||
- uses: actions/checkout@v4
|
||||
- name: audit workspace
|
||||
run: yarn audit
|
||||
- name: audit @tauri-apps/api
|
||||
working-directory: tooling/api
|
||||
run: yarn audit
|
||||
- name: audit @tauri-apps/cli
|
||||
working-directory: tooling/cli/node
|
||||
run: yarn audit
|
||||
|
||||
35
.github/workflows/bench.yml
vendored
35
.github/workflows/bench.yml
vendored
@@ -2,19 +2,22 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: benches
|
||||
name: bench
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
- next
|
||||
- 1.x
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/bench.yml'
|
||||
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
CARGO_PROFILE_DEV_DEBUG: 0 # This would add unnecessary bloat to the target folder, decreasing cache efficiency.
|
||||
LC_ALL: en_US.UTF-8 # This prevents strace from changing it's number format to use commas.
|
||||
LC_ALL: en_US.UTF-8 # This prevents strace from changing its number format to use commas.
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -27,23 +30,22 @@ jobs:
|
||||
matrix:
|
||||
rust: [nightly]
|
||||
platform:
|
||||
- { target: x86_64-unknown-linux-gnu, os: ubuntu-20.04 }
|
||||
- { target: x86_64-unknown-linux-gnu, os: ubuntu-latest }
|
||||
|
||||
runs-on: ${{ matrix.platform.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: install ${{ matrix.rust }}
|
||||
uses: actions-rs/toolchain@v1
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: install Rust ${{ matrix.rust }}
|
||||
uses: dtolnay/rust-toolchain@master
|
||||
with:
|
||||
toolchain: ${{ matrix.rust }}
|
||||
override: true
|
||||
default: true
|
||||
components: rust-src
|
||||
target: ${{ matrix.platform.target }}
|
||||
targets: ${{ matrix.platform.target }}
|
||||
|
||||
- name: setup python
|
||||
uses: actions/setup-python@v2
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.10'
|
||||
architecture: x64
|
||||
@@ -52,9 +54,12 @@ jobs:
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y webkit2gtk-4.0 libayatana-appindicator3-dev xvfb
|
||||
wget https://github.com/sharkdp/hyperfine/releases/download/v1.11.0/hyperfine_1.11.0_amd64.deb
|
||||
sudo dpkg -i hyperfine_1.11.0_amd64.deb
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
libwebkit2gtk-4.1-dev libayatana-appindicator3-dev \
|
||||
xvfb \
|
||||
at-spi2-core
|
||||
wget https://github.com/sharkdp/hyperfine/releases/download/v1.18.0/hyperfine_1.18.0_amd64.deb
|
||||
sudo dpkg -i hyperfine_1.18.0_amd64.deb
|
||||
pip install memory_profiler
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
@@ -70,7 +75,7 @@ jobs:
|
||||
|
||||
- name: clone benchmarks_results
|
||||
if: github.repository == 'tauri-apps/tauri' && github.ref == 'refs/heads/dev'
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.BENCH_PAT }}
|
||||
path: gh-pages
|
||||
|
||||
32
.github/workflows/check-change-tags.yml
vendored
Normal file
32
.github/workflows/check-change-tags.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: check change tags
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- '.changes/*.md'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: dorny/paths-filter@v2
|
||||
id: filter
|
||||
with:
|
||||
list-files: shell
|
||||
filters: |
|
||||
changes:
|
||||
- added|modified: '.changes/*.md'
|
||||
|
||||
- name: check
|
||||
run: node ./.scripts/ci/check-change-tags.js ${{ steps.filter.outputs.changes_files }}
|
||||
if: ${{ steps.filter.outputs.changes == 'true' }}
|
||||
37
.github/workflows/check-generated-files.yml
vendored
37
.github/workflows/check-generated-files.yml
vendored
@@ -2,7 +2,7 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: Check generated files
|
||||
name: check generated files
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
@@ -13,16 +13,6 @@ on:
|
||||
- 'core/tauri-utils/src/config.rs'
|
||||
- 'tooling/cli/schema.json'
|
||||
- 'core/tauri-config-schema/schema.json'
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
paths:
|
||||
- '.github/workflows/check-generated-files.yml'
|
||||
- 'tooling/api/src/**'
|
||||
- 'core/tauri/scripts/bundle.global.js'
|
||||
- 'core/tauri-utils/src/config.rs'
|
||||
- 'tooling/cli/schema.json'
|
||||
- 'core/tauri-config-schema/schema.json'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -35,47 +25,41 @@ jobs:
|
||||
api: ${{ steps.filter.outputs.api }}
|
||||
schema: ${{ steps.filter.outputs.schema }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dorny/paths-filter@v2
|
||||
id: filter
|
||||
with:
|
||||
filters: |
|
||||
api:
|
||||
- 'tooling/api/src/**'
|
||||
- 'tooling/api/docs/js-api.json'
|
||||
- 'core/tauri/scripts/bundle.global.js'
|
||||
schema:
|
||||
- 'core/tauri-utils/src/config.rs'
|
||||
- 'tooling/cli/schema.json'
|
||||
- 'core/tauri-config-schema/schema.json'
|
||||
|
||||
check-api:
|
||||
api:
|
||||
runs-on: ubuntu-latest
|
||||
needs: changes
|
||||
if: needs.changes.outputs.api == 'true'
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: build api
|
||||
working-directory: tooling/api
|
||||
run: yarn && yarn build
|
||||
- name: check api
|
||||
run: |
|
||||
git restore tooling/api/docs/js-api.json
|
||||
./.scripts/ci/has-diff.sh
|
||||
run: ./.scripts/ci/has-diff.sh
|
||||
|
||||
check-schema:
|
||||
schema:
|
||||
runs-on: ubuntu-latest
|
||||
needs: changes
|
||||
if: needs.changes.outputs.schema == 'true'
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: install stable
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- name: install Linux dependencies
|
||||
run: |
|
||||
@@ -87,10 +71,7 @@ jobs:
|
||||
workspaces: core -> ../target
|
||||
|
||||
- name: generate schema.json
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: build
|
||||
args: --manifest-path ./core/tauri-config-schema/Cargo.toml
|
||||
run: cargo build --manifest-path ./core/tauri-config-schema/Cargo.toml
|
||||
|
||||
- name: check schema
|
||||
run: ./.scripts/ci/has-diff.sh
|
||||
|
||||
6
.github/workflows/check-license-header.yml
vendored
6
.github/workflows/check-license-header.yml
vendored
@@ -2,7 +2,7 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: Check generated files
|
||||
name: check license headers
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
@@ -15,7 +15,7 @@ jobs:
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dorny/paths-filter@v2
|
||||
id: filter
|
||||
with:
|
||||
@@ -25,4 +25,4 @@ jobs:
|
||||
- added: '**'
|
||||
- name: check header license on new files
|
||||
if: ${{ steps.filter.outputs.added == 'true' }}
|
||||
run: node check-license-header.js ${{ steps.filter.outputs.added_files }}
|
||||
run: node ./.scripts/ci/check-license-header.js ${{ steps.filter.outputs.added_files }}
|
||||
|
||||
@@ -10,7 +10,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: covector status
|
||||
@@ -2,7 +2,7 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: version or publish
|
||||
name: covector version or publish
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -19,18 +19,18 @@ jobs:
|
||||
platform: [ubuntu-latest, macos-latest, windows-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: install stable
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- name: install Linux dependencies
|
||||
if: matrix.platform == 'ubuntu-latest'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y webkit2gtk-4.0 libayatana-appindicator3-dev libfuse2
|
||||
sudo apt-get install -y webkit2gtk-4.1 libayatana-appindicator3-dev libfuse2
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
@@ -39,10 +39,7 @@ jobs:
|
||||
tooling/cli
|
||||
|
||||
- name: build CLI
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: build
|
||||
args: --manifest-path ./tooling/cli/Cargo.toml
|
||||
run: cargo build --manifest-path ./tooling/cli/Cargo.toml
|
||||
|
||||
- name: run integration tests
|
||||
run: cargo test --test '*' -- --ignored
|
||||
@@ -66,12 +63,12 @@ jobs:
|
||||
- run-integration-tests
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-node@v2
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 14
|
||||
node-version: 18
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
cache: yarn
|
||||
cache-dependency-path: tooling/*/yarn.lock
|
||||
@@ -115,23 +112,20 @@ jobs:
|
||||
repository: tauri-apps/tauri-docs
|
||||
event-type: update-docs
|
||||
|
||||
- name: Trigger cli.js publishing workflow
|
||||
- name: Trigger `@tauri-apps/cli` publishing workflow
|
||||
if: |
|
||||
steps.covector.outputs.successfulPublish == 'true' &&
|
||||
contains(steps.covector.outputs.packagesPublished, 'cli.rs')
|
||||
contains(steps.covector.outputs.packagesPublished, '@tauri-apps/cli')
|
||||
uses: peter-evans/repository-dispatch@v1
|
||||
with:
|
||||
token: ${{ secrets.ORG_TAURI_BOT_PAT }}
|
||||
repository: tauri-apps/tauri
|
||||
event-type: publish-clijs
|
||||
client-payload: '{"releaseId": "${{ steps.covector.outputs.cli.js-releaseId }}" }'
|
||||
event-type: publish-js-cli
|
||||
client-payload: >-
|
||||
{"releaseId": "${{ steps.covector.outputs['-tauri-apps-cli-releaseId'] }}" }
|
||||
|
||||
- name: Trigger cli.rs publishing workflow
|
||||
- name: Trigger `tauri-cli` publishing workflow
|
||||
if: |
|
||||
steps.covector.outputs.successfulPublish == 'true' &&
|
||||
contains(steps.covector.outputs.packagesPublished, 'cli.rs')
|
||||
contains(steps.covector.outputs.packagesPublished, 'tauri-cli')
|
||||
uses: peter-evans/repository-dispatch@v1
|
||||
with:
|
||||
token: ${{ secrets.ORG_TAURI_BOT_PAT }}
|
||||
repository: tauri-apps/tauri
|
||||
event-type: publish-clirs
|
||||
|
||||
24
.github/workflows/docker.yml
vendored
24
.github/workflows/docker.yml
vendored
@@ -17,12 +17,10 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: install stable
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- name: install Linux dependencies
|
||||
run: |
|
||||
@@ -40,10 +38,7 @@ jobs:
|
||||
if-no-files-found: error
|
||||
|
||||
- name: build CLI
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: build
|
||||
args: --manifest-path ./tooling/cli/Cargo.toml
|
||||
run: cargo build --manifest-path ./tooling/cli/Cargo.toml
|
||||
|
||||
- name: Upload CLI
|
||||
uses: actions/upload-artifact@v3
|
||||
@@ -64,20 +59,17 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: install stable
|
||||
uses: actions-rs/toolchain@v1
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
default: true
|
||||
target: ${{ matrix.target.name }}
|
||||
targets: ${{ matrix.target.name }}
|
||||
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
node-version: 18
|
||||
|
||||
- name: Download cross
|
||||
uses: actions/download-artifact@v3
|
||||
@@ -115,7 +107,7 @@ jobs:
|
||||
- name: install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y webkit2gtk-4.0 libayatana-appindicator3-dev
|
||||
sudo apt-get install -y webkit2gtk-4.1 libayatana-appindicator3-dev
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
|
||||
@@ -2,16 +2,16 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: cli clippy and fmt check
|
||||
name: lint cli
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
- next
|
||||
- 1.x
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/lint-fmt-cli.yml'
|
||||
- '.github/workflows/lint-cli.yml'
|
||||
- 'tooling/cli/**'
|
||||
|
||||
env:
|
||||
@@ -23,35 +23,29 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
fmt_check:
|
||||
fmt:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions-rs/toolchain@v1
|
||||
- name: install Rust stable and rustfmt
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
components: rustfmt
|
||||
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: fmt
|
||||
args: --manifest-path ./tooling/cli/Cargo.toml --all -- --check
|
||||
- name: Run cargo fmt
|
||||
run: cargo fmt --manifest-path ./tooling/cli/Cargo.toml --all -- --check
|
||||
|
||||
cli_clippy_check:
|
||||
clippy:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions-rs/toolchain@v1
|
||||
- name: install Rust stable and clippy
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
components: clippy
|
||||
|
||||
- name: install dependencies
|
||||
@@ -63,8 +57,5 @@ jobs:
|
||||
with:
|
||||
workspaces: tooling/cli
|
||||
|
||||
- uses: actions-rs/clippy-check@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
args: --manifest-path ./tooling/cli/Cargo.toml --all-targets --all-features -- -D warnings
|
||||
name: cli
|
||||
- name: run Clippy
|
||||
run: cargo clippy --manifest-path ./tooling/cli/Cargo.toml --all-targets --all-features -- -D warnings
|
||||
70
.github/workflows/lint-core.yml
vendored
Normal file
70
.github/workflows/lint-core.yml
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: lint core
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
- 1.x
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/lint-core.yml'
|
||||
- 'core/**'
|
||||
- '!core/tauri/scripts/**'
|
||||
- 'examples/**'
|
||||
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
CARGO_PROFILE_DEV_DEBUG: 0 # This would add unnecessary bloat to the target folder, decreasing cache efficiency.
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
fmt:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: install Rust stable and rustfmt
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
components: rustfmt
|
||||
|
||||
- name: run cargo fmt
|
||||
run: cargo fmt --all -- --check
|
||||
|
||||
clippy:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
clippy:
|
||||
- { args: '', key: 'empty' }
|
||||
- { args: '--all-features', key: 'all' }
|
||||
- { args: '--features custom-protocol', key: 'custom-protocol' }
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y webkit2gtk-4.1 libayatana-appindicator3-dev
|
||||
|
||||
- name: install Rust stable with clippy
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
components: clippy
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: core -> ../target
|
||||
save-if: ${{ matrix.clippy.key == 'all' }}
|
||||
|
||||
- name: Run clippy - ${{ matrix.clippy.key }}
|
||||
run: cargo clippy --manifest-path ./core/tauri/Cargo.toml --all-targets ${{ matrix.clippy.args }} -- -D warnings
|
||||
83
.github/workflows/lint-fmt-core.yml
vendored
83
.github/workflows/lint-fmt-core.yml
vendored
@@ -1,83 +0,0 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: core clippy and fmt check
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
- next
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/lint-fmt-core.yml'
|
||||
- 'core/**'
|
||||
- '!core/tauri/scripts/**'
|
||||
- 'examples/**'
|
||||
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
CARGO_PROFILE_DEV_DEBUG: 0 # This would add unnecessary bloat to the target folder, decreasing cache efficiency.
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
fmt_check:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
components: rustfmt
|
||||
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: fmt
|
||||
args: --all -- --check
|
||||
|
||||
core_clippy_check:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
clippy:
|
||||
- { args: '', key: 'empty' }
|
||||
- {
|
||||
args: '--features compression,wry,linux-protocol-headers,isolation,custom-protocol,api-all,cli,updater,system-tray,windows7-compat,http-multipart',
|
||||
key: 'all'
|
||||
}
|
||||
- { args: '--features custom-protocol', key: 'custom-protocol' }
|
||||
- { args: '--features api-all', key: 'api-all' }
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y webkit2gtk-4.0 libayatana-appindicator3-dev
|
||||
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
components: clippy
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: core -> ../target
|
||||
save-if: ${{ matrix.clippy.key == 'all' }}
|
||||
|
||||
- uses: actions-rs/clippy-check@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
args: --manifest-path ./core/tauri/Cargo.toml --all-targets ${{ matrix.clippy.args }} -- -D warnings
|
||||
name: ${{ matrix.clippy.key }}
|
||||
37
.github/workflows/lint-js.yml
vendored
37
.github/workflows/lint-js.yml
vendored
@@ -2,7 +2,7 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: api and cli.js lint check
|
||||
name: lint js
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
@@ -16,32 +16,45 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
eslint-check:
|
||||
eslint-cli:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '14'
|
||||
node-version: '18'
|
||||
cache: yarn
|
||||
cache-dependency-path: tooling/*/yarn.lock
|
||||
- name: install cli.js deps via yarn
|
||||
cache-dependency-path: tooling/cli/node/yarn.lock
|
||||
- name: install deps via yarn
|
||||
working-directory: ./tooling/cli/node/
|
||||
run: yarn
|
||||
# nothing to lint
|
||||
#- name: run cli.js lint
|
||||
#- name: run lint
|
||||
# working-directory: ./tooling/cli/node/
|
||||
# run: yarn lint
|
||||
- name: run cli.js format
|
||||
- name: run format
|
||||
working-directory: ./tooling/cli/node/
|
||||
run: yarn format:check
|
||||
|
||||
- name: install api deps via yarn
|
||||
eslint-api:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '18'
|
||||
cache: yarn
|
||||
cache-dependency-path: tooling/api/yarn.lock
|
||||
|
||||
- name: install deps via yarn
|
||||
working-directory: ./tooling/api/
|
||||
run: yarn
|
||||
- name: run api lint
|
||||
- name: run ts:check
|
||||
working-directory: ./tooling/api/
|
||||
run: yarn ts:check
|
||||
- name: run lint
|
||||
working-directory: ./tooling/api/
|
||||
run: yarn lint
|
||||
- name: run api format
|
||||
- name: run format
|
||||
working-directory: ./tooling/api/
|
||||
run: yarn format:check
|
||||
|
||||
61
.github/workflows/publish-cli-js.yml
vendored
61
.github/workflows/publish-cli-js.yml
vendored
@@ -2,7 +2,7 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: publish cli.js
|
||||
name: publish `@tauri-apps/cli`
|
||||
env:
|
||||
DEBUG: napi:*
|
||||
APP_NAME: cli
|
||||
@@ -11,10 +11,10 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
releaseId:
|
||||
description: 'ID of the cli.js release'
|
||||
description: 'ID of the `@tauri-apps/cli` release'
|
||||
required: true
|
||||
repository_dispatch:
|
||||
types: [publish-clijs]
|
||||
types: [publish-js-cli]
|
||||
|
||||
defaults:
|
||||
run:
|
||||
@@ -40,14 +40,18 @@ jobs:
|
||||
build: yarn build:release --target i686-pc-windows-msvc
|
||||
target: i686-pc-windows-msvc
|
||||
architecture: x64
|
||||
- host: ubuntu-18.04
|
||||
- host: windows-latest
|
||||
architecture: x64
|
||||
target: aarch64-pc-windows-msvc
|
||||
build: yarn build:release --target aarch64-pc-windows-msvc --features native-tls-vendored --cargo-flags="--no-default-features"
|
||||
- host: ubuntu-20.04
|
||||
target: x86_64-unknown-linux-gnu
|
||||
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian
|
||||
build: |
|
||||
cd tooling/cli/node
|
||||
yarn build:release --target x86_64-unknown-linux-gnu
|
||||
strip *.node
|
||||
- host: ubuntu-18.04
|
||||
- host: ubuntu-20.04
|
||||
target: x86_64-unknown-linux-musl
|
||||
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine
|
||||
build: |
|
||||
@@ -57,16 +61,16 @@ jobs:
|
||||
- host: macos-latest
|
||||
target: aarch64-apple-darwin
|
||||
build: |
|
||||
yarn build:release --target=aarch64-apple-darwin
|
||||
yarn build:release --features native-tls-vendored --target=aarch64-apple-darwin
|
||||
strip -x *.node
|
||||
- host: ubuntu-18.04
|
||||
- host: ubuntu-20.04
|
||||
target: aarch64-unknown-linux-gnu
|
||||
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian-aarch64
|
||||
build: |
|
||||
cd tooling/cli/node
|
||||
yarn build:release --target aarch64-unknown-linux-gnu
|
||||
aarch64-unknown-linux-gnu-strip *.node
|
||||
- host: ubuntu-18.04
|
||||
- host: ubuntu-20.04
|
||||
architecture: x64
|
||||
target: armv7-unknown-linux-gnueabihf
|
||||
setup: |
|
||||
@@ -75,7 +79,7 @@ jobs:
|
||||
build: |
|
||||
yarn build:release --target=armv7-unknown-linux-gnueabihf
|
||||
arm-linux-gnueabihf-strip *.node
|
||||
- host: ubuntu-18.04
|
||||
- host: ubuntu-20.04
|
||||
architecture: x64
|
||||
target: aarch64-unknown-linux-musl
|
||||
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine
|
||||
@@ -84,14 +88,10 @@ jobs:
|
||||
rustup target add aarch64-unknown-linux-musl
|
||||
yarn build:release --target aarch64-unknown-linux-musl
|
||||
/aarch64-linux-musl-cross/bin/aarch64-linux-musl-strip *.node
|
||||
#- host: windows-latest
|
||||
# architecture: x64
|
||||
# target: aarch64-pc-windows-msvc
|
||||
# build: yarn build:release --target aarch64-pc-windows-msvc
|
||||
name: stable - ${{ matrix.settings.target }} - node@16
|
||||
runs-on: ${{ matrix.settings.host }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v3
|
||||
if: ${{ !matrix.settings.docker }}
|
||||
@@ -101,14 +101,11 @@ jobs:
|
||||
cache: yarn
|
||||
cache-dependency-path: 'tooling/cli/node/yarn.lock'
|
||||
architecture: ${{ matrix.settings.architecture }}
|
||||
- name: Install
|
||||
uses: actions-rs/toolchain@v1
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
if: ${{ !matrix.settings.docker }}
|
||||
with:
|
||||
profile: minimal
|
||||
override: true
|
||||
toolchain: stable
|
||||
target: ${{ matrix.settings.target }}
|
||||
targets: ${{ matrix.settings.target }}
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
with:
|
||||
key: ${{ matrix.settings.target }}
|
||||
@@ -144,7 +141,7 @@ jobs:
|
||||
# runs-on: macos-10.15
|
||||
# name: Build FreeBSD
|
||||
# steps:
|
||||
# - uses: actions/checkout@v3
|
||||
# - uses: actions/checkout@v4
|
||||
# - name: Build
|
||||
# id: build
|
||||
# uses: vmactions/freebsd-vm@v0.1.6
|
||||
@@ -207,7 +204,7 @@ jobs:
|
||||
- '18'
|
||||
runs-on: ${{ matrix.settings.host }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
@@ -240,7 +237,7 @@ jobs:
|
||||
- '18'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
@@ -261,7 +258,7 @@ jobs:
|
||||
- name: install system dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y webkit2gtk-4.0 libayatana-appindicator3-dev
|
||||
sudo apt-get install -y webkit2gtk-4.1 libayatana-appindicator3-dev
|
||||
- name: Test bindings
|
||||
run: yarn test
|
||||
test-linux-x64-musl-binding:
|
||||
@@ -279,7 +276,7 @@ jobs:
|
||||
container:
|
||||
image: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
@@ -297,14 +294,10 @@ jobs:
|
||||
- name: List packages
|
||||
run: ls -R .
|
||||
shell: bash
|
||||
- name: Install system dependencies
|
||||
run: |
|
||||
apk add openssl-dev musl-dev glib-dev cairo-dev pkgconfig gdk-pixbuf-dev webkit2gtk-dev curl libappindicator-dev gtk+3.0-dev
|
||||
- name: Setup and run tests
|
||||
run: |
|
||||
yarn tauri --help
|
||||
ls -la
|
||||
# TODO: fix this test: https://github.com/tauri-apps/tauri/runs/5145729140?check_suite_focus=true#step:9:704
|
||||
#- name: Setup and run tests
|
||||
# run: |
|
||||
# rustup install stable
|
||||
@@ -329,7 +322,7 @@ jobs:
|
||||
steps:
|
||||
- run: docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
||||
working-directory: ${{ github.workspace }}
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: List packages
|
||||
run: ls -R .
|
||||
shell: bash
|
||||
@@ -355,7 +348,7 @@ jobs:
|
||||
set -e
|
||||
export PATH=/usr/local/cargo/bin/:/usr/local/fnm:$PATH
|
||||
apt-get update
|
||||
DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get install --no-install-recommends -y unzip webkit2gtk-4.0 libayatana-appindicator3-dev
|
||||
DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get install --no-install-recommends -y unzip libayatana-appindicator3-dev
|
||||
bash
|
||||
curl https://sh.rustup.rs -sSf | bash -s -- -y
|
||||
curl -fsSL https://fnm.vercel.app/install | bash -s -- --install-dir "/usr/local/fnm" --skip-shell
|
||||
@@ -375,7 +368,7 @@ jobs:
|
||||
- test-linux-x64-musl-binding
|
||||
#- test-linux-arm-bindings
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
@@ -397,8 +390,8 @@ jobs:
|
||||
- name: Publish
|
||||
run: |
|
||||
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc
|
||||
npm publish
|
||||
npm publish --tag next
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
NPM_TOKEN: ${{ secrets.ORG_NPM_TOKEN }}
|
||||
RELEASE_ID: ${{ github.event.client_payload.releaseId || github.event.inputs.releaseId }}
|
||||
RELEASE_ID: ${{ github.event.client_payload.releaseId || inputs.releaseId }}
|
||||
|
||||
30
.github/workflows/publish-cli-rs.yml
vendored
30
.github/workflows/publish-cli-rs.yml
vendored
@@ -2,7 +2,7 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: publish cli.rs
|
||||
name: publish `tauri-cli`
|
||||
env:
|
||||
MACOSX_DEPLOYMENT_TARGET: '10.13'
|
||||
on:
|
||||
@@ -18,28 +18,35 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
config:
|
||||
- os: ubuntu-18.04
|
||||
- os: ubuntu-20.04
|
||||
rust_target: x86_64-unknown-linux-gnu
|
||||
ext: ''
|
||||
args: ''
|
||||
- os: macos-latest
|
||||
rust_target: x86_64-apple-darwin
|
||||
ext: ''
|
||||
args: ''
|
||||
- os: macos-latest
|
||||
rust_target: aarch64-apple-darwin
|
||||
ext: ''
|
||||
args: ''
|
||||
- os: windows-latest
|
||||
rust_target: x86_64-pc-windows-msvc
|
||||
ext: '.exe'
|
||||
args: ''
|
||||
- os: windows-latest
|
||||
rust_target: aarch64-pc-windows-msvc
|
||||
ext: '.exe'
|
||||
args: '--no-default-features --features native-tls-vendored'
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: 'Setup Rust'
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
targets: ${{ matrix.config.rust_target }}
|
||||
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
key: ${{ matrix.config.rust_target }}
|
||||
@@ -51,16 +58,13 @@ jobs:
|
||||
sudo apt-get install -y libgtk-3-dev
|
||||
|
||||
- name: Build CLI
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: build
|
||||
args: --manifest-path ./tooling/cli/Cargo.toml --release
|
||||
run: cargo build --manifest-path ./tooling/cli/Cargo.toml --profile release-size-optimized ${{ matrix.config.args }}
|
||||
|
||||
- name: Upload CLI
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: cargo-tauri-${{ matrix.config.rust_target }}${{ matrix.config.ext }}
|
||||
path: tooling/cli/target/release/cargo-tauri${{ matrix.config.ext }}
|
||||
path: tooling/cli/target/release-size-optimized/cargo-tauri${{ matrix.config.ext }}
|
||||
if-no-files-found: error
|
||||
|
||||
upload:
|
||||
@@ -69,7 +73,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Download built CLIs
|
||||
uses: actions/download-artifact@v3
|
||||
@@ -80,12 +84,12 @@ jobs:
|
||||
run: ./.scripts/ci/pack-cli.sh
|
||||
|
||||
- name: Get CLI version
|
||||
run: echo "CLI_VERSION=$(cat tooling/cli/metadata.json | jq '."cli.js".version' -r)" >> $GITHUB_ENV
|
||||
run: echo "CLI_VERSION=$(cat tooling/cli/metadata-v2.json | jq '."cli.js".version' -r)" >> $GITHUB_ENV
|
||||
|
||||
- name: Publish release
|
||||
uses: softprops/action-gh-release@50195ba7f6f93d1ac97ba8332a178e008ad176aa
|
||||
with:
|
||||
tag_name: cli.rs-v${{ env.CLI_VERSION }}
|
||||
tag_name: tauri-cli-v${{ env.CLI_VERSION }}
|
||||
files: |
|
||||
outputs/cargo-tauri-*.zip
|
||||
outputs/cargo-tauri-*.tgz
|
||||
|
||||
106
.github/workflows/test-android.yml
vendored
Normal file
106
.github/workflows/test-android.yml
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: test android
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/test-android.yml'
|
||||
- 'tooling/cli/templates/mobile/android/**'
|
||||
- 'tooling/cli/src/mobile/**'
|
||||
- '!tooling/cli/src/mobile/ios.rs'
|
||||
- '!tooling/cli/src/mobile/ios/**'
|
||||
- 'core/tauri-build/src/mobile.rs'
|
||||
- 'core/tauri/mobile/android/**'
|
||||
- 'core/tauri/mobile/android-codegen/**'
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ${{ matrix.platform }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [ubuntu-latest, macos-latest, windows-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: install Rust stable
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- name: install Linux dependencies
|
||||
if: matrix.platform == 'ubuntu-latest'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libgtk-3-dev webkit2gtk-4.1
|
||||
|
||||
- name: setup node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
cache: yarn
|
||||
cache-dependency-path: |
|
||||
tooling/api/yarn.lock
|
||||
examples/api/yarn.lock
|
||||
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 17
|
||||
cache: gradle
|
||||
|
||||
- name: Setup NDK
|
||||
uses: nttld/setup-ndk@v1
|
||||
id: setup-ndk
|
||||
with:
|
||||
ndk-version: r25b
|
||||
local-cache: true
|
||||
|
||||
# TODO check after https://github.com/nttld/setup-ndk/issues/518 is fixed
|
||||
- name: Restore Android Symlinks
|
||||
if: matrix.platform == 'ubuntu-latest' || matrix.platform == 'macos-latest'
|
||||
run: |
|
||||
directory="${{ steps.setup-ndk.outputs.ndk-path }}/toolchains/llvm/prebuilt/linux-x86_64/bin"
|
||||
find "$directory" -type l | while read link; do
|
||||
current_target=$(readlink "$link")
|
||||
new_target="$directory/$(basename "$current_target")"
|
||||
ln -sf "$new_target" "$link"
|
||||
echo "Changed $(basename "$link") from $current_target to $new_target"
|
||||
done
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: |
|
||||
tooling/cli
|
||||
examples/api/src-tauri
|
||||
|
||||
- name: build CLI
|
||||
run: cargo build --manifest-path ./tooling/cli/Cargo.toml
|
||||
|
||||
- name: build Tauri API
|
||||
working-directory: ./tooling/api
|
||||
run: yarn && yarn build
|
||||
|
||||
- name: install API example dependencies
|
||||
working-directory: ./examples/api
|
||||
run: yarn
|
||||
|
||||
- name: init Android Studio project
|
||||
working-directory: ./examples/api
|
||||
run: ../../tooling/cli/target/debug/cargo-tauri android init
|
||||
env:
|
||||
NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
|
||||
|
||||
- name: build APK
|
||||
working-directory: ./examples/api
|
||||
run: ../../tooling/cli/target/debug/cargo-tauri android build
|
||||
env:
|
||||
NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
|
||||
20
.github/workflows/test-cli-js.yml
vendored
20
.github/workflows/test-cli-js.yml
vendored
@@ -2,17 +2,17 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: test cli.js
|
||||
name: test `@tauri-apps/cli`
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
- next
|
||||
- 1.x
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/test-cli-js.yml'
|
||||
# currently cli.js only tests the template
|
||||
# currently` @tauri-apps/cli` only tests the template
|
||||
- 'tooling/cli/templates/app/**'
|
||||
|
||||
env:
|
||||
@@ -24,7 +24,7 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test-tauri-js-cli:
|
||||
test:
|
||||
runs-on: ${{ matrix.platform }}
|
||||
|
||||
strategy:
|
||||
@@ -33,17 +33,15 @@ jobs:
|
||||
platform: [ubuntu-latest, macos-latest, windows-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: install Rust stable
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- name: setup node
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 14
|
||||
node-version: 18
|
||||
cache: yarn
|
||||
cache-dependency-path: tooling/cli/node/yarn.lock
|
||||
|
||||
@@ -51,7 +49,7 @@ jobs:
|
||||
if: matrix.platform == 'ubuntu-latest'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y webkit2gtk-4.0 libayatana-appindicator3-dev
|
||||
sudo apt-get install -y webkit2gtk-4.1 libayatana-appindicator3-dev
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
|
||||
47
.github/workflows/test-cli-rs.yml
vendored
47
.github/workflows/test-cli-rs.yml
vendored
@@ -2,16 +2,18 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: test cli.rs
|
||||
name: test `tauri-cli`
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
- next
|
||||
- 1.x
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/test-cli-rs.yml'
|
||||
- 'core/tauri-utils/**'
|
||||
- 'tooling/bundler/**'
|
||||
- 'tooling/cli/**'
|
||||
|
||||
env:
|
||||
@@ -23,25 +25,41 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test-tauri-cli:
|
||||
runs-on: ${{ matrix.platform }}
|
||||
test:
|
||||
runs-on: ${{ matrix.platform.os }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [ubuntu-latest, macos-latest, windows-latest]
|
||||
platform:
|
||||
- {
|
||||
target: x86_64-pc-windows-msvc,
|
||||
os: windows-latest
|
||||
}
|
||||
- {
|
||||
target: aarch64-pc-windows-msvc,
|
||||
os: windows-latest,
|
||||
args: --no-default-features --features native-tls-vendored
|
||||
}
|
||||
- {
|
||||
target: x86_64-unknown-linux-gnu,
|
||||
os: ubuntu-latest
|
||||
}
|
||||
- {
|
||||
target: x86_64-apple-darwin,
|
||||
os: macos-latest
|
||||
}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: install stable
|
||||
uses: actions-rs/toolchain@v1
|
||||
- name: 'Setup Rust'
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
targets: ${{ matrix.platform.target }}
|
||||
|
||||
- name: install Linux dependencies
|
||||
if: matrix.platform == 'ubuntu-latest'
|
||||
if: matrix.platform.os == 'ubuntu-latest'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libgtk-3-dev
|
||||
@@ -50,8 +68,5 @@ jobs:
|
||||
with:
|
||||
workspaces: tooling/cli
|
||||
|
||||
- name: build CLI
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: build
|
||||
args: --manifest-path ./tooling/cli/Cargo.toml
|
||||
- name: test CLI
|
||||
run: cargo test --manifest-path ./tooling/cli/Cargo.toml ${{ matrix.platform.args }}
|
||||
|
||||
70
.github/workflows/test-core.yml
vendored
70
.github/workflows/test-core.yml
vendored
@@ -8,7 +8,7 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
- next
|
||||
- 1.x
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/test-core.yml'
|
||||
@@ -24,7 +24,7 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test-tauri-core:
|
||||
test:
|
||||
runs-on: ${{ matrix.platform.os }}
|
||||
|
||||
strategy:
|
||||
@@ -34,53 +34,69 @@ jobs:
|
||||
- {
|
||||
target: x86_64-pc-windows-msvc,
|
||||
os: windows-latest,
|
||||
toolchain: '1.61.0'
|
||||
toolchain: '1.70.0',
|
||||
cross: false,
|
||||
command: 'test'
|
||||
}
|
||||
- {
|
||||
target: x86_64-unknown-linux-gnu,
|
||||
os: ubuntu-latest,
|
||||
toolchain: '1.60.0'
|
||||
toolchain: '1.70.0',
|
||||
cross: false,
|
||||
command: 'test'
|
||||
}
|
||||
- {
|
||||
target: x86_64-apple-darwin,
|
||||
target: aarch64-apple-darwin,
|
||||
os: macos-14,
|
||||
toolchain: '1.70.0',
|
||||
cross: false,
|
||||
command: 'test'
|
||||
}
|
||||
- {
|
||||
target: aarch64-apple-ios,
|
||||
os: macos-latest,
|
||||
toolchain: '1.60.0'
|
||||
toolchain: '1.70.0',
|
||||
cross: false,
|
||||
command: 'build'
|
||||
}
|
||||
- {
|
||||
target: aarch64-linux-android,
|
||||
os: ubuntu-latest,
|
||||
toolchain: '1.70.0',
|
||||
cross: true,
|
||||
command: 'build'
|
||||
}
|
||||
features:
|
||||
- {
|
||||
args: --no-default-features,
|
||||
key: no-default
|
||||
}
|
||||
- {
|
||||
args: --features api-all,
|
||||
key: api-all
|
||||
}
|
||||
- {
|
||||
args: --features compression,wry,linux-protocol-headers,isolation,custom-protocol,api-all,cli,updater,system-tray,windows7-compat,http-multipart,
|
||||
key: all
|
||||
}
|
||||
- { args: --no-default-features, key: no-default }
|
||||
- { args: --all-features, key: all }
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: install stable
|
||||
uses: actions-rs/toolchain@v1
|
||||
- name: install Rust
|
||||
uses: dtolnay/rust-toolchain@master
|
||||
with:
|
||||
toolchain: ${{ matrix.platform.toolchain }}
|
||||
target: ${{ matrix.platform.target }}
|
||||
override: true
|
||||
default: true
|
||||
targets: ${{ matrix.platform.target }}
|
||||
|
||||
- name: install Linux dependencies
|
||||
if: contains(matrix.platform.target, 'unknown-linux')
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y webkit2gtk-4.0 libayatana-appindicator3-dev
|
||||
sudo apt-get install -y webkit2gtk-4.1 libxdo-dev libayatana-appindicator3-dev
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
prefix-key: v2
|
||||
workspaces: core -> ../target
|
||||
save-if: ${{ matrix.features.key == 'all' }}
|
||||
|
||||
- name: test
|
||||
run: cargo test --target ${{ matrix.platform.target }} ${{ matrix.features.args }}
|
||||
- name: test (using cross)
|
||||
if: ${{ matrix.platform.cross }}
|
||||
run: |
|
||||
cargo install cross --git https://github.com/cross-rs/cross
|
||||
cross ${{ matrix.platform.command }} --target ${{ matrix.platform.target }} ${{ matrix.features.args }}
|
||||
|
||||
- name: test (using cargo)
|
||||
if: ${{ !matrix.platform.cross }}
|
||||
run: cargo ${{ matrix.platform.command }} --target ${{ matrix.platform.target }} ${{ matrix.features.args }}
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: test bundler
|
||||
name: test and lint bundler
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
- next
|
||||
- 1.x
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/test-bundler.yml'
|
||||
@@ -23,7 +23,7 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build-tauri-bundler:
|
||||
test:
|
||||
runs-on: ${{ matrix.platform }}
|
||||
|
||||
strategy:
|
||||
@@ -32,12 +32,10 @@ jobs:
|
||||
platform: [ubuntu-latest, macos-latest, windows-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: install stable
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
@@ -48,46 +46,34 @@ jobs:
|
||||
cd ./tooling/bundler
|
||||
cargo test
|
||||
|
||||
fmt_check:
|
||||
fmt:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions-rs/toolchain@v1
|
||||
- name: install Rust stable and rustfmt
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
components: rustfmt
|
||||
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: fmt
|
||||
args: --manifest-path ./tooling/bundler/Cargo.toml --all -- --check
|
||||
- name: Run cargo fmt
|
||||
run: cargo fmt --manifest-path ./tooling/bundler/Cargo.toml --all -- --check
|
||||
|
||||
clippy-check:
|
||||
clippy:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: install minimal stable with clippy and rustfmt
|
||||
uses: actions-rs/toolchain@v1
|
||||
- name: install Rust stable and clippy
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
default: true
|
||||
components: rustfmt, clippy
|
||||
components: clippy
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: tooling/bundler
|
||||
|
||||
- name: clippy check
|
||||
uses: actions-rs/clippy-check@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
args: --manifest-path ./tooling/bundler/Cargo.toml --all-targets -- -D warnings
|
||||
name: bundler
|
||||
run: cargo clippy --manifest-path ./tooling/bundler/Cargo.toml --all-targets -- -D warnings
|
||||
38
.github/workflows/udeps.yml
vendored
38
.github/workflows/udeps.yml
vendored
@@ -8,7 +8,7 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
- next
|
||||
- 1.x
|
||||
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
@@ -32,7 +32,7 @@ jobs:
|
||||
bundler: ${{ steps.filter.outputs.bundler }}
|
||||
cli: ${{ steps.filter.outputs.cli }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dorny/paths-filter@v2
|
||||
id: filter
|
||||
with:
|
||||
@@ -72,18 +72,13 @@ jobs:
|
||||
needs.changes.outputs.cli == 'true'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: nightly
|
||||
override: true
|
||||
- name: Install Rust nightly
|
||||
uses: dtolnay/rust-toolchain@nightly
|
||||
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: install
|
||||
args: cargo-udeps --locked --force
|
||||
- name: Install udeps
|
||||
run: cargo install cargo-udeps --locked --force
|
||||
|
||||
- name: Upload udeps
|
||||
uses: actions/upload-artifact@v3
|
||||
@@ -115,7 +110,7 @@ jobs:
|
||||
if [ "${UTILS}" == "true" ]; then crates[${#crates[@]}]="\"./core/tauri-utils\""; fi
|
||||
if [ "${BUNDLER}" == "true" ]; then crates[${#crates[@]}]="\"./tooling/bundler\""; fi
|
||||
if [ "${CLI}" == "true" ]; then crates[${#crates[@]}]="\"./tooling/cli\""; fi
|
||||
echo ::set-output name=matrix::[$crates]
|
||||
echo "matrix=[$crates]" >> "$GITHUB_OUTPUT"
|
||||
outputs:
|
||||
matrix: ${{ steps.create-matrix.outputs.matrix }}
|
||||
|
||||
@@ -126,13 +121,10 @@ jobs:
|
||||
matrix:
|
||||
path: ${{ fromJson(needs.setup.outputs.matrix) }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: nightly
|
||||
override: true
|
||||
- name: Install Rust nightly
|
||||
uses: dtolnay/rust-toolchain@nightly
|
||||
|
||||
- name: install dependencies
|
||||
run: |
|
||||
@@ -157,9 +149,7 @@ jobs:
|
||||
- name: Install required packages
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y webkit2gtk-4.0 libayatana-appindicator3-dev
|
||||
sudo apt-get install -y webkit2gtk-4.1 libayatana-appindicator3-dev
|
||||
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: udeps
|
||||
args: --manifest-path ${{ matrix.path }}/Cargo.toml --all-targets --all-features
|
||||
- name: Run udeps
|
||||
run: cargo udeps --manifest-path ${{ matrix.path }}/Cargo.toml --all-targets --all-features
|
||||
|
||||
@@ -11,12 +11,12 @@ if [ -z "$(git diff --name-only tooling/api)" ]; then
|
||||
else
|
||||
cd tooling/api
|
||||
yarn format
|
||||
yarn lint-fix
|
||||
yarn lint:fix
|
||||
cd ../..
|
||||
fi
|
||||
|
||||
if [ -z "$(git diff --name-only tooling/cli/node)" ]; then
|
||||
echo "skipping cli.js - no changes detected"
|
||||
echo "skipping \`@tauri-apps/cli\` - no changes detected"
|
||||
else
|
||||
cd tooling/cli/node
|
||||
yarn format
|
||||
|
||||
@@ -5,9 +5,12 @@
|
||||
node_modules
|
||||
target
|
||||
dist
|
||||
/core/tauri/scripts
|
||||
/core/tauri/scripts/bundle.global.js
|
||||
/tooling/cli/templates
|
||||
/tooling/cli/node
|
||||
/tooling/cli/schema.json
|
||||
/tooling/api/docs/js-api.json
|
||||
/core/tauri-config-schema/schema.json
|
||||
CHANGELOG.md
|
||||
*.wxs
|
||||
**/reference.md
|
||||
*schema.json
|
||||
5
.prettierrc
Normal file
5
.prettierrc
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"singleQuote": true,
|
||||
"semi": false,
|
||||
"trailingComma": "none"
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env pwsh
|
||||
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
79
.scripts/ci/check-change-tags.js
Normal file
79
.scripts/ci/check-change-tags.js
Normal file
@@ -0,0 +1,79 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const ignorePackages = [
|
||||
'tauri-macros',
|
||||
'tauri-codegen',
|
||||
'tauri-runtime',
|
||||
'tauri-runtime-wry',
|
||||
'tauri-driver'
|
||||
]
|
||||
|
||||
const covectorConfig = JSON.parse(
|
||||
fs.readFileSync('.changes/config.json', 'utf8')
|
||||
)
|
||||
const tags = Object.keys(covectorConfig.changeTags)
|
||||
|
||||
const missingTagsFiles = {}
|
||||
const unknownTagsFiles = {}
|
||||
|
||||
function checkChangeFiles(changeFiles) {
|
||||
for (const file of changeFiles) {
|
||||
const content = fs.readFileSync(file, 'utf8')
|
||||
const [frontMatter] = /^---[\s\S.]*---\n/i.exec(content)
|
||||
const packages = frontMatter
|
||||
.split('\n')
|
||||
.filter((l) => !(l === '---' || !l))
|
||||
.map((l) => l.replace(/('|")/g, '').split(':'))
|
||||
|
||||
for (const [package, _, tag] of packages) {
|
||||
if (!tag) {
|
||||
if (ignorePackages.includes(package)) continue
|
||||
|
||||
if (!missingTagsFiles[file]) missingTagsFiles[file] = []
|
||||
missingTagsFiles[file].push(package)
|
||||
} else if (!tags.includes(tag)) {
|
||||
if (!unknownTagsFiles[file]) unknownTagsFiles[file] = []
|
||||
unknownTagsFiles[file].push({ package, tag })
|
||||
}
|
||||
}
|
||||
}
|
||||
const missingTagsEntries = Object.entries(missingTagsFiles)
|
||||
const unknownTagsEntries = Object.entries(unknownTagsFiles)
|
||||
if (missingTagsEntries.length > 0 || unknownTagsEntries.length > 0) {
|
||||
for (const [file, packages] of missingTagsEntries) {
|
||||
for (const package of packages) {
|
||||
console.error(
|
||||
`Package \`${package}\` is missing a change tag in ${file} `
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
for (const [file, packages] of unknownTagsEntries) {
|
||||
for (const { package, tag } of packages) {
|
||||
console.error(
|
||||
`Package \`${package}\` has an uknown change tag ${tag} in ${file} `
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
const [_bin, _script, ...files] = process.argv
|
||||
|
||||
if (files.length > 0) {
|
||||
checkChangeFiles(files.filter((f) => f.toLowerCase() !== 'readme.md'))
|
||||
} else {
|
||||
const changeFiles = fs
|
||||
.readdirSync('.changes')
|
||||
.filter((f) => f.endsWith('.md') && f.toLowerCase() !== 'readme.md')
|
||||
.map((p) => path.join('.changes', p))
|
||||
checkChangeFiles(changeFiles)
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
@@ -9,13 +11,26 @@ const readline = require('readline')
|
||||
const header = `Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
SPDX-License-Identifier: MIT`
|
||||
const bundlerLicense = '// Copyright 2016-2019 Cargo-Bundle developers <https://github.com/burtonageo/cargo-bundle>'
|
||||
const bundlerLicense =
|
||||
'// Copyright 2016-2019 Cargo-Bundle developers <https://github.com/burtonageo/cargo-bundle>'
|
||||
const denoLicense =
|
||||
'// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.'
|
||||
|
||||
const extensions = ['.rs', '.js', '.ts', '.yml']
|
||||
const ignore = ['target', 'templates', 'node_modules', 'gen', 'dist', 'bundle.js', 'bundle.global.js']
|
||||
const extensions = ['.rs', '.js', '.ts', '.yml', '.swift', '.kt']
|
||||
const ignore = [
|
||||
'target',
|
||||
'templates',
|
||||
'node_modules',
|
||||
'gen',
|
||||
'dist',
|
||||
'bundle.global.js'
|
||||
]
|
||||
|
||||
async function checkFile(file) {
|
||||
if (extensions.some(e => file.endsWith(e))) {
|
||||
if (
|
||||
extensions.some((e) => file.endsWith(e)) &&
|
||||
!ignore.some((i) => file.includes(`/${i}/`) || path.basename(file) == i)
|
||||
) {
|
||||
const fileStream = fs.createReadStream(file)
|
||||
const rl = readline.createInterface({
|
||||
input: fileStream,
|
||||
@@ -26,7 +41,13 @@ async function checkFile(file) {
|
||||
let i = 0
|
||||
for await (let line of rl) {
|
||||
// ignore empty lines, allow shebang and bundler license
|
||||
if (line.length === 0 || line.startsWith("#!") || line === bundlerLicense) {
|
||||
if (
|
||||
line.length === 0 ||
|
||||
line.startsWith('#!') ||
|
||||
line.startsWith('// swift-tools-version:') ||
|
||||
line === bundlerLicense ||
|
||||
line === denoLicense
|
||||
) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -93,7 +114,7 @@ if (files.length > 0) {
|
||||
|
||||
run()
|
||||
} else {
|
||||
check('.').then(missing => {
|
||||
check('.').then((missing) => {
|
||||
if (missing.length > 0) {
|
||||
console.log(missing.join('\n'))
|
||||
process.exit(1)
|
||||
@@ -1,5 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
if git diff --quiet --ignore-submodules HEAD
|
||||
then
|
||||
echo "working directory is clean"
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
for o in outputs/*; do
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
@@ -44,7 +45,8 @@ https.get(url, options, (response) => {
|
||||
response.on('end', function () {
|
||||
const data = JSON.parse(chunks.join(''))
|
||||
if (kind === 'cargo') {
|
||||
const versions = data.versions.filter((v) => v.num.startsWith(target))
|
||||
const versions =
|
||||
data.versions?.filter((v) => v.num.startsWith(target)) ?? []
|
||||
console.log(versions.length ? versions[0].num : '0.0.0')
|
||||
} else if (kind === 'npm') {
|
||||
const versions = Object.keys(data.versions).filter((v) =>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
@@ -6,22 +7,24 @@
|
||||
/*
|
||||
This script is solely intended to be run as part of the `covector version` step to
|
||||
keep the `../tooling/cli/metadata.json` up to date with other version bumps. Long term
|
||||
we should look to find a more "rusty way" to import / "pin" a version value in our cli.rs
|
||||
we should look to find a more "rusty way" to import / "pin" a version value in our tauri-cli
|
||||
rust binaries.
|
||||
*/
|
||||
|
||||
const { readFileSync, writeFileSync } = require('fs')
|
||||
const { resolve } = require('path')
|
||||
|
||||
const packageNickname = process.argv[2]
|
||||
const filePath =
|
||||
packageNickname === 'cli.js'
|
||||
? `../../../tooling/cli/metadata.json`
|
||||
: `../../tooling/cli/metadata.json`
|
||||
packageNickname === '@tauri-apps/cli'
|
||||
? `../../../tooling/cli/metadata-v2.json`
|
||||
: `../../tooling/cli/metadata-v2.json`
|
||||
const bump = process.argv[3]
|
||||
let index = null
|
||||
|
||||
switch (bump) {
|
||||
case 'major':
|
||||
case 'premajor':
|
||||
index = 0
|
||||
break
|
||||
case 'minor':
|
||||
@@ -30,6 +33,9 @@ switch (bump) {
|
||||
case 'patch':
|
||||
index = 2
|
||||
break
|
||||
case 'prerelease':
|
||||
index = 3
|
||||
break
|
||||
default:
|
||||
throw new Error('unexpected bump ' + bump)
|
||||
}
|
||||
@@ -43,6 +49,12 @@ const inc = (version) => {
|
||||
v[i] = 0
|
||||
}
|
||||
}
|
||||
if (bump === 'premajor') {
|
||||
const pre = JSON.parse(
|
||||
readFileSync(resolve(filePath, '../../../.changes/pre.json'), 'utf-8')
|
||||
)
|
||||
return `${v.join('.')}-${pre.tag}.0`
|
||||
}
|
||||
return v.join('.')
|
||||
}
|
||||
|
||||
@@ -51,14 +63,14 @@ const metadata = JSON.parse(readFileSync(filePath, 'utf-8'))
|
||||
|
||||
// set field version
|
||||
let version
|
||||
if (packageNickname === 'cli.js') {
|
||||
version = inc(metadata[packageNickname].version)
|
||||
metadata[packageNickname].version = version
|
||||
if (packageNickname === '@tauri-apps/cli') {
|
||||
version = inc(metadata['cli.js'].version)
|
||||
metadata['cli.js'].version = version
|
||||
} else {
|
||||
version = inc(metadata[packageNickname])
|
||||
metadata[packageNickname] = version
|
||||
}
|
||||
|
||||
writeFileSync(filePath, JSON.stringify(metadata, null, 2) + '\n')
|
||||
console.log(`wrote ${version} for ${packageNickname} into metadata.json`)
|
||||
console.log(`wrote ${version} for ${packageNickname} into metadata-v2.json`)
|
||||
console.dir(metadata)
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
docker build -t aarch64-unknown-linux-gnu:latest --file .docker/cross/aarch64.Dockerfile .docker/cross
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env pwsh
|
||||
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
declare -a examples=("api" "sidecar" "updater" "resources" "tauri-dynamic-lib" "workspace")
|
||||
declare -a examples=("api" "sidecar" "resources" "tauri-dynamic-lib" "workspace")
|
||||
declare -a tooling=("bench" "cli" "webdriver")
|
||||
|
||||
for example in "${examples[@]}"
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
: Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
: SPDX-License-Identifier: Apache-2.0
|
||||
: SPDX-License-Identifier: MIT
|
||||
|
||||
@ECHO OFF
|
||||
|
||||
REM Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
|
||||
@@ -1,106 +1,132 @@
|
||||
# The Tauri Architecture
|
||||
|
||||
https://tauri.app
|
||||
|
||||
https://github.com/tauri-apps/tauri
|
||||
|
||||
## Introduction
|
||||
|
||||
Tauri is a polyglot and generic toolkit that is very composable and allows engineers to make a wide variety of applications. It is used for building applications for Desktop Computers using a combination of Rust tools and HTML rendered in a Webview. Apps built with Tauri can ship with any number of pieces of an optional JS API / Rust API so that webviews can control the system via message passing. In fact, developers can extend the default API with their own functionality and bridge the Webview and Rust-based backend easily.
|
||||
|
||||
Tauri apps can have custom menus and have tray-type interfaces. They can be updated, and are managed by the user's operating system as expected. They are very small, because they use the OS's webview. They do not ship a runtime, since the final binary is compiled from Rust. This makes the reversing of Tauri apps not a trivial task.
|
||||
|
||||
## What Tauri is NOT
|
||||
|
||||
- Tauri is not a lightweight kernel wrapper...instead it directly uses [WRY](#wry) and [TAO](#tao) to do the heavy-lifting in making system calls to the OS.
|
||||
- Tauri is not a VM or virtualized environment...instead it is an application toolkit that allows making Webview OS applications.
|
||||
|
||||
## Major Components
|
||||
|
||||
The following section briefly describes the roles of the various parts of Tauri.
|
||||
|
||||
### Tauri Core [STABLE RUST]
|
||||
|
||||
#### [tauri](https://github.com/tauri-apps/tauri/tree/dev/core/tauri)
|
||||
|
||||
This is the major crate that holds everything together. It brings the runtimes, macros, utilities and API into one final product. It reads the `tauri.conf.json` file at compile time in order to bring in features and undertake actual configuration of the app (and even the `Cargo.toml` file in the project's folder). It handles script injection (for polyfills / prototype revision) at runtime, hosts the API for systems interaction, and even manages updating.
|
||||
|
||||
#### [tauri-build](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-build)
|
||||
|
||||
Apply the macros at build-time in order to rig some special features needed by `cargo`.
|
||||
|
||||
#### [tauri-codegen](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-codegen)
|
||||
|
||||
- Embed, hash, and compress assets, including icons for the app as well as the system-tray.
|
||||
- Parse `tauri.conf.json` at compile time and generate the Config struct.
|
||||
|
||||
#### [tauri-macros](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-macros)
|
||||
|
||||
Create macros for the context, handler, and commands by leveraging the `tauri-codegen` crate.
|
||||
|
||||
#### [tauri-runtime](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-runtime)
|
||||
|
||||
This is the glue layer between tauri itself and lower level webview libraries.
|
||||
|
||||
#### [tauri-runtime-wry](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-runtime-wry)
|
||||
|
||||
This crate opens up direct systems-level interactions specifically for WRY, such as printing, monitor detection, and other windowing related tasks. `tauri-runtime` implementation for WRY.
|
||||
|
||||
#### [tauri-utils](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-utils)
|
||||
|
||||
This is common code that is reused in many places and offers useful utilities like parsing configuration files, detecting platform triples, injecting the CSP, and managing assets.
|
||||
|
||||
|
||||
### Tauri Tooling
|
||||
#### [api](https://github.com/tauri-apps/tauri/tree/dev/tooling/api) [TS -> JS]
|
||||
|
||||
#### [@tauri-apps/api](https://github.com/tauri-apps/tauri/tree/dev/tooling/api) [TS -> JS]
|
||||
|
||||
A TypeScript library that creates `cjs` and `esm` JavaScript endpoints for you to import into your Frontend framework so that the Webview can call and listen to backend activity. We also ship the pure TypeScript, because for some frameworks this is more optimal. It uses the message passing of webviews to their hosts.
|
||||
|
||||
#### [bundler](https://github.com/tauri-apps/tauri/tree/dev/tooling/bundler) [RUST / SHELL]
|
||||
|
||||
The bundler is a library that builds a Tauri App for the platform triple it detects / is told. At the moment it currently supports macOS, Windows and Linux - but in the near future will support mobile platforms as well. May be used outside of Tauri projects.
|
||||
|
||||
#### [cli.js](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli/node) [JS]
|
||||
It is a wrapper around [cli.rs](https://github.com/tauri-apps/tauri/blob/dev/tooling/cli) using [napi-rs](https://github.com/napi-rs/napi-rs) to produce NPM packages for each platform.
|
||||
#### [@tauri-apps/cli](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli/node) [JS]
|
||||
|
||||
It is a wrapper around [tauri-cli](https://github.com/tauri-apps/tauri/blob/dev/tooling/cli) using [napi-rs](https://github.com/napi-rs/napi-rs) to produce NPM packages for each platform.
|
||||
|
||||
#### [tauri-cli](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli) [RUST]
|
||||
|
||||
#### [cli.rs](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli) [RUST]
|
||||
This rust executable provides the full interface to all of the required activities for which the CLI is required. It will run on macOS, Windows, and Linux.
|
||||
|
||||
#### [create-tauri-app](https://github.com/tauri-apps/create-tauri-app) [JS]
|
||||
|
||||
This is a toolkit that will enable engineering teams to rapidly scaffold out a new tauri-apps project using the frontend framework of their choice (as long as it has been configured).
|
||||
|
||||
# External Crates
|
||||
|
||||
The Tauri-Apps organisation maintains two "upstream" crates from Tauri, namely TAO for creating and managing application windows, and WRY for interfacing with the Webview that lives within the window.
|
||||
|
||||
## [TAO](https://github.com/tauri-apps/tao)
|
||||
|
||||
Cross-platform application window creation library in Rust that supports all major platforms like Windows, macOS, Linux, iOS and Android. Written in Rust, it is a fork of [winit](https://github.com/rust-windowing/winit) that we have extended for our own needs like menu bar and system tray.
|
||||
|
||||
|
||||
## [WRY](https://github.com/tauri-apps/wry)
|
||||
|
||||
WRY is a cross-platform WebView rendering library in Rust that supports all major desktop platforms like Windows, macOS, and Linux.
|
||||
Tauri uses WRY as the abstract layer responsible to determine which webview is used (and how interactions are made).
|
||||
|
||||
# Additional tooling
|
||||
|
||||
## [binary-releases](https://github.com/tauri-apps/binary-releases)
|
||||
This is the delivery mechanism for tauri prebuilt binaries: currently the cli.rs (used by cli.js) and rustup binaries (used by the deps install command of cli.js). These artifacts are automatically created on release.
|
||||
|
||||
## [tauri-action](https://github.com/tauri-apps/tauri-action)
|
||||
|
||||
This is a github workflow that builds tauri binaries for all platforms. It is not the fastest out there, but it gets the job done and is highly configurable. Even allowing you to create a (very basic) tauri app even if tauri is not setup.
|
||||
|
||||
## [create-pull-request](https://github.com/tauri-apps/create-pull-request)
|
||||
|
||||
Because this is a very risky (potentially destructive) github action, we forked it in order to have strong guarantees that the code we think is running is actually the code that is running.
|
||||
|
||||
## [vue-cli-plugin-tauri](https://github.com/tauri-apps/vue-cli-plugin-tauri)
|
||||
|
||||
This plugin allows you to very quickly install tauri in a vue-cli project.
|
||||
|
||||
## [tauri-vscode](https://github.com/tauri-apps/tauri-vscode)
|
||||
|
||||
This project enhances the VS Code interface with several nice-to-have features.
|
||||
|
||||
# Tauri Plugins [documentation](https://tauri.app/v1/guides/features/plugin/)
|
||||
|
||||
Generally speaking, plugins are authored by third parties (even though there may be official, supported plugins). A plugin generally does 3 things:
|
||||
|
||||
1. It provides rust code to do "something".
|
||||
2. It provides interface glue to make it easy to integrate into an app.
|
||||
3. It provides a JS API for interfacing with the rust code.
|
||||
|
||||
Here are several examples of Tauri Plugins:
|
||||
|
||||
- https://github.com/tauri-apps/tauri-plugin-sql
|
||||
- https://github.com/tauri-apps/tauri-plugin-stronghold
|
||||
- https://github.com/tauri-apps/tauri-plugin-authenticator
|
||||
|
||||
# Workflows
|
||||
|
||||
## What does the Development flow look like?
|
||||
|
||||
A developer must first install the prerequisite toolchains for creating a Tauri app. At the very least this will entail installing rust & cargo, and most likely also a modern version of node.js and potentially another package manager. Some platforms may also require other tooling and libraries, but this has been documented carefully in the respective platform docs.
|
||||
|
||||
Because of the many ways to build front-ends, we will stick with a common node.js based approach for development. (Note: Tauri does not by default ship a node.js runtime.)
|
||||
|
||||
The easiest way to do this is to run the following:
|
||||
|
||||
```
|
||||
npx create-tauri-app
|
||||
```
|
||||
@@ -110,16 +136,19 @@ Which will ask you a bunch of questions about the framework you want to install
|
||||
> If you don't use this process, you will have to manually install the tauri cli, initialise tauri and manually configure the `tauri.conf.json` file.
|
||||
|
||||
Once everything is installed, you can run:
|
||||
|
||||
```
|
||||
yarn tauri dev
|
||||
-or-
|
||||
npm run tauri dev
|
||||
```
|
||||
|
||||
This will do several things:
|
||||
|
||||
1. start the JS Framework devserver
|
||||
2. begin the long process of downloading and compiling the rust libraries
|
||||
3. open an application window with devtools enabled
|
||||
4. keep a long-lived console alive
|
||||
4. keep a long-lived console alive
|
||||
|
||||
If you change your HTML/CSS/TS/JS, your framework devserver should give you its best shot at instant hot module reloading and you will see the changes instantly.
|
||||
|
||||
@@ -131,7 +160,6 @@ If you need to get deeper insight into your current project, or triage requires
|
||||
yarn tauri info
|
||||
```
|
||||
|
||||
|
||||
## What does the Release flow look like?
|
||||
|
||||
The release flow begins with proper configuration in the `tauri.conf.json` file. In this file, the developer can configure not only the basic behaviour of the application (like window size and decoration), they can also provide settings for signing and updating.
|
||||
@@ -139,6 +167,7 @@ The release flow begins with proper configuration in the `tauri.conf.json` file.
|
||||
Depending upon the operating system that the developer (or CI) is building the application on, there will be an app built for them for that system. (Cross compilation is not currently available, however there is an official [GitHub Action](https://github.com/tauri-apps/tauri-action) that can be used to build for all platforms.)
|
||||
|
||||
To kick off this process, just:
|
||||
|
||||
```
|
||||
yarn tauri build
|
||||
```
|
||||
@@ -146,14 +175,17 @@ yarn tauri build
|
||||
After some time, the process will end and you can see the results in the `./src-tauri/target/release` folder.
|
||||
|
||||
## What does the End-User flow look like?
|
||||
|
||||
End users will be provided with binaries in ways that are appropriate for their systems. Whether macOS, Linux, or Windows, direct download or store installations - they will be able to follow procedures for installing and removing that they are used to.
|
||||
|
||||
## What does the Updating flow look like?
|
||||
When a new version is ready, the developer publishes the new signed artifacts to a server (that they have configured within `tauri.conf.json`).
|
||||
|
||||
When a new version is ready, the developer publishes the new signed artifacts to a server (that they have configured within `tauri.conf.json`).
|
||||
|
||||
The application can poll this server to see if there is a new release. When there is a new release, the user is prompted to update. The application update is downloaded, verified (checksum & signature), updated, closed, and restarted.
|
||||
|
||||
## License
|
||||
|
||||
Tauri itself is licensed under MIT or Apache-2.0. If you repackage it and modify any source code, it is your responsibility to verify that you are complying with all upstream licenses. Tauri is provided AS-IS with no explicit claim for suitability for any purpose.
|
||||
|
||||
Here you may peruse our [Software Bill of Materials](https://app.fossa.com/projects/git%2Bgithub.com%2Ftauri-apps%2Ftauri).
|
||||
|
||||
17
Cargo.toml
17
Cargo.toml
@@ -1,4 +1,5 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
# core
|
||||
"core/tauri",
|
||||
@@ -9,22 +10,32 @@ members = [
|
||||
"core/tauri-build",
|
||||
"core/tauri-codegen",
|
||||
"core/tauri-config-schema",
|
||||
"core/tauri-plugin",
|
||||
|
||||
# integration tests
|
||||
"core/tests/restart",
|
||||
"core/tests/app-updater",
|
||||
"core/tests/acl",
|
||||
]
|
||||
|
||||
exclude = [
|
||||
# examples that can be compiled with the tauri CLI
|
||||
"examples/api/src-tauri",
|
||||
"examples/updater/src-tauri",
|
||||
"examples/resources/src-tauri",
|
||||
"examples/sidecar/src-tauri",
|
||||
"examples/web/core",
|
||||
"examples/file-associations/src-tauri",
|
||||
"examples/workspace",
|
||||
"examples/plugins/tauri-plugin-example",
|
||||
]
|
||||
|
||||
[workspace.package]
|
||||
authors = ["Tauri Programme within The Commons Conservancy"]
|
||||
homepage = "https://tauri.app/"
|
||||
repository = "https://github.com/tauri-apps/tauri"
|
||||
categories = ["gui", "web-programming"]
|
||||
license = "Apache-2.0 OR MIT"
|
||||
edition = "2021"
|
||||
rust-version = "1.70"
|
||||
|
||||
# default to small, optimized workspace release binaries
|
||||
[profile.release]
|
||||
panic = "abort"
|
||||
|
||||
161
README.md
161
README.md
@@ -2,126 +2,56 @@
|
||||
|
||||
[](https://github.com/tauri-apps/tauri/tree/dev)
|
||||
[](https://opencollective.com/tauri)
|
||||
[](https://github.com/tauri-apps/tauri/actions?query=workflow%3A%22test+library%22)
|
||||
[](https://github.com/tauri-apps/tauri/actions/workflows/test-core.yml)
|
||||
[](https://app.fossa.com/projects/git%2Bgithub.com%2Ftauri-apps%2Ftauri?ref=badge_shield)
|
||||
[](https://discord.gg/SpmNs4S)
|
||||
[](https://tauri.app)
|
||||
[](https://good-labs.github.io/greater-good-affirmation)
|
||||
[](https://opencollective.com/tauri)
|
||||
|
||||
## Current Releases
|
||||
|
||||
### Core
|
||||
|
||||
| Component | Description | Version | Lin | Win | Mac |
|
||||
| -------------------------------------------------------------------------------------------- | ----------------------------------------- | -------------------------------------------------------------------------------------------------------- | --- | --- | --- |
|
||||
| [**tauri**](https://github.com/tauri-apps/tauri/tree/dev/core/tauri) | runtime core | [](https://crates.io/crates/tauri) | ✅ | ✅ | ✅ |
|
||||
| [**tauri-build**](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-build) | applies macros at build-time | [](https://crates.io/crates/tauri-build) | ✅ | ✅ | ✅ |
|
||||
| [**tauri-codegen**](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-codegen) | handles assets, parses tauri.conf.json | [](https://crates.io/crates/tauri-codegen) | ✅ | ✅ | ✅ |
|
||||
| [**tauri-macros**](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-macros) | creates macros using tauri-codegen | [](https://crates.io/crates/tauri-macros) | ✅ | ✅ | ✅ |
|
||||
| [**tauri-runtime**](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-runtime) | layer between Tauri and webview libraries | [](https://crates.io/crates/tauri-runtime) | ✅ | ✅ | ✅ |
|
||||
| [**tauri-runtime-wry**](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-runtime-wry) | enables system-level interaction via WRY | [](https://crates.io/crates/tauri-runtime-wry) | ✅ | ✅ | ✅ |
|
||||
| [**tauri-utils**](https://github.com/tauri-apps/tauri/tree/dev/core/tauri-utils) | common code used across the tauri crates | [](https://crates.io/crates/tauri-utils) | ✅ | ✅ | ✅ |
|
||||
|
||||
### Tooling
|
||||
|
||||
| Component | Description | Version | Lin | Win | Mac |
|
||||
| --------------------------------------------------------------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------ | --- | --- | --- |
|
||||
| [**bundler**](https://github.com/tauri-apps/tauri/tree/dev/tooling/bundler) | manufacture the final binaries | [](https://crates.io/crates/tauri-bundler) | ✅ | ✅ | ✅ |
|
||||
| [**api.js**](https://github.com/tauri-apps/tauri/tree/dev/tooling/api) | JS API for interaction with Rust backend | [](https://www.npmjs.com/package/@tauri-apps/api) | ✅ | ✅ | ✅ |
|
||||
| [**cli.rs**](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli) | create, develop and build apps | [](https://crates.io/crates/tauri-cli) | ✅ | ✅ | ✅ |
|
||||
| [**cli.js**](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli/node) | Node.js CLI wrapper for cli.rs | [](https://www.npmjs.com/package/@tauri-apps/cli) | ✅ | ✅ | ✅ |
|
||||
|
||||
### Utilities and Plugins
|
||||
|
||||
| Component | Description | Version | Lin | Win | Mac |
|
||||
| ------------------------------------------------------------------------------- | ------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | --- | --- | --- |
|
||||
| [**create-tauri-app**](https://github.com/tauri-apps/create-tauri-app) | Get started with your first Tauri app | [](https://www.npmjs.com/package/create-tauri-app) | ✅ | ✅ | ✅ |
|
||||
| [**vue-cli-plugin-tauri**](https://github.com/tauri-apps/vue-cli-plugin-tauri/) | Vue CLI plugin for Tauri | [](https://www.npmjs.com/package/vue-cli-plugin-tauri) | ✅ | ✅ | ✅ |
|
||||
|
||||
## Introduction
|
||||
|
||||
Tauri is a framework for building tiny, blazingly fast binaries for all major desktop platforms. Developers can integrate any front-end framework that compiles to HTML, JS and CSS for building their user interface. The backend of the application is a rust-sourced binary with an API that the front-end can interact with.
|
||||
|
||||
The user interface in Tauri apps currently leverages [`tao`](https://docs.rs/tao) as a window handling library on macOS and Windows, and [`gtk`](https://gtk-rs.org/docs/gtk/) on Linux via the **Tauri-team** incubated and maintained [WRY](https://github.com/tauri-apps/wry), which creates a unified interface to the system webview (and other goodies like Menu and Taskbar), leveraging WebKit on macOS, WebView2 on Windows and WebKitGTK on Linux.
|
||||
The user interface in Tauri apps currently leverages [`tao`](https://docs.rs/tao) as a window handling library on macOS, Windows, Linux, Android and iOS. To render your application, Tauri uses [WRY](https://github.com/tauri-apps/wry), a library which provides a unified interface to the system webview, leveraging WKWebView on macOS & iOS, WebView2 on Windows, WebKitGTK on Linux and Android System WebView on Android.
|
||||
|
||||
To learn more about the details of how all of these pieces fit together, please consult this [ARCHITECTURE.md](https://github.com/tauri-apps/tauri/blob/dev/ARCHITECTURE.md) document.
|
||||
|
||||
## Get Started
|
||||
## Getting Started
|
||||
|
||||
If you are interested in making a tauri app, please visit the [documentation website](https://tauri.app). This README is directed towards those who are interested in contributing to the core library. But if you just want a quick overview about where `tauri` is at in its development, here's a quick burndown:
|
||||
If you are interested in making a tauri app, please visit the [documentation website](https://tauri.app).
|
||||
|
||||
The quickest way to get started is to install the [prerequisites](https://tauri.app/v1/guides/getting-started/prerequisites) for your system and create a new project with [`create-tauri-app`](https://github.com/tauri-apps/create-tauri-app/#usage). For example with `npm`:
|
||||
|
||||
```sh
|
||||
npm create tauri-app@latest
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
The list of Tauri's features includes, but is not limited to:
|
||||
|
||||
- Built-in app bundler to create app bundles in formats like `.app`, `.dmg`, `.deb`, `.rpm`, `.AppImage` and Windows installers like `.exe` (via NSIS) and `.msi` (via WiX).
|
||||
- Built-in self updater (desktop only)
|
||||
- System tray icons
|
||||
- Native notifications
|
||||
- Localhost free (:fire:)
|
||||
- GitHub action for streamlined CI
|
||||
- VS Code extension
|
||||
|
||||
### Platforms
|
||||
|
||||
Tauri currently supports development and distribution on the following platforms:
|
||||
|
||||
| Platform | Versions |
|
||||
| :----------------------- | :-------------- |
|
||||
| Windows | 7 and above |
|
||||
| macOS | 10.15 and above |
|
||||
| Linux | See below |
|
||||
| iOS/iPadOS (coming soon) | |
|
||||
| Android (coming soon) | |
|
||||
| Platform | Versions |
|
||||
| :----------------- | :-------------------------------------------------------------------------------------------------------------- |
|
||||
| Windows | 7 and above |
|
||||
| macOS | 10.15 and above |
|
||||
| Linux | webkit2gtk 4.0 for Tauri v1 (for example Ubuntu 18.04). webkit2gtk 4.1 for Tauri v2 (for example Ubuntu 22.04). |
|
||||
| iOS/iPadOS (alpha) | 9 and above |
|
||||
| Android (alpha) | 7 and above |
|
||||
|
||||
**Linux Support**
|
||||
|
||||
For **developing** Tauri apps refer to the [Getting Started guide on tauri.app](https://tauri.app/v1/guides/getting-started/prerequisites#setting-up-linux).
|
||||
|
||||
For **running** Tauri apps we support the below configurations (these are automatically added as dependencies for .deb and are bundled for AppImage so that your users don't need to manually install them):
|
||||
|
||||
- Debian (Ubuntu 18.04 and above or equivalent) with the following packages installed:
|
||||
- `libwebkit2gtk-4.0-37`, `libgtk-3-0`, `libayatana-appindicator3-1`<sup>1</sup>
|
||||
- Arch with the following packages installed:
|
||||
- `webkit2gtk`, `gtk3`, `libayatana-appindicator`<sup>1</sup>
|
||||
- Fedora (latest 2 versions) with the following packages installed:
|
||||
- `webkit2gtk3`, `gtk3`, `libappindicator-gtk3`<sup>1</sup>
|
||||
|
||||
<sup>1</sup> `appindicator` is only required if system trays are used
|
||||
|
||||
### Features
|
||||
|
||||
- [x] Desktop Bundler (.app, .dmg, .deb, AppImage, .msi)
|
||||
- [x] Self Updater
|
||||
- [x] App Signing
|
||||
- [x] Native Notifications (toast)
|
||||
- [x] App Tray
|
||||
- [x] Core Plugin System
|
||||
- [x] Scoped Filesystem
|
||||
- [x] Sidecar
|
||||
|
||||
### Security Features
|
||||
|
||||
- [x] localhost-free (:fire:)
|
||||
- [x] custom protocol for secure mode
|
||||
- [x] Dynamic ahead of Time Compilation (dAoT) with functional tree-shaking
|
||||
- [x] functional Address Space Layout Randomization
|
||||
- [x] OTP salting of function names and messages at runtime
|
||||
- [x] CSP Injection
|
||||
|
||||
### Utilities
|
||||
|
||||
- [x] Rust-based CLI
|
||||
- [x] GH Action for creating binaries for all platforms
|
||||
- [x] VS Code Extension
|
||||
|
||||
## Development
|
||||
|
||||
Tauri is a system composed of a number of moving pieces:
|
||||
|
||||
### Infrastructure
|
||||
|
||||
- Git for code management
|
||||
- GitHub for project management
|
||||
- GitHub actions for CI and CD
|
||||
- Discord for discussions
|
||||
- Netlify-hosted documentation website
|
||||
- DigitalOcean Meilisearch instance
|
||||
|
||||
### Operating systems
|
||||
|
||||
Tauri core can be developed on Mac, Linux and Windows, but you are encouraged to use the latest possible operating systems and build tools for your OS.
|
||||
|
||||
### Contributing
|
||||
## Contributing
|
||||
|
||||
Before you start working on something, it's best to check if there is an existing issue first. It's also a good idea to stop by the Discord server and confirm with the team if it makes sense or if someone else is already working on it.
|
||||
|
||||
@@ -131,32 +61,31 @@ Thank you to everyone contributing to Tauri!
|
||||
|
||||
### Documentation
|
||||
|
||||
Documentation in a polyglot system is a tricky proposition. To this end, we prefer to use inline documentation of Rust code and at JSDoc in typescript / javascript code. We autocollect these and publish them using Docusaurus v2 and netlify. Here is the hosting repository for the documentation site: https://github.com/tauri-apps/tauri-docs
|
||||
Documentation in a polyglot system is a tricky proposition. To this end, we prefer to use inline documentation in the Rust & JS source code as much as possible. Check out the hosting repository for the documentation site for further information: https://github.com/tauri-apps/tauri-docs
|
||||
|
||||
### Testing & Linting
|
||||
## Partners
|
||||
|
||||
Test all the things! We have a number of test suites, but are always looking to improve our coverage:
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://crabnebula.dev" target="_blank">
|
||||
<img src=".github/sponsors/crabnebula.svg" alt="CrabNebula" width="283">
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
- Rust (`cargo test`) => sourced via inline `#[cfg(test)]` declarations
|
||||
- Typescript (`jest`) => via spec files
|
||||
- Smoke Tests (run on merges to latest)
|
||||
- eslint, clippy
|
||||
|
||||
### CI/CD
|
||||
|
||||
We recommend you read this article to understand better how we run our pipelines: https://www.jacobbolda.com/setting-up-ci-and-cd-for-tauri/
|
||||
For the complete list of sponsors please visit our [website](https://tauri.app#sponsors) and [Open Collective](https://opencollective.com/tauri).
|
||||
|
||||
## Organization
|
||||
|
||||
Tauri aims to be a sustainable collective based on principles that guide [sustainable free and open software communities](https://sfosc.org). To this end it has become a Programme within the [Commons Conservancy](https://commonsconservancy.org/), and you can contribute financially via [Open Collective](https://opencollective.com/tauri).
|
||||
|
||||
## Semver
|
||||
|
||||
**tauri** is following [Semantic Versioning 2.0](https://semver.org/).
|
||||
|
||||
## Licenses
|
||||
|
||||
Code: (c) 2015 - 2021 - The Tauri Programme within The Commons Conservancy.
|
||||
Code: (c) 2015 - Present - The Tauri Programme within The Commons Conservancy.
|
||||
|
||||
MIT or MIT/Apache 2.0 where applicable.
|
||||
|
||||
|
||||
@@ -24,5 +24,5 @@ Additionally, we may ask you to independently verify our patch, which will be av
|
||||
|
||||
Depending on your decision to accept or deny credit for the vulnerability, you will be publicly attributed to the vulnerability and may be mentioned in our announcements.
|
||||
|
||||
At the current time we do not have the financial ability to reward bounties,
|
||||
At the current time we do not have the financial ability to reward bounties,
|
||||
but in extreme cases will at our discretion consider a reward.
|
||||
|
||||
@@ -1,5 +1,189 @@
|
||||
# Changelog
|
||||
|
||||
## \[2.0.0-beta.0]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`74a2a603`](https://www.github.com/tauri-apps/tauri/commit/74a2a6036a5e57462f161d728cbd8a6f121028ca)([#8661](https://www.github.com/tauri-apps/tauri/pull/8661)) Implement access control list for IPC usage.
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`e8d3793c`](https://www.github.com/tauri-apps/tauri/commit/e8d3793c3c34715569312a91633fde4d58d7621c)([#8732](https://www.github.com/tauri-apps/tauri/pull/8732)) Add `config-json` cargo feature flag (enabled by default) to. Disabling this feature flag will stop cargo from rebuilding when `tauri.conf.json` changes, see [#8721](https://github.com/tauri-apps/tauri/issues/8721) for more info.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.0`
|
||||
- Upgraded to `tauri-codegen@2.0.0-beta.0`
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- [`8de308d1`](https://www.github.com/tauri-apps/tauri/commit/8de308d1bf6a855d7a26af58bd0e744938ba47d8)([#8723](https://www.github.com/tauri-apps/tauri/pull/8723)) Restructured Tauri config per [RFC#5](https://github.com/tauri-apps/rfcs/blob/f3e82a6b0c5390401e855850d47dc7b7d9afd684/texts/0005-tauri-config-restructure.md):
|
||||
|
||||
- Moved `package.productName`, `package.version` and `tauri.bundle.identifier` fields to the top-level.
|
||||
- Removed `package` object.
|
||||
- Renamed `tauri` object to `app`.
|
||||
- Moved `tauri.bundle` object to the top-level.
|
||||
- Renamed `build.distDir` field to `frontendDist`.
|
||||
- Renamed `build.devPath` field to `devUrl` and will no longer accepts paths, it will only accept URLs.
|
||||
- Moved `tauri.pattern` to `app.security.pattern`.
|
||||
- Removed `tauri.bundle.updater` object, and its fields have been moved to the updater plugin under `plugins.updater` object.
|
||||
- Moved `build.withGlobalTauri` to `app.withGlobalTauri`.
|
||||
- Moved `tauri.bundle.dmg` object to `bundle.macOS.dmg`.
|
||||
- Moved `tauri.bundle.deb` object to `bundle.linux.deb`.
|
||||
- Moved `tauri.bundle.appimage` object to `bundle.linux.appimage`.
|
||||
- Removed all license fields from each bundle configuration object and instead added `bundle.license` and `bundle.licenseFile`.
|
||||
- Renamed `AppUrl` to `FrontendDist` and refactored its variants to be more explicit.
|
||||
- [`0cdfda28`](https://www.github.com/tauri-apps/tauri/commit/0cdfda28767701369cd774e2b20d943c6ddc9f05)([#8737](https://www.github.com/tauri-apps/tauri/pull/8737)) Moved `mobile::PluginBuilder`, `mobile::update_entitlements`, `config::plugin_config` and `mobile::update_android_manifest` to the new `tauri-plugin` crate.
|
||||
- [`74a2a603`](https://www.github.com/tauri-apps/tauri/commit/74a2a6036a5e57462f161d728cbd8a6f121028ca)([#8661](https://www.github.com/tauri-apps/tauri/pull/8661)) `CodegenContext::build` and `CodegenContext::try_build` have been removed, use `tauri_build::try_build(tauri_build::Attributes::new().codegen(codegen))` instead.
|
||||
|
||||
## \[2.0.0-alpha.14]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.13`
|
||||
- Upgraded to `tauri-codegen@2.0.0-alpha.13`
|
||||
|
||||
## \[2.0.0-alpha.13]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.12`
|
||||
- Upgraded to `tauri-codegen@2.0.0-alpha.12`
|
||||
|
||||
## \[2.0.0-alpha.12]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`a5479712`](https://www.github.com/tauri-apps/tauri/commit/a5479712095c224e2cb147d5c271acbc2fc97e79)([#8168](https://www.github.com/tauri-apps/tauri/pull/8168)) Fixed an issue that caused the resource compiler to not run on Windows when `package.version` was not set in `tauri.conf.json` preventing the app from starting.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.11`
|
||||
- Upgraded to `tauri-codegen@2.0.0-alpha.11`
|
||||
|
||||
## \[2.0.0-alpha.11]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`c6c59cf2`](https://www.github.com/tauri-apps/tauri/commit/c6c59cf2373258b626b00a26f4de4331765dd487) Pull changes from Tauri 1.5 release.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-codegen@2.0.0-alpha.10`
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.10`
|
||||
|
||||
## \[2.0.0-alpha.10]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`880266a7`](https://www.github.com/tauri-apps/tauri/commit/880266a7f697e1fe58d685de3bb6836ce5251e92)([#8031](https://www.github.com/tauri-apps/tauri/pull/8031)) Bump the MSRV to 1.70.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.9`
|
||||
- Upgraded to `tauri-codegen@2.0.0-alpha.9`
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- [`ebcc21e4`](https://www.github.com/tauri-apps/tauri/commit/ebcc21e4b95f4e8c27639fb1bca545b432f52d5e)([#8057](https://www.github.com/tauri-apps/tauri/pull/8057)) Renamed the beforeDevCommand, beforeBuildCommand and beforeBundleCommand hooks environment variables from `TAURI_PLATFORM, TAURI_ARCH, TAURI_FAMILY, TAURI_PLATFORM_VERSION, TAURI_PLATFORM_TYPE and TAURI_DEBUG` to `TAURI_ENV_PLATFORM, TAURI_ENV_ARCH, TAURI_ENV_FAMILY, TAURI_ENV_PLATFORM_VERSION, TAURI_ENV_PLATFORM_TYPE and TAURI_ENV_DEBUG` to differentiate the prefix with other CLI environment variables.
|
||||
|
||||
## \[2.0.0-alpha.9]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-codegen@2.0.0-alpha.8`
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.8`
|
||||
|
||||
## \[2.0.0-alpha.8]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`560b34dd`](https://www.github.com/tauri-apps/tauri/commit/560b34dd2a194ad62db09b3e9e41a2cfff4e5710)([#7610](https://www.github.com/tauri-apps/tauri/pull/7610)) Skip validation of the `tray-icon` feature flag.
|
||||
|
||||
## \[2.0.0-alpha.7]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`522de0e7`](https://www.github.com/tauri-apps/tauri/commit/522de0e78891d0bdf6387a5118985fc41a11baeb)([#7447](https://www.github.com/tauri-apps/tauri/pull/7447)) Added the `config::plugin_config` function to read the plugin configuration set from the CLI.
|
||||
- [`1e1d839e`](https://www.github.com/tauri-apps/tauri/commit/1e1d839e7e3d9496f71b6bc1336ced01f2965541)([#7450](https://www.github.com/tauri-apps/tauri/pull/7450)) Added the `mobile::update_android_manifest` function.
|
||||
- [`aba04fa8`](https://www.github.com/tauri-apps/tauri/commit/aba04fa823d70ff8df9bd22f8e6a25184689c3cb)([#7448](https://www.github.com/tauri-apps/tauri/pull/7448)) Added the `mobile::update_entitlements` function for iOS.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.7`
|
||||
- Upgraded to `tauri-codegen@2.0.0-alpha.7`
|
||||
|
||||
## \[2.0.0-alpha.6]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`3256a372`](https://www.github.com/tauri-apps/tauri/commit/3256a37263f60eafdf5a8321458b868bff26c1b8)([#7016](https://www.github.com/tauri-apps/tauri/pull/7016)) Fixes injection of the proguard rules on the Android project.
|
||||
|
||||
## \[2.0.0-alpha.5]
|
||||
|
||||
- [`3188f376`](https://www.github.com/tauri-apps/tauri/commit/3188f3764978c6d1452ee31d5a91469691e95094)([#6883](https://www.github.com/tauri-apps/tauri/pull/6883)) Bump the MSRV to 1.65.
|
||||
- [`2969d1cb`](https://www.github.com/tauri-apps/tauri/commit/2969d1cbba39301f9cc611d9f7d7051d80eef846)([#6773](https://www.github.com/tauri-apps/tauri/pull/6773)) Use absolute path to each Android plugin project instead of copying the files to enhance developer experience.
|
||||
- [`cdad6e08`](https://www.github.com/tauri-apps/tauri/commit/cdad6e083728ea61bd6fc734ef93f6306056ea2e)([#6774](https://www.github.com/tauri-apps/tauri/pull/6774)) Changed how the `tauri-android` dependency is injected. This requires the `gen/android` project to be recreated.
|
||||
- [`5a768d5c`](https://www.github.com/tauri-apps/tauri/commit/5a768d5ce69d6c9011c41f38a43481087c8d4921)([#6886](https://www.github.com/tauri-apps/tauri/pull/6886)) Remove `WindowsAttributes::sdk_dir`.
|
||||
|
||||
## \[2.0.0-alpha.4]
|
||||
|
||||
- Added `android` configuration object under `tauri > bundle`.
|
||||
- Bumped due to a bump in tauri-utils.
|
||||
- [db4c9dc6](https://www.github.com/tauri-apps/tauri/commit/db4c9dc655e07ee2184fe04571f500f7910890cd) feat(core): add option to configure Android's minimum SDK version ([#6651](https://www.github.com/tauri-apps/tauri/pull/6651)) on 2023-04-07
|
||||
|
||||
## \[2.0.0-alpha.3]
|
||||
|
||||
- Read the `IPHONEOS_DEPLOYMENT_TARGET` environment variable to set the Swift iOS target version, defaults to 13.
|
||||
- [4c3b9ecf](https://www.github.com/tauri-apps/tauri/commit/4c3b9ecfdcd1a4489b1e466727f11045ef34d67a) fix(build): iOS deployment target env var is IPHONEOS_DEPLOYMENT_TARGET ([#6602](https://www.github.com/tauri-apps/tauri/pull/6602)) on 2023-03-31
|
||||
|
||||
## \[2.0.0-alpha.2]
|
||||
|
||||
- Add `mobile::PluginBuilder` for running build tasks related to Tauri plugins.
|
||||
- [05dad087](https://www.github.com/tauri-apps/tauri/commit/05dad0876842e2a7334431247d49365cee835d3e) feat: initial work for iOS plugins ([#6205](https://www.github.com/tauri-apps/tauri/pull/6205)) on 2023-02-11
|
||||
|
||||
## \[2.0.0-alpha.1]
|
||||
|
||||
- Refactor mobile environment variables.
|
||||
- [dee9460f](https://www.github.com/tauri-apps/tauri/commit/dee9460f9c9bc92e9c638e7691e616849ac2085b) feat: keep CLI alive when iOS app exits, show logs, closes [#5855](https://www.github.com/tauri-apps/tauri/pull/5855) ([#5902](https://www.github.com/tauri-apps/tauri/pull/5902)) on 2022-12-27
|
||||
- Bump the MSRV to 1.64.
|
||||
- [7eb9aa75](https://www.github.com/tauri-apps/tauri/commit/7eb9aa75cfd6a3176d3f566fdda02d88aa529b0f) Update gtk to 0.16 ([#6155](https://www.github.com/tauri-apps/tauri/pull/6155)) on 2023-01-30
|
||||
- Removed mobile logging initialization, which will be handled by `tauri-plugin-log`.
|
||||
- [](https://www.github.com/tauri-apps/tauri/commit/undefined) on undefined
|
||||
|
||||
## \[2.0.0-alpha.0]
|
||||
|
||||
- Set environment variables used by `tauri::mobile_entry_point`.
|
||||
- [98904863](https://www.github.com/tauri-apps/tauri/commit/9890486321c9c79ccfb7c547fafee85b5c3ffa71) feat(core): add `mobile_entry_point` macro ([#4983](https://www.github.com/tauri-apps/tauri/pull/4983)) on 2022-08-21
|
||||
- First mobile alpha release!
|
||||
- [fa3a1098](https://www.github.com/tauri-apps/tauri/commit/fa3a10988a03aed1b66fb17d893b1a9adb90f7cd) feat(ci): prepare 2.0.0-alpha.0 ([#5786](https://www.github.com/tauri-apps/tauri/pull/5786)) on 2022-12-08
|
||||
|
||||
## \[1.5.0]
|
||||
|
||||
### What's Changed
|
||||
|
||||
- [`d1e09da0`](https://www.github.com/tauri-apps/tauri/commit/d1e09da084b849b9e384fc27ed250dd17e72c7a3)([#7918](https://www.github.com/tauri-apps/tauri/pull/7918)) Bump to 1.5 due to tauri-utils dependency bump.
|
||||
|
||||
## \[1.4.1]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`5ecb46b3`](https://www.github.com/tauri-apps/tauri/commit/5ecb46b3410afd1b5c82494c1e0a91d5a358c41a)([#7773](https://www.github.com/tauri-apps/tauri/pull/7773)) Automatically set rpath on macOS if frameworks are bundled and copy frameworks to `src-tauri/target/Frameworks` for usage in development.
|
||||
- [`290e366a`](https://www.github.com/tauri-apps/tauri/commit/290e366ae98e9a52b1b43bfd3e285150427ebffa)([#7419](https://www.github.com/tauri-apps/tauri/pull/7419)) Correctly copy the WebView2 runtime in development when `webviewInstallMode` is used instead of `webviewFixedRuntimePath`.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@1.5.0`
|
||||
- Upgraded to `tauri-codegen@1.4.1`
|
||||
|
||||
## \[1.4.0]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`52474e47`](https://www.github.com/tauri-apps/tauri/commit/52474e479d695865299d8c8d868fb98b99731020)([#7141](https://www.github.com/tauri-apps/tauri/pull/7141)) Enhance Cargo features check.
|
||||
- [`af937290`](https://www.github.com/tauri-apps/tauri/commit/af93729031565a69d1fde6cf16bea3b9b6e43a65)([#6676](https://www.github.com/tauri-apps/tauri/pull/6676)) On Windows, set `LegalCopyright` and `FileDescription` file properties on the executable from `tauri.bundle.copyright` and `tauri.bundle.shortDescription`,
|
||||
- [`d2710e9d`](https://www.github.com/tauri-apps/tauri/commit/d2710e9d2e8fd93975ef6494512370faa8cb3b7e)([#6944](https://www.github.com/tauri-apps/tauri/pull/6944)) Unpin `time`, `ignore`, and `winnow` crate versions. Developers now have to pin crates if needed themselves. A list of crates that need pinning to adhere to Tauri's MSRV will be visible in Tauri's GitHub workflow: https://github.com/tauri-apps/tauri/blob/dev/.github/workflows/test-core.yml#L85.
|
||||
|
||||
## \[1.3.0]
|
||||
|
||||
- Bump minimum supported Rust version to 1.60.
|
||||
|
||||
@@ -1,37 +1,52 @@
|
||||
[package]
|
||||
name = "tauri-build"
|
||||
version = "1.3.0"
|
||||
authors = [ "Tauri Programme within The Commons Conservancy" ]
|
||||
categories = [ "gui", "web-programming" ]
|
||||
license = "Apache-2.0 OR MIT"
|
||||
homepage = "https://tauri.app"
|
||||
repository = "https://github.com/tauri-apps/tauri/tree/dev/core/tauri-build"
|
||||
version = "2.0.0-beta.0"
|
||||
description = "build time code to pair with https://crates.io/crates/tauri"
|
||||
edition = "2021"
|
||||
rust-version = "1.60"
|
||||
exclude = [ "CHANGELOG.md", "/target" ]
|
||||
readme = "README.md"
|
||||
authors = { workspace = true }
|
||||
homepage = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
categories = { workspace = true }
|
||||
license = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = [ "--cfg", "doc_cfg" ]
|
||||
default-target = "x86_64-unknown-linux-gnu"
|
||||
targets = [
|
||||
"x86_64-pc-windows-msvc",
|
||||
"x86_64-unknown-linux-gnu",
|
||||
"x86_64-apple-darwin",
|
||||
"x86_64-linux-android",
|
||||
"x86_64-apple-ios"
|
||||
]
|
||||
rustc-args = [ "--cfg", "docsrs" ]
|
||||
rustdoc-args = [ "--cfg", "docsrs" ]
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1"
|
||||
quote = { version = "1", optional = true }
|
||||
tauri-codegen = { version = "1.3.0", path = "../tauri-codegen", optional = true }
|
||||
tauri-utils = { version = "1.3.0", path = "../tauri-utils", features = [ "build", "resources" ] }
|
||||
cargo_toml = "0.15"
|
||||
winnow = "=0.4.1"
|
||||
tauri-codegen = { version = "2.0.0-beta.0", path = "../tauri-codegen", optional = true }
|
||||
tauri-utils = { version = "2.0.0-beta.0", path = "../tauri-utils", features = [ "build", "resources" ] }
|
||||
cargo_toml = "0.17"
|
||||
serde = "1"
|
||||
serde_json = "1"
|
||||
heck = "0.4"
|
||||
json-patch = "1.0"
|
||||
json-patch = "1.2"
|
||||
walkdir = "2"
|
||||
tauri-winres = "0.1"
|
||||
semver = "1"
|
||||
dirs-next = "2"
|
||||
glob = "0.3"
|
||||
toml = "0.8"
|
||||
schemars = { version = "0.8", features = [ "preserve_order" ] }
|
||||
|
||||
[features]
|
||||
default = [ "config-json" ]
|
||||
codegen = [ "tauri-codegen", "quote" ]
|
||||
isolation = [ "tauri-codegen/isolation", "tauri-utils/isolation" ]
|
||||
config-json = [ ]
|
||||
config-json5 = [ "tauri-utils/config-json5" ]
|
||||
config-toml = [ "tauri-utils/config-toml" ]
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
[](https://github.com/tauri-apps/tauri/tree/dev)
|
||||
[](https://opencollective.com/tauri)
|
||||
[](https://github.com/tauri-apps/tauri/actions?query=workflow%3A%22test+library%22)
|
||||
[](https://github.com/tauri-apps/tauri/actions/workflows/test-core.yml)
|
||||
[](https://app.fossa.com/projects/git%2Bgithub.com%2Ftauri-apps%2Ftauri?ref=badge_shield)
|
||||
[](https://discord.gg/SpmNs4S)
|
||||
[](https://tauri.app)
|
||||
|
||||
288
core/tauri-build/src/acl.rs
Normal file
288
core/tauri-build/src/acl.rs
Normal file
@@ -0,0 +1,288 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use std::{
|
||||
collections::{BTreeMap, BTreeSet},
|
||||
fs::{copy, create_dir_all, read_to_string, File},
|
||||
io::{BufWriter, Write},
|
||||
path::PathBuf,
|
||||
};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use schemars::{
|
||||
schema::{
|
||||
ArrayValidation, InstanceType, Metadata, ObjectValidation, RootSchema, Schema, SchemaObject,
|
||||
SubschemaValidation,
|
||||
},
|
||||
schema_for,
|
||||
};
|
||||
use tauri_utils::{
|
||||
acl::{build::CapabilityFile, capability::Capability, plugin::Manifest},
|
||||
platform::Target,
|
||||
};
|
||||
|
||||
const CAPABILITIES_SCHEMA_FILE_NAME: &str = "schema.json";
|
||||
/// Path of the folder where schemas are saved.
|
||||
const CAPABILITIES_SCHEMA_FOLDER_PATH: &str = "capabilities/schemas";
|
||||
const CAPABILITIES_FILE_NAME: &str = "capabilities.json";
|
||||
const PLUGIN_MANIFESTS_FILE_NAME: &str = "plugin-manifests.json";
|
||||
|
||||
fn capabilities_schema(plugin_manifests: &BTreeMap<String, Manifest>) -> RootSchema {
|
||||
let mut schema = schema_for!(CapabilityFile);
|
||||
|
||||
fn schema_from(plugin: &str, id: &str, description: Option<&str>) -> Schema {
|
||||
Schema::Object(SchemaObject {
|
||||
metadata: Some(Box::new(Metadata {
|
||||
description: description
|
||||
.as_ref()
|
||||
.map(|d| format!("{plugin}:{id} -> {d}")),
|
||||
..Default::default()
|
||||
})),
|
||||
instance_type: Some(InstanceType::String.into()),
|
||||
enum_values: Some(vec![serde_json::Value::String(format!("{plugin}:{id}"))]),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
let mut permission_schemas = Vec::new();
|
||||
|
||||
for (plugin, manifest) in plugin_manifests {
|
||||
for (set_id, set) in &manifest.permission_sets {
|
||||
permission_schemas.push(schema_from(plugin, set_id, Some(&set.description)));
|
||||
}
|
||||
|
||||
if let Some(default) = &manifest.default_permission {
|
||||
permission_schemas.push(schema_from(
|
||||
plugin,
|
||||
"default",
|
||||
Some(default.description.as_ref()),
|
||||
));
|
||||
}
|
||||
|
||||
for (permission_id, permission) in &manifest.permissions {
|
||||
permission_schemas.push(schema_from(
|
||||
plugin,
|
||||
permission_id,
|
||||
permission.description.as_deref(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(Schema::Object(obj)) = schema.definitions.get_mut("Identifier") {
|
||||
obj.object = None;
|
||||
obj.instance_type = None;
|
||||
obj.metadata.as_mut().map(|metadata| {
|
||||
metadata
|
||||
.description
|
||||
.replace("Permission identifier".to_string());
|
||||
metadata
|
||||
});
|
||||
obj.subschemas.replace(Box::new(SubschemaValidation {
|
||||
one_of: Some(permission_schemas),
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
|
||||
if let Some(Schema::Object(obj)) = schema.definitions.get_mut("PermissionEntry") {
|
||||
let permission_entry_any_of_schemas = obj.subschemas().any_of.as_mut().unwrap();
|
||||
|
||||
if let Schema::Object(mut scope_extended_schema_obj) =
|
||||
permission_entry_any_of_schemas.remove(permission_entry_any_of_schemas.len() - 1)
|
||||
{
|
||||
let mut global_scope_one_of = Vec::new();
|
||||
|
||||
for (plugin, manifest) in plugin_manifests {
|
||||
if let Some(global_scope_schema) = &manifest.global_scope_schema {
|
||||
let global_scope_schema_def: Schema = serde_json::from_value(global_scope_schema.clone())
|
||||
.unwrap_or_else(|e| panic!("invalid JSON schema for plugin {plugin}: {e}"));
|
||||
|
||||
let global_scope_schema = Schema::Object(SchemaObject {
|
||||
array: Some(Box::new(ArrayValidation {
|
||||
items: Some(global_scope_schema_def.into()),
|
||||
..Default::default()
|
||||
})),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
let mut required = BTreeSet::new();
|
||||
required.insert("identifier".to_string());
|
||||
|
||||
let mut object = ObjectValidation {
|
||||
required,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mut permission_schemas = Vec::new();
|
||||
if let Some(default) = &manifest.default_permission {
|
||||
permission_schemas.push(schema_from(plugin, "default", Some(&default.description)));
|
||||
}
|
||||
for set in manifest.permission_sets.values() {
|
||||
permission_schemas.push(schema_from(plugin, &set.identifier, Some(&set.description)));
|
||||
}
|
||||
for permission in manifest.permissions.values() {
|
||||
permission_schemas.push(schema_from(
|
||||
plugin,
|
||||
&permission.identifier,
|
||||
permission.description.as_deref(),
|
||||
));
|
||||
}
|
||||
|
||||
let identifier_schema = Schema::Object(SchemaObject {
|
||||
subschemas: Some(Box::new(SubschemaValidation {
|
||||
one_of: Some(permission_schemas),
|
||||
..Default::default()
|
||||
})),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
object
|
||||
.properties
|
||||
.insert("identifier".to_string(), identifier_schema);
|
||||
object
|
||||
.properties
|
||||
.insert("allow".to_string(), global_scope_schema.clone());
|
||||
object
|
||||
.properties
|
||||
.insert("deny".to_string(), global_scope_schema);
|
||||
|
||||
global_scope_one_of.push(Schema::Object(SchemaObject {
|
||||
instance_type: Some(InstanceType::Object.into()),
|
||||
object: Some(Box::new(object)),
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if !global_scope_one_of.is_empty() {
|
||||
scope_extended_schema_obj.object = None;
|
||||
scope_extended_schema_obj
|
||||
.subschemas
|
||||
.replace(Box::new(SubschemaValidation {
|
||||
one_of: Some(global_scope_one_of),
|
||||
..Default::default()
|
||||
}));
|
||||
|
||||
permission_entry_any_of_schemas.push(scope_extended_schema_obj.into());
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
schema
|
||||
}
|
||||
|
||||
pub fn generate_schema(
|
||||
plugin_manifests: &BTreeMap<String, Manifest>,
|
||||
target: Target,
|
||||
) -> Result<()> {
|
||||
let schema = capabilities_schema(plugin_manifests);
|
||||
let schema_str = serde_json::to_string_pretty(&schema).unwrap();
|
||||
let out_dir = PathBuf::from(CAPABILITIES_SCHEMA_FOLDER_PATH);
|
||||
create_dir_all(&out_dir).context("unable to create schema output directory")?;
|
||||
|
||||
let schema_path = out_dir.join(format!("{target}-{CAPABILITIES_SCHEMA_FILE_NAME}"));
|
||||
let mut schema_file = BufWriter::new(File::create(&schema_path)?);
|
||||
write!(schema_file, "{schema_str}")?;
|
||||
|
||||
copy(
|
||||
schema_path,
|
||||
out_dir.join(format!(
|
||||
"{}-{CAPABILITIES_SCHEMA_FILE_NAME}",
|
||||
if target.is_desktop() {
|
||||
"desktop"
|
||||
} else {
|
||||
"mobile"
|
||||
}
|
||||
)),
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn save_capabilities(capabilities: &BTreeMap<String, Capability>) -> Result<PathBuf> {
|
||||
let capabilities_path =
|
||||
PathBuf::from(CAPABILITIES_SCHEMA_FOLDER_PATH).join(CAPABILITIES_FILE_NAME);
|
||||
let capabilities_json = serde_json::to_string(&capabilities)?;
|
||||
if capabilities_json != read_to_string(&capabilities_path).unwrap_or_default() {
|
||||
std::fs::write(&capabilities_path, capabilities_json)?;
|
||||
}
|
||||
Ok(capabilities_path)
|
||||
}
|
||||
|
||||
pub fn save_plugin_manifests(plugin_manifests: &BTreeMap<String, Manifest>) -> Result<PathBuf> {
|
||||
let plugin_manifests_path =
|
||||
PathBuf::from(CAPABILITIES_SCHEMA_FOLDER_PATH).join(PLUGIN_MANIFESTS_FILE_NAME);
|
||||
let plugin_manifests_json = serde_json::to_string(&plugin_manifests)?;
|
||||
if plugin_manifests_json != read_to_string(&plugin_manifests_path).unwrap_or_default() {
|
||||
std::fs::write(&plugin_manifests_path, plugin_manifests_json)?;
|
||||
}
|
||||
Ok(plugin_manifests_path)
|
||||
}
|
||||
|
||||
pub fn get_plugin_manifests() -> Result<BTreeMap<String, Manifest>> {
|
||||
let permission_map =
|
||||
tauri_utils::acl::build::read_permissions().context("failed to read plugin permissions")?;
|
||||
let mut global_scope_map = tauri_utils::acl::build::read_global_scope_schemas()
|
||||
.context("failed to read global scope schemas")?;
|
||||
|
||||
let mut processed = BTreeMap::new();
|
||||
for (plugin_name, permission_files) in permission_map {
|
||||
let manifest = Manifest::new(permission_files, global_scope_map.remove(&plugin_name));
|
||||
processed.insert(plugin_name, manifest);
|
||||
}
|
||||
|
||||
Ok(processed)
|
||||
}
|
||||
|
||||
pub fn validate_capabilities(
|
||||
plugin_manifests: &BTreeMap<String, Manifest>,
|
||||
capabilities: &BTreeMap<String, Capability>,
|
||||
) -> Result<()> {
|
||||
let target = tauri_utils::platform::Target::from_triple(&std::env::var("TARGET").unwrap());
|
||||
|
||||
for capability in capabilities.values() {
|
||||
if !capability.platforms.contains(&target) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for permission_entry in &capability.permissions {
|
||||
let permission_id = permission_entry.identifier();
|
||||
if let Some((plugin_name, permission_name)) = permission_id.get().split_once(':') {
|
||||
let permission_exists = plugin_manifests
|
||||
.get(plugin_name)
|
||||
.map(|manifest| {
|
||||
if permission_name == "default" {
|
||||
manifest.default_permission.is_some()
|
||||
} else {
|
||||
manifest.permissions.contains_key(permission_name)
|
||||
|| manifest.permission_sets.contains_key(permission_name)
|
||||
}
|
||||
})
|
||||
.unwrap_or(false);
|
||||
|
||||
if !permission_exists {
|
||||
let mut available_permissions = Vec::new();
|
||||
for (plugin, manifest) in plugin_manifests {
|
||||
if manifest.default_permission.is_some() {
|
||||
available_permissions.push(format!("{plugin}:default"));
|
||||
}
|
||||
for p in manifest.permissions.keys() {
|
||||
available_permissions.push(format!("{plugin}:{p}"));
|
||||
}
|
||||
for p in manifest.permission_sets.keys() {
|
||||
available_permissions.push(format!("{plugin}:{p}"));
|
||||
}
|
||||
}
|
||||
|
||||
anyhow::bail!(
|
||||
"Permission {} not found, expected one of {}",
|
||||
permission_id.get(),
|
||||
available_permissions.join(", ")
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -10,11 +10,11 @@ use std::{
|
||||
path::PathBuf,
|
||||
};
|
||||
use tauri_codegen::{context_codegen, ContextData};
|
||||
use tauri_utils::config::{AppUrl, WindowUrl};
|
||||
use tauri_utils::config::FrontendDist;
|
||||
|
||||
// TODO docs
|
||||
/// A builder for generating a Tauri application context during compile time.
|
||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "codegen")))]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "codegen")))]
|
||||
#[derive(Debug)]
|
||||
pub struct CodegenContext {
|
||||
dev: bool,
|
||||
@@ -78,33 +78,15 @@ impl CodegenContext {
|
||||
///
|
||||
/// Unless you are doing something special with this builder, you don't need to do anything with
|
||||
/// the returned output path.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// If any parts of the codegen fail, this will panic with the related error message. This is
|
||||
/// typically desirable when running inside a build script; see [`Self::try_build`] for no panics.
|
||||
pub fn build(self) -> PathBuf {
|
||||
match self.try_build() {
|
||||
Ok(out) => out,
|
||||
Err(error) => panic!("Error found during Codegen::build: {error}"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Non-panicking [`Self::build`]
|
||||
pub fn try_build(self) -> Result<PathBuf> {
|
||||
pub(crate) fn try_build(self) -> Result<PathBuf> {
|
||||
let (config, config_parent) = tauri_codegen::get_config(&self.config_path)?;
|
||||
|
||||
// rerun if changed
|
||||
let app_url = if self.dev {
|
||||
&config.build.dev_path
|
||||
} else {
|
||||
&config.build.dist_dir
|
||||
};
|
||||
match app_url {
|
||||
AppUrl::Url(WindowUrl::App(p)) => {
|
||||
match &config.build.frontend_dist {
|
||||
Some(FrontendDist::Directory(p)) => {
|
||||
println!("cargo:rerun-if-changed={}", config_parent.join(p).display());
|
||||
}
|
||||
AppUrl::Files(files) => {
|
||||
Some(FrontendDist::Files(files)) => {
|
||||
for path in files {
|
||||
println!(
|
||||
"cargo:rerun-if-changed={}",
|
||||
@@ -114,13 +96,13 @@ impl CodegenContext {
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
for icon in &config.tauri.bundle.icon {
|
||||
for icon in &config.bundle.icon {
|
||||
println!(
|
||||
"cargo:rerun-if-changed={}",
|
||||
config_parent.join(icon).display()
|
||||
);
|
||||
}
|
||||
if let Some(tray_icon) = config.tauri.system_tray.as_ref().map(|t| &t.icon_path) {
|
||||
if let Some(tray_icon) = config.app.tray_icon.as_ref().map(|t| &t.icon_path) {
|
||||
println!(
|
||||
"cargo:rerun-if-changed={}",
|
||||
config_parent.join(tray_icon).display()
|
||||
|
||||
@@ -2,27 +2,47 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#![cfg_attr(doc_cfg, feature(doc_cfg))]
|
||||
//! [](https://tauri.app)
|
||||
//!
|
||||
//! This applies the macros at build-time in order to rig some special features needed by `cargo`.
|
||||
|
||||
#![doc(
|
||||
html_logo_url = "https://github.com/tauri-apps/tauri/raw/dev/app-icon.png",
|
||||
html_favicon_url = "https://github.com/tauri-apps/tauri/raw/dev/app-icon.png"
|
||||
)]
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
|
||||
use anyhow::Context;
|
||||
pub use anyhow::Result;
|
||||
use cargo_toml::{Dependency, Manifest};
|
||||
use cargo_toml::Manifest;
|
||||
use heck::AsShoutySnakeCase;
|
||||
|
||||
use tauri_utils::{
|
||||
config::Config,
|
||||
resources::{external_binaries, resource_relpath, ResourcePaths},
|
||||
acl::build::parse_capabilities,
|
||||
config::{BundleResources, Config, WebviewInstallMode},
|
||||
resources::{external_binaries, ResourcePaths},
|
||||
};
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::{
|
||||
env::var_os,
|
||||
fs::copy,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
mod acl;
|
||||
#[cfg(feature = "codegen")]
|
||||
mod codegen;
|
||||
mod manifest;
|
||||
mod mobile;
|
||||
mod static_vcruntime;
|
||||
|
||||
#[cfg(feature = "codegen")]
|
||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "codegen")))]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "codegen")))]
|
||||
pub use codegen::context::CodegenContext;
|
||||
|
||||
const PLUGIN_MANIFESTS_FILE_NAME: &str = "plugin-manifests.json";
|
||||
const CAPABILITIES_FILE_NAME: &str = "capabilities.json";
|
||||
|
||||
fn copy_file(from: impl AsRef<Path>, to: impl AsRef<Path>) -> Result<()> {
|
||||
let from = from.as_ref();
|
||||
let to = to.as_ref();
|
||||
@@ -71,11 +91,117 @@ fn copy_binaries(
|
||||
|
||||
/// Copies resources to a path.
|
||||
fn copy_resources(resources: ResourcePaths<'_>, path: &Path) -> Result<()> {
|
||||
for src in resources {
|
||||
let src = src?;
|
||||
println!("cargo:rerun-if-changed={}", src.display());
|
||||
let dest = path.join(resource_relpath(&src));
|
||||
copy_file(&src, dest)?;
|
||||
for resource in resources.iter() {
|
||||
let resource = resource?;
|
||||
println!("cargo:rerun-if-changed={}", resource.path().display());
|
||||
copy_file(resource.path(), path.join(resource.target()))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn symlink_dir(src: &Path, dst: &Path) -> std::io::Result<()> {
|
||||
std::os::unix::fs::symlink(src, dst)
|
||||
}
|
||||
|
||||
/// Makes a symbolic link to a directory.
|
||||
#[cfg(windows)]
|
||||
fn symlink_dir(src: &Path, dst: &Path) -> std::io::Result<()> {
|
||||
std::os::windows::fs::symlink_dir(src, dst)
|
||||
}
|
||||
|
||||
/// Makes a symbolic link to a file.
|
||||
#[cfg(unix)]
|
||||
fn symlink_file(src: &Path, dst: &Path) -> std::io::Result<()> {
|
||||
std::os::unix::fs::symlink(src, dst)
|
||||
}
|
||||
|
||||
/// Makes a symbolic link to a file.
|
||||
#[cfg(windows)]
|
||||
fn symlink_file(src: &Path, dst: &Path) -> std::io::Result<()> {
|
||||
std::os::windows::fs::symlink_file(src, dst)
|
||||
}
|
||||
|
||||
fn copy_dir(from: &Path, to: &Path) -> Result<()> {
|
||||
for entry in walkdir::WalkDir::new(from) {
|
||||
let entry = entry?;
|
||||
debug_assert!(entry.path().starts_with(from));
|
||||
let rel_path = entry.path().strip_prefix(from)?;
|
||||
let dest_path = to.join(rel_path);
|
||||
if entry.file_type().is_symlink() {
|
||||
let target = std::fs::read_link(entry.path())?;
|
||||
if entry.path().is_dir() {
|
||||
symlink_dir(&target, &dest_path)?;
|
||||
} else {
|
||||
symlink_file(&target, &dest_path)?;
|
||||
}
|
||||
} else if entry.file_type().is_dir() {
|
||||
std::fs::create_dir(dest_path)?;
|
||||
} else {
|
||||
std::fs::copy(entry.path(), dest_path)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Copies the framework under `{src_dir}/{framework}.framework` to `{dest_dir}/{framework}.framework`.
|
||||
fn copy_framework_from(src_dir: &Path, framework: &str, dest_dir: &Path) -> Result<bool> {
|
||||
let src_name = format!("{}.framework", framework);
|
||||
let src_path = src_dir.join(&src_name);
|
||||
if src_path.exists() {
|
||||
copy_dir(&src_path, &dest_dir.join(&src_name))?;
|
||||
Ok(true)
|
||||
} else {
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
||||
// Copies the macOS application bundle frameworks to the target folder
|
||||
fn copy_frameworks(dest_dir: &Path, frameworks: &[String]) -> Result<()> {
|
||||
std::fs::create_dir_all(dest_dir).with_context(|| {
|
||||
format!(
|
||||
"Failed to create frameworks output directory at {:?}",
|
||||
dest_dir
|
||||
)
|
||||
})?;
|
||||
for framework in frameworks.iter() {
|
||||
if framework.ends_with(".framework") {
|
||||
let src_path = PathBuf::from(framework);
|
||||
let src_name = src_path
|
||||
.file_name()
|
||||
.expect("Couldn't get framework filename");
|
||||
let dest_path = dest_dir.join(src_name);
|
||||
copy_dir(&src_path, &dest_path)?;
|
||||
continue;
|
||||
} else if framework.ends_with(".dylib") {
|
||||
let src_path = PathBuf::from(framework);
|
||||
if !src_path.exists() {
|
||||
return Err(anyhow::anyhow!("Library not found: {}", framework));
|
||||
}
|
||||
let src_name = src_path.file_name().expect("Couldn't get library filename");
|
||||
let dest_path = dest_dir.join(src_name);
|
||||
copy_file(&src_path, &dest_path)?;
|
||||
continue;
|
||||
} else if framework.contains('/') {
|
||||
return Err(anyhow::anyhow!(
|
||||
"Framework path should have .framework extension: {}",
|
||||
framework
|
||||
));
|
||||
}
|
||||
if let Some(home_dir) = dirs_next::home_dir() {
|
||||
if copy_framework_from(&home_dir.join("Library/Frameworks/"), framework, dest_dir)? {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if copy_framework_from(&PathBuf::from("/Library/Frameworks/"), framework, dest_dir)?
|
||||
|| copy_framework_from(
|
||||
&PathBuf::from("/Network/Library/Frameworks/"),
|
||||
framework,
|
||||
dest_dir,
|
||||
)?
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -102,24 +228,31 @@ fn cfg_alias(alias: &str, has_feature: bool) {
|
||||
#[derive(Debug, Default)]
|
||||
pub struct WindowsAttributes {
|
||||
window_icon_path: Option<PathBuf>,
|
||||
/// The path to the sdk location.
|
||||
///
|
||||
/// For the GNU toolkit this has to be the path where MinGW put windres.exe and ar.exe.
|
||||
/// This could be something like: "C:\Program Files\mingw-w64\x86_64-5.3.0-win32-seh-rt_v4-rev0\mingw64\bin"
|
||||
///
|
||||
/// For MSVC the Windows SDK has to be installed. It comes with the resource compiler rc.exe.
|
||||
/// This should be set to the root directory of the Windows SDK, e.g., "C:\Program Files (x86)\Windows Kits\10" or,
|
||||
/// if multiple 10 versions are installed, set it directly to the correct bin directory "C:\Program Files (x86)\Windows Kits\10\bin\10.0.14393.0\x64"
|
||||
///
|
||||
/// If it is left unset, it will look up a path in the registry, i.e. HKLM\SOFTWARE\Microsoft\Windows Kits\Installed Roots
|
||||
sdk_dir: Option<PathBuf>,
|
||||
/// A string containing an [application manifest] to be included with the application on Windows.
|
||||
///
|
||||
/// Defaults to:
|
||||
/// ```ignore
|
||||
/// ```text
|
||||
#[doc = include_str!("window-app-manifest.xml")]
|
||||
/// ```
|
||||
///
|
||||
/// ## Warning
|
||||
///
|
||||
/// if you are using tauri's dialog APIs, you need to specify a dependency on Common Control v6 by adding the following to your custom manifest:
|
||||
/// ```text
|
||||
/// <dependency>
|
||||
/// <dependentAssembly>
|
||||
/// <assemblyIdentity
|
||||
/// type="win32"
|
||||
/// name="Microsoft.Windows.Common-Controls"
|
||||
/// version="6.0.0.0"
|
||||
/// processorArchitecture="*"
|
||||
/// publicKeyToken="6595b64144ccf1df"
|
||||
/// language="*"
|
||||
/// />
|
||||
/// </dependentAssembly>
|
||||
/// </dependency>
|
||||
/// ```
|
||||
///
|
||||
/// [application manifest]: https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests
|
||||
app_manifest: Option<String>,
|
||||
}
|
||||
@@ -140,47 +273,57 @@ impl WindowsAttributes {
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the sdk dir for windows. Currently only used on Windows. This must be a valid UTF-8
|
||||
/// path. Defaults to whatever the `winres` crate determines is best.
|
||||
#[must_use]
|
||||
pub fn sdk_dir<P: AsRef<Path>>(mut self, sdk_dir: P) -> Self {
|
||||
self.sdk_dir = Some(sdk_dir.as_ref().into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the Windows app [manifest].
|
||||
/// Sets the [application manifest] to be included with the application on Windows.
|
||||
///
|
||||
/// Defaults to:
|
||||
/// ```text
|
||||
#[doc = include_str!("window-app-manifest.xml")]
|
||||
/// ```
|
||||
///
|
||||
/// ## Warning
|
||||
///
|
||||
/// if you are using tauri's dialog APIs, you need to specify a dependency on Common Control v6 by adding the following to your custom manifest:
|
||||
/// ```text
|
||||
/// <dependency>
|
||||
/// <dependentAssembly>
|
||||
/// <assemblyIdentity
|
||||
/// type="win32"
|
||||
/// name="Microsoft.Windows.Common-Controls"
|
||||
/// version="6.0.0.0"
|
||||
/// processorArchitecture="*"
|
||||
/// publicKeyToken="6595b64144ccf1df"
|
||||
/// language="*"
|
||||
/// />
|
||||
/// </dependentAssembly>
|
||||
/// </dependency>
|
||||
/// ```
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// The following manifest will brand the exe as requesting administrator privileges.
|
||||
/// Thus, everytime it is executed, a Windows UAC dialog will appear.
|
||||
///
|
||||
/// Note that you can move the manifest contents to a separate file and use `include_str!("manifest.xml")`
|
||||
/// instead of the inline string.
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// let mut windows = tauri_build::WindowsAttributes::new();
|
||||
/// windows = windows.app_manifest(r#"
|
||||
/// <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
/// <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
/// <security>
|
||||
/// <requestedPrivileges>
|
||||
/// <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
/// </requestedPrivileges>
|
||||
/// </security>
|
||||
/// </trustInfo>
|
||||
/// <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
/// <security>
|
||||
/// <requestedPrivileges>
|
||||
/// <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
/// </requestedPrivileges>
|
||||
/// </security>
|
||||
/// </trustInfo>
|
||||
/// </assembly>
|
||||
/// "#);
|
||||
/// tauri_build::try_build(
|
||||
/// tauri_build::Attributes::new().windows_attributes(windows)
|
||||
/// ).expect("failed to run build script");
|
||||
/// let attrs = tauri_build::Attributes::new().windows_attributes(windows);
|
||||
/// tauri_build::try_build(attrs).expect("failed to run build script");
|
||||
/// ```
|
||||
///
|
||||
/// Defaults to:
|
||||
/// ```ignore
|
||||
#[doc = include_str!("window-app-manifest.xml")]
|
||||
/// Note that you can move the manifest contents to a separate file and use `include_str!("manifest.xml")`
|
||||
/// instead of the inline string.
|
||||
///
|
||||
/// [manifest]: https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests
|
||||
/// ```
|
||||
#[must_use]
|
||||
pub fn app_manifest<S: AsRef<str>>(mut self, manifest: S) -> Self {
|
||||
self.app_manifest = Some(manifest.as_ref().to_string());
|
||||
@@ -193,6 +336,9 @@ impl WindowsAttributes {
|
||||
pub struct Attributes {
|
||||
#[allow(dead_code)]
|
||||
windows_attributes: WindowsAttributes,
|
||||
capabilities_path_pattern: Option<&'static str>,
|
||||
#[cfg(feature = "codegen")]
|
||||
codegen: Option<codegen::context::CodegenContext>,
|
||||
}
|
||||
|
||||
impl Attributes {
|
||||
@@ -207,6 +353,21 @@ impl Attributes {
|
||||
self.windows_attributes = windows_attributes;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the glob pattern to be used to find the capabilities.
|
||||
#[must_use]
|
||||
pub fn capabilities_path_pattern(mut self, pattern: &'static str) -> Self {
|
||||
self.capabilities_path_pattern.replace(pattern);
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(feature = "codegen")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "codegen")))]
|
||||
#[must_use]
|
||||
pub fn codegen(mut self, codegen: codegen::context::CodegenContext) -> Self {
|
||||
self.codegen.replace(codegen);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Run all build time helpers for your Tauri Application.
|
||||
@@ -248,6 +409,7 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
|
||||
use anyhow::anyhow;
|
||||
|
||||
println!("cargo:rerun-if-env-changed=TAURI_CONFIG");
|
||||
#[cfg(feature = "config-json")]
|
||||
println!("cargo:rerun-if-changed=tauri.conf.json");
|
||||
#[cfg(feature = "config-json5")]
|
||||
println!("cargo:rerun-if-changed=tauri.conf.json5");
|
||||
@@ -259,7 +421,11 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
|
||||
cfg_alias("desktop", !mobile);
|
||||
cfg_alias("mobile", mobile);
|
||||
|
||||
let target_triple = std::env::var("TARGET").unwrap();
|
||||
let target = tauri_utils::platform::Target::from_triple(&target_triple);
|
||||
|
||||
let mut config = serde_json::from_value(tauri_utils::config::parse::read_from(
|
||||
target,
|
||||
std::env::current_dir().unwrap(),
|
||||
)?)?;
|
||||
if let Ok(env) = std::env::var("TAURI_CONFIG") {
|
||||
@@ -268,6 +434,22 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
|
||||
}
|
||||
let config: Config = serde_json::from_value(config)?;
|
||||
|
||||
let s = config.identifier.split('.');
|
||||
let last = s.clone().count() - 1;
|
||||
let mut android_package_prefix = String::new();
|
||||
for (i, w) in s.enumerate() {
|
||||
if i == 0 || i != last {
|
||||
android_package_prefix.push_str(w);
|
||||
android_package_prefix.push('_');
|
||||
}
|
||||
}
|
||||
android_package_prefix.pop();
|
||||
println!("cargo:rustc-env=TAURI_ANDROID_PACKAGE_PREFIX={android_package_prefix}");
|
||||
|
||||
if let Some(project_dir) = var_os("TAURI_ANDROID_PROJECT_PATH").map(PathBuf::from) {
|
||||
mobile::generate_gradle_files(project_dir)?;
|
||||
}
|
||||
|
||||
cfg_alias("dev", !has_feature("custom-protocol"));
|
||||
|
||||
let ws_path = get_workspace_dir()?;
|
||||
@@ -284,30 +466,29 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
|
||||
Manifest::complete_from_path(&mut manifest, Path::new("Cargo.toml"))?;
|
||||
}
|
||||
|
||||
if let Some(tauri_build) = manifest.build_dependencies.remove("tauri-build") {
|
||||
let error_message = check_features(&config, tauri_build, true);
|
||||
|
||||
if !error_message.is_empty() {
|
||||
return Err(anyhow!("
|
||||
The `tauri-build` dependency features on the `Cargo.toml` file does not match the allowlist defined under `tauri.conf.json`.
|
||||
Please run `tauri dev` or `tauri build` or {}.
|
||||
", error_message));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(tauri) = manifest.dependencies.remove("tauri") {
|
||||
let error_message = check_features(&config, tauri, false);
|
||||
|
||||
if !error_message.is_empty() {
|
||||
return Err(anyhow!("
|
||||
The `tauri` dependency features on the `Cargo.toml` file does not match the allowlist defined under `tauri.conf.json`.
|
||||
Please run `tauri dev` or `tauri build` or {}.
|
||||
", error_message));
|
||||
}
|
||||
}
|
||||
|
||||
let target_triple = std::env::var("TARGET").unwrap();
|
||||
let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());
|
||||
|
||||
manifest::check(&config, &mut manifest)?;
|
||||
let plugin_manifests = acl::get_plugin_manifests()?;
|
||||
std::fs::write(
|
||||
out_dir.join(PLUGIN_MANIFESTS_FILE_NAME),
|
||||
serde_json::to_string(&plugin_manifests)?,
|
||||
)?;
|
||||
let capabilities = if let Some(pattern) = attributes.capabilities_path_pattern {
|
||||
parse_capabilities(pattern)?
|
||||
} else {
|
||||
parse_capabilities("./capabilities/**/*")?
|
||||
};
|
||||
acl::generate_schema(&plugin_manifests, target)?;
|
||||
acl::validate_capabilities(&plugin_manifests, &capabilities)?;
|
||||
|
||||
let capabilities_path = acl::save_capabilities(&capabilities)?;
|
||||
copy(capabilities_path, out_dir.join(CAPABILITIES_FILE_NAME))?;
|
||||
|
||||
acl::save_plugin_manifests(&plugin_manifests)?;
|
||||
|
||||
println!("cargo:rustc-env=TAURI_ENV_TARGET_TRIPLE={target_triple}");
|
||||
|
||||
// TODO: far from ideal, but there's no other way to get the target dir, see <https://github.com/rust-lang/cargo/issues/5457>
|
||||
let target_dir = out_dir
|
||||
.parent()
|
||||
@@ -317,7 +498,7 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
|
||||
.parent()
|
||||
.unwrap();
|
||||
|
||||
if let Some(paths) = &config.tauri.bundle.external_bin {
|
||||
if let Some(paths) = &config.bundle.external_bin {
|
||||
copy_binaries(
|
||||
ResourcePaths::new(external_binaries(paths, &target_triple).as_slice(), true),
|
||||
&target_triple,
|
||||
@@ -327,30 +508,57 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
|
||||
}
|
||||
|
||||
#[allow(unused_mut, clippy::redundant_clone)]
|
||||
let mut resources = config.tauri.bundle.resources.clone().unwrap_or_default();
|
||||
let mut resources = config
|
||||
.bundle
|
||||
.resources
|
||||
.clone()
|
||||
.unwrap_or_else(|| BundleResources::List(Vec::new()));
|
||||
if target_triple.contains("windows") {
|
||||
if let Some(fixed_webview2_runtime_path) =
|
||||
&config.tauri.bundle.windows.webview_fixed_runtime_path
|
||||
match &config.bundle.windows.webview_fixed_runtime_path {
|
||||
Some(path) => Some(path),
|
||||
None => match &config.bundle.windows.webview_install_mode {
|
||||
WebviewInstallMode::FixedRuntime { path } => Some(path),
|
||||
_ => None,
|
||||
},
|
||||
}
|
||||
{
|
||||
resources.push(fixed_webview2_runtime_path.display().to_string());
|
||||
}
|
||||
}
|
||||
copy_resources(ResourcePaths::new(resources.as_slice(), true), target_dir)?;
|
||||
match resources {
|
||||
BundleResources::List(res) => {
|
||||
copy_resources(ResourcePaths::new(res.as_slice(), true), target_dir)?
|
||||
}
|
||||
BundleResources::Map(map) => copy_resources(ResourcePaths::from_map(&map, true), target_dir)?,
|
||||
}
|
||||
|
||||
if target_triple.contains("darwin") {
|
||||
if let Some(version) = &config.tauri.bundle.macos.minimum_system_version {
|
||||
if let Some(frameworks) = &config.bundle.macos.frameworks {
|
||||
if !frameworks.is_empty() {
|
||||
let frameworks_dir = target_dir.parent().unwrap().join("Frameworks");
|
||||
let _ = std::fs::remove_dir_all(&frameworks_dir);
|
||||
// copy frameworks to the root `target` folder (instead of `target/debug` for instance)
|
||||
// because the rpath is set to `@executable_path/../Frameworks`.
|
||||
copy_frameworks(&frameworks_dir, frameworks)?;
|
||||
|
||||
// If we have frameworks, we need to set the @rpath
|
||||
// https://github.com/tauri-apps/tauri/issues/7710
|
||||
println!("cargo:rustc-link-arg=-Wl,-rpath,@executable_path/../Frameworks");
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(version) = &config.bundle.macos.minimum_system_version {
|
||||
println!("cargo:rustc-env=MACOSX_DEPLOYMENT_TARGET={version}");
|
||||
}
|
||||
}
|
||||
|
||||
if target_triple.contains("windows") {
|
||||
use anyhow::Context;
|
||||
use semver::Version;
|
||||
use tauri_winres::{VersionInfo, WindowsResource};
|
||||
|
||||
fn find_icon<F: Fn(&&String) -> bool>(config: &Config, predicate: F, default: &str) -> PathBuf {
|
||||
let icon_path = config
|
||||
.tauri
|
||||
.bundle
|
||||
.icon
|
||||
.iter()
|
||||
@@ -365,44 +573,36 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
|
||||
.window_icon_path
|
||||
.unwrap_or_else(|| find_icon(&config, |i| i.ends_with(".ico"), "icons/icon.ico"));
|
||||
|
||||
let mut res = WindowsResource::new();
|
||||
|
||||
if let Some(manifest) = attributes.windows_attributes.app_manifest {
|
||||
res.set_manifest(&manifest);
|
||||
} else {
|
||||
res.set_manifest(include_str!("window-app-manifest.xml"));
|
||||
}
|
||||
|
||||
if let Some(version_str) = &config.version {
|
||||
if let Ok(v) = Version::parse(version_str) {
|
||||
let version = v.major << 48 | v.minor << 32 | v.patch << 16;
|
||||
res.set_version_info(VersionInfo::FILEVERSION, version);
|
||||
res.set_version_info(VersionInfo::PRODUCTVERSION, version);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(product_name) = &config.product_name {
|
||||
res.set("ProductName", product_name);
|
||||
}
|
||||
|
||||
if let Some(short_description) = &config.bundle.short_description {
|
||||
res.set("FileDescription", short_description);
|
||||
}
|
||||
|
||||
if let Some(copyright) = &config.bundle.copyright {
|
||||
res.set("LegalCopyright", copyright);
|
||||
}
|
||||
|
||||
if window_icon_path.exists() {
|
||||
let mut res = WindowsResource::new();
|
||||
|
||||
if let Some(manifest) = attributes.windows_attributes.app_manifest {
|
||||
res.set_manifest(&manifest);
|
||||
} else {
|
||||
res.set_manifest(include_str!("window-app-manifest.xml"));
|
||||
}
|
||||
|
||||
if let Some(sdk_dir) = &attributes.windows_attributes.sdk_dir {
|
||||
if let Some(sdk_dir_str) = sdk_dir.to_str() {
|
||||
res.set_toolkit_path(sdk_dir_str);
|
||||
} else {
|
||||
return Err(anyhow!(
|
||||
"sdk_dir path is not valid; only UTF-8 characters are allowed"
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(version) = &config.package.version {
|
||||
if let Ok(v) = Version::parse(version) {
|
||||
let version = v.major << 48 | v.minor << 32 | v.patch << 16;
|
||||
res.set_version_info(VersionInfo::FILEVERSION, version);
|
||||
res.set_version_info(VersionInfo::PRODUCTVERSION, version);
|
||||
}
|
||||
res.set("FileVersion", version);
|
||||
res.set("ProductVersion", version);
|
||||
}
|
||||
if let Some(product_name) = &config.package.product_name {
|
||||
res.set("ProductName", product_name);
|
||||
res.set("FileDescription", product_name);
|
||||
}
|
||||
res.set_icon_with_id(&window_icon_path.display().to_string(), "32512");
|
||||
res.compile().with_context(|| {
|
||||
format!(
|
||||
"failed to compile `{}` into a Windows Resource file during tauri-build",
|
||||
window_icon_path.display()
|
||||
)
|
||||
})?;
|
||||
} else {
|
||||
return Err(anyhow!(format!(
|
||||
"`{}` not found; required for generating a Windows Resource file during tauri-build",
|
||||
@@ -410,6 +610,13 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
|
||||
)));
|
||||
}
|
||||
|
||||
res.compile().with_context(|| {
|
||||
format!(
|
||||
"failed to compile `{}` into a Windows Resource file during tauri-build",
|
||||
window_icon_path.display()
|
||||
)
|
||||
})?;
|
||||
|
||||
let target_env = std::env::var("CARGO_CFG_TARGET_ENV").unwrap();
|
||||
match target_env.as_str() {
|
||||
"gnu" => {
|
||||
@@ -443,96 +650,14 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "codegen")]
|
||||
if let Some(codegen) = attributes.codegen {
|
||||
codegen.try_build()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Eq)]
|
||||
struct Diff {
|
||||
remove: Vec<String>,
|
||||
add: Vec<String>,
|
||||
}
|
||||
|
||||
fn features_diff(current: &[String], expected: &[String]) -> Diff {
|
||||
let mut remove = Vec::new();
|
||||
let mut add = Vec::new();
|
||||
for feature in current {
|
||||
if !expected.contains(feature) {
|
||||
remove.push(feature.clone());
|
||||
}
|
||||
}
|
||||
|
||||
for feature in expected {
|
||||
if !current.contains(feature) {
|
||||
add.push(feature.clone());
|
||||
}
|
||||
}
|
||||
|
||||
Diff { remove, add }
|
||||
}
|
||||
|
||||
fn check_features(config: &Config, dependency: Dependency, is_tauri_build: bool) -> String {
|
||||
use tauri_utils::config::{PatternKind, TauriConfig};
|
||||
|
||||
let features = match dependency {
|
||||
Dependency::Simple(_) => Vec::new(),
|
||||
Dependency::Detailed(dep) => dep.features,
|
||||
Dependency::Inherited(dep) => dep.features,
|
||||
};
|
||||
|
||||
let all_cli_managed_features = if is_tauri_build {
|
||||
vec!["isolation"]
|
||||
} else {
|
||||
TauriConfig::all_features()
|
||||
};
|
||||
|
||||
let expected = if is_tauri_build {
|
||||
match config.tauri.pattern {
|
||||
PatternKind::Isolation { .. } => vec!["isolation".to_string()],
|
||||
_ => vec![],
|
||||
}
|
||||
} else {
|
||||
config
|
||||
.tauri
|
||||
.features()
|
||||
.into_iter()
|
||||
.map(|f| f.to_string())
|
||||
.collect::<Vec<String>>()
|
||||
};
|
||||
|
||||
let diff = features_diff(
|
||||
&features
|
||||
.into_iter()
|
||||
.filter(|f| all_cli_managed_features.contains(&f.as_str()))
|
||||
.collect::<Vec<String>>(),
|
||||
&expected,
|
||||
);
|
||||
|
||||
let mut error_message = String::new();
|
||||
if !diff.remove.is_empty() {
|
||||
error_message.push_str("remove the `");
|
||||
error_message.push_str(&diff.remove.join(", "));
|
||||
error_message.push_str(if diff.remove.len() == 1 {
|
||||
"` feature"
|
||||
} else {
|
||||
"` features"
|
||||
});
|
||||
if !diff.add.is_empty() {
|
||||
error_message.push_str(" and ");
|
||||
}
|
||||
}
|
||||
if !diff.add.is_empty() {
|
||||
error_message.push_str("add the `");
|
||||
error_message.push_str(&diff.add.join(", "));
|
||||
error_message.push_str(if diff.add.len() == 1 {
|
||||
"` feature"
|
||||
} else {
|
||||
"` features"
|
||||
});
|
||||
}
|
||||
|
||||
error_message
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
struct CargoMetadata {
|
||||
workspace_root: PathBuf,
|
||||
@@ -552,42 +677,3 @@ fn get_workspace_dir() -> Result<PathBuf> {
|
||||
|
||||
Ok(serde_json::from_slice::<CargoMetadata>(&output.stdout)?.workspace_root)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Diff;
|
||||
|
||||
#[test]
|
||||
fn array_diff() {
|
||||
for (current, expected, result) in [
|
||||
(vec![], vec![], Default::default()),
|
||||
(
|
||||
vec!["a".into()],
|
||||
vec![],
|
||||
Diff {
|
||||
remove: vec!["a".into()],
|
||||
add: vec![],
|
||||
},
|
||||
),
|
||||
(vec!["a".into()], vec!["a".into()], Default::default()),
|
||||
(
|
||||
vec!["a".into(), "b".into()],
|
||||
vec!["a".into()],
|
||||
Diff {
|
||||
remove: vec!["b".into()],
|
||||
add: vec![],
|
||||
},
|
||||
),
|
||||
(
|
||||
vec!["a".into(), "b".into()],
|
||||
vec!["a".into(), "c".into()],
|
||||
Diff {
|
||||
remove: vec!["b".into()],
|
||||
add: vec!["c".into()],
|
||||
},
|
||||
),
|
||||
] {
|
||||
assert_eq!(super::features_diff(¤t, &expected), result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
217
core/tauri-build/src/manifest.rs
Normal file
217
core/tauri-build/src/manifest.rs
Normal file
@@ -0,0 +1,217 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use cargo_toml::{Dependency, Manifest};
|
||||
use tauri_utils::config::{AppConfig, Config, PatternKind};
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Eq)]
|
||||
struct Diff {
|
||||
remove: Vec<String>,
|
||||
add: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum DependencyKind {
|
||||
Build,
|
||||
Normal,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct AllowlistedDependency {
|
||||
name: String,
|
||||
alias: Option<String>,
|
||||
kind: DependencyKind,
|
||||
all_cli_managed_features: Option<Vec<&'static str>>,
|
||||
expected_features: Vec<String>,
|
||||
}
|
||||
|
||||
pub fn check(config: &Config, manifest: &mut Manifest) -> Result<()> {
|
||||
let dependencies = vec![
|
||||
AllowlistedDependency {
|
||||
name: "tauri-build".into(),
|
||||
alias: None,
|
||||
kind: DependencyKind::Build,
|
||||
all_cli_managed_features: Some(vec!["isolation"]),
|
||||
expected_features: match config.app.security.pattern {
|
||||
PatternKind::Isolation { .. } => vec!["isolation".to_string()],
|
||||
_ => vec![],
|
||||
},
|
||||
},
|
||||
AllowlistedDependency {
|
||||
name: "tauri".into(),
|
||||
alias: None,
|
||||
kind: DependencyKind::Normal,
|
||||
all_cli_managed_features: Some(
|
||||
AppConfig::all_features()
|
||||
.into_iter()
|
||||
.filter(|f| f != &"tray-icon")
|
||||
.collect(),
|
||||
),
|
||||
expected_features: config
|
||||
.app
|
||||
.features()
|
||||
.into_iter()
|
||||
.filter(|f| f != &"tray-icon")
|
||||
.map(|f| f.to_string())
|
||||
.collect::<Vec<String>>(),
|
||||
},
|
||||
];
|
||||
|
||||
for metadata in dependencies {
|
||||
let mut name = metadata.name.clone();
|
||||
let mut deps = find_dependency(manifest, &metadata.name, metadata.kind);
|
||||
if deps.is_empty() {
|
||||
if let Some(alias) = &metadata.alias {
|
||||
deps = find_dependency(manifest, alias, metadata.kind);
|
||||
name = alias.clone();
|
||||
}
|
||||
}
|
||||
|
||||
for dep in deps {
|
||||
if let Err(error) = check_features(dep, &metadata) {
|
||||
return Err(anyhow!("
|
||||
The `{}` dependency features on the `Cargo.toml` file does not match the allowlist defined under `tauri.conf.json`.
|
||||
Please run `tauri dev` or `tauri build` or {}.
|
||||
", name, error));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn find_dependency(manifest: &mut Manifest, name: &str, kind: DependencyKind) -> Vec<Dependency> {
|
||||
let dep = match kind {
|
||||
DependencyKind::Build => manifest.build_dependencies.remove(name),
|
||||
DependencyKind::Normal => manifest.dependencies.remove(name),
|
||||
};
|
||||
|
||||
if let Some(dep) = dep {
|
||||
vec![dep]
|
||||
} else {
|
||||
let mut deps = Vec::new();
|
||||
for target in manifest.target.values_mut() {
|
||||
if let Some(dep) = match kind {
|
||||
DependencyKind::Build => target.build_dependencies.remove(name),
|
||||
DependencyKind::Normal => target.dependencies.remove(name),
|
||||
} {
|
||||
deps.push(dep);
|
||||
}
|
||||
}
|
||||
deps
|
||||
}
|
||||
}
|
||||
|
||||
fn features_diff(current: &[String], expected: &[String]) -> Diff {
|
||||
let mut remove = Vec::new();
|
||||
let mut add = Vec::new();
|
||||
for feature in current {
|
||||
if !expected.contains(feature) {
|
||||
remove.push(feature.clone());
|
||||
}
|
||||
}
|
||||
|
||||
for feature in expected {
|
||||
if !current.contains(feature) {
|
||||
add.push(feature.clone());
|
||||
}
|
||||
}
|
||||
|
||||
Diff { remove, add }
|
||||
}
|
||||
|
||||
fn check_features(dependency: Dependency, metadata: &AllowlistedDependency) -> Result<(), String> {
|
||||
let features = match dependency {
|
||||
Dependency::Simple(_) => Vec::new(),
|
||||
Dependency::Detailed(dep) => dep.features,
|
||||
Dependency::Inherited(dep) => dep.features,
|
||||
};
|
||||
|
||||
let diff = if let Some(all_cli_managed_features) = &metadata.all_cli_managed_features {
|
||||
features_diff(
|
||||
&features
|
||||
.into_iter()
|
||||
.filter(|f| all_cli_managed_features.contains(&f.as_str()))
|
||||
.collect::<Vec<String>>(),
|
||||
&metadata.expected_features,
|
||||
)
|
||||
} else {
|
||||
features_diff(
|
||||
&features
|
||||
.into_iter()
|
||||
.filter(|f| f.starts_with("allow-"))
|
||||
.collect::<Vec<String>>(),
|
||||
&metadata.expected_features,
|
||||
)
|
||||
};
|
||||
|
||||
let mut error_message = String::new();
|
||||
if !diff.remove.is_empty() {
|
||||
error_message.push_str("remove the `");
|
||||
error_message.push_str(&diff.remove.join(", "));
|
||||
error_message.push_str(if diff.remove.len() == 1 {
|
||||
"` feature"
|
||||
} else {
|
||||
"` features"
|
||||
});
|
||||
if !diff.add.is_empty() {
|
||||
error_message.push_str(" and ");
|
||||
}
|
||||
}
|
||||
if !diff.add.is_empty() {
|
||||
error_message.push_str("add the `");
|
||||
error_message.push_str(&diff.add.join(", "));
|
||||
error_message.push_str(if diff.add.len() == 1 {
|
||||
"` feature"
|
||||
} else {
|
||||
"` features"
|
||||
});
|
||||
}
|
||||
|
||||
if error_message.is_empty() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(error_message)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Diff;
|
||||
|
||||
#[test]
|
||||
fn array_diff() {
|
||||
for (current, expected, result) in [
|
||||
(vec![], vec![], Default::default()),
|
||||
(
|
||||
vec!["a".into()],
|
||||
vec![],
|
||||
Diff {
|
||||
remove: vec!["a".into()],
|
||||
add: vec![],
|
||||
},
|
||||
),
|
||||
(vec!["a".into()], vec!["a".into()], Default::default()),
|
||||
(
|
||||
vec!["a".into(), "b".into()],
|
||||
vec!["a".into()],
|
||||
Diff {
|
||||
remove: vec!["b".into()],
|
||||
add: vec![],
|
||||
},
|
||||
),
|
||||
(
|
||||
vec!["a".into(), "b".into()],
|
||||
vec!["a".into(), "c".into()],
|
||||
Diff {
|
||||
remove: vec!["b".into()],
|
||||
add: vec!["c".into()],
|
||||
},
|
||||
),
|
||||
] {
|
||||
assert_eq!(crate::manifest::features_diff(¤t, &expected), result);
|
||||
}
|
||||
}
|
||||
}
|
||||
60
core/tauri-build/src/mobile.rs
Normal file
60
core/tauri-build/src/mobile.rs
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use std::{fs::write, path::PathBuf};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
|
||||
pub fn generate_gradle_files(project_dir: PathBuf) -> Result<()> {
|
||||
let gradle_settings_path = project_dir.join("tauri.settings.gradle");
|
||||
let app_build_gradle_path = project_dir.join("app").join("tauri.build.gradle.kts");
|
||||
|
||||
let mut gradle_settings =
|
||||
"// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.\n".to_string();
|
||||
let mut app_build_gradle = "// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
val implementation by configurations
|
||||
dependencies {"
|
||||
.to_string();
|
||||
|
||||
for (env, value) in std::env::vars_os() {
|
||||
let env = env.to_string_lossy();
|
||||
if env.starts_with("DEP_") && env.ends_with("_ANDROID_LIBRARY_PATH") {
|
||||
let name_len = env.len() - "DEP_".len() - "_ANDROID_LIBRARY_PATH".len();
|
||||
let mut plugin_name = env
|
||||
.chars()
|
||||
.skip("DEP_".len())
|
||||
.take(name_len)
|
||||
.collect::<String>()
|
||||
.to_lowercase()
|
||||
.replace('_', "-");
|
||||
if plugin_name == "tauri" {
|
||||
plugin_name = "tauri-android".into();
|
||||
}
|
||||
let plugin_path = PathBuf::from(value);
|
||||
|
||||
gradle_settings.push_str(&format!("include ':{plugin_name}'"));
|
||||
gradle_settings.push('\n');
|
||||
gradle_settings.push_str(&format!(
|
||||
"project(':{plugin_name}').projectDir = new File({:?})",
|
||||
tauri_utils::display_path(plugin_path)
|
||||
));
|
||||
gradle_settings.push('\n');
|
||||
|
||||
app_build_gradle.push('\n');
|
||||
app_build_gradle.push_str(&format!(r#" implementation(project(":{plugin_name}"))"#));
|
||||
}
|
||||
}
|
||||
|
||||
app_build_gradle.push_str("\n}");
|
||||
|
||||
write(&gradle_settings_path, gradle_settings).context("failed to write tauri.settings.gradle")?;
|
||||
|
||||
write(&app_build_gradle_path, app_build_gradle)
|
||||
.context("failed to write tauri.build.gradle.kts")?;
|
||||
|
||||
println!("cargo:rerun-if-changed={}", gradle_settings_path.display());
|
||||
println!("cargo:rerun-if-changed={}", app_build_gradle_path.display());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,5 +1,147 @@
|
||||
# Changelog
|
||||
|
||||
## \[2.0.0-beta.0]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`74a2a603`](https://www.github.com/tauri-apps/tauri/commit/74a2a6036a5e57462f161d728cbd8a6f121028ca)([#8661](https://www.github.com/tauri-apps/tauri/pull/8661)) Implement access control list for IPC usage.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.0`
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- [`8de308d1`](https://www.github.com/tauri-apps/tauri/commit/8de308d1bf6a855d7a26af58bd0e744938ba47d8)([#8723](https://www.github.com/tauri-apps/tauri/pull/8723)) Restructured Tauri config per [RFC#5](https://github.com/tauri-apps/rfcs/blob/f3e82a6b0c5390401e855850d47dc7b7d9afd684/texts/0005-tauri-config-restructure.md):
|
||||
|
||||
- Moved `package.productName`, `package.version` and `tauri.bundle.identifier` fields to the top-level.
|
||||
- Removed `package` object.
|
||||
- Renamed `tauri` object to `app`.
|
||||
- Moved `tauri.bundle` object to the top-level.
|
||||
- Renamed `build.distDir` field to `frontendDist`.
|
||||
- Renamed `build.devPath` field to `devUrl` and will no longer accepts paths, it will only accept URLs.
|
||||
- Moved `tauri.pattern` to `app.security.pattern`.
|
||||
- Removed `tauri.bundle.updater` object, and its fields have been moved to the updater plugin under `plugins.updater` object.
|
||||
- Moved `build.withGlobalTauri` to `app.withGlobalTauri`.
|
||||
- Moved `tauri.bundle.dmg` object to `bundle.macOS.dmg`.
|
||||
- Moved `tauri.bundle.deb` object to `bundle.linux.deb`.
|
||||
- Moved `tauri.bundle.appimage` object to `bundle.linux.appimage`.
|
||||
- Removed all license fields from each bundle configuration object and instead added `bundle.license` and `bundle.licenseFile`.
|
||||
- Renamed `AppUrl` to `FrontendDist` and refactored its variants to be more explicit.
|
||||
|
||||
## \[2.0.0-alpha.13]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.13`
|
||||
|
||||
## \[2.0.0-alpha.12]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.12`
|
||||
|
||||
## \[2.0.0-alpha.11]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.11`
|
||||
|
||||
## \[2.0.0-alpha.10]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`c6c59cf2`](https://www.github.com/tauri-apps/tauri/commit/c6c59cf2373258b626b00a26f4de4331765dd487) Pull changes from Tauri 1.5 release.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.10`
|
||||
|
||||
## \[2.0.0-alpha.9]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`880266a7`](https://www.github.com/tauri-apps/tauri/commit/880266a7f697e1fe58d685de3bb6836ce5251e92)([#8031](https://www.github.com/tauri-apps/tauri/pull/8031)) Bump the MSRV to 1.70.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.9`
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- [`ebcc21e4`](https://www.github.com/tauri-apps/tauri/commit/ebcc21e4b95f4e8c27639fb1bca545b432f52d5e)([#8057](https://www.github.com/tauri-apps/tauri/pull/8057)) Renamed the beforeDevCommand, beforeBuildCommand and beforeBundleCommand hooks environment variables from `TAURI_PLATFORM, TAURI_ARCH, TAURI_FAMILY, TAURI_PLATFORM_VERSION, TAURI_PLATFORM_TYPE and TAURI_DEBUG` to `TAURI_ENV_PLATFORM, TAURI_ENV_ARCH, TAURI_ENV_FAMILY, TAURI_ENV_PLATFORM_VERSION, TAURI_ENV_PLATFORM_TYPE and TAURI_ENV_DEBUG` to differentiate the prefix with other CLI environment variables.
|
||||
|
||||
## \[2.0.0-alpha.8]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`100d9ede`](https://www.github.com/tauri-apps/tauri/commit/100d9ede35995d9db21d2087dd5606adfafb89a5)([#7802](https://www.github.com/tauri-apps/tauri/pull/7802)) Use `Target` enum from `tauri_utils::platform`.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.8`
|
||||
|
||||
## \[2.0.0-alpha.7]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.7`
|
||||
|
||||
## \[2.0.0-alpha.6]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Updated to latest `tauri-utils`
|
||||
|
||||
## \[2.0.0-alpha.5]
|
||||
|
||||
- [`96639ca2`](https://www.github.com/tauri-apps/tauri/commit/96639ca239c9e4f75142fc07868ac46822111cff)([#6749](https://www.github.com/tauri-apps/tauri/pull/6749)) Moved the `shell` functionality to its own plugin in the plugins-workspace repository.
|
||||
- [`3188f376`](https://www.github.com/tauri-apps/tauri/commit/3188f3764978c6d1452ee31d5a91469691e95094)([#6883](https://www.github.com/tauri-apps/tauri/pull/6883)) Bump the MSRV to 1.65.
|
||||
- [`ae102980`](https://www.github.com/tauri-apps/tauri/commit/ae102980fcdde3f55effdc0623ea425b48d07dd1)([#6719](https://www.github.com/tauri-apps/tauri/pull/6719)) Refactor the `Context` conditional fields and only parse the tray icon on desktop.
|
||||
|
||||
## \[2.0.0-alpha.4]
|
||||
|
||||
- Added `android` configuration object under `tauri > bundle`.
|
||||
- Bumped due to a bump in tauri-utils.
|
||||
- [db4c9dc6](https://www.github.com/tauri-apps/tauri/commit/db4c9dc655e07ee2184fe04571f500f7910890cd) feat(core): add option to configure Android's minimum SDK version ([#6651](https://www.github.com/tauri-apps/tauri/pull/6651)) on 2023-04-07
|
||||
|
||||
## \[2.0.0-alpha.3]
|
||||
|
||||
- Pull changes from Tauri 1.3 release.
|
||||
- [](https://www.github.com/tauri-apps/tauri/commit/undefined) on undefined
|
||||
|
||||
## \[2.0.0-alpha.2]
|
||||
|
||||
- Return `bool` in the invoke handler.
|
||||
- [05dad087](https://www.github.com/tauri-apps/tauri/commit/05dad0876842e2a7334431247d49365cee835d3e) feat: initial work for iOS plugins ([#6205](https://www.github.com/tauri-apps/tauri/pull/6205)) on 2023-02-11
|
||||
|
||||
## \[2.0.0-alpha.1]
|
||||
|
||||
- Bump the MSRV to 1.64.
|
||||
- [7eb9aa75](https://www.github.com/tauri-apps/tauri/commit/7eb9aa75cfd6a3176d3f566fdda02d88aa529b0f) Update gtk to 0.16 ([#6155](https://www.github.com/tauri-apps/tauri/pull/6155)) on 2023-01-30
|
||||
- Added `crate_name` field on `PackageInfo`.
|
||||
- [630a7f4b](https://www.github.com/tauri-apps/tauri/commit/630a7f4b18cef169bfd48673609306fec434e397) refactor: remove mobile log initialization, ref [#6049](https://www.github.com/tauri-apps/tauri/pull/6049) ([#6081](https://www.github.com/tauri-apps/tauri/pull/6081)) on 2023-01-17
|
||||
|
||||
## \[2.0.0-alpha.0]
|
||||
|
||||
- Change `devPath` URL to use the local IP address on iOS and Android.
|
||||
- [6f061504](https://www.github.com/tauri-apps/tauri/commit/6f0615044d09ec58393a7ebca5e45bb175e20db3) feat(cli): add `android dev` and `ios dev` commands ([#4982](https://www.github.com/tauri-apps/tauri/pull/4982)) on 2022-08-20
|
||||
- First mobile alpha release!
|
||||
- [fa3a1098](https://www.github.com/tauri-apps/tauri/commit/fa3a10988a03aed1b66fb17d893b1a9adb90f7cd) feat(ci): prepare 2.0.0-alpha.0 ([#5786](https://www.github.com/tauri-apps/tauri/pull/5786)) on 2022-12-08
|
||||
|
||||
## \[1.4.1]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@1.5.0`
|
||||
|
||||
## \[1.4.0]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`17d5a4f5`](https://www.github.com/tauri-apps/tauri/commit/17d5a4f51f244d3ff42014b5d1b075fad7c636a5)([#6706](https://www.github.com/tauri-apps/tauri/pull/6706)) Early panic if the PNG icon is not RGBA.
|
||||
- [`d2710e9d`](https://www.github.com/tauri-apps/tauri/commit/d2710e9d2e8fd93975ef6494512370faa8cb3b7e)([#6944](https://www.github.com/tauri-apps/tauri/pull/6944)) Unpin `time`, `ignore`, and `winnow` crate versions. Developers now have to pin crates if needed themselves. A list of crates that need pinning to adhere to Tauri's MSRV will be visible in Tauri's GitHub workflow: https://github.com/tauri-apps/tauri/blob/dev/.github/workflows/test-core.yml#L85.
|
||||
|
||||
## \[1.3.0]
|
||||
|
||||
- Bump minimum supported Rust version to 1.60.
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
[package]
|
||||
name = "tauri-codegen"
|
||||
version = "1.3.0"
|
||||
authors = [ "Tauri Programme within The Commons Conservancy" ]
|
||||
categories = [ "gui", "web-programming" ]
|
||||
license = "Apache-2.0 OR MIT"
|
||||
homepage = "https://tauri.app"
|
||||
repository = "https://github.com/tauri-apps/tauri/tree/dev/core/tauri-codegen"
|
||||
version = "2.0.0-beta.0"
|
||||
description = "code generation meant to be consumed inside of `tauri` through `tauri-build` or `tauri-macros`"
|
||||
edition = "2021"
|
||||
rust-version = "1.60"
|
||||
exclude = [ "CHANGELOG.md", "/target" ]
|
||||
readme = "README.md"
|
||||
authors = { workspace = true }
|
||||
homepage = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
categories = { workspace = true }
|
||||
license = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
|
||||
[dependencies]
|
||||
sha2 = "0.10"
|
||||
@@ -19,25 +19,25 @@ proc-macro2 = "1"
|
||||
quote = "1"
|
||||
serde = { version = "1", features = [ "derive" ] }
|
||||
serde_json = "1"
|
||||
tauri-utils = { version = "1.3.0", path = "../tauri-utils", features = [ "build" ] }
|
||||
tauri-utils = { version = "2.0.0-beta.0", path = "../tauri-utils", features = [ "build" ] }
|
||||
thiserror = "1"
|
||||
walkdir = "2"
|
||||
brotli = { version = "3", optional = true, default-features = false, features = [ "std" ] }
|
||||
regex = { version = "1.7.1", optional = true }
|
||||
regex = { version = "1", optional = true }
|
||||
uuid = { version = "1", features = [ "v4" ] }
|
||||
semver = "1"
|
||||
ico = "0.3"
|
||||
png = "0.17"
|
||||
json-patch = "1.0"
|
||||
json-patch = "1.2"
|
||||
url = "2"
|
||||
|
||||
[target."cfg(target_os = \"macos\")".dependencies]
|
||||
plist = "1"
|
||||
time = { version = "=0.3.15", features = [ "parsing", "formatting" ] }
|
||||
time = { version = "0.3", features = [ "parsing", "formatting" ] }
|
||||
|
||||
[features]
|
||||
default = [ "compression" ]
|
||||
compression = [ "brotli", "tauri-utils/compression" ]
|
||||
isolation = [ "tauri-utils/isolation" ]
|
||||
shell-scope = [ "regex" ]
|
||||
config-json5 = [ "tauri-utils/config-json5" ]
|
||||
config-toml = [ "tauri-utils/config-toml" ]
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
[](https://discord.gg/SpmNs4S)
|
||||
[](https://dev.to/tauri)
|
||||
|
||||

|
||||
[](https://github.com/tauri-apps/tauri/actions/workflows/test-core.yml)
|
||||
[](https://tauri.app)
|
||||
|
||||
[](https://good-labs.github.io/greater-good-affirmation)
|
||||
@@ -24,7 +24,7 @@ Tauri apps can have custom menus and have tray-type interfaces. They can be upda
|
||||
|
||||
## This module
|
||||
|
||||
- Embed, hash, and compress assets, including icons for the app as well as the system-tray.
|
||||
- Embed, hash, and compress assets, including icons for the app as well as the tray icon.
|
||||
- Parse `tauri.conf.json` at compile time and generate the Config struct.
|
||||
|
||||
To learn more about the details of how all of these pieces fit together, please consult this [ARCHITECTURE.md](https://github.com/tauri-apps/tauri/blob/dev/ARCHITECTURE.md) document.
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::{ffi::OsStr, str::FromStr};
|
||||
|
||||
@@ -10,17 +11,21 @@ use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
use tauri_utils::acl::capability::Capability;
|
||||
use tauri_utils::acl::plugin::Manifest;
|
||||
use tauri_utils::acl::resolved::Resolved;
|
||||
use tauri_utils::assets::AssetKey;
|
||||
use tauri_utils::config::{AppUrl, Config, PatternKind, WindowUrl};
|
||||
use tauri_utils::config::{Config, FrontendDist, PatternKind};
|
||||
use tauri_utils::html::{
|
||||
inject_nonce_token, parse as parse_html, serialize_node as serialize_html_node,
|
||||
};
|
||||
|
||||
#[cfg(feature = "shell-scope")]
|
||||
use tauri_utils::config::{ShellAllowedArg, ShellAllowedArgs, ShellAllowlistScope};
|
||||
use tauri_utils::platform::Target;
|
||||
|
||||
use crate::embedded_assets::{AssetOptions, CspHashes, EmbeddedAssets, EmbeddedAssetsError};
|
||||
|
||||
const PLUGIN_MANIFESTS_FILE_NAME: &str = "plugin-manifests.json";
|
||||
const CAPABILITIES_FILE_NAME: &str = "capabilities.json";
|
||||
|
||||
/// Necessary data needed by [`context_codegen`] to generate code for a Tauri application context.
|
||||
pub struct ContextData {
|
||||
pub dev: bool,
|
||||
@@ -42,13 +47,13 @@ fn map_core_assets(
|
||||
if path.extension() == Some(OsStr::new("html")) {
|
||||
#[allow(clippy::collapsible_if)]
|
||||
if csp {
|
||||
let mut document = parse_html(String::from_utf8_lossy(input).into_owned());
|
||||
let document = parse_html(String::from_utf8_lossy(input).into_owned());
|
||||
|
||||
if target == Target::Linux {
|
||||
::tauri_utils::html::inject_csp_token(&mut document);
|
||||
::tauri_utils::html::inject_csp_token(&document);
|
||||
}
|
||||
|
||||
inject_nonce_token(&mut document, &dangerous_disable_asset_csp_modification);
|
||||
inject_nonce_token(&document, &dangerous_disable_asset_csp_modification);
|
||||
|
||||
if dangerous_disable_asset_csp_modification.can_modify("script-src") {
|
||||
if let Ok(inline_script_elements) = document.select("script:not(empty)") {
|
||||
@@ -99,14 +104,13 @@ fn map_isolation(
|
||||
) -> impl Fn(&AssetKey, &Path, &mut Vec<u8>, &mut CspHashes) -> Result<(), EmbeddedAssetsError> {
|
||||
move |_key, path, input, _csp_hashes| {
|
||||
if path.extension() == Some(OsStr::new("html")) {
|
||||
let mut isolation_html =
|
||||
tauri_utils::html::parse(String::from_utf8_lossy(input).into_owned());
|
||||
let isolation_html = tauri_utils::html::parse(String::from_utf8_lossy(input).into_owned());
|
||||
|
||||
// this is appended, so no need to reverse order it
|
||||
tauri_utils::html::inject_codegen_isolation_script(&mut isolation_html);
|
||||
tauri_utils::html::inject_codegen_isolation_script(&isolation_html);
|
||||
|
||||
// temporary workaround for windows not loading assets
|
||||
tauri_utils::html::inline_isolation(&mut isolation_html, &dir);
|
||||
tauri_utils::html::inline_isolation(&isolation_html, &dir);
|
||||
|
||||
*input = isolation_html.to_string().as_bytes().to_vec()
|
||||
}
|
||||
@@ -115,16 +119,6 @@ fn map_isolation(
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||
enum Target {
|
||||
Linux,
|
||||
Windows,
|
||||
Darwin,
|
||||
Android,
|
||||
// iOS.
|
||||
Ios,
|
||||
}
|
||||
|
||||
/// Build a `tauri::Context` for including in application code.
|
||||
pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsError> {
|
||||
let ContextData {
|
||||
@@ -134,94 +128,63 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
||||
root,
|
||||
} = data;
|
||||
|
||||
let target = if let Ok(target) = std::env::var("TARGET") {
|
||||
if target.contains("unknown-linux") {
|
||||
Target::Linux
|
||||
} else if target.contains("pc-windows") {
|
||||
Target::Windows
|
||||
} else if target.contains("apple-darwin") {
|
||||
Target::Darwin
|
||||
} else if target.contains("android") {
|
||||
Target::Android
|
||||
} else if target.contains("apple-ios") {
|
||||
Target::Ios
|
||||
} else {
|
||||
panic!("unknown codegen target {target}");
|
||||
}
|
||||
} else if cfg!(target_os = "linux") {
|
||||
Target::Linux
|
||||
} else if cfg!(windows) {
|
||||
Target::Windows
|
||||
} else if cfg!(target_os = "macos") {
|
||||
Target::Darwin
|
||||
} else if cfg!(target_os = "android") {
|
||||
Target::Android
|
||||
} else if cfg!(target_os = "ios") {
|
||||
Target::Ios
|
||||
} else {
|
||||
panic!("unknown codegen target");
|
||||
};
|
||||
let target = std::env::var("TARGET")
|
||||
.or_else(|_| std::env::var("TAURI_ENV_TARGET_TRIPLE"))
|
||||
.as_deref()
|
||||
.map(Target::from_triple)
|
||||
.unwrap_or_else(|_| Target::current());
|
||||
|
||||
let mut options = AssetOptions::new(config.tauri.pattern.clone())
|
||||
.freeze_prototype(config.tauri.security.freeze_prototype)
|
||||
let mut options = AssetOptions::new(config.app.security.pattern.clone())
|
||||
.freeze_prototype(config.app.security.freeze_prototype)
|
||||
.dangerous_disable_asset_csp_modification(
|
||||
config
|
||||
.tauri
|
||||
.app
|
||||
.security
|
||||
.dangerous_disable_asset_csp_modification
|
||||
.clone(),
|
||||
);
|
||||
let csp = if dev {
|
||||
config
|
||||
.tauri
|
||||
.app
|
||||
.security
|
||||
.dev_csp
|
||||
.clone()
|
||||
.or_else(|| config.tauri.security.csp.clone())
|
||||
.as_ref()
|
||||
.or(config.app.security.csp.as_ref())
|
||||
} else {
|
||||
config.tauri.security.csp.clone()
|
||||
config.app.security.csp.as_ref()
|
||||
};
|
||||
if csp.is_some() {
|
||||
options = options.with_csp();
|
||||
}
|
||||
|
||||
let app_url = if dev {
|
||||
&config.build.dev_path
|
||||
let assets = if dev && config.build.dev_url.is_some() {
|
||||
Default::default()
|
||||
} else {
|
||||
&config.build.dist_dir
|
||||
};
|
||||
|
||||
let assets = match app_url {
|
||||
AppUrl::Url(url) => match url {
|
||||
WindowUrl::External(_) => Default::default(),
|
||||
WindowUrl::App(path) => {
|
||||
if path.components().count() == 0 {
|
||||
panic!(
|
||||
"The `{}` configuration cannot be empty",
|
||||
if dev { "devPath" } else { "distDir" }
|
||||
)
|
||||
match &config.build.frontend_dist {
|
||||
Some(url) => match url {
|
||||
FrontendDist::Url(_url) => Default::default(),
|
||||
FrontendDist::Directory(path) => {
|
||||
let assets_path = config_parent.join(path);
|
||||
if !assets_path.exists() {
|
||||
panic!(
|
||||
"The `frontendDist` configuration is set to `{:?}` but this path doesn't exist",
|
||||
path
|
||||
)
|
||||
}
|
||||
EmbeddedAssets::new(assets_path, &options, map_core_assets(&options, target))?
|
||||
}
|
||||
let assets_path = config_parent.join(path);
|
||||
if !assets_path.exists() {
|
||||
panic!(
|
||||
"The `{}` configuration is set to `{:?}` but this path doesn't exist",
|
||||
if dev { "devPath" } else { "distDir" },
|
||||
path
|
||||
)
|
||||
}
|
||||
EmbeddedAssets::new(assets_path, &options, map_core_assets(&options, target))?
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
},
|
||||
AppUrl::Files(files) => EmbeddedAssets::new(
|
||||
files
|
||||
.iter()
|
||||
.map(|p| config_parent.join(p))
|
||||
.collect::<Vec<_>>(),
|
||||
&options,
|
||||
map_core_assets(&options, target),
|
||||
)?,
|
||||
_ => unimplemented!(),
|
||||
FrontendDist::Files(files) => EmbeddedAssets::new(
|
||||
files
|
||||
.iter()
|
||||
.map(|p| config_parent.join(p))
|
||||
.collect::<Vec<_>>(),
|
||||
&options,
|
||||
map_core_assets(&options, target),
|
||||
)?,
|
||||
_ => unimplemented!(),
|
||||
},
|
||||
None => Default::default(),
|
||||
}
|
||||
};
|
||||
|
||||
let out_dir = {
|
||||
@@ -246,7 +209,7 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
||||
"icons/icon.ico",
|
||||
);
|
||||
if icon_path.exists() {
|
||||
ico_icon(&root, &out_dir, icon_path)?
|
||||
ico_icon(&root, &out_dir, icon_path).map(|i| quote!(::std::option::Option::Some(#i)))?
|
||||
} else {
|
||||
let icon_path = find_icon(
|
||||
&config,
|
||||
@@ -254,23 +217,21 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
||||
|i| i.ends_with(".png"),
|
||||
"icons/icon.png",
|
||||
);
|
||||
png_icon(&root, &out_dir, icon_path)?
|
||||
png_icon(&root, &out_dir, icon_path).map(|i| quote!(::std::option::Option::Some(#i)))?
|
||||
}
|
||||
} else if target == Target::Linux {
|
||||
// handle default window icons for Linux targets
|
||||
} else {
|
||||
// handle default window icons for Unix targets
|
||||
let icon_path = find_icon(
|
||||
&config,
|
||||
&config_parent,
|
||||
|i| i.ends_with(".png"),
|
||||
"icons/icon.png",
|
||||
);
|
||||
png_icon(&root, &out_dir, icon_path)?
|
||||
} else {
|
||||
quote!(None)
|
||||
png_icon(&root, &out_dir, icon_path).map(|i| quote!(::std::option::Option::Some(#i)))?
|
||||
}
|
||||
};
|
||||
|
||||
let app_icon = if target == Target::Darwin && dev {
|
||||
let app_icon = if target == Target::MacOS && dev {
|
||||
let mut icon_path = find_icon(
|
||||
&config,
|
||||
&config_parent,
|
||||
@@ -287,15 +248,15 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
||||
}
|
||||
raw_icon(&out_dir, icon_path)?
|
||||
} else {
|
||||
quote!(None)
|
||||
quote!(::std::option::Option::None)
|
||||
};
|
||||
|
||||
let package_name = if let Some(product_name) = &config.package.product_name {
|
||||
let package_name = if let Some(product_name) = &config.product_name {
|
||||
quote!(#product_name.to_string())
|
||||
} else {
|
||||
quote!(env!("CARGO_PKG_NAME").to_string())
|
||||
};
|
||||
let package_version = if let Some(version) = &config.package.version {
|
||||
let package_version = if let Some(version) = &config.version {
|
||||
semver::Version::from_str(version)?;
|
||||
quote!(#version.to_string())
|
||||
} else {
|
||||
@@ -307,27 +268,34 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
||||
version: #package_version.parse().unwrap(),
|
||||
authors: env!("CARGO_PKG_AUTHORS"),
|
||||
description: env!("CARGO_PKG_DESCRIPTION"),
|
||||
crate_name: env!("CARGO_PKG_NAME"),
|
||||
}
|
||||
);
|
||||
|
||||
let system_tray_icon = if let Some(tray) = &config.tauri.system_tray {
|
||||
let system_tray_icon_path = config_parent.join(&tray.icon_path);
|
||||
let ext = system_tray_icon_path.extension();
|
||||
if ext.map_or(false, |e| e == "ico") {
|
||||
ico_icon(&root, &out_dir, system_tray_icon_path)?
|
||||
} else if ext.map_or(false, |e| e == "png") {
|
||||
png_icon(&root, &out_dir, system_tray_icon_path)?
|
||||
let with_tray_icon_code = if target.is_desktop() {
|
||||
if let Some(tray) = &config.app.tray_icon {
|
||||
let tray_icon_icon_path = config_parent.join(&tray.icon_path);
|
||||
let ext = tray_icon_icon_path.extension();
|
||||
if ext.map_or(false, |e| e == "ico") {
|
||||
ico_icon(&root, &out_dir, tray_icon_icon_path)
|
||||
.map(|i| quote!(context.set_tray_icon(#i);))?
|
||||
} else if ext.map_or(false, |e| e == "png") {
|
||||
png_icon(&root, &out_dir, tray_icon_icon_path)
|
||||
.map(|i| quote!(context.set_tray_icon(#i);))?
|
||||
} else {
|
||||
quote!(compile_error!(
|
||||
"The tray icon extension must be either `.ico` or `.png`."
|
||||
))
|
||||
}
|
||||
} else {
|
||||
quote!(compile_error!(
|
||||
"The tray icon extension must be either `.ico` or `.png`."
|
||||
))
|
||||
quote!()
|
||||
}
|
||||
} else {
|
||||
quote!(None)
|
||||
quote!()
|
||||
};
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
let info_plist = if target == Target::Darwin && dev {
|
||||
let info_plist = if target == Target::MacOS && dev {
|
||||
let info_plist_path = config_parent.join("Info.plist");
|
||||
let mut info_plist = if info_plist_path.exists() {
|
||||
plist::Value::from_file(&info_plist_path)
|
||||
@@ -337,10 +305,10 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
||||
};
|
||||
|
||||
if let Some(plist) = info_plist.as_dictionary_mut() {
|
||||
if let Some(product_name) = &config.package.product_name {
|
||||
if let Some(product_name) = &config.product_name {
|
||||
plist.insert("CFBundleName".into(), product_name.clone().into());
|
||||
}
|
||||
if let Some(version) = &config.package.version {
|
||||
if let Some(version) = &config.version {
|
||||
plist.insert("CFBundleShortVersionString".into(), version.clone().into());
|
||||
}
|
||||
let format =
|
||||
@@ -350,14 +318,11 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
||||
}
|
||||
}
|
||||
|
||||
let out_path = out_dir.join("Info.plist");
|
||||
info_plist
|
||||
.to_file_xml(&out_path)
|
||||
.to_file_xml(out_dir.join("Info.plist"))
|
||||
.expect("failed to write Info.plist");
|
||||
|
||||
let info_plist_path = out_path.display().to_string();
|
||||
quote!({
|
||||
tauri::embed_plist::embed_info_plist!(#info_plist_path);
|
||||
tauri::embed_plist::embed_info_plist!(concat!(std::env!("OUT_DIR"), "/Info.plist"));
|
||||
})
|
||||
} else {
|
||||
quote!(())
|
||||
@@ -406,51 +371,41 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
||||
}
|
||||
};
|
||||
|
||||
#[cfg(feature = "shell-scope")]
|
||||
let shell_scope_config = {
|
||||
use regex::Regex;
|
||||
use tauri_utils::config::ShellAllowlistOpen;
|
||||
|
||||
let shell_scopes = get_allowed_clis(&root, &config.tauri.allowlist.shell.scope);
|
||||
|
||||
let shell_scope_open = match &config.tauri.allowlist.shell.open {
|
||||
ShellAllowlistOpen::Flag(false) => quote!(::std::option::Option::None),
|
||||
ShellAllowlistOpen::Flag(true) => {
|
||||
quote!(::std::option::Option::Some(#root::regex::Regex::new(r#"^((mailto:\w+)|(tel:\w+)|(https?://\w+)).+"#).unwrap()))
|
||||
}
|
||||
ShellAllowlistOpen::Validate(regex) => match Regex::new(regex) {
|
||||
Ok(_) => quote!(::std::option::Option::Some(#root::regex::Regex::new(#regex).unwrap())),
|
||||
Err(error) => {
|
||||
let error = error.to_string();
|
||||
quote!({
|
||||
compile_error!(#error);
|
||||
::std::option::Option::Some(#root::regex::Regex::new(#regex).unwrap())
|
||||
})
|
||||
}
|
||||
},
|
||||
_ => panic!("unknown shell open format, unable to prepare"),
|
||||
};
|
||||
|
||||
quote!(#root::ShellScopeConfig {
|
||||
open: #shell_scope_open,
|
||||
scopes: #shell_scopes
|
||||
})
|
||||
let acl_file_path = out_dir.join(PLUGIN_MANIFESTS_FILE_NAME);
|
||||
let acl: BTreeMap<String, Manifest> = if acl_file_path.exists() {
|
||||
let acl_file =
|
||||
std::fs::read_to_string(acl_file_path).expect("failed to read plugin manifest map");
|
||||
serde_json::from_str(&acl_file).expect("failed to parse plugin manifest map")
|
||||
} else {
|
||||
Default::default()
|
||||
};
|
||||
|
||||
#[cfg(not(feature = "shell-scope"))]
|
||||
let shell_scope_config = quote!();
|
||||
let capabilities_file_path = out_dir.join(CAPABILITIES_FILE_NAME);
|
||||
let capabilities: BTreeMap<String, Capability> = if capabilities_file_path.exists() {
|
||||
let capabilities_file =
|
||||
std::fs::read_to_string(capabilities_file_path).expect("failed to read capabilities");
|
||||
serde_json::from_str(&capabilities_file).expect("failed to parse capabilities")
|
||||
} else {
|
||||
Default::default()
|
||||
};
|
||||
|
||||
Ok(quote!(#root::Context::new(
|
||||
#config,
|
||||
::std::sync::Arc::new(#assets),
|
||||
#default_window_icon,
|
||||
#app_icon,
|
||||
#system_tray_icon,
|
||||
#package_info,
|
||||
#info_plist,
|
||||
#pattern,
|
||||
#shell_scope_config
|
||||
)))
|
||||
let resolved_acl = Resolved::resolve(acl, capabilities, target).expect("failed to resolve ACL");
|
||||
|
||||
Ok(quote!({
|
||||
#[allow(unused_mut, clippy::let_and_return)]
|
||||
let mut context = #root::Context::new(
|
||||
#config,
|
||||
::std::boxed::Box::new(#assets),
|
||||
#default_window_icon,
|
||||
#app_icon,
|
||||
#package_info,
|
||||
#info_plist,
|
||||
#pattern,
|
||||
#resolved_acl
|
||||
);
|
||||
#with_tray_icon_code
|
||||
context
|
||||
}))
|
||||
}
|
||||
|
||||
fn ico_icon<P: AsRef<Path>>(
|
||||
@@ -473,15 +428,19 @@ fn ico_icon<P: AsRef<Path>>(
|
||||
let width = entry.width();
|
||||
let height = entry.height();
|
||||
|
||||
let out_path = out_dir.join(path.file_name().unwrap());
|
||||
let icon_file_name = path.file_name().unwrap();
|
||||
let out_path = out_dir.join(icon_file_name);
|
||||
write_if_changed(&out_path, &rgba).map_err(|error| EmbeddedAssetsError::AssetWrite {
|
||||
path: path.to_owned(),
|
||||
error,
|
||||
})?;
|
||||
|
||||
let out_path = out_path.display().to_string();
|
||||
|
||||
let icon = quote!(Some(#root::Icon::Rgba { rgba: include_bytes!(#out_path).to_vec(), width: #width, height: #height }));
|
||||
let icon_file_name = icon_file_name.to_str().unwrap();
|
||||
let icon = quote!(#root::Icon::Rgba {
|
||||
rgba: include_bytes!(concat!(std::env!("OUT_DIR"), "/", #icon_file_name)).to_vec(),
|
||||
width: #width,
|
||||
height: #height
|
||||
});
|
||||
Ok(icon)
|
||||
}
|
||||
|
||||
@@ -497,9 +456,10 @@ fn raw_icon<P: AsRef<Path>>(out_dir: &Path, path: P) -> Result<TokenStream, Embe
|
||||
error,
|
||||
})?;
|
||||
|
||||
let out_path = out_path.display().to_string();
|
||||
|
||||
let icon = quote!(Some(include_bytes!(#out_path).to_vec()));
|
||||
let icon_path = path.file_name().unwrap().to_str().unwrap().to_string();
|
||||
let icon = quote!(::std::option::Option::Some(
|
||||
include_bytes!(concat!(std::env!("OUT_DIR"), "/", #icon_path)).to_vec()
|
||||
));
|
||||
Ok(icon)
|
||||
}
|
||||
|
||||
@@ -516,6 +476,13 @@ fn png_icon<P: AsRef<Path>>(
|
||||
let mut reader = decoder
|
||||
.read_info()
|
||||
.unwrap_or_else(|e| panic!("failed to read icon {}: {}", path.display(), e));
|
||||
|
||||
let (color_type, _) = reader.output_color_type();
|
||||
|
||||
if color_type != png::ColorType::Rgba {
|
||||
panic!("icon {} is not RGBA", path.display());
|
||||
}
|
||||
|
||||
let mut buffer: Vec<u8> = Vec::new();
|
||||
while let Ok(Some(row)) = reader.next_row() {
|
||||
buffer.extend(row.data());
|
||||
@@ -523,15 +490,19 @@ fn png_icon<P: AsRef<Path>>(
|
||||
let width = reader.info().width;
|
||||
let height = reader.info().height;
|
||||
|
||||
let out_path = out_dir.join(path.file_name().unwrap());
|
||||
let icon_file_name = path.file_name().unwrap();
|
||||
let out_path = out_dir.join(icon_file_name);
|
||||
write_if_changed(&out_path, &buffer).map_err(|error| EmbeddedAssetsError::AssetWrite {
|
||||
path: path.to_owned(),
|
||||
error,
|
||||
})?;
|
||||
|
||||
let out_path = out_path.display().to_string();
|
||||
|
||||
let icon = quote!(Some(#root::Icon::Rgba { rgba: include_bytes!(#out_path).to_vec(), width: #width, height: #height }));
|
||||
let icon_file_name = icon_file_name.to_str().unwrap();
|
||||
let icon = quote!(#root::Icon::Rgba {
|
||||
rgba: include_bytes!(concat!(std::env!("OUT_DIR"), "/", #icon_file_name)).to_vec(),
|
||||
width: #width,
|
||||
height: #height,
|
||||
});
|
||||
Ok(icon)
|
||||
}
|
||||
|
||||
@@ -556,7 +527,6 @@ fn find_icon<F: Fn(&&String) -> bool>(
|
||||
default: &str,
|
||||
) -> PathBuf {
|
||||
let icon_path = config
|
||||
.tauri
|
||||
.bundle
|
||||
.icon
|
||||
.iter()
|
||||
@@ -565,78 +535,3 @@ fn find_icon<F: Fn(&&String) -> bool>(
|
||||
.unwrap_or_else(|| default.to_string());
|
||||
config_parent.join(icon_path)
|
||||
}
|
||||
|
||||
#[cfg(feature = "shell-scope")]
|
||||
fn get_allowed_clis(root: &TokenStream, scope: &ShellAllowlistScope) -> TokenStream {
|
||||
let commands = scope
|
||||
.0
|
||||
.iter()
|
||||
.map(|scope| {
|
||||
let sidecar = &scope.sidecar;
|
||||
|
||||
let name = &scope.name;
|
||||
let name = quote!(#name.into());
|
||||
|
||||
let command = scope.command.to_string_lossy();
|
||||
let command = quote!(::std::path::PathBuf::from(#command));
|
||||
|
||||
let args = match &scope.args {
|
||||
ShellAllowedArgs::Flag(true) => quote!(::std::option::Option::None),
|
||||
ShellAllowedArgs::Flag(false) => quote!(::std::option::Option::Some(::std::vec![])),
|
||||
ShellAllowedArgs::List(list) => {
|
||||
let list = list.iter().map(|arg| match arg {
|
||||
ShellAllowedArg::Fixed(fixed) => {
|
||||
quote!(#root::scope::ShellScopeAllowedArg::Fixed(#fixed.into()))
|
||||
}
|
||||
ShellAllowedArg::Var { validator } => {
|
||||
let validator = match regex::Regex::new(validator) {
|
||||
Ok(regex) => {
|
||||
let regex = regex.as_str();
|
||||
quote!(#root::regex::Regex::new(#regex).unwrap())
|
||||
}
|
||||
Err(error) => {
|
||||
let error = error.to_string();
|
||||
quote!({
|
||||
compile_error!(#error);
|
||||
#root::regex::Regex::new(#validator).unwrap()
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
quote!(#root::scope::ShellScopeAllowedArg::Var { validator: #validator })
|
||||
}
|
||||
_ => panic!("unknown shell scope arg, unable to prepare"),
|
||||
});
|
||||
|
||||
quote!(::std::option::Option::Some(::std::vec![#(#list),*]))
|
||||
}
|
||||
_ => panic!("unknown shell scope command, unable to prepare"),
|
||||
};
|
||||
|
||||
(
|
||||
quote!(#name),
|
||||
quote!(
|
||||
#root::scope::ShellScopeAllowedCommand {
|
||||
command: #command,
|
||||
args: #args,
|
||||
sidecar: #sidecar,
|
||||
}
|
||||
),
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if commands.is_empty() {
|
||||
quote!(::std::collections::HashMap::new())
|
||||
} else {
|
||||
let insertions = commands
|
||||
.iter()
|
||||
.map(|(name, value)| quote!(hashmap.insert(#name, #value);));
|
||||
|
||||
quote!({
|
||||
let mut hashmap = ::std::collections::HashMap::new();
|
||||
#(#insertions)*
|
||||
hashmap
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -433,7 +433,7 @@ impl ToTokens for EmbeddedAssets {
|
||||
|
||||
// we expect phf related items to be in path when generating the path code
|
||||
tokens.append_all(quote! {{
|
||||
#[allow(unused)]
|
||||
#[allow(unused_imports)]
|
||||
use ::tauri::utils::assets::{CspHash, EmbeddedAssets, phf, phf::phf_map};
|
||||
EmbeddedAssets::new(phf_map! { #assets }, &[#global_hashes], phf_map! { #html_hashes })
|
||||
}});
|
||||
|
||||
@@ -2,6 +2,16 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//! [](https://tauri.app)
|
||||
//!
|
||||
//! - Embed, hash, and compress assets, including icons for the app as well as the tray icon.
|
||||
//! - Parse `tauri.conf.json` at compile time and generate the Config struct.
|
||||
|
||||
#![doc(
|
||||
html_logo_url = "https://github.com/tauri-apps/tauri/raw/dev/app-icon.png",
|
||||
html_favicon_url = "https://github.com/tauri-apps/tauri/raw/dev/app-icon.png"
|
||||
)]
|
||||
|
||||
pub use self::context::{context_codegen, ContextData};
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
@@ -57,7 +67,10 @@ pub fn get_config(path: &Path) -> Result<(Config, PathBuf), CodegenConfigError>
|
||||
// it is impossible for the content of two separate configs to get mixed up. The chances are
|
||||
// already unlikely unless the developer goes out of their way to run the cli on a different
|
||||
// project than the target crate.
|
||||
let mut config = serde_json::from_value(tauri_utils::config::parse::read_from(parent.clone())?)?;
|
||||
let mut config = serde_json::from_value(tauri_utils::config::parse::read_from(
|
||||
tauri_utils::platform::Target::current(),
|
||||
parent.clone(),
|
||||
)?)?;
|
||||
if let Ok(env) = std::env::var("TAURI_CONFIG") {
|
||||
let merge_config: serde_json::Value =
|
||||
serde_json::from_str(&env).map_err(CodegenConfigError::FormatInline)?;
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
[package]
|
||||
name = "tauri-tauri-config-schema"
|
||||
name = "tauri-config-schema"
|
||||
version = "0.0.0"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[build-dependencies]
|
||||
tauri-utils = { version = "1.0.0", features = [
|
||||
"schema",
|
||||
], path = "../tauri-utils" }
|
||||
tauri-utils = { features = [ "schema" ], path = "../tauri-utils" }
|
||||
schemars = { version = "0.8", features = ["url", "preserve_order"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
serde_with = "1.12"
|
||||
url = { version = "2.3", features = ["serde"] }
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,4 +2,13 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//! [](https://tauri.app)
|
||||
//!
|
||||
//! Hosts the schema for the Tauri configuration file.
|
||||
|
||||
#![doc(
|
||||
html_logo_url = "https://github.com/tauri-apps/tauri/raw/dev/app-icon.png",
|
||||
html_favicon_url = "https://github.com/tauri-apps/tauri/raw/dev/app-icon.png"
|
||||
)]
|
||||
|
||||
fn main() {}
|
||||
|
||||
@@ -1,5 +1,158 @@
|
||||
# Changelog
|
||||
|
||||
## \[2.0.0-beta.0]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`74a2a603`](https://www.github.com/tauri-apps/tauri/commit/74a2a6036a5e57462f161d728cbd8a6f121028ca)([#8661](https://www.github.com/tauri-apps/tauri/pull/8661)) Implement access control list for IPC usage.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.0`
|
||||
- Upgraded to `tauri-codegen@2.0.0-beta.0`
|
||||
|
||||
## \[2.0.0-alpha.13]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`d621d343`](https://www.github.com/tauri-apps/tauri/commit/d621d3437ce3947175eecf345b2c6d1c4c7ce020)([#8607](https://www.github.com/tauri-apps/tauri/pull/8607)) Added tracing for window startup, plugins, `Window::eval`, events, IPC, updater and custom protocol request handlers behind the `tracing` feature flag.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.13`
|
||||
- Upgraded to `tauri-codegen@2.0.0-alpha.13`
|
||||
|
||||
## \[2.0.0-alpha.12]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.12`
|
||||
- Upgraded to `tauri-codegen@2.0.0-alpha.12`
|
||||
|
||||
## \[2.0.0-alpha.11]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.11`
|
||||
- Upgraded to `tauri-codegen@2.0.0-alpha.11`
|
||||
- [`b6ed4ecb`](https://www.github.com/tauri-apps/tauri/commit/b6ed4ecb3730c346c973f1b34aa0de1b7d43ac44)([#7634](https://www.github.com/tauri-apps/tauri/pull/7634)) Update to syn v2.
|
||||
|
||||
## \[2.0.0-alpha.10]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`c6c59cf2`](https://www.github.com/tauri-apps/tauri/commit/c6c59cf2373258b626b00a26f4de4331765dd487) Pull changes from Tauri 1.5 release.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-codegen@2.0.0-alpha.10`
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.10`
|
||||
|
||||
## \[2.0.0-alpha.9]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`880266a7`](https://www.github.com/tauri-apps/tauri/commit/880266a7f697e1fe58d685de3bb6836ce5251e92)([#8031](https://www.github.com/tauri-apps/tauri/pull/8031)) Bump the MSRV to 1.70.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.9`
|
||||
- Upgraded to `tauri-codegen@2.0.0-alpha.9`
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- [`ebcc21e4`](https://www.github.com/tauri-apps/tauri/commit/ebcc21e4b95f4e8c27639fb1bca545b432f52d5e)([#8057](https://www.github.com/tauri-apps/tauri/pull/8057)) Renamed the beforeDevCommand, beforeBuildCommand and beforeBundleCommand hooks environment variables from `TAURI_PLATFORM, TAURI_ARCH, TAURI_FAMILY, TAURI_PLATFORM_VERSION, TAURI_PLATFORM_TYPE and TAURI_DEBUG` to `TAURI_ENV_PLATFORM, TAURI_ENV_ARCH, TAURI_ENV_FAMILY, TAURI_ENV_PLATFORM_VERSION, TAURI_ENV_PLATFORM_TYPE and TAURI_ENV_DEBUG` to differentiate the prefix with other CLI environment variables.
|
||||
|
||||
## \[2.0.0-alpha.8]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`100d9ede`](https://www.github.com/tauri-apps/tauri/commit/100d9ede35995d9db21d2087dd5606adfafb89a5)([#7802](https://www.github.com/tauri-apps/tauri/pull/7802)) Use `Target` enum from `tauri_utils::platform`.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-codegen@2.0.0-alpha.8`
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.8`
|
||||
|
||||
## \[2.0.0-alpha.7]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.7`
|
||||
- Upgraded to `tauri-codegen@2.0.0-alpha.7`
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- [`fbeb5b91`](https://www.github.com/tauri-apps/tauri/commit/fbeb5b9185baeda19e865228179e3e44c165f1d9)([#7170](https://www.github.com/tauri-apps/tauri/pull/7170)) Moved `tauri::api::ipc` to `tauri::ipc` and refactored all types.
|
||||
|
||||
## \[2.0.0-alpha.6]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Updated to latest `tauri-utils`
|
||||
|
||||
## \[2.0.0-alpha.5]
|
||||
|
||||
- [`7a4b1fb9`](https://www.github.com/tauri-apps/tauri/commit/7a4b1fb96da475053c61960f362bbecf18cd00d4)([#6839](https://www.github.com/tauri-apps/tauri/pull/6839)) Added support to attibutes for each command path in the `generate_handler` macro.
|
||||
- [`96639ca2`](https://www.github.com/tauri-apps/tauri/commit/96639ca239c9e4f75142fc07868ac46822111cff)([#6749](https://www.github.com/tauri-apps/tauri/pull/6749)) Moved the `shell` functionality to its own plugin in the plugins-workspace repository.
|
||||
- [`3188f376`](https://www.github.com/tauri-apps/tauri/commit/3188f3764978c6d1452ee31d5a91469691e95094)([#6883](https://www.github.com/tauri-apps/tauri/pull/6883)) Bump the MSRV to 1.65.
|
||||
- [`9a79dc08`](https://www.github.com/tauri-apps/tauri/commit/9a79dc085870e0c1a5df13481ff271b8c6cc3b78)([#6947](https://www.github.com/tauri-apps/tauri/pull/6947)) Removed the module command macros.
|
||||
|
||||
## \[2.0.0-alpha.4]
|
||||
|
||||
- Added `android` configuration object under `tauri > bundle`.
|
||||
- Bumped due to a bump in tauri-utils.
|
||||
- [db4c9dc6](https://www.github.com/tauri-apps/tauri/commit/db4c9dc655e07ee2184fe04571f500f7910890cd) feat(core): add option to configure Android's minimum SDK version ([#6651](https://www.github.com/tauri-apps/tauri/pull/6651)) on 2023-04-07
|
||||
|
||||
## \[2.0.0-alpha.3]
|
||||
|
||||
- Pull changes from Tauri 1.3 release.
|
||||
- [](https://www.github.com/tauri-apps/tauri/commit/undefined) on undefined
|
||||
|
||||
## \[2.0.0-alpha.2]
|
||||
|
||||
- Resolve Android package name from single word bundle identifiers.
|
||||
- [60a8b07d](https://www.github.com/tauri-apps/tauri/commit/60a8b07dc7c56c9c45331cb57d9afb410e7eadf3) fix: handle single word bundle identifier when resolving Android domain ([#6313](https://www.github.com/tauri-apps/tauri/pull/6313)) on 2023-02-19
|
||||
- Return `bool` in the invoke handler.
|
||||
- [05dad087](https://www.github.com/tauri-apps/tauri/commit/05dad0876842e2a7334431247d49365cee835d3e) feat: initial work for iOS plugins ([#6205](https://www.github.com/tauri-apps/tauri/pull/6205)) on 2023-02-11
|
||||
- Refactored the implementation of the `mobile_entry_point` macro.
|
||||
- [9feab904](https://www.github.com/tauri-apps/tauri/commit/9feab904bf08b5c168d4779c21d0419409a68d30) feat(core): add API to call Android plugin ([#6239](https://www.github.com/tauri-apps/tauri/pull/6239)) on 2023-02-10
|
||||
|
||||
## \[2.0.0-alpha.1]
|
||||
|
||||
- Refactor mobile environment variables.
|
||||
- [dee9460f](https://www.github.com/tauri-apps/tauri/commit/dee9460f9c9bc92e9c638e7691e616849ac2085b) feat: keep CLI alive when iOS app exits, show logs, closes [#5855](https://www.github.com/tauri-apps/tauri/pull/5855) ([#5902](https://www.github.com/tauri-apps/tauri/pull/5902)) on 2022-12-27
|
||||
- Bump the MSRV to 1.64.
|
||||
- [7eb9aa75](https://www.github.com/tauri-apps/tauri/commit/7eb9aa75cfd6a3176d3f566fdda02d88aa529b0f) Update gtk to 0.16 ([#6155](https://www.github.com/tauri-apps/tauri/pull/6155)) on 2023-01-30
|
||||
- Removed mobile logging initialization, which will be handled by `tauri-plugin-log`.
|
||||
- [](https://www.github.com/tauri-apps/tauri/commit/undefined) on undefined
|
||||
|
||||
## \[2.0.0-alpha.0]
|
||||
|
||||
- Added the `mobile_entry_point` macro.
|
||||
- [98904863](https://www.github.com/tauri-apps/tauri/commit/9890486321c9c79ccfb7c547fafee85b5c3ffa71) feat(core): add `mobile_entry_point` macro ([#4983](https://www.github.com/tauri-apps/tauri/pull/4983)) on 2022-08-21
|
||||
- First mobile alpha release!
|
||||
- [fa3a1098](https://www.github.com/tauri-apps/tauri/commit/fa3a10988a03aed1b66fb17d893b1a9adb90f7cd) feat(ci): prepare 2.0.0-alpha.0 ([#5786](https://www.github.com/tauri-apps/tauri/pull/5786)) on 2022-12-08
|
||||
|
||||
## \[1.4.2]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`5e05236b`](https://www.github.com/tauri-apps/tauri/commit/5e05236b4987346697c7caae0567d3c50714c198)([#8289](https://www.github.com/tauri-apps/tauri/pull/8289)) Added tracing for window startup, plugins, `Window::eval`, events, IPC, updater and custom protocol request handlers behind the `tracing` feature flag.
|
||||
|
||||
## \[1.4.1]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@1.5.0`
|
||||
- Upgraded to `tauri-codegen@1.4.1`
|
||||
|
||||
## \[1.4.0]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`d68a25e3`](https://www.github.com/tauri-apps/tauri/commit/d68a25e32e012e57a9e5225b589b9ecbea70a887)([#6124](https://www.github.com/tauri-apps/tauri/pull/6124)) Improve compiler error message when generating an async command that has a reference input and don't return a Result.
|
||||
|
||||
## \[1.3.0]
|
||||
|
||||
- Bump minimum supported Rust version to 1.60.
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
[package]
|
||||
name = "tauri-macros"
|
||||
version = "1.3.0"
|
||||
authors = [ "Tauri Programme within The Commons Conservancy" ]
|
||||
categories = [ "gui", "os", "filesystem", "web-programming" ]
|
||||
license = "Apache-2.0 OR MIT"
|
||||
homepage = "https://tauri.app"
|
||||
repository = "https://github.com/tauri-apps/tauri"
|
||||
version = "2.0.0-beta.0"
|
||||
description = "Macros for the tauri crate."
|
||||
edition = "2021"
|
||||
rust-version = "1.60"
|
||||
exclude = [ "CHANGELOG.md", "/target" ]
|
||||
readme = "README.md"
|
||||
authors = { workspace = true }
|
||||
homepage = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
categories = { workspace = true }
|
||||
license = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1"
|
||||
proc-macro2 = { version = "1", features = [ "span-locations" ] }
|
||||
quote = "1"
|
||||
syn = { version = "1", features = [ "full" ] }
|
||||
syn = { version = "2", features = [ "full" ] }
|
||||
heck = "0.4"
|
||||
tauri-codegen = { version = "1.3.0", default-features = false, path = "../tauri-codegen" }
|
||||
tauri-utils = { version = "1.3.0", path = "../tauri-utils" }
|
||||
tauri-codegen = { version = "2.0.0-beta.0", default-features = false, path = "../tauri-codegen" }
|
||||
tauri-utils = { version = "2.0.0-beta.0", path = "../tauri-utils" }
|
||||
|
||||
[features]
|
||||
custom-protocol = [ ]
|
||||
compression = [ "tauri-codegen/compression" ]
|
||||
isolation = [ "tauri-codegen/isolation" ]
|
||||
shell-scope = [ "tauri-codegen/shell-scope" ]
|
||||
config-json5 = [ "tauri-codegen/config-json5", "tauri-utils/config-json5" ]
|
||||
config-toml = [ "tauri-codegen/config-toml", "tauri-utils/config-toml" ]
|
||||
tracing = [ ]
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
[](https://github.com/tauri-apps/tauri/tree/dev)
|
||||
[](https://opencollective.com/tauri)
|
||||
[](https://github.com/tauri-apps/tauri/actions?query=workflow%3A%22test+library%22)
|
||||
[](https://github.com/tauri-apps/tauri/actions/workflows/test-core.yml)
|
||||
[](https://app.fossa.com/projects/git%2Bgithub.com%2Ftauri-apps%2Ftauri?ref=badge_shield)
|
||||
[](https://discord.gg/SpmNs4S)
|
||||
[](https://tauri.app)
|
||||
|
||||
@@ -4,26 +4,40 @@
|
||||
|
||||
use quote::format_ident;
|
||||
use syn::{
|
||||
parse::{Parse, ParseBuffer},
|
||||
Ident, Path, Token,
|
||||
parse::{Parse, ParseBuffer, ParseStream},
|
||||
Attribute, Ident, Path, Token,
|
||||
};
|
||||
|
||||
struct CommandDef {
|
||||
path: Path,
|
||||
attrs: Vec<Attribute>,
|
||||
}
|
||||
|
||||
impl Parse for CommandDef {
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
let attrs = input.call(Attribute::parse_outer)?;
|
||||
let path = input.parse()?;
|
||||
|
||||
Ok(CommandDef { path, attrs })
|
||||
}
|
||||
}
|
||||
|
||||
/// The items parsed from [`generate_handle!`](crate::generate_handle).
|
||||
pub struct Handler {
|
||||
paths: Vec<Path>,
|
||||
command_defs: Vec<CommandDef>,
|
||||
commands: Vec<Ident>,
|
||||
wrappers: Vec<Path>,
|
||||
}
|
||||
|
||||
impl Parse for Handler {
|
||||
fn parse(input: &ParseBuffer<'_>) -> syn::Result<Self> {
|
||||
let paths = input.parse_terminated::<Path, Token![,]>(Path::parse)?;
|
||||
let command_defs = input.parse_terminated(CommandDef::parse, Token![,])?;
|
||||
|
||||
// parse the command names and wrappers from the passed paths
|
||||
let (commands, wrappers) = paths
|
||||
let (commands, wrappers) = command_defs
|
||||
.iter()
|
||||
.map(|path| {
|
||||
let mut wrapper = path.clone();
|
||||
.map(|command_def| {
|
||||
let mut wrapper = command_def.path.clone();
|
||||
let last = super::path_to_command(&mut wrapper);
|
||||
|
||||
// the name of the actual command function
|
||||
@@ -37,7 +51,7 @@ impl Parse for Handler {
|
||||
.unzip();
|
||||
|
||||
Ok(Self {
|
||||
paths: paths.into_iter().collect(), // remove punctuation separators
|
||||
command_defs: command_defs.into_iter().collect(), // remove punctuation separators
|
||||
commands,
|
||||
wrappers,
|
||||
})
|
||||
@@ -47,19 +61,23 @@ impl Parse for Handler {
|
||||
impl From<Handler> for proc_macro::TokenStream {
|
||||
fn from(
|
||||
Handler {
|
||||
paths,
|
||||
command_defs,
|
||||
commands,
|
||||
wrappers,
|
||||
}: Handler,
|
||||
) -> Self {
|
||||
let cmd = format_ident!("__tauri_cmd__");
|
||||
let invoke = format_ident!("__tauri_invoke__");
|
||||
let (paths, attrs): (Vec<Path>, Vec<Vec<Attribute>>) = command_defs
|
||||
.into_iter()
|
||||
.map(|def| (def.path, def.attrs))
|
||||
.unzip();
|
||||
quote::quote!(move |#invoke| {
|
||||
let #cmd = #invoke.message.command();
|
||||
match #cmd {
|
||||
#(stringify!(#commands) => #wrappers!(#paths, #invoke),)*
|
||||
#(#(#attrs)* stringify!(#commands) => #wrappers!(#paths, #invoke),)*
|
||||
_ => {
|
||||
#invoke.resolver.reject(format!("command {} not found", #cmd))
|
||||
return false;
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
@@ -2,19 +2,40 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use std::env::var;
|
||||
|
||||
use heck::{ToLowerCamelCase, ToSnakeCase};
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use quote::{format_ident, quote};
|
||||
use proc_macro2::{Ident, Span, TokenStream as TokenStream2};
|
||||
use quote::{format_ident, quote, quote_spanned};
|
||||
use syn::{
|
||||
ext::IdentExt,
|
||||
parse::{Parse, ParseStream},
|
||||
parse_macro_input,
|
||||
punctuated::Punctuated,
|
||||
spanned::Spanned,
|
||||
FnArg, Ident, ItemFn, Lit, Meta, Pat, Token, Visibility,
|
||||
Expr, ExprLit, FnArg, ItemFn, Lit, Meta, Pat, Token, Visibility,
|
||||
};
|
||||
|
||||
enum WrapperAttributeKind {
|
||||
Meta(Meta),
|
||||
Async,
|
||||
}
|
||||
|
||||
impl Parse for WrapperAttributeKind {
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
match input.parse::<Meta>() {
|
||||
Ok(m) => Ok(Self::Meta(m)),
|
||||
Err(e) => match input.parse::<Token![async]>() {
|
||||
Ok(_) => Ok(Self::Async),
|
||||
Err(_) => Err(e),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct WrapperAttributes {
|
||||
root: TokenStream2,
|
||||
execution_context: ExecutionContext,
|
||||
argument_case: ArgumentCase,
|
||||
}
|
||||
@@ -22,16 +43,24 @@ struct WrapperAttributes {
|
||||
impl Parse for WrapperAttributes {
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
let mut wrapper_attributes = WrapperAttributes {
|
||||
root: quote!(::tauri),
|
||||
execution_context: ExecutionContext::Blocking,
|
||||
argument_case: ArgumentCase::Camel,
|
||||
};
|
||||
|
||||
loop {
|
||||
match input.parse::<Meta>() {
|
||||
Ok(Meta::List(_)) => {}
|
||||
Ok(Meta::NameValue(v)) => {
|
||||
let attrs = Punctuated::<WrapperAttributeKind, Token![,]>::parse_terminated(input)?;
|
||||
for attr in attrs {
|
||||
match attr {
|
||||
WrapperAttributeKind::Meta(Meta::List(_)) => {
|
||||
return Err(syn::Error::new(input.span(), "unexpected list input"));
|
||||
}
|
||||
WrapperAttributeKind::Meta(Meta::NameValue(v)) => {
|
||||
if v.path.is_ident("rename_all") {
|
||||
if let Lit::Str(s) = v.lit {
|
||||
if let Expr::Lit(ExprLit {
|
||||
lit: Lit::Str(s),
|
||||
attrs: _,
|
||||
}) = v.value
|
||||
{
|
||||
wrapper_attributes.argument_case = match s.value().as_str() {
|
||||
"snake_case" => ArgumentCase::Snake,
|
||||
"camelCase" => ArgumentCase::Camel,
|
||||
@@ -43,23 +72,32 @@ impl Parse for WrapperAttributes {
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Meta::Path(p)) => {
|
||||
if p.is_ident("async") {
|
||||
wrapper_attributes.execution_context = ExecutionContext::Async;
|
||||
} else {
|
||||
return Err(syn::Error::new(p.span(), "expected `async`"));
|
||||
}
|
||||
}
|
||||
Err(_e) => {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if v.path.is_ident("root") {
|
||||
if let Expr::Lit(ExprLit {
|
||||
lit: Lit::Str(s),
|
||||
attrs: _,
|
||||
}) = v.value
|
||||
{
|
||||
let lit = s.value();
|
||||
|
||||
let lookahead = input.lookahead1();
|
||||
if lookahead.peek(Token![,]) {
|
||||
input.parse::<Token![,]>()?;
|
||||
wrapper_attributes.root = if lit == "crate" {
|
||||
quote!($crate)
|
||||
} else {
|
||||
let ident = Ident::new(&lit, Span::call_site());
|
||||
quote!(#ident)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
WrapperAttributeKind::Meta(Meta::Path(_)) => {
|
||||
return Err(syn::Error::new(
|
||||
input.span(),
|
||||
"unexpected input, expected one of `rename_all`, `root`, `async`",
|
||||
));
|
||||
}
|
||||
WrapperAttributeKind::Async => {
|
||||
wrapper_attributes.execution_context = ExecutionContext::Async;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,43 +122,140 @@ enum ArgumentCase {
|
||||
struct Invoke {
|
||||
message: Ident,
|
||||
resolver: Ident,
|
||||
acl: Ident,
|
||||
}
|
||||
|
||||
/// Create a new [`Wrapper`] from the function and the generated code parsed from the function.
|
||||
pub fn wrapper(attributes: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let mut attrs = parse_macro_input!(attributes as WrapperAttributes);
|
||||
let function = parse_macro_input!(item as ItemFn);
|
||||
let wrapper = super::format_command_wrapper(&function.sig.ident);
|
||||
let visibility = &function.vis;
|
||||
|
||||
if function.sig.asyncness.is_some() {
|
||||
attrs.execution_context = ExecutionContext::Async;
|
||||
}
|
||||
|
||||
// macros used with `pub use my_macro;` need to be exported with `#[macro_export]`
|
||||
let maybe_macro_export = match &function.vis {
|
||||
Visibility::Public(_) => quote!(#[macro_export]),
|
||||
_ => Default::default(),
|
||||
Visibility::Public(_) | Visibility::Restricted(_) => quote!(#[macro_export]),
|
||||
_ => TokenStream2::default(),
|
||||
};
|
||||
|
||||
let invoke = Invoke {
|
||||
message: format_ident!("__tauri_message__"),
|
||||
resolver: format_ident!("__tauri_resolver__"),
|
||||
acl: format_ident!("__tauri_acl__"),
|
||||
};
|
||||
|
||||
// body to the command wrapper or a `compile_error!` of an error occurred while parsing it.
|
||||
let body = syn::parse::<WrapperAttributes>(attributes)
|
||||
.map(|mut attrs| {
|
||||
if function.sig.asyncness.is_some() {
|
||||
attrs.execution_context = ExecutionContext::Async;
|
||||
}
|
||||
attrs
|
||||
})
|
||||
.and_then(|attrs| match attrs.execution_context {
|
||||
ExecutionContext::Async => body_async(&function, &invoke, attrs.argument_case),
|
||||
ExecutionContext::Blocking => body_blocking(&function, &invoke, attrs.argument_case),
|
||||
})
|
||||
.unwrap_or_else(syn::Error::into_compile_error);
|
||||
// Tauri currently doesn't support async commands that take a reference as input and don't return
|
||||
// a result. See: https://github.com/tauri-apps/tauri/issues/2533
|
||||
//
|
||||
// For now, we provide an informative error message to the user in that case. Once #2533 is
|
||||
// resolved, this check can be removed.
|
||||
let mut async_command_check = TokenStream2::new();
|
||||
if function.sig.asyncness.is_some() {
|
||||
// This check won't catch all possible problems but it should catch the most common ones.
|
||||
let mut ref_argument_span = None;
|
||||
|
||||
let Invoke { message, resolver } = invoke;
|
||||
for arg in &function.sig.inputs {
|
||||
if let syn::FnArg::Typed(pat) = arg {
|
||||
match &*pat.ty {
|
||||
syn::Type::Reference(_) => {
|
||||
ref_argument_span = Some(pat.span());
|
||||
}
|
||||
syn::Type::Path(path) => {
|
||||
// Check if the type contains a lifetime argument
|
||||
let last = path.path.segments.last().unwrap();
|
||||
if let syn::PathArguments::AngleBracketed(args) = &last.arguments {
|
||||
if args
|
||||
.args
|
||||
.iter()
|
||||
.any(|arg| matches!(arg, syn::GenericArgument::Lifetime(_)))
|
||||
{
|
||||
ref_argument_span = Some(pat.span());
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if let Some(span) = ref_argument_span {
|
||||
if let syn::ReturnType::Type(_, return_type) = &function.sig.output {
|
||||
// To check if the return type is `Result` we require it to check a trait that is
|
||||
// only implemented by `Result`. That way we don't exclude renamed result types
|
||||
// which we wouldn't otherwise be able to detect purely from the token stream.
|
||||
// The "error message" displayed to the user is simply the trait name.
|
||||
async_command_check = quote_spanned! {return_type.span() =>
|
||||
#[allow(unreachable_code, clippy::diverging_sub_expression)]
|
||||
const _: () = if false {
|
||||
trait AsyncCommandMustReturnResult {}
|
||||
impl<A, B> AsyncCommandMustReturnResult for ::std::result::Result<A, B> {}
|
||||
let _check: #return_type = unreachable!();
|
||||
let _: &dyn AsyncCommandMustReturnResult = &_check;
|
||||
};
|
||||
};
|
||||
} else {
|
||||
return quote_spanned! {
|
||||
span => compile_error!("async commands that contain references as inputs must return a `Result`");
|
||||
}.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let plugin_name = var("CARGO_PKG_NAME")
|
||||
.expect("missing `CARGO_PKG_NAME` environment variable")
|
||||
.strip_prefix("tauri-plugin-")
|
||||
.map(|name| quote!(::core::option::Option::Some(#name)))
|
||||
.unwrap_or_else(|| quote!(::core::option::Option::None));
|
||||
|
||||
let body = match attrs.execution_context {
|
||||
ExecutionContext::Async => body_async(&plugin_name, &function, &invoke, &attrs)
|
||||
.unwrap_or_else(syn::Error::into_compile_error),
|
||||
ExecutionContext::Blocking => body_blocking(&plugin_name, &function, &invoke, &attrs)
|
||||
.unwrap_or_else(syn::Error::into_compile_error),
|
||||
};
|
||||
|
||||
let Invoke {
|
||||
message,
|
||||
resolver,
|
||||
acl,
|
||||
} = invoke;
|
||||
|
||||
let root = attrs.root;
|
||||
|
||||
let kind = match attrs.execution_context {
|
||||
ExecutionContext::Async if function.sig.asyncness.is_none() => "sync_threadpool",
|
||||
ExecutionContext::Async => "async",
|
||||
ExecutionContext::Blocking => "sync",
|
||||
};
|
||||
|
||||
let loc = function.span().start();
|
||||
let line = loc.line;
|
||||
let col = loc.column;
|
||||
|
||||
let maybe_span = if cfg!(feature = "tracing") {
|
||||
quote!({
|
||||
let _span = tracing::debug_span!(
|
||||
"ipc::request::handler",
|
||||
cmd = #message.command(),
|
||||
kind = #kind,
|
||||
loc.line = #line,
|
||||
loc.col = #col,
|
||||
is_internal = false,
|
||||
)
|
||||
.entered();
|
||||
})
|
||||
} else {
|
||||
quote!()
|
||||
};
|
||||
|
||||
// Rely on rust 2018 edition to allow importing a macro from a path.
|
||||
quote!(
|
||||
#async_command_check
|
||||
|
||||
#function
|
||||
|
||||
#maybe_macro_export
|
||||
@@ -129,10 +264,12 @@ pub fn wrapper(attributes: TokenStream, item: TokenStream) -> TokenStream {
|
||||
// double braces because the item is expected to be a block expression
|
||||
($path:path, $invoke:ident) => {{
|
||||
#[allow(unused_imports)]
|
||||
use ::tauri::command::private::*;
|
||||
use #root::ipc::private::*;
|
||||
// prevent warnings when the body is a `compile_error!` or if the command has no arguments
|
||||
#[allow(unused_variables)]
|
||||
let ::tauri::Invoke { message: #message, resolver: #resolver } = $invoke;
|
||||
let #root::ipc::Invoke { message: #message, resolver: #resolver, acl: #acl } = $invoke;
|
||||
|
||||
#maybe_span
|
||||
|
||||
#body
|
||||
}};
|
||||
@@ -150,15 +287,40 @@ pub fn wrapper(attributes: TokenStream, item: TokenStream) -> TokenStream {
|
||||
/// See the [`tauri::command`] module for all the items and traits that make this possible.
|
||||
///
|
||||
/// [`tauri::command`]: https://docs.rs/tauri/*/tauri/runtime/index.html
|
||||
fn body_async(function: &ItemFn, invoke: &Invoke, case: ArgumentCase) -> syn::Result<TokenStream2> {
|
||||
let Invoke { message, resolver } = invoke;
|
||||
parse_args(function, message, case).map(|args| {
|
||||
fn body_async(
|
||||
plugin_name: &TokenStream2,
|
||||
function: &ItemFn,
|
||||
invoke: &Invoke,
|
||||
attributes: &WrapperAttributes,
|
||||
) -> syn::Result<TokenStream2> {
|
||||
let Invoke {
|
||||
message,
|
||||
resolver,
|
||||
acl,
|
||||
} = invoke;
|
||||
parse_args(plugin_name, function, message, acl, attributes).map(|args| {
|
||||
#[cfg(feature = "tracing")]
|
||||
quote! {
|
||||
use tracing::Instrument;
|
||||
|
||||
let span = tracing::debug_span!("ipc::request::run");
|
||||
#resolver.respond_async_serialized(async move {
|
||||
let result = $path(#(#args?),*);
|
||||
let kind = (&result).async_kind();
|
||||
kind.future(result).await
|
||||
}
|
||||
.instrument(span));
|
||||
return true;
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "tracing"))]
|
||||
quote! {
|
||||
#resolver.respond_async_serialized(async move {
|
||||
let result = $path(#(#args?),*);
|
||||
let kind = (&result).async_kind();
|
||||
kind.future(result).await
|
||||
});
|
||||
return true;
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -169,46 +331,72 @@ fn body_async(function: &ItemFn, invoke: &Invoke, case: ArgumentCase) -> syn::Re
|
||||
///
|
||||
/// [`tauri::command`]: https://docs.rs/tauri/*/tauri/runtime/index.html
|
||||
fn body_blocking(
|
||||
plugin_name: &TokenStream2,
|
||||
function: &ItemFn,
|
||||
invoke: &Invoke,
|
||||
case: ArgumentCase,
|
||||
attributes: &WrapperAttributes,
|
||||
) -> syn::Result<TokenStream2> {
|
||||
let Invoke { message, resolver } = invoke;
|
||||
let args = parse_args(function, message, case)?;
|
||||
let Invoke {
|
||||
message,
|
||||
resolver,
|
||||
acl,
|
||||
} = invoke;
|
||||
let args = parse_args(plugin_name, function, message, acl, attributes)?;
|
||||
|
||||
// the body of a `match` to early return any argument that wasn't successful in parsing.
|
||||
let match_body = quote!({
|
||||
Ok(arg) => arg,
|
||||
Err(err) => return #resolver.invoke_error(err),
|
||||
Err(err) => { #resolver.invoke_error(err); return true },
|
||||
});
|
||||
|
||||
let maybe_span = if cfg!(feature = "tracing") {
|
||||
quote!(let _span = tracing::debug_span!("ipc::request::run").entered();)
|
||||
} else {
|
||||
quote!()
|
||||
};
|
||||
|
||||
Ok(quote! {
|
||||
#maybe_span
|
||||
let result = $path(#(match #args #match_body),*);
|
||||
let kind = (&result).blocking_kind();
|
||||
kind.block(result, #resolver);
|
||||
return true;
|
||||
})
|
||||
}
|
||||
|
||||
/// Parse all arguments for the command wrapper to use from the signature of the command function.
|
||||
fn parse_args(
|
||||
plugin_name: &TokenStream2,
|
||||
function: &ItemFn,
|
||||
message: &Ident,
|
||||
case: ArgumentCase,
|
||||
acl: &Ident,
|
||||
attributes: &WrapperAttributes,
|
||||
) -> syn::Result<Vec<TokenStream2>> {
|
||||
function
|
||||
.sig
|
||||
.inputs
|
||||
.iter()
|
||||
.map(|arg| parse_arg(&function.sig.ident, arg, message, case))
|
||||
.map(|arg| {
|
||||
parse_arg(
|
||||
plugin_name,
|
||||
&function.sig.ident,
|
||||
arg,
|
||||
message,
|
||||
acl,
|
||||
attributes,
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Transform a [`FnArg`] into a command argument.
|
||||
fn parse_arg(
|
||||
plugin_name: &TokenStream2,
|
||||
command: &Ident,
|
||||
arg: &FnArg,
|
||||
message: &Ident,
|
||||
case: ArgumentCase,
|
||||
acl: &Ident,
|
||||
attributes: &WrapperAttributes,
|
||||
) -> syn::Result<TokenStream2> {
|
||||
// we have no use for self arguments
|
||||
let mut arg = match arg {
|
||||
@@ -243,7 +431,7 @@ fn parse_arg(
|
||||
));
|
||||
}
|
||||
|
||||
match case {
|
||||
match attributes.argument_case {
|
||||
ArgumentCase::Camel => {
|
||||
key = key.to_lower_camel_case();
|
||||
}
|
||||
@@ -252,11 +440,15 @@ fn parse_arg(
|
||||
}
|
||||
}
|
||||
|
||||
Ok(quote!(::tauri::command::CommandArg::from_command(
|
||||
::tauri::command::CommandItem {
|
||||
let root = &attributes.root;
|
||||
|
||||
Ok(quote!(#root::ipc::CommandArg::from_command(
|
||||
#root::ipc::CommandItem {
|
||||
plugin: #plugin_name,
|
||||
name: stringify!(#command),
|
||||
key: #key,
|
||||
message: &#message,
|
||||
acl: &#acl,
|
||||
}
|
||||
)))
|
||||
}
|
||||
|
||||
@@ -1,303 +0,0 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use heck::{ToLowerCamelCase, ToSnakeCase};
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::{Span, TokenStream as TokenStream2};
|
||||
|
||||
use quote::{format_ident, quote, quote_spanned};
|
||||
use syn::{
|
||||
parse::{Parse, ParseStream},
|
||||
parse_quote,
|
||||
spanned::Spanned,
|
||||
Data, DeriveInput, Error, Fields, Ident, ItemFn, LitStr, Token,
|
||||
};
|
||||
|
||||
pub(crate) fn generate_command_enum(mut input: DeriveInput) -> TokenStream {
|
||||
let mut deserialize_functions = TokenStream2::new();
|
||||
let mut errors = TokenStream2::new();
|
||||
|
||||
input.attrs.push(parse_quote!(#[allow(dead_code)]));
|
||||
|
||||
match &mut input.data {
|
||||
Data::Enum(data_enum) => {
|
||||
for variant in &mut data_enum.variants {
|
||||
let mut feature: Option<Ident> = None;
|
||||
let mut error_message: Option<String> = None;
|
||||
|
||||
for attr in &variant.attrs {
|
||||
if attr.path.is_ident("cmd") {
|
||||
let r = attr
|
||||
.parse_args_with(|input: ParseStream| {
|
||||
if let Ok(f) = input.parse::<Ident>() {
|
||||
feature.replace(f);
|
||||
input.parse::<Token![,]>()?;
|
||||
let error_message_raw: LitStr = input.parse()?;
|
||||
error_message.replace(error_message_raw.value());
|
||||
}
|
||||
Ok(quote!())
|
||||
})
|
||||
.unwrap_or_else(syn::Error::into_compile_error);
|
||||
errors.extend(r);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(f) = feature {
|
||||
let error_message = if let Some(e) = error_message {
|
||||
let e = e.to_string();
|
||||
quote!(#e)
|
||||
} else {
|
||||
quote!("This API is not enabled in the allowlist.")
|
||||
};
|
||||
|
||||
let deserialize_function_name = quote::format_ident!("__{}_deserializer", variant.ident);
|
||||
deserialize_functions.extend(quote! {
|
||||
#[cfg(not(#f))]
|
||||
#[allow(non_snake_case)]
|
||||
fn #deserialize_function_name<'de, D, T>(deserializer: D) -> ::std::result::Result<T, D::Error>
|
||||
where
|
||||
D: ::serde::de::Deserializer<'de>,
|
||||
{
|
||||
::std::result::Result::Err(::serde::de::Error::custom(crate::Error::ApiNotAllowlisted(#error_message.into()).to_string()))
|
||||
}
|
||||
});
|
||||
|
||||
let deserialize_function_name = deserialize_function_name.to_string();
|
||||
|
||||
variant
|
||||
.attrs
|
||||
.push(parse_quote!(#[cfg_attr(not(#f), serde(deserialize_with = #deserialize_function_name))]));
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Error::new(
|
||||
Span::call_site(),
|
||||
"`command_enum` is only implemented for enums",
|
||||
)
|
||||
.to_compile_error()
|
||||
.into()
|
||||
}
|
||||
};
|
||||
|
||||
TokenStream::from(quote! {
|
||||
#errors
|
||||
#input
|
||||
#deserialize_functions
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn generate_run_fn(input: DeriveInput) -> TokenStream {
|
||||
let name = &input.ident;
|
||||
let data = &input.data;
|
||||
|
||||
let mut errors = TokenStream2::new();
|
||||
|
||||
let mut is_async = false;
|
||||
|
||||
let attrs = input.attrs;
|
||||
for attr in attrs {
|
||||
if attr.path.is_ident("cmd") {
|
||||
let r = attr
|
||||
.parse_args_with(|input: ParseStream| {
|
||||
if let Ok(token) = input.parse::<Ident>() {
|
||||
is_async = token == "async";
|
||||
}
|
||||
Ok(quote!())
|
||||
})
|
||||
.unwrap_or_else(syn::Error::into_compile_error);
|
||||
errors.extend(r);
|
||||
}
|
||||
}
|
||||
|
||||
let maybe_await = if is_async { quote!(.await) } else { quote!() };
|
||||
let maybe_async = if is_async { quote!(async) } else { quote!() };
|
||||
|
||||
let mut matcher;
|
||||
|
||||
match data {
|
||||
Data::Enum(data_enum) => {
|
||||
matcher = TokenStream2::new();
|
||||
|
||||
for variant in &data_enum.variants {
|
||||
let variant_name = &variant.ident;
|
||||
|
||||
let mut feature = None;
|
||||
|
||||
for attr in &variant.attrs {
|
||||
if attr.path.is_ident("cmd") {
|
||||
let r = attr
|
||||
.parse_args_with(|input: ParseStream| {
|
||||
if let Ok(f) = input.parse::<Ident>() {
|
||||
feature.replace(f);
|
||||
input.parse::<Token![,]>()?;
|
||||
let _: LitStr = input.parse()?;
|
||||
}
|
||||
Ok(quote!())
|
||||
})
|
||||
.unwrap_or_else(syn::Error::into_compile_error);
|
||||
errors.extend(r);
|
||||
}
|
||||
}
|
||||
|
||||
let maybe_feature_check = if let Some(f) = feature {
|
||||
quote!(#[cfg(#f)])
|
||||
} else {
|
||||
quote!()
|
||||
};
|
||||
|
||||
let (fields_in_variant, variables) = match &variant.fields {
|
||||
Fields::Unit => (quote_spanned! { variant.span() => }, quote!()),
|
||||
Fields::Unnamed(fields) => {
|
||||
let mut variables = TokenStream2::new();
|
||||
for i in 0..fields.unnamed.len() {
|
||||
let variable_name = format_ident!("value{}", i);
|
||||
variables.extend(quote!(#variable_name,));
|
||||
}
|
||||
(quote_spanned! { variant.span() => (#variables) }, variables)
|
||||
}
|
||||
Fields::Named(fields) => {
|
||||
let mut variables = TokenStream2::new();
|
||||
for field in &fields.named {
|
||||
let ident = field.ident.as_ref().unwrap();
|
||||
variables.extend(quote!(#ident,));
|
||||
}
|
||||
(
|
||||
quote_spanned! { variant.span() => { #variables } },
|
||||
variables,
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
let mut variant_execute_function_name = format_ident!(
|
||||
"{}",
|
||||
variant_name.to_string().to_snake_case().to_lowercase()
|
||||
);
|
||||
variant_execute_function_name.set_span(variant_name.span());
|
||||
|
||||
matcher.extend(quote_spanned! {
|
||||
variant.span() => #maybe_feature_check #name::#variant_name #fields_in_variant => #name::#variant_execute_function_name(context, #variables)#maybe_await.map(Into::into),
|
||||
});
|
||||
}
|
||||
|
||||
matcher.extend(quote! {
|
||||
_ => Err(crate::error::into_anyhow("API not in the allowlist (https://tauri.app/docs/api/config#tauri.allowlist)")),
|
||||
});
|
||||
}
|
||||
_ => {
|
||||
return Error::new(
|
||||
Span::call_site(),
|
||||
"CommandModule is only implemented for enums",
|
||||
)
|
||||
.to_compile_error()
|
||||
.into()
|
||||
}
|
||||
};
|
||||
|
||||
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
|
||||
|
||||
let expanded = quote! {
|
||||
#errors
|
||||
impl #impl_generics #name #ty_generics #where_clause {
|
||||
pub #maybe_async fn run<R: crate::Runtime>(self, context: crate::endpoints::InvokeContext<R>) -> super::Result<crate::endpoints::InvokeResponse> {
|
||||
match self {
|
||||
#matcher
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TokenStream::from(expanded)
|
||||
}
|
||||
|
||||
/// Attributes for the module enum variant handler.
|
||||
pub struct HandlerAttributes {
|
||||
allowlist: Ident,
|
||||
}
|
||||
|
||||
impl Parse for HandlerAttributes {
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
Ok(Self {
|
||||
allowlist: input.parse()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub enum AllowlistCheckKind {
|
||||
Runtime,
|
||||
Serde,
|
||||
}
|
||||
|
||||
pub struct HandlerTestAttributes {
|
||||
allowlist: Ident,
|
||||
error_message: String,
|
||||
allowlist_check_kind: AllowlistCheckKind,
|
||||
}
|
||||
|
||||
impl Parse for HandlerTestAttributes {
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
let allowlist = input.parse()?;
|
||||
input.parse::<Token![,]>()?;
|
||||
let error_message_raw: LitStr = input.parse()?;
|
||||
let error_message = error_message_raw.value();
|
||||
let allowlist_check_kind =
|
||||
if let (Ok(_), Ok(i)) = (input.parse::<Token![,]>(), input.parse::<Ident>()) {
|
||||
if i == "runtime" {
|
||||
AllowlistCheckKind::Runtime
|
||||
} else {
|
||||
AllowlistCheckKind::Serde
|
||||
}
|
||||
} else {
|
||||
AllowlistCheckKind::Serde
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
allowlist,
|
||||
error_message,
|
||||
allowlist_check_kind,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn command_handler(attributes: HandlerAttributes, function: ItemFn) -> TokenStream2 {
|
||||
let allowlist = attributes.allowlist;
|
||||
|
||||
quote!(
|
||||
#[cfg(#allowlist)]
|
||||
#function
|
||||
)
|
||||
}
|
||||
|
||||
pub fn command_test(attributes: HandlerTestAttributes, function: ItemFn) -> TokenStream2 {
|
||||
let allowlist = attributes.allowlist;
|
||||
let error_message = attributes.error_message.as_str();
|
||||
let signature = function.sig.clone();
|
||||
|
||||
let enum_variant_name = function.sig.ident.to_string().to_lower_camel_case();
|
||||
let response = match attributes.allowlist_check_kind {
|
||||
AllowlistCheckKind::Runtime => {
|
||||
let test_name = function.sig.ident.clone();
|
||||
quote!(super::Cmd::#test_name(crate::test::mock_invoke_context()))
|
||||
}
|
||||
AllowlistCheckKind::Serde => quote! {
|
||||
serde_json::from_str::<super::Cmd>(&format!(r#"{{ "cmd": "{}", "data": null }}"#, #enum_variant_name))
|
||||
},
|
||||
};
|
||||
|
||||
quote!(
|
||||
#[cfg(#allowlist)]
|
||||
#function
|
||||
|
||||
#[cfg(not(#allowlist))]
|
||||
#[allow(unused_variables)]
|
||||
#[quickcheck_macros::quickcheck]
|
||||
#signature {
|
||||
if let Err(e) = #response {
|
||||
assert!(e.to_string().contains(#error_message));
|
||||
} else {
|
||||
panic!("unexpected response");
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -11,7 +11,7 @@ use syn::{
|
||||
LitStr, PathArguments, PathSegment, Token,
|
||||
};
|
||||
use tauri_codegen::{context_codegen, get_config, ContextData};
|
||||
use tauri_utils::config::parse::does_supported_file_name_exist;
|
||||
use tauri_utils::{config::parse::does_supported_file_name_exist, platform::Target};
|
||||
|
||||
pub(crate) struct ContextItems {
|
||||
config_file: PathBuf,
|
||||
@@ -20,6 +20,12 @@ pub(crate) struct ContextItems {
|
||||
|
||||
impl Parse for ContextItems {
|
||||
fn parse(input: &ParseBuffer<'_>) -> syn::parse::Result<Self> {
|
||||
let target = std::env::var("TARGET")
|
||||
.or_else(|_| std::env::var("TAURI_ENV_TARGET_TRIPLE"))
|
||||
.as_deref()
|
||||
.map(Target::from_triple)
|
||||
.unwrap_or_else(|_| Target::current());
|
||||
|
||||
let config_file = if input.is_empty() {
|
||||
std::env::var("CARGO_MANIFEST_DIR").map(|m| PathBuf::from(m).join("tauri.conf.json"))
|
||||
} else {
|
||||
@@ -36,7 +42,7 @@ impl Parse for ContextItems {
|
||||
VarError::NotUnicode(_) => "CARGO_MANIFEST_DIR env var contained invalid utf8".into(),
|
||||
})
|
||||
.and_then(|path| {
|
||||
if does_supported_file_name_exist(&path) {
|
||||
if does_supported_file_name_exist(target, &path) {
|
||||
Ok(path)
|
||||
} else {
|
||||
Err(format!(
|
||||
|
||||
@@ -2,12 +2,22 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//! [](https://tauri.app)
|
||||
//!
|
||||
//! Create macros for `tauri::Context`, invoke handler and commands leveraging the `tauri-codegen` crate.
|
||||
|
||||
#![doc(
|
||||
html_logo_url = "https://github.com/tauri-apps/tauri/raw/dev/app-icon.png",
|
||||
html_favicon_url = "https://github.com/tauri-apps/tauri/raw/dev/app-icon.png"
|
||||
)]
|
||||
|
||||
use crate::context::ContextItems;
|
||||
use proc_macro::TokenStream;
|
||||
use syn::{parse_macro_input, DeriveInput, ItemFn};
|
||||
use syn::parse_macro_input;
|
||||
|
||||
mod command;
|
||||
mod command_module;
|
||||
mod menu;
|
||||
mod mobile;
|
||||
mod runtime;
|
||||
|
||||
#[macro_use]
|
||||
@@ -24,6 +34,11 @@ pub fn command(attributes: TokenStream, item: TokenStream) -> TokenStream {
|
||||
command::wrapper(attributes, item)
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn mobile_entry_point(attributes: TokenStream, item: TokenStream) -> TokenStream {
|
||||
mobile::entry_point(attributes, item)
|
||||
}
|
||||
|
||||
/// Accepts a list of commands functions. Creates a handler that allows commands to be called from JS with invoke().
|
||||
///
|
||||
/// # Examples
|
||||
@@ -72,43 +87,67 @@ pub fn generate_context(items: TokenStream) -> TokenStream {
|
||||
#[proc_macro_attribute]
|
||||
pub fn default_runtime(attributes: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let attributes = parse_macro_input!(attributes as runtime::Attributes);
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
let input = parse_macro_input!(input as runtime::Input);
|
||||
runtime::default_runtime(attributes, input).into()
|
||||
}
|
||||
|
||||
/// Prepares the command module enum.
|
||||
#[doc(hidden)]
|
||||
#[proc_macro_derive(CommandModule, attributes(cmd))]
|
||||
pub fn derive_command_module(input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
command_module::generate_run_fn(input)
|
||||
}
|
||||
|
||||
/// Adds a `run` method to an enum (one of the tauri endpoint modules).
|
||||
/// The `run` method takes a `tauri::endpoints::InvokeContext`
|
||||
/// and returns a `tauri::Result<tauri::endpoints::InvokeResponse>`.
|
||||
/// It matches on each enum variant and call a method with name equal to the variant name, lowercased and snake_cased,
|
||||
/// passing the context and the variant's fields as arguments.
|
||||
/// That function must also return the same `Result<InvokeResponse>`.
|
||||
#[doc(hidden)]
|
||||
#[proc_macro_attribute]
|
||||
pub fn command_enum(_: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
command_module::generate_command_enum(input)
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[proc_macro_attribute]
|
||||
pub fn module_command_handler(attributes: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let attributes = parse_macro_input!(attributes as command_module::HandlerAttributes);
|
||||
let input = parse_macro_input!(input as ItemFn);
|
||||
command_module::command_handler(attributes, input).into()
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[proc_macro_attribute]
|
||||
pub fn module_command_test(attributes: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let attributes = parse_macro_input!(attributes as command_module::HandlerTestAttributes);
|
||||
let input = parse_macro_input!(input as ItemFn);
|
||||
command_module::command_test(attributes, input).into()
|
||||
/// Accepts a closure-like syntax to call arbitrary code on a menu item
|
||||
/// after matching against `kind` and retrieving it from `resources_table` using `rid`.
|
||||
///
|
||||
/// You can optionally pass a third parameter to select which item kinds
|
||||
/// to match against, by providing a `|` separated list of item kinds
|
||||
/// ```ignore
|
||||
/// do_menu_item!(|i| i.set_text(text), Check | Submenu);
|
||||
/// ```
|
||||
/// You could also provide a negated list
|
||||
/// ```ignore
|
||||
/// do_menu_item!(|i| i.set_text(text), !Check);
|
||||
/// do_menu_item!(|i| i.set_text(text), !Check | !Submenu);
|
||||
/// ```
|
||||
/// but you can't have mixed negations and positive kinds.
|
||||
/// ```ignore
|
||||
/// do_menu_item!(|i| i.set_text(text), !Check | Submeun);
|
||||
/// ```
|
||||
///
|
||||
/// #### Example
|
||||
///
|
||||
/// ```ignore
|
||||
/// let rid = 23;
|
||||
/// let kind = ItemKind::Check;
|
||||
/// let resources_table = app.resources_table();
|
||||
/// do_menu_item!(|i| i.set_text(text))
|
||||
/// ```
|
||||
/// which will expand into:
|
||||
/// ```ignore
|
||||
/// let rid = 23;
|
||||
/// let kind = ItemKind::Check;
|
||||
/// let resources_table = app.resources_table();
|
||||
/// match kind {
|
||||
/// ItemKind::Submenu => {
|
||||
/// let i = resources_table.get::<Submenu<R>>(rid)?;
|
||||
/// i.set_text(text)
|
||||
/// }
|
||||
/// ItemKind::MenuItem => {
|
||||
/// let i = resources_table.get::<MenuItem<R>>(rid)?;
|
||||
/// i.set_text(text)
|
||||
/// }
|
||||
/// ItemKind::Predefined => {
|
||||
/// let i = resources_table.get::<PredefinedMenuItem<R>>(rid)?;
|
||||
/// i.set_text(text)
|
||||
/// }
|
||||
/// ItemKind::Check => {
|
||||
/// let i = resources_table.get::<CheckMenuItem<R>>(rid)?;
|
||||
/// i.set_text(text)
|
||||
/// }
|
||||
/// ItemKind::Icon => {
|
||||
/// let i = resources_table.get::<IconMenuItem<R>>(rid)?;
|
||||
/// i.set_text(text)
|
||||
/// }
|
||||
/// _ => unreachable!(),
|
||||
/// }
|
||||
/// ```
|
||||
#[proc_macro]
|
||||
pub fn do_menu_item(input: TokenStream) -> TokenStream {
|
||||
let tokens = parse_macro_input!(input as menu::DoMenuItemInput);
|
||||
menu::do_menu_item(tokens).into()
|
||||
}
|
||||
|
||||
118
core/tauri-macros/src/menu.rs
Normal file
118
core/tauri-macros/src/menu.rs
Normal file
@@ -0,0 +1,118 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use proc_macro2::{Ident, Span, TokenStream};
|
||||
use quote::quote;
|
||||
use syn::{
|
||||
parse::{Parse, ParseStream},
|
||||
punctuated::Punctuated,
|
||||
Expr, Token,
|
||||
};
|
||||
|
||||
pub struct DoMenuItemInput {
|
||||
resources_table: Ident,
|
||||
rid: Ident,
|
||||
kind: Ident,
|
||||
var: Ident,
|
||||
expr: Expr,
|
||||
kinds: Vec<NegatedIdent>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct NegatedIdent(bool, Ident);
|
||||
|
||||
impl Parse for NegatedIdent {
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
let t = input.parse::<Token![!]>();
|
||||
let i: Ident = input.parse()?;
|
||||
Ok(NegatedIdent(t.is_ok(), i))
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for DoMenuItemInput {
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
let resources_table: Ident = input.parse()?;
|
||||
let _: Token![,] = input.parse()?;
|
||||
let rid: Ident = input.parse()?;
|
||||
let _: Token![,] = input.parse()?;
|
||||
let kind: Ident = input.parse()?;
|
||||
let _: Token![,] = input.parse()?;
|
||||
let _: Token![|] = input.parse()?;
|
||||
let var: Ident = input.parse()?;
|
||||
let _: Token![|] = input.parse()?;
|
||||
let expr: Expr = input.parse()?;
|
||||
let _: syn::Result<Token![,]> = input.parse();
|
||||
let kinds = Punctuated::<NegatedIdent, Token![|]>::parse_terminated(input)?;
|
||||
|
||||
Ok(Self {
|
||||
resources_table,
|
||||
rid,
|
||||
kind,
|
||||
var,
|
||||
expr,
|
||||
kinds: kinds.into_iter().collect(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn do_menu_item(input: DoMenuItemInput) -> TokenStream {
|
||||
let DoMenuItemInput {
|
||||
rid,
|
||||
resources_table,
|
||||
kind,
|
||||
expr,
|
||||
var,
|
||||
mut kinds,
|
||||
} = input;
|
||||
|
||||
let defaults = vec![
|
||||
NegatedIdent(false, Ident::new("Submenu", Span::call_site())),
|
||||
NegatedIdent(false, Ident::new("MenuItem", Span::call_site())),
|
||||
NegatedIdent(false, Ident::new("Predefined", Span::call_site())),
|
||||
NegatedIdent(false, Ident::new("Check", Span::call_site())),
|
||||
NegatedIdent(false, Ident::new("Icon", Span::call_site())),
|
||||
];
|
||||
|
||||
if kinds.is_empty() {
|
||||
kinds.extend(defaults.clone());
|
||||
}
|
||||
|
||||
let has_negated = kinds.iter().any(|n| n.0);
|
||||
|
||||
if has_negated {
|
||||
kinds.extend(defaults);
|
||||
kinds.sort_by(|a, b| a.1.cmp(&b.1));
|
||||
kinds.dedup_by(|a, b| a.1 == b.1);
|
||||
}
|
||||
|
||||
let (kinds, types): (Vec<Ident>, Vec<Ident>) = kinds
|
||||
.into_iter()
|
||||
.filter_map(|nident| {
|
||||
if nident.0 {
|
||||
None
|
||||
} else {
|
||||
match nident.1 {
|
||||
i if i == "MenuItem" => Some((i, Ident::new("MenuItem", Span::call_site()))),
|
||||
i if i == "Submenu" => Some((i, Ident::new("Submenu", Span::call_site()))),
|
||||
i if i == "Predefined" => Some((i, Ident::new("PredefinedMenuItem", Span::call_site()))),
|
||||
i if i == "Check" => Some((i, Ident::new("CheckMenuItem", Span::call_site()))),
|
||||
i if i == "Icon" => Some((i, Ident::new("IconMenuItem", Span::call_site()))),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
})
|
||||
.unzip();
|
||||
|
||||
quote! {
|
||||
match #kind {
|
||||
#(
|
||||
ItemKind::#kinds => {
|
||||
let #var = #resources_table.get::<#types<R>>(#rid)?;
|
||||
#expr
|
||||
}
|
||||
)*
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
83
core/tauri-macros/src/mobile.rs
Normal file
83
core/tauri-macros/src/mobile.rs
Normal file
@@ -0,0 +1,83 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use quote::{format_ident, quote};
|
||||
use std::env::var;
|
||||
use syn::{parse_macro_input, spanned::Spanned, ItemFn};
|
||||
|
||||
fn get_env_var<R: FnOnce(String) -> String>(
|
||||
name: &str,
|
||||
replacer: R,
|
||||
error: &mut Option<TokenStream2>,
|
||||
function: &ItemFn,
|
||||
) -> TokenStream2 {
|
||||
match var(name) {
|
||||
Ok(value) => {
|
||||
let ident = format_ident!("{}", replacer(value));
|
||||
quote!(#ident)
|
||||
}
|
||||
Err(_) => {
|
||||
error.replace(
|
||||
syn::Error::new(
|
||||
function.span(),
|
||||
format!("`{name}` env var not set, do you have a build script with tauri-build?",),
|
||||
)
|
||||
.into_compile_error(),
|
||||
);
|
||||
quote!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn entry_point(_attributes: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let function = parse_macro_input!(item as ItemFn);
|
||||
let function_name = &function.sig.ident;
|
||||
|
||||
let mut error = None;
|
||||
let domain = get_env_var("TAURI_ANDROID_PACKAGE_PREFIX", |r| r, &mut error, &function);
|
||||
let app_name = get_env_var(
|
||||
"CARGO_PKG_NAME",
|
||||
|r| r.replace('-', "_"),
|
||||
&mut error,
|
||||
&function,
|
||||
);
|
||||
|
||||
if let Some(e) = error {
|
||||
quote!(#e).into()
|
||||
} else {
|
||||
quote!(
|
||||
fn stop_unwind<F: FnOnce() -> T, T>(f: F) -> T {
|
||||
match std::panic::catch_unwind(std::panic::AssertUnwindSafe(f)) {
|
||||
Ok(t) => t,
|
||||
Err(err) => {
|
||||
eprintln!("attempt to unwind out of `rust` with err: {:?}", err);
|
||||
std::process::abort()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#function
|
||||
|
||||
fn _start_app() {
|
||||
#[cfg(target_os = "ios")]
|
||||
::tauri::log_stdout();
|
||||
#[cfg(target_os = "android")]
|
||||
{
|
||||
::tauri::android_binding!(#domain, #app_name, _start_app, ::tauri::wry);
|
||||
}
|
||||
stop_unwind(#function_name);
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "android"))]
|
||||
#[no_mangle]
|
||||
#[inline(never)]
|
||||
pub extern "C" fn start_app() {
|
||||
_start_app()
|
||||
}
|
||||
)
|
||||
.into()
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,54 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
use quote::{quote, ToTokens};
|
||||
use syn::parse::{Parse, ParseStream};
|
||||
use syn::{parse_quote, DeriveInput, GenericParam, Ident, Token, Type, TypeParam};
|
||||
use syn::{
|
||||
parse_quote, DeriveInput, Error, GenericParam, Ident, ItemTrait, ItemType, Token, Type, TypeParam,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) enum Input {
|
||||
Derive(DeriveInput),
|
||||
Trait(ItemTrait),
|
||||
Type(ItemType),
|
||||
}
|
||||
|
||||
impl Parse for Input {
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
input
|
||||
.parse::<DeriveInput>()
|
||||
.map(Self::Derive)
|
||||
.or_else(|_| input.parse().map(Self::Trait))
|
||||
.or_else(|_| input.parse().map(Self::Type))
|
||||
.map_err(|_| {
|
||||
Error::new(
|
||||
input.span(),
|
||||
"default_runtime only supports `struct`, `enum`, `type`, or `trait` definitions",
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Input {
|
||||
fn last_param_mut(&mut self) -> Option<&mut GenericParam> {
|
||||
match self {
|
||||
Input::Derive(d) => d.generics.params.last_mut(),
|
||||
Input::Trait(t) => t.generics.params.last_mut(),
|
||||
Input::Type(t) => t.generics.params.last_mut(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for Input {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
match self {
|
||||
Input::Derive(d) => d.to_tokens(tokens),
|
||||
Input::Trait(t) => t.to_tokens(tokens),
|
||||
Input::Type(t) => t.to_tokens(tokens),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The default runtime type to enable when the provided feature is enabled.
|
||||
pub(crate) struct Attributes {
|
||||
@@ -24,13 +69,11 @@ impl Parse for Attributes {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn default_runtime(attributes: Attributes, input: DeriveInput) -> TokenStream {
|
||||
pub(crate) fn default_runtime(attributes: Attributes, input: Input) -> TokenStream {
|
||||
// create a new copy to manipulate for the wry feature flag
|
||||
let mut wry = input.clone();
|
||||
let wry_runtime = wry
|
||||
.generics
|
||||
.params
|
||||
.last_mut()
|
||||
.last_param_mut()
|
||||
.expect("default_runtime requires the item to have at least 1 generic parameter");
|
||||
|
||||
// set the default value of the last generic parameter to the provided runtime type
|
||||
|
||||
7
core/tauri-plugin/CHANGELOG.md
Normal file
7
core/tauri-plugin/CHANGELOG.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Changelog
|
||||
|
||||
## \[2.0.0-beta.0]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`74a2a603`](https://www.github.com/tauri-apps/tauri/commit/74a2a6036a5e57462f161d728cbd8a6f121028ca)([#8661](https://www.github.com/tauri-apps/tauri/pull/8661)) Implement access control list for IPC usage.
|
||||
41
core/tauri-plugin/Cargo.toml
Normal file
41
core/tauri-plugin/Cargo.toml
Normal file
@@ -0,0 +1,41 @@
|
||||
[package]
|
||||
name = "tauri-plugin"
|
||||
version = "2.0.0-beta.0"
|
||||
description = "Build script and runtime Tauri plugin definitions"
|
||||
authors = { workspace = true }
|
||||
homepage = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
categories = { workspace = true }
|
||||
license = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
features = [ "build", "runtime" ]
|
||||
rustc-args = [ "--cfg", "docsrs" ]
|
||||
rustdoc-args = [ "--cfg", "docsrs" ]
|
||||
|
||||
[features]
|
||||
build = [
|
||||
"dep:anyhow",
|
||||
"dep:serde",
|
||||
"dep:serde_json",
|
||||
"dep:glob",
|
||||
"dep:toml",
|
||||
"dep:plist",
|
||||
"dep:walkdir"
|
||||
]
|
||||
runtime = [ ]
|
||||
|
||||
[dependencies]
|
||||
anyhow = { version = "1", optional = true }
|
||||
serde = { version = "1", optional = true }
|
||||
tauri-utils = { version = "2.0.0-beta.0", default-features = false, path = "../tauri-utils" }
|
||||
serde_json = { version = "1", optional = true }
|
||||
glob = { version = "0.3", optional = true }
|
||||
toml = { version = "0.8", optional = true }
|
||||
schemars = { version = "0.8", features = [ "preserve_order" ] }
|
||||
walkdir = { version = "1", optional = true }
|
||||
|
||||
[target."cfg(target_os = \"macos\")".dependencies]
|
||||
plist = { version = "1", optional = true }
|
||||
232
core/tauri-plugin/src/build/mobile.rs
Normal file
232
core/tauri-plugin/src/build/mobile.rs
Normal file
@@ -0,0 +1,232 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//! Mobile-specific build utilities.
|
||||
|
||||
use std::{
|
||||
env::var_os,
|
||||
fs::{copy, create_dir, create_dir_all, read_to_string, remove_dir_all, write},
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
|
||||
use super::{build_var, cfg_alias};
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
pub fn update_entitlements<F: FnOnce(&mut plist::Dictionary)>(f: F) -> Result<()> {
|
||||
if let (Some(project_path), Ok(app_name)) = (
|
||||
var_os("TAURI_IOS_PROJECT_PATH").map(PathBuf::from),
|
||||
std::env::var("TAURI_IOS_APP_NAME"),
|
||||
) {
|
||||
update_plist_file(
|
||||
project_path
|
||||
.join(format!("{app_name}_iOS"))
|
||||
.join(format!("{app_name}_iOS.entitlements")),
|
||||
f,
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn update_android_manifest(block_identifier: &str, parent: &str, insert: String) -> Result<()> {
|
||||
if let Some(project_path) = var_os("TAURI_ANDROID_PROJECT_PATH").map(PathBuf::from) {
|
||||
let manifest_path = project_path.join("app/src/main/AndroidManifest.xml");
|
||||
let manifest = read_to_string(&manifest_path)?;
|
||||
let rewritten = insert_into_xml(&manifest, block_identifier, parent, &insert);
|
||||
if rewritten != manifest {
|
||||
write(manifest_path, rewritten)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn setup(
|
||||
android_path: Option<PathBuf>,
|
||||
#[allow(unused_variables)] ios_path: Option<PathBuf>,
|
||||
) -> Result<()> {
|
||||
let target_os = build_var("CARGO_CFG_TARGET_OS")?;
|
||||
let mobile = target_os == "android" || target_os == "ios";
|
||||
cfg_alias("mobile", mobile);
|
||||
cfg_alias("desktop", !mobile);
|
||||
|
||||
match target_os.as_str() {
|
||||
"android" => {
|
||||
if let Some(path) = android_path {
|
||||
let manifest_dir = build_var("CARGO_MANIFEST_DIR").map(PathBuf::from)?;
|
||||
let source = manifest_dir.join(path);
|
||||
|
||||
let tauri_library_path = std::env::var("DEP_TAURI_ANDROID_LIBRARY_PATH")
|
||||
.expect("missing `DEP_TAURI_ANDROID_LIBRARY_PATH` environment variable. Make sure `tauri` is a dependency of the plugin.");
|
||||
println!("cargo:rerun-if-env-changed=DEP_TAURI_ANDROID_LIBRARY_PATH");
|
||||
|
||||
create_dir_all(source.join(".tauri")).context("failed to create .tauri directory")?;
|
||||
copy_folder(
|
||||
Path::new(&tauri_library_path),
|
||||
&source.join(".tauri").join("tauri-api"),
|
||||
&[],
|
||||
)
|
||||
.context("failed to copy tauri-api to the plugin project")?;
|
||||
|
||||
println!("cargo:android_library_path={}", source.display());
|
||||
}
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
"ios" => {
|
||||
if let Some(path) = ios_path {
|
||||
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR")
|
||||
.map(PathBuf::from)
|
||||
.unwrap();
|
||||
let tauri_library_path = std::env::var("DEP_TAURI_IOS_LIBRARY_PATH")
|
||||
.expect("missing `DEP_TAURI_IOS_LIBRARY_PATH` environment variable. Make sure `tauri` is a dependency of the plugin.");
|
||||
|
||||
let tauri_dep_path = path.parent().unwrap().join(".tauri");
|
||||
create_dir_all(&tauri_dep_path).context("failed to create .tauri directory")?;
|
||||
copy_folder(
|
||||
Path::new(&tauri_library_path),
|
||||
&tauri_dep_path.join("tauri-api"),
|
||||
&[".build", "Package.resolved", "Tests"],
|
||||
)
|
||||
.context("failed to copy tauri-api to the plugin project")?;
|
||||
tauri_utils::build::link_swift_library(
|
||||
&std::env::var("CARGO_PKG_NAME").unwrap(),
|
||||
manifest_dir.join(path),
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn copy_folder(source: &Path, target: &Path, ignore_paths: &[&str]) -> Result<()> {
|
||||
let _ = remove_dir_all(target);
|
||||
|
||||
for entry in walkdir::WalkDir::new(source) {
|
||||
let entry = entry?;
|
||||
let rel_path = entry.path().strip_prefix(source)?;
|
||||
let rel_path_str = rel_path.to_string_lossy();
|
||||
if ignore_paths
|
||||
.iter()
|
||||
.any(|path| rel_path_str.starts_with(path))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
let dest_path = target.join(rel_path);
|
||||
|
||||
if entry.file_type().is_dir() {
|
||||
create_dir(&dest_path)
|
||||
.with_context(|| format!("failed to create directory {}", dest_path.display()))?;
|
||||
} else {
|
||||
copy(entry.path(), &dest_path).with_context(|| {
|
||||
format!(
|
||||
"failed to copy {} to {}",
|
||||
entry.path().display(),
|
||||
dest_path.display()
|
||||
)
|
||||
})?;
|
||||
println!("cargo:rerun-if-changed={}", entry.path().display());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn update_plist_file<P: AsRef<Path>, F: FnOnce(&mut plist::Dictionary)>(
|
||||
path: P,
|
||||
f: F,
|
||||
) -> Result<()> {
|
||||
use std::io::Cursor;
|
||||
|
||||
let path = path.as_ref();
|
||||
if path.exists() {
|
||||
let plist_str = read_to_string(path)?;
|
||||
let mut plist = plist::Value::from_reader(Cursor::new(&plist_str))?;
|
||||
if let Some(dict) = plist.as_dictionary_mut() {
|
||||
f(dict);
|
||||
let mut plist_buf = Vec::new();
|
||||
let writer = Cursor::new(&mut plist_buf);
|
||||
plist::to_writer_xml(writer, &plist)?;
|
||||
let new_plist_str = String::from_utf8(plist_buf)?;
|
||||
if new_plist_str != plist_str {
|
||||
write(path, new_plist_str)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn xml_block_comment(id: &str) -> String {
|
||||
format!("<!-- {id}. AUTO-GENERATED. DO NOT REMOVE. -->")
|
||||
}
|
||||
|
||||
fn insert_into_xml(xml: &str, block_identifier: &str, parent_tag: &str, contents: &str) -> String {
|
||||
let block_comment = xml_block_comment(block_identifier);
|
||||
|
||||
let mut rewritten = Vec::new();
|
||||
let mut found_block = false;
|
||||
let parent_closing_tag = format!("</{parent_tag}>");
|
||||
for line in xml.split('\n') {
|
||||
if line.contains(&block_comment) {
|
||||
found_block = !found_block;
|
||||
continue;
|
||||
}
|
||||
|
||||
// found previous block which should be removed
|
||||
if found_block {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(index) = line.find(&parent_closing_tag) {
|
||||
let identation = " ".repeat(index + 4);
|
||||
rewritten.push(format!("{}{}", identation, block_comment));
|
||||
for l in contents.split('\n') {
|
||||
rewritten.push(format!("{}{}", identation, l));
|
||||
}
|
||||
rewritten.push(format!("{}{}", identation, block_comment));
|
||||
}
|
||||
|
||||
rewritten.push(line.to_string());
|
||||
}
|
||||
|
||||
rewritten.join("\n")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn insert_into_xml() {
|
||||
let manifest = r#"<manifest>
|
||||
<application>
|
||||
<intent-filter>
|
||||
</intent-filter>
|
||||
</application>
|
||||
</manifest>"#;
|
||||
let id = "tauritest";
|
||||
let new = super::insert_into_xml(manifest, id, "application", "<something></something>");
|
||||
|
||||
let block_id_comment = super::xml_block_comment(id);
|
||||
let expected = format!(
|
||||
r#"<manifest>
|
||||
<application>
|
||||
<intent-filter>
|
||||
</intent-filter>
|
||||
{block_id_comment}
|
||||
<something></something>
|
||||
{block_id_comment}
|
||||
</application>
|
||||
</manifest>"#
|
||||
);
|
||||
|
||||
assert_eq!(new, expected);
|
||||
|
||||
// assert it's still the same after an empty update
|
||||
let new = super::insert_into_xml(&expected, id, "application", "<something></something>");
|
||||
assert_eq!(new, expected);
|
||||
}
|
||||
}
|
||||
125
core/tauri-plugin/src/build/mod.rs
Normal file
125
core/tauri-plugin/src/build/mod.rs
Normal file
@@ -0,0 +1,125 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use anyhow::Result;
|
||||
use tauri_utils::acl::{self, Error};
|
||||
|
||||
pub mod mobile;
|
||||
|
||||
use serde::de::DeserializeOwned;
|
||||
|
||||
use std::{env::var, io::Cursor};
|
||||
|
||||
pub fn plugin_config<T: DeserializeOwned>(name: &str) -> Option<T> {
|
||||
let config_env_var_name = format!(
|
||||
"TAURI_{}_PLUGIN_CONFIG",
|
||||
name.to_uppercase().replace('-', "_")
|
||||
);
|
||||
if let Ok(config_str) = var(&config_env_var_name) {
|
||||
println!("cargo:rerun-if-env-changed={config_env_var_name}");
|
||||
serde_json::from_reader(Cursor::new(config_str))
|
||||
.map(Some)
|
||||
.expect("failed to parse configuration")
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Builder<'a> {
|
||||
commands: &'a [&'static str],
|
||||
global_scope_schema: Option<schemars::schema::RootSchema>,
|
||||
android_path: Option<PathBuf>,
|
||||
ios_path: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl<'a> Builder<'a> {
|
||||
pub fn new(commands: &'a [&'static str]) -> Self {
|
||||
Self {
|
||||
commands,
|
||||
global_scope_schema: None,
|
||||
android_path: None,
|
||||
ios_path: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the global scope JSON schema.
|
||||
pub fn global_scope_schema(mut self, schema: schemars::schema::RootSchema) -> Self {
|
||||
self.global_scope_schema.replace(schema);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the Android project path.
|
||||
pub fn android_path<P: Into<PathBuf>>(mut self, android_path: P) -> Self {
|
||||
self.android_path.replace(android_path.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the iOS project path.
|
||||
pub fn ios_path<P: Into<PathBuf>>(mut self, ios_path: P) -> Self {
|
||||
self.ios_path.replace(ios_path.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// [`Self::try_build`] but will exit automatically if an error is found.
|
||||
pub fn build(self) {
|
||||
if let Err(error) = self.try_build() {
|
||||
println!("{}: {error:#}", env!("CARGO_PKG_NAME"));
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensure this crate is properly configured to be a Tauri plugin.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Errors will occur if environmental variables expected to be set inside of [build scripts]
|
||||
/// are not found, or if the crate violates Tauri plugin conventions.
|
||||
pub fn try_build(self) -> Result<()> {
|
||||
// convention: plugin names should not use underscores
|
||||
let name = build_var("CARGO_PKG_NAME")?;
|
||||
if name.contains('_') {
|
||||
anyhow::bail!("plugin names cannot contain underscores");
|
||||
}
|
||||
|
||||
let out_dir = PathBuf::from(build_var("OUT_DIR")?);
|
||||
|
||||
// requirement: links MUST be set and MUST match the name
|
||||
let _links = build_var("CARGO_MANIFEST_LINKS")?;
|
||||
|
||||
let autogenerated = Path::new("permissions").join(acl::build::AUTOGENERATED_FOLDER_NAME);
|
||||
let commands_dir = autogenerated.join("commands");
|
||||
|
||||
std::fs::create_dir_all(&autogenerated).expect("unable to create permissions dir");
|
||||
|
||||
if !self.commands.is_empty() {
|
||||
acl::build::autogenerate_command_permissions(&commands_dir, self.commands, "");
|
||||
}
|
||||
|
||||
let permissions = acl::build::define_permissions("./permissions/**/*.*", &name, &out_dir)?;
|
||||
|
||||
acl::build::generate_schema(&permissions, "./permissions")?;
|
||||
acl::build::generate_docs(&permissions, &autogenerated)?;
|
||||
|
||||
if let Some(global_scope_schema) = self.global_scope_schema {
|
||||
acl::build::define_global_scope_schema(global_scope_schema, &name, &out_dir)?;
|
||||
}
|
||||
|
||||
mobile::setup(self.android_path, self.ios_path)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn cfg_alias(alias: &str, has_feature: bool) {
|
||||
if has_feature {
|
||||
println!("cargo:rustc-cfg={alias}");
|
||||
}
|
||||
}
|
||||
|
||||
/// Grab an env var that is expected to be set inside of build scripts.
|
||||
fn build_var(key: &'static str) -> Result<String, Error> {
|
||||
std::env::var(key).map_err(|_| Error::BuildVar(key))
|
||||
}
|
||||
25
core/tauri-plugin/src/lib.rs
Normal file
25
core/tauri-plugin/src/lib.rs
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//! [](https://tauri.app)
|
||||
//!
|
||||
//! Interface for building Tauri plugins.
|
||||
|
||||
#![doc(
|
||||
html_logo_url = "https://github.com/tauri-apps/tauri/raw/dev/app-icon.png",
|
||||
html_favicon_url = "https://github.com/tauri-apps/tauri/raw/dev/app-icon.png"
|
||||
)]
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
|
||||
#[cfg(feature = "build")]
|
||||
mod build;
|
||||
#[cfg(feature = "runtime")]
|
||||
mod runtime;
|
||||
|
||||
#[cfg(feature = "build")]
|
||||
#[cfg_attr(docsrs, doc(feature = "build"))]
|
||||
pub use build::*;
|
||||
#[cfg(feature = "runtime")]
|
||||
#[cfg_attr(docsrs, doc(feature = "runtime"))]
|
||||
pub use runtime::*;
|
||||
@@ -1,7 +1,3 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
fn main() {
|
||||
tauri_build::build()
|
||||
}
|
||||
@@ -1,5 +1,259 @@
|
||||
# Changelog
|
||||
|
||||
## \[2.0.0-beta.0]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`af610232`](https://www.github.com/tauri-apps/tauri/commit/af6102327376884364b2075b468bdf08ee0d02aa)([#8710](https://www.github.com/tauri-apps/tauri/pull/8710)) Added `Window::destroy` to force close a window.
|
||||
- [`c77b4032`](https://www.github.com/tauri-apps/tauri/commit/c77b40324ea9bf580871fc11aed69ba0c9b6b8cf)([#8280](https://www.github.com/tauri-apps/tauri/pull/8280)) Add multiwebview support behind the `unstable` feature flag. See `WindowBuilder` and `WebviewBuilder` for more information.
|
||||
- [`00e15675`](https://www.github.com/tauri-apps/tauri/commit/00e1567584721644797b587205187f9cbe4e5cd1)([#8708](https://www.github.com/tauri-apps/tauri/pull/8708)) Added `RuntimeHandle::request_exit` function.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`95da1a27`](https://www.github.com/tauri-apps/tauri/commit/95da1a27476e01e06f6ce0335df8535b662dd9c4)([#8713](https://www.github.com/tauri-apps/tauri/pull/8713)) Fix calling `set_activation_policy` when the event loop is running.
|
||||
|
||||
### What's Changed
|
||||
|
||||
- [`9f8037c2`](https://www.github.com/tauri-apps/tauri/commit/9f8037c2882abac19582025001675370f0d7b669)([#8633](https://www.github.com/tauri-apps/tauri/pull/8633)) On Windows, fix decorated window not transparent initially until resized.
|
||||
- [`9eaeb5a8`](https://www.github.com/tauri-apps/tauri/commit/9eaeb5a8cd95ae24b5e66205bdc2763cb7f965ce)([#8622](https://www.github.com/tauri-apps/tauri/pull/8622)) Added `WindowBuilder::transient_for` and Renamed `WindowBuilder::owner_window` to `WindowBuilder::owner` and `WindowBuilder::parent_window` to `WindowBuilder::parent`.
|
||||
- [`7f033f6d`](https://www.github.com/tauri-apps/tauri/commit/7f033f6dcd54c69a4193765a5c1584755ba92c61)([#8537](https://www.github.com/tauri-apps/tauri/pull/8537)) Add `Window::start_resize_dragging` and `ResizeDirection` enum.
|
||||
- [`6639a579`](https://www.github.com/tauri-apps/tauri/commit/6639a579c76d45210f33a72d37e21d4c5a9d334b)([#8441](https://www.github.com/tauri-apps/tauri/pull/8441)) Added the `WindowConfig::proxy_url` `WebviewBuilder::proxy_url() / WebviewWindowBuilder::proxy_url()` options when creating a webview.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.0`
|
||||
- Upgraded to `tauri-runtime@2.0.0-beta.0`
|
||||
- Upgrated to `tao@0.25`.
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- [`af610232`](https://www.github.com/tauri-apps/tauri/commit/af6102327376884364b2075b468bdf08ee0d02aa)([#8710](https://www.github.com/tauri-apps/tauri/pull/8710)) `WindowDispatch::close` now triggers the `CloseRequested` flow.
|
||||
- [`9eaeb5a8`](https://www.github.com/tauri-apps/tauri/commit/9eaeb5a8cd95ae24b5e66205bdc2763cb7f965ce)([#8622](https://www.github.com/tauri-apps/tauri/pull/8622)) Changed `WindowBuilder::with_config` to take a reference to a `WindowConfig` instead of an owned value.
|
||||
|
||||
## \[1.0.0-alpha.9]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`29ced5ce`](https://www.github.com/tauri-apps/tauri/commit/29ced5ceec40b2934094ade2db9a8855f294e1d1)([#8159](https://www.github.com/tauri-apps/tauri/pull/8159)) Added download event closure via `PendingWindow::download_handler`.
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`d621d343`](https://www.github.com/tauri-apps/tauri/commit/d621d3437ce3947175eecf345b2c6d1c4c7ce020)([#8607](https://www.github.com/tauri-apps/tauri/pull/8607)) Added tracing for window startup, plugins, `Window::eval`, events, IPC, updater and custom protocol request handlers behind the `tracing` feature flag.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`0d0501cb`](https://www.github.com/tauri-apps/tauri/commit/0d0501cb7b5e767c51a3697a148acfe84211a7ad)([#8394](https://www.github.com/tauri-apps/tauri/pull/8394)) Use `arboard` instead of `tao` clipboard implementation to prevent a crash.
|
||||
|
||||
### What's Changed
|
||||
|
||||
- [`cb640c8e`](https://www.github.com/tauri-apps/tauri/commit/cb640c8e949a3d78d78162e2e61b51bf8afae983)([#8393](https://www.github.com/tauri-apps/tauri/pull/8393)) Fix `RunEvent::WindowEvent(event: WindowEvent::FileDrop(FileDropEvent))` never triggered and always prevent default OS behavior when `disable_file_drop_handler` is not used.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.13`
|
||||
- Upgraded to `tauri-runtime@1.0.0-alpha.8`
|
||||
|
||||
## \[1.0.0-alpha.8]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.12`
|
||||
- Upgraded to `tauri-runtime@1.0.0-alpha.7`
|
||||
|
||||
## \[1.0.0-alpha.7]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-runtime@1.0.0-alpha.6`
|
||||
- [\`\`](https://www.github.com/tauri-apps/tauri/commit/undefined) Update to wry v0.35.
|
||||
|
||||
## \[1.0.0-alpha.6]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.11`
|
||||
- Upgraded to `tauri-runtime@1.0.0-alpha.5`
|
||||
|
||||
## \[1.0.0-alpha.5]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`74d2464d`](https://www.github.com/tauri-apps/tauri/commit/74d2464d0e490fae341ad73bdf2964cf215fe6c5)([#8116](https://www.github.com/tauri-apps/tauri/pull/8116)) Added `on_page_load` hook for `PendingWindow`.
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`c6c59cf2`](https://www.github.com/tauri-apps/tauri/commit/c6c59cf2373258b626b00a26f4de4331765dd487) Pull changes from Tauri 1.5 release.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.10`
|
||||
- Upgraded to `tauri-runtime@1.0.0-alpha.4`
|
||||
- [`9580df1d`](https://www.github.com/tauri-apps/tauri/commit/9580df1d7b027befb9e5f025ea2cbaf2dcc82c8e)([#8084](https://www.github.com/tauri-apps/tauri/pull/8084)) Upgrade `gtk` to 0.18.
|
||||
- [`c7c2507d`](https://www.github.com/tauri-apps/tauri/commit/c7c2507da16a9beb71bf06745fe7ac1325ab7c2a)([#8035](https://www.github.com/tauri-apps/tauri/pull/8035)) Update `windows` to version `0.51` and `webview2-com` to version `0.27`
|
||||
- [`9580df1d`](https://www.github.com/tauri-apps/tauri/commit/9580df1d7b027befb9e5f025ea2cbaf2dcc82c8e)([#8084](https://www.github.com/tauri-apps/tauri/pull/8084)) Updated to wry@0.34, removing the `dox` feature flag.
|
||||
|
||||
## \[1.0.0-alpha.4]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`c085adda`](https://www.github.com/tauri-apps/tauri/commit/c085addab58ba851398373c6fd13f9cb026d71e8)([#8009](https://www.github.com/tauri-apps/tauri/pull/8009)) Added `set_progress_bar` to `Window`.
|
||||
- [`c1ec0f15`](https://www.github.com/tauri-apps/tauri/commit/c1ec0f155118527361dd5645d920becbc8afd569)([#7933](https://www.github.com/tauri-apps/tauri/pull/7933)) Added `Window::set_always_on_bottom` and the `always_on_bottom` option when creating a window.
|
||||
- [`880266a7`](https://www.github.com/tauri-apps/tauri/commit/880266a7f697e1fe58d685de3bb6836ce5251e92)([#8031](https://www.github.com/tauri-apps/tauri/pull/8031)) Bump the MSRV to 1.70.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-runtime@1.0.0-alpha.3`
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.9`
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- [`8b166e9b`](https://www.github.com/tauri-apps/tauri/commit/8b166e9bf82e69ddb3200a3a825614980bd8d433)([#7949](https://www.github.com/tauri-apps/tauri/pull/7949)) Check if automation is enabled with the `TAURI_WEBVIEW_AUTOMATION` environment variable instead of `TAURI_AUTOMATION`.
|
||||
- [`2558fab8`](https://www.github.com/tauri-apps/tauri/commit/2558fab861006936296e8511e43ccd69a38f61b0)([#7939](https://www.github.com/tauri-apps/tauri/pull/7939)) Changed `WebviewId` to be an alias for `u32` instead of `u64`
|
||||
|
||||
## \[1.0.0-alpha.3]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.8`
|
||||
- Upgraded to `tauri-runtime@1.0.0-alpha.2`
|
||||
|
||||
## \[1.0.0-alpha.2]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`d5074af5`](https://www.github.com/tauri-apps/tauri/commit/d5074af562b2b5cb6c5711442097c4058af32db6)([#7801](https://www.github.com/tauri-apps/tauri/pull/7801)) Fixes custom protocol not working on Windows.
|
||||
|
||||
## \[1.0.0-alpha.1]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`0d63732b`](https://www.github.com/tauri-apps/tauri/commit/0d63732b962e71b98430f8d7b34ea5b59a2e8bb4)([#7754](https://www.github.com/tauri-apps/tauri/pull/7754)) Update wry to 0.32 to include asynchronous custom protocol support.
|
||||
|
||||
### What's Changed
|
||||
|
||||
- [`6177150b`](https://www.github.com/tauri-apps/tauri/commit/6177150b6f83b52ca359d6e20f7e540f7554e4eb)([#7601](https://www.github.com/tauri-apps/tauri/pull/7601)) Changed `FileDropEvent` to include drop and hover position.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-runtime@1.0.0-alpha.1`
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- [`0d63732b`](https://www.github.com/tauri-apps/tauri/commit/0d63732b962e71b98430f8d7b34ea5b59a2e8bb4)([#7754](https://www.github.com/tauri-apps/tauri/pull/7754)) `tauri-runtime` no longer implements its own HTTP types and relies on the `http` crate instead.
|
||||
|
||||
## \[1.0.0-alpha.0]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`7fb419c3`](https://www.github.com/tauri-apps/tauri/commit/7fb419c326aaf72ecd556d8404377444ebb200e7)([#7535](https://www.github.com/tauri-apps/tauri/pull/7535)) Add `Dispatch::default_vbox`
|
||||
- [`84c41597`](https://www.github.com/tauri-apps/tauri/commit/84c4159754b2e59244211ed9e1fc702d851a0562)([#6394](https://www.github.com/tauri-apps/tauri/pull/6394)) Added `primary_monitor` and `available_monitors` to `Runtime` and `RuntimeHandle`.
|
||||
- [`3b98141a`](https://www.github.com/tauri-apps/tauri/commit/3b98141aa26f74c641a4090874247b97079bd58a)([#3736](https://www.github.com/tauri-apps/tauri/pull/3736)) Added the `Opened` variant to `RunEvent`.
|
||||
- [`2a000e15`](https://www.github.com/tauri-apps/tauri/commit/2a000e150d02dff28c8b20ad097b29e209160045)([#7235](https://www.github.com/tauri-apps/tauri/pull/7235)) Implement navigate method
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-runtime@1.0.0-alpha.0`
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.7`
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- [`fbeb5b91`](https://www.github.com/tauri-apps/tauri/commit/fbeb5b9185baeda19e865228179e3e44c165f1d9)([#7170](https://www.github.com/tauri-apps/tauri/pull/7170)) Removed the `linux-headers` feature (now always enabled) and added `linux-protocol-body`.
|
||||
- [`7fb419c3`](https://www.github.com/tauri-apps/tauri/commit/7fb419c326aaf72ecd556d8404377444ebb200e7)([#7535](https://www.github.com/tauri-apps/tauri/pull/7535)) `Dispatch::create_window`, `Runtime::create_window` and `RuntimeHandle::create_window` has been changed to accept a 3rd parameter which is a closure that takes `RawWindow` and to be executed right after the window is created and before the webview is added to the window.
|
||||
- [`7fb419c3`](https://www.github.com/tauri-apps/tauri/commit/7fb419c326aaf72ecd556d8404377444ebb200e7)([#7535](https://www.github.com/tauri-apps/tauri/pull/7535)) System tray and menu related APIs and structs have all been removed and are now implemented in tauri outside of the runtime-space.
|
||||
- [`7fb419c3`](https://www.github.com/tauri-apps/tauri/commit/7fb419c326aaf72ecd556d8404377444ebb200e7)([#7535](https://www.github.com/tauri-apps/tauri/pull/7535)) `Runtime::new` and `Runtime::new_any_thread` now accept a `RuntimeInitArgs`.
|
||||
- [`7fb419c3`](https://www.github.com/tauri-apps/tauri/commit/7fb419c326aaf72ecd556d8404377444ebb200e7)([#7535](https://www.github.com/tauri-apps/tauri/pull/7535)) Removed `system-tray` feature flag
|
||||
|
||||
## \[0.13.0-alpha.6]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`e0f0dce2`](https://www.github.com/tauri-apps/tauri/commit/e0f0dce220730e2822fc202463aedf0166145de7)([#6442](https://www.github.com/tauri-apps/tauri/pull/6442)) Added the `window_effects` option when creating a window and `Window::set_effects` to change it at runtime.
|
||||
|
||||
## \[0.13.0-alpha.5]
|
||||
|
||||
- [`39f1b04f`](https://www.github.com/tauri-apps/tauri/commit/39f1b04f7be4966488484829cd54c8ce72a04200)([#6943](https://www.github.com/tauri-apps/tauri/pull/6943)) Moved the `event` JS APIs to a plugin.
|
||||
- [`3188f376`](https://www.github.com/tauri-apps/tauri/commit/3188f3764978c6d1452ee31d5a91469691e95094)([#6883](https://www.github.com/tauri-apps/tauri/pull/6883)) Bump the MSRV to 1.65.
|
||||
- [`cebd7526`](https://www.github.com/tauri-apps/tauri/commit/cebd75261ac71b98976314a450cb292eeeec1515)([#6728](https://www.github.com/tauri-apps/tauri/pull/6728)) Moved the `clipboard` feature to its own plugin in the plugins-workspace repository.
|
||||
- [`3f17ee82`](https://www.github.com/tauri-apps/tauri/commit/3f17ee82f6ff21108806edb7b00500b8512b8dc7)([#6737](https://www.github.com/tauri-apps/tauri/pull/6737)) Moved the `global-shortcut` feature to its own plugin in the plugins-workspace repository.
|
||||
- [`31444ac1`](https://www.github.com/tauri-apps/tauri/commit/31444ac196add770f2ad18012d7c18bce7538f22)([#6725](https://www.github.com/tauri-apps/tauri/pull/6725)) Update `wry` to `0.28`
|
||||
|
||||
## \[0.13.0-alpha.4]
|
||||
|
||||
- Added `android` configuration object under `tauri > bundle`.
|
||||
- Bumped due to a bump in tauri-utils.
|
||||
- [db4c9dc6](https://www.github.com/tauri-apps/tauri/commit/db4c9dc655e07ee2184fe04571f500f7910890cd) feat(core): add option to configure Android's minimum SDK version ([#6651](https://www.github.com/tauri-apps/tauri/pull/6651)) on 2023-04-07
|
||||
|
||||
## \[0.13.0-alpha.3]
|
||||
|
||||
- Pull changes from Tauri 1.3 release.
|
||||
- [](https://www.github.com/tauri-apps/tauri/commit/undefined) on undefined
|
||||
|
||||
## \[0.13.0-alpha.2]
|
||||
|
||||
- Add `find_class`, `run_on_android_context` on `RuntimeHandle`.
|
||||
- [05dad087](https://www.github.com/tauri-apps/tauri/commit/05dad0876842e2a7334431247d49365cee835d3e) feat: initial work for iOS plugins ([#6205](https://www.github.com/tauri-apps/tauri/pull/6205)) on 2023-02-11
|
||||
- Allow a wry plugin to be registered at runtime.
|
||||
- [ae296f3d](https://www.github.com/tauri-apps/tauri/commit/ae296f3de16fb6a8badbad5555075a5861681fe5) refactor(tauri-runtime-wry): register runtime plugin after run() ([#6478](https://www.github.com/tauri-apps/tauri/pull/6478)) on 2023-03-17
|
||||
- Added the `shadow` option when creating a window and `Window::set_shadow`.
|
||||
- [a81750d7](https://www.github.com/tauri-apps/tauri/commit/a81750d779bc72f0fdb7de90b7fbddfd8049b328) feat(core): add shadow APIs ([#6206](https://www.github.com/tauri-apps/tauri/pull/6206)) on 2023-02-08
|
||||
- Implemented `with_webview` on Android and iOS.
|
||||
- [05dad087](https://www.github.com/tauri-apps/tauri/commit/05dad0876842e2a7334431247d49365cee835d3e) feat: initial work for iOS plugins ([#6205](https://www.github.com/tauri-apps/tauri/pull/6205)) on 2023-02-11
|
||||
|
||||
## \[0.13.0-alpha.1]
|
||||
|
||||
- Update gtk to 0.16.
|
||||
- [7eb9aa75](https://www.github.com/tauri-apps/tauri/commit/7eb9aa75cfd6a3176d3f566fdda02d88aa529b0f) Update gtk to 0.16 ([#6155](https://www.github.com/tauri-apps/tauri/pull/6155)) on 2023-01-30
|
||||
- Bump the MSRV to 1.64.
|
||||
- [7eb9aa75](https://www.github.com/tauri-apps/tauri/commit/7eb9aa75cfd6a3176d3f566fdda02d88aa529b0f) Update gtk to 0.16 ([#6155](https://www.github.com/tauri-apps/tauri/pull/6155)) on 2023-01-30
|
||||
- Update wry to 0.26.
|
||||
- [f0a1d9cd](https://www.github.com/tauri-apps/tauri/commit/f0a1d9cdbcfb645ce1c5f1cdd597f764991772cd) chore: update rfd and wry versions ([#6174](https://www.github.com/tauri-apps/tauri/pull/6174)) on 2023-02-03
|
||||
|
||||
## \[0.13.0-alpha.0]
|
||||
|
||||
- Support `with_webview` for Android platform alowing execution of JNI code in context.
|
||||
- [8ea87e9c](https://www.github.com/tauri-apps/tauri/commit/8ea87e9c9ca8ba4c7017c8281f78aacd08f45785) feat(android): with_webview access for jni execution ([#5148](https://www.github.com/tauri-apps/tauri/pull/5148)) on 2022-09-08
|
||||
|
||||
## \[0.14.2]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`5e05236b`](https://www.github.com/tauri-apps/tauri/commit/5e05236b4987346697c7caae0567d3c50714c198)([#8289](https://www.github.com/tauri-apps/tauri/pull/8289)) Added tracing for window startup, plugins, `Window::eval`, events, IPC, updater and custom protocol request handlers behind the `tracing` feature flag.
|
||||
|
||||
## \[0.14.1]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`9aa34ada`](https://www.github.com/tauri-apps/tauri/commit/9aa34ada5769dbefa7dfe5f7a6288b3d20b294e4)([#7645](https://www.github.com/tauri-apps/tauri/pull/7645)) Add setting to switch to `http://<scheme>.localhost/` for custom protocols on Windows.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`4bf1e85e`](https://www.github.com/tauri-apps/tauri/commit/4bf1e85e6bf85a7ec92d50c8465bc0588a6399d8)([#7722](https://www.github.com/tauri-apps/tauri/pull/7722)) Properly respect the `focused` option when creating the webview.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@1.5.0`
|
||||
- Upgraded to `tauri-runtime@0.14.1`
|
||||
|
||||
## \[0.14.0]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`c4d6fb4b`](https://www.github.com/tauri-apps/tauri/commit/c4d6fb4b1ea8acf02707a9fe5dcab47c1c5bae7b)([#2353](https://www.github.com/tauri-apps/tauri/pull/2353)) Added the `maximizable`, `minimizable` and `closable` methods to `WindowBuilder`.
|
||||
- [`c4d6fb4b`](https://www.github.com/tauri-apps/tauri/commit/c4d6fb4b1ea8acf02707a9fe5dcab47c1c5bae7b)([#2353](https://www.github.com/tauri-apps/tauri/pull/2353)) Added `set_maximizable`, `set_minimizable`, `set_closable`, `is_maximizable`, `is_minimizable` and `is_closable` methods to the `Dispatch` trait.
|
||||
- [`000104bc`](https://www.github.com/tauri-apps/tauri/commit/000104bc3bc0c9ff3d20558ab9cf2080f126e9e0)([#6472](https://www.github.com/tauri-apps/tauri/pull/6472)) Add `Window::is_focused` getter.
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`d2710e9d`](https://www.github.com/tauri-apps/tauri/commit/d2710e9d2e8fd93975ef6494512370faa8cb3b7e)([#6944](https://www.github.com/tauri-apps/tauri/pull/6944)) Unpin `time`, `ignore`, and `winnow` crate versions. Developers now have to pin crates if needed themselves. A list of crates that need pinning to adhere to Tauri's MSRV will be visible in Tauri's GitHub workflow: https://github.com/tauri-apps/tauri/blob/dev/.github/workflows/test-core.yml#L85.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`b41b57eb`](https://www.github.com/tauri-apps/tauri/commit/b41b57ebb27befd366db5befaafb6043c18fdfef)([#7105](https://www.github.com/tauri-apps/tauri/pull/7105)) Fix panics when registering an invalid global shortcuts or checking it is registered and return proper errors instead.
|
||||
|
||||
### What's Changed
|
||||
|
||||
- [`076e1a81`](https://www.github.com/tauri-apps/tauri/commit/076e1a81a50468e3dfb34ae9ca7e77c5e1758daa)([#7119](https://www.github.com/tauri-apps/tauri/pull/7119)) Use `u32` instead of `u64` for js event listener ids
|
||||
|
||||
## \[0.13.0]
|
||||
|
||||
- Added the `additional_browser_args` option when creating a window.
|
||||
@@ -31,6 +285,11 @@
|
||||
- Implement the webview navigation handler.
|
||||
- [3f35b452](https://www.github.com/tauri-apps/tauri/commit/3f35b452637ef1c794a423f1eda62a15d2ddaf42) Expose wry navigation_handler via WindowBuilder closes [#4080](https://www.github.com/tauri-apps/tauri/pull/4080) ([#5686](https://www.github.com/tauri-apps/tauri/pull/5686)) on 2022-12-27
|
||||
|
||||
## \[0.12.3]
|
||||
|
||||
- Block remote URLs from accessing the IPC.
|
||||
- [9c0593c33](https://www.github.com/tauri-apps/tauri/commit/9c0593c33af52cd9e00ec784d15f63efebdf039c) feat(core): block remote URLs from accessing the IPC on 2023-04-12
|
||||
|
||||
## \[0.12.2]
|
||||
|
||||
- Fix compatibility with older Linux distributions.
|
||||
@@ -76,6 +335,11 @@
|
||||
- Added the `user_agent` option when creating a window.
|
||||
- [a6c94119](https://www.github.com/tauri-apps/tauri/commit/a6c94119d8545d509723b147c273ca5edfe3729f) feat(core): expose user_agent to window config ([#5317](https://www.github.com/tauri-apps/tauri/pull/5317)) on 2022-10-02
|
||||
|
||||
## \[0.11.2]
|
||||
|
||||
- Block remote URLs from accessing the IPC.
|
||||
- [58ea0b452](https://www.github.com/tauri-apps/tauri/commit/58ea0b45268dbd46cbac0ebb0887353d057ca767) feat(core): block remote URLs from accessing the IPC on 2023-04-12
|
||||
|
||||
## \[0.11.1]
|
||||
|
||||
- Add missing allowlist config for `set_cursor_grab`, `set_cursor_visible`, `set_cursor_icon` and `set_cursor_position` APIs.
|
||||
@@ -95,6 +359,11 @@
|
||||
- Update windows to 0.39.0 and webview2-com to 0.19.1.
|
||||
- [e6d9b670](https://www.github.com/tauri-apps/tauri/commit/e6d9b670b0b314ed667b0e164f2c8d27048e678f) refactor: remove unneeded focus code ([#5065](https://www.github.com/tauri-apps/tauri/pull/5065)) on 2022-09-03
|
||||
|
||||
## \[0.10.3]
|
||||
|
||||
- Block remote URLs from accessing the IPC.
|
||||
- [fa90214b0](https://www.github.com/tauri-apps/tauri/commit/fa90214b052b1a5d38d54fbf1ca422b4c37cfd1f) feat(core): block remote URLs from accessing the IPC on 2023-04-12
|
||||
|
||||
## \[0.10.2]
|
||||
|
||||
- Disable drag-n-drop of tao based on `fileDropEnabled` value.
|
||||
|
||||
@@ -1,50 +1,53 @@
|
||||
[package]
|
||||
name = "tauri-runtime-wry"
|
||||
version = "0.13.0"
|
||||
authors = [ "Tauri Programme within The Commons Conservancy" ]
|
||||
categories = [ "gui", "web-programming" ]
|
||||
license = "Apache-2.0 OR MIT"
|
||||
homepage = "https://tauri.app"
|
||||
repository = "https://github.com/tauri-apps/tauri"
|
||||
version = "2.0.0-beta.0"
|
||||
description = "Wry bindings to the Tauri runtime"
|
||||
edition = "2021"
|
||||
rust-version = "1.60"
|
||||
exclude = [ "CHANGELOG.md", "/target" ]
|
||||
readme = "README.md"
|
||||
authors = { workspace = true }
|
||||
homepage = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
categories = { workspace = true }
|
||||
license = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
|
||||
[dependencies]
|
||||
wry = { version = "0.24.1", default-features = false, features = [ "file-drop", "protocol" ] }
|
||||
tauri-runtime = { version = "0.13.0", path = "../tauri-runtime" }
|
||||
tauri-utils = { version = "1.3.0", path = "../tauri-utils" }
|
||||
uuid = { version = "1", features = [ "v4" ] }
|
||||
rand = "0.8"
|
||||
raw-window-handle = "=0.5.0"
|
||||
wry = { version = "0.35.2", default-features = false, features = [ "file-drop", "protocol", "os-webview" ] }
|
||||
tao = { version = "0.25", default-features = false, features = [ "rwh_05", "rwh_06" ] }
|
||||
tauri-runtime = { version = "2.0.0-beta.0", path = "../tauri-runtime" }
|
||||
tauri-utils = { version = "2.0.0-beta.0", path = "../tauri-utils" }
|
||||
raw-window-handle = "0.5"
|
||||
http = "0.2"
|
||||
tracing = { version = "0.1", optional = true }
|
||||
|
||||
[target."cfg(windows)".dependencies]
|
||||
webview2-com = "0.19.1"
|
||||
webview2-com = "0.28"
|
||||
softbuffer = "0.4"
|
||||
|
||||
[target."cfg(windows)".dependencies.windows]
|
||||
version = "0.39.0"
|
||||
version = "0.52"
|
||||
features = [ "Win32_Foundation" ]
|
||||
|
||||
[target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
|
||||
gtk = { version = "0.15", features = [ "v3_20" ] }
|
||||
webkit2gtk = { version = "0.18.2", features = [ "v2_22" ] }
|
||||
gtk = { version = "0.18", features = [ "v3_24" ] }
|
||||
webkit2gtk = { version = "=2.0", features = [ "v2_38" ] }
|
||||
percent-encoding = "2.1"
|
||||
|
||||
[target."cfg(any(target_os = \"ios\", target_os = \"macos\"))".dependencies]
|
||||
cocoa = "0.24"
|
||||
cocoa = "0.25"
|
||||
|
||||
[target."cfg(target_os = \"android\")".dependencies]
|
||||
jni = "0.21"
|
||||
|
||||
[features]
|
||||
dox = [ "wry/dox" ]
|
||||
devtools = [ "wry/devtools", "tauri-runtime/devtools" ]
|
||||
system-tray = [ "tauri-runtime/system-tray", "wry/tray" ]
|
||||
macos-private-api = [
|
||||
"wry/fullscreen",
|
||||
"wry/transparent",
|
||||
"tauri-runtime/macos-private-api"
|
||||
]
|
||||
objc-exception = [ "wry/objc-exception" ]
|
||||
global-shortcut = [ "tauri-runtime/global-shortcut" ]
|
||||
clipboard = [ "tauri-runtime/clipboard" ]
|
||||
linux-headers = [ "wry/linux-headers", "webkit2gtk/v2_36" ]
|
||||
linux-protocol-body = [ "wry/linux-body", "webkit2gtk/v2_40" ]
|
||||
tracing = [ "dep:tracing", "wry/tracing" ]
|
||||
macos-proxy = [ "wry/mac-proxy" ]
|
||||
|
||||
@@ -6,33 +6,38 @@
|
||||
[](https://discord.gg/SpmNs4S)
|
||||
[](https://dev.to/tauri)
|
||||
|
||||

|
||||
[](https://github.com/tauri-apps/tauri/actions/workflows/test-core.yml)
|
||||
[](https://tauri.app)
|
||||
|
||||
[](https://good-labs.github.io/greater-good-affirmation)
|
||||
[](https://opencollective.com/tauri)
|
||||
|
||||
| Component | Version |
|
||||
| --------- | ------------------------------------------- |
|
||||
| tauri-runtime-wry | [](https://crates.io/crates/tauri-runtime-wry) |
|
||||
| Component | Version |
|
||||
| ----------------- | ---------------------------------------------------------------------------------------------------------------------- |
|
||||
| tauri-runtime-wry | [](https://crates.io/crates/tauri-runtime-wry) |
|
||||
|
||||
## About Tauri
|
||||
|
||||
Tauri is a polyglot and generic system that is very composable and allows engineers to make a wide variety of applications. It is used for building applications for Desktop Computers using a combination of Rust tools and HTML rendered in a Webview. Apps built with Tauri can ship with any number of pieces of an optional JS API / Rust API so that webviews can control the system via message passing. In fact, developers can extend the default API with their own functionality and bridge the Webview and Rust-based backend easily.
|
||||
|
||||
Tauri apps can have custom menus and have tray-type interfaces. They can be updated, and are managed by the user's operating system as expected. They are very small, because they use the system's webview. They do not ship a runtime, since the final binary is compiled from rust. This makes the reversing of Tauri apps not a trivial task.
|
||||
|
||||
## This module
|
||||
|
||||
This crate opens up direct systems-level interactions specifically for WRY, such as printing, monitor detection, and other windowing related tasks. `tauri-runtime` implementation for WRY.
|
||||
|
||||
To learn more about the details of how all of these pieces fit together, please consult this [ARCHITECTURE.md](https://github.com/tauri-apps/tauri/blob/dev/ARCHITECTURE.md) document.
|
||||
|
||||
## Semver
|
||||
|
||||
**tauri** is following [Semantic Versioning 2.0](https://semver.org/).
|
||||
|
||||
## Licenses
|
||||
|
||||
Code: (c) 2021 - The Tauri Programme within The Commons Conservancy.
|
||||
|
||||
MIT or MIT/Apache 2.0 where applicable.
|
||||
|
||||
Logo: CC-BY-NC-ND
|
||||
|
||||
- Original Tauri Logo Designs by [Daniel Thompson-Yvetot](https://github.com/nothingismagick) and [Guillaume Chau](https://github.com/akryum)
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//! Clipboard implementation.
|
||||
|
||||
use crate::{getter, Context, Message};
|
||||
|
||||
use std::sync::{
|
||||
mpsc::{channel, Sender},
|
||||
Arc, Mutex,
|
||||
};
|
||||
|
||||
use tauri_runtime::{ClipboardManager, Result, UserEvent};
|
||||
pub use wry::application::clipboard::Clipboard;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ClipboardMessage {
|
||||
WriteText(String, Sender<()>),
|
||||
ReadText(Sender<Option<String>>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ClipboardManagerWrapper<T: UserEvent> {
|
||||
pub context: Context<T>,
|
||||
}
|
||||
|
||||
// SAFETY: this is safe since the `Context` usage is guarded on `send_user_message`.
|
||||
#[allow(clippy::non_send_fields_in_send_ty)]
|
||||
unsafe impl<T: UserEvent> Sync for ClipboardManagerWrapper<T> {}
|
||||
|
||||
impl<T: UserEvent> ClipboardManager for ClipboardManagerWrapper<T> {
|
||||
fn read_text(&self) -> Result<Option<String>> {
|
||||
let (tx, rx) = channel();
|
||||
getter!(self, rx, Message::Clipboard(ClipboardMessage::ReadText(tx)))
|
||||
}
|
||||
|
||||
fn write_text<V: Into<String>>(&mut self, text: V) -> Result<()> {
|
||||
let (tx, rx) = channel();
|
||||
getter!(
|
||||
self,
|
||||
rx,
|
||||
Message::Clipboard(ClipboardMessage::WriteText(text.into(), tx))
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_clipboard_message(
|
||||
message: ClipboardMessage,
|
||||
clipboard_manager: &Arc<Mutex<Clipboard>>,
|
||||
) {
|
||||
match message {
|
||||
ClipboardMessage::WriteText(text, tx) => {
|
||||
clipboard_manager.lock().unwrap().write_text(text);
|
||||
tx.send(()).unwrap();
|
||||
}
|
||||
ClipboardMessage::ReadText(tx) => tx
|
||||
.send(clipboard_manager.lock().unwrap().read_text())
|
||||
.unwrap(),
|
||||
}
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//! Global shortcut implementation.
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fmt,
|
||||
sync::{
|
||||
mpsc::{channel, Sender},
|
||||
Arc, Mutex,
|
||||
},
|
||||
};
|
||||
|
||||
use crate::{getter, Context, Message};
|
||||
|
||||
use tauri_runtime::{Error, GlobalShortcutManager, Result, UserEvent};
|
||||
#[cfg(desktop)]
|
||||
pub use wry::application::{
|
||||
accelerator::{Accelerator, AcceleratorId},
|
||||
global_shortcut::{GlobalShortcut, ShortcutManager as WryShortcutManager},
|
||||
};
|
||||
|
||||
pub type GlobalShortcutListeners = Arc<Mutex<HashMap<AcceleratorId, Box<dyn Fn() + Send>>>>;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum GlobalShortcutMessage {
|
||||
IsRegistered(Accelerator, Sender<bool>),
|
||||
Register(Accelerator, Sender<Result<GlobalShortcutWrapper>>),
|
||||
Unregister(GlobalShortcutWrapper, Sender<Result<()>>),
|
||||
UnregisterAll(Sender<Result<()>>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct GlobalShortcutWrapper(GlobalShortcut);
|
||||
|
||||
// SAFETY: usage outside of main thread is guarded, we use the event loop on such cases.
|
||||
#[allow(clippy::non_send_fields_in_send_ty)]
|
||||
unsafe impl Send for GlobalShortcutWrapper {}
|
||||
|
||||
/// Wrapper around [`WryShortcutManager`].
|
||||
#[derive(Clone)]
|
||||
pub struct GlobalShortcutManagerHandle<T: UserEvent> {
|
||||
pub context: Context<T>,
|
||||
pub shortcuts: Arc<Mutex<HashMap<String, (AcceleratorId, GlobalShortcutWrapper)>>>,
|
||||
pub listeners: GlobalShortcutListeners,
|
||||
}
|
||||
|
||||
// SAFETY: this is safe since the `Context` usage is guarded on `send_user_message`.
|
||||
#[allow(clippy::non_send_fields_in_send_ty)]
|
||||
unsafe impl<T: UserEvent> Sync for GlobalShortcutManagerHandle<T> {}
|
||||
|
||||
impl<T: UserEvent> fmt::Debug for GlobalShortcutManagerHandle<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("GlobalShortcutManagerHandle")
|
||||
.field("context", &self.context)
|
||||
.field("shortcuts", &self.shortcuts)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: UserEvent> GlobalShortcutManager for GlobalShortcutManagerHandle<T> {
|
||||
fn is_registered(&self, accelerator: &str) -> Result<bool> {
|
||||
let (tx, rx) = channel();
|
||||
getter!(
|
||||
self,
|
||||
rx,
|
||||
Message::GlobalShortcut(GlobalShortcutMessage::IsRegistered(
|
||||
accelerator.parse().expect("invalid accelerator"),
|
||||
tx
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
fn register<F: Fn() + Send + 'static>(&mut self, accelerator: &str, handler: F) -> Result<()> {
|
||||
let wry_accelerator: Accelerator = accelerator.parse().expect("invalid accelerator");
|
||||
let id = wry_accelerator.clone().id();
|
||||
let (tx, rx) = channel();
|
||||
let shortcut = getter!(
|
||||
self,
|
||||
rx,
|
||||
Message::GlobalShortcut(GlobalShortcutMessage::Register(wry_accelerator, tx))
|
||||
)??;
|
||||
|
||||
self.listeners.lock().unwrap().insert(id, Box::new(handler));
|
||||
self
|
||||
.shortcuts
|
||||
.lock()
|
||||
.unwrap()
|
||||
.insert(accelerator.into(), (id, shortcut));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn unregister_all(&mut self) -> Result<()> {
|
||||
let (tx, rx) = channel();
|
||||
getter!(
|
||||
self,
|
||||
rx,
|
||||
Message::GlobalShortcut(GlobalShortcutMessage::UnregisterAll(tx))
|
||||
)??;
|
||||
self.listeners.lock().unwrap().clear();
|
||||
self.shortcuts.lock().unwrap().clear();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn unregister(&mut self, accelerator: &str) -> Result<()> {
|
||||
if let Some((accelerator_id, shortcut)) = self.shortcuts.lock().unwrap().remove(accelerator) {
|
||||
let (tx, rx) = channel();
|
||||
getter!(
|
||||
self,
|
||||
rx,
|
||||
Message::GlobalShortcut(GlobalShortcutMessage::Unregister(shortcut, tx))
|
||||
)??;
|
||||
self.listeners.lock().unwrap().remove(&accelerator_id);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_global_shortcut_message(
|
||||
message: GlobalShortcutMessage,
|
||||
global_shortcut_manager: &Arc<Mutex<WryShortcutManager>>,
|
||||
) {
|
||||
match message {
|
||||
GlobalShortcutMessage::IsRegistered(accelerator, tx) => tx
|
||||
.send(
|
||||
global_shortcut_manager
|
||||
.lock()
|
||||
.unwrap()
|
||||
.is_registered(&accelerator),
|
||||
)
|
||||
.unwrap(),
|
||||
GlobalShortcutMessage::Register(accelerator, tx) => tx
|
||||
.send(
|
||||
global_shortcut_manager
|
||||
.lock()
|
||||
.unwrap()
|
||||
.register(accelerator)
|
||||
.map(GlobalShortcutWrapper)
|
||||
.map_err(|e| Error::GlobalShortcut(Box::new(e))),
|
||||
)
|
||||
.unwrap(),
|
||||
GlobalShortcutMessage::Unregister(shortcut, tx) => tx
|
||||
.send(
|
||||
global_shortcut_manager
|
||||
.lock()
|
||||
.unwrap()
|
||||
.unregister(shortcut.0)
|
||||
.map_err(|e| Error::GlobalShortcut(Box::new(e))),
|
||||
)
|
||||
.unwrap(),
|
||||
GlobalShortcutMessage::UnregisterAll(tx) => tx
|
||||
.send(
|
||||
global_shortcut_manager
|
||||
.lock()
|
||||
.unwrap()
|
||||
.unregister_all()
|
||||
.map_err(|e| Error::GlobalShortcut(Box::new(e))),
|
||||
)
|
||||
.unwrap(),
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,238 +0,0 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pub use tauri_runtime::{
|
||||
menu::{
|
||||
Menu, MenuEntry, MenuItem, MenuUpdate, Submenu, SystemTrayMenu, SystemTrayMenuEntry,
|
||||
SystemTrayMenuItem, TrayHandle,
|
||||
},
|
||||
Icon, SystemTrayEvent,
|
||||
};
|
||||
use wry::application::event_loop::EventLoopWindowTarget;
|
||||
pub use wry::application::{
|
||||
event::TrayEvent,
|
||||
event_loop::EventLoopProxy,
|
||||
menu::{
|
||||
ContextMenu as WryContextMenu, CustomMenuItem as WryCustomMenuItem, MenuItem as WryMenuItem,
|
||||
},
|
||||
system_tray::Icon as WryTrayIcon,
|
||||
TrayId as WryTrayId,
|
||||
};
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
pub use wry::application::platform::macos::{
|
||||
CustomMenuItemExtMacOS, SystemTrayBuilderExtMacOS, SystemTrayExtMacOS,
|
||||
};
|
||||
|
||||
use wry::application::system_tray::{SystemTray as WrySystemTray, SystemTrayBuilder};
|
||||
|
||||
use crate::{send_user_message, Context, Error, Message, Result, TrayId, TrayMessage};
|
||||
|
||||
use tauri_runtime::{menu::MenuHash, SystemTray, UserEvent};
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fmt,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
pub type GlobalSystemTrayEventHandler = Box<dyn Fn(TrayId, &SystemTrayEvent) + Send>;
|
||||
pub type GlobalSystemTrayEventListeners = Arc<Mutex<Vec<Arc<GlobalSystemTrayEventHandler>>>>;
|
||||
|
||||
pub type SystemTrayEventHandler = Box<dyn Fn(&SystemTrayEvent) + Send>;
|
||||
pub type SystemTrayEventListeners = Arc<Mutex<Vec<Arc<SystemTrayEventHandler>>>>;
|
||||
pub type SystemTrayItems = Arc<Mutex<HashMap<u16, WryCustomMenuItem>>>;
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct TrayContext {
|
||||
pub tray: Arc<Mutex<Option<WrySystemTray>>>,
|
||||
pub listeners: SystemTrayEventListeners,
|
||||
pub items: SystemTrayItems,
|
||||
}
|
||||
|
||||
impl fmt::Debug for TrayContext {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("TrayContext")
|
||||
.field("items", &self.items)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct SystemTrayManager {
|
||||
pub trays: Arc<Mutex<HashMap<TrayId, TrayContext>>>,
|
||||
pub global_listeners: GlobalSystemTrayEventListeners,
|
||||
}
|
||||
|
||||
impl fmt::Debug for SystemTrayManager {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("SystemTrayManager")
|
||||
.field("trays", &self.trays)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrapper around a [`wry::application::system_tray::Icon`] that can be created from an [`WindowIcon`].
|
||||
pub struct TrayIcon(pub(crate) WryTrayIcon);
|
||||
|
||||
impl TryFrom<Icon> for TrayIcon {
|
||||
type Error = Error;
|
||||
fn try_from(icon: Icon) -> std::result::Result<Self, Self::Error> {
|
||||
WryTrayIcon::from_rgba(icon.rgba, icon.width, icon.height)
|
||||
.map(Self)
|
||||
.map_err(crate::icon_err)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_tray<T>(
|
||||
id: WryTrayId,
|
||||
system_tray: SystemTray,
|
||||
event_loop: &EventLoopWindowTarget<T>,
|
||||
) -> crate::Result<(WrySystemTray, HashMap<u16, WryCustomMenuItem>)> {
|
||||
let icon = TrayIcon::try_from(system_tray.icon.expect("tray icon not set"))?;
|
||||
|
||||
let mut items = HashMap::new();
|
||||
|
||||
#[allow(unused_mut)]
|
||||
let mut builder = SystemTrayBuilder::new(
|
||||
icon.0,
|
||||
system_tray
|
||||
.menu
|
||||
.map(|menu| to_wry_context_menu(&mut items, menu)),
|
||||
)
|
||||
.with_id(id);
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
builder = builder
|
||||
.with_icon_as_template(system_tray.icon_as_template)
|
||||
.with_menu_on_left_click(system_tray.menu_on_left_click);
|
||||
|
||||
if let Some(title) = system_tray.title {
|
||||
builder = builder.with_title(&title);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(tooltip) = system_tray.tooltip {
|
||||
builder = builder.with_tooltip(&tooltip);
|
||||
}
|
||||
|
||||
let tray = builder
|
||||
.build(event_loop)
|
||||
.map_err(|e| Error::SystemTray(Box::new(e)))?;
|
||||
|
||||
Ok((tray, items))
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SystemTrayHandle<T: UserEvent> {
|
||||
pub(crate) context: Context<T>,
|
||||
pub(crate) id: TrayId,
|
||||
pub(crate) proxy: EventLoopProxy<super::Message<T>>,
|
||||
}
|
||||
|
||||
impl<T: UserEvent> TrayHandle for SystemTrayHandle<T> {
|
||||
fn set_icon(&self, icon: Icon) -> Result<()> {
|
||||
self
|
||||
.proxy
|
||||
.send_event(Message::Tray(self.id, TrayMessage::UpdateIcon(icon)))
|
||||
.map_err(|_| Error::FailedToSendMessage)
|
||||
}
|
||||
|
||||
fn set_menu(&self, menu: SystemTrayMenu) -> Result<()> {
|
||||
self
|
||||
.proxy
|
||||
.send_event(Message::Tray(self.id, TrayMessage::UpdateMenu(menu)))
|
||||
.map_err(|_| Error::FailedToSendMessage)
|
||||
}
|
||||
|
||||
fn update_item(&self, id: u16, update: MenuUpdate) -> Result<()> {
|
||||
self
|
||||
.proxy
|
||||
.send_event(Message::Tray(self.id, TrayMessage::UpdateItem(id, update)))
|
||||
.map_err(|_| Error::FailedToSendMessage)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn set_icon_as_template(&self, is_template: bool) -> tauri_runtime::Result<()> {
|
||||
self
|
||||
.proxy
|
||||
.send_event(Message::Tray(
|
||||
self.id,
|
||||
TrayMessage::UpdateIconAsTemplate(is_template),
|
||||
))
|
||||
.map_err(|_| Error::FailedToSendMessage)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn set_title(&self, title: &str) -> tauri_runtime::Result<()> {
|
||||
self
|
||||
.proxy
|
||||
.send_event(Message::Tray(
|
||||
self.id,
|
||||
TrayMessage::UpdateTitle(title.to_owned()),
|
||||
))
|
||||
.map_err(|_| Error::FailedToSendMessage)
|
||||
}
|
||||
|
||||
fn set_tooltip(&self, tooltip: &str) -> Result<()> {
|
||||
self
|
||||
.proxy
|
||||
.send_event(Message::Tray(
|
||||
self.id,
|
||||
TrayMessage::UpdateTooltip(tooltip.to_owned()),
|
||||
))
|
||||
.map_err(|_| Error::FailedToSendMessage)
|
||||
}
|
||||
|
||||
fn destroy(&self) -> Result<()> {
|
||||
let (tx, rx) = std::sync::mpsc::channel();
|
||||
send_user_message(
|
||||
&self.context,
|
||||
Message::Tray(self.id, TrayMessage::Destroy(tx)),
|
||||
)?;
|
||||
rx.recv().unwrap()?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SystemTrayMenuItem> for crate::MenuItemWrapper {
|
||||
fn from(item: SystemTrayMenuItem) -> Self {
|
||||
match item {
|
||||
SystemTrayMenuItem::Separator => Self(WryMenuItem::Separator),
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_wry_context_menu(
|
||||
custom_menu_items: &mut HashMap<MenuHash, WryCustomMenuItem>,
|
||||
menu: SystemTrayMenu,
|
||||
) -> WryContextMenu {
|
||||
let mut tray_menu = WryContextMenu::new();
|
||||
for item in menu.items {
|
||||
match item {
|
||||
SystemTrayMenuEntry::CustomItem(c) => {
|
||||
#[allow(unused_mut)]
|
||||
let mut item = tray_menu.add_item(crate::MenuItemAttributesWrapper::from(&c).0);
|
||||
#[cfg(target_os = "macos")]
|
||||
if let Some(native_image) = c.native_image {
|
||||
item.set_native_image(crate::NativeImageWrapper::from(native_image).0);
|
||||
}
|
||||
custom_menu_items.insert(c.id, item);
|
||||
}
|
||||
SystemTrayMenuEntry::NativeItem(i) => {
|
||||
tray_menu.add_native_item(crate::MenuItemWrapper::from(i).0);
|
||||
}
|
||||
SystemTrayMenuEntry::Submenu(submenu) => {
|
||||
tray_menu.add_submenu(
|
||||
&submenu.title,
|
||||
submenu.enabled,
|
||||
to_wry_context_menu(custom_menu_items, submenu.inner),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
tray_menu
|
||||
}
|
||||
@@ -10,9 +10,7 @@
|
||||
target_os = "openbsd"
|
||||
))]
|
||||
mod imp {
|
||||
use std::rc::Rc;
|
||||
|
||||
pub type Webview = Rc<webkit2gtk::WebView>;
|
||||
pub type Webview = webkit2gtk::WebView;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
@@ -26,6 +24,17 @@ mod imp {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
mod imp {
|
||||
use cocoa::base::id;
|
||||
|
||||
pub struct Webview {
|
||||
pub webview: id,
|
||||
pub manager: id,
|
||||
pub view_controller: id,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
mod imp {
|
||||
use webview2_com::Microsoft::Web::WebView2::Win32::ICoreWebView2Controller;
|
||||
@@ -34,4 +43,10 @@ mod imp {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
mod imp {
|
||||
use wry::JniHandle;
|
||||
pub type Webview = JniHandle;
|
||||
}
|
||||
|
||||
pub use imp::*;
|
||||
|
||||
@@ -1,5 +1,216 @@
|
||||
# Changelog
|
||||
|
||||
## \[2.0.0-beta.0]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`af610232`](https://www.github.com/tauri-apps/tauri/commit/af6102327376884364b2075b468bdf08ee0d02aa)([#8710](https://www.github.com/tauri-apps/tauri/pull/8710)) Added `Window::destroy` to force close a window.
|
||||
- [`c77b4032`](https://www.github.com/tauri-apps/tauri/commit/c77b40324ea9bf580871fc11aed69ba0c9b6b8cf)([#8280](https://www.github.com/tauri-apps/tauri/pull/8280)) Add multiwebview support behind the `unstable` feature flag. See `WindowBuilder` and `WebviewBuilder` for more information.
|
||||
- [`00e15675`](https://www.github.com/tauri-apps/tauri/commit/00e1567584721644797b587205187f9cbe4e5cd1)([#8708](https://www.github.com/tauri-apps/tauri/pull/8708)) Added `RuntimeHandle::request_exit` function.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`95da1a27`](https://www.github.com/tauri-apps/tauri/commit/95da1a27476e01e06f6ce0335df8535b662dd9c4)([#8713](https://www.github.com/tauri-apps/tauri/pull/8713)) Fix calling `set_activation_policy` when the event loop is running.
|
||||
|
||||
### What's Changed
|
||||
|
||||
- [`9eaeb5a8`](https://www.github.com/tauri-apps/tauri/commit/9eaeb5a8cd95ae24b5e66205bdc2763cb7f965ce)([#8622](https://www.github.com/tauri-apps/tauri/pull/8622)) Added `WindowBuilder::transient_for` and Renamed `WindowBuilder::owner_window` to `WindowBuilder::owner` and `WindowBuilder::parent_window` to `WindowBuilder::parent`.
|
||||
- [`7f033f6d`](https://www.github.com/tauri-apps/tauri/commit/7f033f6dcd54c69a4193765a5c1584755ba92c61)([#8537](https://www.github.com/tauri-apps/tauri/pull/8537)) Add `Window::start_resize_dragging` and `ResizeDirection` enum.
|
||||
- [`6639a579`](https://www.github.com/tauri-apps/tauri/commit/6639a579c76d45210f33a72d37e21d4c5a9d334b)([#8441](https://www.github.com/tauri-apps/tauri/pull/8441)) Added the `WindowConfig::proxy_url` `WebviewBuilder::proxy_url() / WebviewWindowBuilder::proxy_url()` options when creating a webview.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.0`
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- [`9eaeb5a8`](https://www.github.com/tauri-apps/tauri/commit/9eaeb5a8cd95ae24b5e66205bdc2763cb7f965ce)([#8622](https://www.github.com/tauri-apps/tauri/pull/8622)) Changed `WindowBuilder::with_config` to take a reference to a `WindowConfig` instead of an owned value.
|
||||
|
||||
## \[1.0.0-alpha.8]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`29ced5ce`](https://www.github.com/tauri-apps/tauri/commit/29ced5ceec40b2934094ade2db9a8855f294e1d1)([#8159](https://www.github.com/tauri-apps/tauri/pull/8159)) Added download event closure via `PendingWindow::download_handler`.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.13`
|
||||
|
||||
## \[1.0.0-alpha.7]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.12`
|
||||
|
||||
## \[1.0.0-alpha.6]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- [\`\`](https://www.github.com/tauri-apps/tauri/commit/undefined) Update dependencies.
|
||||
|
||||
## \[1.0.0-alpha.5]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.11`
|
||||
|
||||
## \[1.0.0-alpha.4]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`74d2464d`](https://www.github.com/tauri-apps/tauri/commit/74d2464d0e490fae341ad73bdf2964cf215fe6c5)([#8116](https://www.github.com/tauri-apps/tauri/pull/8116)) Added `on_page_load` hook for `PendingWindow`.
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`c6c59cf2`](https://www.github.com/tauri-apps/tauri/commit/c6c59cf2373258b626b00a26f4de4331765dd487) Pull changes from Tauri 1.5 release.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.10`
|
||||
- [`9580df1d`](https://www.github.com/tauri-apps/tauri/commit/9580df1d7b027befb9e5f025ea2cbaf2dcc82c8e)([#8084](https://www.github.com/tauri-apps/tauri/pull/8084)) Upgrade `gtk` to 0.18.
|
||||
- [`c7c2507d`](https://www.github.com/tauri-apps/tauri/commit/c7c2507da16a9beb71bf06745fe7ac1325ab7c2a)([#8035](https://www.github.com/tauri-apps/tauri/pull/8035)) Update `windows` to version `0.51` and `webview2-com` to version `0.27`
|
||||
|
||||
## \[1.0.0-alpha.3]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`c085adda`](https://www.github.com/tauri-apps/tauri/commit/c085addab58ba851398373c6fd13f9cb026d71e8)([#8009](https://www.github.com/tauri-apps/tauri/pull/8009)) Added `set_progress_bar` to `Window`.
|
||||
- [`c1ec0f15`](https://www.github.com/tauri-apps/tauri/commit/c1ec0f155118527361dd5645d920becbc8afd569)([#7933](https://www.github.com/tauri-apps/tauri/pull/7933)) Added `Window::set_always_on_bottom` and the `always_on_bottom` option when creating a window.
|
||||
- [`880266a7`](https://www.github.com/tauri-apps/tauri/commit/880266a7f697e1fe58d685de3bb6836ce5251e92)([#8031](https://www.github.com/tauri-apps/tauri/pull/8031)) Bump the MSRV to 1.70.
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`46dcb941`](https://www.github.com/tauri-apps/tauri/commit/46dcb94110ac16d0d4328fa149bb86975b658f59)([#8006](https://www.github.com/tauri-apps/tauri/pull/8006)) Include mobile on docs.rs targets.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.9`
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- [`2558fab8`](https://www.github.com/tauri-apps/tauri/commit/2558fab861006936296e8511e43ccd69a38f61b0)([#7939](https://www.github.com/tauri-apps/tauri/pull/7939)) Added `WindowEventId` type and Changed `Dispatch::on_window_event` return type from `Uuid` to `WindowEventId`
|
||||
|
||||
## \[1.0.0-alpha.2]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.8`
|
||||
|
||||
## \[1.0.0-alpha.1]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`0d63732b`](https://www.github.com/tauri-apps/tauri/commit/0d63732b962e71b98430f8d7b34ea5b59a2e8bb4)([#7754](https://www.github.com/tauri-apps/tauri/pull/7754)) Changed custom protocol closure type to enable asynchronous usage.
|
||||
|
||||
### What's Changed
|
||||
|
||||
- [`6177150b`](https://www.github.com/tauri-apps/tauri/commit/6177150b6f83b52ca359d6e20f7e540f7554e4eb)([#7601](https://www.github.com/tauri-apps/tauri/pull/7601)) Changed `FileDropEvent` to include drop and hover position.
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- [`0d63732b`](https://www.github.com/tauri-apps/tauri/commit/0d63732b962e71b98430f8d7b34ea5b59a2e8bb4)([#7754](https://www.github.com/tauri-apps/tauri/pull/7754)) `tauri-runtime` no longer implements its own HTTP types and relies on the `http` crate instead.
|
||||
|
||||
## \[1.0.0-alpha.0]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`4db363a0`](https://www.github.com/tauri-apps/tauri/commit/4db363a03c182349f8491f46ced258d84723b11f)([#6589](https://www.github.com/tauri-apps/tauri/pull/6589)) Added `visible_on_all_workspaces` configuration option to `WindowBuilder`, `Window`, and `WindowConfig`.
|
||||
- [`84c41597`](https://www.github.com/tauri-apps/tauri/commit/84c4159754b2e59244211ed9e1fc702d851a0562)([#6394](https://www.github.com/tauri-apps/tauri/pull/6394)) Added `primary_monitor` and `available_monitors` to `Runtime` and `RuntimeHandle`.
|
||||
- [`2a000e15`](https://www.github.com/tauri-apps/tauri/commit/2a000e150d02dff28c8b20ad097b29e209160045)([#7235](https://www.github.com/tauri-apps/tauri/pull/7235)) Added `navigate` function to `Dispatch` trait.
|
||||
- [`3b98141a`](https://www.github.com/tauri-apps/tauri/commit/3b98141aa26f74c641a4090874247b97079bd58a)([#3736](https://www.github.com/tauri-apps/tauri/pull/3736)) Added the `Opened` variant to `RunEvent`.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-alpha.7`
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- [`7fb419c3`](https://www.github.com/tauri-apps/tauri/commit/7fb419c326aaf72ecd556d8404377444ebb200e7)([#7535](https://www.github.com/tauri-apps/tauri/pull/7535)) `Dispatch::create_window`, `Runtime::create_window` and `RuntimeHandle::create_window` has been changed to accept a 3rd parameter which is a closure that takes `RawWindow` and to be executed right after the window is created and before the webview is added to the window.
|
||||
- [`7fb419c3`](https://www.github.com/tauri-apps/tauri/commit/7fb419c326aaf72ecd556d8404377444ebb200e7)([#7535](https://www.github.com/tauri-apps/tauri/pull/7535)) System tray and menu related APIs and structs have all been removed and are now implemented in tauri outside of the runtime-space.
|
||||
- [`3a2c3e74`](https://www.github.com/tauri-apps/tauri/commit/3a2c3e74710bef9a14932dce74c351cca6215429)([#7306](https://www.github.com/tauri-apps/tauri/pull/7306)) The `PendingWindow#navigation_handler` closure now receives a `&Url` argument instead of `Url`.
|
||||
- [`7fb419c3`](https://www.github.com/tauri-apps/tauri/commit/7fb419c326aaf72ecd556d8404377444ebb200e7)([#7535](https://www.github.com/tauri-apps/tauri/pull/7535)) `Runtime::new` and `Runtime::new_any_thread` now accept a `RuntimeInitArgs`.
|
||||
- [`7fb419c3`](https://www.github.com/tauri-apps/tauri/commit/7fb419c326aaf72ecd556d8404377444ebb200e7)([#7535](https://www.github.com/tauri-apps/tauri/pull/7535)) Removed `system-tray` feature flag
|
||||
|
||||
## \[0.13.0-alpha.6]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`e0f0dce2`](https://www.github.com/tauri-apps/tauri/commit/e0f0dce220730e2822fc202463aedf0166145de7)([#6442](https://www.github.com/tauri-apps/tauri/pull/6442)) Added the `window_effects` option when creating a window and `Window::set_effects` to change it at runtime.
|
||||
|
||||
## \[0.13.0-alpha.5]
|
||||
|
||||
- [`39f1b04f`](https://www.github.com/tauri-apps/tauri/commit/39f1b04f7be4966488484829cd54c8ce72a04200)([#6943](https://www.github.com/tauri-apps/tauri/pull/6943)) Moved the `event` JS APIs to a plugin.
|
||||
- [`3188f376`](https://www.github.com/tauri-apps/tauri/commit/3188f3764978c6d1452ee31d5a91469691e95094)([#6883](https://www.github.com/tauri-apps/tauri/pull/6883)) Bump the MSRV to 1.65.
|
||||
- [`cebd7526`](https://www.github.com/tauri-apps/tauri/commit/cebd75261ac71b98976314a450cb292eeeec1515)([#6728](https://www.github.com/tauri-apps/tauri/pull/6728)) Moved the `clipboard` feature to its own plugin in the plugins-workspace repository.
|
||||
- [`3f17ee82`](https://www.github.com/tauri-apps/tauri/commit/3f17ee82f6ff21108806edb7b00500b8512b8dc7)([#6737](https://www.github.com/tauri-apps/tauri/pull/6737)) Moved the `global-shortcut` feature to its own plugin in the plugins-workspace repository.
|
||||
|
||||
## \[0.13.0-alpha.4]
|
||||
|
||||
- Added `android` configuration object under `tauri > bundle`.
|
||||
- Bumped due to a bump in tauri-utils.
|
||||
- [db4c9dc6](https://www.github.com/tauri-apps/tauri/commit/db4c9dc655e07ee2184fe04571f500f7910890cd) feat(core): add option to configure Android's minimum SDK version ([#6651](https://www.github.com/tauri-apps/tauri/pull/6651)) on 2023-04-07
|
||||
|
||||
## \[0.13.0-alpha.3]
|
||||
|
||||
- Pull changes from Tauri 1.3 release.
|
||||
- [](https://www.github.com/tauri-apps/tauri/commit/undefined) on undefined
|
||||
|
||||
## \[0.13.0-alpha.2]
|
||||
|
||||
- Add `find_class`, `run_on_android_context` on `RuntimeHandle`.
|
||||
- [05dad087](https://www.github.com/tauri-apps/tauri/commit/05dad0876842e2a7334431247d49365cee835d3e) feat: initial work for iOS plugins ([#6205](https://www.github.com/tauri-apps/tauri/pull/6205)) on 2023-02-11
|
||||
- Added the `shadow` option when creating a window and `Window::set_shadow`.
|
||||
- [a81750d7](https://www.github.com/tauri-apps/tauri/commit/a81750d779bc72f0fdb7de90b7fbddfd8049b328) feat(core): add shadow APIs ([#6206](https://www.github.com/tauri-apps/tauri/pull/6206)) on 2023-02-08
|
||||
- Implemented `with_webview` on Android and iOS.
|
||||
- [05dad087](https://www.github.com/tauri-apps/tauri/commit/05dad0876842e2a7334431247d49365cee835d3e) feat: initial work for iOS plugins ([#6205](https://www.github.com/tauri-apps/tauri/pull/6205)) on 2023-02-11
|
||||
|
||||
## \[0.13.0-alpha.1]
|
||||
|
||||
- Update gtk to 0.16.
|
||||
- [7eb9aa75](https://www.github.com/tauri-apps/tauri/commit/7eb9aa75cfd6a3176d3f566fdda02d88aa529b0f) Update gtk to 0.16 ([#6155](https://www.github.com/tauri-apps/tauri/pull/6155)) on 2023-01-30
|
||||
- Bump the MSRV to 1.64.
|
||||
- [7eb9aa75](https://www.github.com/tauri-apps/tauri/commit/7eb9aa75cfd6a3176d3f566fdda02d88aa529b0f) Update gtk to 0.16 ([#6155](https://www.github.com/tauri-apps/tauri/pull/6155)) on 2023-01-30
|
||||
|
||||
## \[0.13.0-alpha.0]
|
||||
|
||||
- Parse `android` and `ios` Tauri configuration files.
|
||||
- Bumped due to a bump in tauri-utils.
|
||||
- [b3a3afc7](https://www.github.com/tauri-apps/tauri/commit/b3a3afc7de8de4021d73559288f5192732a706cf) feat(core): detect android and ios platform configuration files ([#4997](https://www.github.com/tauri-apps/tauri/pull/4997)) on 2022-08-22
|
||||
- First mobile alpha release!
|
||||
- Bumped due to a bump in tauri-utils.
|
||||
- [fa3a1098](https://www.github.com/tauri-apps/tauri/commit/fa3a10988a03aed1b66fb17d893b1a9adb90f7cd) feat(ci): prepare 2.0.0-alpha.0 ([#5786](https://www.github.com/tauri-apps/tauri/pull/5786)) on 2022-12-08
|
||||
|
||||
## \[0.14.1]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`9aa34ada`](https://www.github.com/tauri-apps/tauri/commit/9aa34ada5769dbefa7dfe5f7a6288b3d20b294e4)([#7645](https://www.github.com/tauri-apps/tauri/pull/7645)) Add setting to switch to `http://<scheme>.localhost/` for custom protocols on Windows.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@1.5.0`
|
||||
|
||||
## \[0.14.0]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`c4d6fb4b`](https://www.github.com/tauri-apps/tauri/commit/c4d6fb4b1ea8acf02707a9fe5dcab47c1c5bae7b)([#2353](https://www.github.com/tauri-apps/tauri/pull/2353)) Added the `maximizable`, `minimizable` and `closable` methods to `WindowBuilder`.
|
||||
- [`c4d6fb4b`](https://www.github.com/tauri-apps/tauri/commit/c4d6fb4b1ea8acf02707a9fe5dcab47c1c5bae7b)([#2353](https://www.github.com/tauri-apps/tauri/pull/2353)) Added `set_maximizable`, `set_minimizable`, `set_closable`, `is_maximizable`, `is_minimizable` and `is_closable` methods to the `Dispatch` trait.
|
||||
- [`000104bc`](https://www.github.com/tauri-apps/tauri/commit/000104bc3bc0c9ff3d20558ab9cf2080f126e9e0)([#6472](https://www.github.com/tauri-apps/tauri/pull/6472)) Add `Window::is_focused` getter.
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`d2710e9d`](https://www.github.com/tauri-apps/tauri/commit/d2710e9d2e8fd93975ef6494512370faa8cb3b7e)([#6944](https://www.github.com/tauri-apps/tauri/pull/6944)) Unpin `time`, `ignore`, and `winnow` crate versions. Developers now have to pin crates if needed themselves. A list of crates that need pinning to adhere to Tauri's MSRV will be visible in Tauri's GitHub workflow: https://github.com/tauri-apps/tauri/blob/dev/.github/workflows/test-core.yml#L85.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`2b487c94`](https://www.github.com/tauri-apps/tauri/commit/2b487c946737352187d7e042dd6142873e62a4ca)([#7012](https://www.github.com/tauri-apps/tauri/pull/7012)) Fixes typo in `CursorIcon` deserialization of the `ZoomIn` variant.
|
||||
|
||||
### What's Changed
|
||||
|
||||
- [`076e1a81`](https://www.github.com/tauri-apps/tauri/commit/076e1a81a50468e3dfb34ae9ca7e77c5e1758daa)([#7119](https://www.github.com/tauri-apps/tauri/pull/7119)) Use `u32` instead of `u64` for js event listener ids
|
||||
- [`ff5e4dbb`](https://www.github.com/tauri-apps/tauri/commit/ff5e4dbbb01bf3fc9c5143df732c75eef6fd98cb)([#6794](https://www.github.com/tauri-apps/tauri/pull/6794)) impl `From<&WindowConfig>` for `WebviewAttributes`.
|
||||
|
||||
## \[0.13.0]
|
||||
|
||||
- Added the `additional_browser_args` option when creating a window.
|
||||
@@ -25,6 +236,11 @@
|
||||
- On Windows, change webview theme based on Window theme for more accurate `prefers-color-scheme` support.
|
||||
- [7a8d570d](https://www.github.com/tauri-apps/tauri/commit/7a8d570db72667367eb24b75ddc5dd07a968f7c0) fix: sync webview theme with window theme on Windows, closes [#5802](https://www.github.com/tauri-apps/tauri/pull/5802) ([#5874](https://www.github.com/tauri-apps/tauri/pull/5874)) on 2022-12-27
|
||||
|
||||
## \[0.12.2]
|
||||
|
||||
- Block remote URLs from accessing the IPC.
|
||||
- [9c0593c33](https://www.github.com/tauri-apps/tauri/commit/9c0593c33af52cd9e00ec784d15f63efebdf039c) feat(core): block remote URLs from accessing the IPC on 2023-04-12
|
||||
|
||||
## \[0.12.1]
|
||||
|
||||
- Fix `allowlist > app > show/hide` always disabled when `allowlist > app > all: false`.
|
||||
@@ -45,6 +261,11 @@
|
||||
- Added the `user_agent` option when creating a window.
|
||||
- [a6c94119](https://www.github.com/tauri-apps/tauri/commit/a6c94119d8545d509723b147c273ca5edfe3729f) feat(core): expose user_agent to window config ([#5317](https://www.github.com/tauri-apps/tauri/pull/5317)) on 2022-10-02
|
||||
|
||||
## \[0.11.2]
|
||||
|
||||
- Block remote URLs from accessing the IPC.
|
||||
- [58ea0b452](https://www.github.com/tauri-apps/tauri/commit/58ea0b45268dbd46cbac0ebb0887353d057ca767) feat(core): block remote URLs from accessing the IPC on 2023-04-12
|
||||
|
||||
## \[0.11.1]
|
||||
|
||||
- Add missing allowlist config for `set_cursor_grab`, `set_cursor_visible`, `set_cursor_icon` and `set_cursor_position` APIs.
|
||||
@@ -58,6 +279,11 @@
|
||||
- Update windows to 0.39.0 and webview2-com to 0.19.1.
|
||||
- [e6d9b670](https://www.github.com/tauri-apps/tauri/commit/e6d9b670b0b314ed667b0e164f2c8d27048e678f) refactor: remove unneeded focus code ([#5065](https://www.github.com/tauri-apps/tauri/pull/5065)) on 2022-09-03
|
||||
|
||||
## \[0.10.3]
|
||||
|
||||
- Block remote URLs from accessing the IPC.
|
||||
- [fa90214b0](https://www.github.com/tauri-apps/tauri/commit/fa90214b052b1a5d38d54fbf1ca422b4c37cfd1f) feat(core): block remote URLs from accessing the IPC on 2023-04-12
|
||||
|
||||
## \[0.10.2]
|
||||
|
||||
- Added option to disable tray menu on left click on macOS.
|
||||
|
||||
@@ -1,52 +1,52 @@
|
||||
[package]
|
||||
name = "tauri-runtime"
|
||||
version = "0.13.0"
|
||||
authors = [ "Tauri Programme within The Commons Conservancy" ]
|
||||
categories = [ "gui", "web-programming" ]
|
||||
license = "Apache-2.0 OR MIT"
|
||||
homepage = "https://tauri.app"
|
||||
repository = "https://github.com/tauri-apps/tauri"
|
||||
version = "2.0.0-beta.0"
|
||||
description = "Runtime for Tauri applications"
|
||||
edition = "2021"
|
||||
rust-version = "1.60"
|
||||
exclude = [ "CHANGELOG.md", "/target" ]
|
||||
readme = "README.md"
|
||||
authors = { workspace = true }
|
||||
homepage = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
categories = { workspace = true }
|
||||
license = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = [ "--cfg", "doc_cfg" ]
|
||||
rustc-args = [ "--cfg", "docsrs" ]
|
||||
rustdoc-args = [ "--cfg", "docsrs" ]
|
||||
default-target = "x86_64-unknown-linux-gnu"
|
||||
targets = [
|
||||
"x86_64-pc-windows-msvc",
|
||||
"x86_64-unknown-linux-gnu",
|
||||
"x86_64-apple-darwin"
|
||||
"x86_64-apple-darwin",
|
||||
"x86_64-linux-android",
|
||||
"x86_64-apple-ios"
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1.0", features = [ "derive" ] }
|
||||
serde_json = "1.0"
|
||||
thiserror = "1.0"
|
||||
tauri-utils = { version = "1.3.0", path = "../tauri-utils" }
|
||||
uuid = { version = "1", features = [ "v4" ] }
|
||||
tauri-utils = { version = "2.0.0-beta.0", path = "../tauri-utils" }
|
||||
http = "0.2.4"
|
||||
http-range = "0.1.4"
|
||||
raw-window-handle = "=0.5.0"
|
||||
rand = "0.8"
|
||||
raw-window-handle = "0.5"
|
||||
url = { version = "2" }
|
||||
|
||||
[target."cfg(windows)".dependencies]
|
||||
webview2-com = "0.19.1"
|
||||
|
||||
[target."cfg(windows)".dependencies.windows]
|
||||
version = "0.39.0"
|
||||
features = [ "Win32_Foundation" ]
|
||||
[target."cfg(windows)".dependencies.windows]
|
||||
version = "0.52"
|
||||
features = [ "Win32_Foundation" ]
|
||||
|
||||
[target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
|
||||
gtk = { version = "0.15", features = [ "v3_20" ] }
|
||||
gtk = { version = "0.18", features = [ "v3_24" ] }
|
||||
|
||||
[target."cfg(target_os = \"android\")".dependencies]
|
||||
jni = "0.21"
|
||||
|
||||
[target."cfg(target_os = \"macos\")".dependencies]
|
||||
url = "2"
|
||||
|
||||
[features]
|
||||
devtools = [ ]
|
||||
system-tray = [ ]
|
||||
macos-private-api = [ ]
|
||||
global-shortcut = [ ]
|
||||
clipboard = [ ]
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
[](https://discord.gg/SpmNs4S)
|
||||
[](https://dev.to/tauri)
|
||||
|
||||

|
||||
[](https://github.com/tauri-apps/tauri/actions/workflows/test-core.yml)
|
||||
[](https://tauri.app)
|
||||
|
||||
[](https://good-labs.github.io/greater-good-affirmation)
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// custom wry types
|
||||
mod request;
|
||||
mod response;
|
||||
|
||||
pub use self::{
|
||||
request::{Request, RequestParts},
|
||||
response::{Builder as ResponseBuilder, Response, ResponseParts},
|
||||
};
|
||||
|
||||
pub use tauri_utils::mime_type::MimeType;
|
||||
|
||||
// re-expose default http types
|
||||
pub use http::{header, method, status, uri::InvalidUri, version, Uri};
|
||||
|
||||
// re-export httprange helper as it can be useful and we need it locally
|
||||
pub use http_range::HttpRange;
|
||||
@@ -1,132 +0,0 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use super::{
|
||||
header::{HeaderMap, HeaderValue},
|
||||
method::Method,
|
||||
};
|
||||
|
||||
/// Represents an HTTP request from the WebView.
|
||||
///
|
||||
/// An HTTP request consists of a head and a potentially optional body.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Linux:** Headers are not exposed.
|
||||
pub struct Request {
|
||||
head: RequestParts,
|
||||
body: Vec<u8>,
|
||||
}
|
||||
|
||||
/// Component parts of an HTTP `Request`
|
||||
///
|
||||
/// The HTTP request head consists of a method, uri, and a set of
|
||||
/// header fields.
|
||||
#[derive(Clone)]
|
||||
pub struct RequestParts {
|
||||
/// The request's method
|
||||
pub method: Method,
|
||||
|
||||
/// The request's URI
|
||||
pub uri: String,
|
||||
|
||||
/// The request's headers
|
||||
pub headers: HeaderMap<HeaderValue>,
|
||||
}
|
||||
|
||||
impl Request {
|
||||
/// Creates a new blank `Request` with the body
|
||||
#[inline]
|
||||
pub fn new(body: Vec<u8>) -> Request {
|
||||
Request {
|
||||
head: RequestParts::new(),
|
||||
body,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new `Request` with the given head and body.
|
||||
///
|
||||
/// # Stability
|
||||
///
|
||||
/// This API is used internally. It may have breaking changes in the future.
|
||||
#[inline]
|
||||
#[doc(hidden)]
|
||||
pub fn new_internal(head: RequestParts, body: Vec<u8>) -> Request {
|
||||
Request { head, body }
|
||||
}
|
||||
|
||||
/// Returns a reference to the associated HTTP method.
|
||||
#[inline]
|
||||
pub fn method(&self) -> &Method {
|
||||
&self.head.method
|
||||
}
|
||||
|
||||
/// Returns a reference to the associated URI.
|
||||
#[inline]
|
||||
pub fn uri(&self) -> &str {
|
||||
&self.head.uri
|
||||
}
|
||||
|
||||
/// Returns a reference to the associated header field map.
|
||||
#[inline]
|
||||
pub fn headers(&self) -> &HeaderMap<HeaderValue> {
|
||||
&self.head.headers
|
||||
}
|
||||
|
||||
/// Returns a reference to the associated HTTP body.
|
||||
#[inline]
|
||||
pub fn body(&self) -> &Vec<u8> {
|
||||
&self.body
|
||||
}
|
||||
|
||||
/// Consumes the request returning the head and body RequestParts.
|
||||
///
|
||||
/// # Stability
|
||||
///
|
||||
/// This API is used internally. It may have breaking changes in the future.
|
||||
#[inline]
|
||||
pub fn into_parts(self) -> (RequestParts, Vec<u8>) {
|
||||
(self.head, self.body)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Request {
|
||||
fn default() -> Request {
|
||||
Request::new(Vec::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Request {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("Request")
|
||||
.field("method", self.method())
|
||||
.field("uri", &self.uri())
|
||||
.field("headers", self.headers())
|
||||
.field("body", self.body())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl RequestParts {
|
||||
/// Creates a new default instance of `RequestParts`
|
||||
fn new() -> RequestParts {
|
||||
RequestParts {
|
||||
method: Method::default(),
|
||||
uri: "".into(),
|
||||
headers: HeaderMap::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for RequestParts {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("Parts")
|
||||
.field("method", &self.method)
|
||||
.field("uri", &self.uri)
|
||||
.field("headers", &self.headers)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
@@ -1,306 +0,0 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use super::{
|
||||
header::{HeaderMap, HeaderName, HeaderValue},
|
||||
status::StatusCode,
|
||||
version::Version,
|
||||
};
|
||||
use std::fmt;
|
||||
|
||||
type Result<T> = core::result::Result<T, Box<dyn std::error::Error>>;
|
||||
|
||||
/// Represents an HTTP response
|
||||
///
|
||||
/// An HTTP response consists of a head and a potentially body.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Linux:** Headers and status code cannot be changed.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use tauri_runtime::http::*;
|
||||
///
|
||||
/// let response = ResponseBuilder::new()
|
||||
/// .status(202)
|
||||
/// .mimetype("text/html")
|
||||
/// .body("hello!".as_bytes().to_vec())
|
||||
/// .unwrap();
|
||||
/// ```
|
||||
///
|
||||
pub struct Response {
|
||||
head: ResponseParts,
|
||||
body: Vec<u8>,
|
||||
}
|
||||
|
||||
/// Component parts of an HTTP `Response`
|
||||
///
|
||||
/// The HTTP response head consists of a status, version, and a set of
|
||||
/// header fields.
|
||||
#[derive(Clone)]
|
||||
pub struct ResponseParts {
|
||||
/// The response's status.
|
||||
pub status: StatusCode,
|
||||
|
||||
/// The response's version.
|
||||
pub version: Version,
|
||||
|
||||
/// The response's headers.
|
||||
pub headers: HeaderMap<HeaderValue>,
|
||||
|
||||
/// The response's mimetype type.
|
||||
pub mimetype: Option<String>,
|
||||
}
|
||||
|
||||
/// An HTTP response builder
|
||||
///
|
||||
/// This type can be used to construct an instance of `Response` through a
|
||||
/// builder-like pattern.
|
||||
#[derive(Debug)]
|
||||
pub struct Builder {
|
||||
inner: Result<ResponseParts>,
|
||||
}
|
||||
|
||||
impl Response {
|
||||
/// Creates a new blank `Response` with the body
|
||||
#[inline]
|
||||
pub fn new(body: Vec<u8>) -> Response {
|
||||
Response {
|
||||
head: ResponseParts::new(),
|
||||
body,
|
||||
}
|
||||
}
|
||||
|
||||
/// Consumes the response returning the head and body ResponseParts.
|
||||
///
|
||||
/// # Stability
|
||||
///
|
||||
/// This API is used internally. It may have breaking changes in the future.
|
||||
#[inline]
|
||||
#[doc(hidden)]
|
||||
pub fn into_parts(self) -> (ResponseParts, Vec<u8>) {
|
||||
(self.head, self.body)
|
||||
}
|
||||
|
||||
/// Sets the status code.
|
||||
#[inline]
|
||||
pub fn set_status(&mut self, status: StatusCode) {
|
||||
self.head.status = status;
|
||||
}
|
||||
|
||||
/// Returns the [`StatusCode`].
|
||||
#[inline]
|
||||
pub fn status(&self) -> StatusCode {
|
||||
self.head.status
|
||||
}
|
||||
|
||||
/// Sets the mimetype.
|
||||
#[inline]
|
||||
pub fn set_mimetype(&mut self, mimetype: Option<String>) {
|
||||
self.head.mimetype = mimetype;
|
||||
}
|
||||
|
||||
/// Returns a reference to the mime type.
|
||||
#[inline]
|
||||
pub fn mimetype(&self) -> Option<&String> {
|
||||
self.head.mimetype.as_ref()
|
||||
}
|
||||
|
||||
/// Returns a reference to the associated version.
|
||||
#[inline]
|
||||
pub fn version(&self) -> Version {
|
||||
self.head.version
|
||||
}
|
||||
|
||||
/// Returns a mutable reference to the associated header field map.
|
||||
#[inline]
|
||||
pub fn headers_mut(&mut self) -> &mut HeaderMap<HeaderValue> {
|
||||
&mut self.head.headers
|
||||
}
|
||||
|
||||
/// Returns a reference to the associated header field map.
|
||||
#[inline]
|
||||
pub fn headers(&self) -> &HeaderMap<HeaderValue> {
|
||||
&self.head.headers
|
||||
}
|
||||
|
||||
/// Returns a mutable reference to the associated HTTP body.
|
||||
#[inline]
|
||||
pub fn body_mut(&mut self) -> &mut Vec<u8> {
|
||||
&mut self.body
|
||||
}
|
||||
|
||||
/// Returns a reference to the associated HTTP body.
|
||||
#[inline]
|
||||
pub fn body(&self) -> &Vec<u8> {
|
||||
&self.body
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Response {
|
||||
#[inline]
|
||||
fn default() -> Response {
|
||||
Response::new(Vec::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Response {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("Response")
|
||||
.field("status", &self.status())
|
||||
.field("version", &self.version())
|
||||
.field("headers", self.headers())
|
||||
.field("body", self.body())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl ResponseParts {
|
||||
/// Creates a new default instance of `ResponseParts`
|
||||
fn new() -> ResponseParts {
|
||||
ResponseParts {
|
||||
status: StatusCode::default(),
|
||||
version: Version::default(),
|
||||
headers: HeaderMap::default(),
|
||||
mimetype: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ResponseParts {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("Parts")
|
||||
.field("status", &self.status)
|
||||
.field("version", &self.version)
|
||||
.field("headers", &self.headers)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl Builder {
|
||||
/// Creates a new default instance of `Builder` to construct either a
|
||||
/// `Head` or a `Response`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use tauri_runtime::http::*;
|
||||
///
|
||||
/// let response = ResponseBuilder::new()
|
||||
/// .status(200)
|
||||
/// .mimetype("text/html")
|
||||
/// .body(Vec::new())
|
||||
/// .unwrap();
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn new() -> Builder {
|
||||
Builder {
|
||||
inner: Ok(ResponseParts::new()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the HTTP mimetype for this response.
|
||||
#[must_use]
|
||||
pub fn mimetype(self, mimetype: &str) -> Self {
|
||||
self.and_then(move |mut head| {
|
||||
head.mimetype = Some(mimetype.to_string());
|
||||
Ok(head)
|
||||
})
|
||||
}
|
||||
|
||||
/// Set the HTTP status for this response.
|
||||
#[must_use]
|
||||
pub fn status<T>(self, status: T) -> Self
|
||||
where
|
||||
StatusCode: TryFrom<T>,
|
||||
<StatusCode as TryFrom<T>>::Error: Into<crate::Error>,
|
||||
{
|
||||
self.and_then(move |mut head| {
|
||||
head.status = TryFrom::try_from(status).map_err(Into::into)?;
|
||||
Ok(head)
|
||||
})
|
||||
}
|
||||
|
||||
/// Set the HTTP version for this response.
|
||||
///
|
||||
/// This function will configure the HTTP version of the `Response` that
|
||||
/// will be returned from `Builder::build`.
|
||||
///
|
||||
/// By default this is HTTP/1.1
|
||||
#[must_use]
|
||||
pub fn version(self, version: Version) -> Self {
|
||||
self.and_then(move |mut head| {
|
||||
head.version = version;
|
||||
Ok(head)
|
||||
})
|
||||
}
|
||||
|
||||
/// Appends a header to this response builder.
|
||||
///
|
||||
/// This function will append the provided key/value as a header to the
|
||||
/// internal `HeaderMap` being constructed. Essentially this is equivalent
|
||||
/// to calling `HeaderMap::append`.
|
||||
#[must_use]
|
||||
pub fn header<K, V>(self, key: K, value: V) -> Self
|
||||
where
|
||||
HeaderName: TryFrom<K>,
|
||||
<HeaderName as TryFrom<K>>::Error: Into<crate::Error>,
|
||||
HeaderValue: TryFrom<V>,
|
||||
<HeaderValue as TryFrom<V>>::Error: Into<crate::Error>,
|
||||
{
|
||||
self.and_then(move |mut head| {
|
||||
let name = <HeaderName as TryFrom<K>>::try_from(key).map_err(Into::into)?;
|
||||
let value = <HeaderValue as TryFrom<V>>::try_from(value).map_err(Into::into)?;
|
||||
head.headers.append(name, value);
|
||||
Ok(head)
|
||||
})
|
||||
}
|
||||
|
||||
/// "Consumes" this builder, using the provided `body` to return a
|
||||
/// constructed `Response`.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// This function may return an error if any previously configured argument
|
||||
/// failed to parse or get converted to the internal representation. For
|
||||
/// example if an invalid `head` was specified via `header("Foo",
|
||||
/// "Bar\r\n")` the error will be returned when this function is called
|
||||
/// rather than when `header` was called.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use tauri_runtime::http::*;
|
||||
///
|
||||
/// let response = ResponseBuilder::new()
|
||||
/// .mimetype("text/html")
|
||||
/// .body(Vec::new())
|
||||
/// .unwrap();
|
||||
/// ```
|
||||
pub fn body(self, body: Vec<u8>) -> Result<Response> {
|
||||
self.inner.map(move |head| Response { head, body })
|
||||
}
|
||||
|
||||
// private
|
||||
|
||||
fn and_then<F>(self, func: F) -> Self
|
||||
where
|
||||
F: FnOnce(ResponseParts) -> Result<ResponseParts>,
|
||||
{
|
||||
Builder {
|
||||
inner: self.inner.and_then(func),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Builder {
|
||||
#[inline]
|
||||
fn default() -> Builder {
|
||||
Builder {
|
||||
inner: Ok(ResponseParts::new()),
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user