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

[Fix] Revert breaking group change in order #2854

Merged
merged 1 commit into from Aug 18, 2023

Conversation

yndajas
Copy link
Contributor

@yndajas yndajas commented Aug 9, 2023

1fa2971 changed the way groups work when there is only one, leading to single nested groups being treated as though they were unnested. Prior to this, if you wanted to group e.g. builtin and external imports together at the top and everything else together as a second group, a single nested group was the way to do it

It appears that this change was unintentional, and was made to try to fix what seems to be a misunderstanding around nested groups ([#2687]). The docs continue to suggest that nested groups should be "mingled together" and makes no reference to a single nested group with no other groups being an invalid option

This therefore reverts the change to how groups work when there is only one. No documentation change should be necessary given this is already the described behaviour

Surfaced in ministryofjustice/hmpps-accredited-programmes-ui#129
Closes #2687

1fa2971 changed the way groups work when there is only one, leading
to single nested groups being treated as though they were unnested.
Prior to this, if you wanted to group e.g. builtin and external
imports together at the top and everything else together as a second
group, a single nested group was the way to do it

[It appears that this change was unintentional][1], and was made to
try to fix what seems to be a misunderstanding around nested groups
([import-js#2687]). [The docs][2] continue to suggest that nested groups
should be "mingled together" and makes no reference to a single nested
group with no other groups being an invalid option

This therefore reverts the change to how groups work when there is
only one. No documentation change should be necessary given this is
already the described behaviour

[1]: import-js#2687 (comment)
[2]: https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/order.md#groups-array
@ljharb
Copy link
Member

ljharb commented Aug 9, 2023

To be clear, I think order should matter in nested groups, but that would be a breaking change, so this PR is the right approach.

tests/src/rules/order.js Show resolved Hide resolved
@yndajas yndajas force-pushed the revert-order-breaking-change branch from 10d479d to 52bdb88 Compare August 9, 2023 11:48
@yndajas
Copy link
Contributor Author

yndajas commented Aug 11, 2023

@ljharb any idea why this fails in one (or more) environments? Is this a common issue unrelated to this PR?

@ljharb
Copy link
Member

ljharb commented Aug 17, 2023

@yndajas the windows failures are expected; the node failure was a fluke, and I've rerun it.

@ljharb ljharb force-pushed the revert-order-breaking-change branch from 52bdb88 to 0847443 Compare August 17, 2023 06:13
@ljharb
Copy link
Member

ljharb commented Aug 17, 2023

I'll land this once we get more travis-ci credits.

@ljharb ljharb closed this Aug 18, 2023
@ljharb ljharb reopened this Aug 18, 2023
@ljharb ljharb closed this Aug 18, 2023
@ljharb ljharb reopened this Aug 18, 2023
@ljharb ljharb merged commit 0847443 into import-js:main Aug 18, 2023
486 of 487 checks passed
@jraoult
Copy link

jraoult commented Aug 27, 2023

I've been holding of any upgrade since 2.26.0. After that release, the change in ordering algorithm introduced a regression. My understanding was that this PR was intended to reverse the sorting behaviour to got back to the one in 2.26.0. If it was the intention, I can report this is still not right then.

The following configuration:

"import/order": [
      "error",
      {
        alphabetize: {
          order: "asc",
          caseInsensitive: true,
        },
        groups: [
          ["external", "builtin"],
          ["parent", "sibling"],
        ],
        "newlines-between": "always",
      },
    ],

pre 2.27 was passing for:

import {parent} from "../a.js";
import {sibling} from "./a.js";

but from 2.27 (including 2.28.1) only accepts:

import {sibling} from "./a.js";
import {parent} from "../a.js";

I understand that the nested group order is "unspecified" in the doc but it is still a change of behaviour from 2.26. So should I update my code to match the new order or is it still a regression waiting for a fix?

@yndajas
Copy link
Contributor Author

yndajas commented Aug 27, 2023

@jraoult are you expecting the former based on ../ coming before ./? In my experience ./ gets sorted before ../, so the latter example would be what I'd expect when parent and sibling imports are intermingled by being in the same nested group

@jraoult
Copy link

jraoult commented Aug 27, 2023

@jraoult are you expecting the former based on ../ coming before ./? In my experience ./ gets sorted before ../, so the latter example would be what I'd expect when parent and sibling imports are intermingled by being in the same nested group

@yndajas I'd expect the nested group to follow the order of the array. So if the nested group conf is ["parent", "sibling"] I'd expect ../ before ./ but I know this is not how it is documented right now (cf. #2854 (comment)) or supposed to work and out of the scope of this PR.

So at minima, I'd expect the order to not change in a minor version. Meaning that 2.28 should order import the same way as 2.26 for the same given configuration. It seemed to be the aim of this PR to revert to the behaviour of 2.26 but from my tests failed to do so.

So my real question is: should I consider this new way of sorting the nested groups a feature, in which case I'll update my code base to match it, or a bug in which case I'll wait until it is fixed.

@yndajas
Copy link
Contributor Author

yndajas commented Aug 27, 2023

@jraoult so in 2.26 (before the breaking change in 2.28.0) the order in nested groups was meaningful? In my (limited) experience with this package the order within nested groups didn't matter (per the docs) until 2.28.0, in which it mattered only when there was just one nested group*, but I'm quite late to the game here

* the way I got around this in 2.28.0 was by adding another nested group to make it not matter again

This is probably one for @ljharb in any case!

@jraoult
Copy link

jraoult commented Aug 27, 2023

@yndajas I don't have any particular opinion on the order TBH. I just expect the import order to stay the same from minor version to minor version so my CI doesn't break. If it is decided that this new way of ordering is stable and the way forward I'm happy to do a one off run on the codebase and call it a day but my gut feeling is that it should have been a major version then 🤷‍♂️

@ljharb
Copy link
Member

ljharb commented Aug 27, 2023

Indeed it's a breaking change if the semantics of nested or unnested groups changed within v2.

It sounds like there's still a bit of regression left; i'd like anything that passed in v2.26 to pass in v2.28 (with the same options, of course). @yndajas got another PR in you? :-D

@yndajas
Copy link
Contributor Author

yndajas commented Aug 27, 2023

Indeed it's a breaking change if the semantics of nested or unnested groups changed within v2.

It sounds like there's still a bit of regression left; i'd like anything that passed in v2.26 to pass in v2.28 (with the same options, of course). @yndajas got another PR in you? :-D

Happy to work on a fix if one is needed, but I'm still a little unclear on what the difference between 2.26 and 2.28.1 is for this rule 🤔 I haven't tested 2.28.1 on one of my own codebases, but pre-2.28.0 I'd have expected ./ to sort before ../ within the same group if sorting alphabetically

Based on release dates I've probably only used 2.27.5 (started on the project that's using this package in April), so I might be missing some context here! This PR was likely focused on fixing a regression specific to 2.28.0 (versus 2.27.5, bringing it back in line with the docs)

I can take a look next week to see if 2.28.1 is working as I'd expect in the project I'm currently on


Re: within-group ordering, can you not de-nest the group? If order within nested groups matters, what's the use of nested groups? Surely the whole purpose of nesting is to identify a group of the same rank?

E.g. if you want type C imports before type D imports, instead of:

[
  [A, B],
  [C, D]
]

could you not just write this?

[
  [A, B],
  C,
  D
]

yndajas added a commit to ministryofjustice/hmpps-accredited-programmes-ui that referenced this pull request Aug 31, 2023
2.28.0 introduced a breaking change where the order of nested groups
(whose purpose is to define different types of imports that are of
equivalent rank) started to matter: a single nested group would be
treated as though it wasn't nested

We got around this by adding a second nested group with most if not all
of the other import types we use

I [fixed the bug][1] in eslint-plugin-import 💅🏻 and this was released in
2.28.1, so we can now revert to the simpler config post-upgrade

[1]: import-js/eslint-plugin-import#2854
yndajas added a commit to ministryofjustice/hmpps-accredited-programmes-ui that referenced this pull request Aug 31, 2023
2.28.0 introduced a breaking change where the order of nested groups
(whose purpose is to define different types of imports that are of
equivalent rank) started to matter: a single nested group would be
treated as though it wasn't nested

We [got around this][1] by adding a second nested group with most if
not all of the other import types we use

I [fixed the bug][2] in eslint-plugin-import 💅🏻 and this was released in
2.28.1, so we can now revert to the simpler config post-upgrade

[1]: ab5a73e
[2]: import-js/eslint-plugin-import#2854
yndajas added a commit to ministryofjustice/hmpps-accredited-programmes-ui that referenced this pull request Aug 31, 2023
2.28.0 introduced a breaking change to `import/order` where the order
of nested groups (whose purpose is to define different types of imports
that are of equivalent rank) started to matter: a single nested group
would be treated as though it wasn't nested

We [got around this][1] by adding a second nested group with most if
not all of the other import types we use

I [fixed the bug][2] in eslint-plugin-import 💅🏻 and this was released in
2.28.1, so we can now revert to the simpler config post-upgrade

[1]: ab5a73e
[2]: import-js/eslint-plugin-import#2854
yndajas added a commit to ministryofjustice/hmpps-accredited-programmes-ui that referenced this pull request Aug 31, 2023
2.28.0 introduced a breaking change to `import/order` where the order
of nested groups (whose purpose is to define different types of imports
that are of equivalent rank) started to matter: a single nested group
would be treated as though it wasn't nested

We [got around this][1] by adding a second nested group with most if
not all of the other import types we use

I [fixed the bug][2] in eslint-plugin-import 💅🏻 and this was released in
2.28.1, so we can now revert to the simpler config post-upgrade

[1]: ab5a73e
[2]: import-js/eslint-plugin-import#2854
yndajas added a commit to ministryofjustice/hmpps-accredited-programmes-ui that referenced this pull request Aug 31, 2023
2.28.0 introduced a breaking change to `import/order` where the order
of nested groups (whose purpose is to define different types of imports
that are of equivalent rank) started to matter: a single nested group
would be treated as though it wasn't nested

We [got around this][1] by adding a second nested group with most if
not all of the other import types we use

It looks like #141
brought us back to 2.27.5. If we go back to 2.28.0 now and revert to
the simpler config, for some reason the ESLint errors don't reappear

In any case, I submitted a [bug fix][2] in eslint-plugin-import 💅
This was released in 2.28.1, so we should upgrade, hopefully preventing
an unexpected return to confusing errors

[1]: ab5a73e
[2]: import-js/eslint-plugin-import#2854
@yndajas
Copy link
Contributor Author

yndajas commented Aug 31, 2023

My findings on this in the project I'm working on are a little inconclusive: we seem to have dropped back to 2.27.5 through a recent Renovate PR, and updating to 2.28.0 again and reverting to a single nested group no longer appears to be problematic. In any case, everything is (also) fine after upgrading to 2.28.1 with a single nested group, so hopefully it's fixed (if it even was broken - I'm more confused now than ever 🤷🏻‍♀️)

More detail here: ministryofjustice/hmpps-accredited-programmes-ui@47bf31b

@jraoult
Copy link

jraoult commented Oct 26, 2023

FYI @ljharb @yndajas, the regression is still here in my case in the freshly released 2.29.0, so I'm staying in 2.26.0 for now but not too sure about the path forward.

@yndajas yndajas deleted the revert-order-breaking-change branch October 26, 2023 16:41
@ljharb
Copy link
Member

ljharb commented Oct 26, 2023

@jraoult can you file a new issue allowing me to repro the problem? Staying on v2.26 is definitely not a viable option long term.

@yndajas
Copy link
Contributor Author

yndajas commented Oct 26, 2023

@jraoult does this definitely not work for you?

groups: [
  "external",
  "builtin",
  "parent",
  "sibling",
],

@jraoult
Copy link

jraoult commented Oct 26, 2023

@ljharb @yndajas so my configuration is:

 "import/order": [
      "error",
      {
        alphabetize: {
          order: "asc",
          caseInsensitive: true,
        },
        groups: [
          ["external", "builtin"],
          ["parent", "sibling"],
        ],
        "newlines-between": "always",
      },
    ],

and typically, this used to pass in 2.26:

import { isNotNull } from "option-t/esm/Nullable";

import { combineNullables } from "../util/combineNullables.js";
import type { BigFraction } from "./BigFraction.js";
import { FRACTION_ZERO } from "./fraction.js";

but fails after 2.26 with message: ../util/combineNullables.js import should occur after import of ./fraction.js

@yndajas
Copy link
Contributor Author

yndajas commented Oct 26, 2023

@jraoult Yeah that's expected behaviour based on the docs (if I understand them correctly), since the path comes later under alphabetical sorting and you've got parent and sibling imports at the same rank by nesting them

I'm not sure sure why it worked the other way in 2.26.0. As I've suggested above, denesting should allow you to require parent imports to come before sibling imports, which should be a single config change and not require any other changes throughout your codebase, all being well!

As @ljharb said, it's probably best to open a separate issue if that doesn't solve the problem

@jraoult
Copy link

jraoult commented Oct 26, 2023

@ljharb issue filled here: #2909

@jraoult
Copy link

jraoult commented Oct 26, 2023

denesting should allow you to require parent imports to come before sibling imports

@yndajas, but then I can not leverage newlines-between the same way.

@yndajas
Copy link
Contributor Author

yndajas commented Oct 26, 2023

@yndajas, but then I can not leverage newlines-between the same way.

Ahh I see what you mean. Might be good to add that to the issue, because that clarifies things a lot

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

Successfully merging this pull request may close these issues.

import/order not respecting builtin
3 participants