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 + '_ {