Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More crate docs #45

Merged
merged 3 commits into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ readme = "README.md"
repository = "https://github.com/reubeno/brush"
version = "0.1.0"

[workspace.lints.rust]
missing_docs = "warn"

[workspace.lints.clippy]
all = { level = "deny", priority = -1 }
pedantic = { level = "deny", priority = -1 }
Expand Down
10 changes: 10 additions & 0 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! The main entry point for the brush shell.

use std::{collections::HashSet, io::IsTerminal, path::Path};

use clap::{builder::styling, Parser};
Expand Down Expand Up @@ -72,20 +74,28 @@ struct CommandLineArgs {
script_args: Vec<String>,
}

/// Type of event to trace.
#[derive(Clone, Debug, Eq, Hash, PartialEq, clap::ValueEnum)]
enum TraceEvent {
/// Traces parsing and evaluation of arithmetic expressions.
#[clap(name = "arithmetic")]
Arithmetic,
/// Traces command execution.
#[clap(name = "commands")]
Commands,
/// Traces command completion generation.
#[clap(name = "complete")]
Complete,
/// Traces word expansion.
#[clap(name = "expand")]
Expand,
/// Traces the process of parsing tokens into an abstract syntax tree.
#[clap(name = "parse")]
Parse,
/// Traces pattern matching.
#[clap(name = "pattern")]
Pattern,
/// Traces the process of tokenizing input text.
#[clap(name = "tokenize")]
Tokenize,
}
Expand Down
11 changes: 6 additions & 5 deletions cli/tests/cases/builtins/shopt.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,12 @@ cases:
stdin: |
shopt extglob

# - name: "shopt -o interactive monitor default"
# args: ["-i"]
# ignore_stderr: true
# stdin: |
# shopt -o monitor
- name: "shopt -o interactive monitor default"
skip: true
args: ["-i"]
ignore_stderr: true
stdin: |
shopt -o monitor

- name: "shopt toggle"
stdin: |
Expand Down
30 changes: 16 additions & 14 deletions cli/tests/cases/patterns.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@ cases:
test_pattern "ad" "+(ab|ac)"

- name: "Pathname expansion: extglob disabled"
known_failure: true
ignore_stderr: true
test_files:
- path: "ab.txt"
Expand All @@ -159,23 +158,26 @@ cases:
- path: "abadac.txt"
- path: "fabadac.txt"
- path: "f.txt"
stdin: |
shopt -u extglob
- path: "script.sh"
contents: |
echo !(a*)
echo "result: $?"

echo !(a*)
echo "result: $?"

echo @(abc|abd).txt
echo "result: $?"
echo @(abc|abd).txt
echo "result: $?"

echo ab?(c).txt
echo "result: $?"
echo ab?(c).txt
echo "result: $?"

echo *(ab|ad|ac).txt
echo "result: $?"
echo *(ab|ad|ac).txt
echo "result: $?"

echo f+(ab|ad|ac).txt
echo "result: $?"
echo f+(ab|ad|ac).txt
echo "result: $?"
stdin: |
shopt -u extglob
chmod +x ./script.sh
./script.sh

- name: "Pathname expansion: Inverted patterns"
ignore_stderr: true
Expand Down
10 changes: 9 additions & 1 deletion cli/tests/cases/word_expansion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,6 @@ cases:
echo "${var[@]@L}"

- name: "Parameter quote transformations - Q"
known_failure: false
stdin: |
var='""'
echo "\${var@Q}: ${var@Q}"
Expand Down Expand Up @@ -705,11 +704,20 @@ cases:
var="Hello, world!"
echo "\${var@K}: ${var@K}"

var="a 'b c' d"
echo "\${var@K}: ${var@K}"

declare -a arr1=(a b c)
echo "\${arr1@K}: ${arr1@K}"
echo "\${arr1[1]@K}: ${arr1[1]@K}"
echo "\${arr1[@]@K}: ${arr1[@]@K}"
echo "\${arr1[*]@K}: ${arr1[*]@K}"

declare -A arr2=(["a"]=1 ["b"]=2)
echo "\${arr2@K}: ${arr2@K}"
echo "\${arr2[b]@K}: ${arr2[b]@K}"
echo "\${arr2[@]@K}: ${arr2[@]@K}"
echo "\${arr2[*]@K}: ${arr2[*]@K}"

- name: "Parameter quote transformations - k"
known_failure: true
Expand Down
2 changes: 2 additions & 0 deletions cli/tests/integration_tests.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! The test harness for brush shell integration tests.

use anyhow::{Context, Result};
use assert_fs::fixture::{FileWriteStr, PathChild};
use clap::Parser;
Expand Down
21 changes: 21 additions & 0 deletions interactive-shell/src/interactive_shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,36 @@ use std::{

type Editor = rustyline::Editor<EditorHelper, rustyline::history::FileHistory>;

/// Options for creating an interactive shell.
pub struct Options {
/// Lower-level options for creating the shell.
pub shell: shell::CreateOptions,
/// Whether to disable bracketed paste mode.
pub disable_bracketed_paste: bool,
}

/// Represents an interactive shell capable of taking commands from standard input
/// and reporting results to standard output and standard error streams.
pub struct InteractiveShell {
/// The `rustyline` editor.
editor: Editor,
/// Optional path to the history file used for the shell.
history_file_path: Option<PathBuf>,
}

/// Represents an error encountered while running or otherwise managing an interactive shell.
#[allow(clippy::module_name_repetitions)]
#[derive(thiserror::Error, Debug)]
pub enum InteractiveShellError {
/// An error occurred with the embedded shell.
#[error("{0}")]
ShellError(#[from] shell::Error),

/// A generic I/O error occurred.
#[error("I/O error: {0}")]
IoError(#[from] std::io::Error),

/// An error occurred while reading input.
#[error("input error: {0}")]
ReadlineError(#[from] rustyline::error::ReadlineError),
}
Expand All @@ -37,6 +48,11 @@ enum InteractiveExecutionResult {
}

impl InteractiveShell {
/// Returns a new interactive shell instance, created with the provided options.
///
/// # Arguments
///
/// * `options` - Options for creating the interactive shell.
pub async fn new(options: &Options) -> Result<InteractiveShell, InteractiveShellError> {
// Set up shell first. Its initialization may influence how the
// editor needs to operate.
Expand All @@ -58,10 +74,12 @@ impl InteractiveShell {
})
}

/// Returns an immutable reference to the inner shell object.
pub fn shell(&self) -> &shell::Shell {
&self.editor.helper().unwrap().shell
}

/// Returns a mutable reference to the inner shell object.
pub fn shell_mut(&mut self) -> &mut shell::Shell {
&mut self.editor.helper_mut().unwrap().shell
}
Expand All @@ -82,6 +100,9 @@ impl InteractiveShell {
Ok(editor)
}

/// Runs the interactive shell loop, reading commands from standard input and writing
/// results to standard output and standard error. Continues until the shell
/// normally exits or until a fatal error occurs.
pub async fn run_interactively(&mut self) -> Result<(), InteractiveShellError> {
loop {
// Check for any completed jobs.
Expand Down
2 changes: 2 additions & 0 deletions interactive-shell/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Library implementing interactive command input and completion for the brush shell.

mod interactive_shell;

pub use interactive_shell::{InteractiveShell, InteractiveShellError, Options};
Loading
Loading