Skip to content

Commit b41c9e0

Browse files
author
Archie Atkinson
committed
Adds recovery deps
1 parent 9322ee5 commit b41c9e0

File tree

9 files changed

+386
-5
lines changed

9 files changed

+386
-5
lines changed

src/justfile.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,9 +344,24 @@ impl<'src> Justfile<'src> {
344344
}
345345
}
346346

347-
recipe.run(context, &scope, &positional, is_dependency)?;
347+
let result = recipe.run(context, &scope, &positional, is_dependency);
348348

349-
if !context.config.no_dependencies {
349+
if let Err(err) = result {
350+
if recipe.recoveries().peekable().peek().is_none() {
351+
return Err(err);
352+
}
353+
354+
let mut ran = Ran::default();
355+
356+
for Dependency { recipe, arguments } in recipe.recoveries() {
357+
let evaluated = arguments
358+
.iter()
359+
.map(|argument| evaluator.evaluate_expression(argument))
360+
.collect::<RunResult<Vec<String>>>()?;
361+
362+
Self::run_recipe(&evaluated, context, &mut ran, recipe, true)?;
363+
}
364+
} else if !context.config.no_dependencies {
350365
let mut ran = Ran::default();
351366

352367
for Dependency { recipe, arguments } in recipe.subsequents() {

src/lexer.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,6 +1117,12 @@ mod tests {
11171117
tokens: (AmpersandAmpersand),
11181118
}
11191119

1120+
test! {
1121+
name: bar_bar,
1122+
text: "||",
1123+
tokens: (BarBar),
1124+
}
1125+
11201126
test! {
11211127
name: equals,
11221128
text: "=",

src/parser.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -956,6 +956,22 @@ impl<'run, 'src> Parser<'run, 'src> {
956956
dependencies.append(&mut subsequents);
957957
}
958958

959+
let if_error = dependencies.len();
960+
961+
if self.accepted(BarBar)? {
962+
let mut recoveries = Vec::new();
963+
964+
while let Some(recovery) = self.accept_dependency()? {
965+
recoveries.push(recovery);
966+
}
967+
968+
if recoveries.is_empty() {
969+
return Err(self.unexpected_token()?);
970+
}
971+
972+
dependencies.append(&mut recoveries);
973+
}
974+
959975
self.expect_eol()?;
960976

961977
let body = self.parse_body()?;
@@ -1007,6 +1023,7 @@ impl<'run, 'src> Parser<'run, 'src> {
10071023
dependencies,
10081024
doc: doc.filter(|doc| !doc.is_empty()),
10091025
file_depth: self.file_depth,
1026+
if_error,
10101027
import_offsets: self.import_offsets.clone(),
10111028
name,
10121029
namepath: self
@@ -2533,7 +2550,7 @@ mod tests {
25332550
column: 9,
25342551
width: 1,
25352552
kind: UnexpectedToken{
2536-
expected: vec![AmpersandAmpersand, Comment, Eof, Eol, Identifier, ParenL],
2553+
expected: vec![AmpersandAmpersand, BarBar, Comment, Eof, Eol, Identifier, ParenL],
25372554
found: Equals
25382555
},
25392556
}

src/recipe.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub(crate) struct Recipe<'src, D = Dependency<'src>> {
2525
pub(crate) doc: Option<String>,
2626
#[serde(skip)]
2727
pub(crate) file_depth: u32,
28+
pub(crate) if_error: usize,
2829
#[serde(skip)]
2930
pub(crate) import_offsets: Vec<usize>,
3031
pub(crate) name: Name<'src>,
@@ -503,7 +504,11 @@ impl<'src, D> Recipe<'src, D> {
503504
}
504505

505506
pub(crate) fn subsequents(&self) -> impl Iterator<Item = &D> {
506-
self.dependencies.iter().skip(self.priors)
507+
self.dependencies[self.priors..self.if_error].iter()
508+
}
509+
510+
pub(crate) fn recoveries(&self) -> impl Iterator<Item = &D> {
511+
self.dependencies[self.if_error..].iter()
507512
}
508513
}
509514

src/unresolved_recipe.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ impl<'src> UnresolvedRecipe<'src> {
5050
dependencies,
5151
doc: self.doc,
5252
file_depth: self.file_depth,
53+
if_error: self.if_error,
5354
import_offsets: self.import_offsets,
5455
name: self.name,
5556
namepath: self.namepath,

tests/json.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ struct Recipe<'a> {
6363
body: Vec<Value>,
6464
dependencies: Vec<Dependency<'a>>,
6565
doc: Option<&'a str>,
66+
if_error: u32,
6667
name: &'a str,
6768
namepath: &'a str,
6869
parameters: Vec<Parameter<'a>>,
@@ -277,6 +278,7 @@ fn dependencies() {
277278
..default()
278279
}]
279280
.into(),
281+
if_error: 1,
280282
priors: 1,
281283
..default()
282284
},
@@ -356,6 +358,7 @@ fn dependency_argument() {
356358
.into(),
357359
}]
358360
.into(),
361+
if_error: 1,
359362
priors: 1,
360363
..default()
361364
},
@@ -601,6 +604,7 @@ fn priors() {
601604
.into(),
602605
name: "b",
603606
namepath: "b",
607+
if_error: 2,
604608
priors: 1,
605609
..default()
606610
},

tests/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ mod private;
103103
mod quiet;
104104
mod quote;
105105
mod readme;
106+
mod recoveries;
106107
mod recursion_limit;
107108
mod regexes;
108109
mod request;

tests/misc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1634,7 +1634,7 @@ fn unexpected_token_in_dependency_position() {
16341634
.arg("foo")
16351635
.justfile("foo: 'bar'")
16361636
.stderr(
1637-
"error: Expected '&&', comment, end of file, end of line, \
1637+
"error: Expected '&&', '||', comment, end of file, end of line, \
16381638
identifier, or '(', but found string
16391639
——▶ justfile:1:6
16401640

0 commit comments

Comments
 (0)