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

Alphabetize imports within groups #1360

Merged
merged 1 commit into from Dec 7, 2019
Merged

Alphabetize imports within groups #1360

merged 1 commit into from Dec 7, 2019

Conversation

stropho
Copy link
Contributor

@stropho stropho commented May 14, 2019

I'm not the real author of these commits. I just rebased the existing #1105 . I'm looking forward to use this new feature.

Closes #1105. Fixes #1406.

…n groups

Fixes #1406. Fixes #389. Closes #629. Closes #1105. Closes #1360.

Co-Authored-By: dannysindra <als478@cornell.edu>
Co-Authored-By: Radim Svoboda <radim.svoboda@socialbakers.com>
Co-Authored-By: Soma Lucz <luczsoma@gmail.com>
Co-Authored-By: Randall Reed, Jr <randallreedjr@gmail.com>
Co-Authored-By: Jordan Harband <ljharb@gmail.com>
@coveralls
Copy link

Coverage Status

Coverage decreased (-0.1%) to 97.82% when pulling 86f6b42 on stropho:alphabetize into 2f85fbe on benmosher:master.

@coveralls
Copy link

coveralls commented May 14, 2019

Coverage Status

Coverage decreased (-0.1%) to 96.338% when pulling aae9da7 on stropho:alphabetize into f12ae59 on benmosher:master.

@stropho
Copy link
Contributor Author

stropho commented May 14, 2019

Can anybody help? Is there any way to test incorrect configuration passed to the eslint rule? It seems like such errors are handled already by the RuleTester and not the rule itself, so I don't see i simple way to test it at the moment.

Or should we just delete the checks to make coveralls happy ?

@ljharb
Copy link
Member

ljharb commented May 15, 2019

Please don’t open duplicate PRs; now i have to maintain both in sync, open, until both are merged together.

Instead, post a link to your commits on the original PR, and a maintainer will update it.

@stropho
Copy link
Contributor Author

stropho commented May 15, 2019

ok, got it

@stropho stropho closed this May 15, 2019
@ljharb ljharb reopened this May 15, 2019
@VincentLanglet
Copy link

Is this ready to merge ? This feature will be great.

@stropho
Copy link
Contributor Author

stropho commented Jun 3, 2019

I believe it is ready. I created a fix based on the suggestion in #1105 . And now, probably some of the maintainers have to say "it's ok" and merge it.

@syashenkov
Copy link

syashenkov commented Jun 5, 2019

I think example still needs correction:

import assert from 'assert';
import buffer from 'buffer';
import foo from 'foo';
import bar from 'bar';
import Baz from 'Baz';

It's unclear if imports should be sorted by module name or imported symbols. Also, it's uncertain what behaviour is expected using star imports (import * as) and symbol imports (import { A, B })

It would be best to make example with some real life imports like

import * as classnames from 'classnames';
import PropTypes from 'prop-types';
import React, { PureComponent } from 'react';
import { compose } from 'recompose';

@syashenkov
Copy link

Or a more clear example like

Pass:

import c from 'a';
import b from 'b';
import a from 'c';

Fail:

import a from 'c';
import b from 'b';
import c from 'a';

@syashenkov
Copy link

@ljharb Could you please look at this PR?

@stropho
Copy link
Contributor Author

stropho commented Jul 9, 2019

Fixed the example.
Rebased on master branch.
Hope everybody is happy now.

Travis CI failed but it has the same errors as master branch did https://travis-ci.org/benmosher/eslint-plugin-import/builds/553254212 . So I don't think there is anything I can do about it right now.

@deb0ch
Copy link

deb0ch commented Aug 6, 2019

The tests don't seem to be failing on master anymore, is this mergeable soon before there are conflicts ?

@stropho
Copy link
Contributor Author

stropho commented Aug 6, 2019

@deb0ch should be mergable; thanks for the reminder, just rebased 🍾 🎉 🍾 🎉

@luczsoma
Copy link
Contributor

@ljharb Could you look into merging this PR?

It is a long-wanted feature, and also would come with a few benefits, since it:

Thank you.

groupedByRanks[groupRank].sort(function(importA, importB) {
return ignoreCase
? importA.localeCompare(importB)
: (importA < importB ? -1 : (importA === importB ? 0 : 1))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scary. Could it be replaced with if... return?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw it is also incorrect I think. The default sensitvity option is variant in localeCompare for the default sorting usage (applies in the above snippet), which does not ignore casing.

I don't want to meddle in this PR, but I suggest the following:

groupedByRanks[groupRank].sort(function(importA, importB) {
  return importA.localeCompare(importB, undefined, { sensitivity: ignoreCase ? 'accent' : 'case' })
})

@luczsoma
Copy link
Contributor

@stropho, since I have no write access to this, in order to get this PR finally merged before any further conflicts emerge, I would like to ask you to

  • either commit the following two minor changes, please,
  • or invite me as a contributor into stropho/eslint-plugin-import-1 so I am able to commit them.
  1. In src/rules/order.js, change this:
groupedByRanks[groupRank].sort(function(importA, importB) {
  return ignoreCase
    ? importA.localeCompare(importB)
    : (importA < importB ? -1 : (importA === importB ? 0 : 1))
})

to this:

groupedByRanks[groupRank].sort(function(importA, importB) {
  return importA.localeCompare(importB, undefined, { 
    sensitivity: ignoreCase ? 'accent' : 'case' 
  })
})
  1. Add the following to CHANGELOG.md, into the Unreleased section:
- [`order`]: Add support for alphabetical sorting within import groups ([#1360], thanks [@duncanbeevers] & [@stropho])

Thank you!

@stropho
Copy link
Contributor Author

stropho commented Aug 26, 2019

@luczsoma I haven't really investigated the code much, just wanted to help to merge it.... anyway, I just tried to fix it myself since you've told me exactly what to do :-D About 4 tests fail now. That is ok but it seems to be nearly impossible for me to find which tests are failing.
I added you as collaborator... Feel free to add changes. I could find some spare time at the end of the week.

@luczsoma
Copy link
Contributor

Thank you @stropho!

As I tried to extend the functionality with configurable numeric sorting (1 < 2 < 10 vs 1 < 10 < 2) and configurable casing options (a-z < A-Z vs a-z > A-Z), I found out that localeCompare doesn't really work as common sense expects, see https://stackoverflow.com/questions/57671159. For the sake of simplicity, I removed localeCompare.

I also fixed @syabro's concerns.

@luczsoma
Copy link
Contributor

I think this should be mergeable now.

@syabro
Copy link

syabro commented Aug 27, 2019

As I tried to extend the functionality with configurable numeric sorting (1 < 2 < 10 vs 1 < 10 < 2) and configurable casing options (a-z < A-Z vs a-z > A-Z)

I bet it could be done later :) We badly need a basic sort

@luczsoma
Copy link
Contributor

As I tried to extend the functionality with configurable numeric sorting (1 < 2 < 10 vs 1 < 10 < 2) and configurable casing options (a-z < A-Z vs a-z > A-Z)

I bet it could be done later :) We badly need a basic sort

Planning to do it some time later. :)

@stropho
Copy link
Contributor Author

stropho commented Aug 28, 2019

thx @luczsoma - I'm not a fan of rewriting code to make it bigger but as long as it is more readable and everybody's happy about it.. why not...

What got my attention though is that the ignoreCase probably does not work as it was intended.
My understanding when ignoreCase=true: it doesn't matter if a is before or after A
My understanding of how it works now: sorting treats a that it equals A but the tested code needs to be equal to the result of sorting :-/
So I changed the tests a bit to actually test the ignoreCase option and had to comment 2 of them because it seems they are not fixable with the current implementation. So what now ?

  1. easier choice - remove ignoreCase option. Why would anyone create files with capital or non-ascii letters ? I understand that this is strongly opinionated. But if anyone will ever want such feature, it could be added later. As mentioned before:

We badly need a basic sort

  1. fix the ignoreCase case. This does not quite fit my schedule. But maybe someone else can try ?

Let's vote!!!
👍 for option 1.
🚀 for option 2.

@stropho
Copy link
Contributor Author

stropho commented Aug 28, 2019

alright, ignoreCase option is removed. Less options --> smaller chance something is not working 😉

@stropho
Copy link
Contributor Author

stropho commented Sep 13, 2019

@ljharb any news? any suggestions to get it merged ?

@aunnk
Copy link

aunnk commented Sep 19, 2019

any updates on this? really want it to be merged.

src/rules/order.js Outdated Show resolved Hide resolved
src/rules/order.js Outdated Show resolved Hide resolved
src/rules/order.js Show resolved Hide resolved
@@ -335,10 +335,10 @@ ruleTester.run('order', rule, {
// Option newlines-between: 'always' with multiline imports #3
test({
code: `
import foo
import a
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why does this need to be changed? can this test be reverted?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the intention of this commit (which is not my own) was to show how the alphabetical sorting in a clearer way, with minimal examples. I would not revert that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If your comment is concerned about only this particular test case (which tests multiline, not ordering), I will revert that part to its original state.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, my comment is because for it not to be a breaking change, no existing test cases should be altered.

@ljharb
Copy link
Member

ljharb commented Sep 19, 2019

(additionally, please rebase this on latest master)

@luczsoma
Copy link
Contributor

Requested changes are done, rebased onto master.

@luczsoma
Copy link
Contributor

@ljharb Is there anything else we can do to get this merged? I cannot dismiss the change request (although everything requested is done), only you (or the author of this PR, @stropho) can.

@stropho stropho requested a review from ljharb September 24, 2019 09:03
@nmorel
Copy link

nmorel commented Oct 14, 2019

I tried the PR and it breaks the newlines-between rules.
With always, I have an empty line between all my imports and not just groups.
From what I see, newlines-between uses rank to determine empty lines to add and alphabetize modifies the ranks to order.

@nmorel
Copy link

nmorel commented Oct 14, 2019

Putting the newlines test first seems to fix it :

if (newlinesBetweenImports !== 'ignore') {
  makeNewlinesBetweenReport(context, imported, newlinesBetweenImports)
}

if (alphabetize.order !== 'ignore') {
  mutateRanksToAlphabetize(imported, alphabetize.order)
}

makeOutOfOrderReport(context, imported)

@cameronmurphy

This comment has been minimized.

@kondei

This comment has been minimized.

@iippis

This comment has been minimized.

Copy link
Member

@ljharb ljharb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of the autofixer, if this ends up breaking side effecty modules by sorting anything across bindingless imports (which should never themselves be sorted), then the autofix for this entire rule will be promptly disabled in a patch.

Please do feel motivated to quickly open a followup PR with test cases that cover those cases if you're interested in ensuring this rule remains autofixable.

@ljharb ljharb closed this in 8224e51 Dec 7, 2019
@ljharb ljharb merged commit 8224e51 into import-js:master Dec 7, 2019
marcusdarmstrong pushed a commit to marcusdarmstrong/eslint-plugin-import that referenced this pull request Dec 9, 2019
…n groups

Fixes import-js#1406. Fixes import-js#389. Closes import-js#629. Closes import-js#1105. Closes import-js#1360.

Co-Authored-By: dannysindra <als478@cornell.edu>
Co-Authored-By: Radim Svoboda <radim.svoboda@socialbakers.com>
Co-Authored-By: Soma Lucz <luczsoma@gmail.com>
Co-Authored-By: Randall Reed, Jr <randallreedjr@gmail.com>
Co-Authored-By: Jordan Harband <ljharb@gmail.com>
RoyalDevGit added a commit to RoyalDevGit/TakeNote that referenced this pull request Jul 9, 2022
Manually alphabetize import groups and lines pending the merging of
import-js/eslint-plugin-import#1360, using WebStorm's Optimize imports
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.

An alphabetical order rule?