diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..5eb1ae5b --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,17 @@ +name: "Release Crate" +on: + push: + tags: + - "v*" +jobs: + publish_crate: + name: Publish Crate + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions-rs/cargo@v1 + if: startsWith(github.ref, 'refs/tags/v') + name: Release Crate + with: + command: publish + args: --workspace --token ${{ secrets.CARGO_REGISTRY_TOKEN }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d8d8f183..720caecc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -76,3 +76,23 @@ samply record cargo run ``` Use `samply record` command to start rust development, and do some operations in the app that you want to profile, then stop the terminal with `ctrl-c`, then samply will open the browser to show the profile results. + +## Release crates version + +When we are ready to release a new version, please follow the steps below: + +1. Run `cargo set-version` to set the new version for all crates. + + ```bash + cargo set-version 0.2.0 + ``` + +2. Git Commit the changes with message `chore: Release v0.2.0`. +3. Create a new git tag with the version `v0.2.0` and push `main` branch and the tag to remote. + + ```bash + git tag v0.2.0 + git push origin main --tags + ``` + +4. Then GitHub Actions will automatically publish the crates to crates.io and create a new release in GitHub. diff --git a/Cargo.lock b/Cargo.lock index 85700c2f..8d3a8494 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -615,9 +615,9 @@ dependencies = [ [[package]] name = "aws-lc-rs" -version = "1.13.3" +version = "1.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c953fe1ba023e6b7730c0d4b031d06f267f23a46167dcbd40316644b10a17ba" +checksum = "879b6c89592deb404ba4dc0ae6b58ffd1795c78991cbb5b8bc441c48a070440d" dependencies = [ "aws-lc-sys", "zeroize", @@ -625,15 +625,16 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.30.0" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbfd150b5dbdb988bcc8fb1fe787eb6b7ee6180ca24da683b61ea5405f3d43ff" +checksum = "a2b715a6010afb9e457ca2b7c9d2b9c344baa8baed7b38dc476034c171b32575" dependencies = [ - "bindgen 0.69.5", + "bindgen 0.72.1", "cc", "cmake", "dunce", "fs_extra", + "libloading", ] [[package]] @@ -668,32 +669,29 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bindgen" -version = "0.69.5" +version = "0.71.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" +checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" dependencies = [ "bitflags 2.9.1", "cexpr", "clang-sys", - "itertools 0.12.1", - "lazy_static", - "lazycell", + "itertools 0.13.0", "log", "prettyplease", "proc-macro2", "quote", "regex", - "rustc-hash 1.1.0", + "rustc-hash 2.1.1", "shlex", "syn 2.0.105", - "which 4.4.2", ] [[package]] name = "bindgen" -version = "0.71.1" +version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" +checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" dependencies = [ "bitflags 2.9.1", "cexpr", @@ -1160,7 +1158,7 @@ dependencies = [ "cocoa-foundation 0.1.2", "core-foundation 0.9.4", "core-graphics 0.23.2", - "foreign-types", + "foreign-types 0.5.0", "libc", "objc", ] @@ -1176,7 +1174,7 @@ dependencies = [ "cocoa-foundation 0.2.1", "core-foundation 0.10.1", "core-graphics 0.24.0", - "foreign-types", + "foreign-types 0.5.0", "libc", "objc", ] @@ -1337,7 +1335,7 @@ dependencies = [ "bitflags 1.3.2", "core-foundation 0.9.4", "core-graphics-types 0.1.3", - "foreign-types", + "foreign-types 0.5.0", "libc", ] @@ -1350,7 +1348,7 @@ dependencies = [ "bitflags 2.9.1", "core-foundation 0.10.1", "core-graphics-types 0.2.0", - "foreign-types", + "foreign-types 0.5.0", "libc", ] @@ -1363,7 +1361,7 @@ dependencies = [ "bitflags 2.9.1", "core-foundation 0.9.4", "core-graphics-types 0.1.3", - "foreign-types", + "foreign-types 0.5.0", "libc", ] @@ -1410,7 +1408,7 @@ checksum = "a593227b66cbd4007b2a050dfdd9e1d1318311409c8d600dc82ba1b15ca9c130" dependencies = [ "core-foundation 0.10.1", "core-graphics 0.24.0", - "foreign-types", + "foreign-types 0.5.0", "libc", ] @@ -2239,6 +2237,15 @@ dependencies = [ "ttf-parser 0.25.1", ] +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared 0.1.1", +] + [[package]] name = "foreign-types" version = "0.5.0" @@ -2246,7 +2253,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" dependencies = [ "foreign-types-macros", - "foreign-types-shared", + "foreign-types-shared 0.3.1", ] [[package]] @@ -2260,6 +2267,12 @@ dependencies = [ "syn 2.0.105", ] +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "foreign-types-shared" version = "0.3.1" @@ -2778,8 +2791,9 @@ dependencies = [ [[package]] name = "gpui" -version = "0.1.0" -source = "git+https://github.com/zed-industries/zed.git#5c7907ad2fb566c787de003e79cfb7ba40364ac2" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8a209a56079b7af7d158e410aaad8666edf5ad55450803eaace98a4eef383f7" dependencies = [ "anyhow", "as-raw-xcb-connection", @@ -2807,7 +2821,7 @@ dependencies = [ "etagere", "filedescriptor", "flume", - "foreign-types", + "foreign-types 0.5.0", "futures", "gpui-macros", "image", @@ -2872,7 +2886,7 @@ dependencies = [ [[package]] name = "gpui-component" -version = "0.1.0" +version = "0.2.0-test2" dependencies = [ "aho-corasick", "anyhow", @@ -2884,6 +2898,7 @@ dependencies = [ "html5ever 0.27.0", "indoc", "itertools 0.13.0", + "lb-wry", "lsp-types 0.97.0", "markdown", "markup5ever_rcdom", @@ -2934,13 +2949,12 @@ dependencies = [ "tree-sitter-zig", "unicode-segmentation", "uuid", - "wry", "zed-sum-tree", ] [[package]] name = "gpui-component-macros" -version = "0.1.0" +version = "0.2.0-test2" dependencies = [ "proc-macro2", "quote", @@ -2949,8 +2963,9 @@ dependencies = [ [[package]] name = "gpui-macros" -version = "0.1.0" -source = "git+https://github.com/zed-industries/zed.git#5c7907ad2fb566c787de003e79cfb7ba40364ac2" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "756549abfa9eef8391c685ae8a79a1a0e30b7d6e51f32cdce61998c689718710" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -3085,7 +3100,7 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hello_world" -version = "0.1.0" +version = "0.2.0-test2" dependencies = [ "anyhow", "gpui", @@ -3214,16 +3229,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "http_client_tls" -version = "0.1.0" -source = "git+https://github.com/zed-industries/zed.git#5c7907ad2fb566c787de003e79cfb7ba40364ac2" -dependencies = [ - "rustls", - "rustls-platform-verifier", - "workspace-hack", -] - [[package]] name = "httparse" version = "1.10.1" @@ -3267,6 +3272,22 @@ dependencies = [ "tower-service", ] +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + [[package]] name = "hyper-util" version = "0.1.16" @@ -3806,10 +3827,50 @@ dependencies = [ ] [[package]] -name = "lazycell" -version = "1.3.0" +name = "lb-wry" +version = "0.53.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" +checksum = "d9cfe72bff8acf9af0d6d276569be5b9cb3f313f9882761ada5a50d3044214d4" +dependencies = [ + "base64", + "block2", + "cookie", + "crossbeam-channel", + "dirs 6.0.0", + "dpi", + "dunce", + "flume", + "gdkx11", + "gtk", + "html5ever 0.29.1", + "http", + "javascriptcore-rs", + "jni", + "kuchikiki", + "libc", + "ndk", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation", + "objc2-ui-kit", + "objc2-web-kit", + "once_cell", + "percent-encoding", + "raw-window-handle", + "sha2", + "soup3", + "tao-macros", + "thiserror 2.0.14", + "url", + "webkit2gtk", + "webkit2gtk-sys", + "webview2-com", + "windows 0.61.3", + "windows-core 0.61.2", + "windows-version", + "x11-dl", +] [[package]] name = "leak" @@ -4155,7 +4216,7 @@ dependencies = [ "bitflags 2.9.1", "block", "core-graphics-types 0.1.3", - "foreign-types", + "foreign-types 0.5.0", "log", "objc", "paste", @@ -4245,6 +4306,23 @@ dependencies = [ "getrandom 0.2.16", ] +[[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework 2.11.1", + "security-framework-sys", + "tempfile", +] + [[package]] name = "ndk" version = "0.9.0" @@ -4513,7 +4591,7 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 3.3.0", "proc-macro2", "quote", "syn 2.0.105", @@ -4731,12 +4809,50 @@ dependencies = [ "pathdiff", ] +[[package]] +name = "openssl" +version = "0.10.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" +dependencies = [ + "bitflags 2.9.1", + "cfg-if", + "foreign-types 0.3.2", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.105", +] + [[package]] name = "openssl-probe" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" +[[package]] +name = "openssl-sys" +version = "0.9.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "option-ext" version = "0.2.0" @@ -5752,18 +5868,17 @@ dependencies = [ [[package]] name = "reqwest_client" -version = "0.1.0" -source = "git+https://github.com/zed-industries/zed.git#5c7907ad2fb566c787de003e79cfb7ba40364ac2" +version = "0.2.0-test2" dependencies = [ "anyhow", "bytes", "futures", - "http_client_tls", + "gpui", "log", "regex", - "serde", + "rustls", + "rustls-platform-verifier", "tokio", - "workspace-hack", "zed-http-client", "zed-reqwest", ] @@ -6047,7 +6162,7 @@ dependencies = [ "openssl-probe", "rustls-pki-types", "schannel", - "security-framework", + "security-framework 3.3.0", ] [[package]] @@ -6084,7 +6199,7 @@ dependencies = [ "rustls-native-certs", "rustls-platform-verifier-android", "rustls-webpki", - "security-framework", + "security-framework 3.3.0", "security-framework-sys", "webpki-root-certs 0.26.11", "windows-sys 0.59.0", @@ -6240,6 +6355,19 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.9.1", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + [[package]] name = "security-framework" version = "3.3.0" @@ -6719,7 +6847,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "story" -version = "0.1.0" +version = "0.2.0-test2" dependencies = [ "anyhow", "autocorrect", @@ -7310,6 +7438,16 @@ dependencies = [ "syn 2.0.105", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.26.2" @@ -7775,8 +7913,9 @@ dependencies = [ [[package]] name = "tree-sitter-md" -version = "0.5.0" -source = "git+https://github.com/tree-sitter-grammars/tree-sitter-markdown?tag=v0.5.0#afaa4138517363362f54c89330c9d79391e81168" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b55ea8733e098490746a07d6f629d1f7820e8953a4aab1341ae39123bcdf93d" dependencies = [ "cc", "tree-sitter-language", @@ -8189,6 +8328,12 @@ dependencies = [ "sval_serde", ] +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version-compare" version = "0.2.0" @@ -8518,14 +8663,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75c7f0ef91146ebfb530314f5f1d24528d7f0767efbfd31dce919275413e393e" dependencies = [ - "webpki-root-certs 1.0.2", + "webpki-root-certs 1.0.3", ] [[package]] name = "webpki-root-certs" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4ffd8df1c57e87c325000a3d6ef93db75279dc3a231125aac571650f22b12a" +checksum = "05d651ec480de84b762e7be71e6efa7461699c19d9e2c272c8d93455f567786e" dependencies = [ "rustls-pki-types", ] @@ -8572,18 +8717,6 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a751b3277700db47d3e574514de2eced5e54dc8a5436a3bf7a0b248b2cee16f3" -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix 0.38.44", -] - [[package]] name = "which" version = "6.0.3" @@ -9196,51 +9329,6 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" -[[package]] -name = "wry" -version = "0.53.3" -source = "git+https://github.com/longbridge/wry#1b0e5d57dd9d4ebea11adfb981718e265c21ec1d" -dependencies = [ - "base64", - "block2", - "cookie", - "crossbeam-channel", - "dirs 6.0.0", - "dpi", - "dunce", - "flume", - "gdkx11", - "gtk", - "html5ever 0.29.1", - "http", - "javascriptcore-rs", - "jni", - "kuchikiki", - "libc", - "ndk", - "objc2", - "objc2-app-kit", - "objc2-core-foundation", - "objc2-foundation", - "objc2-ui-kit", - "objc2-web-kit", - "once_cell", - "percent-encoding", - "raw-window-handle", - "sha2", - "soup3", - "tao-macros", - "thiserror 2.0.14", - "url", - "webkit2gtk", - "webkit2gtk-sys", - "webview2-com", - "windows 0.61.3", - "windows-core 0.61.2", - "windows-version", - "x11-dl", -] - [[package]] name = "wyz" version = "0.5.1" @@ -9330,7 +9418,8 @@ checksum = "bec9e4a500ca8864c5b47b8b482a73d62e4237670e5b5f1d6b9e3cae50f28f2b" [[package]] name = "xim-ctext" version = "0.3.0" -source = "git+https://github.com/zed-industries/xim-rs.git?rev=16f35a2c881b815a2b6cdfd6687988e84f8447d8#16f35a2c881b815a2b6cdfd6687988e84f8447d8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ac61a7062c40f3c37b6e82eeeef835d5cc7824b632a72784a89b3963c33284c" dependencies = [ "encoding_rs", ] @@ -9338,9 +9427,10 @@ dependencies = [ [[package]] name = "xim-parser" version = "0.2.1" -source = "git+https://github.com/zed-industries/xim-rs.git?rev=16f35a2c881b815a2b6cdfd6687988e84f8447d8#16f35a2c881b815a2b6cdfd6687988e84f8447d8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b100b895758fefbf602129502acc0dd474bc08dd1e2036f17a7c118d6fd6fe53" dependencies = [ - "bitflags 2.9.1", + "bitflags 1.3.2", ] [[package]] @@ -9481,8 +9571,9 @@ dependencies = [ [[package]] name = "zed-collections" -version = "0.1.0" -source = "git+https://github.com/zed-industries/zed.git#5c7907ad2fb566c787de003e79cfb7ba40364ac2" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec1b9b3b5d39c11198dda53dbd50e18fbcaebc854c7c62921bf444cb5f21ab8a" dependencies = [ "indexmap", "rustc-hash 2.1.1", @@ -9491,8 +9582,9 @@ dependencies = [ [[package]] name = "zed-derive-refineable" -version = "0.1.0" -source = "git+https://github.com/zed-industries/zed.git#5c7907ad2fb566c787de003e79cfb7ba40364ac2" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0438b07ec0b8965715363dd1096a28e2d758408b7d67d683510b57dc2d121210" dependencies = [ "proc-macro2", "quote", @@ -9503,7 +9595,8 @@ dependencies = [ [[package]] name = "zed-font-kit" version = "0.14.1-zed" -source = "git+https://github.com/zed-industries/font-kit?rev=110523127440aefb11ce0cf280ae7c5071337ec5#110523127440aefb11ce0cf280ae7c5071337ec5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3898e450f36f852edda72e3f985c34426042c4951790b23b107f93394f9bff5" dependencies = [ "bitflags 2.9.1", "byteorder", @@ -9526,8 +9619,9 @@ dependencies = [ [[package]] name = "zed-http-client" -version = "0.1.0" -source = "git+https://github.com/zed-industries/zed.git#5c7907ad2fb566c787de003e79cfb7ba40364ac2" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3f2bb8e91cfc16ef201813d76fa6c4e98e5193f07f88d51c7b912d3761f72f" dependencies = [ "anyhow", "async-compression", @@ -9552,15 +9646,16 @@ dependencies = [ [[package]] name = "zed-media" -version = "0.1.0" -source = "git+https://github.com/zed-industries/zed.git#5c7907ad2fb566c787de003e79cfb7ba40364ac2" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b145013b2053b9b9bef788405815240e4d8648a3c8271ce9e49c7ef2384f48e7" dependencies = [ "anyhow", "bindgen 0.71.1", "core-foundation 0.10.1", "core-video", "ctor", - "foreign-types", + "foreign-types 0.5.0", "metal", "objc", "workspace-hack", @@ -9568,8 +9663,9 @@ dependencies = [ [[package]] name = "zed-perf" -version = "0.1.0" -source = "git+https://github.com/zed-industries/zed.git#5c7907ad2fb566c787de003e79cfb7ba40364ac2" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfdfdb2834f17691d64bbb21aa7b7dd2e933df9711c5c60874973254f37b335c" dependencies = [ "serde", "serde_json", @@ -9579,8 +9675,9 @@ dependencies = [ [[package]] name = "zed-refineable" -version = "0.1.0" -source = "git+https://github.com/zed-industries/zed.git#5c7907ad2fb566c787de003e79cfb7ba40364ac2" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1898ca1f0e28bbe3fe1183899f79c083b646f8b8cea3ae52be6834ab29e0d656" dependencies = [ "workspace-hack", "zed-derive-refineable", @@ -9589,7 +9686,8 @@ dependencies = [ [[package]] name = "zed-reqwest" version = "0.12.15-zed" -source = "git+https://github.com/zed-industries/reqwest.git?rev=c15662463bda39148ba154100dd44d3fba5873a4#c15662463bda39148ba154100dd44d3fba5873a4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac2d05756ff48539950c3282ad7acf3817ad3f08797c205ad1c34a2ce03b9970" dependencies = [ "base64", "bytes", @@ -9602,12 +9700,14 @@ dependencies = [ "http-body-util", "hyper", "hyper-rustls", + "hyper-tls", "hyper-util", "ipnet", "js-sys", "log", "mime", "mime_guess", + "native-tls", "once_cell", "percent-encoding", "pin-project-lite", @@ -9622,6 +9722,7 @@ dependencies = [ "sync_wrapper", "system-configuration", "tokio", + "tokio-native-tls", "tokio-rustls", "tokio-socks", "tokio-util", @@ -9638,7 +9739,8 @@ dependencies = [ [[package]] name = "zed-scap" version = "0.0.8-zed" -source = "git+https://github.com/zed-industries/scap?rev=4afea48c3b002197176fb19cd0f9b180dd36eaac#4afea48c3b002197176fb19cd0f9b180dd36eaac" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b338d705ae33a43ca00287c11129303a7a0aa57b101b72a1c08c863f698ac8" dependencies = [ "anyhow", "cocoa 0.25.0", @@ -9658,8 +9760,9 @@ dependencies = [ [[package]] name = "zed-semantic-version" -version = "0.1.0" -source = "git+https://github.com/zed-industries/zed.git#5c7907ad2fb566c787de003e79cfb7ba40364ac2" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "963eb3815502d03cdb116555e624baa87c286466cc2ad6b022ab5154d4032911" dependencies = [ "anyhow", "serde", @@ -9668,8 +9771,9 @@ dependencies = [ [[package]] name = "zed-sum-tree" -version = "0.1.0" -source = "git+https://github.com/zed-industries/zed.git#5c7907ad2fb566c787de003e79cfb7ba40364ac2" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d490156d0d7311855564d6e1d6dccab992405a0c0e15e1c8ef18920c02177e35" dependencies = [ "arrayvec", "log", @@ -9679,8 +9783,9 @@ dependencies = [ [[package]] name = "zed-util" -version = "0.1.0" -source = "git+https://github.com/zed-industries/zed.git#5c7907ad2fb566c787de003e79cfb7ba40364ac2" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "989eeb4bc093333d33226f5a478d97d1d9b305fce5798bc89dd094768b4286b7" dependencies = [ "anyhow", "async-fs 2.1.3", @@ -9708,15 +9813,16 @@ dependencies = [ "tendril", "unicase", "walkdir", - "which 6.0.3", + "which", "workspace-hack", "zed-collections", ] [[package]] name = "zed-util-macros" -version = "0.1.0" -source = "git+https://github.com/zed-industries/zed.git#5c7907ad2fb566c787de003e79cfb7ba40364ac2" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47eb0c78e38dfec0e59237f5cff5613a926c0262c3688ce070029ca3cc54fa63" dependencies = [ "quote", "syn 2.0.105", @@ -9727,7 +9833,8 @@ dependencies = [ [[package]] name = "zed-xim" version = "0.4.0-zed" -source = "git+https://github.com/zed-industries/xim-rs.git?rev=16f35a2c881b815a2b6cdfd6687988e84f8447d8#16f35a2c881b815a2b6cdfd6687988e84f8447d8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0b46ed118eba34d9ba53d94ddc0b665e0e06a2cf874cfa2dd5dec278148642" dependencies = [ "ahash 0.8.12", "hashbrown 0.14.5", diff --git a/Cargo.toml b/Cargo.toml index bf3b3471..78496ecb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,13 +6,14 @@ resolver = "2" [workspace.dependencies] gpui-component = { path = "crates/ui" } -gpui-component-macros = { path = "crates/macros" } +gpui-component-macros = { path = "crates/macros", version = "0.2.0-test2" } story = { path = "crates/story" } -gpui = { git = "https://github.com/zed-industries/zed.git" } -gpui-macros = { git = "https://github.com/zed-industries/zed.git" } -reqwest_client = { git = "https://github.com/zed-industries/zed.git" } -zed-sum-tree = { git = "https://github.com/zed-industries/zed.git" } +gpui = "0.2.0" +gpui-macros = "0.2.0" +sum-tree = { version = "0.2.0", package = "zed-sum-tree" } +http-client = { version = "0.2.0", package = "zed-http-client" } +reqwest = { version = "0.12.15-zed", package = "zed-reqwest" } anyhow = "1" log = "0.4" diff --git a/README.md b/README.md index 48dd5cf1..fe583e91 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # GPUI Component -[![Build Status](https://github.com/longbridge/gpui-component/actions/workflows/ci.yml/badge.svg)](https://github.com/longbridge/gpui-component/actions/workflows/ci.yml) +[![Build Status](https://github.com/longbridge/gpui-component/actions/workflows/ci.yml/badge.svg)](https://github.com/longbridge/gpui-component/actions/workflows/ci.yml) [![Docs](https://docs.rs/gpui-component/badge.svg)](https://docs.rs/gpui-component/) [![Crates.io](https://img.shields.io/crates/v/gpui-component.svg)](https://crates.io/crates/gpui-component) UI components for building fantastic desktop applications using [GPUI](https://gpui.rs). @@ -31,8 +31,8 @@ We built multi-theme support in the application. This feature is not included in GPUI and GPUI Component are still in development, so you need to add dependencies by git. ```toml -gpui = { git = "https://github.com/zed-industries/zed.git" } -gpui-component = { git = "https://github.com/longbridge/gpui-component.git" } +gpui = "0.2.0" +gpui-component = "0.2.0" ``` ### WebView @@ -42,7 +42,8 @@ gpui-component = { git = "https://github.com/longbridge/gpui-component.git" } GPUI Component has a `WebView` element based on [Wry](https://github.com/tauri-apps/wry). This is an optional feature, which you can enable with a feature flag. ```toml -gpui-component = { git = "https://github.com/longbridge/gpui-component.git", features = ["webview"] } +gpui-component = { version = "0.2.0", features = ["webview"] } +wry = { version = "0.53.3, package = "lb-wry" } ``` More usage examples can be found in the [story](https://github.com/longbridge/gpui-component/tree/main/crates/story) directory. diff --git a/crates/hello_world/Cargo.toml b/crates/hello_world/Cargo.toml index f5ec8a90..0f170e39 100644 --- a/crates/hello_world/Cargo.toml +++ b/crates/hello_world/Cargo.toml @@ -3,7 +3,7 @@ edition = "2021" name = "hello_world" description = "A minimal example of application development with GPUI Component." publish = false -version = "0.1.0" +version = "0.2.0-test2" [dependencies] anyhow.workspace = true diff --git a/crates/macros/Cargo.toml b/crates/macros/Cargo.toml index 0892acee..ae3e4622 100644 --- a/crates/macros/Cargo.toml +++ b/crates/macros/Cargo.toml @@ -1,7 +1,10 @@ [package] edition = "2021" name = "gpui-component-macros" -version = "0.1.0" +description = "Macros for GPUI Component." +version = "0.2.0-test2" +publish = true +license-file = "LICENSE-APACHE" [lib] proc-macro = true diff --git a/crates/macros/LICENSE-APACHE b/crates/macros/LICENSE-APACHE new file mode 100644 index 00000000..e5ee4a2d --- /dev/null +++ b/crates/macros/LICENSE-APACHE @@ -0,0 +1 @@ +../../LICENSE-APACHE diff --git a/crates/reqwest_client/Cargo.toml b/crates/reqwest_client/Cargo.toml new file mode 100644 index 00000000..d0d6a753 --- /dev/null +++ b/crates/reqwest_client/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "reqwest_client" +version = "0.2.0-test2" +publish = false +license = "Apache-2.0" +edition = "2024" + +[lints] +workspace = true + +[features] +test-support = [] + +[lib] +path = "src/reqwest_client.rs" +doctest = true + +[dependencies] +reqwest.workspace = true +http-client.workspace = true +anyhow.workspace = true +log.workspace = true + +rustls = { version = "0.23.26" } +rustls-platform-verifier = "0.5.0" +bytes = "1.0" +futures = "0.3" +tokio = { version = "1", features = ["rt", "rt-multi-thread"] } +regex = "1.5" + +[dev-dependencies] +gpui.workspace = true diff --git a/crates/reqwest_client/LICENSE-APACHE b/crates/reqwest_client/LICENSE-APACHE new file mode 100644 index 00000000..461a0fe5 --- /dev/null +++ b/crates/reqwest_client/LICENSE-APACHE @@ -0,0 +1,222 @@ +Copyright 2022 - 2025 Zed Industries, Inc. + + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + + http://www.apache.org/licenses/LICENSE-2.0 + + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + + +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + + 1. Definitions. + + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + + END OF TERMS AND CONDITIONS diff --git a/crates/reqwest_client/src/http_client_tls.rs b/crates/reqwest_client/src/http_client_tls.rs new file mode 100644 index 00000000..8ddde5c1 --- /dev/null +++ b/crates/reqwest_client/src/http_client_tls.rs @@ -0,0 +1,21 @@ +use std::sync::OnceLock; + +use rustls::ClientConfig; +use rustls_platform_verifier::ConfigVerifierExt; + +static TLS_CONFIG: OnceLock = OnceLock::new(); + +pub fn tls_config() -> ClientConfig { + TLS_CONFIG + .get_or_init(|| { + // rustls uses the `aws_lc_rs` provider by default + // This only errors if the default provider has already + // been installed. We can ignore this `Result`. + rustls::crypto::aws_lc_rs::default_provider() + .install_default() + .ok(); + + ClientConfig::with_platform_verifier() + }) + .clone() +} diff --git a/crates/reqwest_client/src/reqwest_client.rs b/crates/reqwest_client/src/reqwest_client.rs new file mode 100644 index 00000000..e20b9d20 --- /dev/null +++ b/crates/reqwest_client/src/reqwest_client.rs @@ -0,0 +1,344 @@ +use std::error::Error; +use std::sync::{LazyLock, OnceLock}; +use std::{any::type_name, borrow::Cow, mem, pin::Pin, task::Poll, time::Duration}; + +use anyhow::anyhow; +use bytes::{BufMut, Bytes, BytesMut}; +use futures::{AsyncRead, FutureExt as _, TryStreamExt as _}; +use http_client::{RedirectPolicy, Url, http}; +use regex::Regex; +use reqwest::{ + header::{HeaderMap, HeaderValue}, + redirect, +}; + +mod http_client_tls; + +const DEFAULT_CAPACITY: usize = 4096; +static RUNTIME: OnceLock = OnceLock::new(); +static REDACT_REGEX: LazyLock = LazyLock::new(|| Regex::new(r"key=[^&]+").unwrap()); + +pub struct ReqwestClient { + client: reqwest::Client, + proxy: Option, + user_agent: Option, + handle: tokio::runtime::Handle, +} + +impl ReqwestClient { + fn builder() -> reqwest::ClientBuilder { + reqwest::Client::builder() + .use_rustls_tls() + .connect_timeout(Duration::from_secs(10)) + } + + pub fn new() -> Self { + Self::builder() + .build() + .expect("Failed to initialize HTTP client") + .into() + } + + pub fn user_agent(agent: &str) -> anyhow::Result { + let mut map = HeaderMap::new(); + map.insert(http::header::USER_AGENT, HeaderValue::from_str(agent)?); + let client = Self::builder().default_headers(map).build()?; + Ok(client.into()) + } + + pub fn proxy_and_user_agent(proxy: Option, user_agent: &str) -> anyhow::Result { + let user_agent = HeaderValue::from_str(user_agent)?; + + let mut map = HeaderMap::new(); + map.insert(http::header::USER_AGENT, user_agent.clone()); + let mut client = Self::builder().default_headers(map); + let client_has_proxy; + + if let Some(proxy) = proxy.as_ref().and_then(|proxy_url| { + reqwest::Proxy::all(proxy_url.clone()) + .inspect_err(|e| { + log::error!( + "Failed to parse proxy URL '{}': {}", + proxy_url, + e.source().unwrap_or(&e as &_) + ) + }) + .ok() + }) { + // Respect NO_PROXY env var + client = client.proxy(proxy.no_proxy(reqwest::NoProxy::from_env())); + client_has_proxy = true; + } else { + client_has_proxy = false; + }; + + let client = client + .use_preconfigured_tls(http_client_tls::tls_config()) + .build()?; + let mut client: ReqwestClient = client.into(); + client.proxy = client_has_proxy.then_some(proxy).flatten(); + client.user_agent = Some(user_agent); + Ok(client) + } +} + +impl From for ReqwestClient { + fn from(client: reqwest::Client) -> Self { + let handle = tokio::runtime::Handle::try_current().unwrap_or_else(|_| { + log::debug!("no tokio runtime found, creating one for Reqwest..."); + let runtime = RUNTIME.get_or_init(|| { + tokio::runtime::Builder::new_multi_thread() + // Since we now have two executors, let's try to keep our footprint small + .worker_threads(1) + .enable_all() + .build() + .expect("Failed to initialize HTTP client") + }); + + runtime.handle().clone() + }); + Self { + client, + handle, + proxy: None, + user_agent: None, + } + } +} + +// This struct is essentially a re-implementation of +// https://docs.rs/tokio-util/0.7.12/tokio_util/io/struct.ReaderStream.html +// except outside of Tokio's aegis +struct StreamReader { + reader: Option>>, + buf: BytesMut, + capacity: usize, +} + +impl StreamReader { + fn new(reader: Pin>) -> Self { + Self { + reader: Some(reader), + buf: BytesMut::new(), + capacity: DEFAULT_CAPACITY, + } + } +} + +impl futures::Stream for StreamReader { + type Item = std::io::Result; + + fn poll_next( + mut self: Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> Poll> { + let mut this = self.as_mut(); + + let mut reader = match this.reader.take() { + Some(r) => r, + None => return Poll::Ready(None), + }; + + if this.buf.capacity() == 0 { + let capacity = this.capacity; + this.buf.reserve(capacity); + } + + match poll_read_buf(&mut reader, cx, &mut this.buf) { + Poll::Pending => Poll::Pending, + Poll::Ready(Err(err)) => { + self.reader = None; + + Poll::Ready(Some(Err(err))) + } + Poll::Ready(Ok(0)) => { + self.reader = None; + Poll::Ready(None) + } + Poll::Ready(Ok(_)) => { + let chunk = this.buf.split(); + self.reader = Some(reader); + Poll::Ready(Some(Ok(chunk.freeze()))) + } + } + } +} + +/// Implementation from +/// Specialized for this use case +pub fn poll_read_buf( + io: &mut Pin>, + cx: &mut std::task::Context<'_>, + buf: &mut BytesMut, +) -> Poll> { + if !buf.has_remaining_mut() { + return Poll::Ready(Ok(0)); + } + + let n = { + let dst = buf.chunk_mut(); + + // Safety: `chunk_mut()` returns a `&mut UninitSlice`, and `UninitSlice` is a + // transparent wrapper around `[MaybeUninit]`. + let dst = unsafe { &mut *(dst as *mut _ as *mut [std::mem::MaybeUninit]) }; + let mut buf = tokio::io::ReadBuf::uninit(dst); + let ptr = buf.filled().as_ptr(); + let unfilled_portion = buf.initialize_unfilled(); + // SAFETY: Pin projection + let io_pin = unsafe { Pin::new_unchecked(io) }; + std::task::ready!(io_pin.poll_read(cx, unfilled_portion)?); + + // Ensure the pointer does not change from under us + assert_eq!(ptr, buf.filled().as_ptr()); + buf.filled().len() + }; + + // Safety: This is guaranteed to be the number of initialized (and read) + // bytes due to the invariants provided by `ReadBuf::filled`. + unsafe { + buf.advance_mut(n); + } + + Poll::Ready(Ok(n)) +} + +fn redact_error(mut error: reqwest::Error) -> reqwest::Error { + if let Some(url) = error.url_mut() + && let Some(query) = url.query() + && let Cow::Owned(redacted) = REDACT_REGEX.replace_all(query, "key=REDACTED") + { + url.set_query(Some(redacted.as_str())); + } + error +} + +impl http_client::HttpClient for ReqwestClient { + fn proxy(&self) -> Option<&Url> { + self.proxy.as_ref() + } + + fn type_name(&self) -> &'static str { + type_name::() + } + + fn user_agent(&self) -> Option<&HeaderValue> { + self.user_agent.as_ref() + } + + fn send( + &self, + req: http::Request, + ) -> futures::future::BoxFuture< + 'static, + anyhow::Result>, + > { + let (parts, body) = req.into_parts(); + + let mut request = self.client.request(parts.method, parts.uri.to_string()); + request = request.headers(parts.headers); + if let Some(redirect_policy) = parts.extensions.get::() { + request = request.redirect_policy(match redirect_policy { + RedirectPolicy::NoFollow => redirect::Policy::none(), + RedirectPolicy::FollowLimit(limit) => redirect::Policy::limited(*limit as usize), + RedirectPolicy::FollowAll => redirect::Policy::limited(100), + }); + } + let request = request.body(match body.0 { + http_client::Inner::Empty => reqwest::Body::default(), + http_client::Inner::Bytes(cursor) => cursor.into_inner().into(), + http_client::Inner::AsyncReader(stream) => { + reqwest::Body::wrap_stream(StreamReader::new(stream)) + } + }); + + let handle = self.handle.clone(); + async move { + let mut response = handle + .spawn(async { request.send().await }) + .await? + .map_err(redact_error)?; + + let headers = mem::take(response.headers_mut()); + let mut builder = http::Response::builder() + .status(response.status().as_u16()) + .version(response.version()); + *builder.headers_mut().unwrap() = headers; + + let bytes = response + .bytes_stream() + .map_err(futures::io::Error::other) + .into_async_read(); + let body = http_client::AsyncBody::from_reader(bytes); + + builder.body(body).map_err(|e| anyhow!(e)) + } + .boxed() + } + + fn send_multipart_form<'a>( + &'a self, + url: &str, + form: reqwest::multipart::Form, + ) -> futures::future::BoxFuture<'a, anyhow::Result>> + { + let response = self.client.post(url).multipart(form).send(); + self.handle + .spawn(async move { + let response = response.await?; + let mut builder = http::response::Builder::new().status(response.status()); + for (k, v) in response.headers() { + builder = builder.header(k, v) + } + Ok(builder.body(response.bytes().await?.into())?) + }) + .map(|e| e?) + .boxed() + } +} + +#[cfg(test)] +mod tests { + use http_client::{HttpClient, Url}; + + use crate::ReqwestClient; + + #[test] + fn test_proxy_uri() { + let client = ReqwestClient::new(); + assert_eq!(client.proxy(), None); + + let proxy = Url::parse("http://localhost:10809").unwrap(); + let client = ReqwestClient::proxy_and_user_agent(Some(proxy.clone()), "test").unwrap(); + assert_eq!(client.proxy(), Some(&proxy)); + + let proxy = Url::parse("https://localhost:10809").unwrap(); + let client = ReqwestClient::proxy_and_user_agent(Some(proxy.clone()), "test").unwrap(); + assert_eq!(client.proxy(), Some(&proxy)); + + let proxy = Url::parse("socks4://localhost:10808").unwrap(); + let client = ReqwestClient::proxy_and_user_agent(Some(proxy.clone()), "test").unwrap(); + assert_eq!(client.proxy(), Some(&proxy)); + + let proxy = Url::parse("socks4a://localhost:10808").unwrap(); + let client = ReqwestClient::proxy_and_user_agent(Some(proxy.clone()), "test").unwrap(); + assert_eq!(client.proxy(), Some(&proxy)); + + let proxy = Url::parse("socks5://localhost:10808").unwrap(); + let client = ReqwestClient::proxy_and_user_agent(Some(proxy.clone()), "test").unwrap(); + assert_eq!(client.proxy(), Some(&proxy)); + + let proxy = Url::parse("socks5h://localhost:10808").unwrap(); + let client = ReqwestClient::proxy_and_user_agent(Some(proxy.clone()), "test").unwrap(); + assert_eq!(client.proxy(), Some(&proxy)); + } + + #[test] + fn test_invalid_proxy_uri() { + let proxy = Url::parse("socks://127.0.0.1:20170").unwrap(); + let client = ReqwestClient::proxy_and_user_agent(Some(proxy), "test").unwrap(); + assert!( + client.proxy.is_none(), + "An invalid proxy URL should add no proxy to the client!" + ) + } +} diff --git a/crates/story/Cargo.toml b/crates/story/Cargo.toml index b94a7f4f..91b0a9b2 100644 --- a/crates/story/Cargo.toml +++ b/crates/story/Cargo.toml @@ -1,20 +1,20 @@ [package] -edition = "2021" name = "story" +edition = "2024" publish = false -version = "0.1.0" +version = "0.2.0-test2" [dependencies] anyhow.workspace = true gpui.workspace = true gpui-component = { workspace = true, features = ["webview", "tree-sitter-languages"] } +reqwest_client = { path = "../reqwest_client" } chrono = "0.4" fake = { version = "2.10.0", features = ["dummy"] } rand = "0.8" raw-window-handle = { version = "0.6", features = ["std"] } regex = "1" -reqwest_client.workspace = true smol.workspace = true rust-embed = { version = "8.7.2", features = ["interpolate-folder-path"] } serde = "1" diff --git a/crates/story/src/drawer_story.rs b/crates/story/src/drawer_story.rs index 53b0bed4..31fb90f4 100644 --- a/crates/story/src/drawer_story.rs +++ b/crates/story/src/drawer_story.rs @@ -2,13 +2,14 @@ use std::{sync::Arc, time::Duration}; use fake::Fake; use gpui::{ - div, prelude::FluentBuilder as _, px, App, AppContext, Context, Entity, FocusHandle, Focusable, - InteractiveElement as _, IntoElement, ParentElement, Render, SharedString, Styled, Task, Timer, - WeakEntity, Window, + App, AppContext, Context, Entity, FocusHandle, Focusable, InteractiveElement as _, IntoElement, + ParentElement, Render, SharedString, Styled, Task, Timer, WeakEntity, Window, div, + prelude::FluentBuilder as _, px, }; use raw_window_handle::HasWindowHandle; use gpui_component::{ + ActiveTheme as _, ContextModal as _, Icon, IconName, IndexPath, Placement, button::{Button, ButtonVariant, ButtonVariants as _}, checkbox::Checkbox, date_picker::{DatePicker, DatePickerState}, @@ -17,11 +18,11 @@ use gpui_component::{ list::{List, ListDelegate, ListItem}, v_flex, webview::WebView, - wry, ActiveTheme as _, ContextModal as _, Icon, IconName, IndexPath, Placement, + wry, }; use crate::TestAction; -use crate::{section, Story}; +use crate::{Story, section}; pub struct ListItemDeletegate { story: WeakEntity, diff --git a/crates/story/src/webview_story.rs b/crates/story/src/webview_story.rs index 9294ee13..82876638 100644 --- a/crates/story/src/webview_story.rs +++ b/crates/story/src/webview_story.rs @@ -1,13 +1,13 @@ use gpui::{ - div, App, AppContext, ClickEvent, Context, Entity, FocusHandle, Focusable, IntoElement, - ParentElement as _, Render, Styled as _, Window, + App, AppContext, ClickEvent, Context, Entity, FocusHandle, Focusable, IntoElement, + ParentElement as _, Render, Styled as _, Window, div, }; use gpui_component::{ - h_flex, + ActiveTheme, h_flex, input::{InputEvent, InputState, TextInput}, v_flex, webview::WebView, - wry, ActiveTheme, + wry, }; pub fn init(_: &mut App) { diff --git a/crates/ui/Cargo.toml b/crates/ui/Cargo.toml index a1820923..67881f4f 100644 --- a/crates/ui/Cargo.toml +++ b/crates/ui/Cargo.toml @@ -1,12 +1,13 @@ [package] +name = "gpui-component" description = "UI components for building fantastic desktop application by using GPUI." edition = "2021" homepage = "https://github.com/longbridge/gpui-component" -keywords = ["GPUI", "application", "desktop", "ui"] -license-file = "LICENSE-APACHE" -name = "gpui-component" +keywords = ["gpui", "uikit", "shadcn", "desktop", "ui"] publish = true -version = "0.1.0" +version = "0.2.0-test2" +readme = "../../README.md" +license-file = "LICENSE-APACHE" [lib] doctest = false @@ -50,7 +51,7 @@ tree-sitter-languages = [ [dependencies] anyhow.workspace = true gpui = { workspace = true } -gpui-component-macros.workspace = true +gpui-component-macros = { workspace = true } gpui-macros.workspace = true notify.workspace = true ropey.workspace = true @@ -62,7 +63,7 @@ serde_repr.workspace = true smallvec.workspace = true smol.workspace = true tracing.workspace = true -zed-sum-tree.workspace = true +sum-tree.workspace = true enum-iterator = "2.1.0" itertools = "0.13.0" @@ -73,7 +74,7 @@ unicode-segmentation = "1.12.0" uuid = "1.10" # WebView -wry = { git = "https://github.com/longbridge/wry", optional = true } +wry = { version = "0.53.3", package = "lb-wry", optional = true } # Chart num-traits = "0.2" @@ -110,7 +111,7 @@ tree-sitter-javascript = { version = "0.23.1", optional = true } tree-sitter-jsdoc = { version = "0.23.2", optional = true } tree-sitter-json = "0.24.8" tree-sitter-make = { version = "1.1.1", optional = true } -tree-sitter-md = { git = "https://github.com/tree-sitter-grammars/tree-sitter-markdown", tag = "v0.5.0", optional = true } +tree-sitter-md = { version = "0.5.1", optional = true } tree-sitter-proto = { version = "0.2.0", optional = true } tree-sitter-python = { version = "0.23.6", optional = true } tree-sitter-ruby = { version = "0.23.1", optional = true } diff --git a/crates/ui/src/highlighter/diagnostics.rs b/crates/ui/src/highlighter/diagnostics.rs index e2d05816..56d0cabd 100644 --- a/crates/ui/src/highlighter/diagnostics.rs +++ b/crates/ui/src/highlighter/diagnostics.rs @@ -6,7 +6,7 @@ use std::{ use gpui::{px, App, HighlightStyle, Hsla, SharedString, UnderlineStyle}; use ropey::Rope; -use zed_sum_tree::{Bias, SeekTarget, SumTree}; +use sum_tree::{Bias, SeekTarget, SumTree}; use crate::{ input::{Position, RopeExt as _}, @@ -199,7 +199,7 @@ pub struct DiagnosticSummary { end: usize, } -impl zed_sum_tree::Item for DiagnosticEntry { +impl sum_tree::Item for DiagnosticEntry { type Summary = DiagnosticSummary; fn summary(&self, _cx: &()) -> Self::Summary { DiagnosticSummary { @@ -210,7 +210,7 @@ impl zed_sum_tree::Item for DiagnosticEntry { } } -impl zed_sum_tree::Summary for DiagnosticSummary { +impl sum_tree::Summary for DiagnosticSummary { type Context<'a> = &'a (); fn zero(_: Self::Context<'_>) -> Self { DiagnosticSummary { diff --git a/crates/ui/src/highlighter/highlighter.rs b/crates/ui/src/highlighter/highlighter.rs index f0c9aaff..75a278ee 100644 --- a/crates/ui/src/highlighter/highlighter.rs +++ b/crates/ui/src/highlighter/highlighter.rs @@ -10,10 +10,10 @@ use std::{ ops::Range, usize, }; +use sum_tree::Bias; use tree_sitter::{ InputEdit, Node, Parser, Point, Query, QueryCursor, QueryMatch, StreamingIterator, Tree, }; -use zed_sum_tree::Bias; /// A syntax highlighter that supports incremental parsing, multiline text, /// and caching of highlight results. @@ -102,7 +102,7 @@ impl HighlightItem { } } -impl zed_sum_tree::Item for HighlightItem { +impl sum_tree::Item for HighlightItem { type Summary = HighlightSummary; fn summary(&self, _cx: &()) -> Self::Summary { HighlightSummary { @@ -115,7 +115,7 @@ impl zed_sum_tree::Item for HighlightItem { } } -impl zed_sum_tree::Summary for HighlightSummary { +impl sum_tree::Summary for HighlightSummary { type Context<'a> = &'a (); fn zero(_: Self::Context<'_>) -> Self { HighlightSummary { @@ -136,7 +136,7 @@ impl zed_sum_tree::Summary for HighlightSummary { } } -impl<'a> zed_sum_tree::Dimension<'a, HighlightSummary> for usize { +impl<'a> sum_tree::Dimension<'a, HighlightSummary> for usize { fn zero(_: &()) -> Self { 0 } @@ -144,7 +144,7 @@ impl<'a> zed_sum_tree::Dimension<'a, HighlightSummary> for usize { fn add_summary(&mut self, _: &'a HighlightSummary, _: &()) {} } -impl<'a> zed_sum_tree::Dimension<'a, HighlightSummary> for Range { +impl<'a> sum_tree::Dimension<'a, HighlightSummary> for Range { fn zero(_: &()) -> Self { Default::default() } diff --git a/crates/ui/src/input/rope_ext.rs b/crates/ui/src/input/rope_ext.rs index 65bcc718..8106abbf 100644 --- a/crates/ui/src/input/rope_ext.rs +++ b/crates/ui/src/input/rope_ext.rs @@ -1,8 +1,8 @@ use std::ops::Range; use ropey::{LineType, Rope, RopeSlice}; +use sum_tree::Bias; use tree_sitter::Point; -use zed_sum_tree::Bias; use crate::input::Position; @@ -208,7 +208,7 @@ pub trait RopeExt { /// /// ``` /// use gpui_component::input::{Rope, RopeExt}; - /// use zed_sum_tree::Bias; + /// use sum_tree::Bias; /// /// let rope = Rope::from("Hello δΈ­ζ–‡πŸŽ‰ test\nRope"); /// assert_eq!(rope.clip_offset(5, Bias::Left), 5); @@ -393,8 +393,8 @@ impl RopeExt for Rope { #[cfg(test)] mod tests { use ropey::Rope; + use sum_tree::Bias; use tree_sitter::Point; - use zed_sum_tree::Bias; use crate::input::{Position, RopeExt}; diff --git a/crates/ui/src/input/state.rs b/crates/ui/src/input/state.rs index e39e2849..b6c151d1 100644 --- a/crates/ui/src/input/state.rs +++ b/crates/ui/src/input/state.rs @@ -15,8 +15,8 @@ use serde::Deserialize; use std::cell::RefCell; use std::ops::Range; use std::rc::Rc; +use sum_tree::Bias; use unicode_segmentation::*; -use zed_sum_tree::Bias; use super::{ blink_cursor::BlinkCursor, diff --git a/themes/default.json b/crates/ui/src/theme/default-theme.json similarity index 100% rename from themes/default.json rename to crates/ui/src/theme/default-theme.json diff --git a/crates/ui/src/theme/registry.rs b/crates/ui/src/theme/registry.rs index ee15747a..d0e54e7c 100644 --- a/crates/ui/src/theme/registry.rs +++ b/crates/ui/src/theme/registry.rs @@ -10,7 +10,7 @@ use std::{ sync::{Arc, LazyLock}, }; -const DEFAULT_THEME: &str = include_str!("../../../../themes/default.json"); +const DEFAULT_THEME: &str = include_str!("./default-theme.json"); pub(crate) const DEFAULT_THEME_COLORS: LazyLock< HashMap, Arc)>, > = LazyLock::new(|| { @@ -243,6 +243,11 @@ impl ThemeRegistry { } self.themes.clear(); + for theme in self.default_themes.values() { + self.themes + .insert(theme.name.clone(), Rc::new((**theme).clone())); + } + for theme in themes.iter() { if self.themes.contains_key(&theme.name) { continue;