mirror of
https://github.com/nushell/nushell.git
synced 2024-11-22 08:23:24 +01:00
Finish adding makeshift support for to fetch/post plugins
This commit is contained in:
parent
cec2eff933
commit
d0a2888e88
@ -56,7 +56,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> {
|
||||||
Ok(vec![self.setup(callinfo)])
|
self.setup(callinfo)?;
|
||||||
|
Ok(vec![])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filter(&mut self, value: Value) -> Result<Vec<ReturnValue>, ShellError> {
|
fn filter(&mut self, value: Value) -> Result<Vec<ReturnValue>, ShellError> {
|
||||||
@ -72,9 +73,18 @@ fn main() {
|
|||||||
serve_plugin(&mut Fetch::new());
|
serve_plugin(&mut Fetch::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fetch_helper(path: &Value, has_raw: bool, _row: Value) -> ReturnValue {
|
async fn fetch_helper(path: &Value, has_raw: bool, row: Value) -> ReturnValue {
|
||||||
let path_buf = path.as_path()?;
|
let path_buf = path.as_path()?;
|
||||||
let path_str = path_buf.display().to_string();
|
let path_str = path_buf.display().to_string();
|
||||||
|
|
||||||
|
//FIXME: this is a workaround because plugins don't yet support per-item iteration
|
||||||
|
let path_str = if path_str == "$it" {
|
||||||
|
let path_buf = row.as_path()?;
|
||||||
|
path_buf.display().to_string()
|
||||||
|
} else {
|
||||||
|
path_str
|
||||||
|
};
|
||||||
|
|
||||||
let path_span = path.tag.span;
|
let path_span = path.tag.span;
|
||||||
|
|
||||||
let result = fetch(&path_str, path_span).await;
|
let result = fetch(&path_str, path_span).await;
|
||||||
|
@ -12,15 +12,67 @@ use std::path::PathBuf;
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use surf::mime;
|
use surf::mime;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub enum HeaderKind {
|
pub enum HeaderKind {
|
||||||
ContentType(String),
|
ContentType(String),
|
||||||
ContentLength(String),
|
ContentLength(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Post;
|
struct Post {
|
||||||
|
path: Option<Value>,
|
||||||
|
has_raw: bool,
|
||||||
|
body: Option<Value>,
|
||||||
|
user: Option<String>,
|
||||||
|
password: Option<String>,
|
||||||
|
headers: Vec<HeaderKind>,
|
||||||
|
}
|
||||||
|
|
||||||
impl Post {
|
impl Post {
|
||||||
fn new() -> Post {
|
fn new() -> Post {
|
||||||
Post
|
Post {
|
||||||
|
path: None,
|
||||||
|
has_raw: false,
|
||||||
|
body: None,
|
||||||
|
user: None,
|
||||||
|
password: None,
|
||||||
|
headers: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup(&mut self, call_info: CallInfo) -> ReturnValue {
|
||||||
|
self.path = Some(
|
||||||
|
match call_info.args.nth(0).ok_or_else(|| {
|
||||||
|
ShellError::labeled_error(
|
||||||
|
"No file or directory specified",
|
||||||
|
"for command",
|
||||||
|
&call_info.name_tag,
|
||||||
|
)
|
||||||
|
})? {
|
||||||
|
file => file.clone(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
self.has_raw = call_info.args.has("raw");
|
||||||
|
|
||||||
|
self.body = match call_info.args.nth(1).ok_or_else(|| {
|
||||||
|
ShellError::labeled_error("No body specified", "for command", &call_info.name_tag)
|
||||||
|
})? {
|
||||||
|
file => Some(file.clone()),
|
||||||
|
};
|
||||||
|
|
||||||
|
self.user = call_info
|
||||||
|
.args
|
||||||
|
.get("user")
|
||||||
|
.map(|x| x.as_string().unwrap().to_string());
|
||||||
|
|
||||||
|
self.password = call_info
|
||||||
|
.args
|
||||||
|
.get("password")
|
||||||
|
.map(|x| x.as_string().unwrap().to_string());
|
||||||
|
|
||||||
|
self.headers = get_headers(&call_info)?;
|
||||||
|
|
||||||
|
ReturnSuccess::value(UntaggedValue::nothing().into_untagged_value())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,12 +102,21 @@ impl Plugin for Post {
|
|||||||
.filter())
|
.filter())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn begin_filter(&mut self, callinfo: CallInfo) -> Result<Vec<ReturnValue>, ShellError> {
|
fn begin_filter(&mut self, call_info: CallInfo) -> Result<Vec<ReturnValue>, ShellError> {
|
||||||
Ok(vec![block_on(post_helper(callinfo))])
|
self.setup(call_info)?;
|
||||||
|
Ok(vec![])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filter(&mut self, _: Value) -> Result<Vec<ReturnValue>, ShellError> {
|
fn filter(&mut self, row: Value) -> Result<Vec<ReturnValue>, ShellError> {
|
||||||
Ok(vec![])
|
Ok(vec![block_on(post_helper(
|
||||||
|
&self.path.clone().unwrap(),
|
||||||
|
self.has_raw,
|
||||||
|
&self.body.clone().unwrap(),
|
||||||
|
self.user.clone(),
|
||||||
|
self.password.clone(),
|
||||||
|
&self.headers.clone(),
|
||||||
|
row,
|
||||||
|
))])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +124,16 @@ fn main() {
|
|||||||
serve_plugin(&mut Post::new());
|
serve_plugin(&mut Post::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn post_helper(call_info: CallInfo) -> ReturnValue {
|
async fn post_helper(
|
||||||
|
path: &Value,
|
||||||
|
has_raw: bool,
|
||||||
|
body: &Value,
|
||||||
|
user: Option<String>,
|
||||||
|
password: Option<String>,
|
||||||
|
headers: &[HeaderKind],
|
||||||
|
row: Value,
|
||||||
|
) -> ReturnValue {
|
||||||
|
/*
|
||||||
let path = match call_info.args.nth(0).ok_or_else(|| {
|
let path = match call_info.args.nth(0).ok_or_else(|| {
|
||||||
ShellError::labeled_error(
|
ShellError::labeled_error(
|
||||||
"No file or directory specified",
|
"No file or directory specified",
|
||||||
@ -80,6 +150,7 @@ async fn post_helper(call_info: CallInfo) -> ReturnValue {
|
|||||||
file => file.clone(),
|
file => file.clone(),
|
||||||
};
|
};
|
||||||
let path_str = path.as_string()?.to_string();
|
let path_str = path.as_string()?.to_string();
|
||||||
|
|
||||||
let has_raw = call_info.args.has("raw");
|
let has_raw = call_info.args.has("raw");
|
||||||
let user = call_info
|
let user = call_info
|
||||||
.args
|
.args
|
||||||
@ -91,6 +162,28 @@ async fn post_helper(call_info: CallInfo) -> ReturnValue {
|
|||||||
.map(|x| x.as_string().unwrap().to_string());
|
.map(|x| x.as_string().unwrap().to_string());
|
||||||
|
|
||||||
let headers = get_headers(&call_info)?;
|
let headers = get_headers(&call_info)?;
|
||||||
|
*/
|
||||||
|
let path_tag = path.tag.clone();
|
||||||
|
let path_str = path.as_string()?.to_string();
|
||||||
|
|
||||||
|
//FIXME: this is a workaround because plugins don't yet support per-item iteration
|
||||||
|
let path_str = if path_str == "$it" {
|
||||||
|
let path_buf = row.as_path()?;
|
||||||
|
path_buf.display().to_string()
|
||||||
|
} else {
|
||||||
|
path_str
|
||||||
|
};
|
||||||
|
|
||||||
|
//FIXME: this is a workaround because plugins don't yet support per-item iteration
|
||||||
|
let body = if let Ok(x) = body.as_string() {
|
||||||
|
if x == "$it" {
|
||||||
|
&row
|
||||||
|
} else {
|
||||||
|
body
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
body
|
||||||
|
};
|
||||||
|
|
||||||
let (file_extension, contents, contents_tag) =
|
let (file_extension, contents, contents_tag) =
|
||||||
post(&path_str, &body, user, password, &headers, path_tag.clone())
|
post(&path_str, &body, user, password, &headers, path_tag.clone())
|
||||||
|
@ -117,6 +117,26 @@ impl CommandArgs {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn evaluate_once_with_scope(
|
||||||
|
self,
|
||||||
|
registry: &CommandRegistry,
|
||||||
|
scope: &Scope,
|
||||||
|
) -> Result<EvaluatedWholeStreamCommandArgs, ShellError> {
|
||||||
|
let host = self.host.clone();
|
||||||
|
let ctrl_c = self.ctrl_c.clone();
|
||||||
|
let shell_manager = self.shell_manager.clone();
|
||||||
|
let input = self.input;
|
||||||
|
let call_info = self.call_info.evaluate(registry, scope)?;
|
||||||
|
|
||||||
|
Ok(EvaluatedWholeStreamCommandArgs::new(
|
||||||
|
host,
|
||||||
|
ctrl_c,
|
||||||
|
shell_manager,
|
||||||
|
call_info,
|
||||||
|
input,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn source(&self) -> Text {
|
pub fn source(&self) -> Text {
|
||||||
self.call_info.source.clone()
|
self.call_info.source.clone()
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ use crate::prelude::*;
|
|||||||
use derive_new::new;
|
use derive_new::new;
|
||||||
use log::trace;
|
use log::trace;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{Primitive, ReturnSuccess, ReturnValue, Signature, UntaggedValue, Value};
|
use nu_protocol::{Primitive, ReturnSuccess, ReturnValue, Scope, Signature, UntaggedValue, Value};
|
||||||
use serde::{self, Deserialize, Serialize};
|
use serde::{self, Deserialize, Serialize};
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
@ -71,7 +71,10 @@ pub fn filter_plugin(
|
|||||||
) -> Result<OutputStream, ShellError> {
|
) -> Result<OutputStream, ShellError> {
|
||||||
trace!("filter_plugin :: {}", path);
|
trace!("filter_plugin :: {}", path);
|
||||||
|
|
||||||
let args = args.evaluate_once(registry)?;
|
let args = args.evaluate_once_with_scope(
|
||||||
|
registry,
|
||||||
|
&Scope::it_value(UntaggedValue::string("$it").into_untagged_value()),
|
||||||
|
)?;
|
||||||
|
|
||||||
let mut child = std::process::Command::new(path)
|
let mut child = std::process::Command::new(path)
|
||||||
.stdin(std::process::Stdio::piped())
|
.stdin(std::process::Stdio::piped())
|
||||||
|
Loading…
Reference in New Issue
Block a user