Try again with math-like externals (#4629)

* Try again with math-like externals

* clippy 1.59

* clippy 1.59

* clippy 1.59
This commit is contained in:
JT 2022-02-24 14:02:28 -05:00 committed by GitHub
parent 2c9d8c4818
commit 3c62d27c28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 77 additions and 54 deletions

View File

@ -26,8 +26,7 @@ impl NuCompleter {
fn external_command_completion(&self, prefix: &str) -> Vec<String> {
let mut executables = vec![];
let paths;
paths = self.engine_state.env_vars.get("PATH");
let paths = self.engine_state.env_vars.get("PATH");
if let Some(paths) = paths {
if let Ok(paths) = paths.as_list() {
@ -470,7 +469,7 @@ fn file_path_completion(
) -> Vec<(nu_protocol::Span, String)> {
use std::path::{is_separator, Path};
let partial = partial.replace("\"", "");
let partial = partial.replace('\"', "");
let (base_dir_name, partial) = {
// If partial is only a word we want to search in the current dir

View File

@ -86,26 +86,26 @@ impl NushellPrompt {
impl Prompt for NushellPrompt {
fn render_prompt_left(&self) -> Cow<str> {
if let Some(prompt_string) = &self.left_prompt_string {
prompt_string.replace("\n", "\r\n").into()
prompt_string.replace('\n', "\r\n").into()
} else {
let default = DefaultPrompt::new();
default
.render_prompt_left()
.to_string()
.replace("\n", "\r\n")
.replace('\n', "\r\n")
.into()
}
}
fn render_prompt_right(&self) -> Cow<str> {
if let Some(prompt_string) = &self.right_prompt_string {
prompt_string.replace("\n", "\r\n").into()
prompt_string.replace('\n', "\r\n").into()
} else {
let default = DefaultPrompt::new();
default
.render_prompt_right()
.to_string()
.replace("\n", "\r\n")
.replace('\n', "\r\n")
.into()
}
}

View File

@ -188,7 +188,7 @@ fn convert_int(input: &Value, head: Span, radix: u32) -> Value {
Value::Int { val, .. } => val.to_string(),
Value::String { val, .. } => {
if val.starts_with("0x") || val.starts_with("0b") {
match int_from_string(&val.to_string(), head) {
match int_from_string(val, head) {
Ok(x) => return Value::Int { val: x, span: head },
Err(e) => return Value::Error { error: e },
}

View File

@ -451,7 +451,7 @@ fn html_value(value: Value, config: &Config) -> String {
}
other => output_string.push_str(
&htmlescape::encode_minimal(&other.into_abbreviated_string(config))
.replace("\n", "<br>"),
.replace('\n', "<br>"),
),
}
output_string

View File

@ -248,7 +248,7 @@ pub fn run_seq(
};
let last = {
let slice = &free[free.len() - 1][..];
padding = cmp::max(padding, slice.find('.').unwrap_or_else(|| slice.len()));
padding = cmp::max(padding, slice.find('.').unwrap_or(slice.len()));
match parse_float(slice) {
Ok(n) => n,
Err(s) => {

View File

@ -423,7 +423,7 @@ fn generate_ansi_code_list(
let cols = vec!["name".into(), "short name".into(), "code".into()];
let name: Value = Value::string(String::from(ansi_code.long_name), call_span);
let short_name = Value::string(ansi_code.short_name.unwrap_or(""), call_span);
let code_string = String::from(&ansi_code.code.replace("\u{1b}", ""));
let code_string = String::from(&ansi_code.code.replace('\u{1b}', ""));
let code = Value::string(code_string, call_span);
let vals = vec![name, short_name, code];
Value::Record {

View File

@ -397,7 +397,7 @@ impl ExternalCommand {
// Clean the args before we use them:
// https://stackoverflow.com/questions/1200235/how-to-pass-a-quoted-pipe-character-to-cmd-exe
// cmd.exe needs to have a caret to escape a pipe
let arg = arg.item.replace("|", "^|");
let arg = arg.item.replace('|', "^|");
process.arg(&arg);
}
process

View File

@ -928,7 +928,7 @@ where
if f1.len() <= f2.len() + 1 {
f1
} else if !f2.contains("e-") {
f2.replace("e", "e+")
f2.replace('e', "e+")
} else {
f2
}

View File

@ -2956,9 +2956,8 @@ pub fn parse_table_expression(
{
match values.len().cmp(&table_headers.len()) {
std::cmp::Ordering::Less => {
error = error.or_else(|| {
Some(ParseError::MissingColumns(table_headers.len(), span))
})
error = error
.or(Some(ParseError::MissingColumns(table_headers.len(), span)))
}
std::cmp::Ordering::Equal => {}
std::cmp::Ordering::Greater => {

View File

@ -259,7 +259,7 @@ impl PipelineData {
}
/// Simplified flatmapper. For full iterator support use `.into_iter()` instead
pub fn flat_map<U, F>(
pub fn flat_map<U: 'static, F>(
self,
mut f: F,
ctrlc: Option<Arc<AtomicBool>>,
@ -272,10 +272,10 @@ impl PipelineData {
{
match self {
PipelineData::Value(Value::List { vals, .. }, ..) => {
Ok(vals.into_iter().map(f).flatten().into_pipeline_data(ctrlc))
Ok(vals.into_iter().flat_map(f).into_pipeline_data(ctrlc))
}
PipelineData::ListStream(stream, ..) => {
Ok(stream.map(f).flatten().into_pipeline_data(ctrlc))
Ok(stream.flat_map(f).into_pipeline_data(ctrlc))
}
PipelineData::RawStream(stream, ..) => {
let collected = stream.into_bytes()?;
@ -297,7 +297,7 @@ impl PipelineData {
}
}
PipelineData::Value(Value::Range { val, .. }, ..) => match val.into_range_iter() {
Ok(iter) => Ok(iter.map(f).flatten().into_pipeline_data(ctrlc)),
Ok(iter) => Ok(iter.flat_map(f).into_pipeline_data(ctrlc)),
Err(error) => Err(error),
},
PipelineData::Value(v, ..) => Ok(f(v).into_iter().into_pipeline_data(ctrlc)),

View File

@ -2120,7 +2120,7 @@ fn format_filesize(num_bytes: i64, config: &Config) -> String {
// Since get_locale() and Locale::from_name() don't always return the same items
// we need to try and parse it to match. For instance, a valid locale is de_DE
// however Locale::from_name() wants only de so we split and parse it out.
let locale_string = locale_string.replace("_", "-"); // en_AU -> en-AU
let locale_string = locale_string.replace('_', "-"); // en_AU -> en-AU
let locale = match Locale::from_name(&locale_string) {
Ok(loc) => loc,
_ => {

View File

@ -194,7 +194,7 @@ impl ProcessInfo {
pub fn command(&self) -> String {
if let Ok(cmd) = &self.curr_proc.cmdline() {
if !cmd.is_empty() {
cmd.join(" ").replace("\n", " ").replace("\t", " ")
cmd.join(" ").replace('\n', " ").replace('\t', " ")
} else {
self.curr_proc.stat().comm.clone()
}

View File

@ -324,12 +324,12 @@ impl ProcessInfo {
pub fn command(&self) -> String {
if let Some(path) = &self.curr_path {
if !path.cmd.is_empty() {
path.cmd.join(" ").replace("\n", " ").replace("\t", " ")
path.cmd.join(" ").replace('\n', " ").replace('\t', " ")
} else {
String::from("")
String::new()
}
} else {
String::from("")
String::new()
}
}

View File

@ -209,7 +209,7 @@ pub fn collect_proc(interval: Duration, _with_thread: bool) -> Vec<ProcessInfo>
name: None,
domainname: None,
});
let groups = groups.unwrap_or_else(Vec::new);
let groups = groups.unwrap_or_default();
let thread = thread.unwrap_or_default();
let proc = ProcessInfo {

View File

@ -168,5 +168,5 @@ pub fn read_std(std: &[u8]) -> String {
let out = String::from_utf8_lossy(std);
let out = out.lines().collect::<Vec<_>>().join("\n");
let out = out.replace("\r\n", "");
out.replace("\n", "")
out.replace('\n', "")
}

View File

@ -157,5 +157,5 @@ fn read_std(std: &[u8]) -> Vec<u8> {
let out = String::from_utf8_lossy(std);
let out = out.lines().collect::<Vec<_>>().join("\n");
let out = out.replace("\r\n", "");
out.replace("\n", "").into_bytes()
out.replace('\n', "").into_bytes()
}

View File

@ -19,10 +19,6 @@ pub(crate) fn evaluate(
// First, set up env vars as strings only
gather_parent_env_vars(engine_state);
// Make a note of the exceptions we see for externals that look like math expressions
let exceptions = crate::utils::external_exceptions();
engine_state.external_exceptions = exceptions;
// Run a command (or commands) given to us by the user
let (block, delta) = {
let mut working_set = StateWorkingSet::new(engine_state);
@ -78,6 +74,10 @@ pub(crate) fn evaluate(
}
};
// Make a note of the exceptions we see for externals that look like math expressions
let exceptions = crate::utils::external_exceptions(engine_state, &stack);
engine_state.external_exceptions = exceptions;
// Merge the delta in case env vars changed in the config
match nu_engine::env::current_dir(engine_state, &stack) {
Ok(cwd) => {

View File

@ -22,10 +22,6 @@ pub(crate) fn evaluate(
// First, set up env vars as strings only
gather_parent_env_vars(engine_state);
// Make a note of the exceptions we see for externals that look like math expressions
let exceptions = crate::utils::external_exceptions();
engine_state.external_exceptions = exceptions;
let mut stack = nu_protocol::engine::Stack::new();
// Set up our initial config to start from
@ -45,6 +41,10 @@ pub(crate) fn evaluate(
std::process::exit(1);
}
// Make a note of the exceptions we see for externals that look like math expressions
let exceptions = crate::utils::external_exceptions(engine_state, &stack);
engine_state.external_exceptions = exceptions;
let file = std::fs::read(&path).into_diagnostic()?;
let mut working_set = StateWorkingSet::new(engine_state);

View File

@ -35,10 +35,6 @@ pub(crate) fn evaluate(
// First, set up env vars as strings only
gather_parent_env_vars(engine_state);
// Make a note of the exceptions we see for externals that look like math expressions
let exceptions = crate::utils::external_exceptions();
engine_state.external_exceptions = exceptions;
// Set up our initial config to start from
stack.vars.insert(
CONFIG_VARIABLE_ID,
@ -86,6 +82,10 @@ pub(crate) fn evaluate(
report_error(&working_set, &e);
}
// Make a note of the exceptions we see for externals that look like math expressions
let exceptions = crate::utils::external_exceptions(engine_state, &stack);
engine_state.external_exceptions = exceptions;
// seed the cmd_duration_ms env var
stack.add_env_var(
"CMD_DURATION_MS".into(),
@ -322,7 +322,7 @@ pub(crate) fn evaluate(
}
// Make a note of the exceptions we see for externals that look like math expressions
let exceptions = crate::utils::external_exceptions();
let exceptions = crate::utils::external_exceptions(engine_state, &stack);
engine_state.external_exceptions = exceptions;
}
Ok(Signal::CtrlC) => {

View File

@ -102,7 +102,7 @@ fn did_chop_arguments() -> bool {
for arg in arguments {
let chopped = if arg.is_empty() {
&arg
arg
} else {
let to = arg.len() - 1;
&arg[..to]

View File

@ -255,25 +255,50 @@ pub(crate) fn eval_source(
}
/// Finds externals that have names that look like math expressions
pub fn external_exceptions() -> Vec<Vec<u8>> {
pub fn external_exceptions(engine_state: &EngineState, stack: &Stack) -> Vec<Vec<u8>> {
let mut executables = vec![];
if let Ok(path) = std::env::var("PATH") {
for path in std::env::split_paths(&path) {
let path = path.to_string_lossy().to_string();
if let Some(path) = stack.get_env_var(engine_state, "PATH") {
match path {
Value::List { vals, .. } => {
for val in vals {
let path = val.as_string();
if let Ok(mut contents) = std::fs::read_dir(path) {
while let Some(Ok(item)) = contents.next() {
if is_executable::is_executable(&item.path()) {
if let Ok(name) = item.file_name().into_string() {
let name = name.as_bytes().to_vec();
if nu_parser::is_math_expression_like(&name) {
executables.push(name);
if let Ok(path) = path {
if let Ok(mut contents) = std::fs::read_dir(path) {
while let Some(Ok(item)) = contents.next() {
if is_executable::is_executable(&item.path()) {
if let Ok(name) = item.file_name().into_string() {
let name = name.as_bytes().to_vec();
if nu_parser::is_math_expression_like(&name) {
executables.push(name);
}
}
}
}
}
}
}
}
Value::String { val, .. } => {
for path in std::env::split_paths(&val) {
let path = path.to_string_lossy().to_string();
if let Ok(mut contents) = std::fs::read_dir(path) {
while let Some(Ok(item)) = contents.next() {
if is_executable::is_executable(&item.path()) {
if let Ok(name) = item.file_name().into_string() {
let name = name.as_bytes().to_vec();
if nu_parser::is_math_expression_like(&name) {
executables.push(name);
}
}
}
}
}
}
}
_ => {}
}
}
@ -318,7 +343,7 @@ pub fn report_error(
pub(crate) fn get_init_cwd() -> PathBuf {
match std::env::current_dir() {
Ok(cwd) => cwd,
Err(_) => match std::env::var("PWD".to_string()) {
Err(_) => match std::env::var("PWD") {
Ok(cwd) => PathBuf::from(cwd),
Err(_) => match nu_path::home_dir() {
Some(cwd) => cwd,