From 79bd3d59b468be15be98e7c89a5e5abce6b17ca7 Mon Sep 17 00:00:00 2001 From: Tom Gasson Date: Tue, 21 Jun 2022 15:19:18 +1000 Subject: [PATCH] Compact GraphQL query text output Wires the pre-existing `compact` printing into a feature flag. Additionally disables indenting when printing in compact form --- compiler/Cargo.lock | 22 +++++--- compiler/crates/common/src/feature_flags.rs | 4 ++ .../src/print_full_operation.rs | 18 ++++--- .../graphql-text-printer/src/print_to_text.rs | 53 +++++++++++++++---- .../tests/operation_printer/mod.rs | 6 ++- .../src/build_project/generate_artifacts.rs | 11 +++- .../tests/compile_relay_artifacts/mod.rs | 7 ++- .../mod.rs | 7 ++- .../crates/relay-lsp/src/graphql_tools/mod.rs | 1 + .../src/fragment_alias_directive.rs | 9 ++-- 10 files changed, 103 insertions(+), 35 deletions(-) diff --git a/compiler/Cargo.lock b/compiler/Cargo.lock index ac6fda7fba6bf..0087874494d02 100644 --- a/compiler/Cargo.lock +++ b/compiler/Cargo.lock @@ -175,16 +175,16 @@ dependencies = [ [[package]] name = "clap" -version = "3.1.8" +version = "3.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71c47df61d9e16dc010b55dba1952a57d8c215dbb533fd13cdd13369aac73b1c" +checksum = "d2dbdf4bdacb33466e854ce889eee8dfd5729abf7ccd7664d0a2d60cd384440b" dependencies = [ "atty", "bitflags", "clap_derive", + "clap_lex", "indexmap", "lazy_static", - "os_str_bytes", "regex", "strsim", "termcolor", @@ -195,9 +195,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "3.1.7" +version = "3.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3aab4734e083b809aaf5794e14e756d1c798d2c69c7f7de7a09a2f5214993c1" +checksum = "25320346e922cffe59c0bbc5410c8d8784509efb321488971081313cb1e1a33c" dependencies = [ "heck 0.4.0", "proc-macro-error", @@ -206,6 +206,15 @@ dependencies = [ "syn", ] +[[package]] +name = "clap_lex" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5538cd660450ebeb4234cfecf8f2284b844ffc4c50531e66d584ad5b91293613" +dependencies = [ + "os_str_bytes", +] + [[package]] name = "colored" version = "1.9.3" @@ -1193,9 +1202,6 @@ name = "os_str_bytes" version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" -dependencies = [ - "memchr", -] [[package]] name = "ouroboros" diff --git a/compiler/crates/common/src/feature_flags.rs b/compiler/crates/common/src/feature_flags.rs index d036cf1d2a27a..ce9efef4512db 100644 --- a/compiler/crates/common/src/feature_flags.rs +++ b/compiler/crates/common/src/feature_flags.rs @@ -53,6 +53,10 @@ pub struct FeatureFlags { /// Enable support for the experimental `@alias` directive on fragment spreads. #[serde(default)] pub enable_fragment_aliases: FeatureFlag, + + /// Print queries in compact form + #[serde(default)] + pub compact_query_text: FeatureFlag, } #[derive(Debug, Deserialize, Clone, Serialize)] diff --git a/compiler/crates/graphql-text-printer/src/print_full_operation.rs b/compiler/crates/graphql-text-printer/src/print_full_operation.rs index 90c46ff6d373c..9cf673f5b6e74 100644 --- a/compiler/crates/graphql-text-printer/src/print_full_operation.rs +++ b/compiler/crates/graphql-text-printer/src/print_full_operation.rs @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -use crate::{print_fragment, print_operation}; +use crate::{print_fragment, print_operation, PrinterOptions}; use fnv::FnvHashMap; use graphql_ir::{ FragmentDefinition, FragmentSpread, OperationDefinition, Program, ScalarField, Visitor, @@ -13,8 +13,12 @@ use graphql_ir::{ use intern::string_key::StringKey; use std::sync::Arc; -pub fn print_full_operation(program: &Program, operation: &OperationDefinition) -> String { - let mut printer = OperationPrinter::new(program); +pub fn print_full_operation( + program: &Program, + operation: &OperationDefinition, + options: PrinterOptions, +) -> String { + let mut printer = OperationPrinter::new(program, options); printer.print(operation) } @@ -22,19 +26,21 @@ pub struct OperationPrinter<'s> { fragment_result: FnvHashMap, reachable_fragments: FnvHashMap>, program: &'s Program, + options: PrinterOptions, } impl<'s> OperationPrinter<'s> { - pub fn new(program: &'s Program) -> Self { + pub fn new(program: &'s Program, options: PrinterOptions) -> Self { Self { fragment_result: Default::default(), reachable_fragments: Default::default(), program, + options, } } pub fn print(&mut self, operation: &OperationDefinition) -> String { - let mut result = print_operation(&self.program.schema, operation, Default::default()); + let mut result = print_operation(&self.program.schema, operation, self.options); self.visit_operation(operation); let mut fragments: Vec<(StringKey, Arc)> = self.reachable_fragments.drain().collect(); @@ -51,7 +57,7 @@ impl<'s> OperationPrinter<'s> { let schema = &self.program.schema; self.fragment_result .entry(fragment.name.item) - .or_insert_with(|| print_fragment(schema, fragment, Default::default())) + .or_insert_with(|| print_fragment(schema, fragment, self.options)) } } diff --git a/compiler/crates/graphql-text-printer/src/print_to_text.rs b/compiler/crates/graphql-text-printer/src/print_to_text.rs index fa8cf592ee034..e0bbb0c72ce20 100644 --- a/compiler/crates/graphql-text-printer/src/print_to_text.rs +++ b/compiler/crates/graphql-text-printer/src/print_to_text.rs @@ -224,7 +224,10 @@ impl<'schema, 'writer, W: Write> Printer<'schema, 'writer, W> { fn print_selections(&mut self, selections: &[Selection]) -> FmtResult { let len = selections.len(); if len > 0 { - write!(self.writer, " {{")?; + if !self.options.compact { + write!(self.writer, " ")?; + } + write!(self.writer, "{{")?; self.indentation += 1; self.next_line()?; @@ -372,7 +375,10 @@ impl<'schema, 'writer, W: Write> Printer<'schema, 'writer, W> { } fn print_directive(&mut self, directive: &Directive) -> FmtResult { - write!(self.writer, " @{}", directive.name.item)?; + if !self.options.compact { + write!(self.writer, " ")?; + } + write!(self.writer, "@{}", directive.name.item)?; self.print_arguments(&directive.arguments)?; if self.options.debug_directive_data { @@ -390,9 +396,12 @@ impl<'schema, 'writer, W: Write> Printer<'schema, 'writer, W> { fn print_condition_directives(&mut self, conditions: Vec<&Condition>) -> FmtResult { for condition in conditions { + if !self.options.compact { + write!(self.writer, " ")?; + } write!( self.writer, - " @{}", + "@{}", if condition.passing_value { "include" } else { @@ -401,10 +410,18 @@ impl<'schema, 'writer, W: Write> Printer<'schema, 'writer, W> { )?; match &condition.value { ConditionValue::Constant(value) => { - write!(self.writer, "(if: {})", value)?; + write!(self.writer, "(if:")?; + if !self.options.compact { + write!(self.writer, " ")?; + } + write!(self.writer, "{})", value)?; } ConditionValue::Variable(variable) => { - write!(self.writer, "(if: ${})", variable.name.item)?; + write!(self.writer, "(if:")?; + if !self.options.compact { + write!(self.writer, " ")?; + } + write!(self.writer, "${})", variable.name.item)?; } } } @@ -421,12 +438,21 @@ impl<'schema, 'writer, W: Write> Printer<'schema, 'writer, W> { for var_def in variable_definitions.iter() { self.next_line()?; let type_name = self.schema.get_type_string(&var_def.type_); - write!(self.writer, "${}: {}", var_def.name.item, type_name)?; - + write!(self.writer, "${}:", var_def.name.item)?; + if !self.options.compact { + write!(self.writer, " ")?; + } + write!(self.writer, "{}", type_name)?; match &var_def.default_value { None => {} Some(default_value) => { - write!(self.writer, " = ")?; + if !self.options.compact { + write!(self.writer, " ")?; + } + write!(self.writer, "=")?; + if !self.options.compact { + write!(self.writer, " ")?; + } self.print_constant_value(&default_value.item)?; } } @@ -638,7 +664,10 @@ impl<'schema, 'writer, W: Write> Printer<'schema, 'writer, W> { ) -> FmtResult { if let Some(alias) = alias { if alias.item != name { - write!(self.writer, "{}: ", alias.item)?; + write!(self.writer, "{}:", alias.item)?; + if !self.options.compact { + write!(self.writer, " ")?; + } } } write!(self.writer, "{}", name) @@ -646,8 +675,10 @@ impl<'schema, 'writer, W: Write> Printer<'schema, 'writer, W> { fn next_line(&mut self) -> FmtResult { writeln!(self.writer)?; - for _ in 0..self.indentation { - write!(self.writer, " ")?; + if !self.options.compact { + for _ in 0..self.indentation { + write!(self.writer, " ")?; + } } Ok(()) } diff --git a/compiler/crates/graphql-text-printer/tests/operation_printer/mod.rs b/compiler/crates/graphql-text-printer/tests/operation_printer/mod.rs index 6535c3d7e05de..6c4aec13a0b98 100644 --- a/compiler/crates/graphql-text-printer/tests/operation_printer/mod.rs +++ b/compiler/crates/graphql-text-printer/tests/operation_printer/mod.rs @@ -25,7 +25,11 @@ pub fn transform_fixture(fixture: &Fixture<'_>) -> Result { .into_iter() .filter_map(|definition| { if let ExecutableDefinition::Operation(operation) = definition { - Some(print_full_operation(&program, &operation)) + Some(print_full_operation( + &program, + &operation, + Default::default(), + )) } else { None } diff --git a/compiler/crates/relay-compiler/src/build_project/generate_artifacts.rs b/compiler/crates/relay-compiler/src/build_project/generate_artifacts.rs index 38f365791104e..107f0094dba63 100644 --- a/compiler/crates/relay-compiler/src/build_project/generate_artifacts.rs +++ b/compiler/crates/relay-compiler/src/build_project/generate_artifacts.rs @@ -11,7 +11,7 @@ use crate::config::{Config, ProjectConfig}; use common::{NamedItem, SourceLocationKey}; use fnv::FnvHashMap; use graphql_ir::{FragmentDefinition, OperationDefinition}; -use graphql_text_printer::OperationPrinter; +use graphql_text_printer::{OperationPrinter, PrinterOptions}; use intern::string_key::StringKey; use relay_transforms::{ ClientEdgeGeneratedQueryMetadataDirective, Programs, RefetchableDerivedFromMetadata, @@ -37,7 +37,14 @@ pub fn generate_artifacts( programs: &Programs, source_hashes: Arc, ) -> Vec { - let mut operation_printer = OperationPrinter::new(&programs.operation_text); + let printer_options = PrinterOptions { + compact: project_config + .feature_flags + .compact_query_text + .is_fully_enabled(), + ..Default::default() + }; + let mut operation_printer = OperationPrinter::new(&programs.operation_text, printer_options); return group_operations(programs) .into_iter() .map(|(_, operations)| -> Artifact { diff --git a/compiler/crates/relay-compiler/tests/compile_relay_artifacts/mod.rs b/compiler/crates/relay-compiler/tests/compile_relay_artifacts/mod.rs index b5a330ea46789..bf8cd2d22ce69 100644 --- a/compiler/crates/relay-compiler/tests/compile_relay_artifacts/mod.rs +++ b/compiler/crates/relay-compiler/tests/compile_relay_artifacts/mod.rs @@ -97,6 +97,7 @@ pub fn transform_fixture(fixture: &Fixture<'_>) -> Result { enable_client_edges: FeatureFlag::Enabled, skip_printing_nulls: FeatureFlag::Disabled, enable_fragment_aliases: FeatureFlag::Enabled, + compact_query_text: FeatureFlag::Disabled, }; let default_project_config = ProjectConfig { @@ -191,7 +192,11 @@ pub fn transform_fixture(fixture: &Fixture<'_>) -> Result { let text = print_operation_node.map_or_else( || "Query Text is Empty.".to_string(), |print_operation_node| { - print_full_operation(&programs.operation_text, print_operation_node) + print_full_operation( + &programs.operation_text, + print_operation_node, + Default::default(), + ) }, ); diff --git a/compiler/crates/relay-compiler/tests/compile_relay_artifacts_with_custom_id/mod.rs b/compiler/crates/relay-compiler/tests/compile_relay_artifacts_with_custom_id/mod.rs index 8a64618e15928..38842c9beed11 100644 --- a/compiler/crates/relay-compiler/tests/compile_relay_artifacts_with_custom_id/mod.rs +++ b/compiler/crates/relay-compiler/tests/compile_relay_artifacts_with_custom_id/mod.rs @@ -74,6 +74,7 @@ pub fn transform_fixture(fixture: &Fixture<'_>) -> Result { enable_client_edges: FeatureFlag::Enabled, skip_printing_nulls: FeatureFlag::Disabled, enable_fragment_aliases: FeatureFlag::Enabled, + compact_query_text: FeatureFlag::Disabled, }; let project_config = ProjectConfig { @@ -122,7 +123,11 @@ pub fn transform_fixture(fixture: &Fixture<'_>) -> Result { let text = print_operation_node.map_or_else( || "Query Text is Empty.".to_string(), |print_operation_node| { - print_full_operation(&programs.operation_text, print_operation_node) + print_full_operation( + &programs.operation_text, + print_operation_node, + Default::default(), + ) }, ); diff --git a/compiler/crates/relay-lsp/src/graphql_tools/mod.rs b/compiler/crates/relay-lsp/src/graphql_tools/mod.rs index 72acbb29b28c2..61fe043e37f75 100644 --- a/compiler/crates/relay-lsp/src/graphql_tools/mod.rs +++ b/compiler/crates/relay-lsp/src/graphql_tools/mod.rs @@ -145,6 +145,7 @@ fn print_full_operation_text(programs: Programs, operation_name: StringKey) -> O Some(print_full_operation( &programs.operation_text, print_operation_node, + Default::default(), )) } diff --git a/compiler/crates/relay-transforms/src/fragment_alias_directive.rs b/compiler/crates/relay-transforms/src/fragment_alias_directive.rs index 2cd8dc432dd5f..8b118cfb700bd 100644 --- a/compiler/crates/relay-transforms/src/fragment_alias_directive.rs +++ b/compiler/crates/relay-transforms/src/fragment_alias_directive.rs @@ -131,11 +131,10 @@ impl<'program> FragmentAliasTransform<'program> { FragmentAliasMetadata { alias, type_condition, - selection_type: - type_condition.unwrap_or( - self.parent_type - .expect("Selection should be within a parent type."), - ), + selection_type: type_condition.unwrap_or( + self.parent_type + .expect("Selection should be within a parent type."), + ), } .into(), )