From e99329d9a960eef309563165dea753f9e070bb83 Mon Sep 17 00:00:00 2001 From: Chip Senkbeil Date: Thu, 1 Jun 2023 01:48:25 -0500 Subject: [PATCH] Refactor local crate & update/clean dependencies (#191) --- .github/workflows/ci.yml | 73 +- CHANGELOG.md | 1 + Cargo.lock | 159 +- Cargo.toml | 46 +- distant-auth/Cargo.toml | 6 +- distant-auth/src/lib.rs | 3 +- distant-auth/src/methods.rs | 2 +- distant-core/Cargo.toml | 27 +- distant-core/src/api.rs | 12 - distant-core/src/client/process.rs | 3 +- distant-core/src/constants.rs | 15 - distant-core/src/lib.rs | 1 - distant-local/Cargo.toml | 36 + .../api/local.rs => distant-local/src/api.rs | 24 +- .../src/api}/process.rs | 3 +- .../src/api}/process/pty.rs | 2 +- .../src/api}/process/simple.rs | 2 +- .../src/api}/process/simple/tasks.rs | 0 .../src/api}/process/wait.rs | 0 .../local => distant-local/src/api}/state.rs | 0 .../src/api}/state/process.rs | 5 +- .../src/api}/state/process/instance.rs | 6 +- .../src/api}/state/search.rs | 15 +- .../src/api}/state/watcher.rs | 7 +- .../src/api}/state/watcher/path.rs | 7 +- distant-local/src/constants.rs | 14 + distant-local/src/lib.rs | 15 + .../tests/stress/distant/large_file.rs | 0 .../tests/stress/distant/mod.rs | 0 .../tests/stress/distant/watch.rs | 0 .../tests/stress/fixtures.rs | 3 +- .../tests/stress/mod.rs | 0 .../tests/stress_tests.rs | 0 distant-net/Cargo.toml | 12 +- distant-net/src/authentication.rs | 7 +- distant-net/src/common/transport/framed.rs | 3 +- distant-net/src/lib.rs | 5 +- distant-protocol/Cargo.toml | 6 +- distant-protocol/src/common/permissions.rs | 1 + distant-protocol/src/response.rs | 12 +- distant-ssh2/Cargo.toml | 18 +- distant-ssh2/tests/ssh2/launched.rs | 1466 ----------------- distant-ssh2/tests/ssh2/mod.rs | 1 - distant-ssh2/tests/sshd/mod.rs | 34 +- src/cli/commands/client.rs | 7 +- src/cli/commands/common/format.rs | 7 +- src/cli/commands/server.rs | 6 +- src/options.rs | 4 + tests/cli/client/version.rs | 2 +- tests/cli/utils.rs | 3 +- tests/cli/utils/predicates.rs | 3 +- 51 files changed, 273 insertions(+), 1811 deletions(-) create mode 100644 distant-local/Cargo.toml rename distant-core/src/api/local.rs => distant-local/src/api.rs (99%) rename {distant-core/src/api/local => distant-local/src/api}/process.rs (99%) rename {distant-core/src/api/local => distant-local/src/api}/process/pty.rs (99%) rename {distant-core/src/api/local => distant-local/src/api}/process/simple.rs (99%) rename {distant-core/src/api/local => distant-local/src/api}/process/simple/tasks.rs (100%) rename {distant-core/src/api/local => distant-local/src/api}/process/wait.rs (100%) rename {distant-core/src/api/local => distant-local/src/api}/state.rs (100%) rename {distant-core/src/api/local => distant-local/src/api}/state/process.rs (98%) rename {distant-core/src/api/local => distant-local/src/api}/state/process/instance.rs (97%) rename {distant-core/src/api/local => distant-local/src/api}/state/search.rs (99%) rename {distant-core/src/api/local => distant-local/src/api}/state/watcher.rs (98%) rename {distant-core/src/api/local => distant-local/src/api}/state/watcher/path.rs (97%) create mode 100644 distant-local/src/constants.rs create mode 100644 distant-local/src/lib.rs rename {distant-core => distant-local}/tests/stress/distant/large_file.rs (100%) rename {distant-core => distant-local}/tests/stress/distant/mod.rs (100%) rename {distant-core => distant-local}/tests/stress/distant/watch.rs (100%) rename {distant-core => distant-local}/tests/stress/fixtures.rs (95%) rename {distant-core => distant-local}/tests/stress/mod.rs (100%) rename {distant-core => distant-local}/tests/stress_tests.rs (100%) delete mode 100644 distant-ssh2/tests/ssh2/launched.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c539741d..c05a8e69 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,18 +38,12 @@ jobs: toolchain: stable components: clippy - uses: Swatinem/rust-cache@v2 + with: + key: "ci-clippy-${{ matrix.os }}" - name: Check Cargo availability run: cargo --version - - name: distant-auth (all features) - run: cargo clippy -p distant-auth --all-targets --verbose --all-features - - name: distant-net (all features) - run: cargo clippy -p distant-net --all-targets --verbose --all-features - - name: distant-core (all features) - run: cargo clippy -p distant-core --all-targets --verbose --all-features - - name: distant-ssh2 (all features) - run: cargo clippy -p distant-ssh2 --all-targets --verbose --all-features - - name: distant (all features) - run: cargo clippy --all-targets --verbose --all-features + - name: Run clippy (all features) + run: cargo clippy --workspace --all-targets --verbose --all-features rustfmt: name: "Verify code formatting (${{ matrix.os }})" runs-on: ${{ matrix.os }} @@ -73,6 +67,8 @@ jobs: toolchain: stable components: rustfmt - uses: Swatinem/rust-cache@v2 + with: + key: "ci-rustfmt-${{ matrix.os }}" - name: Check Cargo availability run: cargo --version - run: cargo fmt --all -- --check @@ -102,6 +98,8 @@ jobs: with: tool: cargo-nextest@0.9.45 - uses: Swatinem/rust-cache@v2 + with: + key: "ci-tests-${{ matrix.os }}-${{ matrix.rust }}-${{ matrix.target }}" - name: Check Cargo availability run: cargo --version - uses: nick-fields/retry@v2 @@ -157,58 +155,13 @@ jobs: New-ItemProperty -Path $registryPath -Name $name -Value $value -PropertyType String -Force } - name: Extend Windows retry count to be more resilient - if: matrix.os == 'windows-latest' run: echo "NEXTEST_RETRIES=9" >> $GITHUB_ENV shell: bash - - name: Run auth tests (all features) - run: cargo nextest run --profile ci --release --all-features -p distant-auth - - name: Run net tests (default features) - run: cargo nextest run --profile ci --release -p distant-net - - name: Build core (default features) - run: cargo build --release -p distant-core - - name: Run core tests (all features) - run: cargo nextest run --profile ci --release --all-features -p distant-core + if: matrix.os == 'windows-latest' - name: Ensure /run/sshd exists on Unix run: mkdir -p /run/sshd if: matrix.os == 'ubuntu-latest' - - name: Build ssh2 (default features) - run: cargo build --release -p distant-ssh2 - - name: Run ssh2 client tests (all features) - run: cargo nextest run --profile ci --release --all-features -p distant-ssh2 ssh2::client - - name: Build CLI (no default features) - run: cargo build --release --no-default-features - - name: Build CLI (default features) - run: cargo build --release - - name: Run CLI tests (all features) - run: cargo nextest run --profile ci --release --all-features - ssh-launch-tests: - name: "Test ssh launch using Rust ${{ matrix.rust }} on ${{ matrix.os }}" - runs-on: ${{ matrix.os }} - env: - RUSTFLAGS: --cfg ci - RUST_LOG: trace - strategy: - fail-fast: false - matrix: - include: - - { rust: stable, os: macos-latest } - - { rust: stable, os: ubuntu-latest } - steps: - - uses: actions/checkout@v3 - - name: Install Rust ${{ matrix.rust }} - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: ${{ matrix.rust }} - - uses: taiki-e/install-action@v1 - with: - tool: cargo-nextest@0.9.45 - - uses: Swatinem/rust-cache@v2 - - name: Check Cargo availability - run: cargo --version - - name: Install distant cli for use in launch tests - run: | - cargo install --path . - echo "DISTANT_PATH=$HOME/.cargo/bin/distant" >> $GITHUB_ENV - - name: Run ssh2 launch tests (all features) - run: cargo nextest run --profile ci --release --all-features -p distant-ssh2 ssh2::launched + - name: Run all workspace tests (all features) + run: cargo nextest run --profile ci --release --all-features --workspace + - name: Run all doc tests (all features) + run: cargo test --release --all-features --workspace --doc diff --git a/CHANGELOG.md b/CHANGELOG.md index 0be1b928..20f09432 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Capabilities` message type has been changed to `Version` with new struct to report the version information that includes a server version string, protocol version tuple, and capabilities +- `distant_core::api::local` moved to `distant_local` ### Removed diff --git a/Cargo.lock b/Cargo.lock index a23b8a87..25684fb9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -223,9 +223,9 @@ dependencies = [ [[package]] name = "async-once-cell" -version = "0.4.4" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b49bd4c5b769125ea6323601c39815848972880efd33ffb2d01f9f909adc699" +checksum = "fddec5f567375e0a634f94bc8dab1059b9d59a8aba12134c32f5ee21ce3f5f89" [[package]] name = "async-process" @@ -474,9 +474,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.2.7" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34d21f9bf1b425d2968943631ec91202fe5e837264063503708b83013f8fc938" +checksum = "93aae7a4192245f70fe75dd9157fc7b4a5bf53e88d30bd4396f7d8f9284d5acc" dependencies = [ "clap_builder", "clap_derive", @@ -485,9 +485,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.2.7" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914c8c79fb560f238ef6429439a30023c862f7a28e688c58f7203f12b29970bd" +checksum = "4f423e341edefb78c9caba2d9c7f7687d0e72e89df3ce3394554754393ac3990" dependencies = [ "anstream", "anstyle", @@ -498,18 +498,18 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.2.3" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1594fe2312ec4abf402076e407628f5c313e54c32ade058521df4ee34ecac8a8" +checksum = "a04ddfaacc3bc9e6ea67d024575fafc2a813027cf374b8f24f7bc233c6b6be12" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.2.0" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" +checksum = "191d9573962933b4027f932c600cd252ce27a8ad5979418fe78e43c07996f27b" dependencies = [ "heck", "proc-macro2", @@ -519,9 +519,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" [[package]] name = "colorchoice" @@ -820,6 +820,7 @@ dependencies = [ "dialoguer", "directories", "distant-core", + "distant-local", "distant-ssh2", "env_logger", "file-mode", @@ -866,7 +867,6 @@ dependencies = [ name = "distant-core" version = "0.20.0-alpha.7" dependencies = [ - "assert_fs", "async-trait", "bitflags 2.3.1", "bytes", @@ -875,8 +875,29 @@ dependencies = [ "distant-protocol", "env_logger", "futures", - "grep", "hex", + "log", + "num_cpus", + "once_cell", + "rand", + "regex", + "serde", + "serde_bytes", + "serde_json", + "strum", + "test-log", + "tokio", +] + +[[package]] +name = "distant-local" +version = "0.20.0-alpha.7" +dependencies = [ + "assert_fs", + "async-trait", + "distant-core", + "env_logger", + "grep", "ignore", "indoc", "log", @@ -886,16 +907,10 @@ dependencies = [ "portable-pty 0.8.1", "predicates", "rand", - "regex", "rstest", - "serde", - "serde_bytes", - "serde_json", "shell-words", - "strum", "test-log", "tokio", - "tokio-util", "walkdir", "whoami", "winsplit", @@ -1195,9 +1210,9 @@ dependencies = [ [[package]] name = "flexi_logger" -version = "0.25.4" +version = "0.25.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "611de758a8869ffffa7524aafdb48658c64dae95cdce49654d68a8442e500d89" +checksum = "37e7b68b1f7ce9c62856598e99cd6742b9cedb6186b47aa989a82640f20bfa9b" dependencies = [ "chrono", "glob", @@ -1821,12 +1836,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.17" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de" [[package]] name = "memchr" @@ -1976,12 +1988,11 @@ dependencies = [ [[package]] name = "nu-ansi-term" -version = "0.46.0" +version = "0.47.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +checksum = "1df031e117bca634c262e9bd3173776844b6c17a90b3741c9163663b4385af76" dependencies = [ - "overload", - "winapi", + "windows-sys 0.45.0", ] [[package]] @@ -2026,9 +2037,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.17.1" +version = "1.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "9670a07f94779e00908f3e686eab508878ebb390ba6e604d3a284c00e8d0487b" [[package]] name = "opaque-debug" @@ -2074,12 +2085,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - [[package]] name = "p256" version = "0.13.2" @@ -2094,9 +2099,9 @@ dependencies = [ [[package]] name = "papergrid" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1526bb6aa9f10ec339fb10360f22c57edf81d5678d0278e93bc12a47ffbe4b01" +checksum = "1fdfe703c51ddc52887ad78fc69cd2ea78d895ffcd6e955c9d03566db8ab5bb1" dependencies = [ "bytecount", "fnv", @@ -2557,13 +2562,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.8.1" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" +checksum = "81ca098a9821bd52d6b24fd8b10bd081f47d39c22778cafaa75a2857a62c6390" dependencies = [ "aho-corasick 1.0.1", "memchr", - "regex-syntax 0.7.1", + "regex-syntax 0.7.2", ] [[package]] @@ -2580,9 +2585,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" +checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" [[package]] name = "rfc6979" @@ -2793,9 +2798,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4" +checksum = "93107647184f6027e3b7dcb2e11034cf95ffa1e3a682c67951963ac69c1c007d" dependencies = [ "serde", ] @@ -3061,9 +3066,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.28.4" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c2f3ca6693feb29a89724516f016488e9aafc7f37264f898593ee4b942f31b" +checksum = "02f1dc6930a439cc5d154221b5387d153f8183529b07c19aca24ea31e0a167e1" dependencies = [ "cfg-if", "core-foundation-sys", @@ -3076,9 +3081,9 @@ dependencies = [ [[package]] name = "tabled" -version = "0.10.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c3ee73732ffceaea7b8f6b719ce3bb17f253fa27461ffeaf568ebd0cdb4b85" +checksum = "da1a2e56bbf7bfdd08aaa7592157a742205459eff774b73bc01809ae2d99dc2a" dependencies = [ "papergrid", "tabled_derive", @@ -3087,9 +3092,9 @@ dependencies = [ [[package]] name = "tabled_derive" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beca1b4eaceb4f2755df858b88d9b9315b7ccfd1ffd0d7a48a52602301f01a57" +checksum = "99f688a08b54f4f02f0a3c382aefdb7884d3d69609f785bd253dc033243e3fe4" dependencies = [ "heck", "proc-macro-error", @@ -3251,9 +3256,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.28.1" +version = "1.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0aa32867d44e6f2ce3385e89dceb990188b8bb0fb25b0cf576647a6f98ac5105" +checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" dependencies = [ "autocfg", "bytes", @@ -3279,20 +3284,6 @@ dependencies = [ "syn 2.0.16", ] -[[package]] -name = "tokio-util" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", - "tracing", -] - [[package]] name = "toml" version = "0.5.11" @@ -3304,18 +3295,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" +checksum = "5a76a9312f5ba4c2dec6b9161fdf25d87ad8a09256ccea5a556fef03c706a10f" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.19.8" +version = "0.19.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13" +checksum = "2380d56e8670370eee6566b0bfd4265f65b3f432e8c6d85623f728d4fa31f739" dependencies = [ "indexmap", "serde", @@ -3324,26 +3315,6 @@ dependencies = [ "winnow", ] -[[package]] -name = "tracing" -version = "0.1.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" -dependencies = [ - "cfg-if", - "pin-project-lite", - "tracing-core", -] - -[[package]] -name = "tracing-core" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" -dependencies = [ - "once_cell", -] - [[package]] name = "typed-path" version = "0.3.2" diff --git a/Cargo.toml b/Cargo.toml index 45ea8439..c2e35d53 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,14 @@ readme = "README.md" license = "MIT OR Apache-2.0" [workspace] -members = ["distant-auth", "distant-core", "distant-net", "distant-protocol", "distant-ssh2"] +members = [ + "distant-auth", + "distant-core", + "distant-local", + "distant-net", + "distant-protocol", + "distant-ssh2", +] [profile.release] opt-level = 'z' @@ -25,30 +32,31 @@ libssh = ["distant-ssh2/libssh"] ssh2 = ["distant-ssh2/ssh2"] [dependencies] -anyhow = "1.0.70" +anyhow = "1.0.71" async-trait = "0.1.68" -clap = { version = "4.2.1", features = ["derive"] } -clap_complete = "4.2.0" +clap = { version = "4.3.0", features = ["derive"] } +clap_complete = "4.3.0" config = { version = "0.13.3", default-features = false, features = ["toml"] } derive_more = { version = "0.99.17", default-features = false, features = ["display", "from", "error", "is_variant"] } -dialoguer = { version = "0.10.3", default-features = false } +dialoguer = { version = "0.10.4", default-features = false } distant-core = { version = "=0.20.0-alpha.7", path = "distant-core" } -directories = "5.0.0" +distant-local = { version = "=0.20.0-alpha.7", path = "distant-local" } +directories = "5.0.1" file-mode = "0.1.2" -flexi_logger = "0.25.3" +flexi_logger = "0.25.5" indoc = "2.0.1" -log = "0.4.17" -once_cell = "1.17.1" +log = "0.4.18" +once_cell = "1.17.2" rand = { version = "0.8.5", features = ["getrandom"] } rpassword = "7.2.0" -serde = { version = "1.0.159", features = ["derive"] } -serde_json = "1.0.95" +serde = { version = "1.0.163", features = ["derive"] } +serde_json = "1.0.96" shell-words = "1.1.0" service-manager = { version = "0.2.0", features = ["clap", "serde"] } -tabled = "0.10.0" -tokio = { version = "1.27.0", features = ["full"] } -toml_edit = { version = "0.19.8", features = ["serde"] } -terminal_size = "0.2.5" +tabled = "0.12.0" +tokio = { version = "1.28.2", features = ["full"] } +toml_edit = { version = "0.19.10", features = ["serde"] } +terminal_size = "0.2.6" termwiz = "0.20.0" which = "4.4.0" winsplit = "0.1.0" @@ -61,14 +69,14 @@ distant-ssh2 = { version = "=0.20.0-alpha.7", path = "distant-ssh2", default-fea fork = "0.1.21" [target.'cfg(windows)'.dependencies] -sysinfo = "0.28.4" +sysinfo = "0.29.0" windows-service = "0.6.0" [dev-dependencies] -assert_cmd = "2.0.10" -assert_fs = "1.0.12" +assert_cmd = "2.0.11" +assert_fs = "1.0.13" env_logger = "0.10.0" indoc = "2.0.1" -predicates = "3.0.2" +predicates = "3.0.3" rstest = "0.17.0" test-log = "0.2.11" diff --git a/distant-auth/Cargo.toml b/distant-auth/Cargo.toml index ac02bc28..6d0bfa55 100644 --- a/distant-auth/Cargo.toml +++ b/distant-auth/Cargo.toml @@ -18,10 +18,10 @@ tests = [] [dependencies] async-trait = "0.1.68" derive_more = { version = "0.99.17", default-features = false, features = ["display", "from", "error"] } -log = "0.4.17" -serde = { version = "1.0.159", features = ["derive"] } +log = "0.4.18" +serde = { version = "1.0.163", features = ["derive"] } [dev-dependencies] env_logger = "0.10.0" test-log = "0.2.11" -tokio = { version = "1.27.0", features = ["full"] } +tokio = { version = "1.28.2", features = ["full"] } diff --git a/distant-auth/src/lib.rs b/distant-auth/src/lib.rs index 97be5d65..35aff093 100644 --- a/distant-auth/src/lib.rs +++ b/distant-auth/src/lib.rs @@ -9,6 +9,5 @@ pub use methods::*; #[cfg(any(test, feature = "tests"))] pub mod tests { - pub use crate::TestAuthHandler; - pub use crate::TestAuthenticator; + pub use crate::{TestAuthHandler, TestAuthenticator}; } diff --git a/distant-auth/src/methods.rs b/distant-auth/src/methods.rs index 0537c964..c4a68356 100644 --- a/distant-auth/src/methods.rs +++ b/distant-auth/src/methods.rs @@ -121,10 +121,10 @@ pub trait AuthenticationMethod: Send + Sync { #[cfg(test)] mod tests { use std::sync::mpsc; + use test_log::test; use super::*; - use crate::authenticator::TestAuthenticator; struct SuccessAuthenticationMethod; diff --git a/distant-core/Cargo.toml b/distant-core/Cargo.toml index bc9725af..babc9043 100644 --- a/distant-core/Cargo.toml +++ b/distant-core/Cargo.toml @@ -13,37 +13,24 @@ license = "MIT OR Apache-2.0" [dependencies] async-trait = "0.1.68" -bitflags = "2.0.2" +bitflags = "2.3.1" bytes = "1.4.0" derive_more = { version = "0.99.17", default-features = false, features = ["as_mut", "as_ref", "deref", "deref_mut", "display", "from", "error", "into", "into_iterator", "is_variant", "try_into"] } distant-net = { version = "=0.20.0-alpha.7", path = "../distant-net" } distant-protocol = { version = "=0.20.0-alpha.7", path = "../distant-protocol" } futures = "0.3.28" -grep = "0.2.11" hex = "0.4.3" -ignore = "0.4.20" -log = "0.4.17" -notify = { version = "6.0.0", features = ["serde"] } +log = "0.4.18" num_cpus = "1.15.0" -once_cell = "1.17.1" -portable-pty = "0.8.1" +once_cell = "1.17.2" rand = { version = "0.8.5", features = ["getrandom"] } -regex = "1.7.3" -serde = { version = "1.0.159", features = ["derive"] } +regex = "1.8.3" +serde = { version = "1.0.163", features = ["derive"] } serde_bytes = "0.11.9" -serde_json = "1.0.95" -shell-words = "1.1.0" +serde_json = "1.0.96" strum = { version = "0.24.1", features = ["derive"] } -tokio = { version = "1.27.0", features = ["full"] } -tokio-util = { version = "0.7.7", features = ["codec"] } -walkdir = "2.3.3" -whoami = "1.4.0" -winsplit = "0.1.0" +tokio = { version = "1.28.2", features = ["full"] } [dev-dependencies] -assert_fs = "1.0.12" env_logger = "0.10.0" -indoc = "2.0.1" -predicates = "3.0.2" -rstest = "0.17.0" test-log = "0.2.11" diff --git a/distant-core/src/api.rs b/distant-core/src/api.rs index 39c1fafd..41ef0f58 100644 --- a/distant-core/src/api.rs +++ b/distant-core/src/api.rs @@ -12,9 +12,6 @@ use crate::protocol::{ SearchId, SearchQuery, SetPermissionsOptions, SystemInfo, Version, }; -mod local; -pub use local::LocalDistantApi; - mod reply; use reply::DistantSingleReply; @@ -42,15 +39,6 @@ where } } -impl DistantApiServerHandler::LocalData> { - /// Creates a new server using the [`LocalDistantApi`] implementation - pub fn local() -> io::Result { - Ok(Self { - api: LocalDistantApi::initialize()?, - }) - } -} - #[inline] fn unsupported(label: &str) -> io::Result { Err(io::Error::new( diff --git a/distant-core/src/client/process.rs b/distant-core/src/client/process.rs index aa2bd3a2..7ef1eda2 100644 --- a/distant-core/src/client/process.rs +++ b/distant-core/src/client/process.rs @@ -5,9 +5,8 @@ use distant_net::client::Mailbox; use distant_net::common::{Request, Response}; use log::*; use tokio::io; -use tokio::sync::mpsc; use tokio::sync::mpsc::error::{TryRecvError, TrySendError}; -use tokio::sync::RwLock; +use tokio::sync::{mpsc, RwLock}; use tokio::task::JoinHandle; use crate::client::DistantChannel; diff --git a/distant-core/src/constants.rs b/distant-core/src/constants.rs index 52349e74..4fcf71b1 100644 --- a/distant-core/src/constants.rs +++ b/distant-core/src/constants.rs @@ -1,5 +1,3 @@ -use std::time::Duration; - /// Capacity associated stdin, stdout, and stderr pipes receiving data from remote server pub const CLIENT_PIPE_CAPACITY: usize = 10000; @@ -8,16 +6,3 @@ pub const CLIENT_WATCHER_CAPACITY: usize = 100; /// Capacity associated with a client searcher receiving matches pub const CLIENT_SEARCHER_CAPACITY: usize = 10000; - -/// Capacity associated with the server's file watcher to pass events outbound -pub const SERVER_WATCHER_CAPACITY: usize = 10000; - -/// Represents the maximum size (in bytes) that data will be read from pipes -/// per individual `read` call -/// -/// Current setting is 16k size -pub const MAX_PIPE_CHUNK_SIZE: usize = 16384; - -/// Duration in milliseconds to sleep between reading stdout/stderr chunks -/// to avoid sending many small messages to clients -pub const READ_PAUSE_DURATION: Duration = Duration::from_millis(1); diff --git a/distant-core/src/lib.rs b/distant-core/src/lib.rs index 80237acc..95463001 100644 --- a/distant-core/src/lib.rs +++ b/distant-core/src/lib.rs @@ -12,6 +12,5 @@ mod serde_str; /// Network functionality. pub use distant_net as net; - /// Protocol structures. pub use distant_protocol as protocol; diff --git a/distant-local/Cargo.toml b/distant-local/Cargo.toml new file mode 100644 index 00000000..4efdff1f --- /dev/null +++ b/distant-local/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "distant-local" +description = "Library implementing distant API for local interactions" +categories = ["network-programming"] +version = "0.20.0-alpha.7" +authors = ["Chip Senkbeil "] +edition = "2021" +homepage = "https://github.com/chipsenkbeil/distant" +repository = "https://github.com/chipsenkbeil/distant" +readme = "README.md" +license = "MIT OR Apache-2.0" + +[dependencies] +async-trait = "0.1.68" +distant-core = { version = "=0.20.0-alpha.7", path = "../distant-core" } +grep = "0.2.12" +ignore = "0.4.20" +log = "0.4.18" +notify = { version = "6.0.0", features = ["serde"] } +num_cpus = "1.15.0" +portable-pty = "0.8.1" +rand = { version = "0.8.5", features = ["getrandom"] } +shell-words = "1.1.0" +tokio = { version = "1.28.2", features = ["full"] } +walkdir = "2.3.3" +whoami = "1.4.0" +winsplit = "0.1.0" + +[dev-dependencies] +assert_fs = "1.0.13" +env_logger = "0.10.0" +indoc = "2.0.1" +once_cell = "1.17.2" +predicates = "3.0.3" +rstest = "0.17.0" +test-log = "0.2.11" diff --git a/distant-core/src/api/local.rs b/distant-local/src/api.rs similarity index 99% rename from distant-core/src/api/local.rs rename to distant-local/src/api.rs index 0a695759..2b125d33 100644 --- a/distant-core/src/api/local.rs +++ b/distant-local/src/api.rs @@ -3,17 +3,16 @@ use std::time::SystemTime; use std::{env, io}; use async_trait::async_trait; -use ignore::{DirEntry as WalkDirEntry, WalkBuilder}; -use log::*; -use tokio::io::AsyncWriteExt; -use walkdir::WalkDir; - -use crate::protocol::{ +use distant_core::protocol::{ Capabilities, ChangeKind, ChangeKindSet, DirEntry, Environment, FileType, Metadata, Permissions, ProcessId, PtySize, SearchId, SearchQuery, SetPermissionsOptions, SystemInfo, Version, PROTOCOL_VERSION, }; -use crate::{DistantApi, DistantCtx}; +use distant_core::{DistantApi, DistantCtx}; +use ignore::{DirEntry as WalkDirEntry, WalkBuilder}; +use log::*; +use tokio::io::AsyncWriteExt; +use walkdir::WalkDir; mod process; @@ -23,7 +22,7 @@ use state::*; /// Represents an implementation of [`DistantApi`] that works with the local machine /// where the server using this api is running. In other words, this is a direct /// impementation of the API instead of a proxy to another machine as seen with -/// implementations on top of SSH and other protocol +/// implementations on top of SSH and other protocol. pub struct LocalDistantApi { state: GlobalState, } @@ -451,7 +450,7 @@ impl DistantApi for LocalDistantApi { unix: Some({ use std::os::unix::prelude::*; let mode = metadata.mode(); - crate::protocol::UnixMetadata::from(mode) + distant_core::protocol::UnixMetadata::from(mode) }), #[cfg(not(unix))] unix: None, @@ -460,7 +459,7 @@ impl DistantApi for LocalDistantApi { windows: Some({ use std::os::windows::prelude::*; let attributes = metadata.file_attributes(); - crate::protocol::WindowsMetadata::from(attributes) + distant_core::protocol::WindowsMetadata::from(attributes) }), #[cfg(not(windows))] windows: None, @@ -702,15 +701,14 @@ mod tests { use std::time::Duration; use assert_fs::prelude::*; - use distant_net::server::Reply; + use distant_core::net::server::{ConnectionCtx, Reply}; + use distant_core::protocol::Response; use once_cell::sync::Lazy; use predicates::prelude::*; use test_log::test; use tokio::sync::mpsc; use super::*; - use crate::api::ConnectionCtx; - use crate::protocol::Response; static TEMP_SCRIPT_DIR: Lazy = Lazy::new(|| assert_fs::TempDir::new().unwrap()); diff --git a/distant-core/src/api/local/process.rs b/distant-local/src/api/process.rs similarity index 99% rename from distant-core/src/api/local/process.rs rename to distant-local/src/api/process.rs index 91be3655..97dcac39 100644 --- a/distant-core/src/api/local/process.rs +++ b/distant-local/src/api/process.rs @@ -1,11 +1,10 @@ use std::future::Future; use std::pin::Pin; +use distant_core::protocol::{ProcessId, PtySize}; use tokio::io; use tokio::sync::mpsc; -use crate::protocol::{ProcessId, PtySize}; - mod pty; pub use pty::*; diff --git a/distant-core/src/api/local/process/pty.rs b/distant-local/src/api/process/pty.rs similarity index 99% rename from distant-core/src/api/local/process/pty.rs rename to distant-local/src/api/process/pty.rs index 03f80d60..b6b391be 100644 --- a/distant-core/src/api/local/process/pty.rs +++ b/distant-local/src/api/process/pty.rs @@ -3,6 +3,7 @@ use std::io::{self, Read, Write}; use std::path::PathBuf; use std::sync::{Arc, Mutex, Weak}; +use distant_core::protocol::Environment; use log::*; use portable_pty::{CommandBuilder, MasterPty, PtySize as PortablePtySize}; use tokio::sync::mpsc; @@ -13,7 +14,6 @@ use super::{ ProcessPty, PtySize, WaitRx, }; use crate::constants::{MAX_PIPE_CHUNK_SIZE, READ_PAUSE_DURATION}; -use crate::protocol::Environment; /// Represents a process that is associated with a pty pub struct PtyProcess { diff --git a/distant-core/src/api/local/process/simple.rs b/distant-local/src/api/process/simple.rs similarity index 99% rename from distant-core/src/api/local/process/simple.rs rename to distant-local/src/api/process/simple.rs index d959fdd4..9793ba0c 100644 --- a/distant-core/src/api/local/process/simple.rs +++ b/distant-local/src/api/process/simple.rs @@ -2,6 +2,7 @@ use std::ffi::OsStr; use std::path::PathBuf; use std::process::Stdio; +use distant_core::protocol::Environment; use log::*; use tokio::io; use tokio::process::Command; @@ -12,7 +13,6 @@ use super::{ wait, ExitStatus, FutureReturn, InputChannel, NoProcessPty, OutputChannel, Process, ProcessId, ProcessKiller, WaitRx, }; -use crate::protocol::Environment; mod tasks; diff --git a/distant-core/src/api/local/process/simple/tasks.rs b/distant-local/src/api/process/simple/tasks.rs similarity index 100% rename from distant-core/src/api/local/process/simple/tasks.rs rename to distant-local/src/api/process/simple/tasks.rs diff --git a/distant-core/src/api/local/process/wait.rs b/distant-local/src/api/process/wait.rs similarity index 100% rename from distant-core/src/api/local/process/wait.rs rename to distant-local/src/api/process/wait.rs diff --git a/distant-core/src/api/local/state.rs b/distant-local/src/api/state.rs similarity index 100% rename from distant-core/src/api/local/state.rs rename to distant-local/src/api/state.rs diff --git a/distant-core/src/api/local/state/process.rs b/distant-local/src/api/state/process.rs similarity index 98% rename from distant-core/src/api/local/state/process.rs rename to distant-local/src/api/state/process.rs index dd62e40f..7ead4b49 100644 --- a/distant-core/src/api/local/state/process.rs +++ b/distant-local/src/api/state/process.rs @@ -3,12 +3,11 @@ use std::io; use std::ops::Deref; use std::path::PathBuf; -use distant_net::server::Reply; +use distant_core::net::server::Reply; +use distant_core::protocol::{Environment, ProcessId, PtySize, Response}; use tokio::sync::{mpsc, oneshot}; use tokio::task::JoinHandle; -use crate::protocol::{Environment, ProcessId, PtySize, Response}; - mod instance; pub use instance::*; diff --git a/distant-core/src/api/local/state/process/instance.rs b/distant-local/src/api/state/process/instance.rs similarity index 97% rename from distant-core/src/api/local/state/process/instance.rs rename to distant-local/src/api/state/process/instance.rs index 4b2cddbb..4d170fcf 100644 --- a/distant-core/src/api/local/state/process/instance.rs +++ b/distant-local/src/api/state/process/instance.rs @@ -2,14 +2,14 @@ use std::future::Future; use std::io; use std::path::PathBuf; -use distant_net::server::Reply; +use distant_core::net::server::Reply; +use distant_core::protocol::{Environment, ProcessId, PtySize, Response}; use log::*; use tokio::task::JoinHandle; -use crate::api::local::process::{ +use crate::api::process::{ InputChannel, OutputChannel, Process, ProcessKiller, ProcessPty, PtyProcess, SimpleProcess, }; -use crate::protocol::{Environment, ProcessId, PtySize, Response}; /// Holds information related to a spawned process on the server pub struct ProcessInstance { diff --git a/distant-core/src/api/local/state/search.rs b/distant-local/src/api/state/search.rs similarity index 99% rename from distant-core/src/api/local/state/search.rs rename to distant-local/src/api/state/search.rs index f00ccdb8..0e07cbb0 100644 --- a/distant-core/src/api/local/state/search.rs +++ b/distant-local/src/api/state/search.rs @@ -3,7 +3,12 @@ use std::ops::Deref; use std::path::Path; use std::{cmp, io}; -use distant_net::server::Reply; +use distant_core::net::server::Reply; +use distant_core::protocol::{ + Response, SearchId, SearchQuery, SearchQueryContentsMatch, SearchQueryMatch, + SearchQueryMatchData, SearchQueryOptions, SearchQueryPathMatch, SearchQuerySubmatch, + SearchQueryTarget, +}; use grep::matcher::Matcher; use grep::regex::{RegexMatcher, RegexMatcherBuilder}; use grep::searcher::{BinaryDetection, Searcher, SearcherBuilder, Sink, SinkMatch}; @@ -13,12 +18,6 @@ use log::*; use tokio::sync::{broadcast, mpsc, oneshot}; use tokio::task::JoinHandle; -use crate::protocol::{ - Response, SearchId, SearchQuery, SearchQueryContentsMatch, SearchQueryMatch, - SearchQueryMatchData, SearchQueryOptions, SearchQueryPathMatch, SearchQuerySubmatch, - SearchQueryTarget, -}; - const MAXIMUM_SEARCH_THREADS: usize = 12; /// Holds information related to active searches on the server @@ -807,10 +806,10 @@ mod tests { use std::path::PathBuf; use assert_fs::prelude::*; + use distant_core::protocol::{FileType, SearchQueryCondition, SearchQueryMatchData}; use test_log::test; use super::*; - use crate::protocol::{FileType, SearchQueryCondition, SearchQueryMatchData}; fn make_path(path: &str) -> PathBuf { use std::path::MAIN_SEPARATOR; diff --git a/distant-core/src/api/local/state/watcher.rs b/distant-local/src/api/state/watcher.rs similarity index 98% rename from distant-core/src/api/local/state/watcher.rs rename to distant-local/src/api/state/watcher.rs index 477ab02e..fcb00cb9 100644 --- a/distant-core/src/api/local/state/watcher.rs +++ b/distant-local/src/api/state/watcher.rs @@ -3,20 +3,19 @@ use std::io; use std::ops::Deref; use std::path::{Path, PathBuf}; -use distant_net::common::ConnectionId; +use distant_core::net::common::ConnectionId; +use distant_core::protocol::ChangeKind; use log::*; use notify::event::{AccessKind, AccessMode, ModifyKind}; use notify::{ Config as WatcherConfig, Error as WatcherError, ErrorKind as WatcherErrorKind, Event as WatcherEvent, EventKind, PollWatcher, RecursiveMode, Watcher, }; -use tokio::sync::mpsc; use tokio::sync::mpsc::error::TrySendError; -use tokio::sync::oneshot; +use tokio::sync::{mpsc, oneshot}; use tokio::task::JoinHandle; use crate::constants::SERVER_WATCHER_CAPACITY; -use crate::protocol::ChangeKind; mod path; pub use path::*; diff --git a/distant-core/src/api/local/state/watcher/path.rs b/distant-local/src/api/state/watcher/path.rs similarity index 97% rename from distant-core/src/api/local/state/watcher/path.rs rename to distant-local/src/api/state/watcher/path.rs index d6892628..c3cb98b9 100644 --- a/distant-core/src/api/local/state/watcher/path.rs +++ b/distant-local/src/api/state/watcher/path.rs @@ -2,10 +2,9 @@ use std::hash::{Hash, Hasher}; use std::path::{Path, PathBuf}; use std::{fmt, io}; -use distant_net::common::ConnectionId; -use distant_net::server::Reply; - -use crate::protocol::{Change, ChangeKind, ChangeKindSet, Error, Response}; +use distant_core::net::common::ConnectionId; +use distant_core::net::server::Reply; +use distant_core::protocol::{Change, ChangeKind, ChangeKindSet, Error, Response}; /// Represents a path registered with a watcher that includes relevant state including /// the ability to reply with diff --git a/distant-local/src/constants.rs b/distant-local/src/constants.rs new file mode 100644 index 00000000..a595ebf4 --- /dev/null +++ b/distant-local/src/constants.rs @@ -0,0 +1,14 @@ +use std::time::Duration; + +/// Capacity associated with the server's file watcher to pass events outbound +pub const SERVER_WATCHER_CAPACITY: usize = 10000; + +/// Represents the maximum size (in bytes) that data will be read from pipes +/// per individual `read` call +/// +/// Current setting is 16k size +pub const MAX_PIPE_CHUNK_SIZE: usize = 16384; + +/// Duration in milliseconds to sleep between reading stdout/stderr chunks +/// to avoid sending many small messages to clients +pub const READ_PAUSE_DURATION: Duration = Duration::from_millis(1); diff --git a/distant-local/src/lib.rs b/distant-local/src/lib.rs new file mode 100644 index 00000000..ac6afbf2 --- /dev/null +++ b/distant-local/src/lib.rs @@ -0,0 +1,15 @@ +mod api; +mod constants; +pub use api::LocalDistantApi; +use distant_core::{DistantApi, DistantApiServerHandler}; + +/// Implementation of [`DistantApiServerHandler`] using [`LocalDistantApi`]. +pub type LocalDistantApiServerHandler = + DistantApiServerHandler::LocalData>; + +/// Initializes a new [`LocalDistantApiServerHandler`]. +pub fn initialize_handler() -> std::io::Result { + Ok(LocalDistantApiServerHandler::new( + LocalDistantApi::initialize()?, + )) +} diff --git a/distant-core/tests/stress/distant/large_file.rs b/distant-local/tests/stress/distant/large_file.rs similarity index 100% rename from distant-core/tests/stress/distant/large_file.rs rename to distant-local/tests/stress/distant/large_file.rs diff --git a/distant-core/tests/stress/distant/mod.rs b/distant-local/tests/stress/distant/mod.rs similarity index 100% rename from distant-core/tests/stress/distant/mod.rs rename to distant-local/tests/stress/distant/mod.rs diff --git a/distant-core/tests/stress/distant/watch.rs b/distant-local/tests/stress/distant/watch.rs similarity index 100% rename from distant-core/tests/stress/distant/watch.rs rename to distant-local/tests/stress/distant/watch.rs diff --git a/distant-core/tests/stress/fixtures.rs b/distant-local/tests/stress/fixtures.rs similarity index 95% rename from distant-core/tests/stress/fixtures.rs rename to distant-local/tests/stress/fixtures.rs index 05563b9c..63ed8bfc 100644 --- a/distant-core/tests/stress/fixtures.rs +++ b/distant-local/tests/stress/fixtures.rs @@ -5,7 +5,8 @@ use distant_core::net::auth::{DummyAuthHandler, Verifier}; use distant_core::net::client::{Client, TcpConnector}; use distant_core::net::common::PortRange; use distant_core::net::server::Server; -use distant_core::{DistantApiServerHandler, DistantClient, LocalDistantApi}; +use distant_core::{DistantApiServerHandler, DistantClient}; +use distant_local::LocalDistantApi; use rstest::*; use tokio::sync::mpsc; diff --git a/distant-core/tests/stress/mod.rs b/distant-local/tests/stress/mod.rs similarity index 100% rename from distant-core/tests/stress/mod.rs rename to distant-local/tests/stress/mod.rs diff --git a/distant-core/tests/stress_tests.rs b/distant-local/tests/stress_tests.rs similarity index 100% rename from distant-core/tests/stress_tests.rs rename to distant-local/tests/stress_tests.rs diff --git a/distant-net/Cargo.toml b/distant-net/Cargo.toml index 39452d28..a3496a50 100644 --- a/distant-net/Cargo.toml +++ b/distant-net/Cargo.toml @@ -18,23 +18,23 @@ chacha20poly1305 = "0.10.1" derive_more = { version = "0.99.17", default-features = false, features = ["as_mut", "as_ref", "deref", "deref_mut", "display", "from", "error", "into", "into_iterator", "is_variant", "try_into"] } distant-auth = { version = "=0.20.0-alpha.7", path = "../distant-auth" } dyn-clone = "1.0.11" -flate2 = "1.0.25" +flate2 = "1.0.26" hex = "0.4.3" hkdf = "0.12.3" -log = "0.4.17" +log = "0.4.18" paste = "1.0.12" -p256 = { version = "0.13.0", features = ["ecdh", "pem"] } +p256 = { version = "0.13.2", features = ["ecdh", "pem"] } rand = { version = "0.8.5", features = ["getrandom"] } rmp-serde = "1.1.1" sha2 = "0.10.6" -serde = { version = "1.0.159", features = ["derive"] } +serde = { version = "1.0.163", features = ["derive"] } serde_bytes = "0.11.9" strum = { version = "0.24.1", features = ["derive"] } -tokio = { version = "1.27.0", features = ["full"] } +tokio = { version = "1.28.2", features = ["full"] } [dev-dependencies] distant-auth = { version = "=0.20.0-alpha.7", path = "../distant-auth", features = ["tests"] } env_logger = "0.10.0" -serde_json = "1.0.95" +serde_json = "1.0.96" tempfile = "3.5.0" test-log = "0.2.11" diff --git a/distant-net/src/authentication.rs b/distant-net/src/authentication.rs index 8ace4a37..19c5e719 100644 --- a/distant-net/src/authentication.rs +++ b/distant-net/src/authentication.rs @@ -1,10 +1,11 @@ -use crate::common::utils; -use crate::common::{FramedTransport, Transport}; +use std::io; + use async_trait::async_trait; use distant_auth::msg::*; use distant_auth::{AuthHandler, Authenticate, Authenticator}; use log::*; -use std::io; + +use crate::common::{utils, FramedTransport, Transport}; macro_rules! write_frame { ($transport:expr, $data:expr) => {{ diff --git a/distant-net/src/common/transport/framed.rs b/distant-net/src/common/transport/framed.rs index da0bf8b1..d5dded84 100644 --- a/distant-net/src/common/transport/framed.rs +++ b/distant-net/src/common/transport/framed.rs @@ -9,8 +9,7 @@ use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; use super::{InmemoryTransport, Interest, Ready, Reconnectable, Transport}; -use crate::common::utils; -use crate::common::SecretKey32; +use crate::common::{utils, SecretKey32}; mod backup; mod codec; diff --git a/distant-net/src/lib.rs b/distant-net/src/lib.rs index 8356caf0..bd0f0977 100644 --- a/distant-net/src/lib.rs +++ b/distant-net/src/lib.rs @@ -5,8 +5,7 @@ pub mod manager; pub mod server; pub use client::{Client, ReconnectStrategy}; -pub use server::Server; -pub use {log, paste}; - /// Authentication functionality tied to network operations. pub use distant_auth as auth; +pub use server::Server; +pub use {log, paste}; diff --git a/distant-protocol/Cargo.toml b/distant-protocol/Cargo.toml index 30630dc7..45c79a0d 100644 --- a/distant-protocol/Cargo.toml +++ b/distant-protocol/Cargo.toml @@ -16,10 +16,10 @@ default = [] tests = [] [dependencies] -bitflags = "2.0.2" +bitflags = "2.3.1" derive_more = { version = "0.99.17", default-features = false, features = ["deref", "deref_mut", "display", "from", "error", "into", "into_iterator", "is_variant"] } -regex = "1.7.3" -serde = { version = "1.0.159", features = ["derive"] } +regex = "1.8.3" +serde = { version = "1.0.163", features = ["derive"] } serde_bytes = "0.11.9" strum = { version = "0.24.1", features = ["derive"] } diff --git a/distant-protocol/src/common/permissions.rs b/distant-protocol/src/common/permissions.rs index 8f20b062..ec564eed 100644 --- a/distant-protocol/src/common/permissions.rs +++ b/distant-protocol/src/common/permissions.rs @@ -96,6 +96,7 @@ impl Permissions { other_exec: None, } } + /// Creates a set of [`Permissions`] that indicate globally writable status. /// /// ``` diff --git a/distant-protocol/src/response.rs b/distant-protocol/src/response.rs index a0d9e884..30c204b7 100644 --- a/distant-protocol/src/response.rs +++ b/distant-protocol/src/response.rs @@ -612,9 +612,10 @@ mod tests { } mod changed { + use std::path::PathBuf; + use super::*; use crate::common::ChangeKind; - use std::path::PathBuf; #[test] fn should_be_able_to_serialize_to_json() { @@ -742,9 +743,10 @@ mod tests { } mod metadata { + use std::path::PathBuf; + use super::*; use crate::common::{FileType, UnixMetadata, WindowsMetadata}; - use std::path::PathBuf; #[test] fn should_be_able_to_serialize_minimal_payload_to_json() { @@ -1219,9 +1221,10 @@ mod tests { } mod search_results { + use std::path::PathBuf; + use super::*; use crate::common::{SearchQueryContentsMatch, SearchQueryMatch, SearchQuerySubmatch}; - use std::path::PathBuf; #[test] fn should_be_able_to_serialize_to_json() { @@ -1768,9 +1771,10 @@ mod tests { } mod system_info { - use super::*; use std::path::PathBuf; + use super::*; + #[test] fn should_be_able_to_serialize_to_json() { let payload = Response::SystemInfo(SystemInfo { diff --git a/distant-ssh2/Cargo.toml b/distant-ssh2/Cargo.toml index 3985a1cd..337377ac 100644 --- a/distant-ssh2/Cargo.toml +++ b/distant-ssh2/Cargo.toml @@ -17,33 +17,33 @@ ssh2 = ["wezterm-ssh/ssh2", "wezterm-ssh/vendored-openssl-ssh2"] [dependencies] async-compat = "0.2.1" -async-once-cell = "0.4.4" +async-once-cell = "0.5.2" async-trait = "0.1.68" derive_more = { version = "0.99.17", default-features = false, features = ["display", "error"] } distant-core = { version = "=0.20.0-alpha.7", path = "../distant-core" } futures = "0.3.28" hex = "0.4.3" -log = "0.4.17" +log = "0.4.18" rand = { version = "0.8.5", features = ["getrandom"] } rpassword = "7.2.0" shell-words = "1.1.0" smol = "1.3.0" -tokio = { version = "1.27.0", features = ["full"] } +tokio = { version = "1.28.2", features = ["full"] } typed-path = "0.3.2" wezterm-ssh = { version = "0.4.0", default-features = false } winsplit = "0.1.0" # Optional serde support for data structures -serde = { version = "1.0.159", features = ["derive"], optional = true } +serde = { version = "1.0.163", features = ["derive"], optional = true } [dev-dependencies] -anyhow = "1.0.70" -assert_fs = "1.0.12" -dunce = "1.0.3" +anyhow = "1.0.71" +assert_fs = "1.0.13" +dunce = "1.0.4" env_logger = "0.10.0" indoc = "2.0.1" -once_cell = "1.17.1" -predicates = "3.0.2" +once_cell = "1.17.2" +predicates = "3.0.3" rstest = "0.17.0" test-log = "0.2.11" which = "4.4.0" diff --git a/distant-ssh2/tests/ssh2/launched.rs b/distant-ssh2/tests/ssh2/launched.rs deleted file mode 100644 index 5237e917..00000000 --- a/distant-ssh2/tests/ssh2/launched.rs +++ /dev/null @@ -1,1466 +0,0 @@ -use std::path::Path; -use std::time::Duration; - -use assert_fs::prelude::*; -use assert_fs::TempDir; -use distant_core::protocol::{ChangeKindSet, Environment, FileType, Metadata}; -use distant_core::{DistantChannelExt, DistantClient}; -use once_cell::sync::Lazy; -use predicates::prelude::*; -use rstest::*; -use test_log::test; - -use crate::sshd::*; - -static TEMP_SCRIPT_DIR: Lazy = Lazy::new(|| TempDir::new().unwrap()); -static SCRIPT_RUNNER: Lazy = Lazy::new(|| String::from("bash")); - -static ECHO_ARGS_TO_STDOUT_SH: Lazy = Lazy::new(|| { - let script = TEMP_SCRIPT_DIR.child("echo_args_to_stdout.sh"); - script - .write_str(indoc::indoc!( - r#" - #/usr/bin/env bash - printf "%s" "$*" - "# - )) - .unwrap(); - script -}); - -static ECHO_ARGS_TO_STDERR_SH: Lazy = Lazy::new(|| { - let script = TEMP_SCRIPT_DIR.child("echo_args_to_stderr.sh"); - script - .write_str(indoc::indoc!( - r#" - #/usr/bin/env bash - printf "%s" "$*" 1>&2 - "# - )) - .unwrap(); - script -}); - -static ECHO_STDIN_TO_STDOUT_SH: Lazy = Lazy::new(|| { - let script = TEMP_SCRIPT_DIR.child("echo_stdin_to_stdout.sh"); - script - .write_str(indoc::indoc!( - r#" - #/usr/bin/env bash - while IFS= read; do echo "$REPLY"; done - "# - )) - .unwrap(); - script -}); - -static SLEEP_SH: Lazy = Lazy::new(|| { - let script = TEMP_SCRIPT_DIR.child("sleep.sh"); - script - .write_str(indoc::indoc!( - r#" - #!/usr/bin/env bash - sleep "$1" - "# - )) - .unwrap(); - script -}); - -static DOES_NOT_EXIST_BIN: Lazy = - Lazy::new(|| TEMP_SCRIPT_DIR.child("does_not_exist_bin")); - -#[rstest] -#[test(tokio::test)] -async fn read_file_should_fail_if_file_missing(#[future] launched_client: Ctx) { - let mut client = launched_client.await; - let temp = assert_fs::TempDir::new().unwrap(); - let path = temp.child("missing-file").path().to_path_buf(); - - let _ = client.read_file(path).await.unwrap_err(); -} - -#[rstest] -#[test(tokio::test)] -async fn read_file_should_send_blob_with_file_contents( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - - let temp = assert_fs::TempDir::new().unwrap(); - let file = temp.child("test-file"); - file.write_str("some file contents").unwrap(); - - let bytes = client.read_file(file.path().to_path_buf()).await.unwrap(); - assert_eq!(bytes, b"some file contents"); -} - -#[rstest] -#[test(tokio::test)] -async fn read_file_text_should_send_error_if_fails_to_read_file( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - - let temp = assert_fs::TempDir::new().unwrap(); - let path = temp.child("missing-file").path().to_path_buf(); - - let _ = client.read_file_text(path).await.unwrap_err(); -} - -#[rstest] -#[test(tokio::test)] -async fn read_file_text_should_send_text_with_file_contents( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - - let temp = assert_fs::TempDir::new().unwrap(); - let file = temp.child("test-file"); - file.write_str("some file contents").unwrap(); - - let text = client - .read_file_text(file.path().to_path_buf()) - .await - .unwrap(); - assert_eq!(text, "some file contents"); -} - -#[rstest] -#[test(tokio::test)] -async fn write_file_should_send_error_if_fails_to_write_file( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - - // Create a temporary path and add to it to ensure that there are - // extra components that don't exist to cause writing to fail - let temp = assert_fs::TempDir::new().unwrap(); - let file = temp.child("dir").child("test-file"); - - let _ = client - .write_file(file.path().to_path_buf(), b"some text".to_vec()) - .await - .unwrap_err(); - - // Also verify that we didn't actually create the file - file.assert(predicate::path::missing()); -} - -#[rstest] -#[test(tokio::test)] -async fn write_file_should_send_ok_when_successful(#[future] launched_client: Ctx) { - let mut client = launched_client.await; - - // Path should point to a file that does not exist, but all - // other components leading up to it do - let temp = assert_fs::TempDir::new().unwrap(); - let file = temp.child("test-file"); - - client - .write_file(file.path().to_path_buf(), b"some text".to_vec()) - .await - .unwrap(); - - // Also verify that we actually did create the file - // with the associated contents - file.assert("some text"); -} - -#[rstest] -#[test(tokio::test)] -async fn write_file_text_should_send_error_if_fails_to_write_file( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - - // Create a temporary path and add to it to ensure that there are - // extra components that don't exist to cause writing to fail - let temp = assert_fs::TempDir::new().unwrap(); - let file = temp.child("dir").child("test-file"); - - let _ = client - .write_file_text(file.path().to_path_buf(), "some text".to_string()) - .await - .unwrap_err(); - - // Also verify that we didn't actually create the file - file.assert(predicate::path::missing()); -} - -#[rstest] -#[test(tokio::test)] -async fn write_file_text_should_send_ok_when_successful( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - - // Path should point to a file that does not exist, but all - // other components leading up to it do - let temp = assert_fs::TempDir::new().unwrap(); - let file = temp.child("test-file"); - - client - .write_file_text(file.path().to_path_buf(), "some text".to_string()) - .await - .unwrap(); - - // Also verify that we actually did create the file - // with the associated contents - file.assert("some text"); -} - -#[rstest] -#[test(tokio::test)] -async fn append_file_should_send_error_if_fails_to_create_file( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - - // Create a temporary path and add to it to ensure that there are - // extra components that don't exist to cause writing to fail - let temp = assert_fs::TempDir::new().unwrap(); - let file = temp.child("dir").child("test-file"); - - let _ = client - .append_file(file.path().to_path_buf(), b"some extra contents".to_vec()) - .await - .unwrap_err(); - - // Also verify that we didn't actually create the file - file.assert(predicate::path::missing()); -} - -#[rstest] -#[test(tokio::test)] -async fn append_file_should_create_file_if_missing(#[future] launched_client: Ctx) { - let mut client = launched_client.await; - - // Don't create the file directly, but define path - // where the file should be - let temp = assert_fs::TempDir::new().unwrap(); - let file = temp.child("test-file"); - - client - .append_file(file.path().to_path_buf(), b"some extra contents".to_vec()) - .await - .unwrap(); - - // Yield to allow chance to finish appending to file - tokio::time::sleep(Duration::from_millis(50)).await; - - // Also verify that we actually did create to the file - file.assert("some extra contents"); -} - -#[rstest] -#[test(tokio::test)] -async fn append_file_should_send_ok_when_successful(#[future] launched_client: Ctx) { - let mut client = launched_client.await; - - // Create a temporary file and fill it with some contents - let temp = assert_fs::TempDir::new().unwrap(); - let file = temp.child("test-file"); - file.write_str("some file contents").unwrap(); - - client - .append_file(file.path().to_path_buf(), b"some extra contents".to_vec()) - .await - .unwrap(); - - // Yield to allow chance to finish appending to file - tokio::time::sleep(Duration::from_millis(50)).await; - - // Also verify that we actually did append to the file - file.assert("some file contentssome extra contents"); -} - -#[rstest] -#[test(tokio::test)] -async fn append_file_text_should_send_error_if_fails_to_create_file( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - - // Create a temporary path and add to it to ensure that there are - // extra components that don't exist to cause writing to fail - let temp = assert_fs::TempDir::new().unwrap(); - let file = temp.child("dir").child("test-file"); - - let _ = client - .append_file_text(file.path().to_path_buf(), "some extra contents".to_string()) - .await - .unwrap_err(); - - // Also verify that we didn't actually create the file - file.assert(predicate::path::missing()); -} - -#[rstest] -#[test(tokio::test)] -async fn append_file_text_should_create_file_if_missing( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - - // Don't create the file directly, but define path - // where the file should be - let temp = assert_fs::TempDir::new().unwrap(); - let file = temp.child("test-file"); - - client - .append_file_text(file.path().to_path_buf(), "some extra contents".to_string()) - .await - .unwrap(); - - // Yield to allow chance to finish appending to file - tokio::time::sleep(Duration::from_millis(50)).await; - - // Also verify that we actually did create to the file - file.assert("some extra contents"); -} - -#[rstest] -#[test(tokio::test)] -async fn append_file_text_should_send_ok_when_successful( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - - // Create a temporary file and fill it with some contents - let temp = assert_fs::TempDir::new().unwrap(); - let file = temp.child("test-file"); - file.write_str("some file contents").unwrap(); - - client - .append_file_text(file.path().to_path_buf(), "some extra contents".to_string()) - .await - .unwrap(); - - // Yield to allow chance to finish appending to file - tokio::time::sleep(Duration::from_millis(50)).await; - - // Also verify that we actually did append to the file - file.assert("some file contentssome extra contents"); -} - -#[rstest] -#[test(tokio::test)] -async fn dir_read_should_send_error_if_directory_does_not_exist( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - - let temp = assert_fs::TempDir::new().unwrap(); - let dir = temp.child("test-dir"); - - let _ = client - .read_dir( - dir.path().to_path_buf(), - /* depth */ 0, - /* absolute */ false, - /* canonicalize */ false, - /* include_root */ false, - ) - .await - .unwrap_err(); -} - -// /root/ -// /root/file1 -// /root/link1 -> /root/sub1/file2 -// /root/sub1/ -// /root/sub1/file2 -async fn setup_dir() -> assert_fs::TempDir { - let root_dir = assert_fs::TempDir::new().unwrap(); - root_dir.child("file1").touch().unwrap(); - - let sub1 = root_dir.child("sub1"); - sub1.create_dir_all().unwrap(); - - let file2 = sub1.child("file2"); - file2.touch().unwrap(); - - let link1 = root_dir.child("link1"); - link1.symlink_to_file(file2.path()).unwrap(); - - root_dir -} - -#[rstest] -#[test(tokio::test)] -async fn dir_read_should_support_depth_limits(#[future] launched_client: Ctx) { - let mut client = launched_client.await; - - // Create directory with some nested items - let root_dir = setup_dir().await; - - let (entries, _) = client - .read_dir( - root_dir.path().to_path_buf(), - /* depth */ 1, - /* absolute */ false, - /* canonicalize */ false, - /* include_root */ false, - ) - .await - .unwrap(); - - assert_eq!(entries.len(), 3, "Wrong number of entries found"); - - assert_eq!(entries[0].file_type, FileType::File); - assert_eq!(entries[0].path, Path::new("file1")); - assert_eq!(entries[0].depth, 1); - - assert_eq!(entries[1].file_type, FileType::Symlink); - assert_eq!(entries[1].path, Path::new("link1")); - assert_eq!(entries[1].depth, 1); - - assert_eq!(entries[2].file_type, FileType::Dir); - assert_eq!(entries[2].path, Path::new("sub1")); - assert_eq!(entries[2].depth, 1); -} - -#[rstest] -#[test(tokio::test)] -async fn dir_read_should_support_unlimited_depth_using_zero( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - - // Create directory with some nested items - let root_dir = setup_dir().await; - - let (entries, _) = client - .read_dir( - root_dir.path().to_path_buf(), - /* depth */ 0, - /* absolute */ false, - /* canonicalize */ false, - /* include_root */ false, - ) - .await - .unwrap(); - - assert_eq!(entries.len(), 4, "Wrong number of entries found"); - - assert_eq!(entries[0].file_type, FileType::File); - assert_eq!(entries[0].path, Path::new("file1")); - assert_eq!(entries[0].depth, 1); - - assert_eq!(entries[1].file_type, FileType::Symlink); - assert_eq!(entries[1].path, Path::new("link1")); - assert_eq!(entries[1].depth, 1); - - assert_eq!(entries[2].file_type, FileType::Dir); - assert_eq!(entries[2].path, Path::new("sub1")); - assert_eq!(entries[2].depth, 1); - - assert_eq!(entries[3].file_type, FileType::File); - assert_eq!(entries[3].path, Path::new("sub1").join("file2")); - assert_eq!(entries[3].depth, 2); -} - -#[rstest] -#[test(tokio::test)] -async fn dir_read_should_support_including_directory_in_returned_entries( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - - // Create directory with some nested items - let root_dir = setup_dir().await; - - let (entries, _) = client - .read_dir( - root_dir.path().to_path_buf(), - /* depth */ 1, - /* absolute */ false, - /* canonicalize */ false, - /* include_root */ true, - ) - .await - .unwrap(); - - assert_eq!(entries.len(), 4, "Wrong number of entries found"); - - // NOTE: Root entry is always absolute, resolved path - assert_eq!(entries[0].file_type, FileType::Dir); - assert_eq!( - entries[0].path, - dunce::canonicalize(root_dir.path()).unwrap() - ); - assert_eq!(entries[0].depth, 0); - - assert_eq!(entries[1].file_type, FileType::File); - assert_eq!(entries[1].path, Path::new("file1")); - assert_eq!(entries[1].depth, 1); - - assert_eq!(entries[2].file_type, FileType::Symlink); - assert_eq!(entries[2].path, Path::new("link1")); - assert_eq!(entries[2].depth, 1); - - assert_eq!(entries[3].file_type, FileType::Dir); - assert_eq!(entries[3].path, Path::new("sub1")); - assert_eq!(entries[3].depth, 1); -} - -#[rstest] -#[test(tokio::test)] -async fn dir_read_should_support_returning_absolute_paths( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - - // Create directory with some nested items - let root_dir = setup_dir().await; - - let (entries, _) = client - .read_dir( - root_dir.path().to_path_buf(), - /* depth */ 1, - /* absolute */ true, - /* canonicalize */ false, - /* include_root */ false, - ) - .await - .unwrap(); - - assert_eq!(entries.len(), 3, "Wrong number of entries found"); - let root_path = dunce::canonicalize(root_dir.path()).unwrap(); - - assert_eq!(entries[0].file_type, FileType::File); - assert_eq!(entries[0].path, root_path.join("file1")); - assert_eq!(entries[0].depth, 1); - - assert_eq!(entries[1].file_type, FileType::Symlink); - assert_eq!(entries[1].path, root_path.join("link1")); - assert_eq!(entries[1].depth, 1); - - assert_eq!(entries[2].file_type, FileType::Dir); - assert_eq!(entries[2].path, root_path.join("sub1")); - assert_eq!(entries[2].depth, 1); -} - -#[rstest] -#[test(tokio::test)] -async fn dir_read_should_support_returning_canonicalized_paths( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - - // Create directory with some nested items - let root_dir = setup_dir().await; - - let (entries, _) = client - .read_dir( - root_dir.path().to_path_buf(), - /* depth */ 1, - /* absolute */ false, - /* canonicalize */ true, - /* include_root */ false, - ) - .await - .unwrap(); - - assert_eq!(entries.len(), 3, "Wrong number of entries found"); - println!("{:?}", entries); - - assert_eq!(entries[0].file_type, FileType::File); - assert_eq!(entries[0].path, Path::new("file1")); - assert_eq!(entries[0].depth, 1); - - // Symlink should be resolved from $ROOT/link1 -> $ROOT/sub1/file2 - assert_eq!(entries[1].file_type, FileType::Symlink); - assert_eq!(entries[1].path, Path::new("sub1").join("file2")); - assert_eq!(entries[1].depth, 1); - - assert_eq!(entries[2].file_type, FileType::Dir); - assert_eq!(entries[2].path, Path::new("sub1")); - assert_eq!(entries[2].depth, 1); -} - -#[rstest] -#[test(tokio::test)] -async fn create_dir_should_send_error_if_fails(#[future] launched_client: Ctx) { - let mut client = launched_client.await; - - // Make a path that has multiple non-existent components - // so the creation will fail - let root_dir = setup_dir().await; - let path = root_dir.path().join("nested").join("new-dir"); - - let _ = client - .create_dir(path.to_path_buf(), /* all */ false) - .await - .unwrap_err(); - - // Also verify that the directory was not actually created - assert!(!path.exists(), "Path unexpectedly exists"); -} - -#[rstest] -#[test(tokio::test)] -async fn create_dir_should_send_ok_when_successful(#[future] launched_client: Ctx) { - let mut client = launched_client.await; - let root_dir = setup_dir().await; - let path = root_dir.path().join("new-dir"); - - client - .create_dir(path.to_path_buf(), /* all */ false) - .await - .unwrap(); - - // Also verify that the directory was actually created - assert!(path.exists(), "Directory not created"); -} - -#[rstest] -#[test(tokio::test)] -async fn create_dir_should_support_creating_multiple_dir_components( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - let root_dir = setup_dir().await; - let path = root_dir.path().join("nested").join("new-dir"); - - client - .create_dir(path.to_path_buf(), /* all */ true) - .await - .unwrap(); - - // Also verify that the directory was actually created - assert!(path.exists(), "Directory not created"); -} - -#[rstest] -#[test(tokio::test)] -async fn remove_should_send_error_on_failure(#[future] launched_client: Ctx) { - let mut client = launched_client.await; - let temp = assert_fs::TempDir::new().unwrap(); - let file = temp.child("missing-file"); - - let _ = client - .remove(file.path().to_path_buf(), /* false */ false) - .await - .unwrap_err(); - - // Also, verify that path does not exist - file.assert(predicate::path::missing()); -} - -#[rstest] -#[test(tokio::test)] -async fn remove_should_support_deleting_a_directory(#[future] launched_client: Ctx) { - let mut client = launched_client.await; - let temp = assert_fs::TempDir::new().unwrap(); - let dir = temp.child("dir"); - dir.create_dir_all().unwrap(); - - client - .remove(dir.path().to_path_buf(), /* false */ false) - .await - .unwrap(); - - // Also, verify that path does not exist - dir.assert(predicate::path::missing()); -} - -#[rstest] -#[test(tokio::test)] -async fn remove_should_delete_nonempty_directory_if_force_is_true( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - let temp = assert_fs::TempDir::new().unwrap(); - let dir = temp.child("dir"); - dir.create_dir_all().unwrap(); - dir.child("file").touch().unwrap(); - - client - .remove(dir.path().to_path_buf(), /* false */ true) - .await - .unwrap(); - - // Also, verify that path does not exist - dir.assert(predicate::path::missing()); -} - -#[rstest] -#[test(tokio::test)] -async fn remove_should_support_deleting_a_single_file( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - let temp = assert_fs::TempDir::new().unwrap(); - let file = temp.child("some-file"); - file.touch().unwrap(); - - client - .remove(file.path().to_path_buf(), /* false */ false) - .await - .unwrap(); - - // Also, verify that path does not exist - file.assert(predicate::path::missing()); -} - -#[rstest] -#[test(tokio::test)] -async fn copy_should_send_error_on_failure(#[future] launched_client: Ctx) { - let mut client = launched_client.await; - let temp = assert_fs::TempDir::new().unwrap(); - let src = temp.child("src"); - let dst = temp.child("dst"); - - let _ = client - .copy(src.path().to_path_buf(), dst.path().to_path_buf()) - .await - .unwrap_err(); - - // Also, verify that destination does not exist - dst.assert(predicate::path::missing()); -} - -#[rstest] -#[test(tokio::test)] -async fn copy_should_support_copying_an_entire_directory( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - let temp = assert_fs::TempDir::new().unwrap(); - - let src = temp.child("src"); - src.create_dir_all().unwrap(); - let src_file = src.child("file"); - src_file.write_str("some contents").unwrap(); - - let dst = temp.child("dst"); - let dst_file = dst.child("file"); - - client - .copy(src.path().to_path_buf(), dst.path().to_path_buf()) - .await - .unwrap(); - - // Verify that we have source and destination directories and associated contents - src.assert(predicate::path::is_dir()); - src_file.assert(predicate::path::is_file()); - dst.assert(predicate::path::is_dir()); - dst_file.assert(predicate::path::eq_file(src_file.path())); -} - -#[rstest] -#[test(tokio::test)] -async fn copy_should_support_copying_an_empty_directory( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - let temp = assert_fs::TempDir::new().unwrap(); - let src = temp.child("src"); - src.create_dir_all().unwrap(); - let dst = temp.child("dst"); - - client - .copy(src.path().to_path_buf(), dst.path().to_path_buf()) - .await - .unwrap(); - - // Verify that we still have source and destination directories - src.assert(predicate::path::is_dir()); - dst.assert(predicate::path::is_dir()); -} - -#[rstest] -#[test(tokio::test)] -async fn copy_should_support_copying_a_directory_that_only_contains_directories( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - let temp = assert_fs::TempDir::new().unwrap(); - - let src = temp.child("src"); - src.create_dir_all().unwrap(); - let src_dir = src.child("dir"); - src_dir.create_dir_all().unwrap(); - - let dst = temp.child("dst"); - let dst_dir = dst.child("dir"); - - client - .copy(src.path().to_path_buf(), dst.path().to_path_buf()) - .await - .unwrap(); - - // Verify that we have source and destination directories and associated contents - src.assert(predicate::path::is_dir().name("src")); - src_dir.assert(predicate::path::is_dir().name("src/dir")); - dst.assert(predicate::path::is_dir().name("dst")); - dst_dir.assert(predicate::path::is_dir().name("dst/dir")); -} - -#[rstest] -#[test(tokio::test)] -async fn copy_should_support_copying_a_single_file(#[future] launched_client: Ctx) { - let mut client = launched_client.await; - let temp = assert_fs::TempDir::new().unwrap(); - let src = temp.child("src"); - src.write_str("some text").unwrap(); - let dst = temp.child("dst"); - - client - .copy(src.path().to_path_buf(), dst.path().to_path_buf()) - .await - .unwrap(); - - // Verify that we still have source and that destination has source's contents - src.assert(predicate::path::is_file()); - dst.assert(predicate::path::eq_file(src.path())); -} - -#[rstest] -#[test(tokio::test)] -async fn rename_should_fail_if_path_missing(#[future] launched_client: Ctx) { - let mut client = launched_client.await; - let temp = assert_fs::TempDir::new().unwrap(); - let src = temp.child("src"); - let dst = temp.child("dst"); - - let _ = client - .rename(src.path().to_path_buf(), dst.path().to_path_buf()) - .await - .unwrap_err(); - - // Also, verify that destination does not exist - dst.assert(predicate::path::missing()); -} - -#[rstest] -#[test(tokio::test)] -async fn rename_should_support_renaming_an_entire_directory( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - let temp = assert_fs::TempDir::new().unwrap(); - - let src = temp.child("src"); - src.create_dir_all().unwrap(); - let src_file = src.child("file"); - src_file.write_str("some contents").unwrap(); - - let dst = temp.child("dst"); - let dst_file = dst.child("file"); - - client - .rename(src.path().to_path_buf(), dst.path().to_path_buf()) - .await - .unwrap(); - - // Verify that we moved the contents - src.assert(predicate::path::missing()); - src_file.assert(predicate::path::missing()); - dst.assert(predicate::path::is_dir()); - dst_file.assert("some contents"); -} - -#[rstest] -#[test(tokio::test)] -async fn rename_should_support_renaming_a_single_file( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - let temp = assert_fs::TempDir::new().unwrap(); - let src = temp.child("src"); - src.write_str("some text").unwrap(); - let dst = temp.child("dst"); - - client - .rename(src.path().to_path_buf(), dst.path().to_path_buf()) - .await - .unwrap(); - - // Verify that we moved the file - src.assert(predicate::path::missing()); - dst.assert("some text"); -} - -#[rstest] -#[test(tokio::test)] -async fn watch_should_succeed(#[future] launched_client: Ctx) { - // NOTE: Supporting multiple replies being sent back as part of creating, modifying, etc. - let mut client = launched_client.await; - let temp = assert_fs::TempDir::new().unwrap(); - - let file = temp.child("file"); - file.touch().unwrap(); - - let _ = client - .watch( - file.path().to_path_buf(), - /* recursive */ false, - /* only */ ChangeKindSet::default(), - /* except */ ChangeKindSet::default(), - ) - .await - .unwrap(); -} - -#[rstest] -#[test(tokio::test)] -async fn exists_should_send_true_if_path_exists(#[future] launched_client: Ctx) { - let mut client = launched_client.await; - let temp = assert_fs::TempDir::new().unwrap(); - let file = temp.child("file"); - file.touch().unwrap(); - - let exists = client.exists(file.path().to_path_buf()).await.unwrap(); - assert!(exists, "Expected exists to be true, but was false"); -} - -#[rstest] -#[test(tokio::test)] -async fn exists_should_send_false_if_path_does_not_exist( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - let temp = assert_fs::TempDir::new().unwrap(); - let file = temp.child("file"); - - let exists = client.exists(file.path().to_path_buf()).await.unwrap(); - assert!(!exists, "Expected exists to be false, but was true"); -} - -#[rstest] -#[test(tokio::test)] -async fn metadata_should_send_error_on_failure(#[future] launched_client: Ctx) { - let mut client = launched_client.await; - let temp = assert_fs::TempDir::new().unwrap(); - let file = temp.child("file"); - - let _ = client - .metadata( - file.path().to_path_buf(), - /* canonicalize */ false, - /* resolve_file_type */ false, - ) - .await - .unwrap_err(); -} - -#[rstest] -#[test(tokio::test)] -async fn metadata_should_send_back_metadata_on_file_if_exists( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - let temp = assert_fs::TempDir::new().unwrap(); - let file = temp.child("file"); - file.write_str("some text").unwrap(); - - let metadata = client - .metadata( - file.path().to_path_buf(), - /* canonicalize */ false, - /* resolve_file_type */ false, - ) - .await - .unwrap(); - - assert!( - matches!( - metadata, - Metadata { - canonicalized_path: None, - file_type: FileType::File, - len: 9, - readonly: false, - .. - } - ), - "{:?}", - metadata - ); -} - -#[cfg(unix)] -#[rstest] -#[test(tokio::test)] -async fn metadata_should_include_unix_specific_metadata_on_unix_platform( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - let temp = assert_fs::TempDir::new().unwrap(); - let file = temp.child("file"); - file.write_str("some text").unwrap(); - - let metadata = client - .metadata( - file.path().to_path_buf(), - /* canonicalize */ false, - /* resolve_file_type */ false, - ) - .await - .unwrap(); - - #[allow(clippy::match_single_binding)] - match metadata { - Metadata { unix, windows, .. } => { - assert!(unix.is_some(), "Unexpectedly missing unix metadata on unix"); - assert!( - windows.is_none(), - "Unexpectedly got windows metadata on unix" - ); - } - } -} - -#[cfg(windows)] -#[rstest] -#[test(tokio::test)] -async fn metadata_should_include_windows_specific_metadata_on_windows_platform( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - let temp = assert_fs::TempDir::new().unwrap(); - let file = temp.child("file"); - file.write_str("some text").unwrap(); - - let metadata = client - .metadata( - file.path().to_path_buf(), - /* canonicalize */ false, - /* resolve_file_type */ false, - ) - .await - .unwrap(); - - #[allow(clippy::match_single_binding)] - match metadata { - Metadata { unix, windows, .. } => { - assert!( - windows.is_some(), - "Unexpectedly missing windows metadata on windows" - ); - assert!(unix.is_none(), "Unexpectedly got unix metadata on windows"); - } - } -} - -#[rstest] -#[test(tokio::test)] -async fn metadata_should_send_back_metadata_on_dir_if_exists( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - let temp = assert_fs::TempDir::new().unwrap(); - let dir = temp.child("dir"); - dir.create_dir_all().unwrap(); - - let metadata = client - .metadata( - dir.path().to_path_buf(), - /* canonicalize */ false, - /* resolve_file_type */ false, - ) - .await - .unwrap(); - - assert!( - matches!( - metadata, - Metadata { - canonicalized_path: None, - file_type: FileType::Dir, - readonly: false, - .. - } - ), - "{:?}", - metadata - ); -} - -#[rstest] -#[test(tokio::test)] -async fn metadata_should_send_back_metadata_on_symlink_if_exists( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - let temp = assert_fs::TempDir::new().unwrap(); - let file = temp.child("file"); - file.write_str("some text").unwrap(); - - let symlink = temp.child("link"); - symlink.symlink_to_file(file.path()).unwrap(); - - let metadata = client - .metadata( - symlink.path().to_path_buf(), - /* canonicalize */ false, - /* resolve_file_type */ false, - ) - .await - .unwrap(); - - assert!( - matches!( - metadata, - Metadata { - canonicalized_path: None, - file_type: FileType::Symlink, - readonly: false, - .. - } - ), - "{:?}", - metadata - ); -} - -#[rstest] -#[test(tokio::test)] -async fn metadata_should_include_canonicalized_path_if_flag_specified( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - let temp = assert_fs::TempDir::new().unwrap(); - let file = temp.child("file"); - file.write_str("some text").unwrap(); - - let symlink = temp.child("link"); - symlink.symlink_to_file(file.path()).unwrap(); - - let metadata = client - .metadata( - symlink.path().to_path_buf(), - /* canonicalize */ true, - /* resolve_file_type */ false, - ) - .await - .unwrap(); - - match metadata { - Metadata { - canonicalized_path: Some(path), - file_type: FileType::Symlink, - readonly: false, - .. - } => assert_eq!( - path, - dunce::canonicalize(file.path()).unwrap(), - "Symlink canonicalized path does not match referenced file" - ), - x => panic!("Unexpected response: {:?}", x), - } -} - -#[rstest] -#[test(tokio::test)] -async fn metadata_should_resolve_file_type_of_symlink_if_flag_specified( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - let temp = assert_fs::TempDir::new().unwrap(); - let file = temp.child("file"); - file.write_str("some text").unwrap(); - - let symlink = temp.child("link"); - symlink.symlink_to_file(file.path()).unwrap(); - - let metadata = client - .metadata( - symlink.path().to_path_buf(), - /* canonicalize */ false, - /* resolve_file_type */ true, - ) - .await - .unwrap(); - - assert!( - matches!( - metadata, - Metadata { - file_type: FileType::File, - .. - } - ), - "{:?}", - metadata - ); -} - -#[rstest] -#[test(tokio::test)] -async fn proc_spawn_should_fail_if_process_not_found( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - - let _ = client - .spawn( - /* cmd */ DOES_NOT_EXIST_BIN.to_str().unwrap().to_string(), - /* environment */ Environment::new(), - /* current_dir */ None, - /* pty */ None, - ) - .await - .unwrap_err(); -} - -#[rstest] -#[test(tokio::test)] -async fn proc_spawn_should_return_id_of_spawned_process( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - - let proc = client - .spawn( - /* cmd */ - format!( - "{} {}", - *SCRIPT_RUNNER, - ECHO_ARGS_TO_STDOUT_SH.to_str().unwrap() - ), - /* environment */ Environment::new(), - /* current_dir */ None, - /* pty */ None, - ) - .await - .unwrap(); - assert!(proc.id() > 0); -} - -// NOTE: Ignoring on windows because it's using WSL which wants a Linux path -// with / but thinks it's on windows and is providing \ -#[rstest] -#[test(tokio::test)] -#[cfg_attr(windows, ignore)] -async fn proc_spawn_should_send_back_stdout_periodically_when_available( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - - let mut proc = client - .spawn( - /* cmd */ - format!( - "{} {} some stdout", - *SCRIPT_RUNNER, - ECHO_ARGS_TO_STDOUT_SH.to_str().unwrap() - ), - /* environment */ Environment::new(), - /* current_dir */ None, - /* pty */ None, - ) - .await - .unwrap(); - - assert_eq!( - proc.stdout.as_mut().unwrap().read().await.unwrap(), - b"some stdout" - ); - assert!( - proc.wait().await.unwrap().success, - "Process should have completed successfully" - ); -} - -// NOTE: Ignoring on windows because it's using WSL which wants a Linux path -// with / but thinks it's on windows and is providing \ -#[rstest] -#[test(tokio::test)] -#[cfg_attr(windows, ignore)] -async fn proc_spawn_should_send_back_stderr_periodically_when_available( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - - let mut proc = client - .spawn( - /* cmd */ - format!( - "{} {} some stderr", - *SCRIPT_RUNNER, - ECHO_ARGS_TO_STDERR_SH.to_str().unwrap() - ), - /* environment */ Environment::new(), - /* current_dir */ None, - /* pty */ None, - ) - .await - .unwrap(); - - assert_eq!( - proc.stderr.as_mut().unwrap().read().await.unwrap(), - b"some stderr" - ); - assert!( - proc.wait().await.unwrap().success, - "Process should have completed successfully" - ); -} - -// NOTE: Ignoring on windows because it's using WSL which wants a Linux path -// with / but thinks it's on windows and is providing \ -#[rstest] -#[test(tokio::test)] -#[cfg_attr(windows, ignore)] -async fn proc_spawn_should_send_done_signal_when_completed( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - - let proc = client - .spawn( - /* cmd */ - format!("{} {} 0.1", *SCRIPT_RUNNER, SLEEP_SH.to_str().unwrap()), - /* environment */ Environment::new(), - /* current_dir */ None, - /* pty */ None, - ) - .await - .unwrap(); - - let _ = proc.wait().await.unwrap(); -} - -#[rstest] -#[test(tokio::test)] -async fn proc_spawn_should_clear_process_from_state_when_killed( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - - let mut proc = client - .spawn( - /* cmd */ - format!("{} {} 1", *SCRIPT_RUNNER, SLEEP_SH.to_str().unwrap()), - /* environment */ Environment::new(), - /* current_dir */ None, - /* pty */ None, - ) - .await - .unwrap(); - - // Send kill signal - proc.kill().await.unwrap(); - - // Verify killed, which should be success false - let status = proc.wait().await.unwrap(); - assert!(!status.success, "Process succeeded when killed") -} - -#[rstest] -#[test(tokio::test)] -async fn proc_kill_should_fail_if_process_not_running( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - - let mut proc = client - .spawn( - /* cmd */ - format!("{} {} 1", *SCRIPT_RUNNER, SLEEP_SH.to_str().unwrap()), - /* environment */ Environment::new(), - /* current_dir */ None, - /* pty */ None, - ) - .await - .unwrap(); - - // Send kill signal - proc.kill().await.unwrap(); - - // Wait for process to be dead - let mut killer = proc.clone_killer(); - let _ = proc.wait().await.unwrap(); - - // Now send it again, which should fail - let _ = killer.kill().await.unwrap_err(); -} - -#[rstest] -#[test(tokio::test)] -async fn proc_stdin_should_fail_if_process_not_running( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - - let mut proc = client - .spawn( - /* cmd */ - format!("{} {} 1", *SCRIPT_RUNNER, SLEEP_SH.to_str().unwrap()), - /* environment */ Environment::new(), - /* current_dir */ None, - /* pty */ None, - ) - .await - .unwrap(); - - // Send kill signal - proc.kill().await.unwrap(); - - // Wait for process to be dead - let mut stdin = proc.stdin.take().unwrap(); - let _ = proc.wait().await.unwrap(); - - // Now send stdin, which should fail - let _ = stdin.write_str("some data").await.unwrap_err(); -} - -// NOTE: Ignoring on windows because it's using WSL which wants a Linux path -// with / but thinks it's on windows and is providing \ -#[rstest] -#[test(tokio::test)] -#[cfg_attr(windows, ignore)] -async fn proc_stdin_should_send_stdin_to_process(#[future] launched_client: Ctx) { - let mut client = launched_client.await; - - // First, run a program that listens for stdin - let mut proc = client - .spawn( - /* cmd */ - format!( - "{} {}", - *SCRIPT_RUNNER, - ECHO_STDIN_TO_STDOUT_SH.to_str().unwrap() - ), - /* environment */ Environment::new(), - /* current_dir */ None, - /* pty */ None, - ) - .await - .unwrap(); - - // Second, send stdin to the remote process - proc.stdin - .as_mut() - .unwrap() - .write_str("hello world\n") - .await - .unwrap(); - - // Third, check the async response of stdout to verify we got stdin - assert_eq!( - proc.stdout.as_mut().unwrap().read_string().await.unwrap(), - "hello world\n" - ); -} - -#[rstest] -#[test(tokio::test)] -async fn system_info_should_return_system_info_based_on_binary( - #[future] launched_client: Ctx, -) { - let mut client = launched_client.await; - - let system_info = client.system_info().await.unwrap(); - - assert_eq!(system_info.family, std::env::consts::FAMILY.to_string()); - assert_eq!(system_info.os, std::env::consts::OS.to_string()); - assert_eq!(system_info.arch, std::env::consts::ARCH.to_string()); - assert_eq!(system_info.main_separator, std::path::MAIN_SEPARATOR); - assert_ne!(system_info.username, ""); - assert_ne!(system_info.shell, ""); -} diff --git a/distant-ssh2/tests/ssh2/mod.rs b/distant-ssh2/tests/ssh2/mod.rs index 85a10d82..feffde44 100644 --- a/distant-ssh2/tests/ssh2/mod.rs +++ b/distant-ssh2/tests/ssh2/mod.rs @@ -1,3 +1,2 @@ mod client; -mod launched; mod ssh; diff --git a/distant-ssh2/tests/sshd/mod.rs b/distant-ssh2/tests/sshd/mod.rs index 096de64a..8af9abe6 100644 --- a/distant-ssh2/tests/sshd/mod.rs +++ b/distant-ssh2/tests/sshd/mod.rs @@ -15,7 +15,7 @@ use assert_fs::TempDir; use async_trait::async_trait; use derive_more::{Deref, DerefMut, Display}; use distant_core::DistantClient; -use distant_ssh2::{DistantLaunchOpts, Ssh, SshAuthEvent, SshAuthHandler, SshOpts}; +use distant_ssh2::{Ssh, SshAuthEvent, SshAuthHandler, SshOpts}; use log::*; use once_cell::sync::Lazy; use rstest::*; @@ -638,38 +638,6 @@ pub async fn client(sshd: Sshd) -> Ctx { } } -/// Fixture to establish a client to a launched server -#[fixture] -pub async fn launched_client(sshd: Sshd) -> Ctx { - let binary = std::env::var("DISTANT_PATH").unwrap_or_else(|_| String::from("distant")); - debug!("Setting path to distant binary as {binary}"); - - // Attempt to launch the server and connect to it, using $DISTANT_PATH as the path to the - // binary if provided, defaulting to assuming the binary is on our ssh path otherwise - // - // NOTE: Wrapping in ctx does not fully clean up the test as the launched distant server - // is not cleaned up during drop. We don't know what the server's pid is, so our - // only option would be to look up all running distant servers and kill them on drop, - // but that would cause other tests to fail. - // - // Setting an expiration of 1s would clean up running servers and possibly be good enough - let ssh_client = load_ssh_client(&sshd).await; - let mut client = ssh_client - .launch_and_connect(DistantLaunchOpts { - binary, - args: "--shutdown lonely=10".to_string(), - ..Default::default() - }) - .await - .context("Failed to launch and connect to distant server") - .unwrap(); - client.shutdown_on_drop(true); - Ctx { - sshd, - value: client, - } -} - /// Access to raw [`Ssh`] client #[fixture] pub async fn ssh(sshd: Sshd) -> Ctx { diff --git a/src/cli/commands/client.rs b/src/cli/commands/client.rs index 75046345..82fc7e1d 100644 --- a/src/cli/commands/client.rs +++ b/src/cli/commands/client.rs @@ -13,9 +13,10 @@ use distant_core::protocol::{ use distant_core::{DistantChannel, DistantChannelExt, RemoteCommand, Searcher, Watcher}; use log::*; use serde_json::json; -use tabled::object::Rows; -use tabled::style::Style; -use tabled::{Alignment, Disable, Modify, Table, Tabled}; +use tabled::settings::object::Rows; +use tabled::settings::style::Style; +use tabled::settings::{Alignment, Disable, Modify}; +use tabled::{Table, Tabled}; use tokio::sync::mpsc; use crate::cli::common::{ diff --git a/src/cli/commands/common/format.rs b/src/cli/commands/common/format.rs index 6f32e156..c6d825d6 100644 --- a/src/cli/commands/common/format.rs +++ b/src/cli/commands/common/format.rs @@ -8,9 +8,10 @@ use distant_core::protocol::{ SearchQueryPathMatch, SystemInfo, }; use log::*; -use tabled::object::Rows; -use tabled::style::Style; -use tabled::{Alignment, Disable, Modify, Table, Tabled}; +use tabled::settings::object::Rows; +use tabled::settings::style::Style; +use tabled::settings::{Alignment, Disable, Modify}; +use tabled::{Table, Tabled}; use crate::options::Format; diff --git a/src/cli/commands/server.rs b/src/cli/commands/server.rs index 1e06efcf..3bd719b2 100644 --- a/src/cli/commands/server.rs +++ b/src/cli/commands/server.rs @@ -4,7 +4,7 @@ use anyhow::Context; use distant_core::net::auth::Verifier; use distant_core::net::common::{Host, SecretKey32}; use distant_core::net::server::{Server, ServerConfig as NetServerConfig, ServerRef}; -use distant_core::{DistantApiServerHandler, DistantSingleKeyCredentials}; +use distant_core::DistantSingleKeyCredentials; use log::*; use crate::options::ServerSubcommand; @@ -140,8 +140,8 @@ async fn async_run(cmd: ServerSubcommand, _is_forked: bool) -> CliResult { "using an ephemeral port".to_string() } ); - let handler = - DistantApiServerHandler::local().context("Failed to create local distant api")?; + let handler = distant_local::initialize_handler() + .context("Failed to create local distant api")?; let server = Server::tcp() .config(NetServerConfig { shutdown: shutdown.into_inner(), diff --git a/src/options.rs b/src/options.rs index 4d087b96..e1367ddf 100644 --- a/src/options.rs +++ b/src/options.rs @@ -3981,6 +3981,7 @@ mod tests { ManagerServiceSubcommand::Install { kind: None, user: false, + args: Vec::new(), }, )), }; @@ -4008,6 +4009,7 @@ mod tests { ManagerServiceSubcommand::Install { kind: None, user: false, + args: Vec::new(), }, )), } @@ -4026,6 +4028,7 @@ mod tests { ManagerServiceSubcommand::Install { kind: None, user: false, + args: Vec::new(), }, )), }; @@ -4053,6 +4056,7 @@ mod tests { ManagerServiceSubcommand::Install { kind: None, user: false, + args: Vec::new(), }, )), } diff --git a/tests/cli/client/version.rs b/tests/cli/client/version.rs index fc4629c0..364e69e7 100644 --- a/tests/cli/client/version.rs +++ b/tests/cli/client/version.rs @@ -8,7 +8,7 @@ use crate::cli::utils::TrimmedLinesMatchPredicate; #[test_log::test] fn should_output_capabilities(ctx: DistantManagerCtx) { // Because all of our crates have the same version, we can expect it to match - let package_name = "distant-core"; + let package_name = "distant-local"; let package_version = env!("CARGO_PKG_VERSION"); let (major, minor, patch) = PROTOCOL_VERSION; diff --git a/tests/cli/utils.rs b/tests/cli/utils.rs index df8ca859..c5973007 100644 --- a/tests/cli/utils.rs +++ b/tests/cli/utils.rs @@ -3,9 +3,10 @@ use ::predicates::prelude::*; mod predicates; mod reader; -pub use self::predicates::TrimmedLinesMatchPredicate; pub use reader::ThreadedReader; +pub use self::predicates::TrimmedLinesMatchPredicate; + /// Produces a regex predicate using the given string pub fn regex_pred(s: &str) -> ::predicates::str::RegexPredicate { predicate::str::is_match(s).unwrap() diff --git a/tests/cli/utils/predicates.rs b/tests/cli/utils/predicates.rs index d336b513..36915af7 100644 --- a/tests/cli/utils/predicates.rs +++ b/tests/cli/utils/predicates.rs @@ -1,6 +1,7 @@ +use std::fmt; + use predicates::reflection::PredicateReflection; use predicates::Predicate; -use std::fmt; /// Checks if lines of text match the provided, trimming each line /// of both before comparing.