Repository: Brendonovich/prisma-client-rust (language: rust)

Issue:
Custom schema paths not respected
Brought to my attention by @kkharji in #182.

Sorta forgot that `EngineDMMF` already provides the `schema_path` and all my logic for locating the schema is pointless, since it's way more accurate and respects custom schema paths.


Discussion / hints:

Fix patch:
diff --git a/cli/src/generator/header.rs b/cli/src/generator/header.rs
index b94fb141..c6a8302f 100644
--- a/cli/src/generator/header.rs
+++ b/cli/src/generator/header.rs
@@ -1,48 +1,30 @@
 use proc_macro2::TokenStream;
 use quote::quote;
-use std::env::current_dir;
 use std::path::*;
 
 use crate::generator::GenerateArgs;
 
-static SCHEMA_PRISMA: &'static str = "schema.prisma";
-
-fn find_schema_path() -> Result<PathBuf, ()> {
-    let current_dir = current_dir().expect("Failed to get current directory");
-    let current_dir = Path::new(&current_dir);
-
-    let root_file_path = current_dir.join(SCHEMA_PRISMA);
-    let nested_file_path = current_dir.join("prisma").join(SCHEMA_PRISMA);
-
-    match root_file_path.exists() {
-        true => Ok(root_file_path),
-        false if nested_file_path.exists() => Ok(nested_file_path),
-        _ => Err(()),
-    }
-}
-
-fn find_migrations_path() -> Result<PathBuf, ()> {
-    let schema_path = find_schema_path()?;
-
-    let migrations_path = schema_path
+fn find_migrations_path(schema_path: &PathBuf) -> PathBuf {
+    schema_path
         .parent()
-        .expect("Schema path has no parent!")
-        .join("migrations");
-
-    migrations_path.exists().then(|| migrations_path).ok_or(())
+        .map(|p| p.join("migrations"))
+        .filter(|p| p.exists())
+        .expect("Migrations folder not found!")
 }
 
 pub fn generate(args: &GenerateArgs) -> TokenStream {
-    let database_string = &args.datasources[0].provider;
+    let database_string = &args.ctx.datasources[0].provider;
 
     let pcr = quote!(::prisma_client_rust);
 
-    let schema_path = find_schema_path().expect("Schema not found!");
-    let schema_path = schema_path.to_str().expect("Invalid schema path");
+    let schema_path_str = &args.ctx.schema_path;
+    let schema_path = schema_path_str
+        .parse()
+        .expect("Failed to parse schema path!");
 
     let migrations_include = cfg!(feature = "migrations")
         .then(|| {
-            let migrations_path = find_migrations_path().expect("Migrations folder not found!");
+            let migrations_path = find_migrations_path(&schema_path);
             let migrations_path = migrations_path.to_str().expect("Invalid migrations path");
 
             quote!(
@@ -56,7 +38,7 @@ pub fn generate(args: &GenerateArgs) -> TokenStream {
     quote! {
         #![allow(warnings, unused)]
 
-        pub static DATAMODEL_STR: &'static str = include_str!(#schema_path);
+        pub static DATAMODEL_STR: &'static str = include_str!(#schema_path_str);
         static DATABASE_STR: &'static str = #database_string;
 
         #migrations_include
diff --git a/sdk/src/args.rs b/sdk/src/args.rs
index 20e20e53..fbc96318 100644
--- a/sdk/src/args.rs
+++ b/sdk/src/args.rs
@@ -10,12 +10,11 @@ use dmmf::{DmmfInputField, DmmfInputType, DmmfSchema, TypeLocation};
 use proc_macro2::TokenStream;
 use quote::quote;
 
-use crate::{casing::Casing, dmmf::Datasource, FieldTypeExt};
+use crate::{casing::Casing, dmmf::GeneratorCtx, FieldTypeExt};
 
 pub struct GenerateArgs {
     pub dml: datamodel::dml::Datamodel,
-    pub datamodel_str: String,
-    pub datasources: Vec<Datasource>,
+    pub ctx: GeneratorCtx,
     pub schema: DmmfSchema,
     pub read_filters: Vec<Filter>,
     pub write_filters: Vec<Filter>,
@@ -23,12 +22,7 @@ pub struct GenerateArgs {
 }
 
 impl GenerateArgs {
-    pub fn new(
-        mut dml: datamodel::dml::Datamodel,
-        schema: DmmfSchema,
-        datamodel_str: String,
-        datasources: Vec<Datasource>,
-    ) -> Self {
+    pub fn new(mut dml: datamodel::dml::Datamodel, schema: DmmfSchema, ctx: GeneratorCtx) -> Self {
         let scalars = {
             let mut scalars = Vec::new();
             for scalar in schema.input_object_types.get("prisma").unwrap() {
@@ -262,7 +256,7 @@ impl GenerateArgs {
         };
 
         use builtin_connectors::*;
-        let connector = match &datasources[0].provider {
+        let connector = match &ctx.datasources[0].provider {
             #[cfg(feature = "sqlite")]
             p if SQLITE.is_provider(p) => SQLITE,
             #[cfg(feature = "postgresql")]
@@ -280,8 +274,7 @@ impl GenerateArgs {
 
         Self {
             dml,
-            datamodel_str,
-            datasources,
+            ctx,
             schema,
             read_filters,
             write_filters,
diff --git a/sdk/src/dmmf.rs b/sdk/src/dmmf.rs
index 9d73353c..a1815b16 100644
--- a/sdk/src/dmmf.rs
+++ b/sdk/src/dmmf.rs
@@ -1,12 +1,14 @@
 use serde::{Deserialize, Serialize};
 use serde_json::Map;
 
+/// Provided by Prisma CLI to generators
 #[derive(Debug, Serialize, Deserialize)]
 #[serde(rename_all = "camelCase")]
-pub struct EngineDMMF {
+pub struct GeneratorCtx {
     pub generator: Generator,
     pub schema_path: String,
-    pub datamodel: String,
+    #[serde(rename = "datamodel")]
+    pub datamodel_str: String,
     pub datasources: Vec<Datasource>,
 }
 
diff --git a/sdk/src/runtime.rs b/sdk/src/runtime.rs
index 75577a7e..b42f0c78 100644
--- a/sdk/src/runtime.rs
+++ b/sdk/src/runtime.rs
@@ -9,7 +9,7 @@ use serde_json::{Map, Value};
 
 use crate::{
     args::GenerateArgs,
-    dmmf::EngineDMMF,
+    dmmf::GeneratorCtx,
     jsonrpc, prisma_cli,
     utils::{build_schema, rustfmt, validate_names},
 };
@@ -62,10 +62,10 @@ pub fn run_generator(generator: GeneratorMetadata, args: &Vec<String>) {
 
                 let deserializer = &mut serde_json::Deserializer::from_str(&params_str);
 
-                let dmmf = serde_path_to_error::deserialize(deserializer)
+                let generator_ctx = serde_path_to_error::deserialize(deserializer)
                     .expect("Failed to deserialize DMMF from Prisma engines");
 
-                generate(&generator, dmmf);
+                generate(&generator, generator_ctx);
 
                 serde_json::Value::Null
             }
@@ -94,21 +94,23 @@ pub fn run_generator(generator: GeneratorMetadata, args: &Vec<String>) {
     }
 }
 
-fn generate(generator: &GeneratorMetadata, dmmf: EngineDMMF) {
+fn generate(generator: &GeneratorMetadata, ctx: GeneratorCtx) {
     let (configuration, datamodel) =
-        parse_schema(&dmmf.datamodel).expect("Failed to parse datamodel");
+        parse_schema(&ctx.datamodel_str).expect("Failed to parse datamodel");
     let schema = build_schema(&datamodel, &configuration);
 
-    let output_str = dmmf.generator.output.get_value();
+    let output_str = ctx.generator.output.get_value();
     let output_path = Path::new(&output_str);
 
-    let mut file = create_generated_file(&output_path);
+    let config = ctx.generator.config.clone();
 
-    let args = GenerateArgs::new(datamodel, schema.schema, dmmf.datamodel, dmmf.datasources);
+    let args = GenerateArgs::new(datamodel, schema.schema, ctx);
 
     validate_names(&args);
 
-    let generated_str = (generator.generate_fn)(args, dmmf.generator.config);
+    let generated_str = (generator.generate_fn)(args, config);
+
+    let mut file = create_generated_file(&output_path);
 
     file.write(format!("// Code generated by {}. DO NOT EDIT\n\n", generator.name).as_bytes())
         .expect("Failed to write file header");


Test patch: