Skip to content

Commit 60ee94f

Browse files
lukekarrysjumoel
andcommitted
feat: add prettier support
Co-authored-by: Julian Møller Ellehauge <[email protected]>
1 parent 8aef509 commit 60ee94f

File tree

17 files changed

+253
-112
lines changed

17 files changed

+253
-112
lines changed

.gitignore

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22

33
# ignore everything in the root
44
/*
5-
# transient test directories
6-
tap-testdir*/
75

8-
# keep these
96
!**/.gitignore
107
!/.commitlintrc.js
118
!/.eslintrc.js
129
!/.eslintrc.local.*
10+
!/.git-blame-ignore-revs
1311
!/.github/
1412
!/.gitignore
1513
!/.npmrc
14+
!/.prettierignore
15+
!/.prettierrc.js
1616
!/.release-please-manifest.json
1717
!/bin/
1818
!/CHANGELOG*
@@ -30,6 +30,7 @@ tap-testdir*/
3030
!/tap-snapshots/
3131
!/test/
3232
!/tsconfig.json
33+
tap-testdir*/
3334
!/workspace/
3435
/workspace/*
3536
!/workspace/test-workspace/

lib/config.js

Lines changed: 77 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,16 @@ const DEFAULT_CONTENT = require.resolve(NAME)
1919
const getPkgConfig = (pkg) => pkg[CONFIG_KEY] || {}
2020

2121
const merge = mergeWithCustomizers(
22-
customizers.mergeArrays('branches', 'distPaths', 'allowPaths', 'ignorePaths'),
22+
customizers.mergeArrays(
23+
'branches',
24+
'distPaths',
25+
'allowPaths',
26+
'ignorePaths',
27+
'lintIgnorePaths',
28+
'lintExtensions',
29+
'formatIgnorePaths',
30+
'formatExtensions'
31+
),
2332
(value, srcValue, key) => {
2433
if (key === 'ciVersions' && (Array.isArray(srcValue) || isPlainObject(srcValue))) {
2534
return { ...ciVersions.parse(value), ...ciVersions.parse(srcValue) }
@@ -196,17 +205,42 @@ const getFullConfig = async ({
196205
pkgConfig.requiredPackages.devDependencies.filter(p => !p.includes('eslint'))
197206
}
198207

208+
pkgConfig.lintIgnorePaths = [
209+
...(pkgConfig.ignorePaths || []),
210+
...(pkgConfig.lintIgnorePaths || []),
211+
...derived.workspaceGlobs,
212+
]
213+
214+
pkgConfig.formatIgnorePaths = [
215+
...(pkgConfig.ignorePaths || []),
216+
...(pkgConfig.formatIgnorePaths || []),
217+
...derived.workspaceGlobs,
218+
]
219+
199220
if (pkgConfig.typescript) {
200221
defaultsDeep(pkgConfig, { allowPaths: [], requiredPackages: { devDependencies: [] } })
201222
pkgConfig.distPaths = ['dist/']
223+
pkgConfig.lintIgnorePaths = uniq([...pkgConfig.lintIgnorePaths, 'dist/'])
224+
pkgConfig.formatIgnorePaths = uniq([...pkgConfig.formatIgnorePaths, 'dist/'])
202225
pkgConfig.allowDistPaths = false
203-
pkgConfig.allowPaths.push('/src/')
204-
pkgConfig.requiredPackages.devDependencies.push(
226+
pkgConfig.allowPaths = uniq([...pkgConfig.allowPaths, '/src/'])
227+
pkgConfig.requiredPackages.devDependencies = uniq([
228+
...pkgConfig.requiredPackages.devDependencies,
205229
'typescript',
206230
'tshy',
207231
'@typescript-eslint/parser',
208-
...derived.tap16 ? ['c8', 'ts-node'] : []
209-
)
232+
...derived.tap16 ? ['c8', 'ts-node'] : [],
233+
])
234+
}
235+
236+
if (pkgConfig.prettier) {
237+
defaultsDeep(pkgConfig, { requiredPackages: { devDependencies: [] } })
238+
pkgConfig.requiredPackages.devDependencies = uniq([
239+
...pkgConfig.requiredPackages.devDependencies,
240+
'prettier',
241+
'eslint-config-prettier',
242+
'@github/prettier-config',
243+
])
210244
}
211245

212246
const gitUrl = await git.getUrl(rootPkg.path)
@@ -238,24 +272,47 @@ const getFullConfig = async ({
238272
applyRepo: !!repoFiles,
239273
applyModule: !!moduleFiles,
240274
__PARTIAL_DIRS__: fileDirs,
275+
})
276+
277+
const ignoreAddedPaths = gitignore.sort([
278+
...gitignore.allowRootDir([
279+
// Allways allow module files in root or workspaces
280+
...getAddedFiles(moduleFiles).map(s => template(s, fullConfig)),
281+
...(isRoot
282+
? [
283+
// in the root allow all repo files
284+
...getAddedFiles(repoFiles).map(s => template(s, fullConfig)),
285+
// and allow all workspace repo level files in the root
286+
...pkgs
287+
.filter(p => p.path !== rootPkg.path && p.config.workspaceRepo !== false)
288+
.flatMap(() => getAddedFiles(files.workspaceRepo)),
289+
]
290+
: []),
291+
]),
292+
...(isRoot && pkgConfig.lockfile ? ['!/package-lock.json'] : []),
293+
])
294+
295+
Object.assign(fullConfig, {
296+
// Make sure we don't format any files that are being generated since they will cause template-oss-check to fail
297+
// This could be changed if those files were also formatted before save but then we would need to read generated
298+
// the prettier config first and use that as the formatting rules which would get weird
299+
formatIgnorePaths: [
300+
...fullConfig.formatIgnorePaths,
301+
...ignoreAddedPaths
302+
.filter(f => f.startsWith('!'))
303+
.map(f => f.replace(/^!/, ''))
304+
.filter(f => {
305+
const ext = extname(f).slice(1)
306+
// ignore it if the specified format extensions match or if its a directory
307+
return (fullConfig.formatExtensions || []).includes(ext) || (!ext && f.endsWith('/'))
308+
}),
309+
],
241310
// gitignore, these use the full config so need to come at the very end
242311
ignorePaths: [
243312
...gitignore.sort([
244-
...gitignore.allowRootDir([
245-
// Allways allow module files in root or workspaces
246-
...getAddedFiles(moduleFiles).map(s => template(s, fullConfig)),
247-
...isRoot ? [
248-
// in the root allow all repo files
249-
...getAddedFiles(repoFiles).map(s => template(s, fullConfig)),
250-
// and allow all workspace repo level files in the root
251-
...pkgs
252-
.filter(p => p.path !== rootPkg.path && p.config.workspaceRepo !== false)
253-
.flatMap(() => getAddedFiles(files.workspaceRepo)),
254-
] : [],
255-
]),
256-
...isRoot && pkgConfig.lockfile ? ['!/package-lock.json'] : [],
257-
...(pkgConfig.allowPaths || []).map((p) => `!${p}`),
258-
...(pkgConfig.allowDistPaths ? pkgConfig.distPaths : []).map((p) => `!/${p}`),
313+
...ignoreAddedPaths,
314+
...(pkgConfig.allowPaths || []).map(p => `!${p}`),
315+
...(pkgConfig.allowDistPaths ? pkgConfig.distPaths : []).map(p => `!/${p}`),
259316
...(pkgConfig.ignorePaths || []),
260317
]),
261318
// these cant be sorted since they rely on order

lib/content/eslintrc-js.hbs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,9 @@ const localConfigs = readdir(__dirname)
99
module.exports = {
1010
root: true,
1111
ignorePatterns: [
12-
'tap-testdir*/',
13-
{{#each workspaceGlobs}}
12+
{{#each lintIgnorePaths}}
1413
'{{ . }}',
1514
{{/each}}
16-
{{#if typescript}}
17-
'dist/',
18-
{{/if}}
1915
],
2016
{{#if typescript}}
2117
parser: '@typescript-eslint/parser',
@@ -28,5 +24,8 @@ module.exports = {
2824
extends: [
2925
'@npmcli',
3026
...localConfigs,
27+
{{#if prettier}}
28+
'prettier',
29+
{{/if}}
3130
],
3231
}

lib/content/gitignore.hbs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
# ignore everything in the root
22
/*
3-
# transient test directories
4-
tap-testdir*/
53

6-
# keep these
74
{{#each ignorePaths}}
85
{{ . }}
96
{{/each}}

lib/content/index.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,14 @@ const rootModule = {
9696
file: 'eslintrc-js.hbs',
9797
filter: (p) => p.config.eslint,
9898
},
99+
'.prettierrc.{{ cjsExt }}': {
100+
file: 'prettier-js.hbs',
101+
filter: (p) => p.config.prettier,
102+
},
103+
'.prettierignore': {
104+
file: 'prettierignore.hbs',
105+
filter: (p) => p.config.prettier,
106+
},
99107
'.gitignore': 'gitignore.hbs',
100108
'.npmrc': 'npmrc.hbs',
101109
'SECURITY.md': 'SECURITY-md.hbs',
@@ -167,15 +175,21 @@ module.exports = {
167175
'/README*',
168176
'/LICENSE*',
169177
'/CHANGELOG*',
178+
'/.git-blame-ignore-revs',
170179
],
171-
ignorePaths: [
172-
/* to be provided by consuming package */
180+
ignorePaths: ['tap-testdir*/'],
181+
lintIgnorePaths: [
182+
// can be set by consumer
173183
],
184+
lintExtensions: ['js', 'cjs', 'ts', 'mjs', 'jsx', 'tsx'],
185+
formatIgnorePaths: ['tap-snapshots/', 'test/fixtures/**/*.json'],
186+
formatExtensions: ['js', 'cjs', 'ts', 'mjs', 'jsx', 'tsx', 'json'],
174187
ciVersions: {},
175188
latestCiVersion: 22,
176189
lockfile: false,
177190
codeowner: '@npm/cli-team',
178191
eslint: true,
192+
prettier: false,
179193
publish: false,
180194
typescript: false,
181195
esm: false,

lib/content/package-json.hbs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,20 @@
33
"files": {{{ json distPaths }}},
44
"type": {{#if esm}}"module"{{else}}{{{ del }}}{{/if}},
55
"scripts": {
6-
"lint": "{{#if eslint}}eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"{{else}}echo linting disabled{{/if}}",
6+
{{#if eslint}}
7+
"eslint": "eslint \"**/*.{{{ extGlob lintExtensions }}}\"",
8+
"lint": "{{ localNpmPath }} run eslint {{~#if prettier}} && {{ localNpmPath }} run prettier -- --check{{/if}}",
9+
"lintfix": "{{ localNpmPath }} run eslint -- --fix {{~#if prettier}} && {{ localNpmPath }} run prettier -- --write{{/if}}",
10+
{{#if prettier}}
11+
"prettier": "prettier \"**/*.{{{ extGlob formatExtensions }}}\"",
12+
{{/if}}
13+
{{else}}
14+
"eslint": {{{ del }}},
15+
"lint": "echo linting disabled",
16+
"lintfix": {{{ del }}},
17+
{{/if}}
718
"postlint": "template-oss-check",
819
"template-oss-apply": "template-oss-apply --force",
9-
"lintfix": "{{ localNpmPath }} run lint -- --fix",
1020
"snap": "{{#if typescript}}{{#if tap16}}c8 {{/if}}{{/if}}tap",
1121
"test": "{{#if typescript}}{{#if tap16}}c8 {{/if}}{{/if}}tap",
1222
"posttest": "{{ localNpmPath }} run lint",

lib/content/prettier-js.hbs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
const githubConfig = require('@github/prettier-config')
2+
3+
module.exports = {
4+
...githubConfig,
5+
bracketSpacing: true,
6+
}

lib/content/prettierignore.hbs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{{#each formatIgnorePaths}}
2+
{{ . }}
3+
{{/each}}

lib/util/parser.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ class Base {
174174
}
175175

176176
class Gitignore extends Base {
177-
static types = ['codeowners', '.gitignore']
177+
static types = ['codeowners', '.gitignore', '.prettierignore']
178178
comment = (c) => `# ${c}`
179179
}
180180

lib/util/template.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ const makePartials = (dir, isBase) => {
3434

3535
const setupHandlebars = (dirs) => {
3636
Handlebars.registerHelper('obj', ({ hash }) => Object.fromEntries(safeValues(hash)))
37+
Handlebars.registerHelper('extGlob', arr => `{${arr.join(',')}}`)
3738
Handlebars.registerHelper('join', (arr, sep) => arr.join(typeof sep === 'string' ? sep : ', '))
3839
Handlebars.registerHelper('pluck', (arr, key) => arr.map(a => a[key]))
3940
Handlebars.registerHelper('quote', (arr) => arr.map(a => `'${a}'`))

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,17 @@
1010
"template-oss-release-manager": "bin/release-manager.js"
1111
},
1212
"scripts": {
13-
"lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"",
14-
"lintfix": "npm run lint -- --fix",
13+
"lint": "npm run eslint",
14+
"lintfix": "npm run eslint -- --fix",
1515
"posttest": "npm run lint",
1616
"snap": "tap",
1717
"test": "tap",
1818
"template-oss-apply": "template-oss-apply --force",
1919
"postlint": "template-oss-check",
2020
"postinstall": "template-oss-apply",
21+
"eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"",
2122
"test-all": "npm run test -ws -iwr --if-present",
22-
"lint-all": "npm run lint -ws -iwr --if-present",
23-
"test:record": "TAP_SNAPSHOT=1 NOCK_RECORD=1 tap"
23+
"lint-all": "npm run lint -ws -iwr --if-present"
2424
},
2525
"repository": {
2626
"type": "git",

0 commit comments

Comments
 (0)