mirror of
https://github.com/nushell/nushell.git
synced 2024-12-26 00:50:03 +01:00
Add first step of uuid generation and bookkeeping
This commit is contained in:
parent
d4ecf6dfa5
commit
d5d4da0bf8
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1696,6 +1696,7 @@ dependencies = [
|
||||
"toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"toml-query 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3181,6 +3182,7 @@ version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -75,6 +75,7 @@ crossterm = "0.9.6"
|
||||
tempfile = "3.1.0"
|
||||
image = "0.21.2"
|
||||
semver = "0.9.0"
|
||||
uuid = {version = "0.7.4", features = [ "v4", "serde" ]}
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = "0.6.1"
|
||||
|
@ -494,6 +494,7 @@ fn classify_command(
|
||||
Ok(ClassifiedCommand::Internal(InternalCommand {
|
||||
command,
|
||||
name_span: Some(head.span().clone()),
|
||||
span_sources: context.span_sources.clone(),
|
||||
args,
|
||||
}))
|
||||
}
|
||||
|
@ -1,13 +1,16 @@
|
||||
use crate::commands::command::Sink;
|
||||
use crate::context::SpanSource;
|
||||
use crate::parser::{registry::Args, Span, Spanned, TokenNode};
|
||||
use crate::prelude::*;
|
||||
use bytes::{BufMut, BytesMut};
|
||||
use futures::stream::StreamExt;
|
||||
use futures_codec::{Decoder, Encoder, Framed};
|
||||
use log::{log_enabled, trace};
|
||||
use std::collections::HashMap;
|
||||
use std::io::{Error, ErrorKind};
|
||||
use std::sync::Arc;
|
||||
use subprocess::Exec;
|
||||
use uuid::Uuid;
|
||||
|
||||
/// A simple `Codec` implementation that splits up data into lines.
|
||||
pub struct LinesCodec {}
|
||||
@ -116,6 +119,7 @@ impl SinkCommand {
|
||||
crate struct InternalCommand {
|
||||
crate command: Arc<dyn Command>,
|
||||
crate name_span: Option<Span>,
|
||||
crate span_sources: HashMap<Uuid, SpanSource>,
|
||||
crate args: Args,
|
||||
}
|
||||
|
||||
@ -134,8 +138,13 @@ impl InternalCommand {
|
||||
let objects: InputStream =
|
||||
trace_stream!(target: "nu::trace_stream::internal", "input" = input.objects);
|
||||
|
||||
let result =
|
||||
context.run_command(self.command, self.name_span.clone(), self.args, objects)?;
|
||||
let result = context.run_command(
|
||||
self.command,
|
||||
self.name_span.clone(),
|
||||
self.span_sources,
|
||||
self.args,
|
||||
objects,
|
||||
)?;
|
||||
|
||||
let mut result = result.values;
|
||||
|
||||
@ -146,6 +155,9 @@ impl InternalCommand {
|
||||
CommandAction::ChangePath(path) => {
|
||||
context.env.lock().unwrap().path = path;
|
||||
}
|
||||
CommandAction::AddSpanSource(uuid, span_source) => {
|
||||
context.add_span_source(uuid, span_source);
|
||||
}
|
||||
CommandAction::Exit => std::process::exit(0),
|
||||
},
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::context::SpanSource;
|
||||
use crate::errors::ShellError;
|
||||
use crate::object::Value;
|
||||
use crate::parser::{
|
||||
@ -7,7 +8,9 @@ use crate::parser::{
|
||||
use crate::prelude::*;
|
||||
use getset::Getters;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Getters)]
|
||||
#[get = "crate"]
|
||||
@ -15,6 +18,7 @@ pub struct CommandArgs {
|
||||
pub host: Arc<Mutex<dyn Host + Send>>,
|
||||
pub env: Arc<Mutex<Environment>>,
|
||||
pub name_span: Option<Span>,
|
||||
pub span_sources: HashMap<Uuid, SpanSource>,
|
||||
pub args: Args,
|
||||
pub input: InputStream,
|
||||
}
|
||||
@ -49,6 +53,7 @@ impl CommandArgs {
|
||||
pub struct SinkCommandArgs {
|
||||
pub ctx: Context,
|
||||
pub name_span: Option<Span>,
|
||||
pub span_sources: HashMap<Uuid, SpanSource>,
|
||||
pub args: Args,
|
||||
pub input: Vec<Spanned<Value>>,
|
||||
}
|
||||
@ -56,6 +61,7 @@ pub struct SinkCommandArgs {
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum CommandAction {
|
||||
ChangePath(PathBuf),
|
||||
AddSpanSource(Uuid, SpanSource),
|
||||
Exit,
|
||||
}
|
||||
|
||||
@ -82,6 +88,10 @@ impl ReturnSuccess {
|
||||
Ok(ReturnSuccess::Value(input.into()))
|
||||
}
|
||||
|
||||
pub fn action(input: CommandAction) -> ReturnValue {
|
||||
Ok(ReturnSuccess::Action(input))
|
||||
}
|
||||
|
||||
pub fn spanned_value(input: Value, span: Span) -> ReturnValue {
|
||||
Ok(ReturnSuccess::Value(Spanned::from_item(input, span)))
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::context::SpanSource;
|
||||
use crate::errors::ShellError;
|
||||
use crate::object::{Primitive, Switch, Value};
|
||||
use crate::parser::parse::span::Span;
|
||||
@ -5,6 +6,7 @@ use crate::prelude::*;
|
||||
use mime::Mime;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
use uuid::Uuid;
|
||||
|
||||
command! {
|
||||
Open as open(args, path: Spanned<PathBuf>, --raw: Switch,) {
|
||||
@ -21,19 +23,7 @@ command! {
|
||||
|
||||
let path_str = path.to_str().ok_or(ShellError::type_error("Path", "invalid path".spanned(path.span)))?;
|
||||
|
||||
let (file_extension, contents, contents_span) = fetch(&full_path, path_str, path.span)?;
|
||||
// let (file_extension, contents, contents_span) = match &args.expect_nth(0)?.item {
|
||||
// Value::Primitive(Primitive::String(s)) => fetch(&full_path, s, args.expect_nth(0)?.span)?,
|
||||
// _ => {
|
||||
// return Err(ShellError::labeled_error(
|
||||
// "Expected string value for filename",
|
||||
// "expected filename",
|
||||
// args.expect_nth(0)?.span,
|
||||
// ));
|
||||
// }
|
||||
// };
|
||||
|
||||
let mut stream = VecDeque::new();
|
||||
let (file_extension, contents, contents_span, span_source) = fetch(&full_path, path_str, path.span)?;
|
||||
|
||||
let file_extension = if raw.is_present() {
|
||||
None
|
||||
@ -41,6 +31,13 @@ command! {
|
||||
file_extension
|
||||
};
|
||||
|
||||
let mut stream = VecDeque::new();
|
||||
|
||||
if let Some(uuid) = contents_span.source {
|
||||
// If we have loaded something, track its source
|
||||
stream.push_back(ReturnSuccess::action(CommandAction::AddSpanSource(uuid, span_source)))
|
||||
}
|
||||
|
||||
match contents {
|
||||
Value::Primitive(Primitive::String(string)) =>
|
||||
stream.push_back(ReturnSuccess::value(parse_as_value(
|
||||
@ -62,7 +59,7 @@ pub fn fetch(
|
||||
cwd: &PathBuf,
|
||||
location: &str,
|
||||
span: Span,
|
||||
) -> Result<(Option<String>, Value, Span), ShellError> {
|
||||
) -> Result<(Option<String>, Value, Span, SpanSource), ShellError> {
|
||||
let mut cwd = cwd.clone();
|
||||
if location.starts_with("http:") || location.starts_with("https:") {
|
||||
let response = reqwest::get(location);
|
||||
@ -74,12 +71,14 @@ pub fn fetch(
|
||||
(mime::APPLICATION, mime::XML) => Ok((
|
||||
Some("xml".to_string()),
|
||||
Value::string(r.text().unwrap()),
|
||||
span,
|
||||
Span::unknown_with_uuid(Uuid::new_v4()),
|
||||
SpanSource::Url(r.url().to_string()),
|
||||
)),
|
||||
(mime::APPLICATION, mime::JSON) => Ok((
|
||||
Some("json".to_string()),
|
||||
Value::string(r.text().unwrap()),
|
||||
span,
|
||||
Span::unknown_with_uuid(Uuid::new_v4()),
|
||||
SpanSource::Url(r.url().to_string()),
|
||||
)),
|
||||
(mime::APPLICATION, mime::OCTET_STREAM) => {
|
||||
let mut buf: Vec<u8> = vec![];
|
||||
@ -90,7 +89,12 @@ pub fn fetch(
|
||||
span,
|
||||
)
|
||||
})?;
|
||||
Ok((None, Value::Binary(buf), span))
|
||||
Ok((
|
||||
None,
|
||||
Value::Binary(buf),
|
||||
Span::unknown_with_uuid(Uuid::new_v4()),
|
||||
SpanSource::Url(r.url().to_string()),
|
||||
))
|
||||
}
|
||||
(mime::IMAGE, image_ty) => {
|
||||
let mut buf: Vec<u8> = vec![];
|
||||
@ -101,12 +105,18 @@ pub fn fetch(
|
||||
span,
|
||||
)
|
||||
})?;
|
||||
Ok((Some(image_ty.to_string()), Value::Binary(buf), span))
|
||||
Ok((
|
||||
Some(image_ty.to_string()),
|
||||
Value::Binary(buf),
|
||||
Span::unknown_with_uuid(Uuid::new_v4()),
|
||||
SpanSource::Url(r.url().to_string()),
|
||||
))
|
||||
}
|
||||
(mime::TEXT, mime::HTML) => Ok((
|
||||
Some("html".to_string()),
|
||||
Value::string(r.text().unwrap()),
|
||||
span,
|
||||
Span::unknown_with_uuid(Uuid::new_v4()),
|
||||
SpanSource::Url(r.url().to_string()),
|
||||
)),
|
||||
(mime::TEXT, mime::PLAIN) => {
|
||||
let path_extension = r
|
||||
@ -120,16 +130,27 @@ pub fn fetch(
|
||||
.map(|name| name.to_string_lossy().to_string())
|
||||
});
|
||||
|
||||
Ok((path_extension, Value::string(r.text().unwrap()), span))
|
||||
Ok((
|
||||
path_extension,
|
||||
Value::string(r.text().unwrap()),
|
||||
Span::unknown_with_uuid(Uuid::new_v4()),
|
||||
SpanSource::Url(r.url().to_string()),
|
||||
))
|
||||
}
|
||||
(ty, sub_ty) => Ok((
|
||||
None,
|
||||
Value::string(format!("Not yet support MIME type: {} {}", ty, sub_ty)),
|
||||
span,
|
||||
Span::unknown_with_uuid(Uuid::new_v4()),
|
||||
SpanSource::Url(r.url().to_string()),
|
||||
)),
|
||||
}
|
||||
}
|
||||
None => Ok((None, Value::string(format!("No content type found")), span)),
|
||||
None => Ok((
|
||||
None,
|
||||
Value::string(format!("No content type found")),
|
||||
Span::unknown_with_uuid(Uuid::new_v4()),
|
||||
SpanSource::Url(r.url().to_string()),
|
||||
)),
|
||||
},
|
||||
Err(_) => {
|
||||
return Err(ShellError::labeled_error(
|
||||
@ -147,9 +168,15 @@ pub fn fetch(
|
||||
cwd.extension()
|
||||
.map(|name| name.to_string_lossy().to_string()),
|
||||
Value::string(s),
|
||||
span,
|
||||
Span::unknown_with_uuid(Uuid::new_v4()),
|
||||
SpanSource::File(cwd.to_string_lossy().to_string()),
|
||||
)),
|
||||
Err(_) => Ok((
|
||||
None,
|
||||
Value::Binary(bytes),
|
||||
Span::unknown_with_uuid(Uuid::new_v4()),
|
||||
SpanSource::File(cwd.to_string_lossy().to_string()),
|
||||
)),
|
||||
Err(_) => Ok((None, Value::Binary(bytes), span)),
|
||||
},
|
||||
Err(_) => {
|
||||
return Err(ShellError::labeled_error(
|
||||
|
@ -2,8 +2,6 @@ use crate::errors::ShellError;
|
||||
use crate::object::Value;
|
||||
use crate::prelude::*;
|
||||
|
||||
// TODO: "Amount remaining" wrapper
|
||||
|
||||
pub fn trim(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let input = args.input;
|
||||
|
||||
|
@ -4,15 +4,24 @@ use crate::parser::{
|
||||
Span,
|
||||
};
|
||||
use crate::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
use indexmap::IndexMap;
|
||||
use std::collections::HashMap;
|
||||
use std::error::Error;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub enum SpanSource {
|
||||
Url(String),
|
||||
File(String),
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub struct Context {
|
||||
commands: IndexMap<String, Arc<dyn Command>>,
|
||||
sinks: IndexMap<String, Arc<dyn Sink>>,
|
||||
crate span_sources: HashMap<Uuid, SpanSource>,
|
||||
crate host: Arc<Mutex<dyn Host + Send>>,
|
||||
crate env: Arc<Mutex<Environment>>,
|
||||
}
|
||||
@ -22,6 +31,7 @@ impl Context {
|
||||
Ok(Context {
|
||||
commands: indexmap::IndexMap::new(),
|
||||
sinks: indexmap::IndexMap::new(),
|
||||
span_sources: HashMap::new(),
|
||||
host: Arc::new(Mutex::new(crate::env::host::BasicHost)),
|
||||
env: Arc::new(Mutex::new(Environment::basic()?)),
|
||||
})
|
||||
@ -39,6 +49,10 @@ impl Context {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_span_source(&mut self, uuid: Uuid, span_source: SpanSource) {
|
||||
self.span_sources.insert(uuid, span_source);
|
||||
}
|
||||
|
||||
crate fn has_sink(&self, name: &str) -> bool {
|
||||
self.sinks.contains_key(name)
|
||||
}
|
||||
@ -57,6 +71,7 @@ impl Context {
|
||||
let command_args = SinkCommandArgs {
|
||||
ctx: self.clone(),
|
||||
name_span,
|
||||
span_sources: self.span_sources.clone(),
|
||||
args,
|
||||
input,
|
||||
};
|
||||
@ -80,6 +95,7 @@ impl Context {
|
||||
&mut self,
|
||||
command: Arc<dyn Command>,
|
||||
name_span: Option<Span>,
|
||||
span_sources: HashMap<Uuid, SpanSource>,
|
||||
args: Args,
|
||||
input: InputStream,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
@ -87,6 +103,7 @@ impl Context {
|
||||
host: self.host.clone(),
|
||||
env: self.env.clone(),
|
||||
name_span,
|
||||
span_sources,
|
||||
args,
|
||||
input,
|
||||
};
|
||||
|
@ -17,7 +17,12 @@ impl Description {
|
||||
pub fn from(item: Spanned<impl Into<String>>) -> Description {
|
||||
match item {
|
||||
Spanned {
|
||||
span: Span { start: 0, end: 0 },
|
||||
span:
|
||||
Span {
|
||||
start: 0,
|
||||
end: 0,
|
||||
source: None,
|
||||
},
|
||||
item,
|
||||
} => Description::Synthetic(item.into()),
|
||||
Spanned { span, item } => Description::Source(Spanned::from_item(item.into(), span)),
|
||||
|
@ -3,6 +3,7 @@ use derive_new::new;
|
||||
use getset::Getters;
|
||||
use serde::Serialize;
|
||||
use serde_derive::Deserialize;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(
|
||||
new, Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, Hash, Getters,
|
||||
@ -75,13 +76,17 @@ impl<T> Spanned<T> {
|
||||
pub struct Span {
|
||||
crate start: usize,
|
||||
crate end: usize,
|
||||
// source: &'source str,
|
||||
pub source: Option<Uuid>,
|
||||
}
|
||||
|
||||
impl From<Option<Span>> for Span {
|
||||
fn from(input: Option<Span>) -> Span {
|
||||
match input {
|
||||
None => Span { start: 0, end: 0 },
|
||||
None => Span {
|
||||
start: 0,
|
||||
end: 0,
|
||||
source: None,
|
||||
},
|
||||
Some(span) => span,
|
||||
}
|
||||
}
|
||||
@ -104,6 +109,7 @@ impl From<nom5_locate::LocatedSpan<&str>> for Span {
|
||||
Span {
|
||||
start: input.offset,
|
||||
end: input.offset + input.fragment.len(),
|
||||
source: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -113,6 +119,7 @@ impl<T> From<(nom5_locate::LocatedSpan<T>, nom5_locate::LocatedSpan<T>)> for Spa
|
||||
Span {
|
||||
start: input.0.offset,
|
||||
end: input.1.offset,
|
||||
source: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -122,6 +129,7 @@ impl From<(usize, usize)> for Span {
|
||||
Span {
|
||||
start: input.0,
|
||||
end: input.1,
|
||||
source: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -131,13 +139,26 @@ impl From<&std::ops::Range<usize>> for Span {
|
||||
Span {
|
||||
start: input.start,
|
||||
end: input.end,
|
||||
source: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Span {
|
||||
pub fn unknown() -> Span {
|
||||
Span { start: 0, end: 0 }
|
||||
Span {
|
||||
start: 0,
|
||||
end: 0,
|
||||
source: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unknown_with_uuid(uuid: Uuid) -> Span {
|
||||
Span {
|
||||
start: 0,
|
||||
end: 0,
|
||||
source: Some(uuid),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_unknown(&self) -> bool {
|
||||
@ -154,6 +175,7 @@ impl language_reporting::ReportingSpan for Span {
|
||||
Span {
|
||||
start,
|
||||
end: self.end,
|
||||
source: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -161,6 +183,7 @@ impl language_reporting::ReportingSpan for Span {
|
||||
Span {
|
||||
start: self.start,
|
||||
end,
|
||||
source: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user