Add context to deprecation warnings (#473)
Previously, warnings upon encountering a deprecated use `=` in assignments, exports, and aliases would print a message without any indication of where the offending `=` was. This diff adds a proper `Warning` enum, and uses it to report context, as is done with compilation and runtime errors.
This commit is contained in:
parent
1cb90f4e65
commit
1230af138c
@ -46,7 +46,7 @@ pub(crate) use crate::{
|
||||
recipe_context::RecipeContext, recipe_resolver::RecipeResolver, runtime_error::RuntimeError,
|
||||
search_error::SearchError, shebang::Shebang, state::State, string_literal::StringLiteral,
|
||||
token::Token, token_kind::TokenKind, use_color::UseColor, variables::Variables,
|
||||
verbosity::Verbosity,
|
||||
verbosity::Verbosity, warning::Warning,
|
||||
};
|
||||
|
||||
pub(crate) type CompilationResult<'a, T> = Result<T, CompilationError<'a>>;
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::common::*;
|
||||
|
||||
use crate::misc::{maybe_s, show_whitespace, write_error_context, Or};
|
||||
use crate::misc::{maybe_s, show_whitespace, write_message_context, Or};
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub(crate) struct CompilationError<'a> {
|
||||
@ -211,8 +211,9 @@ impl<'a> Display for CompilationError<'a> {
|
||||
|
||||
write!(f, "{}", message.suffix())?;
|
||||
|
||||
write_error_context(
|
||||
write_message_context(
|
||||
f,
|
||||
Color::fmt(f).error(),
|
||||
self.text,
|
||||
self.offset,
|
||||
self.line,
|
||||
|
@ -6,7 +6,7 @@ pub(crate) struct Justfile<'a> {
|
||||
pub(crate) assignments: BTreeMap<&'a str, Expression<'a>>,
|
||||
pub(crate) exports: BTreeSet<&'a str>,
|
||||
pub(crate) aliases: BTreeMap<&'a str, Alias<'a>>,
|
||||
pub(crate) deprecated_equals: bool,
|
||||
pub(crate) warnings: Vec<Warning<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> Justfile<'a> where {
|
||||
|
@ -56,6 +56,7 @@ mod token_kind;
|
||||
mod use_color;
|
||||
mod variables;
|
||||
mod verbosity;
|
||||
mod warning;
|
||||
|
||||
pub use crate::run::run;
|
||||
|
||||
|
@ -55,8 +55,9 @@ pub(crate) fn conjoin<T: Display>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn write_error_context(
|
||||
pub(crate) fn write_message_context(
|
||||
f: &mut Formatter,
|
||||
color: Color,
|
||||
text: &str,
|
||||
offset: usize,
|
||||
line: usize,
|
||||
@ -66,7 +67,6 @@ pub(crate) fn write_error_context(
|
||||
let width = if width == 0 { 1 } else { width };
|
||||
|
||||
let line_number = line.ordinal();
|
||||
let red = Color::fmt(f).error();
|
||||
match text.lines().nth(line) {
|
||||
Some(line) => {
|
||||
let mut i = 0;
|
||||
@ -102,10 +102,10 @@ pub(crate) fn write_error_context(
|
||||
" {0:1$}{2}{3:^<4$}{5}",
|
||||
"",
|
||||
space_column,
|
||||
red.prefix(),
|
||||
color.prefix(),
|
||||
"",
|
||||
space_width,
|
||||
red.suffix()
|
||||
color.suffix()
|
||||
)?;
|
||||
}
|
||||
None => {
|
||||
|
@ -12,7 +12,7 @@ pub(crate) struct Parser<'a> {
|
||||
exports: BTreeSet<&'a str>,
|
||||
aliases: BTreeMap<&'a str, Alias<'a>>,
|
||||
alias_tokens: BTreeMap<&'a str, Token<'a>>,
|
||||
deprecated_equals: bool,
|
||||
warnings: Vec<Warning<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> Parser<'a> {
|
||||
@ -32,7 +32,7 @@ impl<'a> Parser<'a> {
|
||||
exports: empty(),
|
||||
aliases: empty(),
|
||||
alias_tokens: empty(),
|
||||
deprecated_equals: false,
|
||||
warnings: Vec::new(),
|
||||
text,
|
||||
}
|
||||
}
|
||||
@ -421,8 +421,10 @@ impl<'a> Parser<'a> {
|
||||
Name => {
|
||||
if token.lexeme() == "export" {
|
||||
let next = self.tokens.next().unwrap();
|
||||
if next.kind == Name && self.accepted(Equals) {
|
||||
self.deprecated_equals = true;
|
||||
if next.kind == Name && self.peek(Equals) {
|
||||
self.warnings.push(Warning::DeprecatedEquals {
|
||||
equals: self.tokens.next().unwrap(),
|
||||
});
|
||||
self.assignment(next, true)?;
|
||||
doc = None;
|
||||
} else if next.kind == Name && self.accepted(ColonEquals) {
|
||||
@ -435,8 +437,10 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
} else if token.lexeme() == "alias" {
|
||||
let next = self.tokens.next().unwrap();
|
||||
if next.kind == Name && self.accepted(Equals) {
|
||||
self.deprecated_equals = true;
|
||||
if next.kind == Name && self.peek(Equals) {
|
||||
self.warnings.push(Warning::DeprecatedEquals {
|
||||
equals: self.tokens.next().unwrap(),
|
||||
});
|
||||
self.alias(next)?;
|
||||
doc = None;
|
||||
} else if next.kind == Name && self.accepted(ColonEquals) {
|
||||
@ -447,8 +451,10 @@ impl<'a> Parser<'a> {
|
||||
self.recipe(&token, doc, false)?;
|
||||
doc = None;
|
||||
}
|
||||
} else if self.accepted(Equals) {
|
||||
self.deprecated_equals = true;
|
||||
} else if self.peek(Equals) {
|
||||
self.warnings.push(Warning::DeprecatedEquals {
|
||||
equals: self.tokens.next().unwrap(),
|
||||
});
|
||||
self.assignment(token, false)?;
|
||||
doc = None;
|
||||
} else if self.accepted(ColonEquals) {
|
||||
@ -515,7 +521,7 @@ impl<'a> Parser<'a> {
|
||||
assignments: self.assignments,
|
||||
exports: self.exports,
|
||||
aliases: self.aliases,
|
||||
deprecated_equals: self.deprecated_equals,
|
||||
warnings: self.warnings,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
22
src/run.rs
22
src/run.rs
@ -318,22 +318,12 @@ pub fn run() {
|
||||
}
|
||||
});
|
||||
|
||||
if justfile.deprecated_equals {
|
||||
let warning = color.warning().stderr();
|
||||
let message = color.message().stderr();
|
||||
|
||||
eprintln!(
|
||||
"{}",
|
||||
warning.paint(
|
||||
"warning: `=` in assignments, exports, and aliases is being phased out on favor of `:=`"
|
||||
)
|
||||
);
|
||||
|
||||
eprintln!(
|
||||
"{}",
|
||||
message
|
||||
.paint("Please see this issue for more details: https://github.com/casey/just/issues/379")
|
||||
);
|
||||
for warning in &justfile.warnings {
|
||||
if color.stderr().active() {
|
||||
eprintln!("{:#}", warning);
|
||||
} else {
|
||||
eprintln!("{}", warning);
|
||||
}
|
||||
}
|
||||
|
||||
if matches.is_present("SUMMARY") {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::common::*;
|
||||
|
||||
use crate::misc::{maybe_s, ticks, write_error_context, And, Or, Tick};
|
||||
use crate::misc::{maybe_s, ticks, write_message_context, And, Or, Tick};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum RuntimeError<'a> {
|
||||
@ -387,8 +387,9 @@ impl<'a> Display for RuntimeError<'a> {
|
||||
write!(f, "{}", message.suffix())?;
|
||||
|
||||
if let Some(token) = error_token {
|
||||
write_error_context(
|
||||
write_message_context(
|
||||
f,
|
||||
Color::fmt(f).error(),
|
||||
token.text,
|
||||
token.offset,
|
||||
token.line,
|
||||
|
56
src/warning.rs
Normal file
56
src/warning.rs
Normal file
@ -0,0 +1,56 @@
|
||||
use crate::common::*;
|
||||
use crate::misc::write_message_context;
|
||||
|
||||
use Warning::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum Warning<'a> {
|
||||
DeprecatedEquals { equals: Token<'a> },
|
||||
}
|
||||
|
||||
impl Warning<'_> {
|
||||
fn context(&self) -> Option<&Token> {
|
||||
match self {
|
||||
DeprecatedEquals { equals } => Some(equals),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Warning<'_> {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
let warning = Color::fmt(f).warning();
|
||||
let message = Color::fmt(f).message();
|
||||
|
||||
write!(f, "{} {}", warning.paint("warning:"), message.prefix())?;
|
||||
|
||||
match self {
|
||||
DeprecatedEquals { .. } => {
|
||||
writeln!(
|
||||
f,
|
||||
"`=` in assignments, exports, and aliases is being phased out on favor of `:=`"
|
||||
)?;
|
||||
write!(
|
||||
f,
|
||||
"Please see this issue for more details: https://github.com/casey/just/issues/379"
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
write!(f, "{}", message.suffix())?;
|
||||
|
||||
if let Some(token) = self.context() {
|
||||
writeln!(f)?;
|
||||
write_message_context(
|
||||
f,
|
||||
Color::fmt(f).warning(),
|
||||
token.text,
|
||||
token.offset,
|
||||
token.line,
|
||||
token.column,
|
||||
token.lexeme().len(),
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
@ -2414,6 +2414,9 @@ default:
|
||||
stdout: "bar\n",
|
||||
stderr: "warning: `=` in assignments, exports, and aliases is being phased out on favor of `:=`
|
||||
Please see this issue for more details: https://github.com/casey/just/issues/379
|
||||
|
|
||||
3 | foo = 'bar'
|
||||
| ^
|
||||
echo bar
|
||||
",
|
||||
status: EXIT_SUCCESS,
|
||||
@ -2434,6 +2437,9 @@ default:
|
||||
stdout: "bar\n",
|
||||
stderr: "warning: `=` in assignments, exports, and aliases is being phased out on favor of `:=`
|
||||
Please see this issue for more details: https://github.com/casey/just/issues/379
|
||||
|
|
||||
3 | export FOO = 'bar'
|
||||
| ^
|
||||
echo $FOO
|
||||
",
|
||||
status: EXIT_SUCCESS,
|
||||
@ -2454,6 +2460,9 @@ default:
|
||||
stdout: "default\n",
|
||||
stderr: "warning: `=` in assignments, exports, and aliases is being phased out on favor of `:=`
|
||||
Please see this issue for more details: https://github.com/casey/just/issues/379
|
||||
|
|
||||
3 | alias foo = default
|
||||
| ^
|
||||
echo default
|
||||
",
|
||||
status: EXIT_SUCCESS,
|
||||
|
Loading…
Reference in New Issue
Block a user