diff --git a/Cargo.lock b/Cargo.lock index eb5d9b5..af70b77 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1444,6 +1444,18 @@ dependencies = [ "syn", ] +[[package]] +name = "regex" +version = "1.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + [[package]] name = "regex-automata" version = "0.4.7" @@ -1550,6 +1562,7 @@ dependencies = [ "futures", "hashlink 0.8.4", "phf", + "regex", "reqwest", "serde_json", "sqlx", diff --git a/Cargo.toml b/Cargo.toml index 2f88eeb..199ca68 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ stringcase = "0.3.0" tokio = { version = "1.40.0", features = ["full"] } yaml-rust2 = "0.8.1" serde_json = "1.0" +regex = "1" [[bin]] edition = "2021" diff --git a/spago_workspace_config.yaml b/spago_workspace_config.yaml index 15ffdc6..5ecb6c2 100644 --- a/spago_workspace_config.yaml +++ b/spago_workspace_config.yaml @@ -7,3 +7,6 @@ schema_libs_dir: ../OxfordAbstracts/application/purs-projects/lib/generated-new/ variant_enums: - QuestionTypesEnum - ReviewerRecruitmentQuestionTypesEnum +skip_types: + - ".*_aggregate$" + - ".*_aggregate_fields$" diff --git a/src/build_schema.rs b/src/build_schema.rs index 0c07ec1..c9f32d3 100644 --- a/src/build_schema.rs +++ b/src/build_schema.rs @@ -13,7 +13,7 @@ use stringcase::{kebab_case, pascal_case}; use tokio::task::spawn_blocking; use crate::{ - config::{parse_outside_types::OutsideTypes, workspace::WorkspaceConfig}, + config::{parse_outside_types::OutsideTypes, workspace::{SkipRule, WorkspaceConfig}}, enums::generate_enum::generate_enum, hasura_types::as_gql_field, purescript_gen::{ @@ -136,6 +136,10 @@ pub async fn build_schema( continue; } + if should_skip(&obj.name, &workspace_config.skip_types) { + continue; + } + // Convert the hasura_type_name to a PurescriptTypeName let name = pascal_case(&obj.name); @@ -144,12 +148,21 @@ pub async fn build_schema( // Add type fields to the record for field in obj.fields.iter() { + if should_skip(&field.ty.name, &workspace_config.skip_types) { + continue; + } + if should_skip(&field.name, &workspace_config.skip_keys) { + continue; + } // If the field has arguments then the purescript representation will be: // field_name :: { | Arguments } -> ReturnType // Build the arguments record: let mut args = PurescriptRecord::new("Arguments"); for arg in &field.args { + if should_skip(&arg.ty.name, &workspace_config.skip_types) { + continue; + } let arg_type = wrap_type( as_gql_field( &field.name, @@ -235,12 +248,22 @@ pub async fn build_schema( continue; } + if should_skip(&obj.name, &workspace_config.skip_types) { + continue; + } + // Convert the hasura_type_name to a PurescriptTypeName let name = pascal_case(&obj.name); // Build a purescript record with all fields let mut record = PurescriptRecord::new("Query"); for field in obj.fields.iter() { + if should_skip(&field.ty.name, &workspace_config.skip_types) { + continue; + } + if should_skip(&field.name, &workspace_config.skip_keys) { + continue; + } // Work out the type of the field, wrapping in NotNull or Array as required. // This will also resolve any outside types. let arg_type = wrap_type( @@ -506,6 +529,16 @@ import Type.Proxy (Proxy(..)) "#; +fn should_skip(name: &str, rules: &[SkipRule]) -> bool { + let mut skip = false; + for rule in rules { + if rule.pattern.is_match(name) { + skip = !rule.negated; + } + } + skip +} + const GIT_IGNORE: &str = r#" bower_components/ node_modules/ diff --git a/src/config/workspace.rs b/src/config/workspace.rs index 346d3b0..93e7afc 100644 --- a/src/config/workspace.rs +++ b/src/config/workspace.rs @@ -1,10 +1,35 @@ use std::thread::Result; use hashlink::LinkedHashMap; +use regex::Regex; use tokio::fs::File; use tokio::io::AsyncReadExt; use yaml_rust2::{yaml, Yaml}; +#[derive(Clone)] +pub struct SkipRule { + pub pattern: Regex, + pub negated: bool, +} + +impl SkipRule { + pub fn parse(s: &str) -> Self { + if let Some(pattern) = s.strip_prefix('!') { + Self { + pattern: Regex::new(pattern) + .expect(&format!("Invalid regex in skip rule: {pattern}")), + negated: true, + } + } else { + Self { + pattern: Regex::new(s) + .expect(&format!("Invalid regex in skip rule: {s}")), + negated: false, + } + } + } +} + pub async fn parse_workspace() -> Result { let file_path: String = std::env::var("SPAGO_WORKSPACE_CONFIG_YAML") .expect("SPAGO_WORKSPACE_CONFIG_YAML must be set"); @@ -39,6 +64,8 @@ pub struct WorkspaceConfig { pub schema_libs_prefix: String, pub schema_libs_dir: String, pub variant_enums: Vec, + pub skip_types: Vec, + pub skip_keys: Vec, } impl WorkspaceConfig { @@ -52,6 +79,8 @@ impl WorkspaceConfig { let schema_libs_prefix = yaml_hash.get(&Yaml::String("schema_libs_prefix".to_string()))?; let schema_libs_dir = yaml_hash.get(&Yaml::String("schema_libs_dir".to_string()))?; let variant_enums = yaml_hash.get(&Yaml::String("variant_enums".to_string())); + let skip_types = yaml_hash.get(&Yaml::String("skip_types".to_string())); + let skip_keys = yaml_hash.get(&Yaml::String("skip_keys".to_string())); Some(Self { postgres_enums_lib: postgres_enums_lib .as_str() @@ -88,6 +117,30 @@ impl WorkspaceConfig { .to_string() }) .collect(), + skip_types: skip_types + .unwrap_or(&Yaml::Array(vec![])) + .as_vec() + .unwrap_or(&vec![]) + .iter() + .map(|v| { + SkipRule::parse( + v.as_str() + .expect("Workspace yaml skip_types should all be strings"), + ) + }) + .collect(), + skip_keys: skip_keys + .unwrap_or(&Yaml::Array(vec![])) + .as_vec() + .unwrap_or(&vec![]) + .iter() + .map(|v| { + SkipRule::parse( + v.as_str() + .expect("Workspace yaml skip_keys should all be strings"), + ) + }) + .collect(), }) } }