Skip to content

Commit

Permalink
fix(psl): handle named args in ds url env (prisma#4958)
Browse files Browse the repository at this point in the history
We now correctly propagate warnings from the ds url env and emit a warning for the usage of named arguments in the ds url env function
  • Loading branch information
Druue authored Jul 19, 2024
1 parent 15f8fe4 commit 77b82f6
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 12 deletions.
7 changes: 7 additions & 0 deletions psl/diagnostics/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ impl DatamodelError {
)
}

pub fn new_named_env_val(span: Span) -> Self {
Self::new(
"The env function expects a singular, unnamed, string argument.".to_owned(),
span,
)
}

pub fn new_argument_not_found_error(argument_name: &str, span: Span) -> DatamodelError {
Self::new(format!("Argument \"{argument_name}\" is missing."), span)
}
Expand Down
5 changes: 5 additions & 0 deletions psl/diagnostics/src/warning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ impl DatamodelWarning {
Self::new(message, span)
}

pub fn new_named_env_val(span: Span) -> Self {
let message = "The env function doesn't expect named arguments".to_owned();
Self::new(message, span)
}

pub fn new_field_validation(message: &str, model: &str, field: &str, span: Span) -> DatamodelWarning {
let msg = format!(
"Warning validating field `{}` in {} `{}`: {}",
Expand Down
35 changes: 23 additions & 12 deletions psl/psl-core/src/configuration/env_vars.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::parser_database::{ast, coerce};
use diagnostics::{DatamodelError, Diagnostics};
use diagnostics::{DatamodelError, DatamodelWarning, Diagnostics};
use schema_ast::ast::WithSpan;
use serde::Serialize;

/// Either an env var or a string literal.
Expand All @@ -15,16 +16,8 @@ pub struct StringFromEnvVar {
impl StringFromEnvVar {
pub(crate) fn coerce(expr: &ast::Expression, diagnostics: &mut Diagnostics) -> Option<Self> {
match expr {
ast::Expression::Function(name, _, _) if name == "env" => {
let mut errs = Diagnostics::new();
match EnvFunction::from_ast(expr, &mut errs) {
Some(env_function) => Some(StringFromEnvVar::new_from_env_var(env_function.var_name().to_owned())),
None => {
diagnostics.push_error(errs.errors()[0].clone());
None
}
}
}
ast::Expression::Function(name, _, _) if name == "env" => EnvFunction::from_ast(expr, diagnostics)
.map(|env_function| StringFromEnvVar::new_from_env_var(env_function.var_name().to_owned())),
ast::Expression::StringValue(value, _) => Some(StringFromEnvVar::new_literal(value.clone())),
_ => {
diagnostics.push_error(DatamodelError::new_type_mismatch_error(
Expand Down Expand Up @@ -71,6 +64,16 @@ impl EnvFunction {
fn from_ast(expr: &ast::Expression, diagnostics: &mut Diagnostics) -> Option<EnvFunction> {
let args = if let ast::Expression::Function(name, args, _) = &expr {
if name == "env" {
args.arguments
.iter()
.filter(|arg| !arg.is_unnamed())
.for_each(|arg| diagnostics.push_warning(DatamodelWarning::new_named_env_val(arg.span())));

if args.arguments.is_empty() && !args.empty_arguments.is_empty() {
diagnostics.push_error(DatamodelError::new_named_env_val(expr.span()));
return None;
}

args
} else {
diagnostics.push_error(DatamodelError::new_functional_evaluation_error(
Expand All @@ -87,7 +90,15 @@ impl EnvFunction {
return None;
};

if args.arguments.len() != 1 {
if args.arguments.len() + args.empty_arguments.len() != 1 {
diagnostics.push_error(DatamodelError::new_functional_evaluation_error(
"Exactly one string parameter must be passed to the env function.",
expr.span(),
));
return None;
}

if args.trailing_comma.is_some() {
diagnostics.push_error(DatamodelError::new_functional_evaluation_error(
"Exactly one string parameter must be passed to the env function.",
expr.span(),
Expand Down
11 changes: 11 additions & 0 deletions psl/psl/tests/validation/datasource/url_empty_named_arg.prisma
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
datasource testds {
provider = "mysql"
url = env(named: )
}

// error: The env function expects a singular, unnamed, string argument.
// --> schema.prisma:3
//  | 
//  2 |  provider = "mysql"
//  3 |  url = env(named: )
//  | 
11 changes: 11 additions & 0 deletions psl/psl/tests/validation/datasource/url_named_arg.prisma
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
datasource testds {
provider = "mysql"
url = env(named: "DATABASE_URL")
}

// warning: The env function doesn't expect named arguments
// --> schema.prisma:3
//  | 
//  2 |  provider = "mysql"
//  3 |  url = env(named: "DATABASE_URL")
//  | 

0 comments on commit 77b82f6

Please sign in to comment.