diff options
author | isaacs <i@izs.me> | 2021-05-07 02:06:29 +0300 |
---|---|---|
committer | Gar <gar+gh@danger.computer> | 2021-05-10 19:37:12 +0300 |
commit | 1d092144eaaabff63ac8424b40b2286822be7677 (patch) | |
tree | cfc63a6d91736f3165fcc4d38431ff3a2819b660 /lib | |
parent | 1eb7e5c7d466293b472c2506c64e5a89ec84ac2f (diff) |
fix(packages): locale-agnostic string sorting
This adds the 'en' locale to all instances of String.localeCompare
within the CLI codebase.
Tests added for the cases where we're sorting arbitrary user-generated
data. The tests rely on the fact that 'ch' sorts after 'd' in the
`'sk'` locale, but ahead of `'d'` in the `'en'` locale. To ensure that
this is the default behavior if no locale is specified, `LC_ALL=sk` is
set in the test environment.
Other instances of `localeCompare` sort data that the cli controls, so
no tests were added.
Re: https://github.com/npm/cli/issues/2829
PR-URL: https://github.com/npm/cli/pull/3203
Credit: @isaacs
Close: #3203
Reviewed-by: @ruyadorno
Diffstat (limited to 'lib')
-rw-r--r-- | lib/config.js | 4 | ||||
-rw-r--r-- | lib/help.js | 2 | ||||
-rw-r--r-- | lib/ls.js | 2 | ||||
-rw-r--r-- | lib/outdated.js | 2 | ||||
-rw-r--r-- | lib/utils/completion/installed-deep.js | 2 | ||||
-rw-r--r-- | lib/utils/config/describe-all.js | 2 | ||||
-rw-r--r-- | lib/utils/npm-usage.js | 2 | ||||
-rw-r--r-- | lib/utils/tar.js | 4 |
8 files changed, 10 insertions, 10 deletions
diff --git a/lib/config.js b/lib/config.js index f53d7e5ae..4b3ac5873 100644 --- a/lib/config.js +++ b/lib/config.js @@ -199,7 +199,7 @@ class Config extends BaseCommand { ; Configs like \`//<hostname>/:_authToken\` are auth that is restricted ; to the registry host specified. -${data.split('\n').sort((a, b) => a.localeCompare(b)).join('\n').trim()} +${data.split('\n').sort((a, b) => a.localeCompare(b, 'en')).join('\n').trim()} ;;;; ; all available options shown below with default values @@ -227,7 +227,7 @@ ${defData} if (where === 'default' && !long) continue - const keys = Object.keys(data).sort((a, b) => a.localeCompare(b)) + const keys = Object.keys(data).sort((a, b) => a.localeCompare(b, 'en')) if (!keys.length) continue diff --git a/lib/help.js b/lib/help.js index 589819eb0..e9aade521 100644 --- a/lib/help.js +++ b/lib/help.js @@ -77,7 +77,7 @@ class Help extends BaseCommand { if (aManNumber !== bManNumber) return aManNumber - bManNumber - return a.localeCompare(b) + return a.localeCompare(b, 'en') }) const man = mans[0] @@ -443,7 +443,7 @@ const augmentNodesWithMetadata = ({ } const sortAlphabetically = (a, b) => - a.pkgid.localeCompare(b.pkgid) + a.pkgid.localeCompare(b.pkgid, 'en') const humanOutput = ({ color, result, seenItems, unicode }) => { // we need to traverse the entire tree in order to determine which items diff --git a/lib/outdated.js b/lib/outdated.js index 9b656d2ae..13567f358 100644 --- a/lib/outdated.js +++ b/lib/outdated.js @@ -68,7 +68,7 @@ class Outdated extends BaseCommand { })) // sorts list alphabetically - const outdated = this.list.sort((a, b) => a.name.localeCompare(b.name)) + const outdated = this.list.sort((a, b) => a.name.localeCompare(b.name, 'en')) // return if no outdated packages if (outdated.length === 0 && !this.npm.config.get('json')) diff --git a/lib/utils/completion/installed-deep.js b/lib/utils/completion/installed-deep.js index b65c17e41..243068861 100644 --- a/lib/utils/completion/installed-deep.js +++ b/lib/utils/completion/installed-deep.js @@ -16,7 +16,7 @@ const installedDeep = async (npm) => { }) .filter(i => (i.depth - 1) <= depth) .sort((a, b) => a.depth - b.depth) - .sort((a, b) => a.depth === b.depth ? a.name.localeCompare(b.name) : 0) + .sort((a, b) => a.depth === b.depth ? a.name.localeCompare(b.name, 'en') : 0) const res = new Set() const gArb = new Arborist({ global: true, path: resolve(npm.globalDir, '..') }) diff --git a/lib/utils/config/describe-all.js b/lib/utils/config/describe-all.js index ab3f3a63e..5fb785f08 100644 --- a/lib/utils/config/describe-all.js +++ b/lib/utils/config/describe-all.js @@ -7,7 +7,7 @@ const describeAll = () => { const sort = ([keya, {deprecated: depa}], [keyb, {deprecated: depb}]) => { return depa && !depb ? 1 : !depa && depb ? -1 - : keya.localeCompare(keyb) + : keya.localeCompare(keyb, 'en') } return Object.entries(definitions).sort(sort) .map(([key, def]) => def.describe()) diff --git a/lib/utils/npm-usage.js b/lib/utils/npm-usage.js index bc397cb4d..ddb0bab0b 100644 --- a/lib/utils/npm-usage.js +++ b/lib/utils/npm-usage.js @@ -62,7 +62,7 @@ const usages = (npm) => { maxLen = Math.max(maxLen, c.length) return set }, []) - .sort((a, b) => a[0].localeCompare(b[0])) + .sort((a, b) => a[0].localeCompare(b[0], 'en')) .map(([c, usage]) => `\n ${c}${' '.repeat(maxLen - c.length + 1)}${ (usage.split('\n').join('\n' + ' '.repeat(maxLen + 5)))}`) .join('\n') diff --git a/lib/utils/tar.js b/lib/utils/tar.js index 887c40a0f..9e7c33295 100644 --- a/lib/utils/tar.js +++ b/lib/utils/tar.js @@ -76,7 +76,7 @@ const getContents = async (manifest, tarball) => { }) const comparator = (a, b) => { - return a.path.localeCompare(b.path, undefined, { + return a.path.localeCompare(b.path, 'en', { sensitivity: 'case', numeric: true, }) @@ -84,7 +84,7 @@ const getContents = async (manifest, tarball) => { const isUpper = (str) => { const ch = str.charAt(0) - return ch >= 'A' && ch <= 'Z' + return ch === ch.toUpperCase() } const uppers = files.filter(file => isUpper(file.path)) |