-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: natural-order as an optional rule
- Loading branch information
1 parent
a84ebe6
commit 2f1d1a5
Showing
9 changed files
with
200 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
{ | ||
"strict": true | ||
} | ||
"strict": true, | ||
"rules": { | ||
"alphabetic-order": false, | ||
"natural-order": true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,21 @@ | ||
import defaultRules from "./rules"; | ||
import { Rule } from "./types"; | ||
|
||
export const optionalRules = ["natural-order"]; | ||
|
||
const strict = defaultRules | ||
.map((r: Rule) => r.name) | ||
.filter((r) => !optionalRules.includes(r)); | ||
|
||
const ruleSets = { | ||
default: [ | ||
"mandatory-test", | ||
"mandatory-start", | ||
"mandatory-dev", | ||
"no-default-test", | ||
], | ||
strict: defaultRules.map((r: Rule) => r.name), | ||
strict, | ||
optionalRules, | ||
}; | ||
|
||
export default ruleSets; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import { PackageScripts } from "../types"; | ||
import { objectFromEntries } from "../utils"; | ||
|
||
type EntryInfo = { | ||
order: number; | ||
namespace: string; | ||
entry: [string, string]; | ||
}; | ||
|
||
const prepareEntryInfo = (entry: [string, string]) => { | ||
const name = entry[0]; | ||
const namespace = name.split(":")[0]; | ||
|
||
if (name.startsWith("pre")) { | ||
return { | ||
order: 0, | ||
namespace: namespace.substr(3), | ||
entry, | ||
}; | ||
} | ||
if (name.startsWith("post")) { | ||
return { | ||
order: 2, | ||
namespace: namespace.substr(4), | ||
entry, | ||
}; | ||
} | ||
|
||
return { | ||
order: 1, | ||
namespace, | ||
entry, | ||
}; | ||
}; | ||
|
||
export const sortScripts = (scripts: PackageScripts): PackageScripts => { | ||
// prepare namespace and order info | ||
const entries = Object.entries(scripts).map(prepareEntryInfo); | ||
|
||
return objectFromEntries( | ||
entries | ||
// make unique namespace groups | ||
.map((e: EntryInfo) => e.namespace) | ||
.filter( | ||
(name: string, i: number, a: Array<string>) => | ||
a.indexOf(name) === i | ||
) | ||
.sort() | ||
.map((name: string) => | ||
entries.filter((e: EntryInfo) => e.namespace === name) | ||
) | ||
// sort inside the group | ||
.map((group: Array<EntryInfo>) => | ||
// sort `1-title` vs `2-title` etc. | ||
group.sort((a: EntryInfo, b: EntryInfo) => | ||
`${a.order}-${a.entry[0]}`.localeCompare( | ||
`${b.order}-${b.entry[0]}` | ||
) | ||
) | ||
) | ||
// flatten array | ||
.reduce( | ||
(flatted: Array<EntryInfo>, group: Array<EntryInfo>) => [ | ||
...flatted, | ||
...group, | ||
], | ||
[] | ||
) | ||
// reduce to entries again | ||
.map((f: EntryInfo) => f.entry) | ||
); | ||
}; | ||
|
||
export default { | ||
name: "natural-order", | ||
isObjectRule: true, | ||
message: "scripts must be in 'natural' order", | ||
validate: (scripts: PackageScripts) => { | ||
const sorted = sortScripts(scripts); | ||
|
||
return Object.keys(sorted).join("|") === Object.keys(scripts).join("|"); | ||
}, | ||
fix: (scripts: PackageScripts) => sortScripts(scripts), | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import rule, { sortScripts } from "../../src/rules/natural-order"; | ||
|
||
describe("natural-order.ts", () => { | ||
const scriptsUnsorted = { | ||
postbuild: "foo", | ||
"test:lint": "baz", | ||
"build:cleanup": "bar", | ||
"update:typings": "something", | ||
test: "jest", | ||
posttest: "baz", | ||
pretest: "baz", | ||
update: "foo", | ||
"update:dependencies": "updtr", | ||
prebuild: "foo", | ||
build: "foo", | ||
publish: "ok", | ||
prepublishOnly: "else", | ||
}; | ||
|
||
const scriptsSorted = { | ||
prebuild: "foo", | ||
build: "foo", | ||
"build:cleanup": "bar", | ||
postbuild: "foo", | ||
publish: "ok", | ||
prepublishOnly: "else", | ||
pretest: "baz", | ||
test: "jest", | ||
"test:lint": "baz", | ||
posttest: "baz", | ||
update: "foo", | ||
"update:dependencies": "updtr", | ||
"update:typings": "something", | ||
}; | ||
|
||
describe("validate()", () => { | ||
it("should validate correctly", () => { | ||
expect(rule.validate({})).toBe(true); | ||
expect(rule.validate(scriptsUnsorted)).toBe(false); | ||
expect(rule.validate(scriptsSorted)).toBe(true); | ||
}); | ||
}); | ||
|
||
it("should fix issues", () => { | ||
expect(rule.validate(rule.fix(scriptsUnsorted))).toBe(true); | ||
}); | ||
|
||
describe("sortScripts()", () => { | ||
it("should sort correctly", () => { | ||
expect(sortScripts({})).toEqual({}); | ||
expect(Object.keys(sortScripts(scriptsUnsorted))).toEqual( | ||
Object.keys(scriptsSorted) | ||
); | ||
}); | ||
}); | ||
}); |