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: stop sorting scripts #206

Merged
merged 6 commits into from
Feb 18, 2021
Merged

fix: stop sorting scripts #206

merged 6 commits into from
Feb 18, 2021

Conversation

jonathanmorley
Copy link
Contributor

The fields option will override the values in the builtin fields array,
allowing users to signify that a given key should not be sorted, or sorted
in a particular way.

The fields option will override the values in the builtin fields array,
allowing users to signify that a given key should not be sorted, or sorted
in a particular way.
@fisker
Copy link
Collaborator

fisker commented Nov 12, 2020

Why not extend sortOrder to ['name', { key: 'repository', over: myOwnSortFunction }]

@jonathanmorley
Copy link
Contributor Author

I started going down that route, but if you just specify something like sortOrder: [{ key: 'scripts', over: myOwnSortFunction }] then I wouldn't want that to cause the scripts object to appear at the top of the object.

This way you can influence sort of keys without affecting the ordering of those keys

@fisker
Copy link
Collaborator

fisker commented Nov 12, 2020

How about defaultSortOrder.map(key => key === "script" ? { key, over: myOwnSortFunction } : key)

@jonathanmorley
Copy link
Contributor Author

While that would work, it seems more confusing to me. What is the reasoning behind preferring re-using the sortOrder option rather than introducing a new option?

@jonathanmorley
Copy link
Contributor Author

what would be needed to move this forward?

@jonathanmorley
Copy link
Contributor Author

@keithamus ?

@keithamus
Copy link
Owner

Could you please demonstrate a concrete use case for needing this?

@jonathanmorley
Copy link
Contributor Author

Sure.

We use npm-run-all to run multiple scripts sequentially, based on their ordering within the scripts block.

An example of this would be

{
  "scripts": {
    "build:ts": "tsc",
    "build:cdk": "cdk synth",
    "build": "run-s build:*"
  }
}

Reordering the scripts block based on lexical ordering would functionally change the build script, in a breaking way.

@keithamus
Copy link
Owner

@jonathanmorley I would prefer to keep sort-package-json configuration free. So if that is the only use case you're solving, we can:

  1. Simply not sort scripts. This is my preferred option.
  2. Detect npm-run-all in devdeps and conditionally not sort. I'm willing to entertain this idea with more exploration.

@fisker
Copy link
Collaborator

fisker commented Jan 20, 2021

Detect npm-run-all in devdeps and conditionally not sort.

👍

Additional we can also check scripts content has run-s and npm-run-all command. run-p should not effected.

@jonathanmorley
Copy link
Contributor Author

npm-run-all has a third command (npm-run-all) which also has the ability to run commands sequentially.

Rather than add in checks for npm-run-all or run-s, I opted for the approach 2 in #206 (comment)

@fisker
Copy link
Collaborator

fisker commented Jan 22, 2021

What if npm-run-all is installed global. And I mean do both.

@nelson6e65
Copy link

Why not just an option to (dis)allow ordering scripts, regardless of the reason, instead of check for a specific tool? What if I use another tool like npm-run-all but is called different? I need to create another patch for each specific tool that requires specific order on scripts?

@jonathanmorley
Copy link
Contributor Author

jonathanmorley commented Jan 22, 2021

that was the original intent. The fields option would allow a consumer to choose to disabling sorting, or choose a custom sort method for a provided field(s). #206 (comment) mentions about wanting to keep sort-package-json config free though, which I can understand, especially as we consume this library through another package, which also has low configuration

@keithamus
Copy link
Owner

Yeah we can just unilaterally disable sorting of scripts. In my experience these tend to be more taken care of than the rest of the package.json, and the important part of this package is really to sort the main fields so you can predictably head the file to see stuff like name and main

@jonathanmorley jonathanmorley changed the title feat: add option for custom sorting fields fix: stop sorting scripts Jan 27, 2021
@matzkoh
Copy link

matzkoh commented Jan 28, 2021

I use npm-run-all and prefer to sort the scripts.
For example, it makes sense for prefoo foo postfoo to be sorted in that order.
https://docs.npmjs.com/cli/v6/using-npm/scripts#pre--post-scripts

It would be a shame to stop sorting scripts just because some tools depend on the key order of the objects.
(Rather than "the tools depend on it", the users depend on the behavior that happens to work well?)

It is an object, not an array.

@keithamus
Copy link
Owner

We could just sort pre and post scripts, as we know them to have consistent behaviour with and without npm-run-all.

@nelson6e65
Copy link

We could just sort pre and post scripts, as we know them to have consistent behaviour with and without npm-run-all.

I agree with having pre/post scripts sorted it is useful.

@keithamus
Copy link
Owner

I'm finding this diff really difficult to read now. Why does it change a bunch of seemingly unrelated lines? Do you have auto formatting on?

}
return name
})
.sort()
Copy link
Owner

Choose a reason for hiding this comment

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

Seems like this is the only LOC that should be in this diff now, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I believe this is prettier moving the .map up a line since it no longer has a .sort to align with

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@keithamus does this sufficiently explain the diff?

Copy link
Owner

Choose a reason for hiding this comment

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

Why has the index.d.ts changed so much? Is it just that the copy in the main branch is old?

@keithamus keithamus merged commit 9b76ec1 into keithamus:master Feb 18, 2021
@github-actions
Copy link

🎉 This PR is included in version 1.49.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@G-Rath
Copy link
Contributor

G-Rath commented Mar 2, 2021

I'm a bit sad that this was merged, especially as a bug: having scripts sorted consistently across projects as a default is one of the things I love(d) about sort-package-json.

Would it be possible to revisit this to see if we could come up with a middleground for everyone?

@joemaller
Copy link

joemaller commented Mar 10, 2021

I agree with @G-Rath, this change was an unwelcome surprise. We've been using sort-package-json to standardize our package.json files for several years. We use a lot of scripts and keeping those in order was a huge help. After a recent round of updates, I thought something broke when the scripts weren't sorted back into the expected lexical+pre/post order.

I see sort-package-json as a linting tool, and much as I've given formatting over to tools like Prettier, I'm fine with whatever opinionated choices the tool's maintainers decide to make. But removing script sorting is a major loss of functionality which I'll be looking to replace. For now, running npx sort-package-json@1.48 was a sigh of relief.

@benquarmby
Copy link

benquarmby commented Mar 15, 2021

I agree with @G-Rath, this change was an unwelcome surprise.

I'd go so far as to call it a breaking change. We will use ~1.48.0 as an escape hatch for now.

Edit: This edge case really wasn't very hard to solve and costs very little:

{
  "scripts": {
    "build": "run-s build:ts build:cdk",
    "build:cdk": "cdk synth",
    "build:ts": "tsc"
  }
}

@DUBANGARCIA
Copy link

I agree with @G-Rath, this change was an unwelcome surprise. We've been using sort-package-json to standardize our package.json files for several years. We use a lot of scripts and keeping those in order was a huge help. After a recent round of updates, I thought something broke when the scripts weren't sorted back into the expected lexical+pre/post order.

I see sort-package-json as a linting tool, and much as I've given formatting over to tools like Prettier, I'm fine with whatever opinionated choices the tool's maintainers decide to make. But removing script sorting is a major loss of functionality which I'll be looking to replace. For now, running npx sort-package-json@1.48 was a sigh of relief.

Totally agree, the ordering of scripts was very important for my projects to avoid unnecessary merges with git and improve the readability of the package.json, please reconsider this change.

@Maxim-Mazurok
Copy link

I just want to let you know that it also was a surprise that our scripts are not being sorted and I just noticed this... Guess it is me to blame because I didn't pin this package version and was just using the latest.

But yeah, I agree with the guys above that this was a pretty important feature for me, prettier/linter for pacakge.json, in a way. And I'm sad to see this functionality gone. Will pin to 1.48 for now.

@keithamus
Copy link
Owner

This edge case really wasn't very hard to solve and costs very little

Please do submit a PR if you think this is solvable in a deterministic and non-configurable way that addresses the concerns of folks like @jonathanmorley.

@benquarmby
Copy link

@keithamus : The deterministic way was covered in the code example. To be clear, here it is again:

- "build": "run-s build:*",
+ "build": "run-s build:ts build:cdk",

Being explicit about the order and avoiding the magical * is as deterministic as it gets. I say this as someone who makes heavy use of npm-run-all.

I'll be blunt: sort-package-json should never have been watered down to cater for dynamic usage of npm-run-all. It was a breaking change for my projects.

@keithamus
Copy link
Owner

keithamus commented Sep 24, 2021

@G-Rath has submitted a PR which sorts scripts unless npm-run-all is installed. It is released under 1.52.0

@nelson6e65
Copy link

Hmm... What if I have installed and still want to sort them? Examples above shows that.

@Maxim-Mazurok
Copy link

Maxim-Mazurok commented Sep 24, 2021

Hmm... What if I have installed and still want to sort them? Examples above shows that.

I guess you have two choices:

  1. Install it as a regular (non-dev) dependency. Should be fine for non-library projects. (in Script not sorting in 1.49.0 #220 they check that npm-run-all is a dev dependency)
  2. Uninstall it and use through npx

@keithamus
Copy link
Owner

If you would like to improve the heuristic - if you think you could find a deterministic way to sort scripts without effecting existing implicit npm-run-all script orders, then PRs are welcome! For example we could check the contents of scripts to determine if they're using run-s with a wildcard.

@fisker
Copy link
Collaborator

fisker commented Sep 26, 2021

Don't forget npm-run-all foo:* -s, npm-run-all --sequential foo*, npm-run-all --serial foo*, and other cases.

@kachkaev
Copy link
Contributor

Not sure if this is relevant, but npm-run-all has been unmaintained since October 2019. I tried bumping dependencies to get rid of known vulnerabilities, but my PR did not get any attention so far.

We might need to implement a rule that is flexible, i.e. not hard-wired to npm-run-all.

@saiichihashimoto
Copy link

saiichihashimoto commented Dec 16, 2021

Went through a "bisect" of sort-package-json versions until I ended up here to determine this was not a bug, but a conscious decision. This is definitely a breaking change and magic sorting (or lack of sorting?) because a dependency is included is unpredictable behavior. I use npm-run-all extensively and the lack of sorting is painful.

Users of sort-package-json should assume that the json will be resorted (excluding arrays); relying on ordering of object keys is not a bug within sort-package-json, but relying on an unreliability. sort-package-json or npm-run-all should not consider this an issue, considering npm-run-all gives escape hatches for this. If there's a manual order you need scripts to be run, then manually run them in that order. run-s * and run-p * should be agnostic to the order they're run.

Will be pinning to 1.48.1. Regardless of whether the maintainer agrees with the suggested changes, breaking changes like this should definitely be a major version bump, since users reasonably assume a minor version bump wouldn't disable default behavior arbitrarily.

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

Successfully merging this pull request may close these issues.

None yet