rust-cli / rexpect Goto Github PK
View Code? Open in Web Editor NEWRust port of pexpect
License: MIT License
Rust port of pexpect
License: MIT License
Try to read a utf-8 character, program panic.
How to fix this problem?
panicked at 'byte index 1 is not a char boundary; it is inside 'é' (bytes 0..2) of `éª�æ�¶ ...
stack backtrace:
0: backtrace::backtrace::libunwind::trace
at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.44/src/backtrace/libunwind.rs:86
1: backtrace::backtrace::trace_unsynchronized
at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.44/src/backtrace/mod.rs:66
2: std::sys_common::backtrace::_print_fmt
at src/libstd/sys_common/backtrace.rs:78
3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
at src/libstd/sys_common/backtrace.rs:59
4: core::fmt::write
at src/libcore/fmt/mod.rs:1063
5: std::io::Write::write_fmt
at /rustc/4fb7144ed159f94491249e86d5bbd033b5d60550/src/libstd/io/mod.rs:1426
6: std::io::impls::<impl std::io::Write for alloc::boxed::Box>::write_fmt
at src/libstd/io/impls.rs:156
7: std::sys_common::backtrace::_print
at src/libstd/sys_common/backtrace.rs:62
8: std::sys_common::backtrace::print
at src/libstd/sys_common/backtrace.rs:49
9: std::panicking::default_hook::{{closure}}
at src/libstd/panicking.rs:204
10: std::panicking::default_hook
at src/libstd/panicking.rs:221
11: std::panicking::rust_panic_with_hook
at src/libstd/panicking.rs:470
12: rust_begin_unwind
at src/libstd/panicking.rs:378
13: core::panicking::panic_fmt
at src/libcore/panicking.rs:85
14: core::str::slice_error_fail
at src/libcore/str/mod.rs:0
15: core::str::traits::<impl core::slice::SliceIndex for core::ops::range::Range>::index::{{closure}}
at /rustc/4fb7144ed159f94491249e86d5bbd033b5d60550/src/libcore/str/mod.rs:1919
16: core::option::Option::unwrap_or_else
at /rustc/4fb7144ed159f94491249e86d5bbd033b5d60550/src/libcore/option.rs:428
17: core::str::traits::<impl core::slice::SliceIndex for core::ops::range::Range>::index
at /rustc/4fb7144ed159f94491249e86d5bbd033b5d60550/src/libcore/str/mod.rs:1919
18: core::str::traits::<impl core::ops::index::Index for str>::index
at /rustc/4fb7144ed159f94491249e86d5bbd033b5d60550/src/libcore/str/mod.rs:1780
19: <alloc::string::String as core::ops::index::Index<core::ops::range::Range>>::index
at /rustc/4fb7144ed159f94491249e86d5bbd033b5d60550/src/liballoc/string.rs:1999
20: alloc::string::String::drain
at /rustc/4fb7144ed159f94491249e86d5bbd033b5d60550/src/liballoc/string.rs:1551
21: rexpect::reader::NBReader::try_read
at /home/zhangyongcheng/.cargo/registry/src/mirrors.tuna.tsinghua.edu.cn-df7c3c540f42cdbd/rexpect-0.4.0/src/reader.rs:265
22: rexpect::session::StreamSession::try_read
at /home/zhangyongcheng/.cargo/registry/src/mirrors.tuna.tsinghua.edu.cn-df7c3c540f42cdbd/rexpect-0.4.0/src/session.rs:98
Hi @philippkeller
In README.md, the example is referring to rexpect 0.3.0 while the version on crates.io is only upto 0.2.0.
I tried to test out the examples in README.md using 0.2.0 but failed with following message.
[me@fedora01 src]$cargo build
Compiling cmd1 v0.1.0 (file:///home/tjyang/cmd1)
error[E0061]: this function takes 1 parameter but 2 parameters were supplied
--> src/main.rs:8:7
|
8 | p.execute("ping 8.8.8.8", "bytes of data")?;
| ^^^^^^^ expected 1 parameter
error[E0061]: this function takes 1 parameter but 2 parameters were supplied
--> src/main.rs:12:7
|
12 | p.execute("bg", "ping 8.8.8.8")?;
| ^^^^^^^ expected 1 parameter
error[E0061]: this function takes 1 parameter but 2 parameters were supplied
--> src/main.rs:17:7
|
17 | p.execute("fg", "ping 8.8.8.8")?;
| ^^^^^^^ expected 1 parameter
error: aborting due to 3 previous errors
error: Could not compile `cmd1`.
To learn more, run the command again with --verbose.
[me@fedora01 src]$
find fn returns a tuple with the unread buffer and the matched string by needle. The question is if it could also return the position of the expression used in ReadUntil::Any(vec)? Right now I'm looping through the passed expressions and checking which one matches the returned matched string.
Think "did I match username or password prompt, what to send back to the process".
I would like to replace the (seemingly abandoned) error-chain
dependency with the maintained thiserror
.
Does anyone object? @petreeftime?
rexpect has a lot of unwrap()
/expect()
calls in the codebase, which I would like to review after moving to thiserror
(and hopefully fix, of course).
I am learning rexpect via *.rs in examples dir.
[me@ipa01 examples]$ cat Cargo.toml
[package]
name = "rexpect-examples"
version = "0.1.0"
authors = ["rexpect authors"]
description = "Cargo.toml to compile rexpect examples in batch"
license = "MIT"
homepage = "https://github.com/rust-cli/rexpect"
readme = "README.md"
categories = ["command-line-utilities" ]
keywords = ["rexpect", "rust", "bash"]
[dependencies]
rexpect = "0.4.0"
[me@ipa01 examples]$
[me@ipa01 examples]$ tree -L 23
.
├── Cargo.lock
├── Cargo.toml
└── src
└── bin
└── bash_read.rs
2 directories, 3 files
[me@ipa01 examples]$
[me@ipa01 examples]$ cargo run --bin bash_read
Compiling memchr v2.5.0
Compiling libc v0.2.135
Compiling cc v1.0.73
Compiling gimli v0.26.2
Compiling version_check v0.9.4
Compiling adler v1.0.2
Compiling cfg-if v1.0.0
Compiling nix v0.14.1
Compiling rustc-demangle v0.1.21
Compiling fastrand v1.8.0
Compiling remove_dir_all v0.5.3
Compiling regex-syntax v0.6.27
Compiling void v1.0.2
Compiling cfg-if v0.1.10
Compiling bitflags v1.3.2
Compiling miniz_oxide v0.5.4
Compiling error-chain v0.12.4
Compiling backtrace v0.3.66
Compiling object v0.29.0
Compiling aho-corasick v0.7.19
Compiling addr2line v0.17.0
Compiling tempfile v3.3.0
Compiling regex v1.6.0
Compiling rexpect v0.4.0
Compiling rexpect-examples v0.1.0 (/home/me/github/rexpect/contrib/examples)
error[E0432]: unresolved import rexpect::error
--> src/bin/bash_read.rs:2:14
|
2 | use rexpect::error::Error;
| ^^^^^ could not find error
in rexpect
For more information about this error, try rustc --explain E0432
.
error: could not compile rexpect-examples
due to previous error
[me@ipa01 examples]$
Is it possible to provide debugging facility like in pexpect: https://pexpect.readthedocs.io/en/stable/overview.html#debugging
I can not find a way to redirect stdout. For example.expectrl has logging of stdout: https://docs.rs/expectrl/latest/expectrl/#an-example-of-logging
spawn_bash
assumes you're spawning a new terminal on the same machine running rexpect. I use pexpect to write integration tests for embedded targets and pxssh
is really useful. Having the fairly robust ssh login stuff for starters, but also not assuming the login shell is necessarily bash
while still providing reliable synchronization and resetting the prompt (i.e. set PS1 but don't try to load .profile or anything)
Some binary data cannot be represented in an &str
, so functions that take &[u8]
are necessary. Unless I misunderstand or am using the wrong tool.
Use case is programing Marvell ARMADA 3700 over serial port.
Trying to launch an invalid program (file does not exist, is not executable etc.) should return an error.
use rexpect::spawn;
let mut spawned = spawn("invalidprogram", None);
println!("[{}] spawned is Error: {}", std::process::id(), spawned.is_err());
should print something like
[19989] spawned is Error: true
spawn
returns an Ok(PtySession)
Further testing shows:
let mut program = spawned.unwrap(); // does not fail, because it is an Ok(PtySession)
let output = program.exp_eof(); // capturing the full output of the PtySession
println!("{:?}", output);
outputs
Ok("[20011] spawned is Error: true\r\nthread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Nix(ENOENT)', src/main.rs:9:31\r\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\r\n")
So it seems that it does actually fail but does not propagate the Error to the parent.
I notice you can send a control character like <ctrl-c>
for keyboard interrupt, or <ctrl-d>
for EOF. Is there any way to send a signal like SIGTERM
or SIGHUP
(perhaps using a nix::sys::signal::Signal
) to the underlying process?
An alternative might be adding a method to the PtySession
which gives you a mutable reference to the underlying PtyProcess
so you can call signal()
and friends directly on that.
As a rexpect beginner, I had to create my own dir structure and file to really run/test/learn rexpect crate.
[me@ipa01 rexpect]$ pwd
/home/me/github/rexpect
[me@ipa01 rexpect]$ tree contrib -L 4
contrib
└── examples
├── Cargo.toml
└── src
└── bin
├── bash_read.rs
├── bash.rs
├── exit_code.rs
├── ftp.rs
├── repl.rs
└── tcp.rs
3 directories, 7 files
[me@ipa01 rexpect]$
Error-Chain seems to be unmaintained or rather not developed any further. Furthermore most people start adopting failure,anyhow and eyre for new errors in applications, which require Sync on errors to allow easier multithreading. Currently error-chain can't and won't have sync errors, requiring some special handling for errors of this library. Thus I recommend migrating to thiserror.
See also rust-lang-deprecated/error-chain#240 and wisespace-io/pwned-rs#4 for more info and an attached PR for how one can change this.
This is more or less in support of #29
When I put the unicode character "∀" into cat
, the output doesn't roundtrip:
Input:
∀
226 136 128
Output:
��
195 162 194 136 194 128
Code:
use rexpect::spawn;
use rexpect::error::*;
fn display(s: &str)
{
println!("{}", s);
for b in s.as_bytes()
{
print!("{} ", b);
}
println!("");
}
fn repl() -> Result<(), Error>
{
let mut p = spawn("cat", Some(1000))?;
let ex: String = "∀".to_string();
p.send_line(&ex)?;
let line = p.read_line()?;
println!("Input:");
display(&ex);
println!("Output:");
display(&line);
Ok(())
}
fn main()
{
repl().unwrap_or_else(|e| panic!("ftp job failed with {}", e));
}
I don't know how ppl feel about API changes, I'd guess there are so few users it doesn't matter as long as the minor version id bumped appropriately.
APIs should take owned values when they need an owned clone of something, instead of calling to_owned()
or in this case to_string()
.
See: https://www.philipdaniels.com/blog/2019/rust-api-design/
#realm join -v --computer-ou="ou=servers,dc=test,dc=com" test.com -U admin_ad
* Resolving: _ldap._tcp.test.com
* Performing LDAP DSE lookup on: 100.76.1.18
* Performing LDAP DSE lookup on: 100.76.1.19
* Performing LDAP DSE lookup on: 100.64.0.65
* Successfully discovered: test.com
Password for admin_ad: admin_ad_password
realm join -v --computer-ou="ou=ma,ou=servers,dc=test,dc=com" test.com -U admin_ad << MYPASSWD
admin_ad_password
MYPASSWD
//Run this code with cargo
// Join test.com AD domain on CentOS 7 with SSSD enabled.
// Following is the response from realm command
//! realm join -v --computer-ou="ou=unit1,ou=servers,dc=test,dc=com" test.com -U admin_ad
//! * Resolving: _ldap._tcp.test.com
//! * Performing LDAP DSE lookup on: 100.76.1.18
//! * Performing LDAP DSE lookup on: 100.76.1.19
//! * Performing LDAP DSE lookup on: 100.58.0.65
//! * Successfully discovered: test.com
//! Password for admin_ad:
extern crate rexpect;
use rexpect::spawn;
use rexpect::errors::*;
fn join() -> Result<()> {
let mut p = spawn("realm join -v --computer-ou=\"ou=ma,ou=servers,dc=test,dc=com\" test.com -U admin_ad", Some(30_000))?;
p.exp_regex("^Password for .*: ")?;
p.send_line("admin_ad_password")?;
p.exp_eof()?;
Ok(())
}
fn main() {
join().unwrap_or_else(|e| panic!("Failed to joing test.com AD domain {}", e));
}
>target/debug/joinad
thread 'main ' panicked at 'Failed to joing test.com AD domain EOF (End of File): Expected Regex: "^Password for .*: " but got EOF after reading " * Resolving: _ldap._tcp.test.com
Hi, this is a follow-up for #17. Basically I would like to be able to set the terminal size for the spawned process.
My use case is as follows: I'm using rexpect
to create integration tests for my full-screen TUI app (like vim), where I launch the program, send some keystrokes to it, and check that the printed characters are as expected. The layout of my app will depend on the terminal size, and for example some elements are not drawn at all if the size is zero. Currently I can't test my app properly without setting the terminal size.
Currently, my program actually crashes with a zero-size terminal, which I should probably handle, but I am still unable to test the screen contents.
(As another sidenote, this issue didn't come up before because crossterm
(the library I'm using for the TUI) used to check if the size from /dev/tty
(set by rexpect
) is zero, and if it was, it used tput
to query the terminal size instead. However, after an update, this check was removed and it returns a zero-size terminal now, which breaks my tests.)
Is there any way to return control of the terminal back to the user ? e.g. after connecting to a remote server. Thanks.
In python pexpect
I use interact()
method to achieve this.
Hi, I'm trying to write integration tests for an interactive CLI application (full-screen, like vim). Basically in my test, I want to run the main app binary, send some keystrokes to it, and then check the stdout and stderr. rexpect
seems like a good fit, and it works for stdout, but I can't seem to find a way to read the stderr. Is there a way to read it?
There were quite a few changes since version v0.4.0, it would be a good idea to push a new version out to crates.io.
Are there any guidelines for rust-cli organization on how it's best to do this, for example changelog format, steps, etc?
We have some sporadically failing testcases, which blocks CI.
Has been discussed in #101 among other PRs. But I'm opening an issue to keep the discussion in one place.
I'm able to reliably reproduce the failure on my machine like so:
I=1; while cargo nextest run test_read_line; do I=$(($I+1)); echo "PASS $I"; done; echo "FAIL $I"
Starting 1 tests across 1 binaries (19 skipped)
FAIL [ 0.207s] rexpect session::tests::test_read_line
--- STDOUT: rexpect session::tests::test_read_line ---
running 1 test
test session::tests::test_read_line ... FAILED
failures:
failures:
session::tests::test_read_line
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 19 filtered out; finished in 0.21s
--- STDERR: rexpect session::tests::test_read_line ---
thread 'session::tests::test_read_line' panicked at 'assertion failed: `(left == right)`
left: `"hans"`,
right: `"hanshans"`', src/session.rs:437:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Canceling due to test failure: 0 tests still running
------------
Summary [ 0.207s] 1 tests run: 0 passed, 1 failed, 19 skipped
FAIL [ 0.207s] rexpect session::tests::test_read_line
error: test run failed
FAIL 270
It failed after 270 runs of the test. I'm running Ubuntu 20.
@philippkeller It seems like this project is not being actively maintained anymore. Would you like help with maintenance or would you prefer that this was forked an maintained by someone else?
#[test]
fn test_empty_spawn() {
let p = spawn("", Some(1000));
assert!(p.is_ok());
}
Currently such spawn will produce a correct PtySession
but any work with it it's obviously not a good idea.
I wonder if the spawn function have to check the input if it's empty and return the error in such case.
If it's I may provide a PR :)
I am not sure what is a relatively good step here. So create an issue rather than PR :)
Is an async version of rexpect a new crate or should there just be an async module?
While testing gluon with rexpect, there has been one inconsistent test, specicially the hello_world
test. It may be a problem of how I used the api or a rare bug with the repl. Rexpect has worked consistently with every other test that's been thrown at it.
There are a few different variations tried in here, including the original without expecting anything after the first sent import line, expecting a regex, and using execute -- gluon-lang/gluon#478.
It would be great to get your eyes on this if you spot anything I'm missing while using rexpect :)
Should we add some sort of zulip/discord/slack for this package? Adding a channel in an existing forum would be the easiest, anything else feels a bit overkill I think.
Excuse me, how can I execute 'ls -l' to output a directory list after logging into the server via ssh? I managed to execute 'ls -l' successfully, but I'm confused when trying to print out the directory structure. Am I missing any related methods?
Hello, this is perhaps not an issue, but I've been experimenting with the crate and notice the following behavior:
If I get a PtyReplSession
with spawn_bash(Some(timeout))
, and then use p.execute(command, ready)
, the time it takes for this to successfully return is directly related to timeout
regardless of the time it actually takes command
to reach ready
. The higher the timeout
, the longer it takes (but it returns Ok), and viceversa (though at a certain point, very small timeout
s will fail to find ready
).
If I get a PtySession
with spawn(command, Some(timeout))
, and then use p.exp_string(ready)
, the time it takes for this to successfully return is independent of timeout
. I can change timeout
as much as I want (as long as I don't make it too small), and the time to successfully return will remain constant. If ready
is not found, the timeout
works as expected.
I wouldn't expect the execution time of command
to change when running in a PtySession
vs a PtyReplSession
. Could you explain why this happens? Is it a bug or am I missing something?
Example code with PtyReplSession
:
let mut bash_session = spawn_bash(Some(10000))
.expect("session failed");
bash_session.execute("hostname", "mypc")
.expect("command failed");
Example code with PtySession
:
let mut session = spawn("hostname", Some(10000))
.expect("session failed");
session.exp_string("mypc")
.expect("command failed");
Here are some test results:
Test: PtyReplSession
with 2,000ms timeout:
running 1 test
test pruebas_rexpect::with_pty_repl_session_timeout_2000 ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.42s
Test: PtyReplSession
with 10,000ms timeout:
running 1 test
test pruebas_rexpect::with_pty_repl_session_timeout_10000 ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 10.45s
Test: PtySession
with 2,000ms timeout:
running 1 test
test pruebas_rexpect::with_pty_session_timeout_2000 ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.19s
Test: PtySession
with 10,000ms timeout:
running 1 test
test pruebas_rexpect::with_pty_session_timeout_10000 ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.16s
Is it possible to leverage https://docs.rs/strip-ansi-escapes/0.1.0/strip_ansi_escapes somehow to strip ANSI escape codes from the output?
I am interested in adding Windows support for this crate. Would you be willing to accept a PR if I can get this working?
Specifically, I want to look into adding Windows support via PseudoTerminal. Doing so will likely require some additions to this crate, including depending on winapi and some other platform-specific code for Windows builds.
I don't intend on changing the API, as I like the simplicity, and would try not to change the internals much. That said, I haven't looked closely at this codebase yet so I don't really know what will be required.
If this is something you see as possible, I can start working on it. It could take me a couple weeks (or more) to get something working.
I'd like to use the functionality from #103, but it seems that it's not released on crates.io yet. I would appreciate a new release, are there plans for it to happen? Thanks!
(I'll just use the Git version for now.)
It would be nice if we could provide an easy way to test rexpect apps. Maybe something like this?
fn main() -> Result<(), Error> {
let mut p = rexpect::spawn("cat", Some(300))?;
use_cat(&mut p)?;
Ok(())
}
fn use_cat(p: &mut PtySession) -> Result<(), Error> {
p.send_line("I'm a cat")?;
p.exp_string("I'm a cat\r\n")?;
Ok(())
}
mod test {
use super::*;
#[test]
fn option1() -> Result<(), Error> {
use_cat(
rexpect::testing::FakePtySession()
.recv("I'm a cat")
.send("I'm a cat"),
)?;
Ok(())
}
fn option2() -> Result<(), Error> {
let mut p = rexpect::testing::FakePtySession();
std::thread::spawn(|| use_cat(p));
p.recv("I'm a cat");
p.send("I'm a cat");
Ok(())
}
}
Or any suggestions for a better interface? I think option2 looks nicer in the test case, but I think option1 is overall better, since it doesn't require spinning up a new thread, and needing to sync between the two.
I'm not sure how we could get nice error messages with either approach, but I'm working on option1 at the moment and will see how it turns out.
I haven't seen any crates providing special testing-utilities, is it normally not done? Should we have it behind a feature-flag?
Implementation wise, it looks like we would have to store Box<impl PtyProcess>
in PtySession and Box<impl Write>
in StreamSession. So that we can keep PtySession without template arguments. This would break the API, but I don't think it should be a problem?
It would also be nice to borrow from replwrap
and have a method to fold these three lines into one:
p.send_line("hostname")?;
let hostname = p.read_line()?;
p.wait_for_prompt()?; // go sure `hostname` is really done
becomes something like
let output = p.run("hostname")?;
other things that would help missing from pexpect that I've had to add for run(): take multiple commands to pass a script that you read from the host filesystem either as a vec or by splitting on newlines, sanitizing carriage returns, stripping out colour
A common pattern I've done in pexpect is something like the following:
proc = pexpect.spawnu("foo")
proc.setecho(False)
proc.sendline("some input")
proc.expect("> ")
print(proc.before)
The proc.before
part allows me to access the result of the input. Is there currently an equivalent in rexpect?
Hi!
In the last meetup of the CLI WG it came up that we want to make this crate to the CLI WG org.
The benefits that we would get from that would be the increased bus factor. I know we have three or four people that currently maintain this crate, and we wouldn't even increase that number any further when moving to the CLI WG org, but we would get the option of the WG having access to the repository settings and if it happens that we (the current maintainers) are all unresponsive, the WG can install new maintainers.
Please lets have a discussion about that.
@petreeftime suggested that after the maintainership thing got cleared up, we can talk about moving to a more permanent place (#43 (comment)) ... and that's what I'm trying here now! 😆
@souze is also a maintainer IIRC and of course
@philippkeller has the final say as the owner of the repository!
pexpect has child.logfile*
APIs to log child process output to a file-like destination.
I looked around the docs but I didn't seem to find anything similar for rexpect
.
Is there any chance this could be supported?
I was tinkering pty/tty stuff and still not clearly understand how it works :). And you're @philippkeller the most right person who I could address this question. Example below.
Currently this test will pass.
But why?
Why we get this echoed strings?
I've tested the flags.local_flags &= !termios::LocalFlags::ECHO
works fine.
Thanks in advance.
#[test]
/// Open cat, write string, read back string twice, send Ctrl^C and check that cat exited
fn test_no_cmd() {
// wrapping into closure so I can use ?
|| -> std::io::Result<()> {
let process = PtyProcess::new(Command::new("")).expect("could not execute cat");
let f = process.get_file_handle();
let mut writer = LineWriter::new(&f);
let mut reader = BufReader::new(&f);
writer.write_all(b"hello cat\n")?;
let mut buf = String::new();
reader.read_line(&mut buf)?;
assert_eq!(buf, "hello cat\r\n");
Ok(())
}()
.unwrap_or_else(|e| panic!("test_cat failed: {}", e));
}
when call rexpect::spawn
, how to pass env var to the process?
I've traced down the source of a faulty execution in a application that I contribute to the PtySession::expect_eof
never finishing execution on Rut's currently nightly build.
I have a little example that can reproduce the problem:
// On Cargo.toml
// [dependencies]
// rexpect = "0.4"
fn main() {
let mut p = rexpect::spawn("echo 'working as expected'", Some(10000)).unwrap();
println!("{}", p.exp_eof().unwrap());
}
When I run this on nightly the timeout is reached, and if no timeout is set the execution just hangs indefinitely. On stable it just works as expected.
Here's my rust and cargo version for the nightly build:
$ rustc --version --verbose
rustc 1.56.0-nightly (30a0a9b69 2021-08-17)
binary: rustc
commit-hash: 30a0a9b694cde95cbab863f7ef4d554f0f46b606
commit-date: 2021-08-17
host: x86_64-unknown-linux-gnu
release: 1.56.0-nightly
LLVM version: 12.0.1
$ cargo --version --verbose
cargo 1.56.0-nightly (b51439fd8 2021-08-09)
release: 1.56.0
commit-hash: b51439fd8b505d4800a257acfecf3c69f81e35cf
commit-date: 2021-08-09
Would appreciate if you guys could make it compatible with nightly again as it is what I use during development. In the mean time I'll be pining down my nightly to the last working release.
Currently, a LICENSE file is not in the repository. It would be great to add one to match the MIT license in rexpect's Cargo.toml, as well as reference at the bottom of the readme.
I was unable to reproduce the issue on my own. So far the only time it showed up is in https://github.com/philippkeller/rexpect/actions/runs/3060626462/jobs/4939368842, for PR #47.
I've reviewed the code involved in this test, but there was nothing obvious that could lead to such an issue. What I expected was that there's some sort of race condition where Session::read_line
starts reading before the \n
is available, and so it ends up reading the string once, stopping because it can't match and then reading again, but NBReader
looks like it would correctly accumulate characters into the buffer and the whole operation is retried until the match is found in the buffer.
---- session::tests::test_read_line stdout ----
thread 'session::tests::test_read_line' panicked at 'assertion failed: `(left == right)`
left: `"hans"`,
right: `"hanshans"`', src/session.rs:438:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
just a mental note to fix those. Also: might be good to mention the tcp example in the README, or maybe not…
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.