1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
use crate::call_info::UnevaluatedCallInfo;
use crate::command_args::CommandArgs;
use crate::env::host::Host;
use crate::evaluate::scope::Scope;
use crate::shell::shell_manager::ShellManager;
use crate::whole_stream_command::Command;
use indexmap::IndexMap;
use nu_errors::ShellError;
use nu_protocol::hir;
use nu_source::Tag;
use nu_stream::{InputStream, OutputStream};
use parking_lot::Mutex;
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
#[derive(Clone)]
pub struct EvaluationContext {
pub scope: Scope,
pub host: Arc<parking_lot::Mutex<Box<dyn Host>>>,
pub current_errors: Arc<Mutex<Vec<ShellError>>>,
pub ctrl_c: Arc<AtomicBool>,
pub user_recently_used_autoenv_untrust: Arc<AtomicBool>,
pub shell_manager: ShellManager,
pub windows_drives_previous_cwd: Arc<Mutex<std::collections::HashMap<String, String>>>,
}
impl EvaluationContext {
pub fn from_raw(raw_args: &CommandArgs) -> EvaluationContext {
EvaluationContext {
scope: raw_args.scope.clone(),
host: raw_args.host.clone(),
current_errors: raw_args.current_errors.clone(),
ctrl_c: raw_args.ctrl_c.clone(),
shell_manager: raw_args.shell_manager.clone(),
user_recently_used_autoenv_untrust: Arc::new(AtomicBool::new(false)),
windows_drives_previous_cwd: Arc::new(Mutex::new(std::collections::HashMap::new())),
}
}
pub fn from_args(args: &CommandArgs) -> EvaluationContext {
EvaluationContext {
scope: args.scope.clone(),
host: args.host.clone(),
current_errors: args.current_errors.clone(),
ctrl_c: args.ctrl_c.clone(),
shell_manager: args.shell_manager.clone(),
user_recently_used_autoenv_untrust: Arc::new(AtomicBool::new(false)),
windows_drives_previous_cwd: Arc::new(Mutex::new(std::collections::HashMap::new())),
}
}
pub fn error(&self, error: ShellError) {
self.with_errors(|errors| errors.push(error))
}
pub fn clear_errors(&self) {
self.current_errors.lock().clear()
}
pub fn get_errors(&self) -> Vec<ShellError> {
self.current_errors.lock().clone()
}
pub fn configure<T>(
&mut self,
config: &dyn nu_data::config::Conf,
block: impl FnOnce(&dyn nu_data::config::Conf, &mut Self) -> T,
) {
block(config, &mut *self);
}
pub fn with_host<T>(&self, block: impl FnOnce(&mut dyn Host) -> T) -> T {
let mut host = self.host.lock();
block(&mut *host)
}
pub fn with_errors<T>(&self, block: impl FnOnce(&mut Vec<ShellError>) -> T) -> T {
let mut errors = self.current_errors.lock();
block(&mut *errors)
}
pub fn add_commands(&self, commands: Vec<Command>) {
for command in commands {
self.scope.add_command(command.name().to_string(), command);
}
}
#[allow(unused)]
pub(crate) fn get_command(&self, name: &str) -> Option<Command> {
self.scope.get_command(name)
}
pub fn is_command_registered(&self, name: &str) -> bool {
self.scope.has_command(name)
}
pub(crate) async fn run_command(
&self,
command: Command,
name_tag: Tag,
args: hir::Call,
input: InputStream,
) -> Result<OutputStream, ShellError> {
let command_args = self.command_args(args, input, name_tag);
command.run(command_args).await
}
fn call_info(&self, args: hir::Call, name_tag: Tag) -> UnevaluatedCallInfo {
UnevaluatedCallInfo { args, name_tag }
}
fn command_args(&self, args: hir::Call, input: InputStream, name_tag: Tag) -> CommandArgs {
CommandArgs {
host: self.host.clone(),
ctrl_c: self.ctrl_c.clone(),
current_errors: self.current_errors.clone(),
shell_manager: self.shell_manager.clone(),
call_info: self.call_info(args, name_tag),
scope: self.scope.clone(),
input,
}
}
pub fn get_env(&self) -> IndexMap<String, String> {
let mut output = IndexMap::new();
for (var, value) in self.host.lock().vars() {
output.insert(var, value);
}
output
}
}