Skip to content

Commit 648cbd4

Browse files
authored
feat: implement alias (#101)
1 parent 6227f71 commit 648cbd4

File tree

4 files changed

+91
-10
lines changed

4 files changed

+91
-10
lines changed

crates/deno_task_shell/src/shell/execute.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,8 +643,19 @@ fn execute_command_args(
643643
let command_name = if args.is_empty() {
644644
String::new()
645645
} else {
646+
// check if the command name is in the alias hashmap
647+
if let Some(value) = state.alias_map().get(&args[0]) {
648+
args.remove(0);
649+
args = value
650+
.iter()
651+
.chain(args.iter())
652+
.cloned()
653+
.collect::<Vec<String>>();
654+
}
655+
646656
args.remove(0)
647657
};
658+
648659
if state.token().is_cancelled() {
649660
Box::pin(future::ready(ExecuteResult::for_cancellation()))
650661
} else if let Some(stripped_name) = command_name.strip_prefix('!') {

crates/deno_task_shell/src/shell/types.rs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,12 @@ pub struct ShellState {
2727
/// Variables that should be evaluated within the shell and
2828
/// not passed down to any sub commands.
2929
shell_vars: HashMap<String, String>,
30+
/// The current working directory of the shell
3031
cwd: PathBuf,
32+
/// The commands that are available in the shell
3133
commands: Rc<HashMap<String, Rc<dyn ShellCommand>>>,
34+
/// A map of aliases for commands (e.g. `ll=ls -al`)
35+
alias: HashMap<String, Vec<String>>,
3236
/// Token to cancel execution.
3337
token: CancellationToken,
3438
/// Git repository handling.
@@ -51,6 +55,7 @@ impl ShellState {
5155
let mut result = Self {
5256
env_vars: Default::default(),
5357
shell_vars: Default::default(),
58+
alias: Default::default(),
5459
cwd: PathBuf::new(),
5560
commands: Rc::new(commands),
5661
token: CancellationToken::default(),
@@ -72,6 +77,10 @@ impl ShellState {
7277
&self.cwd
7378
}
7479

80+
pub fn alias_map(&self) -> &HashMap<String, Vec<String>> {
81+
&self.alias
82+
}
83+
7584
pub fn git_repository(&self) -> bool {
7685
self.git_repository
7786
}
@@ -131,7 +140,7 @@ impl ShellState {
131140
}
132141
}
133142

134-
// TODO: set_cwd() is being called twice
143+
/// Set the current working directory of this shell
135144
pub fn set_cwd(&mut self, cwd: &Path) {
136145
self.cwd = cwd.to_path_buf();
137146
// $PWD holds the current working directory, so we keep cwd and $PWD in sync
@@ -204,6 +213,15 @@ impl ShellState {
204213
self.set_cwd(new_dir);
205214
self.last_command_cd = true;
206215
}
216+
EnvChange::AliasCommand(alias, cmd) => {
217+
self.alias.insert(
218+
alias.clone(),
219+
cmd.split_whitespace().map(ToString::to_string).collect(),
220+
);
221+
}
222+
EnvChange::UnAliasCommand(alias) => {
223+
self.alias.remove(alias);
224+
}
207225
}
208226
}
209227

@@ -264,12 +282,17 @@ impl ShellState {
264282

265283
#[derive(Debug, PartialEq, Eq)]
266284
pub enum EnvChange {
267-
// `export ENV_VAR=VALUE`
285+
/// `export ENV_VAR=VALUE`
268286
SetEnvVar(String, String),
269-
// `ENV_VAR=VALUE`
287+
/// `ENV_VAR=VALUE`
270288
SetShellVar(String, String),
271-
// `unset ENV_VAR`
289+
/// Create an alias for a command (e.g. ll=ls -al)
290+
AliasCommand(String, String),
291+
/// Remove an alias
292+
UnAliasCommand(String),
293+
/// `unset ENV_VAR`
272294
UnsetVar(String),
295+
/// Set the current working directory to the new Path
273296
Cd(PathBuf),
274297
}
275298

crates/shell/src/commands.rs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,48 @@
11
use std::ffi::OsString;
22

3-
use deno_task_shell::{ExecuteResult, ShellCommand, ShellCommandContext};
3+
use deno_task_shell::{EnvChange, ExecuteResult, ShellCommand, ShellCommandContext};
44
use futures::future::LocalBoxFuture;
55

66
use uu_ls::uumain as uu_ls;
77
pub struct LsCommand;
88

9+
pub struct AliasCommand;
10+
11+
pub struct UnAliasCommand;
12+
13+
impl ShellCommand for AliasCommand {
14+
fn execute(&self, context: ShellCommandContext) -> LocalBoxFuture<'static, ExecuteResult> {
15+
if context.args.len() != 1 {
16+
return Box::pin(futures::future::ready(ExecuteResult::from_exit_code(1)));
17+
}
18+
19+
// parse the args
20+
let env_change = if let Some((alias, cmd)) = context.args[0].split_once('=') {
21+
vec![EnvChange::AliasCommand(alias.into(), cmd.into())]
22+
} else {
23+
return Box::pin(futures::future::ready(ExecuteResult::from_exit_code(1)));
24+
};
25+
26+
let result = ExecuteResult::Continue(0, env_change, Vec::default());
27+
Box::pin(futures::future::ready(result))
28+
}
29+
}
30+
31+
impl ShellCommand for UnAliasCommand {
32+
fn execute(&self, context: ShellCommandContext) -> LocalBoxFuture<'static, ExecuteResult> {
33+
if context.args.len() != 1 {
34+
return Box::pin(futures::future::ready(ExecuteResult::from_exit_code(1)));
35+
}
36+
37+
let result = ExecuteResult::Continue(
38+
0,
39+
vec![EnvChange::UnAliasCommand(context.args[0].clone())],
40+
Vec::default(),
41+
);
42+
Box::pin(futures::future::ready(result))
43+
}
44+
}
45+
946
impl ShellCommand for LsCommand {
1047
fn execute(&self, context: ShellCommandContext) -> LocalBoxFuture<'static, ExecuteResult> {
1148
let result = execute_ls(context);

crates/shell/src/main.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,20 @@ mod completion;
1717
mod helper;
1818

1919
fn commands() -> HashMap<String, Rc<dyn ShellCommand>> {
20-
HashMap::from([(
21-
"ls".to_string(),
22-
Rc::new(commands::LsCommand) as Rc<dyn ShellCommand>,
23-
)])
20+
HashMap::from([
21+
(
22+
"ls".to_string(),
23+
Rc::new(commands::LsCommand) as Rc<dyn ShellCommand>,
24+
),
25+
(
26+
"alias".to_string(),
27+
Rc::new(commands::AliasCommand) as Rc<dyn ShellCommand>,
28+
),
29+
(
30+
"unalias".to_string(),
31+
Rc::new(commands::AliasCommand) as Rc<dyn ShellCommand>,
32+
),
33+
])
2434
}
2535

2636
async fn execute(text: &str, state: &mut ShellState) -> anyhow::Result<i32> {
@@ -48,8 +58,8 @@ async fn execute(text: &str, state: &mut ShellState) -> anyhow::Result<i32> {
4858

4959
match result {
5060
ExecuteResult::Continue(exit_code, changes, _) => {
51-
state.apply_changes(&changes);
5261
// set CWD to the last command's CWD
62+
state.apply_changes(&changes);
5363
std::env::set_current_dir(state.cwd()).context("Failed to set CWD")?;
5464
Ok(exit_code)
5565
}

0 commit comments

Comments
 (0)