diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3fc708af4..378cfdf67 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -50,17 +50,14 @@ jobs: platform: linux arch: x64 regular_build: 'true' - cross: true - os: ubuntu-20.04 rust-target: aarch64-unknown-linux-gnu platform: linux arch: arm64 - cross: true - os: ubuntu-20.04 rust-target: arm-unknown-linux-gnueabihf platform: linux arch: armhf - cross: true - os: macos-13 rust-target: x86_64-apple-darwin platform: darwin @@ -112,20 +109,29 @@ jobs: with: targets: ${{ matrix.rust-target }} if: (fromJson(env.isRelease) || fromJson(env.isNightly)) + - name: Install llvm + if: matrix.platform == 'linux' && (fromJson(env.isRelease) || fromJson(env.isNightly)) + run: | + sudo apt-get update + sudo apt-get install llvm + - name: Install AArch64 target toolchain + if: matrix.rust-target == 'aarch64-unknown-linux-gnu' && (fromJson(env.isRelease) || fromJson(env.isNightly)) + run: | + sudo apt-get update + sudo apt-get install gcc-aarch64-linux-gnu + - name: Install ARM target toolchain + if: matrix.rust-target == 'arm-unknown-linux-gnueabihf' && (fromJson(env.isRelease) || fromJson(env.isNightly)) + run: | + sudo apt-get update + sudo apt-get install gcc-arm-linux-gnueabihf - name: Run rust-cache uses: Swatinem/rust-cache@v2 if: (fromJson(env.isRelease) || fromJson(env.isNightly)) - - name: Build tinymist binary (cross) - shell: pwsh - run: | - cargo install cross --git https://github.com/cross-rs/cross.git --locked --rev 085092ca - cross build --profile=gh-release -p tinymist --target ${{ matrix.rust-target }} --features vendor-openssl - if: matrix.cross && (startsWith(github.ref, 'refs/tags/') || matrix.regular_build == 'true') - name: Build tinymist binary shell: pwsh run: | cargo build --profile=gh-release -p tinymist --target ${{ matrix.rust-target }} - if: "!matrix.cross && (startsWith(github.ref, 'refs/tags/') || matrix.regular_build == 'true')" + if: startsWith(github.ref, 'refs/tags/') || matrix.regular_build == 'true' - name: Rename debug symbols for windows if: matrix.platform == 'win32' && (fromJson(env.isRelease) || fromJson(env.isNightly)) run: | diff --git a/.vscode/settings.json b/.vscode/settings.json index d702ca1df..146ca633c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,4 +6,7 @@ "tinymist.fontPaths": [ "assets/fonts" ], + "files.watcherExclude": { + "**/target": true + }, } diff --git a/Cargo.lock b/Cargo.lock index 1cbfed29f..7ccf2de44 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -220,6 +220,12 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + [[package]] name = "base64" version = "0.22.1" @@ -1056,16 +1062,6 @@ dependencies = [ "log", ] -[[package]] -name = "env_proxy" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a5019be18538406a43b5419a5501461f0c8b49ea7dfda0cfc32f4e51fc44be1" -dependencies = [ - "log", - "url", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -1370,6 +1366,25 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap 2.6.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "h2" version = "0.4.6" @@ -1381,7 +1396,7 @@ dependencies = [ "fnv", "futures-core", "futures-sink", - "http", + "http 1.1.0", "indexmap 2.6.0", "slab", "tokio", @@ -1478,6 +1493,17 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http" version = "1.1.0" @@ -1489,6 +1515,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http 0.2.12", + "pin-project-lite", +] + [[package]] name = "http-body" version = "1.0.1" @@ -1496,7 +1533,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http", + "http 1.1.0", ] [[package]] @@ -1507,8 +1544,8 @@ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", "futures-util", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.1", "pin-project-lite", ] @@ -1530,6 +1567,30 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "hyper" +version = "0.14.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + [[package]] name = "hyper" version = "1.5.0" @@ -1539,9 +1600,9 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2", - "http", - "http-body", + "h2 0.4.6", + "http 1.1.0", + "http-body 1.0.1", "httparse", "httpdate", "itoa", @@ -1551,6 +1612,20 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http 0.2.12", + "hyper 0.14.31", + "rustls 0.21.12", + "tokio", + "tokio-rustls 0.24.1", +] + [[package]] name = "hyper-rustls" version = "0.27.3" @@ -1558,15 +1633,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", - "http", - "hyper", + "http 1.1.0", + "hyper 1.5.0", "hyper-util", - "rustls", + "rustls 0.23.16", "rustls-pki-types", "tokio", - "tokio-rustls", + "tokio-rustls 0.26.0", "tower-service", - "webpki-roots", + "webpki-roots 0.26.6", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper 0.14.31", + "native-tls", + "tokio", + "tokio-native-tls", ] [[package]] @@ -1577,7 +1665,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper", + "hyper 1.5.0", "hyper-util", "native-tls", "tokio", @@ -1592,7 +1680,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69ce21dae6ce6e5f336a444d846e592faf42c5c28f70a5c8ff67893cbcb304d3" dependencies = [ "http-body-util", - "hyper", + "hyper 1.5.0", "hyper-util", "pin-project-lite", "tokio", @@ -1609,9 +1697,9 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http", - "http-body", - "hyper", + "http 1.1.0", + "http-body 1.0.1", + "hyper 1.5.0", "pin-project-lite", "socket2", "tokio", @@ -2414,15 +2502,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" -[[package]] -name = "openssl-src" -version = "300.4.1+3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faa4eac4138c62414b5622d1b31c5c304f34b406b013c079c2bbc652fdd6678c" -dependencies = [ - "cc", -] - [[package]] name = "openssl-sys" version = "0.9.104" @@ -2431,7 +2510,6 @@ checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" dependencies = [ "cc", "libc", - "openssl-src", "pkg-config", "vcpkg", ] @@ -2606,7 +2684,7 @@ version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016" dependencies = [ - "base64", + "base64 0.22.1", "indexmap 2.6.0", "quick-xml 0.32.0", "serde", @@ -2764,7 +2842,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash 2.0.0", - "rustls", + "rustls 0.23.16", "socket2", "thiserror 2.0.3", "tokio", @@ -2782,7 +2860,7 @@ dependencies = [ "rand", "ring", "rustc-hash 2.0.0", - "rustls", + "rustls 0.23.16", "rustls-pki-types", "slab", "thiserror 2.0.3", @@ -2896,7 +2974,7 @@ version = "0.5.0-rc9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f73eee207a7d665262f6b3930ede406b7db2e946bf4d2da71e9f7d52436e3e9" dependencies = [ - "base64", + "base64 0.22.1", "bitvec", "comemo 0.4.0", "dashmap", @@ -2988,7 +3066,7 @@ version = "0.5.0-rc9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47518e908a003bb1b2c3d9d45f38903b745306868bfe9755fbec10d2cdd7c5f0" dependencies = [ - "base64", + "base64 0.22.1", "comemo 0.4.0", "log", "reflexo", @@ -3030,7 +3108,7 @@ dependencies = [ "reflexo", "reflexo-typst-shim", "reflexo-vfs", - "reqwest", + "reqwest 0.12.9", "serde", "serde_json", "serde_with", @@ -3078,23 +3156,68 @@ dependencies = [ "bytecheck", ] +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.31", + "hyper-rustls 0.24.2", + "hyper-tls 0.5.0", + "ipnet", + "js-sys", + "log", + "mime", + "mime_guess", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls 0.21.12", + "rustls-pemfile 1.0.4", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 0.1.2", + "system-configuration", + "tokio", + "tokio-native-tls", + "tokio-rustls 0.24.1", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots 0.25.4", + "winreg", +] + [[package]] name = "reqwest" version = "0.12.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "futures-channel", "futures-core", "futures-util", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.1", "http-body-util", - "hyper", - "hyper-rustls", - "hyper-tls", + "hyper 1.5.0", + "hyper-rustls 0.27.3", + "hyper-tls 0.6.0", "hyper-util", "ipnet", "js-sys", @@ -3106,22 +3229,22 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls", - "rustls-pemfile", + "rustls 0.23.16", + "rustls-pemfile 2.2.0", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper", + "sync_wrapper 1.0.1", "tokio", "tokio-native-tls", - "tokio-rustls", + "tokio-rustls 0.26.0", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots", + "webpki-roots 0.26.6", "windows-registry", ] @@ -3289,6 +3412,18 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustls" +version = "0.21.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "log", + "ring", + "rustls-webpki 0.101.7", + "sct", +] + [[package]] name = "rustls" version = "0.23.16" @@ -3298,11 +3433,20 @@ dependencies = [ "once_cell", "ring", "rustls-pki-types", - "rustls-webpki", + "rustls-webpki 0.102.8", "subtle", "zeroize", ] +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + [[package]] name = "rustls-pemfile" version = "2.2.0" @@ -3321,6 +3465,16 @@ dependencies = [ "web-time", ] +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "rustls-webpki" version = "0.102.8" @@ -3386,6 +3540,16 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "seahash" version = "4.1.0" @@ -3494,7 +3658,7 @@ version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e28bdad6db2b8340e449f7108f020b3b092e8583a9e3fb82713e1d4e71fe817" dependencies = [ - "base64", + "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", @@ -3780,7 +3944,7 @@ dependencies = [ [[package]] name = "sync-lsp" -version = "0.12.4-rc2" +version = "0.12.4-rc3" dependencies = [ "anyhow", "clap", @@ -3798,6 +3962,12 @@ dependencies = [ "tokio-util", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "sync_wrapper" version = "1.0.1" @@ -3840,6 +4010,27 @@ dependencies = [ "yaml-rust", ] +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tap" version = "1.0.1" @@ -3902,7 +4093,7 @@ dependencies = [ [[package]] name = "tests" -version = "0.12.4-rc2" +version = "0.12.4-rc3" dependencies = [ "insta", "lsp-server", @@ -4025,11 +4216,11 @@ dependencies = [ [[package]] name = "tinymist" -version = "0.12.4-rc2" +version = "0.12.4-rc3" dependencies = [ "anyhow", "async-trait", - "base64", + "base64 0.22.1", "cargo_metadata", "chrono", "clap", @@ -4046,7 +4237,7 @@ dependencies = [ "env_logger", "futures", "http-body-util", - "hyper", + "hyper 1.5.0", "hyper-tungstenite", "hyper-util", "itertools 0.13.0", @@ -4066,7 +4257,7 @@ dependencies = [ "serde_yaml", "strum", "sync-lsp", - "tinymist-assets 0.12.4-rc2 (registry+https://github.com/rust-lang/crates.io-index)", + "tinymist-assets 0.12.4-rc3 (registry+https://github.com/rust-lang/crates.io-index)", "tinymist-query", "tinymist-render", "tinymist-world", @@ -4077,7 +4268,6 @@ dependencies = [ "typst", "typst-ansi-hl", "typst-assets", - "typst-kit", "typst-pdf", "typst-preview", "typst-render", @@ -4093,9 +4283,9 @@ dependencies = [ [[package]] name = "tinymist-analysis" -version = "0.12.4-rc2" +version = "0.12.4-rc3" dependencies = [ - "base64", + "base64 0.22.1", "comemo 0.4.0", "ecow 0.2.3", "insta", @@ -4110,17 +4300,17 @@ dependencies = [ [[package]] name = "tinymist-assets" -version = "0.12.4-rc2" +version = "0.12.4-rc3" [[package]] name = "tinymist-assets" -version = "0.12.4-rc2" +version = "0.12.4-rc3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f15b9924413b373fadf822c5a1c9dab36e5083a3e71471fb24a895bd1a2522" +checksum = "3b22a7eddabeb6a407eb0cfef448f8fa84dde19284bbd14b7ee727337557218f" [[package]] name = "tinymist-derive" -version = "0.12.4-rc2" +version = "0.12.4-rc3" dependencies = [ "quote", "syn 2.0.87", @@ -4128,10 +4318,10 @@ dependencies = [ [[package]] name = "tinymist-query" -version = "0.12.4-rc2" +version = "0.12.4-rc3" dependencies = [ "anyhow", - "base64", + "base64 0.22.1", "biblatex 0.9.3", "chrono", "comemo 0.4.0", @@ -4182,9 +4372,9 @@ dependencies = [ [[package]] name = "tinymist-render" -version = "0.12.4-rc2" +version = "0.12.4-rc3" dependencies = [ - "base64", + "base64 0.22.1", "log", "reflexo-vec2svg", "serde", @@ -4193,23 +4383,25 @@ dependencies = [ [[package]] name = "tinymist-world" -version = "0.12.4-rc2" +version = "0.12.4-rc3" dependencies = [ "anyhow", "chrono", "clap", "comemo 0.4.0", "dirs", + "flate2", "log", "parking_lot", "reflexo-typst", "reflexo-typst-shim", + "reqwest 0.11.27", "serde", "serde_json", - "tinymist-assets 0.12.4-rc2 (registry+https://github.com/rust-lang/crates.io-index)", + "tar", + "tinymist-assets 0.12.4-rc3 (registry+https://github.com/rust-lang/crates.io-index)", "typst", "typst-assets", - "typst-kit", ] [[package]] @@ -4277,13 +4469,23 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.12", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls", + "rustls 0.23.16", "rustls-pki-types", "tokio", ] @@ -4446,7 +4648,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http", + "http 1.1.0", "httparse", "log", "rand", @@ -4491,9 +4693,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "typlite" -version = "0.12.4-rc2" +version = "0.12.4-rc3" dependencies = [ - "base64", + "base64 0.22.1", "comemo 0.4.0", "ecow 0.2.3", "insta", @@ -4513,7 +4715,6 @@ dependencies = [ "ecow 0.2.3", "tinymist-world", "typlite", - "typst-kit", ] [[package]] @@ -4605,26 +4806,6 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fe00da1b24da2c4a7da532fc33d0c3bd43a902ca4c408ee2c36eabe70f2f4ba" -[[package]] -name = "typst-kit" -version = "0.12.0" -source = "git+https://github.com/Myriad-Dreamin/typst.git?tag=tinymist-v0.12.0#58426a90a7ef721738a01be09793d33e55eb75a9" -dependencies = [ - "dirs", - "ecow 0.2.3", - "env_proxy", - "flate2", - "fontdb", - "native-tls", - "once_cell", - "openssl", - "tar", - "typst", - "typst-timing", - "typst-utils", - "ureq", -] - [[package]] name = "typst-macros" version = "0.12.0" @@ -4642,7 +4823,7 @@ version = "0.12.0" source = "git+https://github.com/Myriad-Dreamin/typst.git?tag=tinymist-v0.12.0#58426a90a7ef721738a01be09793d33e55eb75a9" dependencies = [ "arrayvec 0.7.6", - "base64", + "base64 0.22.1", "bytemuck", "comemo 0.4.0", "ecow 0.2.3", @@ -4665,7 +4846,7 @@ dependencies = [ [[package]] name = "typst-preview" -version = "0.12.4-rc2" +version = "0.12.4-rc3" dependencies = [ "clap", "comemo 0.4.0", @@ -4678,7 +4859,7 @@ dependencies = [ "reflexo-vec2svg", "serde", "serde_json", - "tinymist-assets 0.12.4-rc2 (registry+https://github.com/rust-lang/crates.io-index)", + "tinymist-assets 0.12.4-rc3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio", "typst", "typst-assets", @@ -4705,7 +4886,7 @@ dependencies = [ [[package]] name = "typst-shim" -version = "0.12.4-rc2" +version = "0.12.4-rc3" dependencies = [ "cfg-if", "typst", @@ -4717,7 +4898,7 @@ name = "typst-svg" version = "0.12.0" source = "git+https://github.com/Myriad-Dreamin/typst.git?tag=tinymist-v0.12.0#58426a90a7ef721738a01be09793d33e55eb75a9" dependencies = [ - "base64", + "base64 0.22.1", "comemo 0.4.0", "ecow 0.2.3", "flate2", @@ -4948,22 +5129,6 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" -[[package]] -name = "ureq" -version = "2.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b74fc6b57825be3373f7054754755f03ac3a8f5d70015ccad699ba2029956f4a" -dependencies = [ - "base64", - "flate2", - "log", - "native-tls", - "once_cell", - "serde", - "serde_json", - "url", -] - [[package]] name = "url" version = "2.5.3" @@ -4982,7 +5147,7 @@ version = "0.43.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6803057b5cbb426e9fb8ce2216f3a9b4ca1dd2c705ba3cbebc13006e437735fd" dependencies = [ - "base64", + "base64 0.22.1", "data-url", "flate2", "fontdb", @@ -5221,6 +5386,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + [[package]] name = "webpki-roots" version = "0.26.6" @@ -5472,6 +5643,16 @@ dependencies = [ "memchr", ] +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "write16" version = "1.0.0" diff --git a/Cargo.toml b/Cargo.toml index f4d6f558d..4d2d29a63 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [workspace.package] description = "An integrated language service for Typst." authors = ["Myriad-Dreamin ", "Nathan Varner"] -version = "0.12.4-rc2" +version = "0.12.4-rc3" edition = "2021" readme = "README.md" license = "Apache-2.0" @@ -104,7 +104,6 @@ reflexo-typst-shim = { version = "0.5.0-rc9", features = ["nightly"] } typst = "0.12.0" -typst-kit = "0.12.0" typst-timing = "0.12.0" typst-svg = "0.12.0" typst-render = "0.12.0" @@ -145,7 +144,7 @@ insta = { version = "1.39", features = ["glob"] } # Our Own Crates typst-preview = { path = "./crates/typst-preview" } -tinymist-assets = { version = "0.12.4-rc2" } +tinymist-assets = { version = "0.12.4-rc3" } tinymist = { path = "./crates/tinymist/" } tinymist-derive = { path = "./crates/tinymist-derive/" } tinymist-analysis = { path = "./crates/tinymist-analysis/" } @@ -183,7 +182,6 @@ undocumented_unsafe_blocks = "warn" # tinymist-assets = { path = "./crates/tinymist-assets/" } typst = { git = "https://github.com/Myriad-Dreamin/typst.git", tag = "tinymist-v0.12.0" } -typst-kit = { git = "https://github.com/Myriad-Dreamin/typst.git", tag = "tinymist-v0.12.0" } typst-timing = { git = "https://github.com/Myriad-Dreamin/typst.git", tag = "tinymist-v0.12.0" } typst-svg = { git = "https://github.com/Myriad-Dreamin/typst.git", tag = "tinymist-v0.12.0" } typst-render = { git = "https://github.com/Myriad-Dreamin/typst.git", tag = "tinymist-v0.12.0" } diff --git a/contrib/typlite/Cargo.toml b/contrib/typlite/Cargo.toml index 788278a37..407b43590 100644 --- a/contrib/typlite/Cargo.toml +++ b/contrib/typlite/Cargo.toml @@ -13,14 +13,8 @@ repository.workspace = true name = "typlite" path = "src/main.rs" -[features] - -# Whether to vendor OpenSSL. Not applicable to Windows and macOS builds. -vendor-openssl = ["typst-kit/vendor-openssl"] - [dependencies] typlite.workspace = true clap.workspace = true tinymist-world.workspace = true ecow.workspace = true -typst-kit.workspace = true diff --git a/crates/tinymist-query/src/package.rs b/crates/tinymist-query/src/package.rs index 5faaee471..d5024005c 100644 --- a/crates/tinymist-query/src/package.rs +++ b/crates/tinymist-query/src/package.rs @@ -8,7 +8,7 @@ use parking_lot::Mutex; use reflexo_typst::typst::prelude::*; use reflexo_typst::{package::PackageSpec, TypstFileId}; use serde::{Deserialize, Serialize}; -use tinymist_world::package::HttpsRegistry; +use tinymist_world::https::HttpsRegistry; use typst::diag::{EcoString, StrResult}; use typst::syntax::package::PackageManifest; use typst::syntax::VirtualPath; diff --git a/crates/tinymist-query/src/tests.rs b/crates/tinymist-query/src/tests.rs index 84a26dd0d..74216d918 100644 --- a/crates/tinymist-query/src/tests.rs +++ b/crates/tinymist-query/src/tests.rs @@ -131,7 +131,6 @@ pub fn run_with_sources(source: &str, f: impl FnOnce(&mut LspUniverse, PathBu }; let mut world = LspUniverseBuilder::build( EntryState::new_rooted(root.as_path().into(), None), - Default::default(), Arc::new( LspUniverseBuilder::resolve_fonts(CompileFontArgs { ignore_system_fonts: true, @@ -139,7 +138,8 @@ pub fn run_with_sources(source: &str, f: impl FnOnce(&mut LspUniverse, PathBu }) .unwrap(), ), - LspUniverseBuilder::resolve_package(None, None), + Default::default(), + None, ) .unwrap(); let sources = source.split("-----"); diff --git a/crates/tinymist-world/Cargo.toml b/crates/tinymist-world/Cargo.toml index b43f337c9..d8744c175 100644 --- a/crates/tinymist-world/Cargo.toml +++ b/crates/tinymist-world/Cargo.toml @@ -23,13 +23,28 @@ log.workspace = true reflexo-typst.workspace = true reflexo-typst-shim = { workspace = true, features = ["nightly"] } typst.workspace = true -typst-kit.workspace = true tinymist-assets = { workspace = true } typst-assets = { workspace = true, features = ["fonts"] } dirs.workspace = true parking_lot.workspace = true +flate2 = "1" +tar = "0.4" + +[target.'cfg(not(any(target_arch = "riscv64", target_arch = "wasm32", all(target_os = "windows", target_arch = "aarch64"))))'.dependencies] +reqwest = { version = "^0.11", default-features = false, features = [ + "rustls-tls", + "blocking", + "multipart", +] } + +[target.'cfg(any(target_arch = "riscv64", all(target_os = "windows", target_arch = "aarch64")))'.dependencies] +reqwest = { version = "^0.11", default-features = false, features = [ + "native-tls", + "blocking", + "multipart", +] } [features] no-content-hint = ["reflexo-typst/no-content-hint"] diff --git a/crates/tinymist-world/src/https.rs b/crates/tinymist-world/src/https.rs new file mode 100644 index 000000000..dd58cdb74 --- /dev/null +++ b/crates/tinymist-world/src/https.rs @@ -0,0 +1,257 @@ +//! Https registry for tinymist. + +use std::path::Path; +use std::sync::OnceLock; +use std::{path::PathBuf, sync::Arc}; + +use log::error; +use parking_lot::Mutex; +use reflexo_typst::package::{DummyNotifier, Notifier, PackageError, PackageRegistry, PackageSpec}; +use reflexo_typst::typst::{ + diag::{eco_format, EcoString}, + syntax::package::PackageVersion, +}; +use reqwest::{blocking::Response, Certificate}; + +/// The http registry without typst.ts to implement more for tinymist. +pub struct HttpsRegistry { + notifier: Arc>, + + packages: OnceLock)>>, + + cert_path: Option, + + data_dir_cache: OnceLock>>, + cache_dir_cache: OnceLock>>, + // package_dir_cache: RwLock, PackageError>>>, +} + +impl Default for HttpsRegistry { + fn default() -> Self { + Self { + notifier: Arc::new(Mutex::::default()), + + // todo: reset cache + packages: OnceLock::new(), + + // Default to None + cert_path: None, + + data_dir_cache: OnceLock::new(), + cache_dir_cache: OnceLock::new(), + // package_dir_cache: RwLock::new(HashMap::new()), + } + } +} + +impl HttpsRegistry { + /// Create a new registry. + pub fn new(cert_path: Option) -> Self { + Self { + cert_path, + ..Default::default() + } + } + + /// Get local path option + pub fn local_path(&self) -> Option> { + if let Some(data_dir) = self.data_dir() { + if data_dir.exists() { + return Some(data_dir.join("typst/packages").into()); + } + } + + None + } + + fn data_dir(&self) -> Option<&Arc> { + self.data_dir_cache + .get_or_init(|| dirs::data_dir().map(From::from)) + .as_ref() + } + + fn cache_dir(&self) -> Option<&Arc> { + self.cache_dir_cache + .get_or_init(|| dirs::cache_dir().map(From::from)) + .as_ref() + } + + /// Get data & cache dir + pub fn paths(&self) -> Vec> { + let mut res = vec![]; + if let Some(data_dir) = self.data_dir() { + let dir: Box = data_dir.join("typst/packages").into(); + if dir.exists() { + res.push(dir); + } + } + + if let Some(cache_dir) = self.cache_dir() { + let dir: Box = cache_dir.join("typst/packages").into(); + if dir.exists() { + res.push(dir); + } + } + + res + } + + /// Make a package available in the on-disk cache. + pub fn prepare_package(&self, spec: &PackageSpec) -> Result, PackageError> { + // let cache = self.package_dir_cache.read(); + // if let Some(dir) = cache.get(spec) { + // return dir.clone(); + // } + + // drop(cache); + // let mut cache = self.package_dir_cache.write(); + // if let Some(dir) = cache.get(spec) { + // return dir.clone(); + // } + + // let dir = self.prepare_package_(spec); + // cache.insert(spec.clone(), dir.clone()); + // dir + self.prepare_package_(spec) + } + + /// Make a package available in the on-disk cache. + pub fn prepare_package_(&self, spec: &PackageSpec) -> Result, PackageError> { + let subdir = format!( + "typst/packages/{}/{}/{}", + spec.namespace, spec.name, spec.version + ); + + if let Some(data_dir) = self.data_dir() { + let dir = data_dir.join(&subdir); + if dir.exists() { + return Ok(dir.into()); + } + } + + if let Some(cache_dir) = self.cache_dir() { + let dir = cache_dir.join(&subdir); + + // Download from network if it doesn't exist yet. + if spec.namespace == "preview" && !dir.exists() { + self.download_package(spec, &dir)?; + } + + if dir.exists() { + return Ok(dir.into()); + } + } + + Err(PackageError::NotFound(spec.clone())) + } + + /// Download a package over the network. + fn download_package(&self, spec: &PackageSpec, package_dir: &Path) -> Result<(), PackageError> { + let url = format!( + "https://packages.typst.org/preview/{}-{}.tar.gz", + spec.name, spec.version + ); + + self.notifier.lock().downloading(spec); + threaded_http(&url, self.cert_path.as_deref(), |resp| { + let reader = match resp.and_then(|r| r.error_for_status()) { + Ok(response) => response, + Err(err) if matches!(err.status().map(|s| s.as_u16()), Some(404)) => { + return Err(PackageError::NotFound(spec.clone())) + } + Err(err) => return Err(PackageError::NetworkFailed(Some(eco_format!("{err}")))), + }; + + let decompressed = flate2::read::GzDecoder::new(reader); + tar::Archive::new(decompressed) + .unpack(package_dir) + .map_err(|err| { + std::fs::remove_dir_all(package_dir).ok(); + PackageError::MalformedArchive(Some(eco_format!("{err}"))) + }) + }) + .ok_or_else(|| PackageError::Other(Some(eco_format!("cannot spawn http thread"))))? + } +} + +impl PackageRegistry for HttpsRegistry { + fn resolve(&self, spec: &PackageSpec) -> Result, PackageError> { + self.prepare_package(spec) + } + + fn packages(&self) -> &[(PackageSpec, Option)] { + self.packages.get_or_init(|| { + let url = "https://packages.typst.org/preview/index.json"; + + threaded_http(url, self.cert_path.as_deref(), |resp| { + let reader = match resp.and_then(|r| r.error_for_status()) { + Ok(response) => response, + Err(err) => { + // todo: silent error + error!("Failed to fetch package index: {err} from {url}"); + return vec![]; + } + }; + + #[derive(serde::Deserialize)] + struct RemotePackageIndex { + name: EcoString, + version: PackageVersion, + description: Option, + } + + let index: Vec = match serde_json::from_reader(reader) { + Ok(index) => index, + Err(err) => { + error!("Failed to parse package index: {err} from {url}"); + return vec![]; + } + }; + + index + .into_iter() + .map(|e| { + ( + PackageSpec { + namespace: "preview".into(), + name: e.name, + version: e.version, + }, + e.description, + ) + }) + .collect::>() + }) + .unwrap_or_default() + }) + } +} + +fn threaded_http( + url: &str, + cert_path: Option<&Path>, + f: impl FnOnce(Result) -> T + Send + Sync, +) -> Option { + std::thread::scope(|s| { + s.spawn(move || { + let client_builder = reqwest::blocking::Client::builder(); + + let client = if let Some(cert_path) = cert_path { + let cert = std::fs::read(cert_path) + .ok() + .and_then(|buf| Certificate::from_pem(&buf).ok()); + if let Some(cert) = cert { + client_builder.add_root_certificate(cert).build().unwrap() + } else { + client_builder.build().unwrap() + } + } else { + client_builder.build().unwrap() + }; + + f(client.get(url).send()) + }) + .join() + .ok() + }) +} diff --git a/crates/tinymist-world/src/lib.rs b/crates/tinymist-world/src/lib.rs index 65b37f4f0..2616d7b1a 100644 --- a/crates/tinymist-world/src/lib.rs +++ b/crates/tinymist-world/src/lib.rs @@ -21,8 +21,8 @@ use reflexo_typst::vfs::{system::SystemAccessModel, Vfs}; use reflexo_typst::{CompilerFeat, CompilerUniverse, CompilerWorld, TypstDict}; use serde::{Deserialize, Serialize}; -pub mod package; -use package::HttpsRegistry; +pub mod https; +use https::HttpsRegistry; const ENV_PATH_SEP: char = if cfg!(windows) { ';' } else { ':' }; @@ -65,22 +65,6 @@ pub struct CompileFontArgs { pub ignore_system_fonts: bool, } -/// Arguments related to where packages are stored in the system. -#[derive(Debug, Clone, Parser, Default, PartialEq, Eq)] -pub struct CompilePackageArgs { - /// Custom path to local packages, defaults to system-dependent location - #[clap(long = "package-path", env = "TYPST_PACKAGE_PATH", value_name = "DIR")] - pub package_path: Option, - - /// Custom path to package cache, defaults to system-dependent location - #[clap( - long = "package-cache-path", - env = "TYPST_PACKAGE_CACHE_PATH", - value_name = "DIR" - )] - pub package_cache_path: Option, -} - /// Common arguments of compile, watch, and query. #[derive(Debug, Clone, Parser, Default)] pub struct CompileOnceArgs { @@ -105,10 +89,6 @@ pub struct CompileOnceArgs { #[clap(flatten)] pub font: CompileFontArgs, - /// Package related arguments. - #[clap(flatten)] - pub package: CompilePackageArgs, - /// The document's creation date formatted as a UNIX timestamp. /// /// For more information, see . @@ -124,26 +104,26 @@ pub struct CompileOnceArgs { /// Path to CA certificate file for network access, especially for /// downloading typst packages. #[clap(long = "cert", env = "TYPST_CERT", value_name = "CERT_PATH")] - pub cert: Option, + pub certification: Option, } impl CompileOnceArgs { /// Get a universe instance from the given arguments. pub fn resolve(&self) -> anyhow::Result { let entry = self.entry()?.try_into()?; + let fonts = LspUniverseBuilder::resolve_fonts(self.font.clone())?; let inputs = self .inputs .iter() .map(|(k, v)| (Str::from(k.as_str()), Value::Str(Str::from(v.as_str())))) .collect(); - let fonts = LspUniverseBuilder::resolve_fonts(self.font.clone())?; - let package = LspUniverseBuilder::resolve_package(self.cert.clone(), Some(&self.package)); + let cert_path = self.certification.clone(); LspUniverseBuilder::build( entry, - Arc::new(LazyHash::new(inputs)), Arc::new(fonts), - package, + Arc::new(LazyHash::new(inputs)), + cert_path, ) .context("failed to create universe") } @@ -205,15 +185,15 @@ impl LspUniverseBuilder { /// See [`LspCompilerFeat`] for instantiation details. pub fn build( entry: EntryState, - inputs: ImmutDict, font_resolver: Arc, - package_registry: HttpsRegistry, + inputs: ImmutDict, + cert_path: Option, ) -> ZResult { Ok(LspUniverse::new_raw( entry, Some(inputs), Vfs::new(SystemAccessModel {}), - package_registry, + HttpsRegistry::new(cert_path), font_resolver, )) } @@ -229,14 +209,6 @@ impl LspUniverseBuilder { })?; Ok(searcher.into()) } - - /// Resolve package registry from given options. - pub fn resolve_package( - cert_path: Option, - args: Option<&CompilePackageArgs>, - ) -> HttpsRegistry { - HttpsRegistry::new(cert_path, args) - } } /// Parses key/value pairs split by the first equal sign. diff --git a/crates/tinymist-world/src/package.rs b/crates/tinymist-world/src/package.rs deleted file mode 100644 index c489ab14b..000000000 --- a/crates/tinymist-world/src/package.rs +++ /dev/null @@ -1,164 +0,0 @@ -//! Https registry for tinymist. - -use std::sync::OnceLock; -use std::{path::PathBuf, sync::Arc}; - -use parking_lot::Mutex; -use reflexo_typst::package::{DummyNotifier, Notifier, PackageError, PackageRegistry, PackageSpec}; -use reflexo_typst::typst::diag::EcoString; -use reflexo_typst::ImmutPath; -use typst_kit::download::{DownloadState, Downloader}; -use typst_kit::package::PackageStorage; - -use crate::CompilePackageArgs; - -/// The https package registry for tinymist. -pub struct HttpsRegistry { - /// The path at which local packages (`@local` packages) are stored. - local_dir: OnceLock>, - /// The path at which non-local packages (`@preview` packages) should be - /// stored when downloaded. - cache_dir: OnceLock>, - /// The cached index of the preview namespace. - index: OnceLock)>>, - /// lazily initialized package storage. - storage: OnceLock, - cert_path: Option, - notifier: Arc>, - // package_dir_cache: RwLock>>, -} - -impl Default for HttpsRegistry { - fn default() -> Self { - Self { - notifier: Arc::new(Mutex::::default()), - // todo: reset cache - index: OnceLock::new(), - // Default to None - cert_path: None, - - local_dir: OnceLock::new(), - cache_dir: OnceLock::new(), - storage: OnceLock::new(), - // package_dir_cache: RwLock::new(HashMap::new()), - } - } -} - -impl std::ops::Deref for HttpsRegistry { - type Target = PackageStorage; - - fn deref(&self) -> &Self::Target { - self.storage() - } -} - -impl HttpsRegistry { - /// Create a new registry. - pub fn new(cert_path: Option, package_args: Option<&CompilePackageArgs>) -> Self { - let local_dir = OnceLock::new(); - if let Some(dir) = package_args.and_then(|args| args.package_path.as_deref()) { - let _ = local_dir.set(Some(dir.into())); - } - - let cache_dir = OnceLock::new(); - if let Some(dir) = package_args.and_then(|args| args.package_cache_path.as_deref()) { - let _ = cache_dir.set(Some(dir.into())); - } - - Self { - cert_path, - local_dir, - cache_dir, - ..Default::default() - } - } - - /// Get local path option - pub fn local_path(&self) -> Option { - self.data_dir().cloned() - } - - fn data_dir(&self) -> Option<&ImmutPath> { - self.local_dir - .get_or_init(|| Some(dirs::data_dir()?.join("typst/packages").into())) - .as_ref() - } - - fn cache_dir(&self) -> Option<&ImmutPath> { - self.cache_dir - .get_or_init(|| Some(dirs::cache_dir()?.join("typst/packages").into())) - .as_ref() - } - - /// Get data & cache dir - pub fn paths(&self) -> Vec { - let mut res = Vec::with_capacity(2); - if let Some(data_dir) = self.data_dir() { - res.push(data_dir.clone()); - } - - if let Some(cache_dir) = self.cache_dir() { - res.push(cache_dir.clone()) - } - - res - } - - /// Get `typst-kit` implementing package storage - pub fn storage(&self) -> &PackageStorage { - self.storage.get_or_init(|| { - let user_agent = concat!("typst/", env!("CARGO_PKG_VERSION")); - let downloader = match self.cert_path.clone() { - Some(cert) => Downloader::with_path(user_agent, cert), - None => Downloader::new(user_agent), - }; - PackageStorage::new( - self.cache_dir().map(|s| s.as_ref().into()), - self.data_dir().map(|s| s.as_ref().into()), - downloader, - ) - }) - } - - /// Make a package available in the on-disk cache. - pub fn prepare_package(&self, spec: &PackageSpec) -> Result { - self.storage() - .prepare_package(spec, &mut NotifierProgress(self.notifier.clone(), spec)) - } -} - -impl PackageRegistry for HttpsRegistry { - fn resolve(&self, spec: &PackageSpec) -> Result { - self.prepare_package(spec).map(From::from) - } - - fn packages(&self) -> &[(PackageSpec, Option)] { - self.index.get_or_init(|| { - let packages = self.storage().download_index().unwrap_or_default().iter(); - - packages - .map(|e| { - ( - PackageSpec { - namespace: "preview".into(), - name: e.name.clone(), - version: e.version, - }, - e.description.clone(), - ) - }) - .collect() - }) - } -} - -struct NotifierProgress<'a>(Arc>, &'a PackageSpec); - -impl typst_kit::download::Progress for NotifierProgress<'_> { - fn print_start(&mut self) { - self.0.lock().downloading(self.1); - } - fn print_progress(&mut self, _state: &DownloadState) {} - fn print_finish(&mut self, _state: &DownloadState) {} -} diff --git a/crates/tinymist/Cargo.toml b/crates/tinymist/Cargo.toml index c64aa0a9e..2ec0dc983 100644 --- a/crates/tinymist/Cargo.toml +++ b/crates/tinymist/Cargo.toml @@ -81,7 +81,6 @@ open = { workspace = true, optional = true } dirs.workspace = true base64.workspace = true rayon.workspace = true -typst-kit.workspace = true typst-ansi-hl = "0.2.0" @@ -100,9 +99,6 @@ dhat-heap = ["dhat"] # into the binary. embed-fonts = ["typst-assets/fonts"] -# Whether to vendor OpenSSL. Not applicable to Windows and macOS builds. -vendor-openssl = ["typst-kit/vendor-openssl"] - # Disable the default content hint. # This requires modifying typst. no-content-hint = [ diff --git a/crates/tinymist/src/actor/mod.rs b/crates/tinymist/src/actor/mod.rs index 2a47d0a6f..b6872e92b 100644 --- a/crates/tinymist/src/actor/mod.rs +++ b/crates/tinymist/src/actor/mod.rs @@ -134,16 +134,12 @@ impl LanguageState { let compile_handle = handle.clone(); let cache = self.cache.clone(); let cert_path = self.compile_config().determine_certification_path(); - let package = self.compile_config().determine_package_opts(); self.client.handle.spawn_blocking(move || { // Create the world let font_resolver = font_resolver.wait().clone(); - let package_registry = - LspUniverseBuilder::resolve_package(cert_path.clone(), Some(&package)); - let verse = - LspUniverseBuilder::build(entry_.clone(), inputs, font_resolver, package_registry) - .expect("incorrect options"); + let verse = LspUniverseBuilder::build(entry_.clone(), font_resolver, inputs, cert_path) + .expect("incorrect options"); // Create the actor let server = CompileServerActor::new_with( diff --git a/crates/tinymist/src/cmd.rs b/crates/tinymist/src/cmd.rs index 89123cd3d..b169aa3c4 100644 --- a/crates/tinymist/src/cmd.rs +++ b/crates/tinymist/src/cmd.rs @@ -334,7 +334,7 @@ impl LanguageState { /// Initialize a new template. pub fn init_template(&mut self, mut args: Vec) -> AnySchedulableResponse { - use crate::tool::package::{self, TemplateSource}; + use crate::tool::package::{self, determine_latest_version, TemplateSource}; #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] @@ -359,7 +359,7 @@ impl LanguageState { // Try to parse without version, but prefer the error message of the // normal package spec parsing if it fails. let spec: VersionlessPackageSpec = from_source.parse().map_err(|_| err)?; - let version = snap.world.registry.determine_latest_version(&spec)?; + let version = determine_latest_version(&snap.world, &spec)?; StrResult::Ok(spec.at(version)) }) .map_err(map_string_err("failed to parse package spec")) @@ -386,7 +386,7 @@ impl LanguageState { /// Get the entry of a template. pub fn get_template_entry(&mut self, mut args: Vec) -> AnySchedulableResponse { - use crate::tool::package::{self, TemplateSource}; + use crate::tool::package::{self, determine_latest_version, TemplateSource}; let from_source = get_arg!(args[0] as String); @@ -404,7 +404,7 @@ impl LanguageState { // Try to parse without version, but prefer the error message of the // normal package spec parsing if it fails. let spec: VersionlessPackageSpec = from_source.parse().map_err(|_| err)?; - let version = snap.world.registry.determine_latest_version(&spec)?; + let version = determine_latest_version(&snap.world, &spec)?; StrResult::Ok(spec.at(version)) }) .map_err(map_string_err("failed to parse package spec")) @@ -547,7 +547,6 @@ impl LanguageState { just_future(async move { let snap = snap.receive().await.map_err(z_internal_error)?; let paths = snap.world.registry.paths(); - let paths = paths.iter().map(|p| p.as_ref()).collect::>(); serde_json::to_value(paths).map_err(|e| internal_error(e.to_string())) }) } @@ -560,8 +559,12 @@ impl LanguageState { let snap = self.primary().snapshot().map_err(z_internal_error)?; just_future(async move { let snap = snap.receive().await.map_err(z_internal_error)?; - let paths = snap.world.registry.local_path(); - let paths = paths.as_deref().into_iter().collect::>(); + let paths = snap + .world + .registry + .local_path() + .into_iter() + .collect::>(); serde_json::to_value(paths).map_err(|e| internal_error(e.to_string())) }) } diff --git a/crates/tinymist/src/init.rs b/crates/tinymist/src/init.rs index 3e30f5036..e7a37ec31 100644 --- a/crates/tinymist/src/init.rs +++ b/crates/tinymist/src/init.rs @@ -576,9 +576,8 @@ impl CompileConfig { root_dir: command.root, inputs: Arc::new(LazyHash::new(inputs)), font: command.font, - package: command.package, creation_timestamp: command.creation_timestamp, - cert: command.cert, + cert: command.certification, }); } @@ -724,14 +723,6 @@ impl CompileConfig { opts } - /// Determines the package options. - pub fn determine_package_opts(&self) -> CompilePackageArgs { - if let Some(extras) = &self.typst_extra_args { - return extras.package.clone(); - } - CompilePackageArgs::default() - } - /// Determines the font resolver. pub fn determine_fonts(&self) -> Deferred> { // todo: on font resolving failure, downgrade to a fake font book @@ -889,8 +880,6 @@ pub struct CompileExtraOpts { pub inputs: ImmutDict, /// Additional font paths. pub font: CompileFontArgs, - /// Package related arguments. - pub package: CompilePackageArgs, /// The creation timestamp for various output. pub creation_timestamp: Option>, /// Path to certification file diff --git a/crates/tinymist/src/tool/package/mod.rs b/crates/tinymist/src/tool/package/mod.rs index 6f60a66d8..58c3bc11b 100644 --- a/crates/tinymist/src/tool/package/mod.rs +++ b/crates/tinymist/src/tool/package/mod.rs @@ -1,4 +1,42 @@ //! Package management tools. +use reflexo_typst::package::PackageRegistry; +use typst::diag::{eco_format, StrResult}; +use typst::syntax::package::{PackageVersion, VersionlessPackageSpec}; + +use crate::LspWorld; + mod init; pub use init::*; + +/// Try to determine the latest version of a package. +pub fn determine_latest_version( + world: &LspWorld, + spec: &VersionlessPackageSpec, +) -> StrResult { + if spec.namespace == "preview" { + let packages = world.registry.packages(); + packages + .iter() + .filter(|(package, _)| package.namespace == "preview" && package.name == spec.name) + .map(|(package, _)| package.version) + .max() + .ok_or_else(|| eco_format!("failed to find package {spec}")) + } else { + // For other namespaces, search locally. We only search in the data + // directory and not the cache directory, because the latter is not + // intended for storage of local packages. + let subdir = format!("typst/packages/{}/{}", spec.namespace, spec.name); + world + .registry + .local_path() + .into_iter() + .flat_map(|dir| std::fs::read_dir(dir.join(&subdir)).ok()) + .flatten() + .filter_map(|entry| entry.ok()) + .map(|entry| entry.path()) + .filter_map(|path| path.file_name()?.to_string_lossy().parse().ok()) + .max() + .ok_or_else(|| eco_format!("please specify the desired version")) + } +} diff --git a/crates/typlite/src/tests.rs b/crates/typlite/src/tests.rs index 2a6a7e16c..4bc683259 100644 --- a/crates/typlite/src/tests.rs +++ b/crates/typlite/src/tests.rs @@ -10,19 +10,20 @@ use typst_syntax::Source; use super::*; fn conv_(s: &str, for_docs: bool) -> EcoString { - static FONT_RESOLVER: LazyLock> = LazyLock::new(|| { - Arc::new( + static FONT_RESOLVER: LazyLock>> = LazyLock::new(|| { + Ok(Arc::new( LspUniverseBuilder::resolve_fonts(CompileFontArgs::default()) - .expect("cannot resolve default fonts"), - ) + .map_err(|e| format!("{e:?}"))?, + )) }); + let font_resolver = FONT_RESOLVER.clone(); let cwd = std::env::current_dir().unwrap(); let main = Source::detached(s); let mut universe = LspUniverseBuilder::build( EntryState::new_rooted(cwd.as_path().into(), Some(main.id())), + font_resolver.unwrap(), Default::default(), - FONT_RESOLVER.clone(), Default::default(), ) .unwrap(); diff --git a/editors/vscode/CHANGELOG.md b/editors/vscode/CHANGELOG.md index 7c1c33f36..4c7ed50c1 100644 --- a/editors/vscode/CHANGELOG.md +++ b/editors/vscode/CHANGELOG.md @@ -18,7 +18,8 @@ We have added maintainers to GitHub since 2024-11-22: ### Compiler -* Added package related arguments to `typstExtraArgs` in https://github.com/Myriad-Dreamin/tinymist/pull/832 and https://github.com/Myriad-Dreamin/tinymist/pull/833 +* ~~Added package related arguments to `typstExtraArgs` in https://github.com/Myriad-Dreamin/tinymist/pull/832 and https://github.com/Myriad-Dreamin/tinymist/pull/833~~ + * (Help Wanted) Reverted because of the OpenSSL problem. See https://github.com/Myriad-Dreamin/tinymist/pull/885. * Taking configuration items from `tinymist` section in https://github.com/Myriad-Dreamin/tinymist/pull/835 ### Editor diff --git a/editors/vscode/package.json b/editors/vscode/package.json index 9a465f72c..d1c412be7 100644 --- a/editors/vscode/package.json +++ b/editors/vscode/package.json @@ -1,6 +1,6 @@ { "name": "tinymist", - "version": "0.12.4-rc2", + "version": "0.12.4-rc3", "description": "An integrated language service for Typst", "keywords": [ "typst", diff --git a/syntaxes/textmate/package.json b/syntaxes/textmate/package.json index 83323075e..f2e46c583 100644 --- a/syntaxes/textmate/package.json +++ b/syntaxes/textmate/package.json @@ -1,6 +1,6 @@ { "name": "typst-textmate", - "version": "0.12.4-rc2", + "version": "0.12.4-rc3", "private": true, "scripts": { "compile": "npx tsc && node ./dist/main.mjs",