mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-04-11 10:43:31 +02:00
Compare commits
459 Commits
@tauri-app
...
@tauri-app
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
005e4a9649 | ||
|
|
88619e8914 | ||
|
|
786f188923 | ||
|
|
7ba67b4aca | ||
|
|
a5bfbaa62b | ||
|
|
b32295de18 | ||
|
|
6755af2302 | ||
|
|
24445d71de | ||
|
|
eaec5fe9c1 | ||
|
|
1e0793b682 | ||
|
|
d03332617c | ||
|
|
d5511c3117 | ||
|
|
426d14bb41 | ||
|
|
87029310b8 | ||
|
|
758d28c8a2 | ||
|
|
a0841d509a | ||
|
|
11af545bf3 | ||
|
|
a0af6c00df | ||
|
|
cf994a6bb0 | ||
|
|
289ae5555d | ||
|
|
7aeac39e7f | ||
|
|
498f405ca8 | ||
|
|
2a402b4845 | ||
|
|
efdce038bb | ||
|
|
e1776946ad | ||
|
|
c072090ed8 | ||
|
|
f153e8b0fe | ||
|
|
8b3e6eccf4 | ||
|
|
cfc53074d0 | ||
|
|
88552d66c3 | ||
|
|
9546548ec0 | ||
|
|
7acac58d23 | ||
|
|
da25f73530 | ||
|
|
26f2e19a4f | ||
|
|
9f0a5fceac | ||
|
|
d1df6be701 | ||
|
|
506f1dd873 | ||
|
|
3c17fb64fd | ||
|
|
6d965e9fbf | ||
|
|
7c7fa0964d | ||
|
|
532b3b1c03 | ||
|
|
202f15fc40 | ||
|
|
261c9f942d | ||
|
|
69dcfdfe0f | ||
|
|
5d29229858 | ||
|
|
4c239729c3 | ||
|
|
c01e87ad46 | ||
|
|
2c076d63d0 | ||
|
|
ba9590aa92 | ||
|
|
1a88fc1a9b | ||
|
|
2b1ceb40d3 | ||
|
|
249cdde9b6 | ||
|
|
11339418b1 | ||
|
|
080b6e1272 | ||
|
|
57612ab249 | ||
|
|
15e1259966 | ||
|
|
b4e16f3d8e | ||
|
|
a4a7233081 | ||
|
|
c734b9e3cd | ||
|
|
afb102c59b | ||
|
|
5998a90f3f | ||
|
|
24aaf0f5af | ||
|
|
94136578bc | ||
|
|
96f65fef36 | ||
|
|
11aa7743e7 | ||
|
|
55733aba9c | ||
|
|
7bc6a2a1d6 | ||
|
|
a7354f9a81 | ||
|
|
eeae0660e1 | ||
|
|
ff79161b0d | ||
|
|
f5b121be6e | ||
|
|
1cc9aa4b66 | ||
|
|
911242f092 | ||
|
|
e7fd7c60d6 | ||
|
|
5878fb45ce | ||
|
|
3afe828940 | ||
|
|
77d44215ef | ||
|
|
e93ca1df3b | ||
|
|
27838365a6 | ||
|
|
167b51a8de | ||
|
|
878198777e | ||
|
|
1601da5b52 | ||
|
|
eb76df4c4f | ||
|
|
1f6e478c84 | ||
|
|
7d85f7cf82 | ||
|
|
f21029b1bc | ||
|
|
a15a97594f | ||
|
|
35110dba21 | ||
|
|
bb50315c50 | ||
|
|
61bbd8373f | ||
|
|
6c9e24a683 | ||
|
|
cee0bfcd6c | ||
|
|
d4c908cfb8 | ||
|
|
669b9c6b5a | ||
|
|
faf282ca6c | ||
|
|
e13ea53a26 | ||
|
|
82c2eb3284 | ||
|
|
58821fc0e5 | ||
|
|
3bbfac8f3b | ||
|
|
16641723b0 | ||
|
|
3fd84cb3c9 | ||
|
|
b2ff840e83 | ||
|
|
4ca297b35b | ||
|
|
c98f385cb5 | ||
|
|
85889f289b | ||
|
|
79542f4d45 | ||
|
|
f56cdc9e39 | ||
|
|
b9e11a8b97 | ||
|
|
f44a2ec47c | ||
|
|
5b769948a8 | ||
|
|
586a816e62 | ||
|
|
6f469534b0 | ||
|
|
30bc3d2095 | ||
|
|
de7da04a62 | ||
|
|
27abecd6e5 | ||
|
|
148f048871 | ||
|
|
3ab170917e | ||
|
|
656a649744 | ||
|
|
f29b788110 | ||
|
|
fafc238f72 | ||
|
|
40c0f44e1c | ||
|
|
f955f7b490 | ||
|
|
e6e17ad1c8 | ||
|
|
ea78bf5558 | ||
|
|
019a74e970 | ||
|
|
ddaabda365 | ||
|
|
3cca5c2be8 | ||
|
|
916a26c2a1 | ||
|
|
0a6e62ac58 | ||
|
|
38df6ea1c1 | ||
|
|
a0a76cea2f | ||
|
|
dfd05441c7 | ||
|
|
5e8aa6f946 | ||
|
|
4942d809ab | ||
|
|
594e3e2939 | ||
|
|
94cca92aeb | ||
|
|
265c23886e | ||
|
|
e8f6eb59a5 | ||
|
|
19b696b61c | ||
|
|
ccc3ea729d | ||
|
|
bcc63bf36d | ||
|
|
8b032c3cf6 | ||
|
|
adac2185a3 | ||
|
|
aa55e03354 | ||
|
|
3f1c59d684 | ||
|
|
71a5e2ba24 | ||
|
|
4754786aa2 | ||
|
|
9970d88bec | ||
|
|
aaecb6a72e | ||
|
|
27fd8cc56c | ||
|
|
9e4b2253f6 | ||
|
|
5462e5cadc | ||
|
|
418d72d72d | ||
|
|
80aa504987 | ||
|
|
c4410daa85 | ||
|
|
276c4b1438 | ||
|
|
9ac930380a | ||
|
|
fd2d7cf8b3 | ||
|
|
d6d3efbd12 | ||
|
|
fc1543c65e | ||
|
|
1df5cdeb06 | ||
|
|
8a1ae2deaf | ||
|
|
51b5d581b5 | ||
|
|
d950ac1239 | ||
|
|
beda18bce9 | ||
|
|
ae6b13dfc0 | ||
|
|
0b690f242f | ||
|
|
f4d67818f8 | ||
|
|
781d74799a | ||
|
|
5d20530c91 | ||
|
|
d0d974fa5e | ||
|
|
0c61784efb | ||
|
|
fe90a2925e | ||
|
|
c4bacce2c2 | ||
|
|
86250a476e | ||
|
|
be95d8d37c | ||
|
|
e713ceb75d | ||
|
|
ec0e092ecd | ||
|
|
31aa90f514 | ||
|
|
67ea20999b | ||
|
|
4a33bc6a62 | ||
|
|
bd64982fe6 | ||
|
|
caec19fce3 | ||
|
|
6968c40053 | ||
|
|
5a85ee2826 | ||
|
|
1bee4f279f | ||
|
|
c0bcc6c0b7 | ||
|
|
fedca73860 | ||
|
|
e78bfa722e | ||
|
|
6f281b2e30 | ||
|
|
a813caf2e4 | ||
|
|
82e1c75594 | ||
|
|
78839b6d2f | ||
|
|
783ef0f2d3 | ||
|
|
d2fc48f0e6 | ||
|
|
a5205f179e | ||
|
|
5529c5ab69 | ||
|
|
5ce0737e9a | ||
|
|
83acd85788 | ||
|
|
3fbc1703f1 | ||
|
|
8385733a69 | ||
|
|
07ff78c2de | ||
|
|
f1badb9fb3 | ||
|
|
97ec422f22 | ||
|
|
7f6d2698c9 | ||
|
|
8a71858eb2 | ||
|
|
bf2635ab62 | ||
|
|
cd5580749c | ||
|
|
b0421cbb21 | ||
|
|
d5775ed6a4 | ||
|
|
007af10d43 | ||
|
|
aa080696e0 | ||
|
|
1bb87a3a22 | ||
|
|
6c047aee14 | ||
|
|
108ab9094a | ||
|
|
380c507d38 | ||
|
|
128c580009 | ||
|
|
3f08054885 | ||
|
|
477bb8cd4e | ||
|
|
5a213a4bdc | ||
|
|
eff778b8f0 | ||
|
|
6d5a396ae9 | ||
|
|
98101cb17f | ||
|
|
68c39b8c0c | ||
|
|
12b4159bda | ||
|
|
ac9bfada4a | ||
|
|
e22e61af6c | ||
|
|
198f11ae7b | ||
|
|
07f2af0002 | ||
|
|
de7bcf3cc5 | ||
|
|
a1e0e268f0 | ||
|
|
be7eab209c | ||
|
|
aaa332c6e7 | ||
|
|
35b25f7e5c | ||
|
|
70c51371e0 | ||
|
|
005fe8ce1e | ||
|
|
cf615e8e4d | ||
|
|
de7a294cc4 | ||
|
|
88c0ad9cf5 | ||
|
|
daf018e4f5 | ||
|
|
05088b0679 | ||
|
|
e64b8f1dce | ||
|
|
a07b513201 | ||
|
|
8a63ceb4f3 | ||
|
|
639d9abfdf | ||
|
|
3fe9ae8520 | ||
|
|
55bf4eb51c | ||
|
|
535691a711 | ||
|
|
02eaf07872 | ||
|
|
c8a82ad223 | ||
|
|
48a7a78f80 | ||
|
|
1d39876f97 | ||
|
|
f22ea29986 | ||
|
|
f1674fce6d | ||
|
|
73c1c2d338 | ||
|
|
9331435a50 | ||
|
|
cd23bb2ca2 | ||
|
|
8f4b1050c4 | ||
|
|
32b213399f | ||
|
|
4973d73a23 | ||
|
|
58a7a552d7 | ||
|
|
b231f4c2e5 | ||
|
|
9273d7b379 | ||
|
|
36b4c12497 | ||
|
|
2f20fdf1d6 | ||
|
|
6251645acf | ||
|
|
4c2e7477e6 | ||
|
|
1a58cdf2ed | ||
|
|
284eca9ef2 | ||
|
|
8276ab767b | ||
|
|
f8fde4f845 | ||
|
|
dd07a36749 | ||
|
|
93e0e1392e | ||
|
|
06833f4fa8 | ||
|
|
b78f90bc9c | ||
|
|
a804a70a7a | ||
|
|
7c334cb185 | ||
|
|
6703b7cbca | ||
|
|
5bd47b4467 | ||
|
|
259d845290 | ||
|
|
c33f6e6cf3 | ||
|
|
e7cd973123 | ||
|
|
7898b601d1 | ||
|
|
b525ddadf7 | ||
|
|
ee028c414d | ||
|
|
edc9923c5b | ||
|
|
a799f24f97 | ||
|
|
ac76a22f38 | ||
|
|
81b853bc87 | ||
|
|
75f5cb4015 | ||
|
|
43230cb6b7 | ||
|
|
fb146339cc | ||
|
|
72d9876bc8 | ||
|
|
f1df6b2c35 | ||
|
|
379cc2b354 | ||
|
|
ea0242db4a | ||
|
|
7213b9e472 | ||
|
|
acdd76833d | ||
|
|
e227fe02f9 | ||
|
|
3f039c18b1 | ||
|
|
79b8a3514b | ||
|
|
d349558abb | ||
|
|
a44cd5a183 | ||
|
|
e673854c83 | ||
|
|
490a6b424e | ||
|
|
85de230f31 | ||
|
|
c3ea3a2b7d | ||
|
|
db0a24a973 | ||
|
|
26f0f71a40 | ||
|
|
ba0206d8a3 | ||
|
|
db1ea98512 | ||
|
|
45384ab3aa | ||
|
|
9247ecf2a4 | ||
|
|
d701f29f17 | ||
|
|
94ab97a884 | ||
|
|
5deb1202f6 | ||
|
|
ed48e2b3c7 | ||
|
|
5541aafef3 | ||
|
|
80c12ead46 | ||
|
|
3e472d0afc | ||
|
|
4ef17d0833 | ||
|
|
9dc9ca6e38 | ||
|
|
e7f245e81e | ||
|
|
720357fd5c | ||
|
|
5829f23171 | ||
|
|
8383bea741 | ||
|
|
cd05827f9f | ||
|
|
9323fb7cda | ||
|
|
251bdd0579 | ||
|
|
253a661516 | ||
|
|
b5c7432769 | ||
|
|
bb23511ea8 | ||
|
|
4bf1c55b0d | ||
|
|
fe18012d30 | ||
|
|
6a47dd212c | ||
|
|
7cec1049e8 | ||
|
|
86fa339de7 | ||
|
|
e62ca4ee95 | ||
|
|
6c06832246 | ||
|
|
9aa0d6e959 | ||
|
|
46de49aaad | ||
|
|
b4ffbe7aa2 | ||
|
|
ab37d6724e | ||
|
|
1b18b7006f | ||
|
|
947a50b8e2 | ||
|
|
77b9a508a4 | ||
|
|
2ca9afb576 | ||
|
|
4b75834a41 | ||
|
|
03098b5315 | ||
|
|
a77be97474 | ||
|
|
c68218b362 | ||
|
|
4f78941763 | ||
|
|
d1e77acd8d | ||
|
|
ab060ebb34 | ||
|
|
8fcbce9404 | ||
|
|
f5e7f3843e | ||
|
|
d7f56fef85 | ||
|
|
d7d03c7197 | ||
|
|
e4463f0814 | ||
|
|
f5f3ed5f6f | ||
|
|
cb92cfd6a6 | ||
|
|
b658ded614 | ||
|
|
04440edce8 | ||
|
|
3657ad82f8 | ||
|
|
7190935680 | ||
|
|
222a96b74b | ||
|
|
de38c31163 | ||
|
|
e1d5b79063 | ||
|
|
5a19147b06 | ||
|
|
31a33d4680 | ||
|
|
b9e6a01879 | ||
|
|
60bf11abcb | ||
|
|
06d63d67a0 | ||
|
|
9be314f07a | ||
|
|
bc5b5e671a | ||
|
|
6cb601d42e | ||
|
|
a8a2cb6fb4 | ||
|
|
cbd9755e09 | ||
|
|
9cc014f2df | ||
|
|
f5e4b67203 | ||
|
|
6edc563cf9 | ||
|
|
0606ab326b | ||
|
|
5ddea72c50 | ||
|
|
a76fb118ce | ||
|
|
e538ba586c | ||
|
|
84c783f6bc | ||
|
|
6e3bd4b9f8 | ||
|
|
fdcaf935fa | ||
|
|
b5eb64728a | ||
|
|
d75713ac6c | ||
|
|
af646520cf | ||
|
|
361ec37fd4 | ||
|
|
33bbd7fe94 | ||
|
|
a029b9f77e | ||
|
|
3fb414b61a | ||
|
|
18ff84fc81 | ||
|
|
c115a978bb | ||
|
|
0e8e9cd064 | ||
|
|
6f064a0d6f | ||
|
|
258494bd24 | ||
|
|
f284f9c545 | ||
|
|
8d16a80d2f | ||
|
|
770051ae63 | ||
|
|
c426c0dca2 | ||
|
|
e816a46b95 | ||
|
|
a4b82d9dba | ||
|
|
b735b6799f | ||
|
|
77f49ad55e | ||
|
|
dbd525ca64 | ||
|
|
28fb036ce4 | ||
|
|
ed33b851c7 | ||
|
|
d72b6f3842 | ||
|
|
83a68deb56 | ||
|
|
0cb0a15ce2 | ||
|
|
edb11c138d | ||
|
|
052e8b4311 | ||
|
|
e52d5e573f | ||
|
|
16e550ec15 | ||
|
|
5618f6d2ff | ||
|
|
11a5816bdf | ||
|
|
3cee26a58a | ||
|
|
7b5e8712e7 | ||
|
|
2421073576 | ||
|
|
46b6598a94 | ||
|
|
cf3e40cc47 | ||
|
|
510b62261c | ||
|
|
2f55bfecbf | ||
|
|
dd7571a780 | ||
|
|
aa06a0534c | ||
|
|
fb0d997117 | ||
|
|
8751c3299f | ||
|
|
2e6db908d7 | ||
|
|
19fb5f0b20 | ||
|
|
b0f27814b9 | ||
|
|
f2e4c9de3a | ||
|
|
ae0fe47c4c | ||
|
|
baca704d4b | ||
|
|
bd73ab0a1a | ||
|
|
cc3d8e7731 | ||
|
|
8ce51cec3b | ||
|
|
0bff8c325d | ||
|
|
a9b2c0625c | ||
|
|
7aa30dec85 | ||
|
|
4926648751 | ||
|
|
06890c70c6 | ||
|
|
1ca69bcf2f | ||
|
|
6bdba1f330 | ||
|
|
b546b42db7 | ||
|
|
67d7877f27 | ||
|
|
89911296e4 | ||
|
|
8f8729d918 | ||
|
|
446fc99bbe | ||
|
|
6e48837860 | ||
|
|
883e52153e | ||
|
|
5966812735 | ||
|
|
b44e9c0fcb | ||
|
|
b2f83f03a8 | ||
|
|
0a2175eabb | ||
|
|
645e1dcc6e |
44
.changes/README.md
Normal file
44
.changes/README.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# 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:enhance'
|
||||
'package-b': 'patch:enhance'
|
||||
---
|
||||
|
||||
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).
|
||||
|
||||
Additionally you could specify a tag for the change file to group it with other changes by prefixing the bump with `:<tag>`, for example:
|
||||
|
||||
```md
|
||||
---
|
||||
'package-a': 'patch:enhance'
|
||||
---
|
||||
|
||||
Change summary goes here
|
||||
```
|
||||
|
||||
which will group this change file with other changes that specify the `bug` tag.
|
||||
|
||||
For list of available tags, see the `changeTags` key in [./config.json](./config.json)
|
||||
6
.changes/asset-resolver-dev-fallback.md
Normal file
6
.changes/asset-resolver-dev-fallback.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"tauri": patch:enhance
|
||||
"tauri-codegen": patch:enhance
|
||||
---
|
||||
|
||||
Enhance `AssetResolver::get` in development mode by reading distDir directly as a fallback to the embedded assets.
|
||||
@@ -1,15 +0,0 @@
|
||||
---
|
||||
"tauri": major:feat
|
||||
"tauri-plugin": major:feat
|
||||
"tauri-build": major:feat
|
||||
"tauri-utils": major:feat
|
||||
"tauri-codegen": major:feat
|
||||
"tauri-macros": major:feat
|
||||
"tauri-runtime": major:feat
|
||||
"tauri-runtime-wry": major:feat
|
||||
"tauri-cli": major:feat
|
||||
"@tauri-apps/api": major:feat
|
||||
"@tauri-apps/cli": major:feat
|
||||
---
|
||||
|
||||
Move to beta!
|
||||
5
.changes/change-pr-10435.md
Normal file
5
.changes/change-pr-10435.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"tauri": patch:bug
|
||||
---
|
||||
|
||||
Fix Specta remote implementation target for `Channel`.
|
||||
6
.changes/cli-desktop-port-exposure.md
Normal file
6
.changes/cli-desktop-port-exposure.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"tauri-cli": "patch:enhance"
|
||||
"@tauri-apps/cli": "patch:enhance"
|
||||
---
|
||||
|
||||
Changes the default behavior of the `dev` command to only expose to localhost (`127.0.0.1`) instead of the default system interface.
|
||||
@@ -71,7 +71,7 @@
|
||||
],
|
||||
"assets": [
|
||||
{
|
||||
"path": "${ pkg.path }/target/package/${ pkg.pkg }-${ pkgFile.version }.crate",
|
||||
"path": "./target/package/${ pkg.pkg }-${ pkgFile.version }.crate",
|
||||
"name": "${ pkg.pkg }-${ pkgFile.version }.crate"
|
||||
}
|
||||
]
|
||||
@@ -188,10 +188,14 @@
|
||||
"path": "./core/tauri-utils",
|
||||
"manager": "rust"
|
||||
},
|
||||
"tauri-macos-sign": {
|
||||
"path": "./tooling/macos-sign",
|
||||
"manager": "rust"
|
||||
},
|
||||
"tauri-bundler": {
|
||||
"path": "./tooling/bundler",
|
||||
"manager": "rust",
|
||||
"dependencies": ["tauri-utils"]
|
||||
"dependencies": ["tauri-utils", "tauri-macos-sign"]
|
||||
},
|
||||
"tauri-runtime": {
|
||||
"path": "./core/tauri-runtime",
|
||||
@@ -262,7 +266,7 @@
|
||||
"tauri-cli": {
|
||||
"path": "./tooling/cli",
|
||||
"manager": "rust",
|
||||
"dependencies": ["tauri-bundler", "tauri-utils"],
|
||||
"dependencies": ["tauri-bundler", "tauri-utils", "tauri-macos-sign"],
|
||||
"postversion": [
|
||||
"cargo check",
|
||||
"cargo build --manifest-path ../../core/tauri-config-schema/Cargo.toml"
|
||||
|
||||
9
.changes/core-plugin-namespace.md
Normal file
9
.changes/core-plugin-namespace.md
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
"tauri": patch:breaking
|
||||
"tauri-plugin": patch:breaking
|
||||
"@tauri-apps/cli": patch:breaking
|
||||
"tauri-cli": patch:breaking
|
||||
---
|
||||
|
||||
Core plugin permissions are now prefixed with `core:`, the `core:default` permission set can now be used and the `core` plugin name is reserved.
|
||||
The `tauri migrate` tool will automate the migration process, which involves prefixing all `app`, `event`, `image`, `menu`, `path`, `resources`, `tray`, `webview` and `window` permissions with `core:`.
|
||||
9
.changes/dev-url-localhost-mobile.md
Normal file
9
.changes/dev-url-localhost-mobile.md
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
"tauri-cli": patch:breaking
|
||||
"@tauri-apps/cli": patch:breaking
|
||||
---
|
||||
|
||||
`ios dev` and `android dev` now uses localhost for the development server unless running on an iOS device,
|
||||
which still requires connecting to the public network address. To conditionally check this on your frontend
|
||||
framework's configuration you can check for the existence of the `TAURI_DEV_HOST`
|
||||
environment variable instead of checking if the target is iOS or Android (previous recommendation).
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"tauri-build": patch:bug
|
||||
---
|
||||
|
||||
Do not trigger build script to rerun if the frontendDist directory does not exist.
|
||||
7
.changes/fix-conf-parsing-error-filepath.md
Normal file
7
.changes/fix-conf-parsing-error-filepath.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"tauri-utils": "patch:bug"
|
||||
---
|
||||
|
||||
Fixed an issue where configuration parsing errors always displayed 'tauri.conf.json' as the file path, even when using 'Tauri.toml' or 'tauri.conf.json5'.
|
||||
|
||||
The error messages now correctly shows the actual config file being used.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"tauri": patch:bug
|
||||
---
|
||||
|
||||
Fix regression on the JavaScript code that processes the IPC message.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"tauri-build": patch:bug
|
||||
---
|
||||
|
||||
Do not rewrite capability JSON schema if it did not change.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"tauri": patch:bug
|
||||
---
|
||||
|
||||
Workaround for zbus not enabling the proper Cargo features for its nix dependency.
|
||||
6
.changes/fix-usage-without-compression.md
Normal file
6
.changes/fix-usage-without-compression.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"tauri": patch:bug
|
||||
"tauri-codegen": patch:bug
|
||||
---
|
||||
|
||||
Fixes asset resolving when not using the `compression` feature.
|
||||
7
.changes/ios-frameworks.md
Normal file
7
.changes/ios-frameworks.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"tauri-utils": patch:feat
|
||||
"@tauri-apps/cli": patch:feat
|
||||
"tauri-cli": patch:feat
|
||||
---
|
||||
|
||||
Added `bundle > iOS > frameworks` configuration to define a list of frameworks that are linked to the Xcode project when it is generated.
|
||||
6
.changes/isolation-main-frame-origin.md
Normal file
6
.changes/isolation-main-frame-origin.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"tauri": "patch:sec"
|
||||
"tauri-utils": "patch:sec"
|
||||
---
|
||||
|
||||
Explicitly check that the main frame's origin is the sender of Isolation Payloads
|
||||
6
.changes/linux-option-gtk-app-id.md
Normal file
6
.changes/linux-option-gtk-app-id.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"tauri-utils": "patch:enhance"
|
||||
"tauri": "patch:enhance"
|
||||
---
|
||||
|
||||
Make the set of gtk application id optional, to allow more then one instance of the app running at the same time.
|
||||
5
.changes/plugin-builder-failable.md
Normal file
5
.changes/plugin-builder-failable.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"tauri": "patch:enhance"
|
||||
---
|
||||
|
||||
Add `tauri::plugin::Builder::try_build` to allow plugins to check if their `TauriPlugin` initialization is valid.
|
||||
@@ -1,13 +1,18 @@
|
||||
{
|
||||
"tag": "beta",
|
||||
"tag": "rc",
|
||||
"changes": [
|
||||
".changes/beta.md",
|
||||
".changes/fix-codegen-rerun-if-changed.md",
|
||||
".changes/fix-process-ipc-message-fn.md",
|
||||
".changes/fix-rewrite-schema.md",
|
||||
".changes/fix-tauri-build-unix.md",
|
||||
".changes/refactor-capabilities-schema.md",
|
||||
".changes/rerun-if-permission-created.md",
|
||||
".changes/update-plugin-template.md"
|
||||
".changes/asset-resolver-dev-fallback.md",
|
||||
".changes/change-pr-10435.md",
|
||||
".changes/cli-desktop-port-exposure.md",
|
||||
".changes/core-plugin-namespace.md",
|
||||
".changes/dev-url-localhost-mobile.md",
|
||||
".changes/fix-conf-parsing-error-filepath.md",
|
||||
".changes/fix-usage-without-compression.md",
|
||||
".changes/ios-frameworks.md",
|
||||
".changes/isolation-main-frame-origin.md",
|
||||
".changes/linux-option-gtk-app-id.md",
|
||||
".changes/plugin-builder-failable.md",
|
||||
".changes/rc-migration.md",
|
||||
".changes/remove-unsecure-configs.md"
|
||||
]
|
||||
}
|
||||
|
||||
6
.changes/rc-migration.md
Normal file
6
.changes/rc-migration.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"tauri-cli": patch:feat
|
||||
"@tauri-apps/cli": patch:feat
|
||||
---
|
||||
|
||||
Added migration from `2.0.0-beta` to `2.0.0-rc`.
|
||||
@@ -1,8 +0,0 @@
|
||||
---
|
||||
"@tauri-apps/cli": patch:enhance
|
||||
"tauri-cli": patch:enhance
|
||||
"tauri-build": patch:enhance
|
||||
"tauri-utils": patch:enhance
|
||||
---
|
||||
|
||||
Moved the capability JSON schema to the `src-tauri/gen` folder so it's easier to track changes on the `capabilities` folder.
|
||||
8
.changes/remove-unsecure-configs.md
Normal file
8
.changes/remove-unsecure-configs.md
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
"tauri-cli": patch:sec
|
||||
"@tauri-apps/cli": patch:sec
|
||||
"tauri": patch:sec
|
||||
---
|
||||
|
||||
Re-enable TLS checks that were previously disabled to support an insecure HTTPS custom protocol on Android which is no longer used.
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
"tauri-plugin": patch:bug
|
||||
"tauri-utils": patch:bug
|
||||
---
|
||||
|
||||
Rerun build script when a new permission is added.
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
"@tauri-apps/cli": patch:enhance
|
||||
"tauri-cli": patch:enhance
|
||||
---
|
||||
|
||||
Update app and plugin templates following generated files change from tauri-build and tauri-plugin.
|
||||
15
.github/CONTRIBUTING.md
vendored
15
.github/CONTRIBUTING.md
vendored
@@ -42,7 +42,7 @@ Hi! We, the maintainers, are really excited that you are interested in contribut
|
||||
|
||||
## Development Guide
|
||||
|
||||
**NOTE: Tauri is undergoing rapid development right now, and the docs match the latest published version of Tauri. They are horribly out of date when compared with the code in the dev branch. This contributor guide is up-to-date, but it doesn't cover all of Tauri's functions in depth. If you have any questions, don't hesitate to ask in our Discord server.**
|
||||
**NOTE: If you have any question don't hesitate to ask in our Discord server. We try to keep this guide to up guide, but if something doesn't work let us know.**
|
||||
|
||||
### General Setup
|
||||
|
||||
@@ -52,14 +52,9 @@ To set up your machine for development, follow the [Tauri setup guide](https://t
|
||||
|
||||
Some Tauri packages will be automatically built when running one of the examples. Others, however, will need to be built beforehand. To build these automatically, run the `.scripts/setup.sh` (Linux and macOS) or `.scripts/setup.ps1` (Windows) script. This will install the Rust and Node.js CLI and build the JS API. After that, you should be able to run all the examples. Note that the setup script should be executed from the root folder of the repository in order to run correctly.
|
||||
|
||||
### Packages Overview
|
||||
### Overview
|
||||
|
||||
- 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.
|
||||
- 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.
|
||||
See [Architecture](../ARCHITECTURE.md#major-components) for an overview of the packages in this repository.
|
||||
|
||||
### Developing Tauri Bundler and Rust CLI
|
||||
|
||||
@@ -71,7 +66,7 @@ The code for the bundler is located in `[Tauri repo root]/tooling/bundler`, and
|
||||
|
||||
### 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" }`, 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 the Rust crates, including the Core, Macros, Utils, WRY runtime, and a few more are located in `[Tauri repo root]/core/tauri-(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 `cargo run --example helloworld` after making changes to test them out.
|
||||
|
||||
#### Building the documentation locally
|
||||
|
||||
@@ -87,4 +82,4 @@ The JS API provides bindings between the developer's JS in the Webview and the b
|
||||
|
||||
## Financial Contribution
|
||||
|
||||
Tauri is an MIT-licensed open source project. Its ongoing development can be supported via [GitHub Sponsors](https://github.com/sponsors/nothingismagick) or [Open Collective](https://opencollective.com/tauri). We prefer GitHub Sponsors as donations made are doubled through the matching fund program.
|
||||
Tauri is an MIT-licensed open source project. Its ongoing development can be supported via [GitHub Sponsors](https://github.com/sponsors/tauri-apps) or [Open Collective](https://opencollective.com/tauri). We prefer GitHub Sponsors as donations made are doubled through the matching fund program.
|
||||
|
||||
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@@ -1,4 +1,4 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -1,4 +1,4 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/config.yml
vendored
2
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,4 +1,4 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
2
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@@ -1,4 +1,4 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -14,7 +14,7 @@ Before submitting a PR, please read https://github.com/tauri-apps/tauri/blob/dev
|
||||
- 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
|
||||
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.
|
||||
|
||||
2
.github/workflows/audit.yml
vendored
2
.github/workflows/audit.yml
vendored
@@ -1,4 +1,4 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
2
.github/workflows/bench.yml
vendored
2
.github/workflows/bench.yml
vendored
@@ -1,4 +1,4 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
2
.github/workflows/check-change-tags.yml
vendored
2
.github/workflows/check-change-tags.yml
vendored
@@ -1,4 +1,4 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
9
.github/workflows/check-generated-files.yml
vendored
9
.github/workflows/check-generated-files.yml
vendored
@@ -1,4 +1,4 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
@@ -37,6 +37,8 @@ jobs:
|
||||
- 'core/tauri-utils/src/config.rs'
|
||||
- 'tooling/cli/schema.json'
|
||||
- 'core/tauri-config-schema/schema.json'
|
||||
- 'core/tauri-acl-schema/*.json'
|
||||
|
||||
|
||||
api:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -70,8 +72,11 @@ jobs:
|
||||
with:
|
||||
workspaces: core -> ../target
|
||||
|
||||
- name: generate schema.json
|
||||
- name: generate config schema
|
||||
run: cargo build --manifest-path ./core/tauri-config-schema/Cargo.toml
|
||||
|
||||
- name: generate ACL schema
|
||||
run: cargo build --manifest-path ./core/tauri-acl-schema/Cargo.toml
|
||||
|
||||
- name: check schema
|
||||
run: ./.scripts/ci/has-diff.sh
|
||||
|
||||
2
.github/workflows/check-license-header.yml
vendored
2
.github/workflows/check-license-header.yml
vendored
@@ -1,4 +1,4 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
30
.github/workflows/covector-comment-on-fork.yml
vendored
Normal file
30
.github/workflows/covector-comment-on-fork.yml
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: covector comment
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: [covector status] # the `name` of the workflow run on `pull_request` running `status` with `comment: true`
|
||||
types:
|
||||
- completed
|
||||
|
||||
# note all other permissions are set to none if not specified
|
||||
# and these set the permissions for `secrets.GITHUB_TOKEN`
|
||||
permissions:
|
||||
# to read the action artifacts on `covector status` workflows
|
||||
actions: read
|
||||
# to write the comment
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
comment:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event.workflow_run.conclusion == 'success' &&
|
||||
(github.event.workflow_run.head_repository.full_name != github.repository || github.actor == 'dependabot[bot]')
|
||||
steps:
|
||||
- name: covector status
|
||||
uses: jbolda/covector/packages/action@covector-v0
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
command: "status"
|
||||
4
.github/workflows/covector-status.yml
vendored
4
.github/workflows/covector-status.yml
vendored
@@ -1,4 +1,4 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
@@ -18,3 +18,5 @@ jobs:
|
||||
id: covector
|
||||
with:
|
||||
command: 'status'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
comment: true
|
||||
|
||||
231
.github/workflows/covector-version-or-publish-v1.yml
vendored
Normal file
231
.github/workflows/covector-version-or-publish-v1.yml
vendored
Normal file
@@ -0,0 +1,231 @@
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: covector version or publish
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 1.x
|
||||
|
||||
jobs:
|
||||
msrv-list:
|
||||
runs-on: ${{ matrix.platform.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform:
|
||||
- {
|
||||
target: x86_64-pc-windows-msvc,
|
||||
os: windows-latest,
|
||||
toolchain: '1.61.0'
|
||||
}
|
||||
- {
|
||||
target: x86_64-unknown-linux-gnu,
|
||||
os: ubuntu-latest,
|
||||
toolchain: '1.60.0'
|
||||
}
|
||||
- {
|
||||
target: x86_64-apple-darwin,
|
||||
os: macos-latest,
|
||||
toolchain: '1.60.0'
|
||||
}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: install rust ${{ matrix.platform.toolchain }}
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ matrix.platform.toolchain }}
|
||||
target: ${{ matrix.platform.target }}
|
||||
override: true
|
||||
default: true
|
||||
|
||||
- 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
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
|
||||
- name: delete lockfile
|
||||
run: rm Cargo.lock
|
||||
|
||||
- name: Downgrade crates with MSRV conflict
|
||||
# The --precise flag can only be used once per invocation.
|
||||
run: |
|
||||
cargo update -p system-deps:6.2.0 --precise 6.1.1
|
||||
cargo update -p toml:0.7.8 --precise 0.7.3
|
||||
cargo update -p toml_edit:0.19.15 --precise 0.19.8
|
||||
cargo update -p embed-resource --precise 2.3.0
|
||||
cargo update -p toml_datetime --precise 0.6.1
|
||||
cargo update -p serde_spanned --precise 0.6.1
|
||||
cargo update -p winnow --precise 0.4.1
|
||||
cargo update -p plist --precise 1.5.1
|
||||
cargo update -p time --precise 0.3.15
|
||||
cargo update -p ignore --precise 0.4.18
|
||||
cargo update -p raw-window-handle --precise 0.5.0
|
||||
cargo update -p cargo_toml:0.15.3 --precise 0.15.2
|
||||
cargo update -p zbus --precise 3.13.0
|
||||
cargo update -p zbus_names --precise 2.5.0
|
||||
cargo update -p colored --precise 2.0.2
|
||||
cargo update -p arboard --precise 3.2.1
|
||||
cargo update -p tempfile --precise 3.6.0
|
||||
cargo update -p serde_with:3.6.1 --precise 3.0.0
|
||||
cargo update -p tokio --precise 1.29.0
|
||||
cargo update -p flate2 --precise 1.0.26
|
||||
cargo update -p h2 --precise 0.3.20
|
||||
cargo update -p reqwest --precise 0.11.18
|
||||
cargo update -p bstr --precise 1.6.2
|
||||
cargo update -p cfg-expr:0.15.7 --precise 0.15.4
|
||||
cargo update -p memchr --precise 2.6.2
|
||||
cargo update -p async-executor --precise 1.5.1
|
||||
cargo update -p proptest --precise 1.2.0
|
||||
cargo update -p regex --precise 1.9.6
|
||||
cargo update -p bstr --precise 1.6.2
|
||||
cargo update -p backtrace --precise 0.3.68
|
||||
cargo update -p blocking --precise 1.4.1
|
||||
cargo update -p ignore --precise 0.4.18
|
||||
cargo update -p regex --precise 1.9.6
|
||||
cargo update -p globset --precise 0.4.13
|
||||
cargo update -p crossbeam-channel --precise 0.5.8
|
||||
cargo update -p crossbeam-utils --precise 0.8.16
|
||||
cargo update -p image --precise 0.24.4
|
||||
cargo update -p async-process --precise 1.7.0
|
||||
cargo update -p is-terminal --precise 0.4.7
|
||||
cargo update -p tar --precise 0.4.39
|
||||
cargo update -p serde_json --precise 1.0.97
|
||||
cargo update -p petgraph --precise 0.6.3
|
||||
cargo update -p os_str_bytes --precise 6.5.1
|
||||
cargo update -p thread_local --precise 1.1.7
|
||||
|
||||
- name: test build
|
||||
run: cargo check --target ${{ matrix.platform.target }} --features tracing,compression,wry,linux-protocol-headers,isolation,custom-protocol,api-all,cli,updater,system-tray,windows7-compat,http-multipart,test
|
||||
|
||||
run-integration-tests:
|
||||
runs-on: ${{ matrix.platform }}
|
||||
needs: msrv-list
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [ubuntu-latest, macos-latest, windows-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- 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 libfuse2
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: |
|
||||
core -> ../target
|
||||
tooling/cli
|
||||
|
||||
- name: build CLI
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: build
|
||||
args: --manifest-path ./tooling/cli/Cargo.toml
|
||||
|
||||
- name: run integration tests
|
||||
run: cargo test --test '*' -- --ignored
|
||||
|
||||
- name: run CLI tests
|
||||
timeout-minutes: 30
|
||||
run: |
|
||||
cd ./tooling/cli/node
|
||||
yarn
|
||||
yarn build
|
||||
yarn test
|
||||
|
||||
version-or-publish:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 65
|
||||
outputs:
|
||||
change: ${{ steps.covector.outputs.change }}
|
||||
commandRan: ${{ steps.covector.outputs.commandRan }}
|
||||
successfulPublish: ${{ steps.covector.outputs.successfulPublish }}
|
||||
needs:
|
||||
- run-integration-tests
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 14
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
cache: yarn
|
||||
cache-dependency-path: tooling/*/yarn.lock
|
||||
|
||||
- name: cargo login
|
||||
run: cargo login ${{ secrets.ORG_CRATES_IO_TOKEN }}
|
||||
- name: git config
|
||||
run: |
|
||||
git config --global user.name "${{ github.event.pusher.name }}"
|
||||
git config --global user.email "${{ github.event.pusher.email }}"
|
||||
|
||||
- name: covector version or publish (publish when no change files present)
|
||||
uses: jbolda/covector/packages/action@covector-v0
|
||||
id: covector
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.ORG_NPM_TOKEN }}
|
||||
CARGO_AUDIT_OPTIONS: ${{ secrets.CARGO_AUDIT_OPTIONS }}
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
command: 'version-or-publish'
|
||||
createRelease: true
|
||||
|
||||
- name: Create Pull Request With Versions Bumped
|
||||
if: steps.covector.outputs.commandRan == 'version'
|
||||
uses: tauri-apps/create-pull-request@v3
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
branch: release/version-updates-v1
|
||||
title: Apply Version Updates From Current Changes (v1)
|
||||
commit-message: 'apply version updates'
|
||||
labels: 'version updates'
|
||||
body: ${{ steps.covector.outputs.change }}
|
||||
|
||||
- name: Trigger doc update
|
||||
if: |
|
||||
steps.covector.outputs.successfulPublish == 'true' &&
|
||||
steps.covector.outputs.packagesPublished != ''
|
||||
uses: peter-evans/repository-dispatch@v1
|
||||
with:
|
||||
token: ${{ secrets.ORG_TAURI_BOT_PAT }}
|
||||
repository: tauri-apps/tauri-docs
|
||||
event-type: update-docs
|
||||
|
||||
- name: Trigger `@tauri-apps/cli` publishing workflow
|
||||
if: |
|
||||
steps.covector.outputs.successfulPublish == 'true' &&
|
||||
contains(steps.covector.outputs.packagesPublished, '@tauri-apps/cli')
|
||||
uses: peter-evans/repository-dispatch@v1
|
||||
with:
|
||||
token: ${{ secrets.ORG_TAURI_BOT_PAT }}
|
||||
event-type: publish-js-cli
|
||||
client-payload: >-
|
||||
{"releaseId": "${{ steps.covector.outputs['-tauri-apps-cli-releaseId'] }}" }
|
||||
|
||||
- name: Trigger `tauri-cli` publishing workflow
|
||||
if: |
|
||||
steps.covector.outputs.successfulPublish == 'true' &&
|
||||
contains(steps.covector.outputs.packagesPublished, 'tauri-cli')
|
||||
uses: peter-evans/repository-dispatch@v1
|
||||
with:
|
||||
token: ${{ secrets.ORG_TAURI_BOT_PAT }}
|
||||
event-type: publish-clirs
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
@@ -87,9 +87,10 @@ jobs:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.ORG_NPM_TOKEN }}
|
||||
CARGO_AUDIT_OPTIONS: ${{ secrets.CARGO_AUDIT_OPTIONS }}
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
command: 'version-or-publish'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
createRelease: true
|
||||
recognizeContributors: true
|
||||
|
||||
- name: Create Pull Request With Versions Bumped
|
||||
if: steps.covector.outputs.commandRan == 'version'
|
||||
@@ -116,16 +117,14 @@ jobs:
|
||||
if: |
|
||||
steps.covector.outputs.successfulPublish == 'true' &&
|
||||
contains(steps.covector.outputs.packagesPublished, '@tauri-apps/cli')
|
||||
uses: peter-evans/repository-dispatch@v1
|
||||
with:
|
||||
event-type: publish-js-cli
|
||||
client-payload: >-
|
||||
{"releaseId": "${{ steps.covector.outputs['-tauri-apps-cli-releaseId'] }}" }
|
||||
run: gh workflow run 31554138 -r dev -f releaseId=${{ steps.covector.outputs['-tauri-apps-cli-releaseId'] }}
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.ORG_TAURI_BOT_PAT }}
|
||||
|
||||
- name: Trigger `tauri-cli` publishing workflow
|
||||
if: |
|
||||
steps.covector.outputs.successfulPublish == 'true' &&
|
||||
contains(steps.covector.outputs.packagesPublished, 'tauri-cli')
|
||||
uses: peter-evans/repository-dispatch@v1
|
||||
with:
|
||||
event-type: publish-clirs
|
||||
run: gh workflow run 31554139 -r dev
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.ORG_TAURI_BOT_PAT }}
|
||||
|
||||
2
.github/workflows/docker.yml
vendored
2
.github/workflows/docker.yml
vendored
@@ -1,4 +1,4 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
2
.github/workflows/lint-cli.yml
vendored
2
.github/workflows/lint-cli.yml
vendored
@@ -1,4 +1,4 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
2
.github/workflows/lint-core.yml
vendored
2
.github/workflows/lint-core.yml
vendored
@@ -1,4 +1,4 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
2
.github/workflows/lint-js.yml
vendored
2
.github/workflows/lint-js.yml
vendored
@@ -1,4 +1,4 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
16
.github/workflows/publish-cli-js.yml
vendored
16
.github/workflows/publish-cli-js.yml
vendored
@@ -1,4 +1,4 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
target: x86_64-apple-darwin
|
||||
architecture: x64
|
||||
build: |
|
||||
yarn build:release
|
||||
yarn build:release --target=x86_64-apple-darwin
|
||||
strip -x *.node
|
||||
- host: windows-latest
|
||||
build: yarn build:release
|
||||
@@ -195,13 +195,13 @@ jobs:
|
||||
matrix:
|
||||
settings:
|
||||
- host: macos-latest
|
||||
target: 'x86_64-apple-darwin'
|
||||
target: aarch64-apple-darwin
|
||||
- host: windows-latest
|
||||
target: x86_64-pc-windows-msvc
|
||||
node:
|
||||
- '14'
|
||||
- '16'
|
||||
- '18'
|
||||
- '20'
|
||||
runs-on: ${{ matrix.settings.host }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -232,9 +232,9 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node:
|
||||
- '14'
|
||||
- '16'
|
||||
- '18'
|
||||
- '20'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -269,9 +269,9 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node:
|
||||
- '14'
|
||||
- '16'
|
||||
- '18'
|
||||
- '20'
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine
|
||||
@@ -312,9 +312,9 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node:
|
||||
- '14'
|
||||
- '16'
|
||||
- '18'
|
||||
- '20'
|
||||
image:
|
||||
- ghcr.io/napi-rs/napi-rs/nodejs:aarch64-16
|
||||
- ghcr.io/napi-rs/napi-rs/nodejs:armhf-16
|
||||
@@ -372,7 +372,7 @@ jobs:
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
node-version: 20
|
||||
check-latest: true
|
||||
cache: yarn
|
||||
cache-dependency-path: 'tooling/cli/node/yarn.lock'
|
||||
|
||||
2
.github/workflows/publish-cli-rs.yml
vendored
2
.github/workflows/publish-cli-rs.yml
vendored
@@ -1,4 +1,4 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
45
.github/workflows/supply-chain.yml
vendored
Normal file
45
.github/workflows/supply-chain.yml
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: supply chain health status
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
- 1.x
|
||||
paths:
|
||||
- '.github/workflows/supply-chain.yml'
|
||||
- '**/Cargo.lock'
|
||||
- '**/Cargo.toml'
|
||||
jobs:
|
||||
cargo-vet:
|
||||
name: check rust dependencies with cargo vet
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CARGO_VET_VERSION: 0.9.1
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: Install Rust
|
||||
run: rustup update stable && rustup default stable
|
||||
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ runner.tool_cache }}/cargo-vet
|
||||
key: cargo-vet-bin-${{ env.CARGO_VET_VERSION }}
|
||||
|
||||
- name: Add the tool cache directory to the search path
|
||||
run: echo "${{ runner.tool_cache }}/cargo-vet/bin" >> $GITHUB_PATH
|
||||
|
||||
- name: Ensure that the tool cache is populated with the cargo-vet binary
|
||||
run: cargo install --root ${{ runner.tool_cache }}/cargo-vet --version ${{ env.CARGO_VET_VERSION }} cargo-vet
|
||||
|
||||
# Enable this again to break the workflow once we have a reasonable amount of suggestions to get to a clean base line
|
||||
# - name: Invoke cargo-vet
|
||||
# run: cargo vet --locked
|
||||
|
||||
- name: Provide audit suggestions
|
||||
run: cargo vet suggest
|
||||
14
.github/workflows/test-android.yml
vendored
14
.github/workflows/test-android.yml
vendored
@@ -1,4 +1,4 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
@@ -85,6 +85,14 @@ jobs:
|
||||
- name: build CLI
|
||||
run: cargo build --manifest-path ./tooling/cli/Cargo.toml
|
||||
|
||||
- name: move CLI to cargo bin dir
|
||||
if: matrix.platform != 'windows-latest'
|
||||
run: mv ./tooling/cli/target/debug/cargo-tauri $HOME/.cargo/bin
|
||||
|
||||
- name: move CLI to cargo bin dir
|
||||
if: matrix.platform == 'windows-latest'
|
||||
run: mv ./tooling/cli/target/debug/cargo-tauri.exe $HOME/.cargo/bin
|
||||
|
||||
- name: build Tauri API
|
||||
working-directory: ./tooling/api
|
||||
run: yarn && yarn build
|
||||
@@ -95,12 +103,12 @@ jobs:
|
||||
|
||||
- name: init Android Studio project
|
||||
working-directory: ./examples/api
|
||||
run: ../../tooling/cli/target/debug/cargo-tauri android init
|
||||
run: 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
|
||||
run: cargo tauri android build
|
||||
env:
|
||||
NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
|
||||
|
||||
2
.github/workflows/test-cli-js.yml
vendored
2
.github/workflows/test-cli-js.yml
vendored
@@ -1,4 +1,4 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
2
.github/workflows/test-cli-rs.yml
vendored
2
.github/workflows/test-cli-rs.yml
vendored
@@ -1,4 +1,4 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
5
.github/workflows/test-core.yml
vendored
5
.github/workflows/test-core.yml
vendored
@@ -1,4 +1,4 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
@@ -93,8 +93,9 @@ jobs:
|
||||
|
||||
- name: test (using cross)
|
||||
if: ${{ matrix.platform.cross }}
|
||||
# update or remove the rev once we update the MSRV from 1.70.0
|
||||
run: |
|
||||
cargo install cross --git https://github.com/cross-rs/cross
|
||||
cargo install cross --git https://github.com/cross-rs/cross --rev 20c73df79c9aaf78a2ad2e9fe8ae981668a729dc --locked
|
||||
cross ${{ matrix.platform.command }} --target ${{ matrix.platform.target }} ${{ matrix.features.args }}
|
||||
|
||||
- name: test (using cargo)
|
||||
|
||||
2
.github/workflows/test-lint-bundler.yml
vendored
2
.github/workflows/test-lint-bundler.yml
vendored
@@ -1,4 +1,4 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
2
.github/workflows/udeps.yml
vendored
2
.github/workflows/udeps.yml
vendored
@@ -1,4 +1,4 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -73,7 +73,7 @@ TODO.md
|
||||
target
|
||||
|
||||
# lock for libs
|
||||
/Cargo.lock
|
||||
#/Cargo.lock Committed to prevent msrv checks from failing
|
||||
/tooling/bench/tests/Cargo.lock
|
||||
/yarn.lock
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
{
|
||||
"singleQuote": true,
|
||||
"semi": false,
|
||||
"trailingComma": "none"
|
||||
"trailingComma": "none",
|
||||
"overrides": [
|
||||
{ "files": [".changes/**.md"], "options": { "singleQuote": false } }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env pwsh
|
||||
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
@@ -69,7 +69,9 @@ function checkChangeFiles(changeFiles) {
|
||||
const [_bin, _script, ...files] = process.argv
|
||||
|
||||
if (files.length > 0) {
|
||||
checkChangeFiles(files.filter((f) => f.toLowerCase() !== 'readme.md'))
|
||||
checkChangeFiles(
|
||||
files.filter((f) => f.toLowerCase() !== '.changes/readme.md')
|
||||
)
|
||||
} else {
|
||||
const changeFiles = fs
|
||||
.readdirSync('.changes')
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
@@ -8,7 +8,7 @@ const fs = require('fs')
|
||||
const path = require('path')
|
||||
const readline = require('readline')
|
||||
|
||||
const header = `Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
const header = `Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
SPDX-License-Identifier: MIT`
|
||||
const bundlerLicense =
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
@@ -34,6 +34,7 @@ switch (bump) {
|
||||
index = 2
|
||||
break
|
||||
case 'prerelease':
|
||||
case 'prepatch':
|
||||
index = 3
|
||||
break
|
||||
default:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env pwsh
|
||||
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
: Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
: Copyright 2019-2024 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
|
||||
REM Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
REM SPDX-License-Identifier: Apache-2.0
|
||||
REM SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# The Tauri Architecture
|
||||
|
||||
https://tauri.app
|
||||
<https://tauri.app>
|
||||
|
||||
https://github.com/tauri-apps/tauri
|
||||
<https://github.com/tauri-apps/tauri>
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -113,9 +113,9 @@ Generally speaking, plugins are authored by third parties (even though there may
|
||||
|
||||
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
|
||||
- <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
|
||||
|
||||
|
||||
5082
Cargo.lock
generated
Normal file
5082
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -10,6 +10,7 @@ members = [
|
||||
"core/tauri-build",
|
||||
"core/tauri-codegen",
|
||||
"core/tauri-config-schema",
|
||||
"core/tauri-acl-schema",
|
||||
"core/tauri-plugin",
|
||||
|
||||
# integration tests
|
||||
@@ -43,3 +44,8 @@ codegen-units = 1
|
||||
lto = true
|
||||
incremental = false
|
||||
opt-level = "s"
|
||||
|
||||
# Temporary patch to schemars to preserve newlines in docstrings for our reference docs schemas
|
||||
# See https://github.com/GREsau/schemars/issues/120 for reference
|
||||
[patch.crates-io]
|
||||
schemars_derive = { git = 'https://github.com/tauri-apps/schemars.git', branch = 'feat/preserve-description-newlines' }
|
||||
|
||||
@@ -6,7 +6,7 @@ PackageSupplier: Organization: The Tauri Programme in the Commons Conservancy
|
||||
PackageHomePage: https://tauri.app
|
||||
PackageLicenseDeclared: Apache-2.0
|
||||
PackageLicenseDeclared: MIT
|
||||
PackageCopyrightText: 2019-2022, The Tauri Programme in the Commons Conservancy
|
||||
PackageCopyrightText: 2019-2024, The Tauri Programme in the Commons Conservancy
|
||||
PackageSummary: <text>Tauri is a rust project that enables developers to make secure
|
||||
and small desktop applications using a web frontend.
|
||||
</text>
|
||||
|
||||
@@ -35,7 +35,7 @@ The list of Tauri's features includes, but is not limited to:
|
||||
- Built-in self updater (desktop only)
|
||||
- System tray icons
|
||||
- Native notifications
|
||||
- Localhost free (:fire:)
|
||||
- Localhost free (🔥)
|
||||
- GitHub action for streamlined CI
|
||||
- VS Code extension
|
||||
|
||||
@@ -48,8 +48,8 @@ Tauri currently supports development and distribution on the following platforms
|
||||
| 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 |
|
||||
| iOS/iPadOS (beta) | 9 and above |
|
||||
| Android (beta) | 7 and above |
|
||||
|
||||
## Contributing
|
||||
|
||||
@@ -61,7 +61,7 @@ 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 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
|
||||
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>
|
||||
|
||||
## Partners
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you have found a potential security threat, vulnerability or exploit in Tauri
|
||||
or one of its upstream dependencies, please DON’T create a pull-request, DON’T
|
||||
file an issue on GitHub, DON’T mention it on Discord and DON’T create a forum thread.
|
||||
or one of its upstream dependencies, please DON'T create a pull-request, DON'T
|
||||
file an issue on GitHub, DON'T mention it on Discord and DON'T create a forum thread.
|
||||
|
||||
Please submit your report via the GitHub Private Vulnerability Disclosure functionality.
|
||||
|
||||
|
||||
12
core/tauri-acl-schema/Cargo.toml
Normal file
12
core/tauri-acl-schema/Cargo.toml
Normal file
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "tauri-acl-schema"
|
||||
version = "0.0.0"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[build-dependencies]
|
||||
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"
|
||||
url = { version = "2.3", features = ["serde"] }
|
||||
34
core/tauri-acl-schema/build.rs
Normal file
34
core/tauri-acl-schema/build.rs
Normal file
@@ -0,0 +1,34 @@
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use std::{error::Error, path::PathBuf};
|
||||
|
||||
use schemars::schema_for;
|
||||
use tauri_utils::{
|
||||
acl::capability::Capability,
|
||||
acl::{Permission, Scopes},
|
||||
write_if_changed,
|
||||
};
|
||||
|
||||
macro_rules! schema {
|
||||
($name:literal, $path:ty) => {
|
||||
(concat!($name, "-schema.json"), schema_for!($path))
|
||||
};
|
||||
}
|
||||
|
||||
pub fn main() -> Result<(), Box<dyn Error>> {
|
||||
let schemas = [
|
||||
schema!("capability", Capability),
|
||||
schema!("permission", Permission),
|
||||
schema!("scope", Scopes),
|
||||
];
|
||||
|
||||
let out = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR")?);
|
||||
for (filename, schema) in schemas {
|
||||
let schema = serde_json::to_string_pretty(&schema)?;
|
||||
write_if_changed(out.join(filename), schema)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
234
core/tauri-acl-schema/capability-schema.json
Normal file
234
core/tauri-acl-schema/capability-schema.json
Normal file
@@ -0,0 +1,234 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Capability",
|
||||
"description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\n It controls application windows fine grained access to the Tauri core, application, or plugin commands.\n If a window is not matching any capability then it has no access to the IPC layer at all.\n\n This can be done to create groups of windows, based on their required system access, which can reduce\n impact of frontend vulnerabilities in less privileged windows.\n Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`.\n A Window can have none, one, or multiple associated capabilities.\n\n ## Example\n\n ```json\n {\n \"identifier\": \"main-user-files-write\",\n \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\",\n \"windows\": [\n \"main\"\n ],\n \"permissions\": [\n \"core:default\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n },\n \"platforms\": [\"macOS\",\"windows\"]\n }\n ```",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"identifier",
|
||||
"permissions"
|
||||
],
|
||||
"properties": {
|
||||
"identifier": {
|
||||
"description": "Identifier of the capability.\n\n ## Example\n\n `main-user-files-write`",
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"description": "Description of what the capability is intended to allow on associated windows.\n\n It should contain a description of what the grouped permissions should allow.\n\n ## Example\n\n This capability allows the `main` window access to `filesystem` write related\n commands and `dialog` commands to enable programatic access to files selected by the user.",
|
||||
"default": "",
|
||||
"type": "string"
|
||||
},
|
||||
"remote": {
|
||||
"description": "Configure remote URLs that can use the capability permissions.\n\n This setting is optional and defaults to not being set, as our\n default use case is that the content is served from our local application.\n\n :::caution\n Make sure you understand the security implications of providing remote\n sources with local system access.\n :::\n\n ## Example\n\n ```json\n {\n \"urls\": [\"https://*.mydomain.dev\"]\n }\n ```",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/CapabilityRemote"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"local": {
|
||||
"description": "Whether this capability is enabled for local app URLs or not. Defaults to `true`.",
|
||||
"default": true,
|
||||
"type": "boolean"
|
||||
},
|
||||
"windows": {
|
||||
"description": "List of windows that are affected by this capability. Can be a glob pattern.\n\n On multiwebview windows, prefer [`Self::webviews`] for a fine grained access control.\n\n ## Example\n\n `[\"main\"]`",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"webviews": {
|
||||
"description": "List of webviews that are affected by this capability. Can be a glob pattern.\n\n This is only required when using on multiwebview contexts, by default\n all child webviews of a window that matches [`Self::windows`] are linked.\n\n ## Example\n\n `[\"sub-webview-one\", \"sub-webview-two\"]`",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"permissions": {
|
||||
"description": "List of permissions attached to this capability.\n\n Must include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`.\n For commands directly implemented in the application itself only `${permission-name}`\n is required.\n\n ## Example\n\n ```json\n [\n \"core:default\",\n \"shell:allow-open\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n }\n ```",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/PermissionEntry"
|
||||
},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"platforms": {
|
||||
"description": "Limit which target platforms this capability applies to.\n\n By default all platforms are targeted.\n\n ## Example\n\n `[\"macOS\",\"windows\"]`",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/definitions/Target"
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"CapabilityRemote": {
|
||||
"description": "Configuration for remote URLs that are associated with the capability.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"urls"
|
||||
],
|
||||
"properties": {
|
||||
"urls": {
|
||||
"description": "Remote domains this capability refers to using the [URLPattern standard](https://urlpattern.spec.whatwg.org/).\n\n ## Examples\n\n - \"https://*.mydomain.dev\": allows subdomains of mydomain.dev\n - \"https://mydomain.dev/api/*\": allows any subpath of mydomain.dev/api",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"PermissionEntry": {
|
||||
"description": "An entry for a permission value in a [`Capability`] can be either a raw permission [`Identifier`]\n or an object that references a permission and extends its scope.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Reference a permission or permission set by identifier.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Identifier"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Reference a permission or permission set by identifier and extends its scope.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"identifier"
|
||||
],
|
||||
"properties": {
|
||||
"identifier": {
|
||||
"description": "Identifier of the permission or permission set.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Identifier"
|
||||
}
|
||||
]
|
||||
},
|
||||
"allow": {
|
||||
"description": "Data that defines what is allowed by the scope.",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
},
|
||||
"deny": {
|
||||
"description": "Data that defines what is denied by the scope. This should be prioritized by validation logic.",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"Identifier": {
|
||||
"type": "string"
|
||||
},
|
||||
"Value": {
|
||||
"description": "All supported ACL values.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Represents a null JSON value.",
|
||||
"type": "null"
|
||||
},
|
||||
{
|
||||
"description": "Represents a [`bool`].",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"description": "Represents a valid ACL [`Number`].",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Number"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Represents a [`String`].",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Represents a list of other [`Value`]s.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Represents a map of [`String`] keys to [`Value`]s.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"Number": {
|
||||
"description": "A valid ACL number.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Represents an [`i64`].",
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
{
|
||||
"description": "Represents a [`f64`].",
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Target": {
|
||||
"description": "Platform target.",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "MacOS.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"macOS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Windows.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"windows"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Linux.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Android.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"android"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "iOS.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"iOS"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
205
core/tauri-acl-schema/permission-schema.json
Normal file
205
core/tauri-acl-schema/permission-schema.json
Normal file
@@ -0,0 +1,205 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Permission",
|
||||
"description": "Descriptions of explicit privileges of commands.\n\n It can enable commands to be accessible in the frontend of the application.\n\n If the scope is defined it can be used to fine grain control the access of individual or multiple commands.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"identifier"
|
||||
],
|
||||
"properties": {
|
||||
"version": {
|
||||
"description": "The version of the permission.",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"format": "uint64",
|
||||
"minimum": 1.0
|
||||
},
|
||||
"identifier": {
|
||||
"description": "A unique identifier for the permission.",
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"description": "Human-readable description of what the permission does.\n Tauri internal convention is to use <h4> headings in markdown content\n for Tauri documentation generation purposes.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"commands": {
|
||||
"description": "Allowed or denied commands when using this permission.",
|
||||
"default": {
|
||||
"allow": [],
|
||||
"deny": []
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Commands"
|
||||
}
|
||||
]
|
||||
},
|
||||
"scope": {
|
||||
"description": "Allowed or denied scoped when using this permission.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Scopes"
|
||||
}
|
||||
]
|
||||
},
|
||||
"platforms": {
|
||||
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/definitions/Target"
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"Commands": {
|
||||
"description": "Allowed and denied commands inside a permission.\n\n If two commands clash inside of `allow` and `deny`, it should be denied by default.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow": {
|
||||
"description": "Allowed command.",
|
||||
"default": [],
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"deny": {
|
||||
"description": "Denied command, which takes priority.",
|
||||
"default": [],
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Scopes": {
|
||||
"description": "An argument for fine grained behavior control of Tauri commands.\n\n It can be of any serde serializable type and is used to allow or prevent certain actions inside a Tauri command.\n The configured scope is passed to the command and will be enforced by the command implementation.\n\n ## Example\n\n ```json\n {\n \"allow\": [{ \"path\": \"$HOME/**\" }],\n \"deny\": [{ \"path\": \"$HOME/secret.txt\" }]\n }\n ```",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow": {
|
||||
"description": "Data that defines what is allowed by the scope.",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
},
|
||||
"deny": {
|
||||
"description": "Data that defines what is denied by the scope. This should be prioritized by validation logic.",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Value": {
|
||||
"description": "All supported ACL values.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Represents a null JSON value.",
|
||||
"type": "null"
|
||||
},
|
||||
{
|
||||
"description": "Represents a [`bool`].",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"description": "Represents a valid ACL [`Number`].",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Number"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Represents a [`String`].",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Represents a list of other [`Value`]s.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Represents a map of [`String`] keys to [`Value`]s.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"Number": {
|
||||
"description": "A valid ACL number.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Represents an [`i64`].",
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
{
|
||||
"description": "Represents a [`f64`].",
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Target": {
|
||||
"description": "Platform target.",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "MacOS.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"macOS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Windows.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"windows"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Linux.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Android.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"android"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "iOS.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"iOS"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
84
core/tauri-acl-schema/scope-schema.json
Normal file
84
core/tauri-acl-schema/scope-schema.json
Normal file
@@ -0,0 +1,84 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Scopes",
|
||||
"description": "An argument for fine grained behavior control of Tauri commands.\n\n It can be of any serde serializable type and is used to allow or prevent certain actions inside a Tauri command.\n The configured scope is passed to the command and will be enforced by the command implementation.\n\n ## Example\n\n ```json\n {\n \"allow\": [{ \"path\": \"$HOME/**\" }],\n \"deny\": [{ \"path\": \"$HOME/secret.txt\" }]\n }\n ```",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow": {
|
||||
"description": "Data that defines what is allowed by the scope.",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
},
|
||||
"deny": {
|
||||
"description": "Data that defines what is denied by the scope. This should be prioritized by validation logic.",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"Value": {
|
||||
"description": "All supported ACL values.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Represents a null JSON value.",
|
||||
"type": "null"
|
||||
},
|
||||
{
|
||||
"description": "Represents a [`bool`].",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"description": "Represents a valid ACL [`Number`].",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Number"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Represents a [`String`].",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Represents a list of other [`Value`]s.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Represents a map of [`String`] keys to [`Value`]s.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"Number": {
|
||||
"description": "A valid ACL number.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Represents an [`i64`].",
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
{
|
||||
"description": "Represents a [`f64`].",
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
14
core/tauri-acl-schema/src/main.rs
Normal file
14
core/tauri-acl-schema/src/main.rs
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// 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,204 @@
|
||||
# Changelog
|
||||
|
||||
## \[2.0.0-rc.0]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-codegen@2.0.0-rc.0`
|
||||
- Upgraded to `tauri-utils@2.0.0-rc.0`
|
||||
|
||||
## \[2.0.0-beta.19]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`69dcfdfe0`](https://www.github.com/tauri-apps/tauri/commit/69dcfdfe0f3b0570fcf5997267a7200087d5341b) ([#10267](https://www.github.com/tauri-apps/tauri/pull/10267) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fix build script rerun-if-changed instruction if Info.plist do not exist next to tauri.conf.json.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-codegen@2.0.0-beta.19`
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.19`
|
||||
|
||||
## \[2.0.0-beta.18]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`35110dba2`](https://www.github.com/tauri-apps/tauri/commit/35110dba21d7db0f155c45da58b41c9ca4d5853c) ([#10106](https://www.github.com/tauri-apps/tauri/pull/10106)) Fix delete app data button gone on higher scaling (>= 1.5)
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.18`
|
||||
- Upgraded to `tauri-codegen@2.0.0-beta.18`
|
||||
- [`f955f7b49`](https://www.github.com/tauri-apps/tauri/commit/f955f7b4903bcea376c0a8b430736f66c8cebf56) ([#9929](https://www.github.com/tauri-apps/tauri/pull/9929)) Switch from `dirs_next` to `dirs` as `dirs_next` is now unmaintained while `dirs` is
|
||||
|
||||
## \[2.0.0-beta.17]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`adac2185a`](https://www.github.com/tauri-apps/tauri/commit/adac2185a3e2e65a89a3c392363c50ddde4acff2)([#9898](https://www.github.com/tauri-apps/tauri/pull/9898)) Check for Android version code before building the package in release mode.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`19b696b61`](https://www.github.com/tauri-apps/tauri/commit/19b696b61c95ced0f07dd7471565ad329a0badcf)([#9710](https://www.github.com/tauri-apps/tauri/pull/9710)) Avoid copying resources if the target path is the same as source.
|
||||
|
||||
### What's Changed
|
||||
|
||||
- [`9ac930380`](https://www.github.com/tauri-apps/tauri/commit/9ac930380a5df3fe700e68e75df8684d261ca292)([#9850](https://www.github.com/tauri-apps/tauri/pull/9850)) Emit `cargo:rustc-check-cfg` instruction so Cargo validates custom cfg attributes on Rust 1.80 (or nightly-2024-05-05).
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.17`
|
||||
- Upgraded to `tauri-codegen@2.0.0-beta.17`
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- [`1df5cdeb0`](https://www.github.com/tauri-apps/tauri/commit/1df5cdeb06f5464e0eec4055e21b7b7bc8739eed)([#9858](https://www.github.com/tauri-apps/tauri/pull/9858)) Use `tauri.conf.json > identifier` to set the `PackageName` in Android and `BundleId` in iOS.
|
||||
- [`aaecb6a72`](https://www.github.com/tauri-apps/tauri/commit/aaecb6a72e5d1462967cc910c2628999997742d0)([#9890](https://www.github.com/tauri-apps/tauri/pull/9890)) Renamed `dev` function to `is_dev`
|
||||
|
||||
## \[2.0.0-beta.16]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.16`
|
||||
- Upgraded to `tauri-codegen@2.0.0-beta.16`
|
||||
|
||||
## \[2.0.0-beta.15]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.15`
|
||||
- Upgraded to `tauri-codegen@2.0.0-beta.15`
|
||||
|
||||
## \[2.0.0-beta.14]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.14`
|
||||
- Upgraded to `tauri-codegen@2.0.0-beta.14`
|
||||
|
||||
## \[2.0.0-beta.13]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`88c0ad9cf`](https://www.github.com/tauri-apps/tauri/commit/88c0ad9cf5d2f9ed65285540c26b54fb18b10137)([#9471](https://www.github.com/tauri-apps/tauri/pull/9471)) Fix tauri always rebuilding even if source code didn't change.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.13`
|
||||
- Upgraded to `tauri-codegen@2.0.0-beta.13`
|
||||
|
||||
## \[2.0.0-beta.12]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.12`
|
||||
- Upgraded to `tauri-codegen@2.0.0-beta.12`
|
||||
|
||||
## \[2.0.0-beta.11]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.11`
|
||||
- Upgraded to `tauri-codegen@2.0.0-beta.11`
|
||||
|
||||
## \[2.0.0-beta.10]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`e227fe02f`](https://www.github.com/tauri-apps/tauri/commit/e227fe02f986e145c0731a64693e1c830a9eb5b0)([#9156](https://www.github.com/tauri-apps/tauri/pull/9156)) Allow plugins to define (at compile time) JavaScript that are initialized when `withGlobalTauri` is true.
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`7213b9e47`](https://www.github.com/tauri-apps/tauri/commit/7213b9e47242bef814aa7257e0bf84631bf5fe7e)([#9124](https://www.github.com/tauri-apps/tauri/pull/9124)) Fallback to an empty permission set if the plugin did not define its `default` permissions.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.10`
|
||||
- Upgraded to `tauri-codegen@2.0.0-beta.10`
|
||||
|
||||
## \[2.0.0-beta.9]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-codegen@2.0.0-beta.9`
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.9`
|
||||
|
||||
## \[2.0.0-beta.8]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.8`
|
||||
- Upgraded to `tauri-codegen@2.0.0-beta.8`
|
||||
|
||||
## \[2.0.0-beta.7]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`bb23511ea`](https://www.github.com/tauri-apps/tauri/commit/bb23511ea80bcaffbdebf057301e463fff268c90)([#9079](https://www.github.com/tauri-apps/tauri/pull/9079)) Fixed generation of capability schema for permissions field which previously disallowed mixed (strings and objects) permission definition.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.7`
|
||||
- Upgraded to `tauri-codegen@2.0.0-beta.7`
|
||||
|
||||
## \[2.0.0-beta.6]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.6`
|
||||
- Upgraded to `tauri-codegen@2.0.0-beta.6`
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- [`3657ad82`](https://www.github.com/tauri-apps/tauri/commit/3657ad82f88ce528551d032d521c52eed3f396b4)([#9008](https://www.github.com/tauri-apps/tauri/pull/9008)) Allow defining permissions for the application commands via `tauri_build::Attributes::app_manifest`.
|
||||
|
||||
## \[2.0.0-beta.5]
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- [`b9e6a018`](https://www.github.com/tauri-apps/tauri/commit/b9e6a01879d9233040f3d3fab11c59e70563da7e)([#8937](https://www.github.com/tauri-apps/tauri/pull/8937)) The `custom-protocol` Cargo feature is no longer required on your application and is now ignored. To check if running on production, use `#[cfg(not(dev))]` instead of `#[cfg(feature = "custom-protocol")]`.
|
||||
- [`b9e6a018`](https://www.github.com/tauri-apps/tauri/commit/b9e6a01879d9233040f3d3fab11c59e70563da7e)([#8937](https://www.github.com/tauri-apps/tauri/pull/8937)) Removed `tauri_build::CodegenContext::dev()` and added `tauri_build::dev()`.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.5`
|
||||
- Upgraded to `tauri-codegen@2.0.0-beta.5`
|
||||
|
||||
## \[2.0.0-beta.4]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`b5eb6472`](https://www.github.com/tauri-apps/tauri/commit/b5eb64728aeb410d3f3068608a94762655c4690f)([#8940](https://www.github.com/tauri-apps/tauri/pull/8940)) Enable Hight DPI awareness for NSIS installer so it is not blurry on some systems.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.4`
|
||||
- Upgraded to `tauri-codegen@2.0.0-beta.4`
|
||||
|
||||
## \[2.0.0-beta.3]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.3`
|
||||
- Upgraded to `tauri-codegen@2.0.0-beta.3`
|
||||
|
||||
## \[2.0.0-beta.2]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`83a68deb`](https://www.github.com/tauri-apps/tauri/commit/83a68deb5676d39cd4728d2e140f6b46d5f787ed)([#8797](https://www.github.com/tauri-apps/tauri/pull/8797)) Added a new configuration option `tauri.conf.json > app > security > capabilities` to reference existing capabilities and inline new ones. If it is empty, all capabilities are still included preserving the current behavior.
|
||||
- [`edb11c13`](https://www.github.com/tauri-apps/tauri/commit/edb11c138def2e317099db432479e3ca5dbf803f)([#8781](https://www.github.com/tauri-apps/tauri/pull/8781)) Added `Attributes::plugin()` to register a plugin that is inlined in the application crate.
|
||||
- [`8d16a80d`](https://www.github.com/tauri-apps/tauri/commit/8d16a80d2fb2468667e7987d0cc99dbc7e3b9d0a)([#8802](https://www.github.com/tauri-apps/tauri/pull/8802)) Added `CodegenContext::capability` to include a capability file dynamically.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`0e8e9cd0`](https://www.github.com/tauri-apps/tauri/commit/0e8e9cd064627e734adf8f62e571dc5f4e8f4d9f)([#8906](https://www.github.com/tauri-apps/tauri/pull/8906)) Fixes the capability schema not resolving inner definitions.
|
||||
- [`19fb5f0b`](https://www.github.com/tauri-apps/tauri/commit/19fb5f0b20479885bf8bc4fdd8c431052420191d)([#8782](https://www.github.com/tauri-apps/tauri/pull/8782)) Fix generating invalid schema files.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.2`
|
||||
- Upgraded to `tauri-codegen@2.0.0-beta.2`
|
||||
|
||||
## \[2.0.0-beta.1]
|
||||
|
||||
### Enhancements
|
||||
@@ -174,6 +373,13 @@
|
||||
- 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.1]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@1.5.2`
|
||||
- Upgraded to `tauri-codegen@1.4.2`
|
||||
|
||||
## \[1.5.0]
|
||||
|
||||
### What's Changed
|
||||
@@ -198,7 +404,7 @@
|
||||
|
||||
- [`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.
|
||||
- [`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]
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "tauri-build"
|
||||
version = "2.0.0-beta.1"
|
||||
version = "2.0.0-rc.0"
|
||||
description = "build time code to pair with https://crates.io/crates/tauri"
|
||||
exclude = [ "CHANGELOG.md", "/target" ]
|
||||
readme = "README.md"
|
||||
@@ -28,20 +28,20 @@ rustdoc-args = [ "--cfg", "docsrs" ]
|
||||
[dependencies]
|
||||
anyhow = "1"
|
||||
quote = { version = "1", optional = true }
|
||||
tauri-codegen = { version = "2.0.0-beta.1", path = "../tauri-codegen", optional = true }
|
||||
tauri-utils = { version = "2.0.0-beta.1", path = "../tauri-utils", features = [ "build", "resources" ] }
|
||||
tauri-codegen = { version = "2.0.0-rc.0", path = "../tauri-codegen", optional = true }
|
||||
tauri-utils = { version = "2.0.0-rc.0", path = "../tauri-utils", features = [ "build", "resources" ] }
|
||||
cargo_toml = "0.17"
|
||||
serde = "1"
|
||||
serde_json = "1"
|
||||
heck = "0.4"
|
||||
heck = "0.5"
|
||||
json-patch = "1.2"
|
||||
walkdir = "2"
|
||||
tauri-winres = "0.1"
|
||||
semver = "1"
|
||||
dirs-next = "2"
|
||||
dirs = "5"
|
||||
glob = "0.3"
|
||||
toml = "0.8"
|
||||
schemars = { version = "0.8", features = [ "preserve_order" ] }
|
||||
schemars = { version = "0.8.18", features = [ "preserve_order" ] }
|
||||
|
||||
[features]
|
||||
default = [ "config-json" ]
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use std::{
|
||||
collections::{BTreeMap, BTreeSet},
|
||||
collections::{BTreeMap, BTreeSet, HashMap},
|
||||
env::current_dir,
|
||||
fs::{copy, create_dir_all, read_to_string, write},
|
||||
path::PathBuf,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
@@ -17,7 +18,11 @@ use schemars::{
|
||||
schema_for,
|
||||
};
|
||||
use tauri_utils::{
|
||||
acl::{build::CapabilityFile, capability::Capability, plugin::Manifest},
|
||||
acl::{
|
||||
capability::{Capability, CapabilityFile},
|
||||
manifest::Manifest,
|
||||
APP_ACL_KEY,
|
||||
},
|
||||
platform::Target,
|
||||
};
|
||||
|
||||
@@ -25,43 +30,119 @@ const CAPABILITIES_SCHEMA_FILE_NAME: &str = "schema.json";
|
||||
/// Path of the folder where schemas are saved.
|
||||
const CAPABILITIES_SCHEMA_FOLDER_PATH: &str = "gen/schemas";
|
||||
const CAPABILITIES_FILE_NAME: &str = "capabilities.json";
|
||||
const PLUGIN_MANIFESTS_FILE_NAME: &str = "plugin-manifests.json";
|
||||
const ACL_MANIFESTS_FILE_NAME: &str = "acl-manifests.json";
|
||||
|
||||
fn capabilities_schema(plugin_manifests: &BTreeMap<String, Manifest>) -> RootSchema {
|
||||
/// Definition of a plugin that is part of the Tauri application instead of having its own crate.
|
||||
///
|
||||
/// By default it generates a plugin manifest that parses permissions from the `permissions/$plugin-name` directory.
|
||||
/// To change the glob pattern that is used to find permissions, use [`Self::permissions_path_pattern`].
|
||||
///
|
||||
/// To autogenerate permissions for each of the plugin commands, see [`Self::commands`].
|
||||
#[derive(Debug, Default)]
|
||||
pub struct InlinedPlugin {
|
||||
commands: &'static [&'static str],
|
||||
permissions_path_pattern: Option<&'static str>,
|
||||
}
|
||||
|
||||
impl InlinedPlugin {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Define a list of commands that gets permissions autogenerated in the format of `allow-$command` and `deny-$command`
|
||||
/// where $command is the command name in snake_case.
|
||||
pub fn commands(mut self, commands: &'static [&'static str]) -> Self {
|
||||
self.commands = commands;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets a glob pattern that is used to find the permissions of this inlined plugin.
|
||||
///
|
||||
/// **Note:** You must emit [rerun-if-changed] instructions for the plugin permissions directory.
|
||||
///
|
||||
/// By default it is `./permissions/$plugin-name/**/*`
|
||||
pub fn permissions_path_pattern(mut self, pattern: &'static str) -> Self {
|
||||
self.permissions_path_pattern.replace(pattern);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Tauri application permission manifest.
|
||||
///
|
||||
/// By default it generates a manifest that parses permissions from the `permissions` directory.
|
||||
/// To change the glob pattern that is used to find permissions, use [`Self::permissions_path_pattern`].
|
||||
///
|
||||
/// To autogenerate permissions for each of the app commands, see [`Self::commands`].
|
||||
#[derive(Debug, Default)]
|
||||
pub struct AppManifest {
|
||||
commands: &'static [&'static str],
|
||||
permissions_path_pattern: Option<&'static str>,
|
||||
}
|
||||
|
||||
impl AppManifest {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Define a list of commands that gets permissions autogenerated in the format of `allow-$command` and `deny-$command`
|
||||
/// where $command is the command name in snake_case.
|
||||
pub fn commands(mut self, commands: &'static [&'static str]) -> Self {
|
||||
self.commands = commands;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets a glob pattern that is used to find the permissions of the app.
|
||||
///
|
||||
/// **Note:** You must emit [rerun-if-changed] instructions for the permissions directory.
|
||||
///
|
||||
/// By default it is `./permissions/**/*` ignoring any [`InlinedPlugin`].
|
||||
pub fn permissions_path_pattern(mut self, pattern: &'static str) -> Self {
|
||||
self.permissions_path_pattern.replace(pattern);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
fn capabilities_schema(acl_manifests: &BTreeMap<String, Manifest>) -> RootSchema {
|
||||
let mut schema = schema_for!(CapabilityFile);
|
||||
|
||||
fn schema_from(plugin: &str, id: &str, description: Option<&str>) -> Schema {
|
||||
fn schema_from(key: &str, id: &str, description: Option<&str>) -> Schema {
|
||||
let command_name = if key == APP_ACL_KEY {
|
||||
id.to_string()
|
||||
} else {
|
||||
format!("{key}:{id}")
|
||||
};
|
||||
Schema::Object(SchemaObject {
|
||||
metadata: Some(Box::new(Metadata {
|
||||
description: description
|
||||
.as_ref()
|
||||
.map(|d| format!("{plugin}:{id} -> {d}")),
|
||||
.map(|d| format!("{command_name} -> {d}")),
|
||||
..Default::default()
|
||||
})),
|
||||
instance_type: Some(InstanceType::String.into()),
|
||||
enum_values: Some(vec![serde_json::Value::String(format!("{plugin}:{id}"))]),
|
||||
enum_values: Some(vec![serde_json::Value::String(command_name)]),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
let mut permission_schemas = Vec::new();
|
||||
|
||||
for (plugin, manifest) in plugin_manifests {
|
||||
for (key, manifest) in acl_manifests {
|
||||
for (set_id, set) in &manifest.permission_sets {
|
||||
permission_schemas.push(schema_from(plugin, set_id, Some(&set.description)));
|
||||
permission_schemas.push(schema_from(key, set_id, Some(&set.description)));
|
||||
}
|
||||
|
||||
if let Some(default) = &manifest.default_permission {
|
||||
permission_schemas.push(schema_from(
|
||||
plugin,
|
||||
"default",
|
||||
Some(default.description.as_ref()),
|
||||
));
|
||||
}
|
||||
permission_schemas.push(schema_from(
|
||||
key,
|
||||
"default",
|
||||
manifest
|
||||
.default_permission
|
||||
.as_ref()
|
||||
.map(|d| d.description.as_ref()),
|
||||
));
|
||||
|
||||
for (permission_id, permission) in &manifest.permissions {
|
||||
permission_schemas.push(schema_from(
|
||||
plugin,
|
||||
key,
|
||||
permission_id,
|
||||
permission.description.as_deref(),
|
||||
));
|
||||
@@ -83,27 +164,32 @@ fn capabilities_schema(plugin_manifests: &BTreeMap<String, Manifest>) -> RootSch
|
||||
}));
|
||||
}
|
||||
|
||||
let mut definitions = Vec::new();
|
||||
|
||||
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)
|
||||
if let Schema::Object(scope_extended_schema_obj) =
|
||||
permission_entry_any_of_schemas.last_mut().unwrap()
|
||||
{
|
||||
let mut global_scope_one_of = Vec::new();
|
||||
|
||||
for (plugin, manifest) in plugin_manifests {
|
||||
for (key, manifest) in acl_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_def: RootSchema =
|
||||
serde_json::from_value(global_scope_schema.clone())
|
||||
.unwrap_or_else(|e| panic!("invalid JSON schema for plugin {key}: {e}"));
|
||||
|
||||
let global_scope_schema = Schema::Object(SchemaObject {
|
||||
array: Some(Box::new(ArrayValidation {
|
||||
items: Some(global_scope_schema_def.into()),
|
||||
items: Some(Schema::Object(global_scope_schema_def.schema).into()),
|
||||
..Default::default()
|
||||
})),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
definitions.push(global_scope_schema_def.definitions);
|
||||
|
||||
let mut required = BTreeSet::new();
|
||||
required.insert("identifier".to_string());
|
||||
|
||||
@@ -113,15 +199,20 @@ fn capabilities_schema(plugin_manifests: &BTreeMap<String, Manifest>) -> RootSch
|
||||
};
|
||||
|
||||
let mut permission_schemas = Vec::new();
|
||||
if let Some(default) = &manifest.default_permission {
|
||||
permission_schemas.push(schema_from(plugin, "default", Some(&default.description)));
|
||||
}
|
||||
permission_schemas.push(schema_from(
|
||||
key,
|
||||
"default",
|
||||
manifest
|
||||
.default_permission
|
||||
.as_ref()
|
||||
.map(|d| d.description.as_ref()),
|
||||
));
|
||||
for set in manifest.permission_sets.values() {
|
||||
permission_schemas.push(schema_from(plugin, &set.identifier, Some(&set.description)));
|
||||
permission_schemas.push(schema_from(key, &set.identifier, Some(&set.description)));
|
||||
}
|
||||
for permission in manifest.permissions.values() {
|
||||
permission_schemas.push(schema_from(
|
||||
plugin,
|
||||
key,
|
||||
&permission.identifier,
|
||||
permission.description.as_deref(),
|
||||
));
|
||||
@@ -161,27 +252,26 @@ fn capabilities_schema(plugin_manifests: &BTreeMap<String, Manifest>) -> RootSch
|
||||
one_of: Some(global_scope_one_of),
|
||||
..Default::default()
|
||||
}));
|
||||
|
||||
permission_entry_any_of_schemas.push(scope_extended_schema_obj.into());
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
for definitions_map in definitions {
|
||||
schema.definitions.extend(definitions_map);
|
||||
}
|
||||
|
||||
schema
|
||||
}
|
||||
|
||||
pub fn generate_schema(
|
||||
plugin_manifests: &BTreeMap<String, Manifest>,
|
||||
target: Target,
|
||||
) -> Result<()> {
|
||||
let schema = capabilities_schema(plugin_manifests);
|
||||
pub fn generate_schema(acl_manifests: &BTreeMap<String, Manifest>, target: Target) -> Result<()> {
|
||||
let schema = capabilities_schema(acl_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}"));
|
||||
if schema_str != read_to_string(&schema_path).unwrap_or_default() {
|
||||
write(&schema_path, "{schema_str}")?;
|
||||
write(&schema_path, schema_str)?;
|
||||
|
||||
copy(
|
||||
schema_path,
|
||||
@@ -209,17 +299,17 @@ pub fn save_capabilities(capabilities: &BTreeMap<String, Capability>) -> Result<
|
||||
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)?;
|
||||
pub fn save_acl_manifests(acl_manifests: &BTreeMap<String, Manifest>) -> Result<PathBuf> {
|
||||
let acl_manifests_path =
|
||||
PathBuf::from(CAPABILITIES_SCHEMA_FOLDER_PATH).join(ACL_MANIFESTS_FILE_NAME);
|
||||
let acl_manifests_json = serde_json::to_string(&acl_manifests)?;
|
||||
if acl_manifests_json != read_to_string(&acl_manifests_path).unwrap_or_default() {
|
||||
std::fs::write(&acl_manifests_path, acl_manifests_json)?;
|
||||
}
|
||||
Ok(plugin_manifests_path)
|
||||
Ok(acl_manifests_path)
|
||||
}
|
||||
|
||||
pub fn get_plugin_manifests() -> Result<BTreeMap<String, Manifest>> {
|
||||
pub fn get_manifests_from_plugins() -> 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()
|
||||
@@ -234,52 +324,197 @@ pub fn get_plugin_manifests() -> Result<BTreeMap<String, Manifest>> {
|
||||
Ok(processed)
|
||||
}
|
||||
|
||||
pub fn inline_plugins(
|
||||
out_dir: &Path,
|
||||
inlined_plugins: HashMap<&'static str, InlinedPlugin>,
|
||||
) -> Result<BTreeMap<String, Manifest>> {
|
||||
let mut acl_manifests = BTreeMap::new();
|
||||
|
||||
for (name, plugin) in inlined_plugins {
|
||||
let plugin_out_dir = out_dir.join("plugins").join(name);
|
||||
create_dir_all(&plugin_out_dir)?;
|
||||
|
||||
let mut permission_files = if plugin.commands.is_empty() {
|
||||
Vec::new()
|
||||
} else {
|
||||
tauri_utils::acl::build::autogenerate_command_permissions(
|
||||
&plugin_out_dir,
|
||||
plugin.commands,
|
||||
"",
|
||||
false,
|
||||
);
|
||||
tauri_utils::acl::build::define_permissions(
|
||||
&plugin_out_dir.join("*").to_string_lossy(),
|
||||
name,
|
||||
&plugin_out_dir,
|
||||
|_| true,
|
||||
)?
|
||||
};
|
||||
|
||||
if let Some(pattern) = plugin.permissions_path_pattern {
|
||||
permission_files.extend(tauri_utils::acl::build::define_permissions(
|
||||
pattern,
|
||||
name,
|
||||
&plugin_out_dir,
|
||||
|_| true,
|
||||
)?);
|
||||
} else {
|
||||
let default_permissions_path = Path::new("permissions").join(name);
|
||||
if default_permissions_path.exists() {
|
||||
println!(
|
||||
"cargo:rerun-if-changed={}",
|
||||
default_permissions_path.display()
|
||||
);
|
||||
}
|
||||
permission_files.extend(tauri_utils::acl::build::define_permissions(
|
||||
&default_permissions_path
|
||||
.join("**")
|
||||
.join("*")
|
||||
.to_string_lossy(),
|
||||
name,
|
||||
&plugin_out_dir,
|
||||
|_| true,
|
||||
)?);
|
||||
}
|
||||
|
||||
let manifest = tauri_utils::acl::manifest::Manifest::new(permission_files, None);
|
||||
acl_manifests.insert(name.into(), manifest);
|
||||
}
|
||||
|
||||
Ok(acl_manifests)
|
||||
}
|
||||
|
||||
pub fn app_manifest_permissions(
|
||||
out_dir: &Path,
|
||||
manifest: AppManifest,
|
||||
inlined_plugins: &HashMap<&'static str, InlinedPlugin>,
|
||||
) -> Result<Manifest> {
|
||||
let app_out_dir = out_dir.join("app-manifest");
|
||||
create_dir_all(&app_out_dir)?;
|
||||
let pkg_name = "__app__";
|
||||
|
||||
let mut permission_files = if manifest.commands.is_empty() {
|
||||
Vec::new()
|
||||
} else {
|
||||
let autogenerated_path = Path::new("./permissions/autogenerated");
|
||||
tauri_utils::acl::build::autogenerate_command_permissions(
|
||||
autogenerated_path,
|
||||
manifest.commands,
|
||||
"",
|
||||
false,
|
||||
);
|
||||
tauri_utils::acl::build::define_permissions(
|
||||
&autogenerated_path.join("*").to_string_lossy(),
|
||||
pkg_name,
|
||||
&app_out_dir,
|
||||
|_| true,
|
||||
)?
|
||||
};
|
||||
|
||||
if let Some(pattern) = manifest.permissions_path_pattern {
|
||||
permission_files.extend(tauri_utils::acl::build::define_permissions(
|
||||
pattern,
|
||||
pkg_name,
|
||||
&app_out_dir,
|
||||
|_| true,
|
||||
)?);
|
||||
} else {
|
||||
let default_permissions_path = Path::new("permissions");
|
||||
if default_permissions_path.exists() {
|
||||
println!(
|
||||
"cargo:rerun-if-changed={}",
|
||||
default_permissions_path.display()
|
||||
);
|
||||
}
|
||||
|
||||
let permissions_root = current_dir()?.join("permissions");
|
||||
let inlined_plugins_permissions: Vec<_> = inlined_plugins
|
||||
.keys()
|
||||
.map(|name| permissions_root.join(name))
|
||||
.collect();
|
||||
|
||||
permission_files.extend(tauri_utils::acl::build::define_permissions(
|
||||
&default_permissions_path
|
||||
.join("**")
|
||||
.join("*")
|
||||
.to_string_lossy(),
|
||||
pkg_name,
|
||||
&app_out_dir,
|
||||
// filter out directories containing inlined plugins
|
||||
|p| {
|
||||
!inlined_plugins_permissions
|
||||
.iter()
|
||||
.any(|inlined_path| p.starts_with(inlined_path))
|
||||
},
|
||||
)?);
|
||||
}
|
||||
|
||||
Ok(tauri_utils::acl::manifest::Manifest::new(
|
||||
permission_files,
|
||||
None,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn validate_capabilities(
|
||||
plugin_manifests: &BTreeMap<String, Manifest>,
|
||||
acl_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) {
|
||||
if !capability
|
||||
.platforms
|
||||
.as_ref()
|
||||
.map(|platforms| platforms.contains(&target))
|
||||
.unwrap_or(true)
|
||||
{
|
||||
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}"));
|
||||
}
|
||||
let key = permission_id.get_prefix().unwrap_or(APP_ACL_KEY);
|
||||
let permission_name = permission_id.get_base();
|
||||
|
||||
if key == "core" && permission_name == "default" {
|
||||
continue;
|
||||
}
|
||||
|
||||
let permission_exists = acl_manifests
|
||||
.get(key)
|
||||
.map(|manifest| {
|
||||
// the default permission is always treated as valid, the CLI automatically adds it on the `tauri add` command
|
||||
permission_name == "default"
|
||||
|| 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 (key, manifest) in acl_manifests {
|
||||
let prefix = if key == APP_ACL_KEY {
|
||||
"".to_string()
|
||||
} else {
|
||||
format!("{key}:")
|
||||
};
|
||||
if manifest.default_permission.is_some() {
|
||||
available_permissions.push(format!("{prefix}default"));
|
||||
}
|
||||
for p in manifest.permissions.keys() {
|
||||
available_permissions.push(format!("{prefix}{p}"));
|
||||
}
|
||||
for p in manifest.permission_sets.keys() {
|
||||
available_permissions.push(format!("{prefix}{p}"));
|
||||
}
|
||||
|
||||
anyhow::bail!(
|
||||
"Permission {} not found, expected one of {}",
|
||||
permission_id.get(),
|
||||
available_permissions.join(", ")
|
||||
);
|
||||
}
|
||||
|
||||
anyhow::bail!(
|
||||
"Permission {} not found, expected one of {}",
|
||||
permission_id.get(),
|
||||
available_permissions.join(", ")
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::{
|
||||
env::var,
|
||||
fs::{create_dir_all, File},
|
||||
io::{BufWriter, Write},
|
||||
path::PathBuf,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
use tauri_codegen::{context_codegen, ContextData};
|
||||
use tauri_utils::config::FrontendDist;
|
||||
@@ -17,17 +17,17 @@ use tauri_utils::config::FrontendDist;
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "codegen")))]
|
||||
#[derive(Debug)]
|
||||
pub struct CodegenContext {
|
||||
dev: bool,
|
||||
config_path: PathBuf,
|
||||
out_file: PathBuf,
|
||||
capabilities: Option<Vec<PathBuf>>,
|
||||
}
|
||||
|
||||
impl Default for CodegenContext {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
dev: false,
|
||||
config_path: PathBuf::from("tauri.conf.json"),
|
||||
out_file: PathBuf::from("tauri-build-context.rs"),
|
||||
capabilities: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -66,11 +66,13 @@ impl CodegenContext {
|
||||
self
|
||||
}
|
||||
|
||||
/// Run the codegen in a `dev` context, meaning that Tauri is using a dev server or local file for development purposes,
|
||||
/// usually with the `tauri dev` CLI command.
|
||||
/// Adds a capability file to the generated context.
|
||||
#[must_use]
|
||||
pub fn dev(mut self) -> Self {
|
||||
self.dev = true;
|
||||
pub fn capability<P: AsRef<Path>>(mut self, path: P) -> Self {
|
||||
self
|
||||
.capabilities
|
||||
.get_or_insert_with(Default::default)
|
||||
.push(path.as_ref().to_path_buf());
|
||||
self
|
||||
}
|
||||
|
||||
@@ -113,18 +115,23 @@ impl CodegenContext {
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
println!(
|
||||
"cargo:rerun-if-changed={}",
|
||||
config_parent.join("Info.plist").display()
|
||||
);
|
||||
{
|
||||
let info_plist_path = config_parent.join("Info.plist");
|
||||
if info_plist_path.exists() {
|
||||
println!("cargo:rerun-if-changed={}", info_plist_path.display());
|
||||
}
|
||||
}
|
||||
|
||||
let code = context_codegen(ContextData {
|
||||
dev: self.dev,
|
||||
dev: crate::is_dev(),
|
||||
config,
|
||||
config_parent,
|
||||
// it's very hard to have a build script for unit tests, so assume this is always called from
|
||||
// outside the tauri crate, making the ::tauri root valid.
|
||||
root: quote::quote!(::tauri),
|
||||
capabilities: self.capabilities,
|
||||
assets: None,
|
||||
test: false,
|
||||
})?;
|
||||
|
||||
// get the full output file path
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
@@ -15,15 +15,15 @@
|
||||
use anyhow::Context;
|
||||
pub use anyhow::Result;
|
||||
use cargo_toml::Manifest;
|
||||
use heck::AsShoutySnakeCase;
|
||||
|
||||
use tauri_utils::{
|
||||
acl::build::parse_capabilities,
|
||||
acl::{build::parse_capabilities, APP_ACL_KEY},
|
||||
config::{BundleResources, Config, WebviewInstallMode},
|
||||
resources::{external_binaries, ResourcePaths},
|
||||
};
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
env::var_os,
|
||||
fs::copy,
|
||||
path::{Path, PathBuf},
|
||||
@@ -40,7 +40,9 @@ mod static_vcruntime;
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "codegen")))]
|
||||
pub use codegen::context::CodegenContext;
|
||||
|
||||
const PLUGIN_MANIFESTS_FILE_NAME: &str = "plugin-manifests.json";
|
||||
pub use acl::{AppManifest, InlinedPlugin};
|
||||
|
||||
const ACL_MANIFESTS_FILE_NAME: &str = "acl-manifests.json";
|
||||
const CAPABILITIES_FILE_NAME: &str = "capabilities.json";
|
||||
|
||||
fn copy_file(from: impl AsRef<Path>, to: impl AsRef<Path>) -> Result<()> {
|
||||
@@ -91,10 +93,18 @@ fn copy_binaries(
|
||||
|
||||
/// Copies resources to a path.
|
||||
fn copy_resources(resources: ResourcePaths<'_>, path: &Path) -> Result<()> {
|
||||
let path = path.canonicalize()?;
|
||||
for resource in resources.iter() {
|
||||
let resource = resource?;
|
||||
|
||||
println!("cargo:rerun-if-changed={}", resource.path().display());
|
||||
copy_file(resource.path(), path.join(resource.target()))?;
|
||||
|
||||
// avoid copying the resource if target is the same as source
|
||||
let src = resource.path().canonicalize()?;
|
||||
let target = path.join(resource.target());
|
||||
if src != target {
|
||||
copy_file(src, target)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -146,7 +156,7 @@ fn copy_dir(from: &Path, to: &Path) -> Result<()> {
|
||||
|
||||
// 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_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))?;
|
||||
@@ -158,12 +168,8 @@ fn copy_framework_from(src_dir: &Path, framework: &str, dest_dir: &Path) -> Resu
|
||||
|
||||
// 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
|
||||
)
|
||||
})?;
|
||||
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);
|
||||
@@ -188,7 +194,7 @@ fn copy_frameworks(dest_dir: &Path, frameworks: &[String]) -> Result<()> {
|
||||
framework
|
||||
));
|
||||
}
|
||||
if let Some(home_dir) = dirs_next::home_dir() {
|
||||
if let Some(home_dir) = dirs::home_dir() {
|
||||
if copy_framework_from(&home_dir.join("Library/Frameworks/"), framework, dest_dir)? {
|
||||
continue;
|
||||
}
|
||||
@@ -206,18 +212,10 @@ fn copy_frameworks(dest_dir: &Path, frameworks: &[String]) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// checks if the given Cargo feature is enabled.
|
||||
fn has_feature(feature: &str) -> bool {
|
||||
// when a feature is enabled, Cargo sets the `CARGO_FEATURE_<name` env var to 1
|
||||
// https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts
|
||||
std::env::var(format!("CARGO_FEATURE_{}", AsShoutySnakeCase(feature)))
|
||||
.map(|x| x == "1")
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
// creates a cfg alias if `has_feature` is true.
|
||||
// `alias` must be a snake case string.
|
||||
fn cfg_alias(alias: &str, has_feature: bool) {
|
||||
println!("cargo:rustc-check-cfg=cfg({alias})");
|
||||
if has_feature {
|
||||
println!("cargo:rustc-cfg={alias}");
|
||||
}
|
||||
@@ -301,7 +299,7 @@ impl WindowsAttributes {
|
||||
/// # Example
|
||||
///
|
||||
/// The following manifest will brand the exe as requesting administrator privileges.
|
||||
/// Thus, everytime it is executed, a Windows UAC dialog will appear.
|
||||
/// Thus, every time it is executed, a Windows UAC dialog will appear.
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// let mut windows = tauri_build::WindowsAttributes::new();
|
||||
@@ -339,6 +337,8 @@ pub struct Attributes {
|
||||
capabilities_path_pattern: Option<&'static str>,
|
||||
#[cfg(feature = "codegen")]
|
||||
codegen: Option<codegen::context::CodegenContext>,
|
||||
inlined_plugins: HashMap<&'static str, InlinedPlugin>,
|
||||
app_manifest: AppManifest,
|
||||
}
|
||||
|
||||
impl Attributes {
|
||||
@@ -365,6 +365,22 @@ impl Attributes {
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds the given plugin to the list of inlined plugins (a plugin that is part of your application).
|
||||
///
|
||||
/// See [`InlinedPlugin`] for more information.
|
||||
pub fn plugin(mut self, name: &'static str, plugin: InlinedPlugin) -> Self {
|
||||
self.inlined_plugins.insert(name, plugin);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the application manifest for the Access Control List.
|
||||
///
|
||||
/// See [`AppManifest`] for more information.
|
||||
pub fn app_manifest(mut self, manifest: AppManifest) -> Self {
|
||||
self.app_manifest = manifest;
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(feature = "codegen")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "codegen")))]
|
||||
#[must_use]
|
||||
@@ -374,6 +390,12 @@ impl Attributes {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_dev() -> bool {
|
||||
std::env::var("DEP_TAURI_DEV")
|
||||
.expect("missing `cargo:dev` instruction, please update tauri to latest")
|
||||
== "true"
|
||||
}
|
||||
|
||||
/// Run all build time helpers for your Tauri Application.
|
||||
///
|
||||
/// The current helpers include the following:
|
||||
@@ -442,19 +464,21 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
|
||||
let last = s.clone().count() - 1;
|
||||
let mut android_package_prefix = String::new();
|
||||
for (i, w) in s.enumerate() {
|
||||
if i == 0 || i != last {
|
||||
if i == last {
|
||||
println!("cargo:rustc-env=TAURI_ANDROID_PACKAGE_NAME_APP_NAME={w}");
|
||||
} else {
|
||||
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}");
|
||||
println!("cargo:rustc-env=TAURI_ANDROID_PACKAGE_NAME_PREFIX={android_package_prefix}");
|
||||
|
||||
if let Some(project_dir) = var_os("TAURI_ANDROID_PROJECT_PATH").map(PathBuf::from) {
|
||||
mobile::generate_gradle_files(project_dir)?;
|
||||
mobile::generate_gradle_files(project_dir, &config)?;
|
||||
}
|
||||
|
||||
cfg_alias("dev", !has_feature("custom-protocol"));
|
||||
cfg_alias("dev", is_dev());
|
||||
|
||||
let ws_path = get_workspace_dir()?;
|
||||
let mut manifest =
|
||||
@@ -473,26 +497,45 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
|
||||
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 mut acl_manifests = acl::get_manifests_from_plugins()?;
|
||||
let app_manifest = acl::app_manifest_permissions(
|
||||
&out_dir,
|
||||
attributes.app_manifest,
|
||||
&attributes.inlined_plugins,
|
||||
)?;
|
||||
if app_manifest.default_permission.is_some()
|
||||
|| !app_manifest.permission_sets.is_empty()
|
||||
|| !app_manifest.permissions.is_empty()
|
||||
{
|
||||
acl_manifests.insert(APP_ACL_KEY.into(), app_manifest);
|
||||
}
|
||||
acl_manifests.extend(acl::inline_plugins(&out_dir, attributes.inlined_plugins)?);
|
||||
|
||||
std::fs::write(
|
||||
out_dir.join(ACL_MANIFESTS_FILE_NAME),
|
||||
serde_json::to_string(&acl_manifests)?,
|
||||
)?;
|
||||
|
||||
let capabilities = if let Some(pattern) = attributes.capabilities_path_pattern {
|
||||
parse_capabilities(pattern)?
|
||||
} else {
|
||||
println!("cargo:rerun-if-changed=capabilities");
|
||||
parse_capabilities("./capabilities/**/*")?
|
||||
};
|
||||
acl::generate_schema(&plugin_manifests, target)?;
|
||||
acl::validate_capabilities(&plugin_manifests, &capabilities)?;
|
||||
acl::generate_schema(&acl_manifests, target)?;
|
||||
acl::validate_capabilities(&acl_manifests, &capabilities)?;
|
||||
|
||||
let capabilities_path = acl::save_capabilities(&capabilities)?;
|
||||
copy(capabilities_path, out_dir.join(CAPABILITIES_FILE_NAME))?;
|
||||
|
||||
acl::save_plugin_manifests(&plugin_manifests)?;
|
||||
acl::save_acl_manifests(&acl_manifests)?;
|
||||
|
||||
tauri_utils::plugin::load_global_api_scripts(&out_dir);
|
||||
|
||||
println!("cargo:rustc-env=TAURI_ENV_TARGET_TRIPLE={target_triple}");
|
||||
// when running codegen in this build script, we need to access the env var directly
|
||||
std::env::set_var("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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
@@ -65,7 +65,7 @@ pub fn check(config: &Config, manifest: &mut Manifest) -> Result<()> {
|
||||
if deps.is_empty() {
|
||||
if let Some(alias) = &metadata.alias {
|
||||
deps = find_dependency(manifest, alias, metadata.kind);
|
||||
name = alias.clone();
|
||||
name.clone_from(alias);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// Copyright 2019-2024 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};
|
||||
use semver::Version;
|
||||
use tauri_utils::config::Config;
|
||||
|
||||
pub fn generate_gradle_files(project_dir: PathBuf) -> Result<()> {
|
||||
use crate::is_dev;
|
||||
|
||||
pub fn generate_gradle_files(project_dir: PathBuf, config: &Config) -> 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 app_tauri_properties_path = project_dir.join("app").join("tauri.properties");
|
||||
|
||||
let mut gradle_settings =
|
||||
"// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.\n".to_string();
|
||||
@@ -16,6 +21,7 @@ pub fn generate_gradle_files(project_dir: PathBuf) -> Result<()> {
|
||||
val implementation by configurations
|
||||
dependencies {"
|
||||
.to_string();
|
||||
let mut app_tauri_properties = Vec::new();
|
||||
|
||||
for (env, value) in std::env::vars_os() {
|
||||
let env = env.to_string_lossy();
|
||||
@@ -48,13 +54,56 @@ dependencies {"
|
||||
|
||||
app_build_gradle.push_str("\n}");
|
||||
|
||||
if let Some(version) = config.version.as_ref() {
|
||||
app_tauri_properties.push(format!("tauri.android.versionName={version}"));
|
||||
if let Some(version_code) = config.bundle.android.version_code.as_ref() {
|
||||
app_tauri_properties.push(format!("tauri.android.versionCode={version_code}"));
|
||||
} else if let Ok(version) = Version::parse(version) {
|
||||
let mut version_code = version.major * 1000000 + version.minor * 1000 + version.patch;
|
||||
|
||||
if is_dev() {
|
||||
version_code = version_code.clamp(1, 2100000000);
|
||||
}
|
||||
|
||||
if version_code == 0 {
|
||||
return Err(anyhow::anyhow!(
|
||||
"You must change the `version` in `tauri.conf.json`. The default value `0.0.0` is not allowed for Android package and must be at least `0.0.1`."
|
||||
));
|
||||
} else if version_code > 2100000000 {
|
||||
return Err(anyhow::anyhow!(
|
||||
"Invalid version code {}. Version code must be between 1 and 2100000000. You must change the `version` in `tauri.conf.json`.",
|
||||
version_code
|
||||
));
|
||||
}
|
||||
|
||||
app_tauri_properties.push(format!("tauri.android.versionCode={version_code}"));
|
||||
}
|
||||
}
|
||||
|
||||
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")?;
|
||||
|
||||
if !app_tauri_properties.is_empty() {
|
||||
write(
|
||||
&app_tauri_properties_path,
|
||||
format!(
|
||||
"// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.\n{}",
|
||||
app_tauri_properties.join("\n")
|
||||
),
|
||||
)
|
||||
.context("failed to write tauri.properties")?;
|
||||
}
|
||||
|
||||
println!("cargo:rerun-if-changed={}", gradle_settings_path.display());
|
||||
println!("cargo:rerun-if-changed={}", app_build_gradle_path.display());
|
||||
if !app_tauri_properties.is_empty() {
|
||||
println!(
|
||||
"cargo:rerun-if-changed={}",
|
||||
app_tauri_properties_path.display()
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// taken from https://github.com/ChrisDenton/static_vcruntime/
|
||||
// taken from <https://github.com/ChrisDenton/static_vcruntime/>
|
||||
// we're not using static_vcruntime directly because we want this for debug builds too
|
||||
|
||||
use std::{env, fs, io::Write, path::Path};
|
||||
|
||||
@@ -1,5 +1,176 @@
|
||||
# Changelog
|
||||
|
||||
## \[2.0.0-rc.0]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`1e0793b68`](https://www.github.com/tauri-apps/tauri/commit/1e0793b6821799829e380c88066b3415cc9006df) ([#10357](https://www.github.com/tauri-apps/tauri/pull/10357)) Enhance `AssetResolver::get` in development mode by reading distDir directly as a fallback to the embedded assets.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`24445d71d`](https://www.github.com/tauri-apps/tauri/commit/24445d71de92d526d0ccaecb54f13003ddc6f6b4)([#10432](https://www.github.com/tauri-apps/tauri/pull/10432)) Fixes asset resolving when not using the `compression` feature.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-rc.0`
|
||||
|
||||
## \[2.0.0-beta.19]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`5d2922985`](https://www.github.com/tauri-apps/tauri/commit/5d2922985801908e4b929a7a0e387806ff02ab89) ([#10268](https://www.github.com/tauri-apps/tauri/pull/10268) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fix icon rewriting always triggering build to rerun due to conflicts between file names.
|
||||
|
||||
### What's Changed
|
||||
|
||||
- [`4c239729c`](https://www.github.com/tauri-apps/tauri/commit/4c239729c3e1b899ecbc6793c3682848e8de1729) ([#10167](https://www.github.com/tauri-apps/tauri/pull/10167) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add support for `test = true` in `generate_context!` macro to skip some code generation that could affect some tests, for now it only skips empedding a plist on macOS.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.19`
|
||||
|
||||
## \[2.0.0-beta.18]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`5b769948a`](https://www.github.com/tauri-apps/tauri/commit/5b769948a81cac333f64c870a470ba6525bd5cd3) ([#9959](https://www.github.com/tauri-apps/tauri/pull/9959)) Add `include_image_codegen` function to help embedding instances of `Image` struct at compile-time in rust to be used with window, menu or tray icons.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`1f6e478c8`](https://www.github.com/tauri-apps/tauri/commit/1f6e478c842a16219798b9962718e9ddb969c041) ([#9878](https://www.github.com/tauri-apps/tauri/pull/9878)) Fixes Info.plist rewriting always triggering build to rerun.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.18`
|
||||
|
||||
## \[2.0.0-beta.17]
|
||||
|
||||
### What's Changed
|
||||
|
||||
- [`ccc3ea729`](https://www.github.com/tauri-apps/tauri/commit/ccc3ea729de205ef467f737f1feeb5bf02d9cd72)([#9646](https://www.github.com/tauri-apps/tauri/pull/9646)) Use `TAURI_ENV_TARGET_TRIPLE` (which is set by `tauri-build`) to determine the target when reading the config file.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.17`
|
||||
|
||||
## \[2.0.0-beta.16]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.16`
|
||||
|
||||
## \[2.0.0-beta.15]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.15`
|
||||
|
||||
## \[2.0.0-beta.14]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.14`
|
||||
|
||||
## \[2.0.0-beta.13]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.13`
|
||||
|
||||
## \[2.0.0-beta.12]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.12`
|
||||
|
||||
## \[2.0.0-beta.11]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.11`
|
||||
|
||||
## \[2.0.0-beta.10]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`e227fe02f`](https://www.github.com/tauri-apps/tauri/commit/e227fe02f986e145c0731a64693e1c830a9eb5b0)([#9156](https://www.github.com/tauri-apps/tauri/pull/9156)) Allow plugins to define (at compile time) JavaScript that are initialized when `withGlobalTauri` is true.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.10`
|
||||
|
||||
## \[2.0.0-beta.9]
|
||||
|
||||
### New Features
|
||||
|
||||
- [`ba0206d8a`](https://www.github.com/tauri-apps/tauri/commit/ba0206d8a30a9b43ec5090dcaabd1a23baa1420c)([#9141](https://www.github.com/tauri-apps/tauri/pull/9141)) The `Context` codegen now accepts a `assets` input to define a custom `tauri::Assets` implementation.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.9`
|
||||
|
||||
## \[2.0.0-beta.8]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.8`
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- [`ed48e2b3c`](https://www.github.com/tauri-apps/tauri/commit/ed48e2b3c7fa914e4c9af432c02b8154f872c68a)([#9122](https://www.github.com/tauri-apps/tauri/pull/9122)) Expose `tauri::image` module to export the `JsImage` type and removed the `Image` root re-export.
|
||||
|
||||
## \[2.0.0-beta.7]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.7`
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- [`d1e77acd8`](https://www.github.com/tauri-apps/tauri/commit/d1e77acd8dfdf554b90b542513a58a2de1ef2360)([#9011](https://www.github.com/tauri-apps/tauri/pull/9011)) Change the generated context code to use the new `Image` type in tauri.
|
||||
|
||||
## \[2.0.0-beta.6]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.6`
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- [`3657ad82`](https://www.github.com/tauri-apps/tauri/commit/3657ad82f88ce528551d032d521c52eed3f396b4)([#9008](https://www.github.com/tauri-apps/tauri/pull/9008)) Allow defining permissions for the application commands via `tauri_build::Attributes::app_manifest`.
|
||||
|
||||
## \[2.0.0-beta.5]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`bc5b5e67`](https://www.github.com/tauri-apps/tauri/commit/bc5b5e671a546512f823f1c157421b4c3311dfc0)([#8984](https://www.github.com/tauri-apps/tauri/pull/8984)) Do not include a CSP tag in the application HTML and rely on the custom protocol response header instead.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.5`
|
||||
|
||||
## \[2.0.0-beta.4]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.4`
|
||||
|
||||
## \[2.0.0-beta.3]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.3`
|
||||
|
||||
## \[2.0.0-beta.2]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`83a68deb`](https://www.github.com/tauri-apps/tauri/commit/83a68deb5676d39cd4728d2e140f6b46d5f787ed)([#8797](https://www.github.com/tauri-apps/tauri/pull/8797)) Added a new configuration option `tauri.conf.json > app > security > capabilities` to reference existing capabilities and inline new ones. If it is empty, all capabilities are still included preserving the current behavior.
|
||||
- [`8d16a80d`](https://www.github.com/tauri-apps/tauri/commit/8d16a80d2fb2468667e7987d0cc99dbc7e3b9d0a)([#8802](https://www.github.com/tauri-apps/tauri/pull/8802)) The `generate_context` proc macro now accepts a `capabilities` attribute where the value is an array of file paths that can be [conditionally compiled](https://doc.rust-lang.org/reference/conditional-compilation.html). These capabilities are added to the application along the capabilities defined in the Tauri configuration file.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@2.0.0-beta.2`
|
||||
|
||||
## \[2.0.0-beta.1]
|
||||
|
||||
### Dependencies
|
||||
@@ -135,6 +306,12 @@
|
||||
- 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]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-utils@1.5.2`
|
||||
|
||||
## \[1.4.1]
|
||||
|
||||
### Dependencies
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "tauri-codegen"
|
||||
version = "2.0.0-beta.1"
|
||||
version = "2.0.0-rc.0"
|
||||
description = "code generation meant to be consumed inside of `tauri` through `tauri-build` or `tauri-macros`"
|
||||
exclude = [ "CHANGELOG.md", "/target" ]
|
||||
readme = "README.md"
|
||||
@@ -14,12 +14,13 @@ rust-version = { workspace = true }
|
||||
|
||||
[dependencies]
|
||||
sha2 = "0.10"
|
||||
base64 = "0.21"
|
||||
base64 = "0.22"
|
||||
proc-macro2 = "1"
|
||||
quote = "1"
|
||||
syn = "2"
|
||||
serde = { version = "1", features = [ "derive" ] }
|
||||
serde_json = "1"
|
||||
tauri-utils = { version = "2.0.0-beta.1", path = "../tauri-utils", features = [ "build" ] }
|
||||
tauri-utils = { version = "2.0.0-rc.0", path = "../tauri-utils", features = [ "build" ] }
|
||||
thiserror = "1"
|
||||
walkdir = "2"
|
||||
brotli = { version = "3", optional = true, default-features = false, features = [ "std" ] }
|
||||
@@ -36,7 +37,6 @@ plist = "1"
|
||||
time = { version = "0.3", features = [ "parsing", "formatting" ] }
|
||||
|
||||
[features]
|
||||
default = [ "compression" ]
|
||||
compression = [ "brotli", "tauri-utils/compression" ]
|
||||
isolation = [ "tauri-utils/isolation" ]
|
||||
config-json5 = [ "tauri-utils/config-json5" ]
|
||||
|
||||
@@ -4,10 +4,9 @@
|
||||
|
||||
[](https://github.com/tauri-apps/tauri)
|
||||
[](https://discord.gg/SpmNs4S)
|
||||
[](https://dev.to/tauri)
|
||||
|
||||
[](https://github.com/tauri-apps/tauri/actions/workflows/test-core.yml)
|
||||
[](https://tauri.app)
|
||||
[](https://tauri.app)
|
||||
|
||||
[](https://good-labs.github.io/greater-good-affirmation)
|
||||
[](https://opencollective.com/tauri)
|
||||
|
||||
@@ -1,29 +1,36 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::convert::identity;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::{ffi::OsStr, str::FromStr};
|
||||
|
||||
use crate::{
|
||||
embedded_assets::{
|
||||
ensure_out_dir, AssetOptions, CspHashes, EmbeddedAssets, EmbeddedAssetsResult,
|
||||
},
|
||||
image::CachedIcon,
|
||||
};
|
||||
use base64::Engine;
|
||||
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::{Config, FrontendDist, PatternKind};
|
||||
use tauri_utils::html::{
|
||||
inject_nonce_token, parse as parse_html, serialize_node as serialize_html_node,
|
||||
use syn::Expr;
|
||||
use tauri_utils::{
|
||||
acl::capability::{Capability, CapabilityFile},
|
||||
acl::manifest::Manifest,
|
||||
acl::resolved::Resolved,
|
||||
assets::AssetKey,
|
||||
config::{CapabilityEntry, Config, FrontendDist, PatternKind},
|
||||
html::{inject_nonce_token, parse as parse_html, serialize_node as serialize_html_node, NodeRef},
|
||||
platform::Target,
|
||||
plugin::GLOBAL_API_SCRIPT_FILE_LIST_PATH,
|
||||
tokens::{map_lit, str_lit},
|
||||
};
|
||||
use tauri_utils::platform::Target;
|
||||
|
||||
use crate::embedded_assets::{AssetOptions, CspHashes, EmbeddedAssets, EmbeddedAssetsError};
|
||||
|
||||
const PLUGIN_MANIFESTS_FILE_NAME: &str = "plugin-manifests.json";
|
||||
const ACL_MANIFESTS_FILE_NAME: &str = "acl-manifests.json";
|
||||
const CAPABILITIES_FILE_NAME: &str = "capabilities.json";
|
||||
|
||||
/// Necessary data needed by [`context_codegen`] to generate code for a Tauri application context.
|
||||
@@ -32,14 +39,38 @@ pub struct ContextData {
|
||||
pub config: Config,
|
||||
pub config_parent: PathBuf,
|
||||
pub root: TokenStream,
|
||||
/// Additional capabilities to include.
|
||||
pub capabilities: Option<Vec<PathBuf>>,
|
||||
/// The custom assets implementation
|
||||
pub assets: Option<Expr>,
|
||||
/// Skip runtime-only types generation for tests (e.g. embed-plist usage).
|
||||
pub test: bool,
|
||||
}
|
||||
|
||||
fn inject_script_hashes(document: &NodeRef, key: &AssetKey, csp_hashes: &mut CspHashes) {
|
||||
if let Ok(inline_script_elements) = document.select("script:not(empty)") {
|
||||
let mut scripts = Vec::new();
|
||||
for inline_script_el in inline_script_elements {
|
||||
let script = inline_script_el.as_node().text_contents();
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(&script);
|
||||
let hash = hasher.finalize();
|
||||
scripts.push(format!(
|
||||
"'sha256-{}'",
|
||||
base64::engine::general_purpose::STANDARD.encode(hash)
|
||||
));
|
||||
}
|
||||
csp_hashes
|
||||
.inline_scripts
|
||||
.entry(key.clone().into())
|
||||
.or_default()
|
||||
.append(&mut scripts);
|
||||
}
|
||||
}
|
||||
|
||||
fn map_core_assets(
|
||||
options: &AssetOptions,
|
||||
target: Target,
|
||||
) -> impl Fn(&AssetKey, &Path, &mut Vec<u8>, &mut CspHashes) -> Result<(), EmbeddedAssetsError> {
|
||||
#[cfg(feature = "isolation")]
|
||||
let pattern = tauri_utils::html::PatternObject::from(&options.pattern);
|
||||
) -> impl Fn(&AssetKey, &Path, &mut Vec<u8>, &mut CspHashes) -> EmbeddedAssetsResult<()> {
|
||||
let csp = options.csp;
|
||||
let dangerous_disable_asset_csp_modification =
|
||||
options.dangerous_disable_asset_csp_modification.clone();
|
||||
@@ -49,45 +80,10 @@ fn map_core_assets(
|
||||
if csp {
|
||||
let document = parse_html(String::from_utf8_lossy(input).into_owned());
|
||||
|
||||
if target == Target::Linux {
|
||||
::tauri_utils::html::inject_csp_token(&document);
|
||||
}
|
||||
|
||||
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)") {
|
||||
let mut scripts = Vec::new();
|
||||
for inline_script_el in inline_script_elements {
|
||||
let script = inline_script_el.as_node().text_contents();
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(&script);
|
||||
let hash = hasher.finalize();
|
||||
scripts.push(format!(
|
||||
"'sha256-{}'",
|
||||
base64::engine::general_purpose::STANDARD.encode(hash)
|
||||
));
|
||||
}
|
||||
csp_hashes
|
||||
.inline_scripts
|
||||
.entry(key.clone().into())
|
||||
.or_default()
|
||||
.append(&mut scripts);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "isolation")]
|
||||
if dangerous_disable_asset_csp_modification.can_modify("style-src") {
|
||||
if let tauri_utils::html::PatternObject::Isolation { .. } = &pattern {
|
||||
// create the csp for the isolation iframe styling now, to make the runtime less complex
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(tauri_utils::pattern::isolation::IFRAME_STYLE);
|
||||
let hash = hasher.finalize();
|
||||
csp_hashes.styles.push(format!(
|
||||
"'sha256-{}'",
|
||||
base64::engine::general_purpose::STANDARD.encode(hash)
|
||||
));
|
||||
}
|
||||
inject_script_hashes(&document, key, csp_hashes);
|
||||
}
|
||||
|
||||
*input = serialize_html_node(&document);
|
||||
@@ -101,10 +97,19 @@ fn map_core_assets(
|
||||
fn map_isolation(
|
||||
_options: &AssetOptions,
|
||||
dir: PathBuf,
|
||||
) -> impl Fn(&AssetKey, &Path, &mut Vec<u8>, &mut CspHashes) -> Result<(), EmbeddedAssetsError> {
|
||||
move |_key, path, input, _csp_hashes| {
|
||||
) -> impl Fn(&AssetKey, &Path, &mut Vec<u8>, &mut CspHashes) -> EmbeddedAssetsResult<()> {
|
||||
// create the csp for the isolation iframe styling now, to make the runtime less complex
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(tauri_utils::pattern::isolation::IFRAME_STYLE);
|
||||
let hash = hasher.finalize();
|
||||
let iframe_style_csp_hash = format!(
|
||||
"'sha256-{}'",
|
||||
base64::engine::general_purpose::STANDARD.encode(hash)
|
||||
);
|
||||
|
||||
move |key, path, input, csp_hashes| {
|
||||
if path.extension() == Some(OsStr::new("html")) {
|
||||
let isolation_html = tauri_utils::html::parse(String::from_utf8_lossy(input).into_owned());
|
||||
let isolation_html = parse_html(String::from_utf8_lossy(input).into_owned());
|
||||
|
||||
// this is appended, so no need to reverse order it
|
||||
tauri_utils::html::inject_codegen_isolation_script(&isolation_html);
|
||||
@@ -112,6 +117,15 @@ fn map_isolation(
|
||||
// temporary workaround for windows not loading assets
|
||||
tauri_utils::html::inline_isolation(&isolation_html, &dir);
|
||||
|
||||
inject_nonce_token(
|
||||
&isolation_html,
|
||||
&tauri_utils::config::DisabledCspModificationKind::Flag(false),
|
||||
);
|
||||
|
||||
inject_script_hashes(&isolation_html, key, csp_hashes);
|
||||
|
||||
csp_hashes.styles.push(iframe_style_csp_hash.clone());
|
||||
|
||||
*input = isolation_html.to_string().as_bytes().to_vec()
|
||||
}
|
||||
|
||||
@@ -120,16 +134,21 @@ fn map_isolation(
|
||||
}
|
||||
|
||||
/// Build a `tauri::Context` for including in application code.
|
||||
pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsError> {
|
||||
pub fn context_codegen(data: ContextData) -> EmbeddedAssetsResult<TokenStream> {
|
||||
let ContextData {
|
||||
dev,
|
||||
config,
|
||||
config_parent,
|
||||
root,
|
||||
capabilities: additional_capabilities,
|
||||
assets,
|
||||
test,
|
||||
} = data;
|
||||
|
||||
let target = std::env::var("TARGET")
|
||||
.or_else(|_| std::env::var("TAURI_ENV_TARGET_TRIPLE"))
|
||||
#[allow(unused_variables)]
|
||||
let running_tests = test;
|
||||
|
||||
let target = std::env::var("TAURI_ENV_TARGET_TRIPLE")
|
||||
.as_deref()
|
||||
.map(Target::from_triple)
|
||||
.unwrap_or_else(|_| Target::current());
|
||||
@@ -157,21 +176,23 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
||||
options = options.with_csp();
|
||||
}
|
||||
|
||||
let assets = if dev && config.build.dev_url.is_some() {
|
||||
Default::default()
|
||||
let assets = if let Some(assets) = assets {
|
||||
quote!(#assets)
|
||||
} else if dev && config.build.dev_url.is_some() {
|
||||
let assets = EmbeddedAssets::default();
|
||||
quote!(#assets)
|
||||
} else {
|
||||
match &config.build.frontend_dist {
|
||||
let assets = 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
|
||||
"The `frontendDist` configuration is set to `{path:?}` but this path doesn't exist"
|
||||
)
|
||||
}
|
||||
EmbeddedAssets::new(assets_path, &options, map_core_assets(&options, target))?
|
||||
EmbeddedAssets::new(assets_path, &options, map_core_assets(&options))?
|
||||
}
|
||||
FrontendDist::Files(files) => EmbeddedAssets::new(
|
||||
files
|
||||
@@ -179,25 +200,16 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
||||
.map(|p| config_parent.join(p))
|
||||
.collect::<Vec<_>>(),
|
||||
&options,
|
||||
map_core_assets(&options, target),
|
||||
map_core_assets(&options),
|
||||
)?,
|
||||
_ => unimplemented!(),
|
||||
},
|
||||
None => Default::default(),
|
||||
}
|
||||
};
|
||||
quote!(#assets)
|
||||
};
|
||||
|
||||
let out_dir = {
|
||||
let out_dir = std::env::var("OUT_DIR")
|
||||
.map_err(|_| EmbeddedAssetsError::OutDir)
|
||||
.map(PathBuf::from)
|
||||
.and_then(|p| p.canonicalize().map_err(|_| EmbeddedAssetsError::OutDir))?;
|
||||
|
||||
// make sure that our output directory is created
|
||||
std::fs::create_dir_all(&out_dir).map_err(|_| EmbeddedAssetsError::OutDir)?;
|
||||
|
||||
out_dir
|
||||
};
|
||||
let out_dir = ensure_out_dir()?;
|
||||
|
||||
let default_window_icon = {
|
||||
if target == Target::Windows {
|
||||
@@ -209,7 +221,8 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
||||
"icons/icon.ico",
|
||||
);
|
||||
if icon_path.exists() {
|
||||
ico_icon(&root, &out_dir, icon_path).map(|i| quote!(::std::option::Option::Some(#i)))?
|
||||
let icon = CachedIcon::new(&root, &icon_path)?;
|
||||
quote!(::std::option::Option::Some(#icon))
|
||||
} else {
|
||||
let icon_path = find_icon(
|
||||
&config,
|
||||
@@ -217,7 +230,8 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
||||
|i| i.ends_with(".png"),
|
||||
"icons/icon.png",
|
||||
);
|
||||
png_icon(&root, &out_dir, icon_path).map(|i| quote!(::std::option::Option::Some(#i)))?
|
||||
let icon = CachedIcon::new(&root, &icon_path)?;
|
||||
quote!(::std::option::Option::Some(#icon))
|
||||
}
|
||||
} else {
|
||||
// handle default window icons for Unix targets
|
||||
@@ -227,7 +241,8 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
||||
|i| i.ends_with(".png"),
|
||||
"icons/icon.png",
|
||||
);
|
||||
png_icon(&root, &out_dir, icon_path).map(|i| quote!(::std::option::Option::Some(#i)))?
|
||||
let icon = CachedIcon::new(&root, &icon_path)?;
|
||||
quote!(::std::option::Option::Some(#icon))
|
||||
}
|
||||
};
|
||||
|
||||
@@ -246,7 +261,9 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
||||
"icons/icon.png",
|
||||
);
|
||||
}
|
||||
raw_icon(&out_dir, icon_path)?
|
||||
|
||||
let icon = CachedIcon::new_raw(&root, &icon_path)?;
|
||||
quote!(::std::option::Option::Some(#icon.to_vec()))
|
||||
} else {
|
||||
quote!(::std::option::Option::None)
|
||||
};
|
||||
@@ -275,18 +292,8 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
||||
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`."
|
||||
))
|
||||
}
|
||||
let icon = CachedIcon::new(&root, &tray_icon_icon_path)?;
|
||||
quote!(context.set_tray_icon(::std::option::Option::Some(#icon));)
|
||||
} else {
|
||||
quote!()
|
||||
}
|
||||
@@ -295,7 +302,7 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
||||
};
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
let info_plist = if target == Target::MacOS && dev {
|
||||
let info_plist = if target == Target::MacOS && dev && !running_tests {
|
||||
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)
|
||||
@@ -310,19 +317,20 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
||||
}
|
||||
if let Some(version) = &config.version {
|
||||
plist.insert("CFBundleShortVersionString".into(), version.clone().into());
|
||||
}
|
||||
let format =
|
||||
time::format_description::parse("[year][month][day].[hour][minute][second]").unwrap();
|
||||
if let Ok(build_number) = time::OffsetDateTime::now_utc().format(&format) {
|
||||
plist.insert("CFBundleVersion".into(), build_number.into());
|
||||
plist.insert("CFBundleVersion".into(), version.clone().into());
|
||||
}
|
||||
}
|
||||
|
||||
let mut plist_contents = std::io::BufWriter::new(Vec::new());
|
||||
info_plist
|
||||
.to_file_xml(out_dir.join("Info.plist"))
|
||||
.expect("failed to write Info.plist");
|
||||
.to_writer_xml(&mut plist_contents)
|
||||
.expect("failed to serialize plist");
|
||||
let plist_contents =
|
||||
String::from_utf8_lossy(&plist_contents.into_inner().unwrap()).into_owned();
|
||||
|
||||
let plist = crate::Cached::try_from(plist_contents)?;
|
||||
quote!({
|
||||
tauri::embed_plist::embed_info_plist!(concat!(std::env!("OUT_DIR"), "/Info.plist"));
|
||||
tauri::embed_plist::embed_info_plist!(#plist);
|
||||
})
|
||||
} else {
|
||||
quote!(())
|
||||
@@ -331,10 +339,10 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
||||
let info_plist = quote!(());
|
||||
|
||||
let pattern = match &options.pattern {
|
||||
PatternKind::Brownfield => quote!(#root::Pattern::Brownfield(std::marker::PhantomData)),
|
||||
PatternKind::Brownfield => quote!(#root::Pattern::Brownfield),
|
||||
#[cfg(not(feature = "isolation"))]
|
||||
PatternKind::Isolation { dir: _ } => {
|
||||
quote!(#root::Pattern::Brownfield(std::marker::PhantomData))
|
||||
quote!(#root::Pattern::Brownfield)
|
||||
}
|
||||
#[cfg(feature = "isolation")]
|
||||
PatternKind::Isolation { dir } => {
|
||||
@@ -371,7 +379,7 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
||||
}
|
||||
};
|
||||
|
||||
let acl_file_path = out_dir.join(PLUGIN_MANIFESTS_FILE_NAME);
|
||||
let acl_file_path = out_dir.join(ACL_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");
|
||||
@@ -381,7 +389,8 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
||||
};
|
||||
|
||||
let capabilities_file_path = out_dir.join(CAPABILITIES_FILE_NAME);
|
||||
let capabilities: BTreeMap<String, Capability> = if capabilities_file_path.exists() {
|
||||
let mut capabilities_from_files: 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")
|
||||
@@ -389,7 +398,96 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
||||
Default::default()
|
||||
};
|
||||
|
||||
let resolved_acl = Resolved::resolve(acl, capabilities, target).expect("failed to resolve ACL");
|
||||
let mut capabilities = if config.app.security.capabilities.is_empty() {
|
||||
capabilities_from_files
|
||||
} else {
|
||||
let mut capabilities = BTreeMap::new();
|
||||
for capability_entry in &config.app.security.capabilities {
|
||||
match capability_entry {
|
||||
CapabilityEntry::Inlined(capability) => {
|
||||
capabilities.insert(capability.identifier.clone(), capability.clone());
|
||||
}
|
||||
CapabilityEntry::Reference(id) => {
|
||||
let capability = capabilities_from_files
|
||||
.remove(id)
|
||||
.unwrap_or_else(|| panic!("capability with identifier {id} not found"));
|
||||
capabilities.insert(id.clone(), capability);
|
||||
}
|
||||
}
|
||||
}
|
||||
capabilities
|
||||
};
|
||||
|
||||
let acl_tokens = map_lit(
|
||||
quote! { ::std::collections::BTreeMap },
|
||||
&acl,
|
||||
str_lit,
|
||||
identity,
|
||||
);
|
||||
|
||||
if let Some(paths) = additional_capabilities {
|
||||
for path in paths {
|
||||
let capability = CapabilityFile::load(&path)
|
||||
.unwrap_or_else(|e| panic!("failed to read capability {}: {e}", path.display()));
|
||||
match capability {
|
||||
CapabilityFile::Capability(c) => {
|
||||
capabilities.insert(c.identifier.clone(), c);
|
||||
}
|
||||
CapabilityFile::List(capabilities_list)
|
||||
| CapabilityFile::NamedList {
|
||||
capabilities: capabilities_list,
|
||||
} => {
|
||||
capabilities.extend(
|
||||
capabilities_list
|
||||
.into_iter()
|
||||
.map(|c| (c.identifier.clone(), c)),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let resolved = Resolved::resolve(&acl, capabilities, target).expect("failed to resolve ACL");
|
||||
let runtime_authority = quote!(#root::ipc::RuntimeAuthority::new(#acl_tokens, #resolved));
|
||||
|
||||
let plugin_global_api_script_file_list_path = out_dir.join(GLOBAL_API_SCRIPT_FILE_LIST_PATH);
|
||||
let plugin_global_api_script =
|
||||
if config.app.with_global_tauri && plugin_global_api_script_file_list_path.exists() {
|
||||
let file_list_str = std::fs::read_to_string(plugin_global_api_script_file_list_path)
|
||||
.expect("failed to read plugin global API script paths");
|
||||
let file_list = serde_json::from_str::<Vec<PathBuf>>(&file_list_str)
|
||||
.expect("failed to parse plugin global API script paths");
|
||||
|
||||
let mut plugins = Vec::new();
|
||||
for path in file_list {
|
||||
plugins.push(std::fs::read_to_string(&path).unwrap_or_else(|e| {
|
||||
panic!(
|
||||
"failed to read plugin global API script {}: {e}",
|
||||
path.display()
|
||||
)
|
||||
}));
|
||||
}
|
||||
|
||||
Some(plugins)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let plugin_global_api_script = if let Some(scripts) = plugin_global_api_script {
|
||||
let scripts = scripts.into_iter().map(|s| quote!(#s));
|
||||
quote!(::std::option::Option::Some(&[#(#scripts),*]))
|
||||
} else {
|
||||
quote!(::std::option::Option::None)
|
||||
};
|
||||
|
||||
let maybe_config_parent_setter = if dev {
|
||||
let config_parent = config_parent.to_string_lossy();
|
||||
quote!({
|
||||
context.with_config_parent(#config_parent);
|
||||
})
|
||||
} else {
|
||||
quote!()
|
||||
};
|
||||
|
||||
Ok(quote!({
|
||||
#[allow(unused_mut, clippy::let_and_return)]
|
||||
@@ -401,137 +499,29 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
||||
#package_info,
|
||||
#info_plist,
|
||||
#pattern,
|
||||
#resolved_acl
|
||||
#runtime_authority,
|
||||
#plugin_global_api_script
|
||||
);
|
||||
|
||||
#with_tray_icon_code
|
||||
#maybe_config_parent_setter
|
||||
|
||||
context
|
||||
}))
|
||||
}
|
||||
|
||||
fn ico_icon<P: AsRef<Path>>(
|
||||
root: &TokenStream,
|
||||
out_dir: &Path,
|
||||
path: P,
|
||||
) -> Result<TokenStream, EmbeddedAssetsError> {
|
||||
let path = path.as_ref();
|
||||
let bytes = std::fs::read(path)
|
||||
.unwrap_or_else(|e| panic!("failed to read icon {}: {}", path.display(), e))
|
||||
.to_vec();
|
||||
let icon_dir = ico::IconDir::read(std::io::Cursor::new(bytes))
|
||||
.unwrap_or_else(|e| panic!("failed to parse icon {}: {}", path.display(), e));
|
||||
let entry = &icon_dir.entries()[0];
|
||||
let rgba = entry
|
||||
.decode()
|
||||
.unwrap_or_else(|e| panic!("failed to decode icon {}: {}", path.display(), e))
|
||||
.rgba_data()
|
||||
.to_vec();
|
||||
let width = entry.width();
|
||||
let height = entry.height();
|
||||
|
||||
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 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)
|
||||
}
|
||||
|
||||
fn raw_icon<P: AsRef<Path>>(out_dir: &Path, path: P) -> Result<TokenStream, EmbeddedAssetsError> {
|
||||
let path = path.as_ref();
|
||||
let bytes = std::fs::read(path)
|
||||
.unwrap_or_else(|e| panic!("failed to read icon {}: {}", path.display(), e))
|
||||
.to_vec();
|
||||
|
||||
let out_path = out_dir.join(path.file_name().unwrap());
|
||||
write_if_changed(&out_path, &bytes).map_err(|error| EmbeddedAssetsError::AssetWrite {
|
||||
path: path.to_owned(),
|
||||
error,
|
||||
})?;
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
fn png_icon<P: AsRef<Path>>(
|
||||
root: &TokenStream,
|
||||
out_dir: &Path,
|
||||
path: P,
|
||||
) -> Result<TokenStream, EmbeddedAssetsError> {
|
||||
let path = path.as_ref();
|
||||
let bytes = std::fs::read(path)
|
||||
.unwrap_or_else(|e| panic!("failed to read icon {}: {}", path.display(), e))
|
||||
.to_vec();
|
||||
let decoder = png::Decoder::new(std::io::Cursor::new(bytes));
|
||||
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());
|
||||
}
|
||||
let width = reader.info().width;
|
||||
let height = reader.info().height;
|
||||
|
||||
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 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)
|
||||
}
|
||||
|
||||
fn write_if_changed(out_path: &Path, data: &[u8]) -> std::io::Result<()> {
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
|
||||
if let Ok(curr) = std::fs::read(out_path) {
|
||||
if curr == data {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
let mut out_file = File::create(out_path)?;
|
||||
out_file.write_all(data)
|
||||
}
|
||||
|
||||
fn find_icon<F: Fn(&&String) -> bool>(
|
||||
fn find_icon(
|
||||
config: &Config,
|
||||
config_parent: &Path,
|
||||
predicate: F,
|
||||
predicate: impl Fn(&&String) -> bool,
|
||||
default: &str,
|
||||
) -> PathBuf {
|
||||
let icon_path = config
|
||||
.bundle
|
||||
.icon
|
||||
.iter()
|
||||
.find(|i| predicate(i))
|
||||
.cloned()
|
||||
.unwrap_or_else(|| default.to_string());
|
||||
.find(predicate)
|
||||
.map(AsRef::as_ref)
|
||||
.unwrap_or(default);
|
||||
config_parent.join(icon_path)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
@@ -8,7 +8,6 @@ use quote::{quote, ToTokens, TokenStreamExt};
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fmt::Write,
|
||||
fs::File,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
@@ -48,6 +47,9 @@ pub enum EmbeddedAssetsError {
|
||||
#[error("invalid prefix {prefix} used while including path {path}")]
|
||||
PrefixInvalid { prefix: PathBuf, path: PathBuf },
|
||||
|
||||
#[error("invalid extension `{extension}` used for image {path}, must be `ico` or `png`")]
|
||||
InvalidImageExtension { extension: PathBuf, path: PathBuf },
|
||||
|
||||
#[error("failed to walk directory {path} because {error}")]
|
||||
Walkdir {
|
||||
path: PathBuf,
|
||||
@@ -61,6 +63,8 @@ pub enum EmbeddedAssetsError {
|
||||
Version(#[from] semver::Error),
|
||||
}
|
||||
|
||||
pub type EmbeddedAssetsResult<T> = Result<T, EmbeddedAssetsError>;
|
||||
|
||||
/// Represent a directory of assets that are compressed and embedded.
|
||||
///
|
||||
/// This is the compile time generation of [`tauri_utils::assets::Assets`] from a directory. Assets
|
||||
@@ -336,19 +340,7 @@ impl EmbeddedAssets {
|
||||
std::fs::create_dir_all(&out_dir).map_err(|_| EmbeddedAssetsError::OutDir)?;
|
||||
|
||||
// get a hash of the input - allows for caching existing files
|
||||
let hash = {
|
||||
let mut hasher = crate::vendor::blake3_reference::Hasher::default();
|
||||
hasher.update(&input);
|
||||
|
||||
let mut bytes = [0u8; 32];
|
||||
hasher.finalize(&mut bytes);
|
||||
|
||||
let mut hex = String::with_capacity(2 * bytes.len());
|
||||
for b in bytes {
|
||||
write!(hex, "{b:02x}").map_err(EmbeddedAssetsError::Hex)?;
|
||||
}
|
||||
hex
|
||||
};
|
||||
let hash = crate::checksum(&input).map_err(EmbeddedAssetsError::Hex)?;
|
||||
|
||||
// use the content hash to determine filename, keep extensions that exist
|
||||
let out_path = if let Some(ext) = path.extension().and_then(|e| e.to_str()) {
|
||||
@@ -439,3 +431,14 @@ impl ToTokens for EmbeddedAssets {
|
||||
}});
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn ensure_out_dir() -> EmbeddedAssetsResult<PathBuf> {
|
||||
let out_dir = std::env::var("OUT_DIR")
|
||||
.map_err(|_| EmbeddedAssetsError::OutDir)
|
||||
.map(PathBuf::from)
|
||||
.and_then(|p| p.canonicalize().map_err(|_| EmbeddedAssetsError::OutDir))?;
|
||||
|
||||
// make sure that our output directory is created
|
||||
std::fs::create_dir_all(&out_dir).map_err(|_| EmbeddedAssetsError::OutDir)?;
|
||||
Ok(out_dir)
|
||||
}
|
||||
|
||||
118
core/tauri-codegen/src/image.rs
Normal file
118
core/tauri-codegen/src/image.rs
Normal file
@@ -0,0 +1,118 @@
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use crate::{
|
||||
embedded_assets::{EmbeddedAssetsError, EmbeddedAssetsResult},
|
||||
Cached,
|
||||
};
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{quote, ToTokens, TokenStreamExt};
|
||||
use std::{ffi::OsStr, io::Cursor, path::Path};
|
||||
|
||||
/// The format the Icon is consumed as.
|
||||
pub(crate) enum IconFormat {
|
||||
/// The image, completely unmodified.
|
||||
Raw,
|
||||
|
||||
/// RGBA raw data, meant to be consumed by [`tauri::image::Image`].
|
||||
Image { width: u32, height: u32 },
|
||||
}
|
||||
|
||||
pub struct CachedIcon {
|
||||
cache: Cached,
|
||||
format: IconFormat,
|
||||
root: TokenStream,
|
||||
}
|
||||
|
||||
impl CachedIcon {
|
||||
pub fn new(root: &TokenStream, icon: &Path) -> EmbeddedAssetsResult<Self> {
|
||||
match icon.extension().map(OsStr::to_string_lossy).as_deref() {
|
||||
Some("png") => Self::new_png(root, icon),
|
||||
Some("ico") => Self::new_ico(root, icon),
|
||||
unknown => Err(EmbeddedAssetsError::InvalidImageExtension {
|
||||
extension: unknown.unwrap_or_default().into(),
|
||||
path: icon.to_path_buf(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
/// Cache the icon without any manipulation.
|
||||
pub fn new_raw(root: &TokenStream, icon: &Path) -> EmbeddedAssetsResult<Self> {
|
||||
let buf = Self::open(icon);
|
||||
Cached::try_from(buf).map(|cache| Self {
|
||||
cache,
|
||||
root: root.clone(),
|
||||
format: IconFormat::Raw,
|
||||
})
|
||||
}
|
||||
|
||||
/// Cache an ICO icon as RGBA data, see [`ImageFormat::Image`].
|
||||
pub fn new_ico(root: &TokenStream, icon: &Path) -> EmbeddedAssetsResult<Self> {
|
||||
let buf = Self::open(icon);
|
||||
|
||||
let icon_dir = ico::IconDir::read(Cursor::new(&buf))
|
||||
.unwrap_or_else(|e| panic!("failed to parse icon {}: {}", icon.display(), e));
|
||||
|
||||
let entry = &icon_dir.entries()[0];
|
||||
let rgba = entry
|
||||
.decode()
|
||||
.unwrap_or_else(|e| panic!("failed to decode icon {}: {}", icon.display(), e))
|
||||
.rgba_data()
|
||||
.to_vec();
|
||||
|
||||
Cached::try_from(rgba).map(|cache| Self {
|
||||
cache,
|
||||
root: root.clone(),
|
||||
format: IconFormat::Image {
|
||||
width: entry.width(),
|
||||
height: entry.height(),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/// Cache a PNG icon as RGBA data, see [`ImageFormat::Image`].
|
||||
pub fn new_png(root: &TokenStream, icon: &Path) -> EmbeddedAssetsResult<Self> {
|
||||
let buf = Self::open(icon);
|
||||
let decoder = png::Decoder::new(Cursor::new(&buf));
|
||||
let mut reader = decoder
|
||||
.read_info()
|
||||
.unwrap_or_else(|e| panic!("failed to read icon {}: {}", icon.display(), e));
|
||||
|
||||
if reader.output_color_type().0 != png::ColorType::Rgba {
|
||||
panic!("icon {} is not RGBA", icon.display());
|
||||
}
|
||||
|
||||
let mut rgba = Vec::with_capacity(reader.output_buffer_size());
|
||||
while let Ok(Some(row)) = reader.next_row() {
|
||||
rgba.extend(row.data());
|
||||
}
|
||||
|
||||
Cached::try_from(rgba).map(|cache| Self {
|
||||
cache,
|
||||
root: root.clone(),
|
||||
format: IconFormat::Image {
|
||||
width: reader.info().width,
|
||||
height: reader.info().height,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
fn open(path: &Path) -> Vec<u8> {
|
||||
std::fs::read(path).unwrap_or_else(|e| panic!("failed to open icon {}: {}", path.display(), e))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for CachedIcon {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
let root = &self.root;
|
||||
let cache = &self.cache;
|
||||
let raw = quote!(::std::include_bytes!(#cache));
|
||||
tokens.append_all(match self.format {
|
||||
IconFormat::Raw => raw,
|
||||
IconFormat::Image { width, height } => {
|
||||
quote!(#root::image::Image::new(#raw, #width, #height))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
@@ -13,14 +13,21 @@
|
||||
)]
|
||||
|
||||
pub use self::context::{context_codegen, ContextData};
|
||||
use crate::embedded_assets::{ensure_out_dir, EmbeddedAssetsError};
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{quote, ToTokens, TokenStreamExt};
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
fmt::{self, Write},
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
pub use tauri_utils::config::{parse::ConfigError, Config};
|
||||
use tauri_utils::platform::Target;
|
||||
use tauri_utils::write_if_changed;
|
||||
|
||||
mod context;
|
||||
pub mod embedded_assets;
|
||||
pub mod image;
|
||||
#[doc(hidden)]
|
||||
pub mod vendor;
|
||||
|
||||
@@ -63,22 +70,28 @@ pub fn get_config(path: &Path) -> Result<(Config, PathBuf), CodegenConfigError>
|
||||
.map(ToOwned::to_owned)
|
||||
.ok_or_else(|| CodegenConfigError::Parent(path.into_owned()))?;
|
||||
|
||||
let target = std::env::var("TAURI_ENV_TARGET_TRIPLE")
|
||||
.as_deref()
|
||||
.map(Target::from_triple)
|
||||
.unwrap_or_else(|_| Target::current());
|
||||
|
||||
// in the future we may want to find a way to not need the TAURI_CONFIG env var so that
|
||||
// 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(
|
||||
tauri_utils::platform::Target::current(),
|
||||
target,
|
||||
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)?;
|
||||
json_patch::merge(&mut config, &merge_config);
|
||||
}
|
||||
|
||||
let old_cwd = std::env::current_dir().map_err(CodegenConfigError::CurrentDir)?;
|
||||
// Set working directory to where `tauri.config.json` is, so that relative paths in it are parsed correctly.
|
||||
let old_cwd = std::env::current_dir().map_err(CodegenConfigError::CurrentDir)?;
|
||||
std::env::set_current_dir(parent.clone()).map_err(CodegenConfigError::CurrentDir)?;
|
||||
|
||||
let config = serde_json::from_value(config)?;
|
||||
@@ -88,3 +101,54 @@ pub fn get_config(path: &Path) -> Result<(Config, PathBuf), CodegenConfigError>
|
||||
|
||||
Ok((config, parent))
|
||||
}
|
||||
|
||||
/// Create a blake3 checksum of the passed bytes.
|
||||
fn checksum(bytes: &[u8]) -> Result<String, fmt::Error> {
|
||||
let mut hasher = vendor::blake3_reference::Hasher::default();
|
||||
hasher.update(bytes);
|
||||
|
||||
let mut bytes = [0u8; 32];
|
||||
hasher.finalize(&mut bytes);
|
||||
|
||||
let mut hex = String::with_capacity(2 * bytes.len());
|
||||
for b in bytes {
|
||||
write!(hex, "{b:02x}")?;
|
||||
}
|
||||
Ok(hex)
|
||||
}
|
||||
|
||||
/// Cache the data to `$OUT_DIR`, only if it does not already exist.
|
||||
///
|
||||
/// Due to using a checksum as the filename, an existing file should be the exact same content
|
||||
/// as the data being checked.
|
||||
struct Cached {
|
||||
checksum: String,
|
||||
}
|
||||
|
||||
impl TryFrom<String> for Cached {
|
||||
type Error = EmbeddedAssetsError;
|
||||
|
||||
fn try_from(value: String) -> Result<Self, Self::Error> {
|
||||
Self::try_from(Vec::from(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<Vec<u8>> for Cached {
|
||||
type Error = EmbeddedAssetsError;
|
||||
|
||||
fn try_from(content: Vec<u8>) -> Result<Self, Self::Error> {
|
||||
let checksum = checksum(content.as_ref()).map_err(EmbeddedAssetsError::Hex)?;
|
||||
let path = ensure_out_dir()?.join(&checksum);
|
||||
|
||||
write_if_changed(&path, &content)
|
||||
.map(|_| Self { checksum })
|
||||
.map_err(|error| EmbeddedAssetsError::AssetWrite { path, error })
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for Cached {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
let path = &self.checksum;
|
||||
tokens.append_all(quote!(::std::concat!(::std::env!("OUT_DIR"), "/", #path)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
2
core/tauri-codegen/src/vendor/mod.rs
vendored
2
core/tauri-codegen/src/vendor/mod.rs
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ publish = false
|
||||
|
||||
[build-dependencies]
|
||||
tauri-utils = { features = [ "schema" ], path = "../tauri-utils" }
|
||||
schemars = { version = "0.8", features = ["url", "preserve_order"] }
|
||||
schemars = { version = "0.8.18", features = ["url", "preserve_order"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
url = { version = "2.3", features = ["serde"] }
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user