From 036cc8cffaefe2d1f156e6f8fc0ec08af4ecb27c Mon Sep 17 00:00:00 2001 From: seastian Date: Thu, 19 Feb 2026 17:14:06 +0100 Subject: [PATCH 1/5] skip types --- Cargo.lock | 13 +++++++++++++ Cargo.toml | 1 + spago_workspace_config.yaml | 3 +++ src/build_schema.rs | 12 ++++++++++++ src/config/workspace.rs | 16 ++++++++++++++++ 5 files changed, 45 insertions(+) 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..af5b496 100644 --- a/src/build_schema.rs +++ b/src/build_schema.rs @@ -9,6 +9,7 @@ use cynic_introspection::{ Directive, DirectiveLocation, FieldWrapping, InterfaceType, IntrospectionQuery, Type, UnionType, WrappingType, }; +use regex::Regex; use stringcase::{kebab_case, pascal_case}; use tokio::task::spawn_blocking; @@ -136,6 +137,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,6 +149,9 @@ 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 the field has arguments then the purescript representation will be: // field_name :: { | Arguments } -> ReturnType @@ -506,6 +514,10 @@ import Type.Proxy (Proxy(..)) "#; +fn should_skip(name: &str, skip_types: &[Regex]) -> bool { + skip_types.iter().any(|re| re.is_match(name)) +} + const GIT_IGNORE: &str = r#" bower_components/ node_modules/ diff --git a/src/config/workspace.rs b/src/config/workspace.rs index 346d3b0..3a6e25a 100644 --- a/src/config/workspace.rs +++ b/src/config/workspace.rs @@ -1,6 +1,7 @@ use std::thread::Result; use hashlink::LinkedHashMap; +use regex::Regex; use tokio::fs::File; use tokio::io::AsyncReadExt; use yaml_rust2::{yaml, Yaml}; @@ -39,6 +40,7 @@ pub struct WorkspaceConfig { pub schema_libs_prefix: String, pub schema_libs_dir: String, pub variant_enums: Vec, + pub skip_types: Vec, } impl WorkspaceConfig { @@ -52,6 +54,7 @@ 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())); Some(Self { postgres_enums_lib: postgres_enums_lib .as_str() @@ -88,6 +91,19 @@ impl WorkspaceConfig { .to_string() }) .collect(), + skip_types: skip_types + .unwrap_or(&Yaml::Array(vec![])) + .as_vec() + .unwrap_or(&vec![]) + .iter() + .map(|v| { + let pattern = v + .as_str() + .expect("Workspace yaml skip_types should all be strings"); + Regex::new(pattern) + .expect(&format!("Invalid regex in skip_types: {pattern}")) + }) + .collect(), }) } } From 0367827fb34f44c5af3a4aa9ddefe37c10638ee8 Mon Sep 17 00:00:00 2001 From: seastian Date: Thu, 19 Feb 2026 17:48:17 +0100 Subject: [PATCH 2/5] more --- src/build_schema.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/build_schema.rs b/src/build_schema.rs index af5b496..c158c64 100644 --- a/src/build_schema.rs +++ b/src/build_schema.rs @@ -243,12 +243,19 @@ 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; + } // 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( From 45b468148383531c80ea3604da8b9d511f110ef4 Mon Sep 17 00:00:00 2001 From: seastian Date: Thu, 19 Feb 2026 18:13:07 +0100 Subject: [PATCH 3/5] skip keys --- src/build_schema.rs | 10 ++++++++-- src/config/workspace.rs | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/build_schema.rs b/src/build_schema.rs index c158c64..3d56f74 100644 --- a/src/build_schema.rs +++ b/src/build_schema.rs @@ -152,6 +152,9 @@ pub async fn build_schema( 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 @@ -256,6 +259,9 @@ pub async fn build_schema( 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( @@ -521,8 +527,8 @@ import Type.Proxy (Proxy(..)) "#; -fn should_skip(name: &str, skip_types: &[Regex]) -> bool { - skip_types.iter().any(|re| re.is_match(name)) +fn should_skip(name: &str, skip: &[Regex]) -> bool { + skip.iter().any(|re| re.is_match(name)) } const GIT_IGNORE: &str = r#" diff --git a/src/config/workspace.rs b/src/config/workspace.rs index 3a6e25a..b98a70f 100644 --- a/src/config/workspace.rs +++ b/src/config/workspace.rs @@ -41,6 +41,7 @@ pub struct WorkspaceConfig { pub schema_libs_dir: String, pub variant_enums: Vec, pub skip_types: Vec, + pub skip_keys: Vec, } impl WorkspaceConfig { @@ -55,6 +56,7 @@ impl WorkspaceConfig { 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() @@ -104,6 +106,19 @@ impl WorkspaceConfig { .expect(&format!("Invalid regex in skip_types: {pattern}")) }) .collect(), + skip_keys: skip_keys + .unwrap_or(&Yaml::Array(vec![])) + .as_vec() + .unwrap_or(&vec![]) + .iter() + .map(|v| { + let pattern = v + .as_str() + .expect("Workspace yaml skip_keys should all be strings"); + Regex::new(pattern) + .expect(&format!("Invalid regex in skip_keys: {pattern}")) + }) + .collect(), }) } } From a46552753fdc0eca780fde5b2c78e457362a35bb Mon Sep 17 00:00:00 2001 From: seastian Date: Thu, 19 Feb 2026 21:38:01 +0100 Subject: [PATCH 4/5] negate --- src/build_schema.rs | 13 ++++++++---- src/config/workspace.rs | 46 ++++++++++++++++++++++++++++++----------- 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/build_schema.rs b/src/build_schema.rs index 3d56f74..56f0938 100644 --- a/src/build_schema.rs +++ b/src/build_schema.rs @@ -9,12 +9,11 @@ use cynic_introspection::{ Directive, DirectiveLocation, FieldWrapping, InterfaceType, IntrospectionQuery, Type, UnionType, WrappingType, }; -use regex::Regex; 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::{ @@ -527,8 +526,14 @@ import Type.Proxy (Proxy(..)) "#; -fn should_skip(name: &str, skip: &[Regex]) -> bool { - skip.iter().any(|re| re.is_match(name)) +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#" diff --git a/src/config/workspace.rs b/src/config/workspace.rs index b98a70f..93e7afc 100644 --- a/src/config/workspace.rs +++ b/src/config/workspace.rs @@ -6,6 +6,30 @@ 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"); @@ -40,8 +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, + pub skip_types: Vec, + pub skip_keys: Vec, } impl WorkspaceConfig { @@ -99,11 +123,10 @@ impl WorkspaceConfig { .unwrap_or(&vec![]) .iter() .map(|v| { - let pattern = v - .as_str() - .expect("Workspace yaml skip_types should all be strings"); - Regex::new(pattern) - .expect(&format!("Invalid regex in skip_types: {pattern}")) + SkipRule::parse( + v.as_str() + .expect("Workspace yaml skip_types should all be strings"), + ) }) .collect(), skip_keys: skip_keys @@ -112,11 +135,10 @@ impl WorkspaceConfig { .unwrap_or(&vec![]) .iter() .map(|v| { - let pattern = v - .as_str() - .expect("Workspace yaml skip_keys should all be strings"); - Regex::new(pattern) - .expect(&format!("Invalid regex in skip_keys: {pattern}")) + SkipRule::parse( + v.as_str() + .expect("Workspace yaml skip_keys should all be strings"), + ) }) .collect(), }) From 0e87d8d2eea3a13fcd46226e0b092ec8eff3d5d9 Mon Sep 17 00:00:00 2001 From: seastian Date: Thu, 19 Feb 2026 22:54:46 +0100 Subject: [PATCH 5/5] skip args --- src/build_schema.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/build_schema.rs b/src/build_schema.rs index 56f0938..c9f32d3 100644 --- a/src/build_schema.rs +++ b/src/build_schema.rs @@ -160,6 +160,9 @@ pub async fn build_schema( // 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,