Skip to content

Commit

Permalink
feat: implement source (#102)
Browse files Browse the repository at this point in the history
  • Loading branch information
wolfv authored Sep 11, 2024
1 parent 2d2124a commit b2c752b
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 44 deletions.
38 changes: 36 additions & 2 deletions crates/shell/src/commands.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
use std::ffi::OsString;
use std::{ffi::OsString, fs};

use deno_task_shell::{EnvChange, ExecuteResult, ShellCommand, ShellCommandContext};
use futures::future::LocalBoxFuture;
use futures::{future::LocalBoxFuture, FutureExt};

use uu_ls::uumain as uu_ls;

use crate::execute;
pub struct LsCommand;

pub struct AliasCommand;

pub struct UnAliasCommand;

pub struct SourceCommand;

impl ShellCommand for AliasCommand {
fn execute(&self, context: ShellCommandContext) -> LocalBoxFuture<'static, ExecuteResult> {
if context.args.len() != 1 {
Expand Down Expand Up @@ -61,3 +65,33 @@ fn execute_ls(context: ShellCommandContext) -> ExecuteResult {
let exit_code = uu_ls(args.into_iter());
ExecuteResult::from_exit_code(exit_code)
}

impl ShellCommand for SourceCommand {
fn execute(&self, context: ShellCommandContext) -> LocalBoxFuture<'static, ExecuteResult> {
if context.args.len() != 1 {
return Box::pin(futures::future::ready(ExecuteResult::from_exit_code(1)));
}

let script = context.args[0].clone();
let script_file = context.state.cwd().join(script);
match fs::read_to_string(&script_file) {
Ok(content) => {
let state = context.state.clone();
async move {
execute::execute_inner(&content, state)
.await
.unwrap_or_else(|e| {
eprintln!("Could not source script: {:?}", script_file);
eprintln!("Error: {}", e);
ExecuteResult::from_exit_code(1)
})
}
.boxed_local()
}
Err(e) => {
eprintln!("Could not read file: {:?} ({})", script_file, e);
Box::pin(futures::future::ready(ExecuteResult::from_exit_code(1)))
}
}
}
}
44 changes: 44 additions & 0 deletions crates/shell/src/execute.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use anyhow::Context;
use deno_task_shell::{
execute_sequential_list, AsyncCommandBehavior, ExecuteResult, ShellPipeReader, ShellPipeWriter,
ShellState,
};

pub async fn execute_inner(text: &str, state: ShellState) -> anyhow::Result<ExecuteResult> {
let list = deno_task_shell::parser::parse(text);

let stderr = ShellPipeWriter::stderr();
let stdout = ShellPipeWriter::stdout();
let stdin = ShellPipeReader::stdin();

if let Err(e) = list {
anyhow::bail!("Syntax error: {}", e);
}

// spawn a sequential list and pipe its output to the environment
let result = execute_sequential_list(
list.unwrap(),
state,
stdin,
stdout,
stderr,
AsyncCommandBehavior::Wait,
)
.await;

Ok(result)
}

pub async fn execute(text: &str, state: &mut ShellState) -> anyhow::Result<i32> {
let result = execute_inner(text, state.clone()).await?;

match result {
ExecuteResult::Continue(exit_code, changes, _) => {
// set CWD to the last command's CWD
state.apply_changes(&changes);
std::env::set_current_dir(state.cwd()).context("Failed to set CWD")?;
Ok(exit_code)
}
ExecuteResult::Exit(_, _) => Ok(0),
}
}
50 changes: 8 additions & 42 deletions crates/shell/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ use std::rc::Rc;
use anyhow::Context;
use clap::Parser;
use deno_task_shell::parser::debug_parse;
use deno_task_shell::{
execute_sequential_list, AsyncCommandBehavior, ExecuteResult, ShellCommand, ShellPipeReader,
ShellPipeWriter, ShellState,
};
use deno_task_shell::{ShellCommand, ShellState};
use rustyline::error::ReadlineError;
use rustyline::{CompletionType, Config, Editor};

mod commands;
mod completion;
mod execute;
mod helper;

pub use execute::execute;

fn commands() -> HashMap<String, Rc<dyn ShellCommand>> {
HashMap::from([
(
Expand All @@ -30,43 +30,13 @@ fn commands() -> HashMap<String, Rc<dyn ShellCommand>> {
"unalias".to_string(),
Rc::new(commands::AliasCommand) as Rc<dyn ShellCommand>,
),
(
"source".to_string(),
Rc::new(commands::SourceCommand) as Rc<dyn ShellCommand>,
),
])
}

async fn execute(text: &str, state: &mut ShellState) -> anyhow::Result<i32> {
let list = deno_task_shell::parser::parse(text);

let mut stderr = ShellPipeWriter::stderr();
let stdout = ShellPipeWriter::stdout();
let stdin = ShellPipeReader::stdin();

if let Err(e) = list {
let _ = stderr.write_line(&format!("Syntax error: {}", e));
return Ok(1);
}

// spawn a sequential list and pipe its output to the environment
let result = execute_sequential_list(
list.unwrap(),
state.clone(),
stdin,
stdout,
stderr,
AsyncCommandBehavior::Wait,
)
.await;

match result {
ExecuteResult::Continue(exit_code, changes, _) => {
// set CWD to the last command's CWD
state.apply_changes(&changes);
std::env::set_current_dir(state.cwd()).context("Failed to set CWD")?;
Ok(exit_code)
}
ExecuteResult::Exit(_, _) => Ok(0),
}
}

#[derive(Parser)]
struct Options {
/// The path to the file that should be executed
Expand All @@ -93,10 +63,6 @@ async fn interactive() -> anyhow::Result<()> {
let helper = helper::ShellPromptHelper::default();
rl.set_helper(Some(helper));

// let h = ShellCompleter {};

// rl.set_helper(Some(h));

let mut state = init_state();

let home = dirs::home_dir().context("Couldn't get home directory")?;
Expand Down

0 comments on commit b2c752b

Please sign in to comment.