[cli] Part 2: Don't use exit() to terminate the CLI.

It's not possible to do meaningful clean-up (such as saving history)
if we use exit() to quit.  Instead, each handled command returns a
boolean requesting exit.  I elected not to allow ".exit" when
processing commands from the command line; it might be useful to
handle accept that.  In general, though, REPLs that accept "-c
'commands'" on the command line exit after processing those commands,
so I'd rather think more deeply about that model than build in ".exit"
with our existing system.
This commit is contained in:
Nick Alexander 2018-06-22 11:28:02 -07:00
parent c19337c8bf
commit c41d728d1d

View file

@ -9,7 +9,6 @@
// specific language governing permissions and limitations under the License. // specific language governing permissions and limitations under the License.
use std::io::Write; use std::io::Write;
use std::process;
use failure::{ use failure::{
err_msg, err_msg,
@ -238,7 +237,9 @@ impl Repl {
match res { match res {
Ok(MetaCommand(cmd)) => { Ok(MetaCommand(cmd)) => {
debug!("read command: {:?}", cmd); debug!("read command: {:?}", cmd);
self.handle_command(cmd); if !self.handle_command(cmd) {
break;
}
}, },
Ok(Empty) | Ok(Empty) |
Ok(More) => (), Ok(More) => (),
@ -265,7 +266,7 @@ impl Repl {
} }
/// Runs a single command input. /// Runs a single command input.
fn handle_command(&mut self, cmd: Command) { fn handle_command(&mut self, cmd: Command) -> bool {
let should_print_times = self.timer_on && cmd.is_timed(); let should_print_times = self.timer_on && cmd.is_timed();
let mut start = PreciseTime::now(); let mut start = PreciseTime::now();
@ -279,9 +280,8 @@ impl Repl {
self.close(); self.close();
}, },
Command::Exit => { Command::Exit => {
self.close();
eprintln!("Exiting…"); eprintln!("Exiting…");
process::exit(0); return false;
}, },
Command::Help(args) => { Command::Help(args) => {
self.help_command(args); self.help_command(args);
@ -378,6 +378,8 @@ impl Repl {
eprint!(": "); eprint!(": ");
format_time(start.to(end)); format_time(start.to(end));
} }
return true;
} }
fn execute_import<T>(&mut self, path: T) fn execute_import<T>(&mut self, path: T)