Skip to content

Commit

Permalink
chore: minor cleanups and test additions (#364)
Browse files Browse the repository at this point in the history
Add more tests for FUNCNAME and LINENO well-known variables.
  • Loading branch information
reubeno authored Jan 27, 2025
1 parent b237567 commit c34bf7a
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 30 deletions.
4 changes: 2 additions & 2 deletions brush-core/src/builtins/colon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ impl builtins::SimpleCommand for ColonCommand {
}
}

fn execute(
fn execute<I: Iterator<Item = S>, S: AsRef<str>>(
_context: commands::ExecutionContext<'_>,
_args: &[&str],
_args: I,
) -> Result<builtins::BuiltinResult, crate::error::Error> {
Ok(builtins::BuiltinResult {
exit_code: builtins::ExitCode::Success,
Expand Down
7 changes: 3 additions & 4 deletions brush-core/src/builtins/declare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,8 @@ impl DeclareCommand {
cs.push('-');
}

let separator_str = if matches!(variable.value(), ShellValue::Unset(_)) {
let resolved_value = variable.resolve_value(context.shell);
let separator_str = if matches!(resolved_value, ShellValue::Unset(_)) {
""
} else {
"="
Expand All @@ -217,9 +218,7 @@ impl DeclareCommand {
writeln!(
context.stdout(),
"declare -{cs} {name}{separator_str}{}",
variable
.value()
.format(variables::FormatStyle::DeclarePrint, context.shell)?
resolved_value.format(variables::FormatStyle::DeclarePrint, context.shell)?
)?;

Ok(true)
Expand Down
2 changes: 1 addition & 1 deletion brush-core/src/builtins/dirs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::io::Write;
use crate::{builtins, commands};

/// Manage the current directory stack.
#[derive(Parser, Debug, Default)]
#[derive(Default, Parser)]
pub(crate) struct DirsCommand {
/// Clear the directory stack.
#[arg(short = 'c')]
Expand Down
2 changes: 1 addition & 1 deletion brush-core/src/builtins/dot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use clap::Parser;
use crate::{builtins, commands};

/// Evalute the provided script in the current shell environment.
#[derive(Debug, Parser)]
#[derive(Parser)]
pub(crate) struct DotCommand {
/// Path to the script to evaluate.
script_path: String,
Expand Down
19 changes: 7 additions & 12 deletions brush-core/src/builtins/factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ pub trait SimpleCommand {
-> Result<String, error::Error>;

/// Executes the built-in command.
fn execute(
fn execute<I: Iterator<Item = S>, S: AsRef<str>>(
context: commands::ExecutionContext<'_>,
args: &[&str],
args: I,
) -> Result<builtins::BuiltinResult, error::Error>;
}

Expand Down Expand Up @@ -75,17 +75,12 @@ async fn exec_simple_builtin_impl<T: SimpleCommand + Send + Sync>(
context: commands::ExecutionContext<'_>,
args: Vec<CommandArg>,
) -> Result<builtins::BuiltinResult, error::Error> {
let plain_args: Vec<_> = args
.into_iter()
.map(|arg| match arg {
CommandArg::String(s) => s,
CommandArg::Assignment(a) => a.to_string(),
})
.collect();

let plain_args: Vec<_> = plain_args.iter().map(AsRef::as_ref).collect();
let plain_args = args.into_iter().map(|arg| match arg {
CommandArg::String(s) => s,
CommandArg::Assignment(a) => a.to_string(),
});

T::execute(context, plain_args.as_slice())
T::execute(context, plain_args)
}

fn exec_builtin<T: builtins::Command + Send + Sync>(
Expand Down
23 changes: 14 additions & 9 deletions brush-core/src/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ pub struct Shell {
/// Clone depth from the original ancestor shell.
depth: usize,

/// Positional parameters ($1 and beyond)
pub positional_parameters: Vec<String>,

/// Shell name
/// Shell name (a.k.a. $0)
pub shell_name: Option<String>,

/// Positional parameters stack ($1 and beyond)
pub positional_parameters: Vec<String>,

/// Detailed display string for the shell
pub shell_product_display_str: Option<String>,

Expand Down Expand Up @@ -298,6 +298,7 @@ impl Shell {
}),
)?;

// TODO(vars): when extdebug is enabled, BASH_ARGC and BASH_ARGV are set to valid values
// TODO(vars): implement BASH_ARGC
// TODO(vars): implement BASH_ARGV

Expand Down Expand Up @@ -1199,11 +1200,15 @@ impl Shell {
}

fn get_funcname_value(&self) -> variables::ShellValue {
self.function_call_stack
.iter()
.map(|s| s.function_name.as_str())
.collect::<Vec<_>>()
.into()
if self.function_call_stack.is_empty() {
ShellValue::Unset(variables::ShellValueUnsetType::IndexedArray)
} else {
self.function_call_stack
.iter()
.map(|s| s.function_name.as_str())
.collect::<Vec<_>>()
.into()
}
}

fn get_bash_source_value(&self) -> variables::ShellValue {
Expand Down
7 changes: 6 additions & 1 deletion brush-core/src/variables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,12 @@ impl ShellVariable {
}
}

fn resolve_value(&self, shell: &Shell) -> ShellValue {
/// Returns the variable's value; for dynamic values, this will resolve the value.
///
/// # Arguments
///
/// * `shell` - The shell in which the variable is being resolved.
pub(crate) fn resolve_value(&self, shell: &Shell) -> ShellValue {
// N.B. We do *not* specially handle a dynamic value that resolves to a dynamic value.
match &self.value {
ShellValue::Dynamic { getter, .. } => getter(shell),
Expand Down
30 changes: 30 additions & 0 deletions brush-shell/tests/cases/well_known_vars.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,23 @@ cases:
echo "BASHOPTS: $BASHOPTS"
- name: "BASH_SOURCE and FUNCNAME"
stdin: |
echo "Input entry"; declare -p BASH_SOURCE FUNCNAME
function myfunc() {
echo "In function: \$1: $1"
declare -p BASH_SOURCE FUNCNAME
if [[ $1 -gt 0 ]]; then
myfunc $(( $1 - 1 ))
fi
}
myfunc 4
echo "Input exit"; declare -p BASH_SOURCE FUNCNAME
- name: "BASH_SUBSHELL"
stdin: |
echo "Initial BASH_SUBSHELL: $BASH_SUBSHELL"
Expand Down Expand Up @@ -96,6 +113,19 @@ cases:
echo $group
done) | sort
- name: "LINENO"
stdin: |
echo "LINENO: $LINENO"
echo "LINENO: $LINENO"
echo "LINENO: $LINENO"
- name: "LINENO with multi-line input"
known_failure: true # Not implemented correctly yet
stdin: |
for f in 1 2 3; do
echo "LINENO: $LINENO"
done
- name: "SHELLOPTS"
stdin: |
echo "SHELLOPTS: $SHELLOPTS"
Expand Down

0 comments on commit c34bf7a

Please sign in to comment.