Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lexographically sorted printSchema for comparison/diff stability? #941

Closed
benjie opened this issue Jul 6, 2017 · 4 comments
Closed

Lexographically sorted printSchema for comparison/diff stability? #941

benjie opened this issue Jul 6, 2017 · 4 comments

Comments

@benjie
Copy link
Member

benjie commented Jul 6, 2017

printSchema already sorts the type names alphabetically:

.sort((name1, name2) => name1.localeCompare(name2))

It would also be useful for diffing if fields, arguments, enum values and various other entities were also sorted alphabetically. I have performed some local modifications and it seems the changes required are quite minor. However, I believe it's possibly the case that a schema sorted in one way is not identical to a schema sorted in another because the order of fields/arguments may affect the order in which they are resolved?

I therefore have the following questions:

  1. Would ordering the printSchema alphabetically by default be an acceptable change?
  2. If not, would it be acceptable to add a second argument added to printSchema that supports an enumeration of sort modes (e.g. 'natural' for the current ordering, 'alphabetic', and even something more exotic like ordering by heirarchy as in Add printFineSchema() for printing hierarchy ordered types. #281)?
  3. Would you accept a pull request to add these changes?

Keywords (to help others find this issue, also detailing what I searched for before): alphabetic, lexographic, lexical, order, sort, printSchema, print, stable

@benjie
Copy link
Member Author

benjie commented Jul 6, 2017

It seems this has already been attempted in #889 and since reverted in #920 because the relation s = parse(print(s)) didn't hold.

@benjie
Copy link
Member Author

benjie commented Jul 7, 2017

For anyone who needs this functionality for whatever reason; here's an ugly hack to tide you over, currently it sorts fields, args and enums via duck-typing:

const { parse, buildASTSchema } = require("graphql");
const { printSchema } = require("graphql/utilities");

const printSchemaOrdered = originalSchema => {
  // Clone schema so we don't damage anything
  const schema = buildASTSchema(parse(printSchema(originalSchema)));

  const typeMap = schema.getTypeMap();
  Object.keys(typeMap).forEach(name => {
    const Type = typeMap[name];

    // Object?
    if (Type.getFields) {
      const fields = Type.getFields();
      const keys = Object.keys(fields).sort();
      keys.forEach(key => {
        const value = fields[key];

        // Move the key to the end of the object
        delete fields[key];
        fields[key] = value;

        // Sort args
        if (value.args) {
          value.args.sort((a, b) => a.name.localeCompare(b.name));
        }
      });
    }

    // Enum?
    if (Type.getValues) {
      Type.getValues().sort((a, b) => a.name.localeCompare(b.name));
    }
  });

  return printSchema(schema);
};

@leebyron
Copy link
Contributor

leebyron commented Dec 7, 2017

The order of fields and arguments is often meaningful. I don't think such a feature should be part of printSchema, however a lexographicSortSchema function would be useful which returns a new Schema instance - that would be far more flexible and allow for printing the sorted schema or doing anything else you can do with a schema.

Feel free to send a PR if you're still interested, though I'm closing this issue for repo maintenance.

@leebyron leebyron closed this as completed Dec 7, 2017
@IvanGoncharov
Copy link
Member

@leebyron I'm already working on utility function to sort the result of introspection query.
I will try to submit PR in a next few days.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants