Remove duplicate dependencies (#3961)

* chore: Replace surf with reqwest

Removes a lot of older, duplication versions of some dependencies
(roughtly 90 dependencies removed in total)

* chore: Remove syn 0.11

* chore: Remove unnecessary features from ptree

Removes some more duplicate dependencies

* cargo update

* Ensure we run the fetch and post plugins on the tokio runtime

* Fix clippy warning

* fix: Github requires a user agent on requests

Co-authored-by: Darren Schroeder <343840+fdncred@users.noreply.github.com>
This commit is contained in:
Markus Westerlind 2021-08-28 05:34:11 +02:00 committed by GitHub
parent 7fe05b8296
commit 1c1c58e802
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 553 additions and 1733 deletions

2104
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -10,7 +10,6 @@ version = "0.36.1"
bigdecimal = { package = "bigdecimal-rs", version = "0.2.1", features = ["serde"] } bigdecimal = { package = "bigdecimal-rs", version = "0.2.1", features = ["serde"] }
codespan-reporting = "0.11.0" codespan-reporting = "0.11.0"
derive-new = "0.5.8" derive-new = "0.5.8"
derive_is_enum_variant = "0.1.1"
indexmap = { version="1.6.1", features=["serde-1"] } indexmap = { version="1.6.1", features=["serde-1"] }
log = "0.4" log = "0.4"
num-bigint = { version="0.3.1", features=["serde"] } num-bigint = { version="0.3.1", features=["serde"] }

View File

@ -6,7 +6,7 @@ use nu_source::{HasSpan, Span, Spanned, SpannedItem};
use super::token_group::TokenBuilder; use super::token_group::TokenBuilder;
#[derive(Debug, Clone, PartialEq, is_enum_variant)] #[derive(Debug, Clone, PartialEq)]
pub enum TokenContents { pub enum TokenContents {
/// A baseline token is an atomic chunk of source code. This means that the /// A baseline token is an atomic chunk of source code. This means that the
/// token contains the entirety of string literals, as well as the entirety /// token contains the entirety of string literals, as well as the entirety
@ -34,6 +34,12 @@ impl fmt::Display for TokenContents {
} }
} }
impl TokenContents {
pub fn is_eol(&self) -> bool {
matches!(self, Self::Eol)
}
}
pub type CommandBuilder = TokenBuilder<Spanned<String>>; pub type CommandBuilder = TokenBuilder<Spanned<String>>;
pub type CommentsBuilder = TokenBuilder<LiteComment>; pub type CommentsBuilder = TokenBuilder<LiteComment>;
pub type PipelineBuilder = TokenBuilder<LiteCommand>; pub type PipelineBuilder = TokenBuilder<LiteCommand>;

View File

@ -1,6 +1,4 @@
#[macro_use] #[macro_use]
extern crate derive_is_enum_variant;
#[macro_use]
extern crate derive_new; extern crate derive_new;
mod errors; mod errors;

View File

@ -16,7 +16,8 @@ nu-errors = { path="../nu-errors", version = "0.36.1" }
nu-plugin = { path="../nu-plugin", version = "0.36.1" } nu-plugin = { path="../nu-plugin", version = "0.36.1" }
nu-protocol = { path="../nu-protocol", version = "0.36.1" } nu-protocol = { path="../nu-protocol", version = "0.36.1" }
nu-source = { path="../nu-source", version = "0.36.1" } nu-source = { path="../nu-source", version = "0.36.1" }
surf = { version="2.2.0", features=["hyper-client"] } reqwest = "0.11"
tokio = { version = "1", features = ["rt-multi-thread"] }
url = "2.2.1" url = "2.2.1"
mime = "0.3.16" mime = "0.3.16"

View File

@ -113,14 +113,14 @@ async fn helper(
_ => None, _ => None,
}; };
let mut response = surf::RequestBuilder::new(surf::http::Method::Get, url) let client = http_client();
.middleware(surf::middleware::Redirect::default()); let mut request = client.get(url);
if let Some(login) = login { if let Some(login) = login {
response = surf::get(location).header("Authorization", format!("Basic {}", login)); request = request.header("Authorization", format!("Basic {}", login));
} }
let generate_error = |t: &str, e: surf::Error, span: &Span| { let generate_error = |t: &str, e: reqwest::Error, span: &Span| {
ShellError::labeled_error( ShellError::labeled_error(
format!("Could not load {} from remote url: {:?}", t, e), format!("Could not load {} from remote url: {:?}", t, e),
"could not load", "could not load",
@ -132,33 +132,24 @@ async fn helper(
anchor: Some(AnchorLocation::Url(location.to_string())), anchor: Some(AnchorLocation::Url(location.to_string())),
}; };
match response.await { match request.send().await {
Ok(mut r) => match r.header("content-type") { Ok(r) => match r.headers().get("content-type") {
Some(content_type) => { Some(content_type) => {
let content_type_header_value = content_type.get(0); let content_type = content_type.to_str().map_err(|e| {
let content_type_header_value = match content_type_header_value { ShellError::labeled_error(e.to_string(), "MIME type were invalid", &tag)
Some(h) => h, })?;
None => { let content_type = mime::Mime::from_str(content_type).map_err(|_| {
return Err(ShellError::labeled_error( ShellError::labeled_error(
"no content type found", format!("MIME type unknown: {}", content_type),
"no content type found", "given unknown MIME type",
span, span,
)) )
} })?;
};
let content_type = mime::Mime::from_str(content_type_header_value.as_str())
.map_err(|_| {
ShellError::labeled_error(
format!("MIME type unknown: {}", content_type_header_value),
"given unknown MIME type",
span,
)
})?;
match (content_type.type_(), content_type.subtype()) { match (content_type.type_(), content_type.subtype()) {
(mime::APPLICATION, mime::XML) => Ok(( (mime::APPLICATION, mime::XML) => Ok((
Some("xml".to_string()), Some("xml".to_string()),
UntaggedValue::string( UntaggedValue::string(
r.body_string() r.text()
.await .await
.map_err(|e| generate_error("text", e, &span))?, .map_err(|e| generate_error("text", e, &span))?,
) )
@ -167,7 +158,7 @@ async fn helper(
(mime::APPLICATION, mime::JSON) => Ok(( (mime::APPLICATION, mime::JSON) => Ok((
Some("json".to_string()), Some("json".to_string()),
UntaggedValue::string( UntaggedValue::string(
r.body_string() r.text()
.await .await
.map_err(|e| generate_error("text", e, &span))?, .map_err(|e| generate_error("text", e, &span))?,
) )
@ -175,15 +166,16 @@ async fn helper(
)), )),
(mime::APPLICATION, mime::OCTET_STREAM) => { (mime::APPLICATION, mime::OCTET_STREAM) => {
let buf: Vec<u8> = r let buf: Vec<u8> = r
.body_bytes() .bytes()
.await .await
.map_err(|e| generate_error("binary", e, &span))?; .map_err(|e| generate_error("binary", e, &span))?
.to_vec();
Ok((None, UntaggedValue::binary(buf).into_value(tag))) Ok((None, UntaggedValue::binary(buf).into_value(tag)))
} }
(mime::IMAGE, mime::SVG) => Ok(( (mime::IMAGE, mime::SVG) => Ok((
Some("svg".to_string()), Some("svg".to_string()),
UntaggedValue::string( UntaggedValue::string(
r.body_string() r.text()
.await .await
.map_err(|e| generate_error("svg", e, &span))?, .map_err(|e| generate_error("svg", e, &span))?,
) )
@ -191,9 +183,10 @@ async fn helper(
)), )),
(mime::IMAGE, image_ty) => { (mime::IMAGE, image_ty) => {
let buf: Vec<u8> = r let buf: Vec<u8> = r
.body_bytes() .bytes()
.await .await
.map_err(|e| generate_error("image", e, &span))?; .map_err(|e| generate_error("image", e, &span))?
.to_vec();
Ok(( Ok((
Some(image_ty.to_string()), Some(image_ty.to_string()),
UntaggedValue::binary(buf).into_value(tag), UntaggedValue::binary(buf).into_value(tag),
@ -202,7 +195,7 @@ async fn helper(
(mime::TEXT, mime::HTML) => Ok(( (mime::TEXT, mime::HTML) => Ok((
Some("html".to_string()), Some("html".to_string()),
UntaggedValue::string( UntaggedValue::string(
r.body_string() r.text()
.await .await
.map_err(|e| generate_error("text", e, &span))?, .map_err(|e| generate_error("text", e, &span))?,
) )
@ -211,7 +204,7 @@ async fn helper(
(mime::TEXT, mime::CSV) => Ok(( (mime::TEXT, mime::CSV) => Ok((
Some("csv".to_string()), Some("csv".to_string()),
UntaggedValue::string( UntaggedValue::string(
r.body_string() r.text()
.await .await
.map_err(|e| generate_error("text", e, &span))?, .map_err(|e| generate_error("text", e, &span))?,
) )
@ -238,7 +231,7 @@ async fn helper(
Ok(( Ok((
path_extension, path_extension,
UntaggedValue::string( UntaggedValue::string(
r.body_string() r.text()
.await .await
.map_err(|e| generate_error("text", e, &span))?, .map_err(|e| generate_error("text", e, &span))?,
) )
@ -246,7 +239,7 @@ async fn helper(
)) ))
} }
(_ty, _sub_ty) if has_raw => { (_ty, _sub_ty) if has_raw => {
let raw_bytes = r.body_bytes().await; let raw_bytes = r.bytes().await;
let raw_bytes = match raw_bytes { let raw_bytes = match raw_bytes {
Ok(r) => r, Ok(r) => r,
Err(e) => { Err(e) => {
@ -264,7 +257,10 @@ async fn helper(
Ok(response_str) => { Ok(response_str) => {
Ok((None, UntaggedValue::string(response_str).into_value(tag))) Ok((None, UntaggedValue::string(response_str).into_value(tag)))
} }
Err(_) => Ok((None, UntaggedValue::binary(raw_bytes).into_value(tag))), Err(_) => Ok((
None,
UntaggedValue::binary(raw_bytes.to_vec()).into_value(tag),
)),
} }
} }
(ty, sub_ty) => Err(ShellError::unimplemented(format!( (ty, sub_ty) => Err(ShellError::unimplemented(format!(
@ -286,3 +282,13 @@ async fn helper(
)), )),
} }
} }
// Only panics if the user agent is invalid but we define it statically so either
// it always or never fails
#[allow(clippy::unwrap_used)]
fn http_client() -> reqwest::Client {
reqwest::Client::builder()
.user_agent("nushell")
.build()
.unwrap()
}

View File

@ -1,4 +1,3 @@
use futures::executor::block_on;
use nu_errors::ShellError; use nu_errors::ShellError;
use nu_plugin::Plugin; use nu_plugin::Plugin;
use nu_protocol::{CallInfo, ReturnValue, Signature, SyntaxShape}; use nu_protocol::{CallInfo, ReturnValue, Signature, SyntaxShape};
@ -33,7 +32,8 @@ impl Plugin for Fetch {
fn begin_filter(&mut self, callinfo: CallInfo) -> Result<Vec<ReturnValue>, ShellError> { fn begin_filter(&mut self, callinfo: CallInfo) -> Result<Vec<ReturnValue>, ShellError> {
self.setup(callinfo)?; self.setup(callinfo)?;
Ok(vec![block_on(fetch( let runtime = tokio::runtime::Runtime::new()?;
Ok(vec![runtime.block_on(fetch(
&self.path.clone().ok_or_else(|| { &self.path.clone().ok_or_else(|| {
ShellError::labeled_error("internal error: path not set", "path not set", &self.tag) ShellError::labeled_error("internal error: path not set", "path not set", &self.tag)
})?, })?,

View File

@ -19,7 +19,8 @@ nu-protocol = { path="../nu-protocol", version = "0.36.1" }
nu-source = { path="../nu-source", version = "0.36.1" } nu-source = { path="../nu-source", version = "0.36.1" }
num-traits = "0.2.12" num-traits = "0.2.12"
serde_json = "1.0.57" serde_json = "1.0.57"
surf = "2.2.0" reqwest = "0.11"
tokio = { version = "1", features = ["rt-multi-thread"] }
url = "2.1.1" url = "2.1.1"
[features] [features]

View File

@ -1,4 +1,3 @@
use futures::executor::block_on;
use nu_errors::ShellError; use nu_errors::ShellError;
use nu_plugin::Plugin; use nu_plugin::Plugin;
use nu_protocol::{CallInfo, ReturnValue, Signature, SyntaxShape}; use nu_protocol::{CallInfo, ReturnValue, Signature, SyntaxShape};
@ -46,7 +45,8 @@ impl Plugin for Post {
fn begin_filter(&mut self, call_info: CallInfo) -> Result<Vec<ReturnValue>, ShellError> { fn begin_filter(&mut self, call_info: CallInfo) -> Result<Vec<ReturnValue>, ShellError> {
self.setup(call_info)?; self.setup(call_info)?;
Ok(vec![block_on(post_helper( let runtime = tokio::runtime::Runtime::new()?;
Ok(vec![runtime.block_on(post_helper(
&self.path.clone().ok_or_else(|| { &self.path.clone().ok_or_else(|| {
ShellError::labeled_error("expected a 'path'", "expected a 'path'", &self.tag) ShellError::labeled_error("expected a 'path'", "expected a 'path'", &self.tag)
})?, })?,

View File

@ -132,7 +132,7 @@ pub async fn post(
value: UntaggedValue::Primitive(Primitive::String(body_str)), value: UntaggedValue::Primitive(Primitive::String(body_str)),
.. ..
} => { } => {
let mut s = surf::post(location).body(body_str.to_string()); let mut s = http_client().post(location).body(body_str.to_string());
if let Some(login) = login { if let Some(login) = login {
s = s.header("Authorization", format!("Basic {}", login)); s = s.header("Authorization", format!("Basic {}", login));
} }
@ -143,28 +143,29 @@ pub async fn post(
HeaderKind::ContentLength(cl) => s.header("Content-Length", cl), HeaderKind::ContentLength(cl) => s.header("Content-Length", cl),
}; };
} }
s.await
s.send().await
} }
Value { Value {
value: UntaggedValue::Primitive(Primitive::Binary(b)), value: UntaggedValue::Primitive(Primitive::Binary(b)),
.. ..
} => { } => {
let mut s = surf::post(location).body(&b[..]); let mut s = http_client().post(location).body(Vec::from(&b[..]));
if let Some(login) = login { if let Some(login) = login {
s = s.header("Authorization", format!("Basic {}", login)); s = s.header("Authorization", format!("Basic {}", login));
} }
s.await s.send().await
} }
Value { value, tag } => { Value { value, tag } => {
match value_to_json_value(&value.clone().into_untagged_value()) { match value_to_json_value(&value.clone().into_untagged_value()) {
Ok(json_value) => match serde_json::to_string(&json_value) { Ok(json_value) => match serde_json::to_string(&json_value) {
Ok(result_string) => { Ok(result_string) => {
let mut s = surf::post(location).body(result_string); let mut s = http_client().post(location).body(result_string);
if let Some(login) = login { if let Some(login) = login {
s = s.header("Authorization", format!("Basic {}", login)); s = s.header("Authorization", format!("Basic {}", login));
} }
s.await s.send().await
} }
_ => { _ => {
return Err(ShellError::labeled_error( return Err(ShellError::labeled_error(
@ -185,9 +186,12 @@ pub async fn post(
} }
}; };
match response { match response {
Ok(mut r) => match r.header("content-type") { Ok(r) => match r.headers().get("content-type") {
Some(content_type) => { Some(content_type) => {
let content_type = Mime::from_str(content_type.as_str()).map_err(|_| { let content_type = content_type.to_str().map_err(|e| {
ShellError::labeled_error(e.to_string(), "MIME type were invalid", &tag)
})?;
let content_type = Mime::from_str(content_type).map_err(|_| {
ShellError::labeled_error( ShellError::labeled_error(
format!("Unknown MIME type: {}", content_type), format!("Unknown MIME type: {}", content_type),
"unknown MIME type", "unknown MIME type",
@ -197,7 +201,7 @@ pub async fn post(
match (content_type.type_(), content_type.subtype()) { match (content_type.type_(), content_type.subtype()) {
(mime::APPLICATION, mime::XML) => Ok(( (mime::APPLICATION, mime::XML) => Ok((
Some("xml".to_string()), Some("xml".to_string()),
UntaggedValue::string(r.body_string().await.map_err(|_| { UntaggedValue::string(r.text().await.map_err(|_| {
ShellError::labeled_error( ShellError::labeled_error(
"Could not load text from remote url", "Could not load text from remote url",
"could not load", "could not load",
@ -211,7 +215,7 @@ pub async fn post(
)), )),
(mime::APPLICATION, mime::JSON) => Ok(( (mime::APPLICATION, mime::JSON) => Ok((
Some("json".to_string()), Some("json".to_string()),
UntaggedValue::string(r.body_string().await.map_err(|_| { UntaggedValue::string(r.text().await.map_err(|_| {
ShellError::labeled_error( ShellError::labeled_error(
"Could not load text from remote url", "Could not load text from remote url",
"could not load", "could not load",
@ -224,13 +228,17 @@ pub async fn post(
}, },
)), )),
(mime::APPLICATION, mime::OCTET_STREAM) => { (mime::APPLICATION, mime::OCTET_STREAM) => {
let buf: Vec<u8> = r.body_bytes().await.map_err(|_| { let buf: Vec<u8> = r
ShellError::labeled_error( .bytes()
"Could not load binary file", .await
"could not load", .map_err(|_| {
&tag, ShellError::labeled_error(
) "Could not load binary file",
})?; "could not load",
&tag,
)
})?
.to_vec();
Ok(( Ok((
None, None,
UntaggedValue::binary(buf), UntaggedValue::binary(buf),
@ -241,13 +249,17 @@ pub async fn post(
)) ))
} }
(mime::IMAGE, image_ty) => { (mime::IMAGE, image_ty) => {
let buf: Vec<u8> = r.body_bytes().await.map_err(|_| { let buf: Vec<u8> = r
ShellError::labeled_error( .bytes()
"Could not load image file", .await
"could not load", .map_err(|_| {
&tag, ShellError::labeled_error(
) "Could not load image file",
})?; "could not load",
&tag,
)
})?
.to_vec();
Ok(( Ok((
Some(image_ty.to_string()), Some(image_ty.to_string()),
UntaggedValue::binary(buf), UntaggedValue::binary(buf),
@ -259,7 +271,7 @@ pub async fn post(
} }
(mime::TEXT, mime::HTML) => Ok(( (mime::TEXT, mime::HTML) => Ok((
Some("html".to_string()), Some("html".to_string()),
UntaggedValue::string(r.body_string().await.map_err(|_| { UntaggedValue::string(r.text().await.map_err(|_| {
ShellError::labeled_error( ShellError::labeled_error(
"Could not load text from remote url", "Could not load text from remote url",
"could not load", "could not load",
@ -291,7 +303,7 @@ pub async fn post(
Ok(( Ok((
path_extension, path_extension,
UntaggedValue::string(r.body_string().await.map_err(|_| { UntaggedValue::string(r.text().await.map_err(|_| {
ShellError::labeled_error( ShellError::labeled_error(
"Could not load text from remote url", "Could not load text from remote url",
"could not load", "could not load",
@ -509,3 +521,13 @@ fn extract_header_value(call_info: &CallInfo, key: &str) -> Result<Option<String
Ok(None) Ok(None)
} }
// Only panics if the user agent is invalid but we define it statically so either
// it always or never fails
#[allow(clippy::unwrap_used)]
fn http_client() -> reqwest::Client {
reqwest::Client::builder()
.user_agent("nushell")
.build()
.unwrap()
}

View File

@ -15,6 +15,7 @@ nu-errors = { path="../nu-errors", version = "0.36.1" }
nu-plugin = { path="../nu-plugin", version = "0.36.1" } nu-plugin = { path="../nu-plugin", version = "0.36.1" }
nu-protocol = { path="../nu-protocol", version = "0.36.1" } nu-protocol = { path="../nu-protocol", version = "0.36.1" }
nu-source = { path="../nu-source", version = "0.36.1" } nu-source = { path="../nu-source", version = "0.36.1" }
ptree = "0.3.1" ptree = { version = "0.3.1", default-features = false }
[build-dependencies] [build-dependencies]