Skip to content

Commit

Permalink
Förmatterdämmerung (#346)
Browse files Browse the repository at this point in the history
Format with rustfmt
  • Loading branch information
casey authored Dec 8, 2018
1 parent ec82cc2 commit 3d67786
Show file tree
Hide file tree
Showing 31 changed files with 1,645 additions and 985 deletions.
113 changes: 63 additions & 50 deletions src/assignment_evaluator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,30 @@ use brev;
pub struct AssignmentEvaluator<'a: 'b, 'b> {
pub assignments: &'b Map<&'a str, Expression<'a>>,
pub invocation_directory: &'b Result<PathBuf, String>,
pub dotenv: &'b Map<String, String>,
pub dry_run: bool,
pub evaluated: Map<&'a str, String>,
pub exports: &'b Set<&'a str>,
pub overrides: &'b Map<&'b str, &'b str>,
pub quiet: bool,
pub scope: &'b Map<&'a str, String>,
pub shell: &'b str,
pub dotenv: &'b Map<String, String>,
pub dry_run: bool,
pub evaluated: Map<&'a str, String>,
pub exports: &'b Set<&'a str>,
pub overrides: &'b Map<&'b str, &'b str>,
pub quiet: bool,
pub scope: &'b Map<&'a str, String>,
pub shell: &'b str,
}

impl<'a, 'b> AssignmentEvaluator<'a, 'b> {
pub fn evaluate_assignments(
assignments: &Map<&'a str, Expression<'a>>,
invocation_directory: &Result<PathBuf, String>,
dotenv: &'b Map<String, String>,
overrides: &Map<&str, &str>,
quiet: bool,
shell: &'a str,
dry_run: bool,
dotenv: &'b Map<String, String>,
overrides: &Map<&str, &str>,
quiet: bool,
shell: &'a str,
dry_run: bool,
) -> RunResult<'a, Map<&'a str, String>> {
let mut evaluator = AssignmentEvaluator {
evaluated: empty(),
exports: &empty(),
scope: &empty(),
exports: &empty(),
scope: &empty(),
assignments,
invocation_directory,
dotenv,
Expand All @@ -47,14 +47,14 @@ impl<'a, 'b> AssignmentEvaluator<'a, 'b> {

pub fn evaluate_line(
&mut self,
line: &[Fragment<'a>],
arguments: &Map<&str, Cow<str>>
line: &[Fragment<'a>],
arguments: &Map<&str, Cow<str>>,
) -> RunResult<'a, String> {
let mut evaluated = String::new();
for fragment in line {
match *fragment {
Fragment::Text{ref text} => evaluated += text.lexeme,
Fragment::Expression{ref expression} => {
Fragment::Text { ref text } => evaluated += text.lexeme,
Fragment::Expression { ref expression } => {
evaluated += &self.evaluate_expression(expression, arguments)?;
}
}
Expand All @@ -76,7 +76,7 @@ impl<'a, 'b> AssignmentEvaluator<'a, 'b> {
}
} else {
return Err(RuntimeError::Internal {
message: format!("attempted to evaluated unknown assignment {}", name)
message: format!("attempted to evaluated unknown assignment {}", name),
});
}

Expand All @@ -86,10 +86,10 @@ impl<'a, 'b> AssignmentEvaluator<'a, 'b> {
fn evaluate_expression(
&mut self,
expression: &Expression<'a>,
arguments: &Map<&str, Cow<str>>
arguments: &Map<&str, Cow<str>>,
) -> RunResult<'a, String> {
match *expression {
Expression::Variable{name, ..} => {
Expression::Variable { name, .. } => {
if self.evaluated.contains_key(name) {
Ok(self.evaluated[name].clone())
} else if self.scope.contains_key(name) {
Expand All @@ -101,64 +101,66 @@ impl<'a, 'b> AssignmentEvaluator<'a, 'b> {
Ok(arguments[name].to_string())
} else {
Err(RuntimeError::Internal {
message: format!("attempted to evaluate undefined variable `{}`", name)
message: format!("attempted to evaluate undefined variable `{}`", name),
})
}
}
Expression::Call{name, arguments: ref call_arguments, ref token} => {
let call_arguments = call_arguments.iter().map(|argument| {
self.evaluate_expression(argument, arguments)
}).collect::<Result<Vec<String>, RuntimeError>>()?;
Expression::Call {
name,
arguments: ref call_arguments,
ref token,
} => {
let call_arguments = call_arguments
.iter()
.map(|argument| self.evaluate_expression(argument, arguments))
.collect::<Result<Vec<String>, RuntimeError>>()?;
let context = FunctionContext {
invocation_directory: &self.invocation_directory,
dotenv: self.dotenv,
};
evaluate_function(token, name, &context, &call_arguments)
}
Expression::String{ref cooked_string} => Ok(cooked_string.cooked.clone()),
Expression::Backtick{raw, ref token} => {
Expression::String { ref cooked_string } => Ok(cooked_string.cooked.clone()),
Expression::Backtick { raw, ref token } => {
if self.dry_run {
Ok(format!("`{}`", raw))
} else {
Ok(self.run_backtick(self.dotenv, raw, token)?)
}
}
Expression::Concatination{ref lhs, ref rhs} => {
Ok(
self.evaluate_expression(lhs, arguments)?
+
&self.evaluate_expression(rhs, arguments)?
)
Expression::Concatination { ref lhs, ref rhs } => {
Ok(self.evaluate_expression(lhs, arguments)? + &self.evaluate_expression(rhs, arguments)?)
}
}
}

fn run_backtick(
&self,
dotenv: &Map<String, String>,
raw: &str,
token: &Token<'a>,
dotenv: &Map<String, String>,
raw: &str,
token: &Token<'a>,
) -> RunResult<'a, String> {
let mut cmd = Command::new(self.shell);

cmd.export_environment_variables(self.scope, dotenv, self.exports)?;

cmd.arg("-cu")
.arg(raw);
cmd.arg("-cu").arg(raw);

cmd.stderr(if self.quiet {
process::Stdio::null()
} else {
process::Stdio::inherit()
});

InterruptHandler::guard(|| brev::output(cmd)
.map_err(|output_error| RuntimeError::Backtick{token: token.clone(), output_error})
)
InterruptHandler::guard(|| {
brev::output(cmd).map_err(|output_error| RuntimeError::Backtick {
token: token.clone(),
output_error,
})
})
}
}


#[cfg(test)]
mod test {
use super::*;
Expand All @@ -173,11 +175,16 @@ mod test {
#[test]
fn backtick_code() {
match parse_success("a:\n echo {{`f() { return 100; }; f`}}")
.run(&no_cwd_err(), &["a"], &Default::default()).unwrap_err() {
RuntimeError::Backtick{token, output_error: OutputError::Code(code)} => {
.run(&no_cwd_err(), &["a"], &Default::default())
.unwrap_err()
{
RuntimeError::Backtick {
token,
output_error: OutputError::Code(code),
} => {
assert_eq!(code, 100);
assert_eq!(token.lexeme, "`f() { return 100; }; f`");
},
}
other => panic!("expected a code run error, but got: {}", other),
}
}
Expand All @@ -196,10 +203,16 @@ recipe:
..Default::default()
};

match parse_success(text).run(&no_cwd_err(), &["recipe"], &configuration).unwrap_err() {
RuntimeError::Backtick{token, output_error: OutputError::Code(_)} => {
match parse_success(text)
.run(&no_cwd_err(), &["recipe"], &configuration)
.unwrap_err()
{
RuntimeError::Backtick {
token,
output_error: OutputError::Code(_),
} => {
assert_eq!(token.lexeme, "`echo $exported_variable`");
},
}
other => panic!("expected a backtick code errror, but got: {}", other),
}
}
Expand Down
46 changes: 23 additions & 23 deletions src/assignment_resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,21 @@ use common::*;
use CompilationErrorKind::*;

pub struct AssignmentResolver<'a: 'b, 'b> {
assignments: &'b Map<&'a str, Expression<'a>>,
assignments: &'b Map<&'a str, Expression<'a>>,
assignment_tokens: &'b Map<&'a str, Token<'a>>,
stack: Vec<&'a str>,
seen: Set<&'a str>,
evaluated: Set<&'a str>,
stack: Vec<&'a str>,
seen: Set<&'a str>,
evaluated: Set<&'a str>,
}

impl<'a: 'b, 'b> AssignmentResolver<'a, 'b> {
pub fn resolve_assignments(
assignments: &Map<&'a str, Expression<'a>>,
assignments: &Map<&'a str, Expression<'a>>,
assignment_tokens: &Map<&'a str, Token<'a>>,
) -> CompilationResult<'a, ()> {

let mut resolver = AssignmentResolver {
stack: empty(),
seen: empty(),
stack: empty(),
seen: empty(),
evaluated: empty(),
assignments,
assignment_tokens,
Expand All @@ -45,44 +44,45 @@ impl<'a: 'b, 'b> AssignmentResolver<'a, 'b> {
} else {
let message = format!("attempted to resolve unknown assignment `{}`", name);
return Err(CompilationError {
text: "",
index: 0,
line: 0,
text: "",
index: 0,
line: 0,
column: 0,
width: None,
kind: Internal{message}
width: None,
kind: Internal { message },
});
}
Ok(())
}

fn resolve_expression(
&mut self, expression: &Expression<'a>) -> CompilationResult<'a, ()> {
fn resolve_expression(&mut self, expression: &Expression<'a>) -> CompilationResult<'a, ()> {
match *expression {
Expression::Variable{name, ref token} => {
Expression::Variable { name, ref token } => {
if self.evaluated.contains(name) {
return Ok(());
} else if self.seen.contains(name) {
let token = &self.assignment_tokens[name];
self.stack.push(name);
return Err(token.error(CircularVariableDependency {
variable: name,
circle: self.stack.clone(),
circle: self.stack.clone(),
}));
} else if self.assignments.contains_key(name) {
self.resolve_assignment(name)?;
} else {
return Err(token.error(UndefinedVariable{variable: name}));
return Err(token.error(UndefinedVariable { variable: name }));
}
}
Expression::Call{ref token, ref arguments, ..} => {
resolve_function(token, arguments.len())?
}
Expression::Concatination{ref lhs, ref rhs} => {
Expression::Call {
ref token,
ref arguments,
..
} => resolve_function(token, arguments.len())?,
Expression::Concatination { ref lhs, ref rhs } => {
self.resolve_expression(lhs)?;
self.resolve_expression(rhs)?;
}
Expression::String{..} | Expression::Backtick{..} => {}
Expression::String { .. } | Expression::Backtick { .. } => {}
}
Ok(())
}
Expand Down
19 changes: 8 additions & 11 deletions src/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ extern crate atty;

use common::*;

use self::ansi_term::{Style, Prefix, Suffix, ANSIGenericString};
use self::ansi_term::Color::*;
use self::ansi_term::{ANSIGenericString, Prefix, Style, Suffix};
use self::atty::is as is_atty;
use self::atty::Stream;

Expand All @@ -18,26 +18,23 @@ pub enum UseColor {
#[derive(Copy, Clone)]
pub struct Color {
use_color: UseColor,
atty: bool,
style: Style,
atty: bool,
style: Style,
}

impl Default for Color {
fn default() -> Color {
Color {
use_color: UseColor::Never,
atty: false,
style: Style::new(),
atty: false,
style: Style::new(),
}
}
}

impl Color {
fn restyle(self, style: Style) -> Color {
Color {
style,
..self
}
Color { style, ..self }
}

fn redirect(self, stream: Stream) -> Color {
Expand Down Expand Up @@ -127,8 +124,8 @@ impl Color {
pub fn active(&self) -> bool {
match self.use_color {
UseColor::Always => true,
UseColor::Never => false,
UseColor::Auto => self.atty,
UseColor::Never => false,
UseColor::Auto => self.atty,
}
}

Expand Down
14 changes: 7 additions & 7 deletions src/command_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@ use common::*;
pub trait CommandExt {
fn export_environment_variables<'a>(
&mut self,
scope: &Map<&'a str, String>,
dotenv: &Map<String, String>,
exports: &Set<&'a str>
scope: &Map<&'a str, String>,
dotenv: &Map<String, String>,
exports: &Set<&'a str>,
) -> RunResult<'a, ()>;
}

impl CommandExt for Command {
fn export_environment_variables<'a>(
&mut self,
scope: &Map<&'a str, String>,
dotenv: &Map<String, String>,
exports: &Set<&'a str>
scope: &Map<&'a str, String>,
dotenv: &Map<String, String>,
exports: &Set<&'a str>,
) -> RunResult<'a, ()> {
for (name, value) in dotenv {
self.env(name, value);
Expand All @@ -24,7 +24,7 @@ impl CommandExt for Command {
self.env(name, value);
} else {
return Err(RuntimeError::Internal {
message: format!("scope does not contain exported variable `{}`", name),
message: format!("scope does not contain exported variable `{}`", name),
});
}
}
Expand Down
Loading

0 comments on commit 3d67786

Please sign in to comment.