feat(repl): add `DENO_REPL_HISTORY` to change history file path (#18047)

This commit is contained in:
Nick Hanley 2023-03-16 12:22:24 -04:00 committed by GitHub
parent b258763558
commit 1a3c2e2f1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 83 additions and 18 deletions

View File

@ -593,6 +593,9 @@ static ENV_VARIABLES_HELP: &str = r#"ENVIRONMENT VARIABLES:
DENO_DIR Set the cache directory
DENO_INSTALL_ROOT Set deno install's output directory
(defaults to $HOME/.deno/bin)
DENO_REPL_HISTORY Set REPL history file path
History file is disabled when the value is empty
(defaults to $DENO_DIR/deno_history.txt)
DENO_NO_PACKAGE_JSON Disables auto-resolution of package.json
DENO_NO_PROMPT Set to disable permission prompts on access
(alternative to passing --no-prompt on invocation)

14
cli/cache/deno_dir.rs vendored
View File

@ -2,6 +2,7 @@
use super::DiskCache;
use std::env;
use std::path::PathBuf;
/// `DenoDir` serves as coordinator for multiple `DiskCache`s containing them
@ -109,8 +110,17 @@ impl DenoDir {
}
/// Path used for the REPL history file.
pub fn repl_history_file_path(&self) -> PathBuf {
self.root.join("deno_history.txt")
/// Can be overridden or disabled by setting `DENO_REPL_HISTORY` environment variable.
pub fn repl_history_file_path(&self) -> Option<PathBuf> {
if let Some(deno_repl_history) = env::var_os("DENO_REPL_HISTORY") {
if deno_repl_history.is_empty() {
None
} else {
Some(PathBuf::from(deno_repl_history))
}
} else {
Some(self.root.join("deno_history.txt"))
}
}
/// Folder path used for downloading new versions of deno.

View File

@ -654,6 +654,52 @@ fn missing_deno_dir() {
assert!(err.is_empty());
}
#[test]
fn custom_history_path() {
use std::fs::read;
let temp_dir = TempDir::new();
let history_path = temp_dir.path().join("history.txt");
let (out, err) = util::run_and_collect_output(
true,
"repl",
Some(vec!["1"]),
Some(vec![
(
"DENO_REPL_HISTORY".to_owned(),
history_path.to_str().unwrap().to_owned(),
),
("NO_COLOR".to_owned(), "1".to_owned()),
]),
false,
);
assert!(read(&history_path).is_ok());
assert_ends_with!(out, "1\n");
assert!(err.is_empty());
}
#[test]
fn disable_history_file() {
let deno_dir = util::new_deno_dir();
let default_history_path = deno_dir.path().join("deno_history.txt");
let (out, err) = util::run_and_collect_output(
true,
"repl",
Some(vec!["1"]),
Some(vec![
(
"DENO_DIR".to_owned(),
deno_dir.path().to_str().unwrap().to_owned(),
),
("DENO_REPL_HISTORY".to_owned(), "".to_owned()),
("NO_COLOR".to_owned(), "1".to_owned()),
]),
false,
);
assert!(!default_history_path.try_exists().unwrap());
assert_ends_with!(out, "1\n");
assert!(err.is_empty());
}
#[test]
fn save_last_eval() {
let (out, err) = util::run_and_collect_output(

View File

@ -401,7 +401,7 @@ impl Highlighter for EditorHelper {
#[derive(Clone)]
pub struct ReplEditor {
inner: Arc<Mutex<Editor<EditorHelper>>>,
history_file_path: PathBuf,
history_file_path: Option<PathBuf>,
errored_on_history_save: Arc<AtomicBool>,
should_exit_on_interrupt: Arc<AtomicBool>,
}
@ -409,7 +409,7 @@ pub struct ReplEditor {
impl ReplEditor {
pub fn new(
helper: EditorHelper,
history_file_path: PathBuf,
history_file_path: Option<PathBuf>,
) -> Result<Self, AnyError> {
let editor_config = Config::builder()
.completion_type(CompletionType::List)
@ -418,7 +418,9 @@ impl ReplEditor {
let mut editor =
Editor::with_config(editor_config).expect("Failed to create editor.");
editor.set_helper(Some(helper));
editor.load_history(&history_file_path).unwrap_or(());
if let Some(history_file_path) = &history_file_path {
editor.load_history(history_file_path).unwrap_or(());
}
editor.bind_sequence(
KeyEvent(KeyCode::Char('s'), Modifiers::CTRL),
EventHandler::Simple(Cmd::Newline),
@ -435,13 +437,15 @@ impl ReplEditor {
})),
);
let history_file_dir = history_file_path.parent().unwrap();
std::fs::create_dir_all(history_file_dir).with_context(|| {
format!(
"Unable to create directory for the history file: {}",
history_file_dir.display()
)
})?;
if let Some(history_file_path) = &history_file_path {
let history_file_dir = history_file_path.parent().unwrap();
std::fs::create_dir_all(history_file_dir).with_context(|| {
format!(
"Unable to create directory for the history file: {}",
history_file_dir.display()
)
})?;
}
Ok(ReplEditor {
inner: Arc::new(Mutex::new(editor)),
@ -457,13 +461,15 @@ impl ReplEditor {
pub fn update_history(&self, entry: String) {
self.inner.lock().add_history_entry(entry);
if let Err(e) = self.inner.lock().append_history(&self.history_file_path) {
if self.errored_on_history_save.load(Relaxed) {
return;
}
if let Some(history_file_path) = &self.history_file_path {
if let Err(e) = self.inner.lock().append_history(history_file_path) {
if self.errored_on_history_save.load(Relaxed) {
return;
}
self.errored_on_history_save.store(true, Relaxed);
eprintln!("Unable to save history file: {e}");
self.errored_on_history_save.store(true, Relaxed);
eprintln!("Unable to save history file: {e}");
}
}
}