From b708e80f1d67586e32cbb3ea835fbfdffdecd238 Mon Sep 17 00:00:00 2001 From: Dave Rolsky Date: Sat, 2 Apr 2022 15:18:36 -0500 Subject: [PATCH] Always sort scalar types by name when returning them Previously these were returned in an essentially random order. This would lead to flapping in the generated code when running the client CLI against the same schema multiple times. In the application I'm writing, I check in the generated schema, so this sort of flapping in the generated code creates unwanted noise in the commit history. --- CHANGELOG.md | 3 +++ graphql_client_codegen/src/query.rs | 21 ++++++++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a1ed1f7..c6db1ec5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. `rustls` rather than `native-tls`. - Code generated by the `graphql-client` CLI program now suppresses all warnings from rustc and clippy. +- The generated code now sorts enums, inputs, and scalar types by name. This + fixes "flapping" in the generated code that used to happen types could be + randomly ordered each time the generator ran. ## 0.10.0 - 2021-07-04 diff --git a/graphql_client_codegen/src/query.rs b/graphql_client_codegen/src/query.rs index d8ff35bb..b585cce1 100644 --- a/graphql_client_codegen/src/query.rs +++ b/graphql_client_codegen/src/query.rs @@ -587,34 +587,49 @@ pub(crate) struct UsedTypes { } impl UsedTypes { + // We sort the returned inputs and other types in order to ensure that the + // generated code is the same every time when given the schema. Without + // sorting the order is random, and code generated with the CLI tool may + // change even when the source schema does not change. pub(crate) fn inputs<'s, 'a: 's>( &'s self, schema: &'a Schema, ) -> impl Iterator + 's { - schema + let mut inputs = schema .inputs() .filter(move |(id, _input)| self.types.contains(&TypeId::Input(*id))) + .collect::>(); + inputs.sort_by_key(|(_id, input)| input.name.as_str()); + inputs.into_iter() } pub(crate) fn scalars<'s, 'a: 's>( &'s self, schema: &'a Schema, ) -> impl Iterator + 's { - self.types + let mut scalars = self + .types .iter() .filter_map(TypeId::as_scalar_id) .map(move |scalar_id| (scalar_id, schema.get_scalar(scalar_id))) .filter(|(_id, scalar)| !crate::schema::DEFAULT_SCALARS.contains(&scalar.name.as_str())) + .collect::>(); + scalars.sort_by_key(|(_id, scalar)| scalar.name.as_str()); + scalars.into_iter() } pub(crate) fn enums<'a, 'schema: 'a>( &'a self, schema: &'schema Schema, ) -> impl Iterator + 'a { - self.types + let mut enums = self + .types .iter() .filter_map(TypeId::as_enum_id) .map(move |enum_id| (enum_id, schema.get_enum(enum_id))) + .collect::>(); + enums.sort_by_key(|(_id, enum_)| enum_.name.as_str()); + enums.into_iter() } pub(crate) fn fragment_ids(&self) -> impl Iterator + '_ {