From 1a073e477827cf8b49edbd694aca536dc545f1ec Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Fri, 3 May 2024 11:48:39 -0700 Subject: [PATCH 01/18] chore: bump @npmcli/template-oss to 4.22.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ee52ed43..010c7930 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ ], "devDependencies": { "@npmcli/eslint-config": "^4.0.0", - "@npmcli/template-oss": "file:./", + "@npmcli/template-oss": "4.22.0", "nock": "^13.3.8", "tap": "^16.0.0" }, From 9440c4f2a8292d4920d9a6d815a13dbd75146ecf Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Tue, 7 May 2024 13:03:00 -0700 Subject: [PATCH 02/18] fix: pass releases to publish check (#444) If `publish: true` is not set, then the release intergration workflow falls back to running `npm view $SPEC` which will error if the package has not been published. This tags the CODEOWNERS in the release issue so we know something went wrong. This doesn't have much use now that we are moving everything to `publish: true` but it would have caught a missing publish last week that I missed on `@npmcli/fs`: https://github.com/npm/fs/actions/runs/8946801618/job/24577963034#step:7:4 The `RELEASES` env var was only being set for the publish step, not the check if published step. --- lib/content/_job-release-integration-yml.hbs | 2 ++ package.json | 2 +- tap-snapshots/test/apply/source-snapshots.js.test.cjs | 6 ++++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/content/_job-release-integration-yml.hbs b/lib/content/_job-release-integration-yml.hbs index daeba3c2..97efc840 100644 --- a/lib/content/_job-release-integration-yml.hbs +++ b/lib/content/_job-release-integration-yml.hbs @@ -19,6 +19,8 @@ steps: {{else}} {{> stepsSetupYml }} - name: Check If Published + env: + RELEASES: $\{{ inputs.releases }} {{/if}} run: | EXIT_CODE=0 diff --git a/package.json b/package.json index 010c7930..ee52ed43 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ ], "devDependencies": { "@npmcli/eslint-config": "^4.0.0", - "@npmcli/template-oss": "4.22.0", + "@npmcli/template-oss": "file:./", "nock": "^13.3.8", "tap": "^16.0.0" }, diff --git a/tap-snapshots/test/apply/source-snapshots.js.test.cjs b/tap-snapshots/test/apply/source-snapshots.js.test.cjs index 5ef24507..b0462e69 100644 --- a/tap-snapshots/test/apply/source-snapshots.js.test.cjs +++ b/tap-snapshots/test/apply/source-snapshots.js.test.cjs @@ -898,6 +898,8 @@ jobs: - name: Install Dependencies run: npm i --ignore-scripts --no-audit --no-fund - name: Check If Published + env: + RELEASES: \${{ inputs.releases }} run: | EXIT_CODE=0 @@ -2552,6 +2554,8 @@ jobs: - name: Install Dependencies run: npm i --ignore-scripts --no-audit --no-fund - name: Check If Published + env: + RELEASES: \${{ inputs.releases }} run: | EXIT_CODE=0 @@ -4072,6 +4076,8 @@ jobs: - name: Install Dependencies run: npm i --ignore-scripts --no-audit --no-fund - name: Check If Published + env: + RELEASES: \${{ inputs.releases }} run: | EXIT_CODE=0 From 8aef509c19639a08a47cf0378ea54799229891ff Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 8 May 2024 19:03:41 -0700 Subject: [PATCH 03/18] fix: dont conclude checks if they were never set (#446) --- .github/workflows/ci-release.yml | 4 ++-- lib/content/ci-release-yml.hbs | 4 ++-- .../test/apply/source-snapshots.js.test.cjs | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci-release.yml b/.github/workflows/ci-release.yml index af138475..4709ee43 100644 --- a/.github/workflows/ci-release.yml +++ b/.github/workflows/ci-release.yml @@ -61,7 +61,7 @@ jobs: run: npm run postlint --ignore-scripts -ws -iwr --if-present - name: Conclude Check uses: LouisBrunner/checks-action@v1.6.0 - if: always() + if: steps.create-check.outputs.check-id && always() with: token: ${{ secrets.GITHUB_TOKEN }} conclusion: ${{ job.status }} @@ -142,7 +142,7 @@ jobs: run: npm test --ignore-scripts -ws -iwr --if-present - name: Conclude Check uses: LouisBrunner/checks-action@v1.6.0 - if: always() + if: steps.create-check.outputs.check-id && always() with: token: ${{ secrets.GITHUB_TOKEN }} conclusion: ${{ job.status }} diff --git a/lib/content/ci-release-yml.hbs b/lib/content/ci-release-yml.hbs index 54f95f08..88aee56f 100644 --- a/lib/content/ci-release-yml.hbs +++ b/lib/content/ci-release-yml.hbs @@ -27,7 +27,7 @@ jobs: {{> stepLintYml jobRunFlags=allFlags }} - name: Conclude Check uses: LouisBrunner/checks-action@v1.6.0 - if: always() + if: steps.create-check.outputs.check-id && always() with: token: $\{{ secrets.GITHUB_TOKEN }} conclusion: $\{{ job.status }} @@ -42,7 +42,7 @@ jobs: {{> stepTestYml jobRunFlags=allFlags }} - name: Conclude Check uses: LouisBrunner/checks-action@v1.6.0 - if: always() + if: steps.create-check.outputs.check-id && always() with: token: $\{{ secrets.GITHUB_TOKEN }} conclusion: $\{{ job.status }} diff --git a/tap-snapshots/test/apply/source-snapshots.js.test.cjs b/tap-snapshots/test/apply/source-snapshots.js.test.cjs index b0462e69..a757ef1a 100644 --- a/tap-snapshots/test/apply/source-snapshots.js.test.cjs +++ b/tap-snapshots/test/apply/source-snapshots.js.test.cjs @@ -452,7 +452,7 @@ jobs: run: npm run postlint --ignore-scripts - name: Conclude Check uses: LouisBrunner/checks-action@v1.6.0 - if: always() + if: steps.create-check.outputs.check-id && always() with: token: \${{ secrets.GITHUB_TOKEN }} conclusion: \${{ job.status }} @@ -521,7 +521,7 @@ jobs: run: npm test --ignore-scripts - name: Conclude Check uses: LouisBrunner/checks-action@v1.6.0 - if: always() + if: steps.create-check.outputs.check-id && always() with: token: \${{ secrets.GITHUB_TOKEN }} conclusion: \${{ job.status }} @@ -2102,7 +2102,7 @@ jobs: run: npm run postlint --ignore-scripts -ws -iwr --if-present - name: Conclude Check uses: LouisBrunner/checks-action@v1.6.0 - if: always() + if: steps.create-check.outputs.check-id && always() with: token: \${{ secrets.GITHUB_TOKEN }} conclusion: \${{ job.status }} @@ -2171,7 +2171,7 @@ jobs: run: npm test --ignore-scripts -ws -iwr --if-present - name: Conclude Check uses: LouisBrunner/checks-action@v1.6.0 - if: always() + if: steps.create-check.outputs.check-id && always() with: token: \${{ secrets.GITHUB_TOKEN }} conclusion: \${{ job.status }} @@ -3775,7 +3775,7 @@ jobs: run: npm run postlint --ignore-scripts -ws -iwr --if-present - name: Conclude Check uses: LouisBrunner/checks-action@v1.6.0 - if: always() + if: steps.create-check.outputs.check-id && always() with: token: \${{ secrets.GITHUB_TOKEN }} conclusion: \${{ job.status }} @@ -3844,7 +3844,7 @@ jobs: run: npm test --ignore-scripts -ws -iwr --if-present - name: Conclude Check uses: LouisBrunner/checks-action@v1.6.0 - if: always() + if: steps.create-check.outputs.check-id && always() with: token: \${{ secrets.GITHUB_TOKEN }} conclusion: \${{ job.status }} From 60ee94f58f085c9f85a73638501a1baac67507a7 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 15 May 2024 09:30:12 -0700 Subject: [PATCH 04/18] feat: add prettier support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Julian Møller Ellehauge --- .gitignore | 7 +- lib/config.js | 97 +++++++++++++++---- lib/content/eslintrc-js.hbs | 9 +- lib/content/gitignore.hbs | 3 - lib/content/index.js | 18 +++- lib/content/package-json.hbs | 14 ++- lib/content/prettier-js.hbs | 6 ++ lib/content/prettierignore.hbs | 3 + lib/util/parser.js | 2 +- lib/util/template.js | 1 + package.json | 8 +- .../test/apply/source-snapshots.js.test.cjs | 64 ++++++------ .../test/check/snapshots.js.test.cjs | 36 ++++--- test/apply/eslint.js | 24 ----- test/apply/lint.js | 61 ++++++++++++ workspace/test-workspace/.gitignore | 5 +- workspace/test-workspace/package.json | 7 +- 17 files changed, 253 insertions(+), 112 deletions(-) create mode 100644 lib/content/prettier-js.hbs create mode 100644 lib/content/prettierignore.hbs delete mode 100644 test/apply/eslint.js create mode 100644 test/apply/lint.js diff --git a/.gitignore b/.gitignore index e0bd2dd9..9d61ca63 100644 --- a/.gitignore +++ b/.gitignore @@ -2,17 +2,17 @@ # ignore everything in the root /* -# transient test directories -tap-testdir*/ -# keep these !**/.gitignore !/.commitlintrc.js !/.eslintrc.js !/.eslintrc.local.* +!/.git-blame-ignore-revs !/.github/ !/.gitignore !/.npmrc +!/.prettierignore +!/.prettierrc.js !/.release-please-manifest.json !/bin/ !/CHANGELOG* @@ -30,6 +30,7 @@ tap-testdir*/ !/tap-snapshots/ !/test/ !/tsconfig.json +tap-testdir*/ !/workspace/ /workspace/* !/workspace/test-workspace/ diff --git a/lib/config.js b/lib/config.js index f8d51dc7..a1d6fd0a 100644 --- a/lib/config.js +++ b/lib/config.js @@ -19,7 +19,16 @@ const DEFAULT_CONTENT = require.resolve(NAME) const getPkgConfig = (pkg) => pkg[CONFIG_KEY] || {} const merge = mergeWithCustomizers( - customizers.mergeArrays('branches', 'distPaths', 'allowPaths', 'ignorePaths'), + customizers.mergeArrays( + 'branches', + 'distPaths', + 'allowPaths', + 'ignorePaths', + 'lintIgnorePaths', + 'lintExtensions', + 'formatIgnorePaths', + 'formatExtensions' + ), (value, srcValue, key) => { if (key === 'ciVersions' && (Array.isArray(srcValue) || isPlainObject(srcValue))) { return { ...ciVersions.parse(value), ...ciVersions.parse(srcValue) } @@ -196,17 +205,42 @@ const getFullConfig = async ({ pkgConfig.requiredPackages.devDependencies.filter(p => !p.includes('eslint')) } + pkgConfig.lintIgnorePaths = [ + ...(pkgConfig.ignorePaths || []), + ...(pkgConfig.lintIgnorePaths || []), + ...derived.workspaceGlobs, + ] + + pkgConfig.formatIgnorePaths = [ + ...(pkgConfig.ignorePaths || []), + ...(pkgConfig.formatIgnorePaths || []), + ...derived.workspaceGlobs, + ] + if (pkgConfig.typescript) { defaultsDeep(pkgConfig, { allowPaths: [], requiredPackages: { devDependencies: [] } }) pkgConfig.distPaths = ['dist/'] + pkgConfig.lintIgnorePaths = uniq([...pkgConfig.lintIgnorePaths, 'dist/']) + pkgConfig.formatIgnorePaths = uniq([...pkgConfig.formatIgnorePaths, 'dist/']) pkgConfig.allowDistPaths = false - pkgConfig.allowPaths.push('/src/') - pkgConfig.requiredPackages.devDependencies.push( + pkgConfig.allowPaths = uniq([...pkgConfig.allowPaths, '/src/']) + pkgConfig.requiredPackages.devDependencies = uniq([ + ...pkgConfig.requiredPackages.devDependencies, 'typescript', 'tshy', '@typescript-eslint/parser', - ...derived.tap16 ? ['c8', 'ts-node'] : [] - ) + ...derived.tap16 ? ['c8', 'ts-node'] : [], + ]) + } + + if (pkgConfig.prettier) { + defaultsDeep(pkgConfig, { requiredPackages: { devDependencies: [] } }) + pkgConfig.requiredPackages.devDependencies = uniq([ + ...pkgConfig.requiredPackages.devDependencies, + 'prettier', + 'eslint-config-prettier', + '@github/prettier-config', + ]) } const gitUrl = await git.getUrl(rootPkg.path) @@ -238,24 +272,47 @@ const getFullConfig = async ({ applyRepo: !!repoFiles, applyModule: !!moduleFiles, __PARTIAL_DIRS__: fileDirs, + }) + + const ignoreAddedPaths = gitignore.sort([ + ...gitignore.allowRootDir([ + // Allways allow module files in root or workspaces + ...getAddedFiles(moduleFiles).map(s => template(s, fullConfig)), + ...(isRoot + ? [ + // in the root allow all repo files + ...getAddedFiles(repoFiles).map(s => template(s, fullConfig)), + // and allow all workspace repo level files in the root + ...pkgs + .filter(p => p.path !== rootPkg.path && p.config.workspaceRepo !== false) + .flatMap(() => getAddedFiles(files.workspaceRepo)), + ] + : []), + ]), + ...(isRoot && pkgConfig.lockfile ? ['!/package-lock.json'] : []), + ]) + + Object.assign(fullConfig, { + // Make sure we don't format any files that are being generated since they will cause template-oss-check to fail + // This could be changed if those files were also formatted before save but then we would need to read generated + // the prettier config first and use that as the formatting rules which would get weird + formatIgnorePaths: [ + ...fullConfig.formatIgnorePaths, + ...ignoreAddedPaths + .filter(f => f.startsWith('!')) + .map(f => f.replace(/^!/, '')) + .filter(f => { + const ext = extname(f).slice(1) + // ignore it if the specified format extensions match or if its a directory + return (fullConfig.formatExtensions || []).includes(ext) || (!ext && f.endsWith('/')) + }), + ], // gitignore, these use the full config so need to come at the very end ignorePaths: [ ...gitignore.sort([ - ...gitignore.allowRootDir([ - // Allways allow module files in root or workspaces - ...getAddedFiles(moduleFiles).map(s => template(s, fullConfig)), - ...isRoot ? [ - // in the root allow all repo files - ...getAddedFiles(repoFiles).map(s => template(s, fullConfig)), - // and allow all workspace repo level files in the root - ...pkgs - .filter(p => p.path !== rootPkg.path && p.config.workspaceRepo !== false) - .flatMap(() => getAddedFiles(files.workspaceRepo)), - ] : [], - ]), - ...isRoot && pkgConfig.lockfile ? ['!/package-lock.json'] : [], - ...(pkgConfig.allowPaths || []).map((p) => `!${p}`), - ...(pkgConfig.allowDistPaths ? pkgConfig.distPaths : []).map((p) => `!/${p}`), + ...ignoreAddedPaths, + ...(pkgConfig.allowPaths || []).map(p => `!${p}`), + ...(pkgConfig.allowDistPaths ? pkgConfig.distPaths : []).map(p => `!/${p}`), ...(pkgConfig.ignorePaths || []), ]), // these cant be sorted since they rely on order diff --git a/lib/content/eslintrc-js.hbs b/lib/content/eslintrc-js.hbs index bb38c366..c01ead8e 100644 --- a/lib/content/eslintrc-js.hbs +++ b/lib/content/eslintrc-js.hbs @@ -9,13 +9,9 @@ const localConfigs = readdir(__dirname) module.exports = { root: true, ignorePatterns: [ - 'tap-testdir*/', - {{#each workspaceGlobs}} + {{#each lintIgnorePaths}} '{{ . }}', {{/each}} - {{#if typescript}} - 'dist/', - {{/if}} ], {{#if typescript}} parser: '@typescript-eslint/parser', @@ -28,5 +24,8 @@ module.exports = { extends: [ '@npmcli', ...localConfigs, + {{#if prettier}} + 'prettier', + {{/if}} ], } diff --git a/lib/content/gitignore.hbs b/lib/content/gitignore.hbs index 21074e32..70aa8746 100644 --- a/lib/content/gitignore.hbs +++ b/lib/content/gitignore.hbs @@ -1,9 +1,6 @@ # ignore everything in the root /* -# transient test directories -tap-testdir*/ -# keep these {{#each ignorePaths}} {{ . }} {{/each}} diff --git a/lib/content/index.js b/lib/content/index.js index 84315218..f4f68e8a 100644 --- a/lib/content/index.js +++ b/lib/content/index.js @@ -96,6 +96,14 @@ const rootModule = { file: 'eslintrc-js.hbs', filter: (p) => p.config.eslint, }, + '.prettierrc.{{ cjsExt }}': { + file: 'prettier-js.hbs', + filter: (p) => p.config.prettier, + }, + '.prettierignore': { + file: 'prettierignore.hbs', + filter: (p) => p.config.prettier, + }, '.gitignore': 'gitignore.hbs', '.npmrc': 'npmrc.hbs', 'SECURITY.md': 'SECURITY-md.hbs', @@ -167,15 +175,21 @@ module.exports = { '/README*', '/LICENSE*', '/CHANGELOG*', + '/.git-blame-ignore-revs', ], - ignorePaths: [ - /* to be provided by consuming package */ + ignorePaths: ['tap-testdir*/'], + lintIgnorePaths: [ + // can be set by consumer ], + lintExtensions: ['js', 'cjs', 'ts', 'mjs', 'jsx', 'tsx'], + formatIgnorePaths: ['tap-snapshots/', 'test/fixtures/**/*.json'], + formatExtensions: ['js', 'cjs', 'ts', 'mjs', 'jsx', 'tsx', 'json'], ciVersions: {}, latestCiVersion: 22, lockfile: false, codeowner: '@npm/cli-team', eslint: true, + prettier: false, publish: false, typescript: false, esm: false, diff --git a/lib/content/package-json.hbs b/lib/content/package-json.hbs index a115f51e..98e7d591 100644 --- a/lib/content/package-json.hbs +++ b/lib/content/package-json.hbs @@ -3,10 +3,20 @@ "files": {{{ json distPaths }}}, "type": {{#if esm}}"module"{{else}}{{{ del }}}{{/if}}, "scripts": { - "lint": "{{#if eslint}}eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"{{else}}echo linting disabled{{/if}}", + {{#if eslint}} + "eslint": "eslint \"**/*.{{{ extGlob lintExtensions }}}\"", + "lint": "{{ localNpmPath }} run eslint {{~#if prettier}} && {{ localNpmPath }} run prettier -- --check{{/if}}", + "lintfix": "{{ localNpmPath }} run eslint -- --fix {{~#if prettier}} && {{ localNpmPath }} run prettier -- --write{{/if}}", + {{#if prettier}} + "prettier": "prettier \"**/*.{{{ extGlob formatExtensions }}}\"", + {{/if}} + {{else}} + "eslint": {{{ del }}}, + "lint": "echo linting disabled", + "lintfix": {{{ del }}}, + {{/if}} "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force", - "lintfix": "{{ localNpmPath }} run lint -- --fix", "snap": "{{#if typescript}}{{#if tap16}}c8 {{/if}}{{/if}}tap", "test": "{{#if typescript}}{{#if tap16}}c8 {{/if}}{{/if}}tap", "posttest": "{{ localNpmPath }} run lint", diff --git a/lib/content/prettier-js.hbs b/lib/content/prettier-js.hbs new file mode 100644 index 00000000..13d1ba90 --- /dev/null +++ b/lib/content/prettier-js.hbs @@ -0,0 +1,6 @@ +const githubConfig = require('@github/prettier-config') + +module.exports = { + ...githubConfig, + bracketSpacing: true, +} diff --git a/lib/content/prettierignore.hbs b/lib/content/prettierignore.hbs new file mode 100644 index 00000000..1d6d58da --- /dev/null +++ b/lib/content/prettierignore.hbs @@ -0,0 +1,3 @@ +{{#each formatIgnorePaths}} +{{ . }} +{{/each}} diff --git a/lib/util/parser.js b/lib/util/parser.js index 48b5f4e8..2156f6cd 100644 --- a/lib/util/parser.js +++ b/lib/util/parser.js @@ -174,7 +174,7 @@ class Base { } class Gitignore extends Base { - static types = ['codeowners', '.gitignore'] + static types = ['codeowners', '.gitignore', '.prettierignore'] comment = (c) => `# ${c}` } diff --git a/lib/util/template.js b/lib/util/template.js index 8a291f48..c7889a23 100644 --- a/lib/util/template.js +++ b/lib/util/template.js @@ -34,6 +34,7 @@ const makePartials = (dir, isBase) => { const setupHandlebars = (dirs) => { Handlebars.registerHelper('obj', ({ hash }) => Object.fromEntries(safeValues(hash))) + Handlebars.registerHelper('extGlob', arr => `{${arr.join(',')}}`) Handlebars.registerHelper('join', (arr, sep) => arr.join(typeof sep === 'string' ? sep : ', ')) Handlebars.registerHelper('pluck', (arr, key) => arr.map(a => a[key])) Handlebars.registerHelper('quote', (arr) => arr.map(a => `'${a}'`)) diff --git a/package.json b/package.json index ee52ed43..83cc496c 100644 --- a/package.json +++ b/package.json @@ -10,17 +10,17 @@ "template-oss-release-manager": "bin/release-manager.js" }, "scripts": { - "lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"", - "lintfix": "npm run lint -- --fix", + "lint": "npm run eslint", + "lintfix": "npm run eslint -- --fix", "posttest": "npm run lint", "snap": "tap", "test": "tap", "template-oss-apply": "template-oss-apply --force", "postlint": "template-oss-check", "postinstall": "template-oss-apply", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"", "test-all": "npm run test -ws -iwr --if-present", - "lint-all": "npm run lint -ws -iwr --if-present", - "test:record": "TAP_SNAPSHOT=1 NOCK_RECORD=1 tap" + "lint-all": "npm run lint -ws -iwr --if-present" }, "repository": { "type": "git", diff --git a/tap-snapshots/test/apply/source-snapshots.js.test.cjs b/tap-snapshots/test/apply/source-snapshots.js.test.cjs index a757ef1a..27e0be01 100644 --- a/tap-snapshots/test/apply/source-snapshots.js.test.cjs +++ b/tap-snapshots/test/apply/source-snapshots.js.test.cjs @@ -1231,17 +1231,17 @@ jobs: # ignore everything in the root /* -# transient test directories -tap-testdir*/ -# keep these !**/.gitignore !/.commitlintrc.js !/.eslintrc.js !/.eslintrc.local.* +!/.git-blame-ignore-revs !/.github/ !/.gitignore !/.npmrc +!/.prettierignore +!/.prettierrc.js !/.release-please-manifest.json !/bin/ !/CHANGELOG* @@ -1259,6 +1259,7 @@ tap-testdir*/ !/tap-snapshots/ !/test/ !/tsconfig.json +tap-testdir*/ .npmrc ======================================== @@ -1341,10 +1342,11 @@ package.json "name": "testpkg", "version": "1.0.0", "scripts": { - "lint": "eslint /"**/*.{js,cjs,ts,mjs,jsx,tsx}/"", + "eslint": "eslint /"**/*.{js,cjs,ts,mjs,jsx,tsx}/"", + "lint": "npm run eslint", + "lintfix": "npm run eslint -- --fix", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force", - "lintfix": "npm run lint -- --fix", "snap": "tap", "test": "tap", "posttest": "npm run lint" @@ -2887,17 +2889,17 @@ jobs: # ignore everything in the root /* -# transient test directories -tap-testdir*/ -# keep these !**/.gitignore !/.commitlintrc.js !/.eslintrc.js !/.eslintrc.local.* +!/.git-blame-ignore-revs !/.github/ !/.gitignore !/.npmrc +!/.prettierignore +!/.prettierrc.js !/.release-please-manifest.json !/bin/ !/CHANGELOG* @@ -2915,6 +2917,7 @@ tap-testdir*/ !/tap-snapshots/ !/test/ !/tsconfig.json +tap-testdir*/ !/workspaces/ /workspaces/* !/workspaces/a/ @@ -3007,10 +3010,11 @@ package.json "workspaces/b" ], "scripts": { - "lint": "eslint /"**/*.{js,cjs,ts,mjs,jsx,tsx}/"", + "eslint": "eslint /"**/*.{js,cjs,ts,mjs,jsx,tsx}/"", + "lint": "npm run eslint", + "lintfix": "npm run eslint -- --fix", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force", - "lintfix": "npm run lint -- --fix", "snap": "tap", "test": "tap", "posttest": "npm run lint", @@ -3134,13 +3138,11 @@ workspaces/a/.gitignore # ignore everything in the root /* -# transient test directories -tap-testdir*/ -# keep these !**/.gitignore !/.eslintrc.js !/.eslintrc.local.* +!/.git-blame-ignore-revs !/.gitignore !/bin/ !/CHANGELOG* @@ -3153,6 +3155,7 @@ tap-testdir*/ !/scripts/ !/tap-snapshots/ !/test/ +tap-testdir*/ workspaces/a/package.json ======================================== @@ -3160,10 +3163,11 @@ workspaces/a/package.json "name": "a", "version": "1.0.0", "scripts": { - "lint": "eslint /"**/*.{js,cjs,ts,mjs,jsx,tsx}/"", + "eslint": "eslint /"**/*.{js,cjs,ts,mjs,jsx,tsx}/"", + "lint": "npm run eslint", + "lintfix": "npm run eslint -- --fix", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force", - "lintfix": "npm run lint -- --fix", "snap": "tap", "test": "tap", "posttest": "npm run lint" @@ -3214,13 +3218,11 @@ workspaces/b/.gitignore # ignore everything in the root /* -# transient test directories -tap-testdir*/ -# keep these !**/.gitignore !/.eslintrc.js !/.eslintrc.local.* +!/.git-blame-ignore-revs !/.gitignore !/bin/ !/CHANGELOG* @@ -3233,6 +3235,7 @@ tap-testdir*/ !/scripts/ !/tap-snapshots/ !/test/ +tap-testdir*/ workspaces/b/package.json ======================================== @@ -3240,10 +3243,11 @@ workspaces/b/package.json "name": "b", "version": "1.0.0", "scripts": { - "lint": "eslint /"**/*.{js,cjs,ts,mjs,jsx,tsx}/"", + "eslint": "eslint /"**/*.{js,cjs,ts,mjs,jsx,tsx}/"", + "lint": "npm run eslint", + "lintfix": "npm run eslint -- --fix", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force", - "lintfix": "npm run lint -- --fix", "snap": "tap", "test": "tap", "posttest": "npm run lint" @@ -4498,13 +4502,11 @@ workspaces/a/.gitignore # ignore everything in the root /* -# transient test directories -tap-testdir*/ -# keep these !**/.gitignore !/.eslintrc.js !/.eslintrc.local.* +!/.git-blame-ignore-revs !/.gitignore !/bin/ !/CHANGELOG* @@ -4517,6 +4519,7 @@ tap-testdir*/ !/scripts/ !/tap-snapshots/ !/test/ +tap-testdir*/ workspaces/a/package.json ======================================== @@ -4524,10 +4527,11 @@ workspaces/a/package.json "name": "a", "version": "1.0.0", "scripts": { - "lint": "eslint /"**/*.{js,cjs,ts,mjs,jsx,tsx}/"", + "eslint": "eslint /"**/*.{js,cjs,ts,mjs,jsx,tsx}/"", + "lint": "npm run eslint", + "lintfix": "npm run eslint -- --fix", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force", - "lintfix": "npm run lint -- --fix", "snap": "tap", "test": "tap", "posttest": "npm run lint" @@ -4578,13 +4582,11 @@ workspaces/b/.gitignore # ignore everything in the root /* -# transient test directories -tap-testdir*/ -# keep these !**/.gitignore !/.eslintrc.js !/.eslintrc.local.* +!/.git-blame-ignore-revs !/.gitignore !/bin/ !/CHANGELOG* @@ -4597,6 +4599,7 @@ tap-testdir*/ !/scripts/ !/tap-snapshots/ !/test/ +tap-testdir*/ workspaces/b/package.json ======================================== @@ -4604,10 +4607,11 @@ workspaces/b/package.json "name": "b", "version": "1.0.0", "scripts": { - "lint": "eslint /"**/*.{js,cjs,ts,mjs,jsx,tsx}/"", + "eslint": "eslint /"**/*.{js,cjs,ts,mjs,jsx,tsx}/"", + "lint": "npm run eslint", + "lintfix": "npm run eslint -- --fix", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force", - "lintfix": "npm run lint -- --fix", "snap": "tap", "test": "tap", "posttest": "npm run lint" diff --git a/tap-snapshots/test/check/snapshots.js.test.cjs b/tap-snapshots/test/check/snapshots.js.test.cjs index a59000a1..88039c1b 100644 --- a/tap-snapshots/test/check/snapshots.js.test.cjs +++ b/tap-snapshots/test/check/snapshots.js.test.cjs @@ -76,10 +76,11 @@ The module file package.json needs to be updated: "lib/" ] "scripts" is missing, expected { - "lint": "eslint /"**/*.{js,cjs,ts,mjs,jsx,tsx}/"", + "eslint": "eslint /"**/*.{js,cjs,ts,mjs,jsx,tsx}/"", + "lint": "npm run eslint", + "lintfix": "npm run eslint -- --fix", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force", - "lintfix": "npm run lint -- --fix", "snap": "tap", "test": "tap", "posttest": "npm run lint" @@ -123,14 +124,16 @@ The following files are tracked by git but matching a pattern in .gitignore: To correct it: move files to not match one of the following patterns: /* - tap-testdir*/ !**/.gitignore !/.commitlintrc.js !/.eslintrc.js !/.eslintrc.local.* + !/.git-blame-ignore-revs !/.github/ !/.gitignore !/.npmrc + !/.prettierignore + !/.prettierrc.js !/.release-please-manifest.json !/bin/ !/CHANGELOG* @@ -148,6 +151,7 @@ To correct it: move files to not match one of the following patterns: !/tap-snapshots/ !/test/ !/tsconfig.json + tap-testdir*/ ------------------------------------------------------------------- ` @@ -164,14 +168,16 @@ The following files are tracked by git but matching a pattern in .gitignore: To correct it: move files to not match one of the following patterns: /* - tap-testdir*/ !**/.gitignore !/.commitlintrc.js !/.eslintrc.js !/.eslintrc.local.* + !/.git-blame-ignore-revs !/.github/ !/.gitignore !/.npmrc + !/.prettierignore + !/.prettierrc.js !/.release-please-manifest.json !/bin/ !/CHANGELOG* @@ -189,6 +195,7 @@ To correct it: move files to not match one of the following patterns: !/tap-snapshots/ !/test/ !/tsconfig.json + tap-testdir*/ !/workspaces/ /workspaces/* !/workspaces/a/ @@ -203,10 +210,10 @@ The following files are tracked by git but matching a pattern in workspaces/a/.g To correct it: move files to not match one of the following patterns: /* - tap-testdir*/ !**/.gitignore !/.eslintrc.js !/.eslintrc.local.* + !/.git-blame-ignore-revs !/.gitignore !/bin/ !/CHANGELOG* @@ -219,6 +226,7 @@ To correct it: move files to not match one of the following patterns: !/scripts/ !/tap-snapshots/ !/test/ + tap-testdir*/ ------------------------------------------------------------------- @@ -229,10 +237,10 @@ The following files are tracked by git but matching a pattern in workspaces/b/.g To correct it: move files to not match one of the following patterns: /* - tap-testdir*/ !**/.gitignore !/.eslintrc.js !/.eslintrc.local.* + !/.git-blame-ignore-revs !/.gitignore !/bin/ !/CHANGELOG* @@ -245,6 +253,7 @@ To correct it: move files to not match one of the following patterns: !/scripts/ !/tap-snapshots/ !/test/ + tap-testdir*/ ------------------------------------------------------------------- ` @@ -333,10 +342,11 @@ The module file package.json needs to be updated: "lib/" ] "scripts" is missing, expected { - "lint": "eslint /"**/*.{js,cjs,ts,mjs,jsx,tsx}/"", + "eslint": "eslint /"**/*.{js,cjs,ts,mjs,jsx,tsx}/"", + "lint": "npm run eslint", + "lintfix": "npm run eslint -- --fix", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force", - "lintfix": "npm run lint -- --fix", "snap": "tap", "test": "tap", "posttest": "npm run lint", @@ -412,10 +422,11 @@ The module file package.json needs to be updated: "lib/" ] "scripts" is missing, expected { - "lint": "eslint /"**/*.{js,cjs,ts,mjs,jsx,tsx}/"", + "eslint": "eslint /"**/*.{js,cjs,ts,mjs,jsx,tsx}/"", + "lint": "npm run eslint", + "lintfix": "npm run eslint -- --fix", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force", - "lintfix": "npm run lint -- --fix", "snap": "tap", "test": "tap", "posttest": "npm run lint" @@ -484,10 +495,11 @@ The module file package.json needs to be updated: "lib/" ] "scripts" is missing, expected { - "lint": "eslint /"**/*.{js,cjs,ts,mjs,jsx,tsx}/"", + "eslint": "eslint /"**/*.{js,cjs,ts,mjs,jsx,tsx}/"", + "lint": "npm run eslint", + "lintfix": "npm run eslint -- --fix", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force", - "lintfix": "npm run lint -- --fix", "snap": "tap", "test": "tap", "posttest": "npm run lint" diff --git a/test/apply/eslint.js b/test/apply/eslint.js deleted file mode 100644 index 56692818..00000000 --- a/test/apply/eslint.js +++ /dev/null @@ -1,24 +0,0 @@ -const t = require('tap') -const setup = require('../setup.js') - -t.test('can disable eslint', async (t) => { - const s = await setup(t, { - package: { - templateOSS: { - eslint: false, - }, - }, - }) - await s.apply() - - const pkg = await s.readJson('package.json') - delete pkg.templateOSS // templateOSS config has eslint in it - t.notMatch(JSON.stringify(pkg), 'eslint') - - const gitignore = await s.readFile('.gitignore') - t.notMatch(gitignore, 'eslint') - - const checks = await s.check() - t.equal(checks.length, 1) - t.notMatch(checks[0].solution, 'eslint') -}) diff --git a/test/apply/lint.js b/test/apply/lint.js new file mode 100644 index 00000000..a1b8d94b --- /dev/null +++ b/test/apply/lint.js @@ -0,0 +1,61 @@ +const t = require('tap') +const setup = require('../setup.js') + +t.test('can disable eslint', async (t) => { + const s = await setup(t, { + package: { + templateOSS: { + eslint: false, + }, + }, + }) + await s.apply() + + const pkg = await s.readJson('package.json') + delete pkg.templateOSS // templateOSS config has eslint in it + t.notMatch(JSON.stringify(pkg), 'eslint') + + const gitignore = await s.readFile('.gitignore') + t.notMatch(gitignore, 'eslint') + + const checks = await s.check() + t.equal(checks.length, 1) + t.notMatch(checks[0].solution, 'eslint') +}) + +t.test('can enable prettier', async (t) => { + const s = await setup(t, { + ok: true, + package: { + templateOSS: { + prettier: true, + }, + }, + }) + await s.apply() + + const pkg = await s.readJson('package.json') + t.ok(pkg.scripts.prettier) + t.match(pkg.scripts.lint, 'npm run prettier') + t.match(pkg.scripts.lintfix, 'npm run prettier') + + const checks = await s.check() + t.equal(checks.length, 1) + t.match(checks[0].body, [ + 'prettier', + 'eslint-config-prettier', + '@github/prettier-config', + ]) + + await s.writeJson('package.json', { + ...pkg, + devDependencies: { + ...pkg.devDependencies, + prettier: '^3.0.0', + 'eslint-config-prettier': '^9.0.0', + '@github/prettier-config': '0.0.6', + }, + }) + + t.strictSame(await s.check(), []) +}) diff --git a/workspace/test-workspace/.gitignore b/workspace/test-workspace/.gitignore index a96d056a..8591cc37 100644 --- a/workspace/test-workspace/.gitignore +++ b/workspace/test-workspace/.gitignore @@ -2,13 +2,11 @@ # ignore everything in the root /* -# transient test directories -tap-testdir*/ -# keep these !**/.gitignore !/.eslintrc.js !/.eslintrc.local.* +!/.git-blame-ignore-revs !/.gitignore !/bin/ !/CHANGELOG* @@ -21,3 +19,4 @@ tap-testdir*/ !/scripts/ !/tap-snapshots/ !/test/ +tap-testdir*/ diff --git a/workspace/test-workspace/package.json b/workspace/test-workspace/package.json index cd0d379d..4acf9648 100644 --- a/workspace/test-workspace/package.json +++ b/workspace/test-workspace/package.json @@ -6,12 +6,13 @@ "private": true, "scripts": { "test": "tap", - "lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"", + "lint": "npm run eslint", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force", - "lintfix": "npm run lint -- --fix", + "lintfix": "npm run eslint -- --fix", "snap": "tap", - "posttest": "npm run lint" + "posttest": "npm run lint", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "devDependencies": { "@npmcli/eslint-config": "^4.0.0", From 210247ef9622f2f3f9f9924ce30c68e471353896 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 15 May 2024 16:39:21 -0700 Subject: [PATCH 05/18] chore: add prettier:true to template-oss config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Julian Møller Ellehauge --- .eslintrc.js | 1 + .prettierignore | 14 ++++++++++++++ .prettierrc.js | 8 ++++++++ package.json | 11 ++++++++--- 4 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 .prettierignore create mode 100644 .prettierrc.js diff --git a/.eslintrc.js b/.eslintrc.js index 0c65d1f5..c160050a 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -17,5 +17,6 @@ module.exports = { extends: [ '@npmcli', ...localConfigs, + 'prettier', ], } diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..9f89ee15 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,14 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +tap-testdir*/ +tap-snapshots/ +test/fixtures/**/*.json +workspace/test-workspace/** +/.commitlintrc.js +/.eslintrc.js +/.github/ +/.prettierrc.js +/.release-please-manifest.json +/package.json +/release-please-config.json +/tsconfig.json diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 00000000..86dd0cc0 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,8 @@ +/* This file is automatically added by @npmcli/template-oss. Do not edit. */ + +const githubConfig = require('@github/prettier-config') + +module.exports = { + ...githubConfig, + bracketSpacing: true, +} diff --git a/package.json b/package.json index 83cc496c..e6f2c523 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,8 @@ "template-oss-release-manager": "bin/release-manager.js" }, "scripts": { - "lint": "npm run eslint", - "lintfix": "npm run eslint -- --fix", + "lint": "npm run eslint && npm run prettier -- --check", + "lintfix": "npm run eslint -- --fix && npm run prettier -- --write", "posttest": "npm run lint", "snap": "tap", "test": "tap", @@ -19,6 +19,7 @@ "postlint": "template-oss-check", "postinstall": "template-oss-apply", "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"", + "prettier": "prettier \"**/*.{js,cjs,ts,mjs,jsx,tsx,json}\"", "test-all": "npm run test -ws -iwr --if-present", "lint-all": "npm run lint -ws -iwr --if-present" }, @@ -66,9 +67,12 @@ "lib/" ], "devDependencies": { + "@github/prettier-config": "0.0.6", "@npmcli/eslint-config": "^4.0.0", "@npmcli/template-oss": "file:./", + "eslint-config-prettier": "^9.1.0", "nock": "^13.3.8", + "prettier": "^3.2.5", "tap": "^16.0.0" }, "tap": { @@ -86,7 +90,8 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "publish": true + "publish": true, + "prettier": true }, "engines": { "node": "^18.17.0 || >=20.5.0" From b35bca55b28b41773aa6b936fc626bc15b40eae5 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 15 May 2024 16:55:19 -0700 Subject: [PATCH 06/18] fix: run prettier --- bin/apply.js | 7 +- bin/check.js | 6 +- bin/release-manager.js | 2 +- bin/release-please.js | 40 +++---- lib/apply/apply-files.js | 33 +++--- lib/apply/apply-version.js | 6 +- lib/apply/index.js | 5 +- lib/check/check-apply.js | 76 +++++++------- lib/check/check-changelog.js | 5 +- lib/check/check-engines.js | 11 +- lib/check/check-gitignore.js | 28 ++--- lib/check/check-required.js | 28 +++-- lib/check/check-unwanted.js | 5 +- lib/check/index.js | 17 +-- lib/config.js | 48 ++++----- lib/content/index.js | 51 ++++----- lib/index.js | 6 +- lib/release/changelog.js | 59 +++++------ lib/release/node-workspace-format.js | 24 ++--- lib/release/release-manager.js | 137 +++++++++++------------- lib/release/release-please.js | 108 +++++++++---------- lib/release/util.js | 19 ++-- lib/util/ci-versions.js | 6 +- lib/util/dependabot.js | 4 +- lib/util/files.js | 47 +++++---- lib/util/git.js | 11 +- lib/util/gitignore.js | 24 +++-- lib/util/has-package.js | 19 ++-- lib/util/import-or-require.js | 2 +- lib/util/json-diff.js | 43 ++++---- lib/util/merge.js | 35 ++++--- lib/util/output.js | 13 ++- lib/util/parser.js | 145 ++++++++++++++------------ lib/util/path.js | 8 +- lib/util/template.js | 20 ++-- test/apply/allow-paths.js | 14 +-- test/apply/dependabot.js | 32 +++--- test/apply/engines.js | 48 ++------- test/apply/esm.js | 2 +- test/apply/files-snapshots.js | 18 ++-- test/apply/index.js | 22 ++-- test/apply/lint.js | 10 +- test/apply/lockfile.js | 4 +- test/apply/merge-yml.js | 23 +--- test/apply/npm-bin.js | 6 +- test/apply/overwrite-false.js | 2 +- test/apply/release-config.js | 17 +-- test/apply/release.js | 6 +- test/apply/source-snapshots.js | 10 +- test/apply/tap.js | 9 +- test/apply/typescript.js | 6 +- test/apply/version.js | 2 +- test/bin/apply.js | 18 ++-- test/bin/check.js | 37 ++++--- test/check/diff-snapshots.js | 19 ++-- test/check/dogfood.js | 2 +- test/check/engines.js | 117 ++++++++++----------- test/check/gitignore.js | 2 +- test/check/index.js | 2 +- test/check/required.js | 14 ++- test/check/snapshots.js | 14 +-- test/check/unwanted.js | 6 +- test/fixtures/header.js | 21 ++-- test/fixtures/json-delete.js | 2 +- test/fixtures/json-merge.js | 2 +- test/fixtures/mock-release.js | 9 +- test/fixtures/yml-merge.js | 18 ++-- test/index.js | 8 +- test/release/changelog.js | 150 +++++++++++++++------------ test/release/release-manager.js | 17 +-- test/release/release-please.js | 21 ++-- test/setup.js | 119 ++++++++++----------- test/util/has-package.js | 5 +- 73 files changed, 928 insertions(+), 1004 deletions(-) diff --git a/bin/apply.js b/bin/apply.js index 2405a3e0..6a7d2f60 100755 --- a/bin/apply.js +++ b/bin/apply.js @@ -3,10 +3,7 @@ const apply = require('../lib/apply/index.js') const main = async () => { - const { - npm_config_global: globalMode, - npm_config_local_prefix: root, - } = process.env + const { npm_config_global: globalMode, npm_config_local_prefix: root } = process.env // do nothing in global mode or when the local prefix isn't set if (globalMode === 'true' || !root) { @@ -16,7 +13,7 @@ const main = async () => { await apply(root) } -module.exports = main().catch((err) => { +module.exports = main().catch(err => { console.error(err.stack) process.exitCode = 1 }) diff --git a/bin/check.js b/bin/check.js index 8b3417cb..d5772946 100755 --- a/bin/check.js +++ b/bin/check.js @@ -4,9 +4,7 @@ const check = require('../lib/check/index.js') const output = require('../lib/util/output.js') const main = async () => { - const { - npm_config_local_prefix: root, - } = process.env + const { npm_config_local_prefix: root } = process.env if (!root) { throw new Error('This package requires npm >7.21.1') @@ -20,7 +18,7 @@ const main = async () => { } } -module.exports = main().catch((err) => { +module.exports = main().catch(err => { console.error(err.stack) process.exitCode = 1 }) diff --git a/bin/release-manager.js b/bin/release-manager.js index 2ab6dcd6..e42c2686 100755 --- a/bin/release-manager.js +++ b/bin/release-manager.js @@ -19,7 +19,7 @@ ReleaseManager.run({ }, }).values, }) - .then((result) => { + .then(result => { core.setOutput('result', result) return null }) diff --git a/bin/release-please.js b/bin/release-please.js index f11a4dc9..a4229e5b 100755 --- a/bin/release-please.js +++ b/bin/release-please.js @@ -18,23 +18,27 @@ ReleasePlease.run({ // `RELEASE_PLEASE_` // (eg`RELEASE_PLEASE_lastReleaseSha=`) to set one-off config items for // the release please run without needing to commit and push the config. - overrides: Object.fromEntries(Object.entries(process.env) - .filter(([k, v]) => k.startsWith('RELEASE_PLEASE_') && v != null) - .map(([k, v]) => [k.replace('RELEASE_PLEASE_', ''), v])), -}).then(({ pr, releases }) => { - if (pr) { - core.setOutput('pr', JSON.stringify(pr)) - core.setOutput('pr-branch', pr.headBranchName) - core.setOutput('pr-number', pr.number) - core.setOutput('pr-sha', pr.sha) - } + overrides: Object.fromEntries( + Object.entries(process.env) + .filter(([k, v]) => k.startsWith('RELEASE_PLEASE_') && v != null) + .map(([k, v]) => [k.replace('RELEASE_PLEASE_', ''), v]), + ), +}) + .then(({ pr, releases }) => { + if (pr) { + core.setOutput('pr', JSON.stringify(pr)) + core.setOutput('pr-branch', pr.headBranchName) + core.setOutput('pr-number', pr.number) + core.setOutput('pr-sha', pr.sha) + } - if (releases) { - core.setOutput('releases', JSON.stringify(releases)) - } + if (releases) { + core.setOutput('releases', JSON.stringify(releases)) + } - return null -}).catch(err => { - core.setFailed('Release Please failed') - core.error(err) -}) + return null + }) + .catch(err => { + core.setFailed('Release Please failed') + core.error(err) + }) diff --git a/lib/apply/apply-files.js b/lib/apply/apply-files.js index 175bbbd8..d656964f 100644 --- a/lib/apply/apply-files.js +++ b/lib/apply/apply-files.js @@ -6,26 +6,21 @@ const run = async (dir, files, options) => { const { rm, add } = files log.verbose('apply-files', 'rm', rm) - await rmEach(dir, rm, options, (f) => fs.rm(f)) + await rmEach(dir, rm, options, f => fs.rm(f)) log.verbose('apply-files', 'add', add) - await parseEach(dir, add, options, {}, (p) => p.applyWrite()) + await parseEach(dir, add, options, {}, p => p.applyWrite()) } -module.exports = [{ - run: (options) => run( - options.config.repoDir, - options.config.repoFiles, - options - ), - when: ({ config: c }) => c.applyRepo && c.needsUpdate, - name: 'apply-repo', -}, { - run: (options) => run( - options.config.moduleDir, - options.config.moduleFiles, - options - ), - when: ({ config: c }) => c.applyModule && c.needsUpdate, - name: 'apply-module', -}] +module.exports = [ + { + run: options => run(options.config.repoDir, options.config.repoFiles, options), + when: ({ config: c }) => c.applyRepo && c.needsUpdate, + name: 'apply-repo', + }, + { + run: options => run(options.config.moduleDir, options.config.moduleFiles, options), + when: ({ config: c }) => c.applyModule && c.needsUpdate, + name: 'apply-module', + }, +] diff --git a/lib/apply/apply-version.js b/lib/apply/apply-version.js index e3bddbdd..d7ebbe8c 100644 --- a/lib/apply/apply-version.js +++ b/lib/apply/apply-version.js @@ -2,11 +2,7 @@ const { log } = require('proc-log') const PackageJson = require('@npmcli/package-json') const run = async ({ config: c }) => { - const { - moduleDir: dir, - __CONFIG_KEY__: key, - __VERSION__: version, - } = c + const { moduleDir: dir, __CONFIG_KEY__: key, __VERSION__: version } = c log.verbose('apply-version', dir) diff --git a/lib/apply/index.js b/lib/apply/index.js index 75e66a43..15e90a12 100644 --- a/lib/apply/index.js +++ b/lib/apply/index.js @@ -1,6 +1,3 @@ const run = require('../index.js') -module.exports = (root) => run(root, [ - require('./apply-files.js'), - require('./apply-version.js'), -]) +module.exports = root => run(root, [require('./apply-files.js'), require('./apply-version.js')]) diff --git a/lib/check/check-apply.js b/lib/check/check-apply.js index 749ca60f..1fb46174 100644 --- a/lib/check/check-apply.js +++ b/lib/check/check-apply.js @@ -8,22 +8,25 @@ const solution = 'npx template-oss-apply --force' const run = async (type, dir, files, options) => { const res = [] - const rel = (f) => relative(options.root, f) + const rel = f => relative(options.root, f) const { add: addFiles, rm: rmFiles } = files - const rm = await rmEach(dir, rmFiles, options, (f) => rel(f)) - const [add, update] = partition(await parseEach(dir, addFiles, options, {}, async (p) => { - const diff = await p.applyDiff() - const target = rel(p.target) - if (diff === null) { - // needs to be added - return target - } else if (diff === true) { - // its ok, no diff, this is filtered out - return null - } - return { file: target, diff } - }), (d) => typeof d === 'string') + const rm = await rmEach(dir, rmFiles, options, f => rel(f)) + const [add, update] = partition( + await parseEach(dir, addFiles, options, {}, async p => { + const diff = await p.applyDiff() + const target = rel(p.target) + if (diff === null) { + // needs to be added + return target + } else if (diff === true) { + // its ok, no diff, this is filtered out + return null + } + return { file: target, diff } + }), + d => typeof d === 'string', + ) log.verbose('check-apply', 'rm', rm) if (rm.length) { @@ -44,31 +47,28 @@ const run = async (type, dir, files, options) => { } log.verbose('check-apply', 'update', update) - res.push(...update.sort((a, b) => localeCompare(a.file, b.file)).map(({ file, diff }) => ({ - title: `The ${type} file ${basename(file)} needs to be updated:`, - body: [`${file}\n${'='.repeat(40)}\n${diff}`], - solution, - }))) + res.push( + ...update + .sort((a, b) => localeCompare(a.file, b.file)) + .map(({ file, diff }) => ({ + title: `The ${type} file ${basename(file)} needs to be updated:`, + body: [`${file}\n${'='.repeat(40)}\n${diff}`], + solution, + })), + ) return res } -module.exports = [{ - run: (options) => run( - 'repo', - options.config.repoDir, - options.config.repoFiles, - options - ), - when: ({ config: c }) => c.applyRepo, - name: 'check-repo', -}, { - run: (options) => run( - 'module', - options.config.moduleDir, - options.config.moduleFiles, - options - ), - when: ({ config: c }) => c.applyModule, - name: 'check-module', -}] +module.exports = [ + { + run: options => run('repo', options.config.repoDir, options.config.repoFiles, options), + when: ({ config: c }) => c.applyRepo, + name: 'check-repo', + }, + { + run: options => run('module', options.config.moduleDir, options.config.moduleFiles, options), + when: ({ config: c }) => c.applyModule, + name: 'check-module', + }, +] diff --git a/lib/check/check-changelog.js b/lib/check/check-changelog.js index 11053aec..cae54f29 100644 --- a/lib/check/check-changelog.js +++ b/lib/check/check-changelog.js @@ -14,10 +14,7 @@ const run = async ({ root, path }) => { if (!mustStart.test(content)) { return { title: `The ${relative(root, changelog)} is incorrect:`, - body: [ - 'The changelog should start with', - `"# Changelog\n\n#"`, - ], + body: ['The changelog should start with', `"# Changelog\n\n#"`], solution: 'reformat the changelog to have the correct heading', } } diff --git a/lib/check/check-engines.js b/lib/check/check-engines.js index 4a2a0ad5..2a863074 100644 --- a/lib/check/check-engines.js +++ b/lib/check/check-engines.js @@ -27,15 +27,14 @@ const run = async ({ root, path, pkg, config: { omitEngines = [] } }) => { } if (invalid.length) { - const title = `The following production dependencies are not compatible with ` + + const title = + `The following production dependencies are not compatible with ` + `\`engines.node: ${engines}\` found in \`${pkgPath}\`:` return { title, - body: invalid.map((dep) => [ - `${dep.name}:`, - ` engines.node: ${dep.engines}`, - ` location: ${dep.location}`, - ].join('\n')).join('\n'), + body: invalid + .map(dep => [`${dep.name}:`, ` engines.node: ${dep.engines}`, ` location: ${dep.location}`].join('\n')) + .join('\n'), solution: 'Remove them or move them to devDependencies.', } } diff --git a/lib/check/check-gitignore.js b/lib/check/check-gitignore.js index e22cc361..9868e370 100644 --- a/lib/check/check-gitignore.js +++ b/lib/check/check-gitignore.js @@ -13,34 +13,34 @@ const NAME = 'check-gitignore' const run = async ({ root, path, config }) => { log.verbose(NAME, { root, path }) - const relativeToRoot = (f) => relative(root, resolve(path, f)) + const relativeToRoot = f => relative(root, resolve(path, f)) // use the root to detect a git repo but the project directory (path) for the // ignore check const ignoreFile = resolve(path, '.gitignore') - if (!await git.is({ cwd: root }) || !existsSync(ignoreFile)) { + if (!(await git.is({ cwd: root })) || !existsSync(ignoreFile)) { log.verbose(NAME, 'no git or no gitignore') return null } log.verbose(NAME, `using ignore file ${ignoreFile}`) - const res = await git.spawn([ - 'ls-files', - '--cached', - '--ignored', - // https://git-scm.com/docs/git-ls-files#_exclude_patterns - `--${config.isRoot ? 'exclude-from' : 'exclude-per-directory'}=${basename(ignoreFile)}`, - ], { cwd: path }) + const res = await git.spawn( + [ + 'ls-files', + '--cached', + '--ignored', + // https://git-scm.com/docs/git-ls-files#_exclude_patterns + `--${config.isRoot ? 'exclude-from' : 'exclude-per-directory'}=${basename(ignoreFile)}`, + ], + { cwd: path }, + ) log.verbose(NAME, 'ls-files', res) // TODO: files should be filtered if they have already been moved/deleted // but not committed. Currently you must commit for this check to pass. - const files = res.stdout - .trim() - .split('\n') - .filter(Boolean) + const files = res.stdout.trim().split('\n').filter(Boolean) if (!files.length) { return null @@ -49,7 +49,7 @@ const run = async ({ root, path, config }) => { const ignores = (await fs.readFile(ignoreFile)) .toString() .split(/\r?\n/) - .filter((l) => l && !l.trim().startsWith('#')) + .filter(l => l && !l.trim().startsWith('#')) const relIgnore = relativeToRoot(ignoreFile) diff --git a/lib/check/check-required.js b/lib/check/check-required.js index 9f04ef9f..781f5b45 100644 --- a/lib/check/check-required.js +++ b/lib/check/check-required.js @@ -3,25 +3,21 @@ const npa = require('npm-package-arg') const { partition } = require('lodash') const hasPackage = require('../util/has-package.js') -const rmCommand = (specs) => - `npm rm ${specs.map((s) => s.name).join(' ')}`.trim() +const rmCommand = specs => `npm rm ${specs.map(s => s.name).join(' ')}`.trim() -const installCommand = (specs, flags) => specs.length ? - `npm i ${specs.map((s) => `${s.name}@${s.fetchSpec}`).join(' ')} ${flags.join(' ')}`.trim() : '' +const installCommand = (specs, flags) => + specs.length ? `npm i ${specs.map(s => `${s.name}@${s.fetchSpec}`).join(' ')} ${flags.join(' ')}`.trim() : '' // ensure required packages are present in the correct place const run = ({ pkg, path, config: { requiredPackages = {} } }) => { // keys are the dependency location in package.json // values are a filtered list of parsed specs that dont exist in the current package // { [location]: [spec1, spec2] } - const requiredByLocation = Object.entries(requiredPackages) - .reduce((acc, [location, pkgs]) => { - acc[location] = pkgs - .filter((spec) => !hasPackage(pkg, spec, [location], path)) - .map((spec) => npa(spec)) - log.verbose(location, pkg, pkgs) - return acc - }, {}) + const requiredByLocation = Object.entries(requiredPackages).reduce((acc, [location, pkgs]) => { + acc[location] = pkgs.filter(spec => !hasPackage(pkg, spec, [location], path)).map(spec => npa(spec)) + log.verbose(location, pkg, pkgs) + return acc + }, {}) const requiredEntries = Object.entries(requiredByLocation) @@ -30,19 +26,21 @@ const run = ({ pkg, path, config: { requiredPackages = {} } }) => { if (requiredEntries.flatMap(([, specs]) => specs).length) { return requiredEntries.map(([location, specs]) => { const locationFlag = hasPackage.flags[location] - const [exactSpecs, saveSpecs] = partition(specs, (s) => s.type === 'version') + const [exactSpecs, saveSpecs] = partition(specs, s => s.type === 'version') log.verbose('check-required', location, specs) return { title: `The following required ${location} were not found:`, - body: specs.map((s) => s.rawSpec === '*' ? s.name : `${s.name}@${s.rawSpec}`), + body: specs.map(s => (s.rawSpec === '*' ? s.name : `${s.name}@${s.rawSpec}`)), // solution is to remove any existing all at once but add back in by --save- solution: [ rmCommand(specs), installCommand(saveSpecs, [locationFlag]), installCommand(exactSpecs, [locationFlag, '--save-exact']), - ].filter(Boolean).join(' && '), + ] + .filter(Boolean) + .join(' && '), } }) } diff --git a/lib/check/check-unwanted.js b/lib/check/check-unwanted.js index 13eb27fb..9b838628 100644 --- a/lib/check/check-unwanted.js +++ b/lib/check/check-unwanted.js @@ -1,11 +1,10 @@ - const hasPackage = require('../util/has-package.js') const run = ({ pkg, config: { allowedPackages = [], unwantedPackages = [] } }) => { // ensure packages that should not be present are removed const hasUnwanted = unwantedPackages - .filter((name) => !allowedPackages.includes(name)) - .filter((name) => hasPackage(pkg, name)) + .filter(name => !allowedPackages.includes(name)) + .filter(name => hasPackage(pkg, name)) if (hasUnwanted.length) { return { diff --git a/lib/check/index.js b/lib/check/index.js index 9310099c..ab7e03d4 100644 --- a/lib/check/index.js +++ b/lib/check/index.js @@ -1,10 +1,11 @@ const run = require('../index.js') -module.exports = (root) => run(root, [ - require('./check-apply.js'), - require('./check-required.js'), - require('./check-unwanted.js'), - require('./check-gitignore.js'), - require('./check-changelog.js'), - require('./check-engines.js'), -]) +module.exports = root => + run(root, [ + require('./check-apply.js'), + require('./check-required.js'), + require('./check-unwanted.js'), + require('./check-gitignore.js'), + require('./check-changelog.js'), + require('./check-engines.js'), + ]) diff --git a/lib/config.js b/lib/config.js index a1d6fd0a..86ad9fb4 100644 --- a/lib/config.js +++ b/lib/config.js @@ -16,7 +16,7 @@ const { name: NAME, version: LATEST_VERSION } = require('../package.json') const CONFIG_KEY = 'templateOSS' const MERGE_KEYS = [...FILE_KEYS, 'defaultContent', 'content'] const DEFAULT_CONTENT = require.resolve(NAME) -const getPkgConfig = (pkg) => pkg[CONFIG_KEY] || {} +const getPkgConfig = pkg => pkg[CONFIG_KEY] || {} const merge = mergeWithCustomizers( customizers.mergeArrays( @@ -27,13 +27,13 @@ const merge = mergeWithCustomizers( 'lintIgnorePaths', 'lintExtensions', 'formatIgnorePaths', - 'formatExtensions' + 'formatExtensions', ), (value, srcValue, key) => { if (key === 'ciVersions' && (Array.isArray(srcValue) || isPlainObject(srcValue))) { return { ...ciVersions.parse(value), ...ciVersions.parse(srcValue) } } - } + }, ) const mergeConfigs = (...configs) => { @@ -48,7 +48,7 @@ const mergeConfigs = (...configs) => { }) } -const readContentPath = async (path) => { +const readContentPath = async path => { if (!path) { return {} } @@ -71,10 +71,7 @@ const getFiles = async (path, rawConfig, templateSettings) => { if (!dir) { return [] } - return [ - parseFiles(pick(content, FILE_KEYS), dir, pick(rawConfig, FILE_KEYS), templateSettings), - dir, - ] + return [parseFiles(pick(content, FILE_KEYS), dir, pick(rawConfig, FILE_KEYS), templateSettings), dir] } const getFullConfig = async ({ @@ -124,13 +121,11 @@ const getFullConfig = async ({ const publicPkgs = pkgs.filter(p => !p.pkgJson.private) const allPrivate = pkgs.every(p => p.pkgJson.private) - const branches = uniq([...pkgConfig.branches ?? [], pkgConfig.releaseBranch]).filter(Boolean) + const branches = uniq([...(pkgConfig.branches ?? []), pkgConfig.releaseBranch]).filter(Boolean) const gitBranches = await git.getBranches(rootPkg.path, branches) - const defaultBranch = await git.defaultBranch(rootPkg.path) ?? 'main' + const defaultBranch = (await git.defaultBranch(rootPkg.path)) ?? 'main' const isReleaseBranch = !!pkgConfig.backport - const releaseBranch = isReleaseBranch - ? pkgConfig.releaseBranch.replace(/\*/g, pkgConfig.backport) - : defaultBranch + const releaseBranch = isReleaseBranch ? pkgConfig.releaseBranch.replace(/\*/g, pkgConfig.backport) : defaultBranch const esm = pkg.pkgJson?.type === 'module' || !!pkgConfig.typescript || !!pkgConfig.esm @@ -201,8 +196,9 @@ const getFullConfig = async ({ } if (!pkgConfig.eslint && Array.isArray(pkgConfig.requiredPackages?.devDependencies)) { - pkgConfig.requiredPackages.devDependencies = - pkgConfig.requiredPackages.devDependencies.filter(p => !p.includes('eslint')) + pkgConfig.requiredPackages.devDependencies = pkgConfig.requiredPackages.devDependencies.filter( + p => !p.includes('eslint'), + ) } pkgConfig.lintIgnorePaths = [ @@ -229,7 +225,7 @@ const getFullConfig = async ({ 'typescript', 'tshy', '@typescript-eslint/parser', - ...derived.tap16 ? ['c8', 'ts-node'] : [], + ...(derived.tap16 ? ['c8', 'ts-node'] : []), ]) } @@ -280,13 +276,13 @@ const getFullConfig = async ({ ...getAddedFiles(moduleFiles).map(s => template(s, fullConfig)), ...(isRoot ? [ - // in the root allow all repo files - ...getAddedFiles(repoFiles).map(s => template(s, fullConfig)), - // and allow all workspace repo level files in the root - ...pkgs - .filter(p => p.path !== rootPkg.path && p.config.workspaceRepo !== false) - .flatMap(() => getAddedFiles(files.workspaceRepo)), - ] + // in the root allow all repo files + ...getAddedFiles(repoFiles).map(s => template(s, fullConfig)), + // and allow all workspace repo level files in the root + ...pkgs + .filter(p => p.path !== rootPkg.path && p.config.workspaceRepo !== false) + .flatMap(() => getAddedFiles(files.workspaceRepo)), + ] : []), ]), ...(isRoot && pkgConfig.lockfile ? ['!/package-lock.json'] : []), @@ -317,10 +313,8 @@ const getFullConfig = async ({ ]), // these cant be sorted since they rely on order // to allow a previously ignored directoy - ...isRoot - ? gitignore.allowDir(wsPkgs.map((p) => makePosix(relative(rootPkg.path, p.path)))) - : [], - ].filter(p => !pkgConfig.eslint ? !p.includes('eslint') : true), + ...(isRoot ? gitignore.allowDir(wsPkgs.map(p => makePosix(relative(rootPkg.path, p.path)))) : []), + ].filter(p => (!pkgConfig.eslint ? !p.includes('eslint') : true)), }) return fullConfig diff --git a/lib/content/index.js b/lib/content/index.js index f4f68e8a..4100bb7b 100644 --- a/lib/content/index.js +++ b/lib/content/index.js @@ -1,8 +1,8 @@ const { name: NAME, version: LATEST_VERSION } = require('../../package.json') -const isPublic = (p) => p.config.isPublic +const isPublic = p => p.config.isPublic -const sharedRootAdd = (name) => ({ +const sharedRootAdd = name => ({ // release '.github/workflows/release.yml': { file: 'release-yml.hbs', @@ -19,17 +19,17 @@ const sharedRootAdd = (name) => ({ '.release-please-manifest.json': { file: 'release-please-manifest-json.hbs', filter: isPublic, - parser: (p) => p.JsonMergeNoComment, + parser: p => p.JsonMergeNoComment, }, 'release-please-config.json': { file: 'release-please-config-json.hbs', filter: isPublic, - parser: (p) => p.JsonMergeNoComment, + parser: p => p.JsonMergeNoComment, }, 'tsconfig.json': { file: 'tsconfig-json.hbs', - filter: (p) => p.config.typescript, - parser: (p) => p.JsonMergeNoComment, + filter: p => p.config.typescript, + parser: p => p.JsonMergeNoComment, }, // this lint commits which is only necessary for releases '.github/workflows/pull-request.yml': { @@ -42,15 +42,15 @@ const sharedRootAdd = (name) => ({ // dependabot '.github/dependabot.yml': { file: 'dependabot-yml.hbs', - filter: (p) => p.config.dependabot, + filter: p => p.config.dependabot, }, '.github/workflows/post-dependabot.yml': { file: 'post-dependabot-yml.hbs', - filter: (p) => p.config.dependabot, + filter: p => p.config.dependabot, }, '.github/settings.yml': { file: 'settings-yml.hbs', - filter: (p) => !p.config.isReleaseBranch, + filter: p => !p.config.isReleaseBranch, }, // composite actions '.github/actions/install-latest-npm/action.yml': 'action-install-latest-npm-yml.hbs', @@ -59,10 +59,10 @@ const sharedRootAdd = (name) => ({ const sharedRootRm = () => ({ '.github/workflows/pull-request.yml': { - filter: (p) => p.config.allPrivate, + filter: p => p.config.allPrivate, }, '.github/settings.yml': { - filter: (p) => p.config.isReleaseBranch, + filter: p => p.config.isReleaseBranch, }, }) @@ -94,15 +94,15 @@ const rootModule = { add: { '.eslintrc.{{ cjsExt }}': { file: 'eslintrc-js.hbs', - filter: (p) => p.config.eslint, + filter: p => p.config.eslint, }, '.prettierrc.{{ cjsExt }}': { file: 'prettier-js.hbs', - filter: (p) => p.config.prettier, + filter: p => p.config.prettier, }, '.prettierignore': { file: 'prettierignore.hbs', - filter: (p) => p.config.prettier, + filter: p => p.config.prettier, }, '.gitignore': 'gitignore.hbs', '.npmrc': 'npmrc.hbs', @@ -111,9 +111,7 @@ const rootModule = { 'CONTRIBUTING.md': 'CONTRIBUTING-md.hbs', 'package.json': 'package-json.hbs', }, - rm: [ - '.eslintrc.!({{ cjsExt }}|local.*)', - ], + rm: ['.eslintrc.!({{ cjsExt }}|local.*)'], } // Changes for each workspace but applied to the root of the repo @@ -133,16 +131,12 @@ const workspaceModule = { add: { '.eslintrc.{{ cjsExt }}': { file: 'eslintrc-js.hbs', - filter: (p) => p.config.eslint, + filter: p => p.config.eslint, }, '.gitignore': 'gitignore.hbs', 'package.json': 'package-json.hbs', }, - rm: [ - '.npmrc', - '.eslintrc.!({{ cjsExt }}|local.*)', - 'SECURITY.md', - ], + rm: ['.npmrc', '.eslintrc.!({{ cjsExt }}|local.*)', 'SECURITY.md'], } module.exports = { @@ -159,10 +153,7 @@ module.exports = { // {{major}} to have the major version being published replaced in the string. defaultPublishTag: 'latest', releaseBranch: 'release/v*', - distPaths: [ - 'bin/', - 'lib/', - ], + distPaths: ['bin/', 'lib/'], allowDistPaths: true, allowPaths: [ '/.eslintrc.local.*', @@ -205,11 +196,7 @@ module.exports = { 'standard', ], requiredPackages: { - devDependencies: [ - `${NAME}@${LATEST_VERSION}`, - '@npmcli/eslint-config', - 'tap', - ], + devDependencies: [`${NAME}@${LATEST_VERSION}`, '@npmcli/eslint-config', 'tap'], }, allowedPackages: [], changelogTypes: [ diff --git a/lib/index.js b/lib/index.js index a1e01bc2..c43d1ba9 100644 --- a/lib/index.js +++ b/lib/index.js @@ -4,7 +4,7 @@ const getConfig = require('./config.js') const PackageJson = require('@npmcli/package-json') const mapWorkspaces = require('@npmcli/map-workspaces') -const getPkg = async (path) => { +const getPkg = async path => { log.verbose('get-pkg', path) const pkgJson = (await PackageJson.load(path)).content @@ -27,7 +27,7 @@ const getWsPkgs = async (root, rootPkg) => { // Include all by default const { workspaces } = rootPkg.config - const include = (name) => Array.isArray(workspaces) ? workspaces.includes(name) : true + const include = name => (Array.isArray(workspaces) ? workspaces.includes(name) : true) // Look through all workspaces on the root pkg const rootWorkspaces = await mapWorkspaces({ pkg: rootPkg.pkgJson, cwd: root }) @@ -43,7 +43,7 @@ const getWsPkgs = async (root, rootPkg) => { return wsPkgs } -const getPkgs = async (root) => { +const getPkgs = async root => { log.verbose('get-pkgs', 'root', root) const rootPkg = await getPkg(root) diff --git a/lib/release/changelog.js b/lib/release/changelog.js index 8358e6c2..9ee059a7 100644 --- a/lib/release/changelog.js +++ b/lib/release/changelog.js @@ -11,7 +11,7 @@ class Changelog { [Changelog.BREAKING]: '⚠️ BREAKING CHANGES', } - constructor ({ version, url, sections }) { + constructor({ version, url, sections }) { this.#title = `## ${url ? link(version, url) : version} (${formatDate()})` for (const section of sections) { this.#types.add(section.type) @@ -20,7 +20,7 @@ class Changelog { } } - add (type, ...entries) { + add(type, ...entries) { if (!this.#types.has(type) || !entries.length) { return } @@ -28,11 +28,11 @@ class Changelog { this.#entries[type].push(...entries) } - #getEntries (type) { + #getEntries(type) { return this.#entries[type].map(list).join('\n') } - toString () { + toString() { const body = [this.#title] const includedTypes = [] @@ -47,7 +47,7 @@ class Changelog { // empty string which will skip the release PR being created. // We do this because we don't want PRs opened if they only contain // chores but we do want to rebuild existing PRs if chores are added. - if (includedTypes.every((type) => this.#sections[type]?.hidden)) { + if (includedTypes.every(type => this.#sections[type]?.hidden)) { return '' } @@ -62,7 +62,7 @@ class ChangelogNotes { #graphql #ghUrl - constructor (github) { + constructor(github) { this.#owner = github.repository.owner this.#repo = github.repository.repo this.#rest = github.octokit.rest @@ -70,7 +70,7 @@ class ChangelogNotes { this.#ghUrl = makeGitHubUrl(this.#owner, this.#repo) } - async #getAuthorsForCommits (commits) { + async #getAuthorsForCommits(commits) { const shas = commits .filter(c => c.type !== 'deps') .map(c => c.sha) @@ -82,7 +82,7 @@ class ChangelogNotes { const authorsByCommit = {} const { repository } = await this.#graphql( - `fragment CommitAuthors on GitObject { + `fragment CommitAuthors on GitObject { ... on Commit { authors (first:10) { nodes { @@ -94,23 +94,23 @@ class ChangelogNotes { } query { repository (owner:"${this.#owner}", name:"${this.#repo}") { - ${shas.map((s) => { + ${shas.map(s => { return `_${s}: object (expression: "${s}") { ...CommitAuthors }` })} } - }` + }`, ) for (const [key, commit] of Object.entries(repository)) { if (commit) { authorsByCommit[key.slice(1)] = commit.authors.nodes - .map((a) => a.user && a.user.login ? `@${a.user.login}` : a.name) + .map(a => (a.user && a.user.login ? `@${a.user.login}` : a.name)) .filter(Boolean) } } return authorsByCommit } - async #getPullRequestNumbersForCommits (commits) { + async #getPullRequestNumbersForCommits(commits) { const shas = commits .filter(c => !c.pullRequest?.number) .map(c => c.sha) @@ -122,19 +122,20 @@ class ChangelogNotes { const pullRequestsByCommit = {} for (const sha of shas) { - pullRequestsByCommit[sha] = await this.#rest.repos.listPullRequestsAssociatedWithCommit({ - owner: this.#owner, - repo: this.#repo, - commit_sha: sha, - per_page: 1, - }) - .then((r) => r.data[0].number) + pullRequestsByCommit[sha] = await this.#rest.repos + .listPullRequestsAssociatedWithCommit({ + owner: this.#owner, + repo: this.#repo, + commit_sha: sha, + per_page: 1, + }) + .then(r => r.data[0].number) .catch(() => null) } return pullRequestsByCommit } - #buildEntry (commit) { + #buildEntry(commit) { const entry = [] if (commit.sha) { @@ -161,7 +162,7 @@ class ChangelogNotes { return entry.join(' ') } - #filterCommits (commits) { + #filterCommits(commits) { const filteredCommits = [] const keyedDuplicates = {} @@ -186,8 +187,8 @@ class ChangelogNotes { // Sort all our duplicates so we get the latest verion (by PR number) of each type. // Then flatten so we can put them all back into the changelog const sortedDupes = Object.values(keyedDuplicates) - .filter((items) => Boolean(items.length)) - .map((items) => items.sort((a, b) => b.pullRequestNumber - a.pullRequestNumber)) + .filter(items => Boolean(items.length)) + .map(items => items.sort((a, b) => b.pullRequestNumber - a.pullRequestNumber)) .flatMap(items => items[0]) // This moves them to the bottom of their changelog section which is not @@ -199,7 +200,7 @@ class ChangelogNotes { return filteredCommits } - async buildNotes (rawCommits, { version, previousTag, currentTag, changelogSections }) { + async buildNotes(rawCommits, { version, previousTag, currentTag, changelogSections }) { // get authors for commits for each sha const authors = await this.#getAuthorsForCommits(rawCommits) @@ -208,7 +209,7 @@ class ChangelogNotes { // lookup commits without a pr number and find one if it exists const prNumbers = await this.#getPullRequestNumbersForCommits(rawCommits) - const fullCommits = rawCommits.map((commit) => { + const fullCommits = rawCommits.map(commit => { commit.authors = authors[commit.sha] ?? [] commit.pullRequestNumber = Number(commit.pullRequest?.number ?? prNumbers[commit.sha]) return commit @@ -216,9 +217,7 @@ class ChangelogNotes { const changelog = new Changelog({ version, - url: previousTag - ? this.#ghUrl('compare', `${previousTag.toString()}...${currentTag.toString()}`) - : null, + url: previousTag ? this.#ghUrl('compare', `${previousTag.toString()}...${currentTag.toString()}`) : null, sections: changelogSections, }) @@ -227,9 +226,7 @@ class ChangelogNotes { changelog.add(commit.type, this.#buildEntry(commit)) // And breaking changes to its own section - changelog.add(Changelog.BREAKING, ...commit.notes - .filter(n => n.title === 'BREAKING CHANGE') - .map(n => n.text)) + changelog.add(Changelog.BREAKING, ...commit.notes.filter(n => n.title === 'BREAKING CHANGE').map(n => n.text)) } return changelog.toString() diff --git a/lib/release/node-workspace-format.js b/lib/release/node-workspace-format.js index 57135d1a..78a86be9 100644 --- a/lib/release/node-workspace-format.js +++ b/lib/release/node-workspace-format.js @@ -12,7 +12,7 @@ module.exports = class extends ManifestPlugin { #releasesByPackage = new Map() #pathsByComponent = new Map() - async preconfigure (strategiesByPath) { + async preconfigure(strategiesByPath) { // First build a list of all releases that will happen based on // the conventional commits for (const path in strategiesByPath) { @@ -25,17 +25,19 @@ module.exports = class extends ManifestPlugin { return strategiesByPath } - run (candidates) { + run(candidates) { this.#rewriteWorkspaceChangelogItems(candidates) this.#sortReleases(candidates) return candidates } - #replaceWorkspace ({ name, versionRange }) { + #replaceWorkspace({ name, versionRange }) { const version = versionRange.replace(/^[\^~]/, '') const { path, component } = this.#releasesByPackage.get(name) const { tagSeparator, includeVInTag } = this.repositoryConfig[path] - const { repository: { owner, repo } } = this.github + const { + repository: { owner, repo }, + } = this.github const tag = new TagName(version, component, tagSeparator, includeVInTag).toString() const url = `https://github.com/${owner}/${repo}/releases/tag/${tag}` return list(`${link('workspace', url)}: ${wrapSpecs(`${name}@${version}`)}`) @@ -46,7 +48,7 @@ module.exports = class extends ManifestPlugin { // be part of the changelog plugin since they are written after that by the // node-workspace plugin. A possible PR to release-please could add an option // to customize these or run them through the changelog notes generator. - #rewriteWorkspaceChangelogItems (candidates) { + #rewriteWorkspaceChangelogItems(candidates) { for (const candidate of candidates) { for (const release of candidate.pullRequest.body.releaseData) { // Update notes with a link to each workspaces release notes @@ -57,13 +59,11 @@ module.exports = class extends ManifestPlugin { .replace(/^\s{2}\* devDependencies\n/gm, '') .replace(/^\s{2}\* peerDependencies\n/gm, '') .replace(/^\s{2}\* optionalDependencies\n/gm, '') - .replace( - /^\s{4}\* (?[^\s]+) bumped to (?[^\s]+)/gm, - (...args) => this.#replaceWorkspace(args.at(-1)) + .replace(/^\s{4}\* (?[^\s]+) bumped to (?[^\s]+)/gm, (...args) => + this.#replaceWorkspace(args.at(-1)), ) - .replace( - /^\s{4}\* (?[^\s]+) bumped from (?:[^\s]+) to (?[^\s]+)/gm, - (...args) => this.#replaceWorkspace(args.at(-1)) + .replace(/^\s{4}\* (?[^\s]+) bumped from (?:[^\s]+) to (?[^\s]+)/gm, (...args) => + this.#replaceWorkspace(args.at(-1)), ) // Find the associated changelog and update that too @@ -79,7 +79,7 @@ module.exports = class extends ManifestPlugin { // Sort root release to the top of the pull request // release please pre sorts based on graph order so - #sortReleases (candidates) { + #sortReleases(candidates) { for (const candidate of candidates) { candidate.pullRequest.body.releaseData.sort((a, b) => { const aPath = this.#pathsByComponent.get(a.component) diff --git a/lib/release/release-manager.js b/lib/release/release-manager.js index 69e58ee8..91b673a9 100644 --- a/lib/release/release-manager.js +++ b/lib/release/release-manager.js @@ -21,17 +21,7 @@ class ReleaseManager { #info - constructor ({ - token, - repo, - cwd = process.cwd(), - pr, - backport, - defaultTag, - lockfile, - publish, - silent, - }) { + constructor({ token, repo, cwd = process.cwd(), pr, backport, defaultTag, lockfile, publish, silent }) { assert(token, 'GITHUB_TOKEN is required') assert(repo, 'GITHUB_REPOSITORY is required') assert(cwd, 'cwd is required') @@ -51,12 +41,12 @@ class ReleaseManager { this.#info = silent ? noop : core.info } - static async run (options) { + static async run(options) { const manager = new ReleaseManager(options) return manager.run() } - async run () { + async run() { const { data: pullRequest } = await this.#octokit.rest.pulls.get({ owner: this.#owner, repo: this.#repo, @@ -84,51 +74,55 @@ class ReleaseManager { return `### Release Checklist for ${release.tag}\n\n${checklist}` } - async #getPrReleases ({ pullRequest }) { + async #getPrReleases({ pullRequest }) { return /
.*<\/summary>/.test(pullRequest.body) ? await this.#getPrMonoRepoReleases({ pullRequest }) : [this.#getPrRootRelease({ pullRequest }), []] } - async #getPrMonoRepoReleases ({ pullRequest }) { + async #getPrMonoRepoReleases({ pullRequest }) { const releases = pullRequest.body.match(/
.*<\/summary>/g) this.#info(`Found ${releases.length} releases`) - const workspacesComponents = [...await mapWorkspaces({ - cwd: this.#cwd, - pkg: require(join(this.#cwd, 'package.json')), - })] - .reduce((acc, [k]) => { - const wsComponentName = k.startsWith('@') ? k.split('/')[1] : k - acc[wsComponentName] = k - return acc - }, {}) + const workspacesComponents = [ + ...(await mapWorkspaces({ + cwd: this.#cwd, + pkg: require(join(this.#cwd, 'package.json')), + })), + ].reduce((acc, [k]) => { + const wsComponentName = k.startsWith('@') ? k.split('/')[1] : k + acc[wsComponentName] = k + return acc + }, {}) const MONO_VERSIONS = /
(?:(.*?):\s)?(.*?)<\/summary>/ - return releases.reduce((acc, r) => { - const [, name, version] = r.match(MONO_VERSIONS) + return releases.reduce( + (acc, r) => { + const [, name, version] = r.match(MONO_VERSIONS) - const release = this.#getPrReleaseInfo({ - pullRequest, - name, - version, - workspaces: workspacesComponents, - }) + const release = this.#getPrReleaseInfo({ + pullRequest, + name, + version, + workspaces: workspacesComponents, + }) - if (release.isRoot) { - this.#info(`Found root: ${JSON.stringify(release)}`) - acc[0] = release - } else { - this.#info(`Found workspace: ${JSON.stringify(release)}`) - acc[1].push(release) - } + if (release.isRoot) { + this.#info(`Found root: ${JSON.stringify(release)}`) + acc[0] = release + } else { + this.#info(`Found workspace: ${JSON.stringify(release)}`) + acc[1].push(release) + } - return acc - }, [null, []]) + return acc + }, + [null, []], + ) } - #getPrRootRelease ({ pullRequest }) { + #getPrRootRelease({ pullRequest }) { this.#info('Found no monorepo, checking for single root version') const match = pullRequest.body.match(/\n##\s\[(.*?)\]/) @@ -140,7 +134,7 @@ class ReleaseManager { return this.#getPrReleaseInfo({ pullRequest, version }) } - #getPrReleaseInfo ({ pullRequest, workspaces = {}, name = null, version: rawVersion }) { + #getPrReleaseInfo({ pullRequest, workspaces = {}, name = null, version: rawVersion }) { const version = semver.parse(rawVersion) const prerelease = !!version.prerelease.length const tag = `${name ? `${name}-` : ''}v${rawVersion}` @@ -156,51 +150,47 @@ class ReleaseManager { version: rawVersion, major: version.major, url: `https://github.com/${pullRequest.base.repo.full_name}/releases/tag/${tag}`, - flags: [ - workspaces[name] ? `-w ${workspaces[name]}` : null, - `--tag=${publishTag}`, - ].filter(Boolean).join(' '), + flags: [workspaces[name] ? `-w ${workspaces[name]}` : null, `--tag=${publishTag}`].filter(Boolean).join(' '), } } - async #getReleaseProcess ({ release, workspaces }) { + async #getReleaseProcess({ release, workspaces }) { const RELEASE_LIST_ITEM = /^\d+\.\s/gm this.#info(`Fetching release process from repo wiki: ${this.#owner}/${this.#repo}`) const releaseProcess = await fetch( - `https://raw.githubusercontent.com/wiki/${this.#owner}/${this.#repo}/Release-Process.md` - ) - .then(r => { - // If the url fails with anything but a 404 we want the process to blow - // up because that means something is very wrong. This is a rare edge - // case that isn't worth testing. - /* istanbul ignore else */ - if (r.statusCode === 200) { - this.#info('Found release process from wiki') - return r.body.text() - } else if (r.statusCode === 404) { - this.#info('No release process found in wiki, falling back to default process') - return this.#getReleaseSteps() - } else { - throw new Error(`Release process fetch failed with status: ${r.statusCode}`) - } - }) + `https://raw.githubusercontent.com/wiki/${this.#owner}/${this.#repo}/Release-Process.md`, + ).then(r => { + // If the url fails with anything but a 404 we want the process to blow + // up because that means something is very wrong. This is a rare edge + // case that isn't worth testing. + /* istanbul ignore else */ + if (r.statusCode === 200) { + this.#info('Found release process from wiki') + return r.body.text() + } else if (r.statusCode === 404) { + this.#info('No release process found in wiki, falling back to default process') + return this.#getReleaseSteps() + } else { + throw new Error(`Release process fetch failed with status: ${r.statusCode}`) + } + }) // XXX: the release steps need to always be the last thing in the doc for this to work const releaseLines = releaseProcess.split('\n') - const releaseStartLine = releaseLines.reduce((acc, l, i) => l.match(/^#+\s/) ? i : acc, 0) + const releaseStartLine = releaseLines.reduce((acc, l, i) => (l.match(/^#+\s/) ? i : acc), 0) const section = releaseLines.slice(releaseStartLine).join('\n') return section .split({ - [Symbol.split]: (str) => { + [Symbol.split]: str => { const [, ...matches] = str.split(RELEASE_LIST_ITEM) this.#info(`Found ${matches.length} release items`) - return matches.map((m) => `- [ ] . ${m}`.trim()) + return matches.map(m => `- [ ] . ${m}`.trim()) }, }) - .filter((item) => { + .filter(item => { if (release.prerelease && item.includes('> NOT FOR PRERELEASE')) { return false } @@ -214,7 +204,7 @@ class ReleaseManager { .map((item, index) => item.replace('', index + 1)) } - #getReleaseSteps () { + #getReleaseSteps() { const R = `-R ${this.#owner}/${this.#repo}` const manualSteps = ` @@ -275,12 +265,7 @@ class ReleaseManager { ` /* eslint-enable max-len */ - return [ - this.#publish ? autoSteps : manualSteps, - alwaysSteps, - ] - .map(v => dedent(v)) - .join('\n\n') + return [this.#publish ? autoSteps : manualSteps, alwaysSteps].map(v => dedent(v)).join('\n\n') } } diff --git a/lib/release/release-please.js b/lib/release/release-please.js index 96811c2b..d4b515da 100644 --- a/lib/release/release-please.js +++ b/lib/release/release-please.js @@ -1,10 +1,6 @@ const RP = require('release-please') -const { - DefaultVersioningStrategy, -} = require('release-please/build/src/versioning-strategies/default.js') -const { - PrereleaseVersioningStrategy, -} = require('release-please/build/src/versioning-strategies/prerelease.js') +const { DefaultVersioningStrategy } = require('release-please/build/src/versioning-strategies/default.js') +const { PrereleaseVersioningStrategy } = require('release-please/build/src/versioning-strategies/prerelease.js') const { ROOT_PROJECT_PATH } = require('release-please/build/src/manifest.js') const { CheckpointLogger, logger } = require('release-please/build/src/util/logger.js') const assert = require('assert') @@ -31,16 +27,7 @@ class ReleasePlease { #octokit #manifest - constructor ({ - token, - repo, - branch, - backport, - defaultTag, - overrides, - silent, - trace, - }) { + constructor({ token, repo, branch, backport, defaultTag, overrides, silent, trace }) { assert(token, 'token is required') assert(repo, 'repo is required') assert(branch, 'branch is required') @@ -57,28 +44,33 @@ class ReleasePlease { this.#trace = trace } - static async run (options) { + static async run(options) { const releasePlease = new ReleasePlease(options) await releasePlease.init() return releasePlease.run() } - async init () { - RP.registerChangelogNotes('default', ({ github, ...o }) => - new ChangelogNotes(github, o)) - RP.registerVersioningStrategy('default', (o) => - o.prerelease ? new PrereleaseVersioningStrategy(o) : new DefaultVersioningStrategy(o)) - RP.registerPlugin('node-workspace-format', ({ github, targetBranch, repositoryConfig, ...o }) => - new NodeWorkspaceFormat(github, targetBranch, repositoryConfig, o)) + async init() { + RP.registerChangelogNotes('default', ({ github, ...o }) => new ChangelogNotes(github, o)) + RP.registerVersioningStrategy('default', o => + o.prerelease ? new PrereleaseVersioningStrategy(o) : new DefaultVersioningStrategy(o), + ) + RP.registerPlugin( + 'node-workspace-format', + ({ github, targetBranch, repositoryConfig, ...o }) => + new NodeWorkspaceFormat(github, targetBranch, repositoryConfig, o), + ) if (this.#silent) { this.#info = noop - RP.setLogger(Object.entries(logger).reduce((acc, [k, v]) => { - if (typeof v === 'function') { - acc[k] = noop - } - return acc - }, {})) + RP.setLogger( + Object.entries(logger).reduce((acc, [k, v]) => { + if (typeof v === 'function') { + acc[k] = noop + } + return acc + }, {}), + ) } else { this.#info = core.info RP.setLogger(new CheckpointLogger(true, !!this.#trace)) @@ -90,16 +82,10 @@ class ReleasePlease { token: this.#token, }) this.#octokit = this.#github.octokit - this.#manifest = await RP.Manifest.fromManifest( - this.#github, - this.#branch, - undefined, - undefined, - this.#overrides - ) + this.#manifest = await RP.Manifest.fromManifest(this.#github, this.#branch, undefined, undefined, this.#overrides) } - async run () { + async run() { const rootPr = await this.#getRootPullRequest() const releases = await this.#getReleases() @@ -108,11 +94,13 @@ class ReleasePlease { // release please does not guarantee that the release PR will have the latest sha, // but we always need it so we can attach the relevant checks to the sha. - rootPr.sha = await this.#octokit.paginate(this.#octokit.rest.pulls.listCommits, { - owner: this.#owner, - repo: this.#repo, - pull_number: rootPr.number, - }).then(r => r[r.length - 1].sha) + rootPr.sha = await this.#octokit + .paginate(this.#octokit.rest.pulls.listCommits, { + owner: this.#owner, + repo: this.#repo, + pull_number: rootPr.number, + }) + .then(r => r[r.length - 1].sha) } if (releases) { @@ -126,19 +114,23 @@ class ReleasePlease { defaultTag: this.#defaultTag, }) - release.prNumber = await this.#octokit.rest.repos.listPullRequestsAssociatedWithCommit({ - owner: this.#owner, - repo: this.#repo, - commit_sha: release.sha, - per_page: 1, - }).then(r => r.data[0]?.number) - - release.pkgName = await this.#octokit.rest.repos.getContent({ - owner: this.#owner, - repo: this.#repo, - ref: this.#branch, - path: `${release.path === '.' ? '' : release.path}/package.json`, - }).then(r => JSON.parse(Buffer.from(r.data.content, r.data.encoding)).name) + release.prNumber = await this.#octokit.rest.repos + .listPullRequestsAssociatedWithCommit({ + owner: this.#owner, + repo: this.#repo, + commit_sha: release.sha, + per_page: 1, + }) + .then(r => r.data[0]?.number) + + release.pkgName = await this.#octokit.rest.repos + .getContent({ + owner: this.#owner, + repo: this.#repo, + ref: this.#branch, + path: `${release.path === '.' ? '' : release.path}/package.json`, + }) + .then(r => JSON.parse(Buffer.from(r.data.content, r.data.encoding)).name) } } @@ -148,14 +140,14 @@ class ReleasePlease { } } - async #getRootPullRequest () { + async #getRootPullRequest() { // We only ever get a single pull request with our current release-please settings // Update this if we start creating individual PRs per workspace release const pullRequests = await this.#manifest.createPullRequests() return pullRequests.filter(Boolean)[0] ?? null } - async #getReleases () { + async #getReleases() { // if we have a root release, always put it as the first item in the array const rawReleases = await this.#manifest.createReleases().then(r => r.filter(Boolean)) let rootRelease = null diff --git a/lib/release/util.js b/lib/release/util.js index d614ce39..671919e8 100644 --- a/lib/release/util.js +++ b/lib/release/util.js @@ -1,11 +1,11 @@ const semver = require('semver') const SPEC = new RegExp(`([^\\s]+@${semver.src[semver.tokens.FULLPLAIN]})`, 'g') -const code = (c) => `\`${c}\`` -const wrapSpecs = (str) => str.replace(SPEC, code('$1')) -const block = (lang) => `\`\`\`${lang ? `${lang}` : ''}` +const code = c => `\`${c}\`` +const wrapSpecs = str => str.replace(SPEC, code('$1')) +const block = lang => `\`\`\`${lang ? `${lang}` : ''}` const link = (text, url) => `[${text}](${url})` -const list = (text) => `* ${text}` +const list = text => `* ${text}` const formatDate = (date = new Date()) => { const year = date.getFullYear() const month = (date.getMonth() + 1).toString().padStart(2, '0') @@ -17,12 +17,15 @@ const getPublishTag = (v, { backport, defaultTag }) => { const version = semver.parse(v) return version.prerelease.length ? `prerelease-${version.major}` - : backport ? `latest-${backport}` - : defaultTag.replace(/{{\s*major\s*}}/, version.major) + : backport + ? `latest-${backport}` + : defaultTag.replace(/{{\s*major\s*}}/, version.major) } -const makeGitHubUrl = (owner, repo) => - (...p) => `https://github.com/${owner}/${repo}/${p.join('/')}` +const makeGitHubUrl = + (owner, repo) => + (...p) => + `https://github.com/${owner}/${repo}/${p.join('/')}` const noop = () => {} diff --git a/lib/util/ci-versions.js b/lib/util/ci-versions.js index ac42e96f..91042547 100644 --- a/lib/util/ci-versions.js +++ b/lib/util/ci-versions.js @@ -1,16 +1,16 @@ const { uniq, range, isPlainObject } = require('lodash') const semver = require('semver') -const parseCiVersions = (ciVersions) => { +const parseCiVersions = ciVersions => { if (Array.isArray(ciVersions)) { - return Object.fromEntries(ciVersions.map((v) => [v, true])) + return Object.fromEntries(ciVersions.map(v => [v, true])) } if (isPlainObject(ciVersions)) { return ciVersions } } -const getLowerBounds = (sRange) => { +const getLowerBounds = sRange => { return new semver.Range(sRange).set.map(c => c[0]) } diff --git a/lib/util/dependabot.js b/lib/util/dependabot.js index 913657f0..38f4dd8e 100644 --- a/lib/util/dependabot.js +++ b/lib/util/dependabot.js @@ -1,7 +1,7 @@ const { name: NAME } = require('../../package.json') const { minimatch } = require('minimatch') -const parseDependabotConfig = (v) => typeof v === 'string' ? { strategy: v } : (v ?? {}) +const parseDependabotConfig = v => (typeof v === 'string' ? { strategy: v } : v ?? {}) module.exports = (config, defaultConfig, branches) => { const { dependabot } = config @@ -12,7 +12,7 @@ module.exports = (config, defaultConfig, branches) => { } return branches - .filter((b) => dependabot[b] !== false) + .filter(b => dependabot[b] !== false) .map(branch => { const isReleaseBranch = minimatch(branch, config.releaseBranch) return { diff --git a/lib/util/files.js b/lib/util/files.js index 0842c6e8..71703220 100644 --- a/lib/util/files.js +++ b/lib/util/files.js @@ -12,21 +12,17 @@ const FILE_KEYS = ['rootRepo', 'rootModule', 'workspaceRepo', 'workspaceModule'] const globify = pattern => pattern.split('\\').join('/') -const deepMapKeys = (obj, fn) => Object.entries(obj).reduce((acc, [key, value]) => { - acc[fn(key)] = isPlainObject(value) ? deepMapKeys(value, fn) : value - return acc -}, {}) +const deepMapKeys = (obj, fn) => + Object.entries(obj).reduce((acc, [key, value]) => { + acc[fn(key)] = isPlainObject(value) ? deepMapKeys(value, fn) : value + return acc + }, {}) const mergeFiles = mergeWithCustomizers((value, srcValue, key, target, source, stack) => { // This will merge all files except if the src file has overwrite:false. Then // the files will be turned into an array so they can be applied on top of // each other in the parser. - if ( - stack[0] === ADD_KEY && - FILE_KEYS.includes(stack[1]) && - value?.file && - srcValue?.overwrite === false - ) { + if (stack[0] === ADD_KEY && FILE_KEYS.includes(stack[1]) && value?.file && srcValue?.overwrite === false) { return [value, omit(srcValue, 'overwrite')] } }, customizers.overwriteArrays) @@ -47,10 +43,14 @@ const fileEntries = (dir, files, options) => { // applied or diffed against the target. This is how overwrite:false // works and they are merged. const source = Array.isArray(value) - ? value.reduce((acc, { file, ...rest }) => { - acc.file.push(file) - return Object.assign(acc, rest) - }, { file: [] }) : value + ? value.reduce( + (acc, { file, ...rest }) => { + acc.file.push(file) + return Object.assign(acc, rest) + }, + { file: [] }, + ) + : value results.push([target, source]) } @@ -110,12 +110,12 @@ const parseEach = async (dir, files, options, parseOptions, fn) => { } const parseConfig = (files, dir, overrides, templateSettings) => { - const normalizeFiles = (v) => { - v = deepMapKeys(v, (s) => template(s, templateSettings)) + const normalizeFiles = v => { + v = deepMapKeys(v, s => template(s, templateSettings)) return deepMapValues(v, (value, key) => { if (key === RM_KEY && Array.isArray(value)) { return value.reduce((acc, k) => { - // template files nows since they need to be normalized before merging + // template files nows since they need to be normalized before merging acc[template(k, templateSettings)] = true return acc }, {}) @@ -132,15 +132,18 @@ const parseConfig = (files, dir, overrides, templateSettings) => { } const merged = mergeFiles(normalizeFiles(files), normalizeFiles(overrides)) - const withDefaults = defaultsDeep(merged, FILE_KEYS.reduce((acc, k) => { - acc[k] = { [ADD_KEY]: {}, [RM_KEY]: {} } - return acc - }, {})) + const withDefaults = defaultsDeep( + merged, + FILE_KEYS.reduce((acc, k) => { + acc[k] = { [ADD_KEY]: {}, [RM_KEY]: {} } + return acc + }, {}), + ) return withDefaults } -const getAddedFiles = (files) => files ? Object.keys(files[ADD_KEY] || {}) : [] +const getAddedFiles = files => (files ? Object.keys(files[ADD_KEY] || {}) : []) module.exports = { rmEach, diff --git a/lib/util/git.js b/lib/util/git.js index 681af788..06439830 100644 --- a/lib/util/git.js +++ b/lib/util/git.js @@ -5,7 +5,7 @@ const { minimatch } = require('minimatch') const cache = new Map() const tryGit = async (path, ...args) => { - if (!await git.is({ cwd: path })) { + if (!(await git.is({ cwd: path }))) { throw new Error('no git') } const key = [path, ...args].join(',') @@ -31,7 +31,7 @@ const getRemoteUrl = async (path, remote) => { } } -const getUrl = async (path) => { +const getUrl = async path => { return (await getRemoteUrl(path, 'upstream')) ?? (await getRemoteUrl(path, 'origin')) } @@ -41,7 +41,10 @@ const getBranches = async (path, branchPatterns) => { try { const res = await tryGit(path, 'ls-remote', '--heads', 'origin').then(r => r.split('\n')) - const remotes = res.map((h) => h.match(/refs\/heads\/(.*)$/)).filter(Boolean).map(h => h[1]) + const remotes = res + .map(h => h.match(/refs\/heads\/(.*)$/)) + .filter(Boolean) + .map(h => h[1]) for (const branch of remotes) { for (const pattern of branchPatterns) { if (minimatch(branch, pattern)) { @@ -61,7 +64,7 @@ const getBranches = async (path, branchPatterns) => { } } -const defaultBranch = async (path) => { +const defaultBranch = async path => { try { const remotes = await tryGit(path, 'remote', 'show', 'origin') return remotes.match(/HEAD branch: (.*)$/m)?.[1] diff --git a/lib/util/gitignore.js b/lib/util/gitignore.js index 665e1009..28e719cf 100644 --- a/lib/util/gitignore.js +++ b/lib/util/gitignore.js @@ -4,17 +4,19 @@ const localeCompare = require('@isaacs/string-locale-compare')('en') const sortGitPaths = (a, b) => localeCompare(a.replace(/^!/g, ''), b.replace(/^!/g, '')) -const allowDir = (p) => { +const allowDir = p => { const parts = p.split(posix.sep) - return parts.flatMap((part, index, list) => { - const prev = list.slice(0, index) - const isLast = index === list.length - 1 - const ignorePart = ['', ...prev, part, ''].join(posix.sep) - return [`!${ignorePart}`, !isLast && `${ignorePart}*`] - }).filter(Boolean) + return parts + .flatMap((part, index, list) => { + const prev = list.slice(0, index) + const isLast = index === list.length - 1 + const ignorePart = ['', ...prev, part, ''].join(posix.sep) + return [`!${ignorePart}`, !isLast && `${ignorePart}*`] + }) + .filter(Boolean) } -const allowRootDir = (p) => { +const allowRootDir = p => { // This negates the first part of each path for the gitignore // files. It should be used to allow directories where everything // should be allowed inside such as .github/. It shouldn't be used on @@ -26,9 +28,9 @@ const allowRootDir = (p) => { } const gitignore = { - allowDir: (dirs) => uniq(dirs.map(allowDir).flat()), - allowRootDir: (dirs) => dirs.map(allowRootDir).map((p) => `!${posix.sep}${p}`), - sort: (arr) => uniq(arr.sort(sortGitPaths)), + allowDir: dirs => uniq(dirs.map(allowDir).flat()), + allowRootDir: dirs => dirs.map(allowRootDir).map(p => `!${posix.sep}${p}`), + sort: arr => uniq(arr.sort(sortGitPaths)), } module.exports = gitignore diff --git a/lib/util/has-package.js b/lib/util/has-package.js index bffddfad..639c5b52 100644 --- a/lib/util/has-package.js +++ b/lib/util/has-package.js @@ -39,16 +39,11 @@ const getSpecVersion = (spec, where) => { return null } -const isVersion = (s) => s instanceof semver.SemVer +const isVersion = s => s instanceof semver.SemVer // Returns whether the pkg has the dependency in a semver // compatible version in one or more locationscccc -const hasPackage = ( - pkg, - spec, - locations = installLocations, - path -) => { +const hasPackage = (pkg, spec, locations = installLocations, path) => { const name = npa(spec).name const requested = getSpecVersion(spec) @@ -57,16 +52,16 @@ const hasPackage = ( } const existingByLocation = locations - .map((location) => pkg[location]) - .filter((deps) => has(deps, name)) - .map((deps) => getSpecVersion(`${name}@${deps[name]}`, path)) + .map(location => pkg[location]) + .filter(deps => has(deps, name)) + .map(deps => getSpecVersion(`${name}@${deps[name]}`, path)) .filter(Boolean) - return existingByLocation.some((existing) => { + return existingByLocation.some(existing => { if (existing === true) { return true } - switch ([existing, requested].map((t) => isVersion(t) ? 'VER' : 'RNG').join('-')) { + switch ([existing, requested].map(t => (isVersion(t) ? 'VER' : 'RNG')).join('-')) { case `VER-VER`: // two versions, use semver.eq to check equality return semver.eq(existing, requested) diff --git a/lib/util/import-or-require.js b/lib/util/import-or-require.js index 8fc7ef97..0fb0ef4b 100644 --- a/lib/util/import-or-require.js +++ b/lib/util/import-or-require.js @@ -7,7 +7,7 @@ const { pathToFileURL } = require('url') const importOrRequireCache = new Map() -const importOrRequire = async (path) => { +const importOrRequire = async path => { if (importOrRequireCache.has(path)) { return importOrRequireCache.get(path) } diff --git a/lib/util/json-diff.js b/lib/util/json-diff.js index ccc32b6d..faeac0ac 100644 --- a/lib/util/json-diff.js +++ b/lib/util/json-diff.js @@ -6,28 +6,29 @@ const j = (obj, replacer = null) => JSON.stringify(obj, replacer, 2) // DELETE is a special string that will be the value of updated if it exists // but should be deleted -const jsonDiff = (s1, s2, DELETE) => diff(s1, s2) - .map(({ op, path, value }) => { - // there could be cases where a whole object is reported - // as missing and the expected value does not need to show - // special DELETED values so filter those out here - const msgVal = j(value, (_, v) => v === DELETE ? undefined : v) - const prev = j(get(s1, path)) - const key = j(path.reduce((acc, p) => acc + (typeof p === 'number' ? `[${p}]` : `.${p}`))) +const jsonDiff = (s1, s2, DELETE) => + diff(s1, s2) + .map(({ op, path, value }) => { + // there could be cases where a whole object is reported + // as missing and the expected value does not need to show + // special DELETED values so filter those out here + const msgVal = j(value, (_, v) => (v === DELETE ? undefined : v)) + const prev = j(get(s1, path)) + const key = j(path.reduce((acc, p) => acc + (typeof p === 'number' ? `[${p}]` : `.${p}`))) - const msg = (...args) => format('%s is %s, expected %s', ...args) - const AD = msg(key, 'missing', msgVal) - const RM = msg(key, prev, 'to be removed') - const UP = msg(key, prev, msgVal) + const msg = (...args) => format('%s is %s, expected %s', ...args) + const AD = msg(key, 'missing', msgVal) + const RM = msg(key, prev, 'to be removed') + const UP = msg(key, prev, msgVal) - if (op === 'replace') { - return value === DELETE ? RM : UP - } else if (op === 'add' && value !== DELETE) { - return AD - } - }) - .filter(Boolean) - .sort((a, b) => a.localeCompare(b)) - .join('\n') + if (op === 'replace') { + return value === DELETE ? RM : UP + } else if (op === 'add' && value !== DELETE) { + return AD + } + }) + .filter(Boolean) + .sort((a, b) => a.localeCompare(b)) + .join('\n') module.exports = jsonDiff diff --git a/lib/util/merge.js b/lib/util/merge.js index 05a24300..c889d359 100644 --- a/lib/util/merge.js +++ b/lib/util/merge.js @@ -32,16 +32,17 @@ const mergeWith = (...args) => { // Create a merge function that will run a set of customizer functions const mergeWithCustomizers = (...customizers) => { - return (...objects) => mergeWith({}, ...objects, (...args) => { - for (const customizer of customizers) { - const result = customizer(...args) - // undefined means the customizer will defer to the next one - // the default behavior of undefined in lodash is to merge - if (result !== undefined) { - return result + return (...objects) => + mergeWith({}, ...objects, (...args) => { + for (const customizer of customizers) { + const result = customizer(...args) + // undefined means the customizer will defer to the next one + // the default behavior of undefined in lodash is to merge + if (result !== undefined) { + return result + } } - } - }) + }) } const customizers = { @@ -52,14 +53,16 @@ const customizers = { } }, // Merge arrays if their key matches one of the passed in keys - mergeArrays: (...keys) => (value, srcValue, key) => { - if (Array.isArray(srcValue)) { - if (keys.includes(key)) { - return (Array.isArray(value) ? value : []).concat(srcValue) + mergeArrays: + (...keys) => + (value, srcValue, key) => { + if (Array.isArray(srcValue)) { + if (keys.includes(key)) { + return (Array.isArray(value) ? value : []).concat(srcValue) + } + return srcValue } - return srcValue - } - }, + }, } module.exports = { diff --git a/lib/util/output.js b/lib/util/output.js index d96bea23..b9e32f6d 100644 --- a/lib/util/output.js +++ b/lib/util/output.js @@ -1,8 +1,12 @@ const indent = (v, i = 2) => { if (Array.isArray(v)) { - return v.map((a) => indent(a, i)).join('\n') + return v.map(a => indent(a, i)).join('\n') } - return v.toString().split('\n').map((l) => ' '.repeat(i) + l).join('\n') + return v + .toString() + .split('\n') + .map(l => ' '.repeat(i) + l) + .join('\n') } const output = () => { @@ -15,13 +19,12 @@ const output = () => { } } -const outputProblems = (problems) => { +const outputProblems = problems => { const o = output() o.push('', 'Some problems were detected:') o.sep() for (const { title, body, solution } of problems) { - const [solutionTitle, ...solutionRest] = Array.isArray(solution) - ? solution : [solution] + const [solutionTitle, ...solutionRest] = Array.isArray(solution) ? solution : [solution] o.push(title, '', indent(body), '', `To correct it: ${solutionTitle}`) if (solutionRest.length) { o.push('', indent(solutionRest)) diff --git a/lib/util/parser.js b/lib/util/parser.js index 2156f6cd..c70c783b 100644 --- a/lib/util/parser.js +++ b/lib/util/parser.js @@ -27,7 +27,7 @@ const traverse = (value, visit, keys = []) => { } } -const fsOk = (code) => (error) => { +const fsOk = code => error => { if (error.code === 'ENOENT') { return null } @@ -37,107 +37,114 @@ const fsOk = (code) => (error) => { class Base { static types = [] static header = 'This file is automatically added by {{ __NAME__ }}. Do not edit.' - comment = (v) => v + comment = v => v merge = false // supply a merge function which runs on prepare for certain types DELETE = template.DELETE - constructor (target, source, options, fileOptions) { + constructor(target, source, options, fileOptions) { this.target = target this.source = source this.options = options this.fileOptions = fileOptions } - header () { + header() { if (typeof this.comment === 'function') { return this.comment(this.template(this.constructor.header || '')) } } - clean () { + clean() { if (this.fileOptions.clean) { return fs.rm(this.target).catch(fsOk()) } return null } - read (s) { + read(s) { if (Array.isArray(s)) { return Promise.all(s.map(f => this.read(f))) } return fs.readFile(s, { encoding: 'utf-8' }) } - template (s) { + template(s) { if (Array.isArray(s)) { return Promise.all(s.map(f => this.template(f))) } return template(s, this.options) } - parse (s) { + parse(s) { return s } - prepare (s) { + prepare(s) { const header = this.header() return header ? `${header}\n\n${s}` : s } - prepareTarget (s) { + prepareTarget(s) { return s } - toString (s) { + toString(s) { return s.toString() } - async write (s) { + async write(s) { // XXX: find more efficient way to do this. we can build all possible dirs before get here await fs.mkdir(dirname(this.target), { owner: 'inherit', recursive: true, force: true }) return fs.writeFile(this.target, this.toString(s), { owner: 'inherit' }) } - diffPatch (t, s) { + diffPatch(t, s) { // create a patch and strip out the filename. if it ends up an empty string // then return true since the files are equal - return Diff.createPatch('', t.replace(/\r\n/g, '\n'), s.replace(/\r\n/g, '\n')) - .split('\n').slice(4).join('\n') + return Diff.createPatch('', t.replace(/\r\n/g, '\n'), s.replace(/\r\n/g, '\n')).split('\n').slice(4).join('\n') } - diff (t, s) { + diff(t, s) { return this.diffPatch(t, s) } // the apply methods are the only ones that should be called publically // XXX: everything is allowed to be overridden in base classes but we could // find a different solution than making everything public - applyWrite () { - return Promise.resolve(this.clean()) - .then(() => this.read(this.source)) - // replace template vars first, this will throw for nonexistant vars - // because it must be parseable after this step - .then((s) => this.template(s)) - // parse into whatever data structure is necessary for maniuplating - // diffing, merging, etc. by default its a string - .then((s) => { - this.sourcePreParse = s - return this.parse(s) - }) - // prepare the source for writing and diffing, pass in current - // target for merging. errors parsing or preparing targets are ok here - .then((s) => this.applyTarget().catch(() => null).then((t) => this.prepare(s, t))) - .then((s) => this.write(s)) - } - - applyTarget () { - return Promise.resolve(this.read(this.target)) - .then((s) => this.parse(s)) - // for only preparing the target for diffing - .then((s) => this.prepareTarget(s)) - } - - async applyDiff () { + applyWrite() { + return ( + Promise.resolve(this.clean()) + .then(() => this.read(this.source)) + // replace template vars first, this will throw for nonexistant vars + // because it must be parseable after this step + .then(s => this.template(s)) + // parse into whatever data structure is necessary for maniuplating + // diffing, merging, etc. by default its a string + .then(s => { + this.sourcePreParse = s + return this.parse(s) + }) + // prepare the source for writing and diffing, pass in current + // target for merging. errors parsing or preparing targets are ok here + .then(s => + this.applyTarget() + .catch(() => null) + .then(t => this.prepare(s, t)), + ) + .then(s => this.write(s)) + ) + } + + applyTarget() { + return ( + Promise.resolve(this.read(this.target)) + .then(s => this.parse(s)) + // for only preparing the target for diffing + .then(s => this.prepareTarget(s)) + ) + } + + async applyDiff() { // handle if old does not exist const targetError = 'ETARGETERROR' const target = await this.applyTarget().catch(fsOk(targetError)) @@ -148,10 +155,10 @@ class Base { } const source = await Promise.resolve(this.read(this.source)) - .then((s) => this.template(s)) - .then((s) => this.parse(s)) + .then(s => this.template(s)) + .then(s => this.parse(s)) // gets the target to diff against in case it needs to merge, etc - .then((s) => this.prepare(s, target)) + .then(s => this.prepare(s, target)) // if there was a target error then there is no need to diff // so we just show the source with an error message @@ -175,27 +182,27 @@ class Base { class Gitignore extends Base { static types = ['codeowners', '.gitignore', '.prettierignore'] - comment = (c) => `# ${c}` + comment = c => `# ${c}` } class Js extends Base { static types = ['*.js', '*.cjs'] - comment = (c) => `/* ${c} */` + comment = c => `/* ${c} */` } class Ini extends Base { static types = ['*.ini'] - comment = (c) => `; ${c}` + comment = c => `; ${c}` - toString (s) { + toString(s) { return typeof s === 'string' ? s : ini.stringify(s) } - parse (s) { + parse(s) { return typeof s === 'string' ? ini.parse(s) : s } - prepare (s, t) { + prepare(s, t) { let source = s if (typeof this.merge === 'function' && t) { source = this.merge(t, s) @@ -203,7 +210,7 @@ class Ini extends Base { return super.prepare(this.toString(source)) } - diff (t, s) { + diff(t, s) { return jsonDiff(this.parse(t), this.parse(s), this.DELETE) } } @@ -215,14 +222,14 @@ class IniMerge extends Ini { class Markdown extends Base { static types = ['*.md'] - comment = (c) => `` + comment = c => `` } class Yml extends Base { static types = ['*.yml'] - comment = (c) => ` ${c}` + comment = c => ` ${c}` - toString (s) { + toString(s) { try { return s.toString({ lineWidth: 0, indent: 2 }) } catch (err) { @@ -231,22 +238,22 @@ class Yml extends Base { } } - parse (s) { + parse(s) { return yaml.parseDocument(s) } - prepare (s) { + prepare(s) { s.commentBefore = this.header() return this.toString(s) } - prepareTarget (s) { + prepareTarget(s) { return this.toString(s) } } class YmlMerge extends Yml { - prepare (source, t) { + prepare(source, t) { if (t === null) { // If target does not exist or is in an // error state, we cant do anything but write @@ -256,7 +263,7 @@ class YmlMerge extends Yml { const key = [].concat(this.key) - const getId = (node) => { + const getId = node => { const index = node.items.findIndex(p => p.key?.value === this.id) return index !== -1 ? node.items[index].value?.value : node.toJSON() } @@ -284,20 +291,20 @@ class Json extends Base { static types = ['*.json'] // its a json comment! not really but we do add a special key // to json objects - comment = (c) => ({ [`//${this.options.config.__NAME__}`]: c }) + comment = c => ({ [`//${this.options.config.__NAME__}`]: c }) - toString (s) { - return JSON.stringify(s, (_, v) => v === this.DELETE ? undefined : v, 2).trim() + '\n' + toString(s) { + return JSON.stringify(s, (_, v) => (v === this.DELETE ? undefined : v), 2).trim() + '\n' } - parse (s) { + parse(s) { if (Array.isArray(s)) { return s.map(f => this.parse(f)).reduce((a, f) => this.merge(a, f), {}) } return jsonParse(s) } - prepare (s, t) { + prepare(s, t) { let source = s if (typeof this.merge === 'function' && t) { source = this.merge(t, s) @@ -305,7 +312,7 @@ class Json extends Base { return setFirst(this.header(), source) } - diff (t, s) { + diff(t, s) { return jsonDiff(t, s, this.DELETE) } } @@ -322,7 +329,7 @@ class JsonMergeNoComment extends JsonMerge { class PackageJson extends JsonMerge { static types = ['package.json'] - async prepare (s, t) { + async prepare(s, t) { // merge new source with current pkg content const update = super.prepare(s, t) @@ -336,7 +343,7 @@ class PackageJson extends JsonMerge { return update } - async write (s) { + async write(s) { const pkg = await NpmPackageJson.load(dirname(this.target)) pkg.update(s) traverse(pkg.content, (keys, value) => { @@ -378,7 +385,7 @@ for (const parser of Object.values(Parsers)) { } } -const getParser = (file) => { +const getParser = file => { for (const [type, parser] of parserLookup) { if (minimatch(file, type, { nocase: true, dot: true, matchBase: true })) { return parser diff --git a/lib/util/path.js b/lib/util/path.js index e0582f59..3b65b83d 100644 --- a/lib/util/path.js +++ b/lib/util/path.js @@ -1,9 +1,9 @@ const { posix, win32 } = require('path') -const makePosix = (v) => v.split(win32.sep).join(posix.sep) -const deglob = (v) => makePosix(v).replace(/[/*]+$/, '') -const posixDir = (v) => `${v === '.' ? '' : deglob(v).replace(/\/$/, '')}${posix.sep}` -const posixGlob = (str) => `${posixDir(str)}**` +const makePosix = v => v.split(win32.sep).join(posix.sep) +const deglob = v => makePosix(v).replace(/[/*]+$/, '') +const posixDir = v => `${v === '.' ? '' : deglob(v).replace(/\/$/, '')}${posix.sep}` +const posixGlob = str => `${posixDir(str)}**` module.exports = { makePosix, diff --git a/lib/util/template.js b/lib/util/template.js index c7889a23..1413bed6 100644 --- a/lib/util/template.js +++ b/lib/util/template.js @@ -4,12 +4,12 @@ const { Range } = require('semver') const fs = require('fs') const DELETE = '__DELETE__' -const safeValues = (obj) => Object.entries(obj).map(([key, value]) => - [key, new Handlebars.SafeString(value)]) +const safeValues = obj => Object.entries(obj).map(([key, value]) => [key, new Handlebars.SafeString(value)]) -const partialName = (s) => basename(s, extname(s)) // remove extension - .replace(/^_/, '') // remove leading underscore - .replace(/-([a-z])/g, (_, g) => g.toUpperCase()) // camelcase +const partialName = s => + basename(s, extname(s)) // remove extension + .replace(/^_/, '') // remove leading underscore + .replace(/-([a-z])/g, (_, g) => g.toUpperCase()) // camelcase const makePartials = (dir, isBase) => { const partials = fs.readdirSync(dir).reduce((acc, f) => { @@ -32,16 +32,16 @@ const makePartials = (dir, isBase) => { Handlebars.registerPartial(partials) } -const setupHandlebars = (dirs) => { +const setupHandlebars = dirs => { Handlebars.registerHelper('obj', ({ hash }) => Object.fromEntries(safeValues(hash))) Handlebars.registerHelper('extGlob', arr => `{${arr.join(',')}}`) Handlebars.registerHelper('join', (arr, sep) => arr.join(typeof sep === 'string' ? sep : ', ')) Handlebars.registerHelper('pluck', (arr, key) => arr.map(a => a[key])) - Handlebars.registerHelper('quote', (arr) => arr.map(a => `'${a}'`)) - Handlebars.registerHelper('last', (arr) => arr[arr.length - 1]) - Handlebars.registerHelper('json', (c) => JSON.stringify(c)) + Handlebars.registerHelper('quote', arr => arr.map(a => `'${a}'`)) + Handlebars.registerHelper('last', arr => arr[arr.length - 1]) + Handlebars.registerHelper('json', c => JSON.stringify(c)) Handlebars.registerHelper('del', () => JSON.stringify(DELETE)) - Handlebars.registerHelper('semverRangeMajor', (v) => new Range(v).set[0][0].semver.major) + Handlebars.registerHelper('semverRangeMajor', v => new Range(v).set[0][0].semver.major) Handlebars.registerHelper('lte', (a, b) => a <= b) if (Array.isArray(dirs)) { diff --git a/test/apply/allow-paths.js b/test/apply/allow-paths.js index fd272d68..31c7caf7 100644 --- a/test/apply/allow-paths.js +++ b/test/apply/allow-paths.js @@ -1,14 +1,11 @@ const t = require('tap') const setup = require('../setup.js') -t.test('allow paths are merged', async (t) => { +t.test('allow paths are merged', async t => { const s = await setup(t, { package: { templateOSS: { - allowPaths: [ - '/a', - '/b', - ], + allowPaths: ['/a', '/b'], }, }, }) @@ -20,16 +17,13 @@ t.test('allow paths are merged', async (t) => { t.ok(ignore.includes('!/lib/')) }) -t.test('works with custom content', async (t) => { +t.test('works with custom content', async t => { const s = await setup(t, { package: { templateOSS: { content: 'content_dir', defaultContent: false, - allowPaths: [ - '/a', - '/b', - ], + allowPaths: ['/a', '/b'], }, }, testdir: { diff --git a/test/apply/dependabot.js b/test/apply/dependabot.js index c2950b9f..6f44e04e 100644 --- a/test/apply/dependabot.js +++ b/test/apply/dependabot.js @@ -10,7 +10,7 @@ const setupDependabot = async (t, { branches = ['main'], ...config } = {}) => { mocks: { '@npmcli/git': { is: async () => true, - spawn: async (args) => { + spawn: async args => { const command = args.filter(a => typeof a === 'string').join(' ') if (command === 'ls-remote --heads origin') { return { @@ -28,9 +28,9 @@ const setupDependabot = async (t, { branches = ['main'], ...config } = {}) => { }) await s.apply() - const postDependabot = await s.readFile('.github/workflows/post-dependabot.yml') - .catch(() => false) - const dependabot = await s.readFile('.github/dependabot.yml') + const postDependabot = await s.readFile('.github/workflows/post-dependabot.yml').catch(() => false) + const dependabot = await s + .readFile('.github/dependabot.yml') .then(r => yaml.parse(r).updates) .catch(() => false) @@ -41,7 +41,7 @@ const setupDependabot = async (t, { branches = ['main'], ...config } = {}) => { } } -t.test('default', async (t) => { +t.test('default', async t => { const s = await setupDependabot(t) t.equal(s.dependabot.length, 1) @@ -60,7 +60,7 @@ t.test('default', async (t) => { t.ok(s.postDependabot) }) -t.test('change strategy', async (t) => { +t.test('change strategy', async t => { const s = await setupDependabot(t, { dependabot: 'some-other-strategy', }) @@ -68,7 +68,7 @@ t.test('change strategy', async (t) => { t.equal(s.dependabot[0]['versioning-strategy'], 'some-other-strategy') }) -t.test('turn off specific branch', async (t) => { +t.test('turn off specific branch', async t => { const s = await setupDependabot(t, { dependabot: { main: false, @@ -77,24 +77,24 @@ t.test('turn off specific branch', async (t) => { t.equal(s.dependabot, null) }) -t.test('release brancheses', async (t) => { +t.test('release brancheses', async t => { const s = await setupDependabot(t, { - branches: [ - 'release/v10', - ], + branches: ['release/v10'], }) t.match(s.dependabot[0], { 'target-branch': 'release/v10', - allow: [{ - 'dependency-type': 'direct', - 'dependency-name': '@npmcli/template-oss', - }], + allow: [ + { + 'dependency-type': 'direct', + 'dependency-name': '@npmcli/template-oss', + }, + ], labels: ['Dependencies', 'Backport', 'release/v10'], }) }) -t.test('no dependabot', async (t) => { +t.test('no dependabot', async t => { const s = await setupDependabot(t, { dependabot: false, }) diff --git a/test/apply/engines.js b/test/apply/engines.js index 9744a50c..d334d877 100644 --- a/test/apply/engines.js +++ b/test/apply/engines.js @@ -3,7 +3,7 @@ const { join } = require('path') const yaml = require('yaml') const setup = require('../setup.js') -const getCiJobs = async (s) => { +const getCiJobs = async s => { const file = await s.readFile(join('.github', 'workflows', 'ci.yml')) const { jobs } = yaml.parse(file) return { @@ -12,7 +12,7 @@ const getCiJobs = async (s) => { } } -t.test('sets ci versions from engines', async (t) => { +t.test('sets ci versions from engines', async t => { const s = await setup(t, { package: { engines: { node: '>=10' }, @@ -30,18 +30,10 @@ t.test('sets ci versions from engines', async (t) => { const versions = await getCiJobs(s) t.equal(versions.lint, '22.x') - t.strictSame(versions.test, [ - '10.0.0', - '10.x', - '14.x', - '16.x', - '18.x', - '20.x', - '22.x', - ]) + t.strictSame(versions.test, ['10.0.0', '10.x', '14.x', '16.x', '18.x', '20.x', '22.x']) }) -t.test('can set ci to latest plus other versions', async (t) => { +t.test('can set ci to latest plus other versions', async t => { const s = await setup(t, { package: { engines: { node: '*' }, @@ -57,27 +49,16 @@ t.test('can set ci to latest plus other versions', async (t) => { const versions = await getCiJobs(s) t.equal(versions.lint, '22.x') - t.strictSame(versions.test, [ - '6.x', - '8.x', - '22.x', - ]) + t.strictSame(versions.test, ['6.x', '8.x', '22.x']) }) -t.test('sort by major', async (t) => { +t.test('sort by major', async t => { const s = await setup(t, { package: { engines: { node: '*' }, templateOSS: { latestCiVersion: null, - ciVersions: [ - '7.x', - '6.0.0', - '6.x', - '7.0.0', - '8.x', - '8.0.0', - ], + ciVersions: ['7.x', '6.0.0', '6.x', '7.0.0', '8.x', '8.0.0'], }, }, }) @@ -88,17 +69,10 @@ t.test('sort by major', async (t) => { const versions = await getCiJobs(s) t.equal(versions.lint, '8.x') - t.strictSame(versions.test, [ - '6.0.0', - '6.x', - '7.0.0', - '7.x', - '8.0.0', - '8.x', - ]) + t.strictSame(versions.test, ['6.0.0', '6.x', '7.0.0', '7.x', '8.0.0', '8.x']) }) -t.test('latest ci versions', async (t) => { +t.test('latest ci versions', async t => { const s = await setup(t, { package: { templateOSS: { @@ -113,7 +87,5 @@ t.test('latest ci versions', async (t) => { const versions = await getCiJobs(s) t.equal(versions.lint, '22.x') - t.strictSame(versions.test, [ - '22.x', - ]) + t.strictSame(versions.test, ['22.x']) }) diff --git a/test/apply/esm.js b/test/apply/esm.js index 3afc80ca..aeaa9f18 100644 --- a/test/apply/esm.js +++ b/test/apply/esm.js @@ -1,7 +1,7 @@ const t = require('tap') const setup = require('../setup.js') -t.test('basic', async (t) => { +t.test('basic', async t => { const s = await setup(t, { package: { type: 'module', diff --git a/test/apply/files-snapshots.js b/test/apply/files-snapshots.js index 79d27bf7..5dd1299e 100644 --- a/test/apply/files-snapshots.js +++ b/test/apply/files-snapshots.js @@ -4,7 +4,7 @@ const setup = require('../setup.js') t.cleanSnapshot = setup.clean t.formatSnapshot = setup.format.readdir -t.test('turn off repo', async (t) => { +t.test('turn off repo', async t => { const s = await setup(t, { package: { templateOSS: { @@ -16,7 +16,7 @@ t.test('turn off repo', async (t) => { await t.resolveMatchSnapshot(s.readdir()) }) -t.test('turn off module', async (t) => { +t.test('turn off module', async t => { const s = await setup(t, { package: { templateOSS: { @@ -28,7 +28,7 @@ t.test('turn off module', async (t) => { await t.resolveMatchSnapshot(s.readdir()) }) -t.test('turn off root', async (t) => { +t.test('turn off root', async t => { const s = await setup(t, { package: { templateOSS: { @@ -41,7 +41,7 @@ t.test('turn off root', async (t) => { await t.resolveMatchSnapshot(s.readdir()) }) -t.test('turn off add/rm types', async (t) => { +t.test('turn off add/rm types', async t => { const s = await setup(t, { package: { templateOSS: { @@ -58,7 +58,7 @@ t.test('turn off add/rm types', async (t) => { await t.resolveMatchSnapshot(s.readdir()) }) -t.test('turn off specific files', async (t) => { +t.test('turn off specific files', async t => { const s = await setup(t, { package: { templateOSS: { @@ -93,7 +93,7 @@ t.test('turn off specific files', async (t) => { await t.resolveMatchSnapshot(s.readdir()) }) -t.test('workspaces with relative content path', async (t) => { +t.test('workspaces with relative content path', async t => { const s = await setup(t, { package: { templateOSS: { @@ -118,7 +118,7 @@ t.test('workspaces with relative content path', async (t) => { await t.resolveMatchSnapshot(s.readdir()) }) -t.test('workspaces', async (t) => { +t.test('workspaces', async t => { const s = await setup(t, { package: { templateOSS: { @@ -149,7 +149,7 @@ t.test('workspaces', async (t) => { await t.resolveMatchSnapshot(s.readdir()) }) -t.test('workspaces only (like npm/cli)', async (t) => { +t.test('workspaces only (like npm/cli)', async t => { const s = await setup(t, { package: { templateOSS: { @@ -163,7 +163,7 @@ t.test('workspaces only (like npm/cli)', async (t) => { await t.resolveMatchSnapshot(s.readdir()) }) -t.test('private workspace', async (t) => { +t.test('private workspace', async t => { const s = await setup(t, { package: { name: 'root-pkg', diff --git a/test/apply/index.js b/test/apply/index.js index 3be5f2a5..a968fe92 100644 --- a/test/apply/index.js +++ b/test/apply/index.js @@ -2,7 +2,7 @@ const t = require('tap') const { join } = require('path') const setup = require('../setup.js') -t.test('turn off root files', async (t) => { +t.test('turn off root files', async t => { const s = await setup(t, { package: { templateOSS: { @@ -26,7 +26,7 @@ t.test('turn off root files', async (t) => { t.ok(await s.exists('.eslintrc.yml')) }) -t.test('turn off root rm only', async (t) => { +t.test('turn off root rm only', async t => { const s = await setup(t, { package: { templateOSS: { @@ -54,7 +54,7 @@ t.test('turn off root rm only', async (t) => { t.ok(await s.exists('.eslintrc.yml')) }) -t.test('turn off root add only', async (t) => { +t.test('turn off root add only', async t => { const s = await setup(t, { package: { templateOSS: { @@ -82,7 +82,7 @@ t.test('turn off root add only', async (t) => { t.notOk(await s.exists('.eslintrc.yml')) }) -t.test('turn off specific files', async (t) => { +t.test('turn off specific files', async t => { const s = await setup(t, { package: { templateOSS: { @@ -120,7 +120,7 @@ t.test('turn off specific files', async (t) => { t.ok(await s.exists('.eslintrc.yml')) }) -t.test('root can set workspace files', async (t) => { +t.test('root can set workspace files', async t => { const s = await setup(t, { package: { templateOSS: { @@ -146,7 +146,7 @@ t.test('root can set workspace files', async (t) => { t.ok(await s.exists(s.workspaces.a, '.npmrc')) }) -t.test('workspace config can override root', async (t) => { +t.test('workspace config can override root', async t => { const s = await setup(t, { package: { templateOSS: { @@ -179,7 +179,7 @@ t.test('workspace config can override root', async (t) => { t.notOk(await s.exists(s.workspaces.a, '.npmrc')) }) -t.test('workspaces can override content', async (t) => { +t.test('workspaces can override content', async t => { const s = await setup(t, { package: { templateOSS: { @@ -209,7 +209,7 @@ t.test('workspaces can override content', async (t) => { t.ok(await s.exists('x.js')) }) -t.test('content can override partials', async (t) => { +t.test('content can override partials', async t => { const s = await setup(t, { package: { templateOSS: { @@ -239,7 +239,7 @@ t.test('content can override partials', async (t) => { t.ok(release.includes('job: 1')) }) -t.test('content can extend files', async (t) => { +t.test('content can extend files', async t => { const s = await setup(t, { package: { templateOSS: { @@ -259,7 +259,7 @@ t.test('content can extend files', async (t) => { t.ok(release.includes('smoke-publish')) }) -t.test('config via multiple locations', async (t) => { +t.test('config via multiple locations', async t => { const s = await setup(t, { package: { templateOSS: { @@ -301,7 +301,7 @@ t.test('config via multiple locations', async (t) => { t.equal(ws.split('\n').slice(-1)[0], 'npm-ws-a-ws-b-ws-c') }) -t.test('private workspace', async (t) => { +t.test('private workspace', async t => { const s = await setup(t, { package: { name: 'root-pkg', diff --git a/test/apply/lint.js b/test/apply/lint.js index a1b8d94b..88914d92 100644 --- a/test/apply/lint.js +++ b/test/apply/lint.js @@ -1,7 +1,7 @@ const t = require('tap') const setup = require('../setup.js') -t.test('can disable eslint', async (t) => { +t.test('can disable eslint', async t => { const s = await setup(t, { package: { templateOSS: { @@ -23,7 +23,7 @@ t.test('can disable eslint', async (t) => { t.notMatch(checks[0].solution, 'eslint') }) -t.test('can enable prettier', async (t) => { +t.test('can enable prettier', async t => { const s = await setup(t, { ok: true, package: { @@ -41,11 +41,7 @@ t.test('can enable prettier', async (t) => { const checks = await s.check() t.equal(checks.length, 1) - t.match(checks[0].body, [ - 'prettier', - 'eslint-config-prettier', - '@github/prettier-config', - ]) + t.match(checks[0].body, ['prettier', 'eslint-config-prettier', '@github/prettier-config']) await s.writeJson('package.json', { ...pkg, diff --git a/test/apply/lockfile.js b/test/apply/lockfile.js index 3ffeba99..ee7321c3 100644 --- a/test/apply/lockfile.js +++ b/test/apply/lockfile.js @@ -1,7 +1,7 @@ const t = require('tap') const setup = require('../setup.js') -t.test('lockfile', async (t) => { +t.test('lockfile', async t => { const s = await setup(t, { package: { templateOSS: { @@ -17,7 +17,7 @@ t.test('lockfile', async (t) => { t.ok(npmrc.includes('package-lock=true')) }) -t.test('no lockfile by default', async (t) => { +t.test('no lockfile by default', async t => { const s = await setup(t) await s.apply() const gitignore = await s.readFile('.gitignore') diff --git a/test/apply/merge-yml.js b/test/apply/merge-yml.js index d80e50f7..2dbdad92 100644 --- a/test/apply/merge-yml.js +++ b/test/apply/merge-yml.js @@ -2,9 +2,9 @@ const t = require('tap') const yaml = require('yaml') const setup = require('../setup.js') -const toYml = (data) => new yaml.Document(data).toString() +const toYml = data => new yaml.Document(data).toString() -t.test('json merge', async (t) => { +t.test('json merge', async t => { const s = await setup(t, { package: { templateOSS: { @@ -15,19 +15,11 @@ t.test('json merge', async (t) => { testdir: { 'target.yml': toYml({ existing: 'header', - key: [ - { id: 1, a: 1 }, - { id: 2, a: 2 }, - { noid: 1 }, - ], + key: [{ id: 1, a: 1 }, { id: 2, a: 2 }, { noid: 1 }], }), 'clean-target.yml': toYml({ existing: 'header', - key: [ - { id: 1, a: 1 }, - { id: 2, a: 2 }, - { noid: 1 }, - ], + key: [{ id: 1, a: 1 }, { id: 2, a: 2 }, { noid: 1 }], }), content: { 'index.js': await setup.fixture('yml-merge.js'), @@ -47,12 +39,7 @@ t.test('json merge', async (t) => { t.strictSame(yaml.parse(await s.readFile('target.yml')), { existing: 'header', - key: [ - { id: 1, b: 1 }, - { id: 2, b: 2 }, - { noid: 1 }, - { id: 3, b: 3 }, - ], + key: [{ id: 1, b: 1 }, { id: 2, b: 2 }, { noid: 1 }, { id: 3, b: 3 }], }) t.strictSame(yaml.parse(await s.readFile('clean-target.yml')), { new: 'header', diff --git a/test/apply/npm-bin.js b/test/apply/npm-bin.js index c61f6ab3..8cab4153 100644 --- a/test/apply/npm-bin.js +++ b/test/apply/npm-bin.js @@ -2,7 +2,7 @@ const t = require('tap') const { join } = require('path') const setup = require('../setup.js') -t.test('custom npm path', async (t) => { +t.test('custom npm path', async t => { const s = await setup(t, { ok: true, package: { @@ -16,7 +16,7 @@ t.test('custom npm path', async (t) => { t.equal(scripts.posttest, 'node /path/to/npm run lint') }) -t.test('relative npm bin with workspaces', async (t) => { +t.test('relative npm bin with workspaces', async t => { const s = await setup(t, { ok: true, package: { @@ -38,7 +38,7 @@ t.test('relative npm bin with workspaces', async (t) => { }) await s.apply() - const readScripts = (p) => s.readJson(join(p, 'package.json')).then(r => r.scripts) + const readScripts = p => s.readJson(join(p, 'package.json')).then(r => r.scripts) const ws = s.workspaces const pkgs = ['', ws.a, ws.b, ws.c, ws.d, ws.e] diff --git a/test/apply/overwrite-false.js b/test/apply/overwrite-false.js index 260d7f7f..efc513b6 100644 --- a/test/apply/overwrite-false.js +++ b/test/apply/overwrite-false.js @@ -1,7 +1,7 @@ const t = require('tap') const setup = require('../setup.js') -t.test('json merge', async (t) => { +t.test('json merge', async t => { const s = await setup(t, { ok: true, package: { diff --git a/test/apply/release-config.js b/test/apply/release-config.js index 13e187cf..16ab3598 100644 --- a/test/apply/release-config.js +++ b/test/apply/release-config.js @@ -1,20 +1,23 @@ const t = require('tap') const setup = require('../setup.js') -const PLUGINS = [ - 'node-workspace', - 'node-workspace-format', -] +const PLUGINS = ['node-workspace', 'node-workspace-format'] -t.test('root only', async (t) => { +t.test('root only', async t => { const prvt = { private: true } const cases = [ [{}, { plugins: false, pr: true }], [{ workspaces: { a: 'a' } }, { plugins: true, pr: true }], [{ workspaces: { a: prvt } }, { plugins: false, pr: true }], [{ package: prvt }, { plugins: false, pr: false }], - [{ package: prvt, workspaces: { a: 'a' } }, { plugins: true, pr: true }], - [{ package: prvt, workspaces: { a: prvt } }, { plugins: false, pr: false }], + [ + { package: prvt, workspaces: { a: 'a' } }, + { plugins: true, pr: true }, + ], + [ + { package: prvt, workspaces: { a: prvt } }, + { plugins: false, pr: false }, + ], ] for (const [config, expected] of cases) { diff --git a/test/apply/release.js b/test/apply/release.js index dcc5762a..3009d7fe 100644 --- a/test/apply/release.js +++ b/test/apply/release.js @@ -2,7 +2,7 @@ const t = require('tap') const { join } = require('path') const setup = require('../setup.js') -t.test('no workspace flags in commands', async (t) => { +t.test('no workspace flags in commands', async t => { const s = await setup(t, { package: { templateOSS: { @@ -22,7 +22,7 @@ t.test('no workspace flags in commands', async (t) => { t.match(release, '--backport=""') }) -t.test('uses workspace flags in commands', async (t) => { +t.test('uses workspace flags in commands', async t => { const s = await setup(t, { workspaces: { a: 'a', @@ -36,7 +36,7 @@ t.test('uses workspace flags in commands', async (t) => { t.match(ciRelease, '--ignore-scripts -ws -iwr --if-present\n') }) -t.test('backport', async (t) => { +t.test('backport', async t => { const s = await setup(t, { package: { templateOSS: { diff --git a/test/apply/source-snapshots.js b/test/apply/source-snapshots.js index f1ec9901..6ceae1fa 100644 --- a/test/apply/source-snapshots.js +++ b/test/apply/source-snapshots.js @@ -4,13 +4,13 @@ const setup = require('../setup.js') t.cleanSnapshot = setup.clean t.formatSnapshot = setup.format.readdirSource -t.test('root only', async (t) => { +t.test('root only', async t => { const s = await setup(t) await s.apply() await t.resolveMatchSnapshot(s.readdirSource()) }) -t.test('with workspaces', async (t) => { +t.test('with workspaces', async t => { const s = await setup(t, { workspaces: { a: 'a', b: 'b' }, }) @@ -18,7 +18,7 @@ t.test('with workspaces', async (t) => { await t.resolveMatchSnapshot(s.readdirSource()) }) -t.test('workspaces only', async (t) => { +t.test('workspaces only', async t => { const s = await setup(t, { package: { templateOSS: { @@ -32,7 +32,7 @@ t.test('workspaces only', async (t) => { await t.resolveMatchSnapshot(s.readdirSource()) }) -t.test('with content path', async (t) => { +t.test('with content path', async t => { const s = await setup(t, { package: { templateOSS: { @@ -50,7 +50,7 @@ t.test('with content path', async (t) => { await t.resolveMatchSnapshot(s.readdirSource()) }) -t.test('workspaces with nested content path', async (t) => { +t.test('workspaces with nested content path', async t => { const s = await setup(t, { package: { templateOSS: { diff --git a/test/apply/tap.js b/test/apply/tap.js index 2a204877..7dbf076c 100644 --- a/test/apply/tap.js +++ b/test/apply/tap.js @@ -1,7 +1,7 @@ const t = require('tap') const setup = require('../setup.js') -t.test('tap@18', async (t) => { +t.test('tap@18', async t => { const s = await setup(t, { ok: true, package: { @@ -16,7 +16,7 @@ t.test('tap@18', async (t) => { t.strictSame(pkg.tap, {}) }) -t.test('tap@16', async (t) => { +t.test('tap@16', async t => { const s = await setup(t, { ok: true, package: { @@ -29,9 +29,6 @@ t.test('tap@16', async (t) => { await s.apply() const pkg = await s.readJson('package.json') t.strictSame(pkg.tap, { - 'nyc-arg': [ - '--exclude', - 'tap-snapshots/**', - ], + 'nyc-arg': ['--exclude', 'tap-snapshots/**'], }) }) diff --git a/test/apply/typescript.js b/test/apply/typescript.js index 7bf5f458..42f09b1a 100644 --- a/test/apply/typescript.js +++ b/test/apply/typescript.js @@ -1,7 +1,7 @@ const t = require('tap') const setup = require('../setup.js') -t.test('basic', async (t) => { +t.test('basic', async t => { const s = await setup(t, { ok: true, package: { @@ -33,7 +33,7 @@ t.test('basic', async (t) => { t.ok(await s.exists('.commitlintrc.cjs')) }) -t.test('no default content', async (t) => { +t.test('no default content', async t => { const s = await setup(t, { ok: true, package: { @@ -56,7 +56,7 @@ t.test('no default content', async (t) => { t.strictSame(checks[0].body, ['typescript', 'tshy', '@typescript-eslint/parser']) }) -t.test('with tap 16', async (t) => { +t.test('with tap 16', async t => { const s = await setup(t, { ok: true, package: { diff --git a/test/apply/version.js b/test/apply/version.js index 83e9607d..10286273 100644 --- a/test/apply/version.js +++ b/test/apply/version.js @@ -2,7 +2,7 @@ const t = require('tap') const { join } = require('path') const setup = require('../setup.js') -t.test('applies version', async (t) => { +t.test('applies version', async t => { const s = await setup(t, { package: { templateOSS: { diff --git a/test/bin/apply.js b/test/bin/apply.js index 9c80e2f9..c4a32c39 100644 --- a/test/bin/apply.js +++ b/test/bin/apply.js @@ -1,8 +1,12 @@ const t = require('tap') -const templateApply = (mocks) => t.mock('../../bin/apply.js', mocks && { - '../../lib/apply/index.js': async () => mocks(), -}) +const templateApply = mocks => + t.mock( + '../../bin/apply.js', + mocks && { + '../../lib/apply/index.js': async () => mocks(), + }, + ) const _console = console const _global = process.env.npm_config_global @@ -27,26 +31,26 @@ t.afterEach(() => { } }) -t.test('when npm_config_local_prefix is unset, does nothing', async (t) => { +t.test('when npm_config_local_prefix is unset, does nothing', async t => { await templateApply() t.notOk(process.exitCode, 'exitCode is unset') }) -t.test('when npm_config_global is true, does nothing', async (t) => { +t.test('when npm_config_global is true, does nothing', async t => { process.env.npm_config_global = 'true' await templateApply() t.notOk(process.exitCode, 'exitCode is unset') }) -t.test('with mocks', async (t) => { +t.test('with mocks', async t => { process.env.npm_config_local_prefix = 'heynow' await templateApply(() => {}) t.notOk(process.exitCode, 'exitCode is unset') }) -t.test('error', async (t) => { +t.test('error', async t => { process.env.npm_config_local_prefix = 'heynow' await templateApply(() => { diff --git a/test/bin/check.js b/test/bin/check.js index 40b3704b..b6a4654b 100644 --- a/test/bin/check.js +++ b/test/bin/check.js @@ -1,8 +1,12 @@ const t = require('tap') -const templateCheck = (mocks) => t.mock('../../bin/check.js', mocks && { - '../../lib/check/index.js': async () => mocks(), -}) +const templateCheck = mocks => + t.mock( + '../../bin/check.js', + mocks && { + '../../lib/check/index.js': async () => mocks(), + }, + ) const _console = console const _prefix = process.env.npm_config_local_prefix @@ -25,7 +29,7 @@ t.afterEach(() => { } }) -t.test('no local prefix', async (t) => { +t.test('no local prefix', async t => { await templateCheck() t.equal(process.exitCode, 1, 'exit code') @@ -33,24 +37,27 @@ t.test('no local prefix', async (t) => { t.equal(errors.length, 1) }) -t.test('problems', async (t) => { +t.test('problems', async t => { process.env.npm_config_local_prefix = t.testdir() - await templateCheck(() => [{ - title: 'message1', - body: ['a', 'b'], - solution: 'solution1', - }, { - title: 'message2', - body: ['c'], - solution: 'solution2', - }]) + await templateCheck(() => [ + { + title: 'message1', + body: ['a', 'b'], + solution: 'solution1', + }, + { + title: 'message2', + body: ['c'], + solution: 'solution2', + }, + ]) t.ok(process.exitCode, 'exit code') t.matchSnapshot(errors.join('\n')) }) -t.test('no problems', async (t) => { +t.test('no problems', async t => { process.env.npm_config_local_prefix = t.testdir() await templateCheck(() => []) diff --git a/test/check/diff-snapshots.js b/test/check/diff-snapshots.js index 569b362d..36f3a61a 100644 --- a/test/check/diff-snapshots.js +++ b/test/check/diff-snapshots.js @@ -5,7 +5,7 @@ const setup = require('../setup.js') t.cleanSnapshot = setup.clean t.formatSnapshot = setup.format.checks -t.test('update and remove errors', async (t) => { +t.test('update and remove errors', async t => { const s = await setup(t, { ok: true }) await s.apply() @@ -16,17 +16,14 @@ t.test('update and remove errors', async (t) => { const ci = await s.readFile(ciPath) await s.writeFile(ciPath, ci.split('\n').slice(0, -21).join('\n')) - await s.appendFile( - join('.github', 'workflows', 'audit.yml'), - '>>>>I HOPE THIS IS NOT VALID YAML<<<<<<<<<<<' - ) + await s.appendFile(join('.github', 'workflows', 'audit.yml'), '>>>>I HOPE THIS IS NOT VALID YAML<<<<<<<<<<<') await s.writeFile('.eslintrc.json', 'this has to be deleted') await t.resolveMatchSnapshot(s.check()) }) -t.test('will diff json', async (t) => { +t.test('will diff json', async t => { const s = await setup(t, { ok: true }) await s.apply() @@ -44,7 +41,7 @@ t.test('will diff json', async (t) => { await t.resolveMatchSnapshot(s.check()) }) -t.test('json overwrite', async (t) => { +t.test('json overwrite', async t => { const s = await setup(t, { package: { templateOSS: { @@ -66,7 +63,7 @@ t.test('json overwrite', async (t) => { t.strictSame(await s.check(), []) }) -t.test('json merge', async (t) => { +t.test('json merge', async t => { const s = await setup(t, { package: { templateOSS: { @@ -88,7 +85,7 @@ t.test('json merge', async (t) => { t.strictSame(await s.check(), []) }) -t.test('json delete', async (t) => { +t.test('json delete', async t => { const s = await setup(t, { package: { templateOSS: { @@ -110,7 +107,7 @@ t.test('json delete', async (t) => { t.strictSame(await s.check(), []) }) -t.test('different headers', async (t) => { +t.test('different headers', async t => { const s = await setup(t, { package: { templateOSS: { @@ -131,7 +128,7 @@ t.test('different headers', async (t) => { t.strictSame(await s.check(), []) }) -t.test('unknown file type', async (t) => { +t.test('unknown file type', async t => { const s = await setup(t, { package: { templateOSS: { diff --git a/test/check/dogfood.js b/test/check/dogfood.js index 152997b6..aefd89b1 100644 --- a/test/check/dogfood.js +++ b/test/check/dogfood.js @@ -2,7 +2,7 @@ const t = require('tap') const { resolve } = require('path') const check = require('../../lib/check/index.js') -t.test('this repo passes all checks', async (t) => { +t.test('this repo passes all checks', async t => { const root = resolve(__dirname, '..', '..') const res = await check(root) t.equal(res.length, 0) diff --git a/test/check/engines.js b/test/check/engines.js index 7e5741c1..f9c51dcf 100644 --- a/test/check/engines.js +++ b/test/check/engines.js @@ -1,68 +1,69 @@ const t = require('tap') const setup = require('../setup.js') -const setupEngines = ({ engines, omitEngines }) => setup(t, { - ok: true, - package: { - engines: { node: engines }, - templateOSS: { - omitEngines, - }, - dependencies: { - eighteen: '1.0.0', - sixteen: '1.0.0', - nothing: '1.0.0', - anything: '1.0.0', - ohdoteight: '1.0.0', - }, - }, - testdir: { - node_modules: { - nothing: { - 'package.json': JSON.stringify({ - name: 'nothing', - version: '1.0.0', - }), - }, - anything: { - 'package.json': JSON.stringify({ - name: 'anything', - version: '1.0.0', - engines: { - node: '*', - }, - }), +const setupEngines = ({ engines, omitEngines }) => + setup(t, { + ok: true, + package: { + engines: { node: engines }, + templateOSS: { + omitEngines, }, - ohdoteight: { - 'package.json': JSON.stringify({ - name: 'ohdoteight', - version: '1.0.0', - engines: { - node: '>=0.8', - }, - }), + dependencies: { + eighteen: '1.0.0', + sixteen: '1.0.0', + nothing: '1.0.0', + anything: '1.0.0', + ohdoteight: '1.0.0', }, - eighteen: { - 'package.json': JSON.stringify({ - name: 'eighteen', - version: '1.0.0', - engines: { - node: '>=18', - }, - }), - }, - sixteen: { - 'package.json': JSON.stringify({ - name: 'sixteen', - version: '1.0.0', - engines: { - node: '>=16', - }, - }), + }, + testdir: { + node_modules: { + nothing: { + 'package.json': JSON.stringify({ + name: 'nothing', + version: '1.0.0', + }), + }, + anything: { + 'package.json': JSON.stringify({ + name: 'anything', + version: '1.0.0', + engines: { + node: '*', + }, + }), + }, + ohdoteight: { + 'package.json': JSON.stringify({ + name: 'ohdoteight', + version: '1.0.0', + engines: { + node: '>=0.8', + }, + }), + }, + eighteen: { + 'package.json': JSON.stringify({ + name: 'eighteen', + version: '1.0.0', + engines: { + node: '>=18', + }, + }), + }, + sixteen: { + 'package.json': JSON.stringify({ + name: 'sixteen', + version: '1.0.0', + engines: { + node: '>=16', + }, + }), + }, }, }, - }, -}) + }) const cases = [ [['^14 || ^16 || >=18'], ['eighteen', 'sixteen']], diff --git a/test/check/gitignore.js b/test/check/gitignore.js index 614de7dc..b2cb9778 100644 --- a/test/check/gitignore.js +++ b/test/check/gitignore.js @@ -1,7 +1,7 @@ const t = require('tap') const setup = require('../setup.js') -t.test('allow package-lock', async (t) => { +t.test('allow package-lock', async t => { const s = await setup.git(t, { ok: true, package: { diff --git a/test/check/index.js b/test/check/index.js index d0205c9a..d3cf0912 100644 --- a/test/check/index.js +++ b/test/check/index.js @@ -1,7 +1,7 @@ const t = require('tap') const setup = require('../setup.js') -t.test('empty content is ok', async (t) => { +t.test('empty content is ok', async t => { const s = await setup(t, { package: { templateOSS: { diff --git a/test/check/required.js b/test/check/required.js index b94cfd3d..cc3615c4 100644 --- a/test/check/required.js +++ b/test/check/required.js @@ -1,7 +1,7 @@ const t = require('tap') const setup = require('../setup.js') -t.test('ok with required', async (t) => { +t.test('ok with required', async t => { const s = await setup(t, { ok: true, }) @@ -9,7 +9,7 @@ t.test('ok with required', async (t) => { t.strictSame(await s.check(), []) }) -t.test('required in each location', async (t) => { +t.test('required in each location', async t => { const s = await setup(t, { package: { dependencies: { @@ -44,18 +44,16 @@ t.test('required in each location', async (t) => { t.strictSame(await s.check(), []) }) -t.test('can be pinned', async (t) => { +t.test('can be pinned', async t => { const config = { templateOSS: { requiredPackages: { - devDependencies: [ - 'a@1.0.0', - ], + devDependencies: ['a@1.0.0'], }, }, } - await t.test('ok', async (t) => { + await t.test('ok', async t => { const s = await setup(t, { package: { devDependencies: { @@ -69,7 +67,7 @@ t.test('can be pinned', async (t) => { t.strictSame(await s.check(), []) }) - await t.test('not ok', async (t) => { + await t.test('not ok', async t => { const s = await setup(t, { package: { devDependencies: { diff --git a/test/check/snapshots.js b/test/check/snapshots.js index 07fd3c38..fa812e1b 100644 --- a/test/check/snapshots.js +++ b/test/check/snapshots.js @@ -5,25 +5,25 @@ const setup = require('../setup.js') t.cleanSnapshot = setup.clean t.formatSnapshot = setup.format.checks -t.test('check empty dir', async (t) => { +t.test('check empty dir', async t => { const s = await setup(t) await t.resolveMatchSnapshot(s.check()) }) -t.test('workspaces with empty dir', async (t) => { +t.test('workspaces with empty dir', async t => { const s = await setup(t, { workspaces: { a: '@name/aaaa', b: 'bbb' }, }) await t.resolveMatchSnapshot(s.check()) }) -t.test('not ok without required', async (t) => { +t.test('not ok without required', async t => { const s = await setup(t) await s.apply() await t.resolveMatchSnapshot(s.check()) }) -t.test('changelog', async (t) => { +t.test('changelog', async t => { const s = await setup(t, { ok: true, testdir: { @@ -34,7 +34,7 @@ t.test('changelog', async (t) => { await t.resolveMatchSnapshot(s.check()) }) -t.test('gitignore', async (t) => { +t.test('gitignore', async t => { const s = await setup.git(t, { ok: true }) await s.writeFile('ignorethis', 'empty') @@ -45,7 +45,7 @@ t.test('gitignore', async (t) => { await t.resolveMatchSnapshot(s.check()) }) -t.test('gitignore with workspaces workspace', async (t) => { +t.test('gitignore with workspaces workspace', async t => { const s = await setup.git(t, { ok: true, workspaces: { @@ -63,7 +63,7 @@ t.test('gitignore with workspaces workspace', async (t) => { await t.resolveMatchSnapshot(s.check()) }) -t.test('unwanted', async (t) => { +t.test('unwanted', async t => { const s = await setup(t, { ok: true, package: { diff --git a/test/check/unwanted.js b/test/check/unwanted.js index 1d49912c..d50487e1 100644 --- a/test/check/unwanted.js +++ b/test/check/unwanted.js @@ -1,7 +1,7 @@ const t = require('tap') const setup = require('../setup.js') -t.test('unwanted can be overriden with allow', async (t) => { +t.test('unwanted can be overriden with allow', async t => { const s = await setup(t, { ok: true, package: { @@ -9,9 +9,7 @@ t.test('unwanted can be overriden with allow', async (t) => { eslint: '^8.0.0', }, templateOSS: { - allowedPackages: [ - 'eslint', - ], + allowedPackages: ['eslint'], }, }, }) diff --git a/test/fixtures/header.js b/test/fixtures/header.js index 317dc4f2..c85f15b4 100644 --- a/test/fixtures/header.js +++ b/test/fixtures/header.js @@ -3,21 +3,24 @@ module.exports = { add: { 'header.txt': { file: 'source.txt', - parser: (p) => class extends p.Base { - static header = 'Different header' - }, + parser: p => + class extends p.Base { + static header = 'Different header' + }, }, 'noheader.txt': { file: 'source.txt', - parser: (p) => class extends p.Base { - static header = null - }, + parser: p => + class extends p.Base { + static header = null + }, }, 'nocomment.txt': { file: 'source.txt', - parser: (p) => class extends p.Base { - comment = null - }, + parser: p => + class extends p.Base { + comment = null + }, }, }, }, diff --git a/test/fixtures/json-delete.js b/test/fixtures/json-delete.js index d35a2408..a8c5b12c 100644 --- a/test/fixtures/json-delete.js +++ b/test/fixtures/json-delete.js @@ -3,7 +3,7 @@ module.exports = { add: { 'target.json': { file: 'source.json', - parser: (p) => p.Json, + parser: p => p.Json, }, }, }, diff --git a/test/fixtures/json-merge.js b/test/fixtures/json-merge.js index 69d78c27..54435256 100644 --- a/test/fixtures/json-merge.js +++ b/test/fixtures/json-merge.js @@ -3,7 +3,7 @@ module.exports = { add: { 'target.json': { file: 'source.json', - parser: (p) => p.JsonMerge, + parser: p => p.JsonMerge, }, }, }, diff --git a/test/fixtures/mock-release.js b/test/fixtures/mock-release.js index 0c308a62..9df552d8 100644 --- a/test/fixtures/mock-release.js +++ b/test/fixtures/mock-release.js @@ -11,7 +11,7 @@ const RECORD = 'NOCK_RECORD' in process.env ? true : undefined const REPO = 'npm/npm-cli-release-please' const BRANCH = 'template-oss-mock-testing-branch-do-not-delete' -const getPath = (t) => { +const getPath = t => { const fixtureName = relative(CWD, t.testdirName).split(`${sep}tap-testdir-`)[1] return { fixtureName: basename(fixtureName), @@ -19,7 +19,7 @@ const getPath = (t) => { } } -const setup = (t) => { +const setup = t => { const { fixtureName, fixturePath } = getPath(t) // name snapshots by the fixture name so they are all in separate files. this @@ -80,10 +80,7 @@ const releasePlease = async (t, { setup: s, ...opts } = {}) => { } } -const releaseManager = (t, { - cwd = t.testdir({ 'package.json': '{"name":"pkg"}' }), - ...opts -} = {}) => { +const releaseManager = (t, { cwd = t.testdir({ 'package.json': '{"name":"pkg"}' }), ...opts } = {}) => { const s = setup(t) const ReleaseManager = t.mock('../../lib/release/release-manager.js') return ReleaseManager.run({ diff --git a/test/fixtures/yml-merge.js b/test/fixtures/yml-merge.js index 26e891bd..adee0014 100644 --- a/test/fixtures/yml-merge.js +++ b/test/fixtures/yml-merge.js @@ -3,18 +3,20 @@ module.exports = { add: { 'target.yml': { file: 'source.yml', - parser: (p) => class extends p.YmlMerge { - key = 'key' - id = 'id' - }, + parser: p => + class extends p.YmlMerge { + key = 'key' + id = 'id' + }, }, 'clean-target.yml': { file: 'source.yml', clean: () => true, - parser: (p) => class extends p.YmlMerge { - key = 'key' - id = 'id' - }, + parser: p => + class extends p.YmlMerge { + key = 'key' + id = 'id' + }, }, }, }, diff --git a/test/index.js b/test/index.js index 5563ad00..e4098f0f 100644 --- a/test/index.js +++ b/test/index.js @@ -1,18 +1,18 @@ const t = require('tap') const setup = require('./setup.js') -t.test('apply and check is ok', async (t) => { +t.test('apply and check is ok', async t => { const s = await setup(t, { ok: true }) t.same(await s.runAll(), []) }) -t.test('apply and check multiple is ok', async (t) => { +t.test('apply and check multiple is ok', async t => { const s = await setup(t, { ok: true }) t.same(await s.runAll(), []) t.same(await s.runAll(), []) }) -t.test('apply and check workspaces are ok', async (t) => { +t.test('apply and check workspaces are ok', async t => { const s = await setup(t, { ok: true, workspaces: { a: 'a', b: 'b', c: 'c' }, @@ -21,7 +21,7 @@ t.test('apply and check workspaces are ok', async (t) => { t.same(await s.runAll(), []) }) -t.test('empty content is ok', async (t) => { +t.test('empty content is ok', async t => { const s = await setup(t, { package: { templateOSS: { diff --git a/test/release/changelog.js b/test/release/changelog.js index 06030bca..e0083130 100644 --- a/test/release/changelog.js +++ b/test/release/changelog.js @@ -10,9 +10,7 @@ const mockGitHub = ({ commits, authors }) => ({ // simulate a bad sha passed in that doesnt return a commit acc[`_${c.sha}`] = null } else { - const author = i % 2 - ? { user: { login: 'username' } } - : { name: 'Name' } + const author = i % 2 ? { user: { login: 'username' } } : { name: 'Name' } acc[`_${c.sha}`] = { authors: { nodes: authors ? [author] : [] } } } } @@ -22,12 +20,14 @@ const mockGitHub = ({ commits, authors }) => ({ octokit: { rest: { repos: { - listPullRequestsAssociatedWithCommit: async (commit) => { + listPullRequestsAssociatedWithCommit: async commit => { if (commit.commit_sha === 'd') { return { - data: [{ - number: 50, - }], + data: [ + { + number: 50, + }, + ], } } }, @@ -40,32 +40,37 @@ const mockChangelog = async ({ shas = true, authors = true, previousTag = true, - commits: rawCommits = [{ - sha: 'a', - type: 'feat', - bareMessage: 'Hey now', - scope: 'bin', - }, { - sha: 'b', - type: 'feat', - notes: [{ title: 'BREAKING CHANGE', text: 'breaking' }], - bareMessage: 'b', - pullRequest: { - number: '100', + commits: rawCommits = [ + { + sha: 'a', + type: 'feat', + bareMessage: 'Hey now', + scope: 'bin', + }, + { + sha: 'b', + type: 'feat', + notes: [{ title: 'BREAKING CHANGE', text: 'breaking' }], + bareMessage: 'b', + pullRequest: { + number: '100', + }, + }, + { + sha: 'c', + type: 'deps', + bareMessage: 'test@1.2.3', }, - }, { - sha: 'c', - type: 'deps', - bareMessage: 'test@1.2.3', - }, { - sha: 'd', - type: 'fix', - bareMessage: 'this fixes it', - }], + { + sha: 'd', + type: 'fix', + bareMessage: 'this fixes it', + }, + ], } = {}) => { const commits = rawCommits .map(({ notes = [], ...rest }) => ({ notes, ...rest })) - .map(({ sha, ...rest }) => shas ? { sha, ...rest } : { ...rest }) + .map(({ sha, ...rest }) => (shas ? { sha, ...rest } : { ...rest })) const github = mockGitHub({ commits, authors }) const changelog = new ChangelogNotes(github) @@ -79,7 +84,7 @@ const mockChangelog = async ({ return notes .split('\n') - .map((l) => l.replace(/\d{4}-\d{2}-\d{2}/g, 'DATE')) + .map(l => l.replace(/\d{4}-\d{2}-\d{2}/g, 'DATE')) .filter(Boolean) } @@ -120,39 +125,45 @@ t.test('no tag/authors/shas', async t => { t.test('filters out multiple template oss commits', async t => { const changelog = await mockChangelog({ authors: false, - commits: [{ - sha: 'z', - type: 'fix', - bareMessage: 'just a fix', - }, { - sha: 'a', - type: 'chore', - bareMessage: 'postinstall for dependabot template-oss PR', - pullRequest: { - number: '100', + commits: [ + { + sha: 'z', + type: 'fix', + bareMessage: 'just a fix', }, - }, { - sha: 'b', - type: 'chore', - bareMessage: 'postinstall for dependabot template-oss PR', - pullRequest: { - number: '101', + { + sha: 'a', + type: 'chore', + bareMessage: 'postinstall for dependabot template-oss PR', + pullRequest: { + number: '100', + }, }, - }, { - sha: 'c', - type: 'chore', - bareMessage: 'bump @npmcli/template-oss from 1 to 2', - pullRequest: { - number: '101', + { + sha: 'b', + type: 'chore', + bareMessage: 'postinstall for dependabot template-oss PR', + pullRequest: { + number: '101', + }, }, - }, { - sha: 'd', - type: 'chore', - bareMessage: 'bump @npmcli/template-oss from 0 to 1', - pullRequest: { - number: '100', + { + sha: 'c', + type: 'chore', + bareMessage: 'bump @npmcli/template-oss from 1 to 2', + pullRequest: { + number: '101', + }, + }, + { + sha: 'd', + type: 'chore', + bareMessage: 'bump @npmcli/template-oss from 0 to 1', + pullRequest: { + number: '100', + }, }, - }], + ], }) t.strictSame(changelog, [ '## [1.0.0](https://github.com/npm/cli/compare/v0.1.0...v1.0.0) (DATE)', @@ -169,15 +180,18 @@ t.test('filters out multiple template oss commits', async t => { t.test('empty change log with only chore commits', async t => { const changelog = await mockChangelog({ authors: false, - commits: [{ - sha: 'a', - type: 'chore', - bareMessage: 'some chore', - }, { - sha: 'a', - type: 'chore', - bareMessage: 'another chore', - }], + commits: [ + { + sha: 'a', + type: 'chore', + bareMessage: 'some chore', + }, + { + sha: 'a', + type: 'chore', + bareMessage: 'another chore', + }, + ], }) t.strictSame(changelog, []) }) diff --git a/test/release/release-manager.js b/test/release/release-manager.js index 1da2a306..142fb591 100644 --- a/test/release/release-manager.js +++ b/test/release/release-manager.js @@ -8,13 +8,16 @@ t.test('init', async t => { t.rejects(ReleaseManager.run({})) t.rejects(ReleaseManager.run({ token: 'ok' })) t.rejects(ReleaseManager.run({ token: 'ok', repo: 'ok' })) - t.doesNotThrow(() => new ReleaseManager({ - token: 'ok', - repo: 'ok', - pr: 'ok', - silent: false, - defaultTag: 'latest', - })) + t.doesNotThrow( + () => + new ReleaseManager({ + token: 'ok', + repo: 'ok', + pr: 'ok', + silent: false, + defaultTag: 'latest', + }), + ) }) t.test('mock release manager', async t => { diff --git a/test/release/release-please.js b/test/release/release-please.js index c33431c1..1111dc00 100644 --- a/test/release/release-please.js +++ b/test/release/release-please.js @@ -10,17 +10,18 @@ t.test('init', async t => { await t.rejects(ReleasePlease.run({})) await t.rejects(ReleasePlease.run({ token: 'ok' })) await t.rejects(ReleasePlease.run({ token: 'ok', repo: 'ok' })) - await t.rejects(new ReleasePlease({ - token: 'ok', - repo: 'ok', - branch: 'ok', - defaultTag: 'ok', - }).init()) + await t.rejects( + new ReleasePlease({ + token: 'ok', + repo: 'ok', + branch: 'ok', + defaultTag: 'ok', + }).init(), + ) }) t.todo('cases', async t => { - const execRepo = (cmd, opts) => - execSync(cmd, { cwd: REPO_DIR, encoding: 'utf-8', ...opts }).trim() + const execRepo = (cmd, opts) => execSync(cmd, { cwd: REPO_DIR, encoding: 'utf-8', ...opts }).trim() const updateJSON = (p, fn) => { const file = resolve(REPO_DIR, p) @@ -29,7 +30,7 @@ t.todo('cases', async t => { } let init = false - const before = (s) => { + const before = s => { if (s.record) { execRepo('git pull') execRepo(`git reset --hard origin/${BRANCH}`) @@ -46,7 +47,7 @@ t.todo('cases', async t => { const matchPr = async (t, s, { flags, msg, prerelease }) => { if (s.record) { - updateJSON(join(REPO_DIR, 'release-please-config.json'), (d) => ({ + updateJSON(join(REPO_DIR, 'release-please-config.json'), d => ({ ...d, 'last-release-sha': execRepo('git log --grep="chore: release" --format=format:%H -n1'), 'release-search-depth': 7, diff --git a/test/setup.js b/test/setup.js index 33305b6f..dec4bf2d 100644 --- a/test/setup.js +++ b/test/setup.js @@ -9,7 +9,7 @@ const output = require('../lib/util/output.js') const CONTENT = require('..') const { name: NAME, version: VERSION } = require('../package.json') -const createPackageJson = (pkg) => ({ +const createPackageJson = pkg => ({ 'package.json': JSON.stringify(pkg, null, 2), }) @@ -25,37 +25,41 @@ const pkgWithName = (name, defName) => { } // minimum package.json for no errors -const okPackage = () => Object.entries(CONTENT.requiredPackages) - .reduce((acc, [location, deps]) => { - acc[location] = Object.fromEntries(deps.map((name) => { - const arg = npa(name) - return [arg.name, arg.fetchSpec === 'latest' ? '*' : arg.fetchSpec] - })) - return acc - }, { - engines: { - node: '^14.17.0 || ^16.13.0 || >=18.0.0', +const okPackage = () => + Object.entries(CONTENT.requiredPackages).reduce( + (acc, [location, deps]) => { + acc[location] = Object.fromEntries( + deps.map(name => { + const arg = npa(name) + return [arg.name, arg.fetchSpec === 'latest' ? '*' : arg.fetchSpec] + }), + ) + return acc }, - tap: { - 'nyc-arg': [ - '--exclude', - 'tap-snapshots/**', - ], + { + engines: { + node: '^14.17.0 || ^16.13.0 || >=18.0.0', + }, + tap: { + 'nyc-arg': ['--exclude', 'tap-snapshots/**'], + }, }, - }) + ) const setupRoot = async (t, root, mocks) => { const rootPath = (...p) => join(root, ...p) // fs methods for reading from the root - const rootFs = Object.fromEntries(Object.entries({ - readdir: fs.readdir, - readFile: (p) => fs.readFile(p, { encoding: 'utf-8' }), - writeFile: (p, d) => fs.writeFile(p, d, { encoding: 'utf-8' }), - appendFile: fs.appendFile, - stat: fs.stat, - unlink: fs.unlink, - }).map(([k, fn]) => [k, (p, ...rest) => fn(rootPath(p), ...rest)])) + const rootFs = Object.fromEntries( + Object.entries({ + readdir: fs.readdir, + readFile: p => fs.readFile(p, { encoding: 'utf-8' }), + writeFile: (p, d) => fs.writeFile(p, d, { encoding: 'utf-8' }), + appendFile: fs.appendFile, + stat: fs.stat, + unlink: fs.unlink, + }).map(([k, fn]) => [k, (p, ...rest) => fn(rootPath(p), ...rest)]), + ) // Returns a recurisve list of relative file // paths in the testdir root @@ -68,7 +72,7 @@ const setupRoot = async (t, root, mocks) => { continue } if ((await rootFs.stat(nextPath)).isDirectory()) { - paths.push(...await readdir(nextPath)) + paths.push(...(await readdir(nextPath))) } else { paths.push(nextPath) } @@ -80,7 +84,7 @@ const setupRoot = async (t, root, mocks) => { // paths and the values are the full contents const readdirSource = async (p = '') => { const files = await readdir(p) - const contents = await Promise.all(files.map((f) => rootFs.readFile(f))) + const contents = await Promise.all(files.map(f => rootFs.readFile(f))) return Object.fromEntries(files.map((f, i) => [f, contents[i]])) } @@ -92,9 +96,13 @@ const setupRoot = async (t, root, mocks) => { ...rootFs, readdirSource, readdir, - readJson: async (f) => JSON.parse(await rootFs.readFile(f)), + readJson: async f => JSON.parse(await rootFs.readFile(f)), writeJson: (p, d) => rootFs.writeFile(p, JSON.stringify(d, null, 2)), - exists: (...p) => fs.access(rootPath(...p)).then(() => true).catch(() => false), + exists: (...p) => + fs + .access(rootPath(...p)) + .then(() => true) + .catch(() => false), join: rootPath, apply: () => apply(root), check: () => check(root), @@ -102,18 +110,9 @@ const setupRoot = async (t, root, mocks) => { } } -const setup = async (t, { - package = {}, - workspaces = {}, - testdir = {}, - mocks = {}, - ok = false, -} = {}) => { +const setup = async (t, { package = {}, workspaces = {}, testdir = {}, mocks = {}, ok = false } = {}) => { const wsLookup = {} - const pkg = merge( - ok ? okPackage() : {}, - pkgWithName(package, 'testpkg') - ) + const pkg = merge(ok ? okPackage() : {}, pkgWithName(package, 'testpkg')) // convenience for passing in workspaces as an object // and getting those converted to a proper workspaces array @@ -125,10 +124,7 @@ const setup = async (t, { merge(testdir, { [wsDir]: {} }) for (const [wsBase, wsPkgName] of wsEntries) { - const wsPkg = merge( - pkgWithName(wsPkgName, wsBase), - ok ? okPackage() : {} - ) + const wsPkg = merge(pkgWithName(wsPkgName, wsBase), ok ? okPackage() : {}) const wsPath = posix.join(wsDir, wsBase) // obj to lookup workspaces by path in tests wsLookup[wsBase] = wsPath @@ -139,10 +135,7 @@ const setup = async (t, { // creates dir with a root package.json and // package.json files for each workspace - const root = t.testdir(merge( - createPackageJson(pkg), - testdir - )) + const root = t.testdir(merge(createPackageJson(pkg), testdir)) return { ...(await setupRoot(t, root, mocks)), @@ -152,7 +145,7 @@ const setup = async (t, { const setupGit = async (...args) => { const s = await setup(...args) - const git = (arg) => Git.spawn(arg.split(' '), { cwd: s.root }) + const git = arg => Git.spawn(arg.split(' '), { cwd: s.root }) const gca = async () => { await git('add -A .') @@ -170,19 +163,21 @@ const setupGit = async (...args) => { } } -const cleanSnapshot = (str) => str - .replace(resolve(), '{{ROOT}}') - .replace(/\\+/g, '/') - .replace(/\r\n/g, '\n') - .replace(new RegExp(`("version": "|${esc(NAME)}@)${esc(VERSION)}`, 'g'), '$1{{VERSION}}') +const cleanSnapshot = str => + str + .replace(resolve(), '{{ROOT}}') + .replace(/\\+/g, '/') + .replace(/\r\n/g, '\n') + .replace(new RegExp(`("version": "|${esc(NAME)}@)${esc(VERSION)}`, 'g'), '$1{{VERSION}}') const formatSnapshots = { - checks: (arr) => output(arr).trim(), - readdir: (arr) => arr.sort(localeCompare).join('\n').trim(), - readdirSource: (obj) => Object.entries(obj) - .sort((a, b) => localeCompare(a[0], b[0])) - .map(([file, content]) => [file, '='.repeat(40), content].join('\n').trim()) - .join('\n\n') - .trim(), + checks: arr => output(arr).trim(), + readdir: arr => arr.sort(localeCompare).join('\n').trim(), + readdirSource: obj => + Object.entries(obj) + .sort((a, b) => localeCompare(a[0], b[0])) + .map(([file, content]) => [file, '='.repeat(40), content].join('\n').trim()) + .join('\n\n') + .trim(), } module.exports = setup @@ -192,7 +187,7 @@ module.exports.pkgVersion = VERSION module.exports.clean = cleanSnapshot module.exports.format = formatSnapshots module.exports.okPackage = okPackage -module.exports.fixture = (f) => fs.readFile(resolve(__dirname, 'fixtures', f), 'utf-8') +module.exports.fixture = f => fs.readFile(resolve(__dirname, 'fixtures', f), 'utf-8') module.exports.log = (t, f = () => true) => { const cb = (...args) => f(...args) && console.error(...args) process.on('log', cb) diff --git a/test/util/has-package.js b/test/util/has-package.js index 08921091..df95ee80 100644 --- a/test/util/has-package.js +++ b/test/util/has-package.js @@ -27,13 +27,13 @@ const checks = [ [{ a: '^1.0.0' }, 'a@sometag', false], ] -checks.forEach((args) => { +checks.forEach(args => { const res = args.pop() const [pkg, spec, ...rest] = args t.equal(hasPackage({ dependencies: pkg }, spec, ...rest), res, `${JSON.stringify(pkg)}-${spec}`) }) -t.test('works with file urls', async (t) => { +t.test('works with file urls', async t => { const root = t.testdir({ nested: { 'package.json': JSON.stringify({ @@ -50,7 +50,6 @@ t.test('works with file urls', async (t) => { version: '5.0.1', }), }, - }, }) From b07d17a63391cbefbb08ffc1492460bfb6ce1a7c Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Fri, 17 May 2024 10:13:32 -0700 Subject: [PATCH 07/18] chore: add .git-blame-ignore-revs for initial prettier (#448) --- .git-blame-ignore-revs | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .git-blame-ignore-revs diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 00000000..dedb3286 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,2 @@ +# Initial prettier formatting +b35bca55b28b41773aa6b936fc626bc15b40eae5 From 8252fb28a4e6eb8ffb268f54f79b34f1af1dfe2d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 13:53:51 -0400 Subject: [PATCH 08/18] deps: bump release-please from 16.10.2 to 16.12.0 (#452) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [release-please](https://github.com/googleapis/release-please) from 16.10.2 to 16.12.0.
Release notes

Sourced from release-please's releases.

v16.12.0

16.12.0 (2024-06-06)

Features

Bug Fixes

  • node: do not update versions of packages installed using a protocol (#2281) (eeb1411), closes #2173

v16.11.0

16.11.0 (2024-06-06)

Features

  • php-yoshi: support BEGIN_VERSION_OVERRIDE in php-yoshi (#2300) (b9d4544)
Changelog

Sourced from release-please's changelog.

16.12.0 (2024-06-06)

Features

Bug Fixes

  • node: do not update versions of packages installed using a protocol (#2281) (eeb1411), closes #2173

16.11.0 (2024-06-06)

Features

  • php-yoshi: support BEGIN_VERSION_OVERRIDE in php-yoshi (#2300) (b9d4544)
Commits
  • 3895d89 chore(main): release 16.12.0 (#2303)
  • 719fdf5 feat: issue a combined PR comment for all releases (#2286)
  • eeb1411 fix(node): do not update versions of packages installed using a protocol (#2281)
  • 39adf74 chore(main): release 16.11.0 (#2302)
  • b9d4544 feat(php-yoshi): support BEGIN_VERSION_OVERRIDE in php-yoshi (#2300)
  • 4a26987 chore(deps): update dependency sinon to v18 (#2293)
  • 3d6f6ac chore(deps): update dependency @​types/sinon to v17 (#2292)
  • 656b9a9 ci: use correct release-please-action domain after organization url was chang...
  • cb106cd docs: tweak typo in the spelling of release (#2273)
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=release-please&package-manager=npm_and_yarn&previous-version=16.10.2&new-version=16.12.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gar --- package.json | 2 +- tap-snapshots/test/release/release-manager-npm-cli.js.test.cjs | 2 +- .../test/release/release-manager-prerelease.js.test.cjs | 2 +- .../test/release/release-manager-workspace-names.js.test.cjs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index e6f2c523..7e3d7467 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "minimatch": "^9.0.2", "npm-package-arg": "^11.0.1", "proc-log": "^4.0.0", - "release-please": "16.10.2", + "release-please": "16.12.0", "semver": "^7.3.5", "undici": "^6.7.0", "yaml": "^2.1.1" diff --git a/tap-snapshots/test/release/release-manager-npm-cli.js.test.cjs b/tap-snapshots/test/release/release-manager-npm-cli.js.test.cjs index 13d393ea..ef3dfcaa 100644 --- a/tap-snapshots/test/release/release-manager-npm-cli.js.test.cjs +++ b/tap-snapshots/test/release/release-manager-npm-cli.js.test.cjs @@ -152,7 +152,7 @@ exports[`test/release/release-manager.js TAP npm/cli > must match snapshot 1`] = - [ ] 11. Label and fast-track \`nodejs/node\` PR > **Note**: - > This requires being a \`nodejs\` collaborator. Currently @lukekarrys is so ping them to do these steps! + > This requires being a \`nodejs\` collaborator. This could be you! - Thumbs-up reaction on the Fast-track comment - Add an LGTM / Approval diff --git a/tap-snapshots/test/release/release-manager-prerelease.js.test.cjs b/tap-snapshots/test/release/release-manager-prerelease.js.test.cjs index 05c68584..5379a7fc 100644 --- a/tap-snapshots/test/release/release-manager-prerelease.js.test.cjs +++ b/tap-snapshots/test/release/release-manager-prerelease.js.test.cjs @@ -143,7 +143,7 @@ exports[`test/release/release-manager.js TAP prerelease > must match snapshot 1` - [ ] 10. Label and fast-track \`nodejs/node\` PR > **Note**: - > This requires being a \`nodejs\` collaborator. Currently @lukekarrys is so ping them to do these steps! + > This requires being a \`nodejs\` collaborator. This could be you! - Thumbs-up reaction on the Fast-track comment - Add an LGTM / Approval diff --git a/tap-snapshots/test/release/release-manager-workspace-names.js.test.cjs b/tap-snapshots/test/release/release-manager-workspace-names.js.test.cjs index 0d620a29..e1dd6941 100644 --- a/tap-snapshots/test/release/release-manager-workspace-names.js.test.cjs +++ b/tap-snapshots/test/release/release-manager-workspace-names.js.test.cjs @@ -152,7 +152,7 @@ exports[`test/release/release-manager.js TAP workspace names > expect resolving - [ ] 11. Label and fast-track \`nodejs/node\` PR > **Note**: - > This requires being a \`nodejs\` collaborator. Currently @lukekarrys is so ping them to do these steps! + > This requires being a \`nodejs\` collaborator. This could be you! - Thumbs-up reaction on the Fast-track comment - Add an LGTM / Approval From 9acf69e865666da8c1f73ea45ae2604df8875435 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Jul 2024 11:31:12 -0400 Subject: [PATCH 09/18] chore: release 4.23.0 (#445) :robot: I have created a release *beep* *boop* --- ## [4.23.0](https://github.com/npm/template-oss/compare/v4.22.0...v4.23.0) (2024-06-27) ### Features * [`60ee94f`](https://github.com/npm/template-oss/commit/60ee94f58f085c9f85a73638501a1baac67507a7) [#447](https://github.com/npm/template-oss/pull/447) add prettier support (@lukekarrys, @jumoel) ### Bug Fixes * [`b35bca5`](https://github.com/npm/template-oss/commit/b35bca55b28b41773aa6b936fc626bc15b40eae5) [#447](https://github.com/npm/template-oss/pull/447) run prettier (@lukekarrys) * [`8aef509`](https://github.com/npm/template-oss/commit/8aef509c19639a08a47cf0378ea54799229891ff) [#446](https://github.com/npm/template-oss/pull/446) dont conclude checks if they were never set (#446) (@lukekarrys) * [`9440c4f`](https://github.com/npm/template-oss/commit/9440c4f2a8292d4920d9a6d815a13dbd75146ecf) [#444](https://github.com/npm/template-oss/pull/444) pass releases to publish check (#444) (@lukekarrys) ### Dependencies * [`8252fb2`](https://github.com/npm/template-oss/commit/8252fb28a4e6eb8ffb268f54f79b34f1af1dfe2d) [#452](https://github.com/npm/template-oss/pull/452) bump release-please from 16.10.2 to 16.12.0 (#452) (@dependabot[bot], @wraithgar) ### Chores * [`b07d17a`](https://github.com/npm/template-oss/commit/b07d17a63391cbefbb08ffc1492460bfb6ce1a7c) [#448](https://github.com/npm/template-oss/pull/448) add .git-blame-ignore-revs for initial prettier (#448) (@lukekarrys) * [`210247e`](https://github.com/npm/template-oss/commit/210247ef9622f2f3f9f9924ce30c68e471353896) [#447](https://github.com/npm/template-oss/pull/447) add prettier:true to template-oss config (@lukekarrys, @jumoel) * [`1a073e4`](https://github.com/npm/template-oss/commit/1a073e477827cf8b49edbd694aca536dc545f1ec) [#443](https://github.com/npm/template-oss/pull/443) bump @npmcli/template-oss to 4.22.0 (@lukekarrys) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 22 ++++++++++++++++++++++ package.json | 2 +- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 60136e2f..6d801fc2 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.22.0" + ".": "4.23.0" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 79fd0ce1..5c3b14cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,27 @@ # Changelog +## [4.23.0](https://github.com/npm/template-oss/compare/v4.22.0...v4.23.0) (2024-06-27) + +### Features + +* [`60ee94f`](https://github.com/npm/template-oss/commit/60ee94f58f085c9f85a73638501a1baac67507a7) [#447](https://github.com/npm/template-oss/pull/447) add prettier support (@lukekarrys, @jumoel) + +### Bug Fixes + +* [`b35bca5`](https://github.com/npm/template-oss/commit/b35bca55b28b41773aa6b936fc626bc15b40eae5) [#447](https://github.com/npm/template-oss/pull/447) run prettier (@lukekarrys) +* [`8aef509`](https://github.com/npm/template-oss/commit/8aef509c19639a08a47cf0378ea54799229891ff) [#446](https://github.com/npm/template-oss/pull/446) dont conclude checks if they were never set (#446) (@lukekarrys) +* [`9440c4f`](https://github.com/npm/template-oss/commit/9440c4f2a8292d4920d9a6d815a13dbd75146ecf) [#444](https://github.com/npm/template-oss/pull/444) pass releases to publish check (#444) (@lukekarrys) + +### Dependencies + +* [`8252fb2`](https://github.com/npm/template-oss/commit/8252fb28a4e6eb8ffb268f54f79b34f1af1dfe2d) [#452](https://github.com/npm/template-oss/pull/452) bump release-please from 16.10.2 to 16.12.0 (#452) (@dependabot[bot], @wraithgar) + +### Chores + +* [`b07d17a`](https://github.com/npm/template-oss/commit/b07d17a63391cbefbb08ffc1492460bfb6ce1a7c) [#448](https://github.com/npm/template-oss/pull/448) add .git-blame-ignore-revs for initial prettier (#448) (@lukekarrys) +* [`210247e`](https://github.com/npm/template-oss/commit/210247ef9622f2f3f9f9924ce30c68e471353896) [#447](https://github.com/npm/template-oss/pull/447) add prettier:true to template-oss config (@lukekarrys, @jumoel) +* [`1a073e4`](https://github.com/npm/template-oss/commit/1a073e477827cf8b49edbd694aca536dc545f1ec) [#443](https://github.com/npm/template-oss/pull/443) bump @npmcli/template-oss to 4.22.0 (@lukekarrys) + ## [4.22.0](https://github.com/npm/template-oss/compare/v4.21.4...v4.22.0) (2024-05-03) ### Features diff --git a/package.json b/package.json index 7e3d7467..e1a0b0bd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/template-oss", - "version": "4.22.0", + "version": "4.23.0", "description": "templated files used in npm CLI team oss projects", "main": "lib/content/index.js", "bin": { From ca477050dece8e0f4a628abad67ad79e084a298f Mon Sep 17 00:00:00 2001 From: Chris Sidi Date: Wed, 17 Jul 2024 11:09:50 -0400 Subject: [PATCH 10/18] fix: Use `include-workspace-root` for `/main` in Post Dependabot (#462) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `steps.metadata.outputs.directory` is set to `/main`, not `/`, when `package.json` is at the root of the repository. I suspect adding `target-branch` to `dependabot.yml` (#330) added a `main` segment to Dependabot PR branch names, which changed the value of `steps.metadata.outputs.directory`. By fixing this issue, we shouldn't need to routinely use stafftools to fix up template-oss Dependabot PRs. 🤞🏼 I couldn't quickly find a `bump @npmcli/template-oss` Dependabot PR for a workspace to inspect `steps.metadata.outputs.directory` and fix workspaces support. If that's important, we may want to either enable Dependabot for `npm/cli` or create a separate `template-oss-test` repo. It's not clear if Dependabot will create a PR for `workspace/test-workspace` upon our next release. ### Example Dependabot PR branch names The first PR updates just `@npmcli/template-oss`. The second updates multiple dependencies including `@npmcli/template-oss`. PR | branch name | segments | steps.metadata.outputs.directory -|-|-|- https://github.com/npm/agent/pull/110 | `dependabot/npm_and_yarn/main/npmcli/template-oss-4.23.0` | 5 | `/main` https://github.com/npm/statusboard/pull/877 | `dependabot/npm_and_yarn/main/dependency-updates-4de8b5bfcf` | 4 | `/` ## References Failed "Post Dependabot" run: https://github.com/npm/agent/actions/runs/9963674341/job/27530225303 Fix manually tested here: https://github.com/npm/agent/pull/110/commits/ef85b0854e5ee9c26c289ceeba083edc3339a2bb [branchNameToDirectoryName](https://github.com/dependabot/fetch-metadata/blob/ffa2dc8ffecf17d26f6a81b83f9ef5edd33ba93a/src/dependabot/update_metadata.ts#L31) Bug report: https://github.com/dependabot/fetch-metadata/issues/540 --- .github/actions/create-check/action.yml | 2 +- .github/actions/install-latest-npm/action.yml | 2 +- .github/workflows/post-dependabot.yml | 2 +- SECURITY.md | 2 +- lib/content/SECURITY-md.hbs | 2 +- lib/content/action-create-check-yml.hbs | 2 +- lib/content/action-install-latest-npm-yml.hbs | 2 +- lib/content/post-dependabot-yml.hbs | 5 ++--- lib/util/dependabot.js | 2 +- .../test/apply/source-snapshots.js.test.cjs | 22 +++++++++---------- 10 files changed, 21 insertions(+), 22 deletions(-) diff --git a/.github/actions/create-check/action.yml b/.github/actions/create-check/action.yml index aa24a5b0..d1220c90 100644 --- a/.github/actions/create-check/action.yml +++ b/.github/actions/create-check/action.yml @@ -25,7 +25,7 @@ runs: with: result-encoding: string script: | - const { repo: { owner, repo}, runId, serverUrl } = context + const { repo: { owner, repo}, runId, serverUrl } = context const { JOB_NAME, SHA } = process.env const job = await github.rest.actions.listJobsForWorkflowRun({ diff --git a/.github/actions/install-latest-npm/action.yml b/.github/actions/install-latest-npm/action.yml index 8339dbf0..580603dd 100644 --- a/.github/actions/install-latest-npm/action.yml +++ b/.github/actions/install-latest-npm/action.yml @@ -44,7 +44,7 @@ runs: MATCH=$SPEC echo "Found compatible version: npm@$MATCH" break - fi + fi done if [ -z $MATCH ]; then diff --git a/.github/workflows/post-dependabot.yml b/.github/workflows/post-dependabot.yml index a7ebe12d..1ea8693c 100644 --- a/.github/workflows/post-dependabot.yml +++ b/.github/workflows/post-dependabot.yml @@ -49,7 +49,7 @@ jobs: id: flags run: | dependabot_dir="${{ steps.metadata.outputs.directory }}" - if [[ "$dependabot_dir" == "/" ]]; then + if [[ "$dependabot_dir" == "/" || "$dependabot_dir" == "/main" ]]; then echo "workspace=-iwr" >> $GITHUB_OUTPUT else # strip leading slash from directory so it works as a diff --git a/SECURITY.md b/SECURITY.md index 9cd2deaf..4fe06a2a 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,7 +2,7 @@ GitHub takes the security of our software products and services seriously, including the open source code repositories managed through our GitHub organizations, such as [GitHub](https://github.com/GitHub). -If you believe you have found a security vulnerability in this GitHub-owned open source repository, you can report it to us in one of two ways. +If you believe you have found a security vulnerability in this GitHub-owned open source repository, you can report it to us in one of two ways. If the vulnerability you have found is *not* [in scope for the GitHub Bug Bounty Program](https://bounty.github.com/#scope) or if you do not wish to be considered for a bounty reward, please report the issue to us directly through [opensource-security@github.com](mailto:opensource-security@github.com). diff --git a/lib/content/SECURITY-md.hbs b/lib/content/SECURITY-md.hbs index 2a877aa8..79276315 100644 --- a/lib/content/SECURITY-md.hbs +++ b/lib/content/SECURITY-md.hbs @@ -1,6 +1,6 @@ GitHub takes the security of our software products and services seriously, including the open source code repositories managed through our GitHub organizations, such as [GitHub](https://github.com/GitHub). -If you believe you have found a security vulnerability in this GitHub-owned open source repository, you can report it to us in one of two ways. +If you believe you have found a security vulnerability in this GitHub-owned open source repository, you can report it to us in one of two ways. If the vulnerability you have found is *not* [in scope for the GitHub Bug Bounty Program](https://bounty.github.com/#scope) or if you do not wish to be considered for a bounty reward, please report the issue to us directly through [opensource-security@github.com](mailto:opensource-security@github.com). diff --git a/lib/content/action-create-check-yml.hbs b/lib/content/action-create-check-yml.hbs index 1ac91f97..fe8f10dc 100644 --- a/lib/content/action-create-check-yml.hbs +++ b/lib/content/action-create-check-yml.hbs @@ -23,7 +23,7 @@ runs: with: result-encoding: string script: | - const { repo: { owner, repo}, runId, serverUrl } = context + const { repo: { owner, repo}, runId, serverUrl } = context const { JOB_NAME, SHA } = process.env const job = await github.rest.actions.listJobsForWorkflowRun({ diff --git a/lib/content/action-install-latest-npm-yml.hbs b/lib/content/action-install-latest-npm-yml.hbs index ee423487..c986c18e 100644 --- a/lib/content/action-install-latest-npm-yml.hbs +++ b/lib/content/action-install-latest-npm-yml.hbs @@ -42,7 +42,7 @@ runs: MATCH=$SPEC echo "Found compatible version: npm@$MATCH" break - fi + fi done if [ -z $MATCH ]; then diff --git a/lib/content/post-dependabot-yml.hbs b/lib/content/post-dependabot-yml.hbs index 46cfdc58..6842e490 100644 --- a/lib/content/post-dependabot-yml.hbs +++ b/lib/content/post-dependabot-yml.hbs @@ -26,7 +26,7 @@ jobs: id: flags run: | dependabot_dir="$\{{ steps.metadata.outputs.directory }}" - if [[ "$dependabot_dir" == "/" ]]; then + if [[ "$dependabot_dir" == "/" || "$dependabot_dir" == "/{{ releaseBranch }}" ]]; then echo "workspace=-iwr" >> $GITHUB_OUTPUT else # strip leading slash from directory so it works as a @@ -64,7 +64,7 @@ jobs: run: | git commit -am "$\{{ steps.apply.outputs.message }}" git push - + # If the previous step failed, then reset the commit and remove any workflow changes # and attempt to commit and push again. This is helpful because we will have a commit # with the correct prefix that we can then --amend with @npmcli/stafftools later. @@ -98,4 +98,3 @@ jobs: echo "This PR has a breaking change. Run 'npx -p @npmcli/stafftools gh template-oss-fix'" echo "for more information on how to fix this with a BREAKING CHANGE footer." exit 1 - diff --git a/lib/util/dependabot.js b/lib/util/dependabot.js index 38f4dd8e..5e0df40c 100644 --- a/lib/util/dependabot.js +++ b/lib/util/dependabot.js @@ -1,7 +1,7 @@ const { name: NAME } = require('../../package.json') const { minimatch } = require('minimatch') -const parseDependabotConfig = v => (typeof v === 'string' ? { strategy: v } : v ?? {}) +const parseDependabotConfig = v => (typeof v === 'string' ? { strategy: v } : (v ?? {})) module.exports = (config, defaultConfig, branches) => { const { dependabot } = config diff --git a/tap-snapshots/test/apply/source-snapshots.js.test.cjs b/tap-snapshots/test/apply/source-snapshots.js.test.cjs index 27e0be01..667ebcf9 100644 --- a/tap-snapshots/test/apply/source-snapshots.js.test.cjs +++ b/tap-snapshots/test/apply/source-snapshots.js.test.cjs @@ -72,7 +72,7 @@ runs: with: result-encoding: string script: | - const { repo: { owner, repo}, runId, serverUrl } = context + const { repo: { owner, repo}, runId, serverUrl } = context const { JOB_NAME, SHA } = process.env const job = await github.rest.actions.listJobsForWorkflowRun({ @@ -146,7 +146,7 @@ runs: MATCH=$SPEC echo "Found compatible version: npm@$MATCH" break - fi + fi done if [ -z $MATCH ]; then @@ -725,7 +725,7 @@ jobs: id: flags run: | dependabot_dir="\${{ steps.metadata.outputs.directory }}" - if [[ "$dependabot_dir" == "/" ]]; then + if [[ "$dependabot_dir" == "/" || "$dependabot_dir" == "/main" ]]; then echo "workspace=-iwr" >> $GITHUB_OUTPUT else # strip leading slash from directory so it works as a @@ -1414,7 +1414,7 @@ SECURITY.md GitHub takes the security of our software products and services seriously, including the open source code repositories managed through our GitHub organizations, such as [GitHub](https://github.com/GitHub). -If you believe you have found a security vulnerability in this GitHub-owned open source repository, you can report it to us in one of two ways. +If you believe you have found a security vulnerability in this GitHub-owned open source repository, you can report it to us in one of two ways. If the vulnerability you have found is *not* [in scope for the GitHub Bug Bounty Program](https://bounty.github.com/#scope) or if you do not wish to be considered for a bounty reward, please report the issue to us directly through [opensource-security@github.com](mailto:opensource-security@github.com). @@ -1512,7 +1512,7 @@ runs: with: result-encoding: string script: | - const { repo: { owner, repo}, runId, serverUrl } = context + const { repo: { owner, repo}, runId, serverUrl } = context const { JOB_NAME, SHA } = process.env const job = await github.rest.actions.listJobsForWorkflowRun({ @@ -1586,7 +1586,7 @@ runs: MATCH=$SPEC echo "Found compatible version: npm@$MATCH" break - fi + fi done if [ -z $MATCH ]; then @@ -2383,7 +2383,7 @@ jobs: id: flags run: | dependabot_dir="\${{ steps.metadata.outputs.directory }}" - if [[ "$dependabot_dir" == "/" ]]; then + if [[ "$dependabot_dir" == "/" || "$dependabot_dir" == "/main" ]]; then echo "workspace=-iwr" >> $GITHUB_OUTPUT else # strip leading slash from directory so it works as a @@ -3099,7 +3099,7 @@ SECURITY.md GitHub takes the security of our software products and services seriously, including the open source code repositories managed through our GitHub organizations, such as [GitHub](https://github.com/GitHub). -If you believe you have found a security vulnerability in this GitHub-owned open source repository, you can report it to us in one of two ways. +If you believe you have found a security vulnerability in this GitHub-owned open source repository, you can report it to us in one of two ways. If the vulnerability you have found is *not* [in scope for the GitHub Bug Bounty Program](https://bounty.github.com/#scope) or if you do not wish to be considered for a bounty reward, please report the issue to us directly through [opensource-security@github.com](mailto:opensource-security@github.com). @@ -3300,7 +3300,7 @@ runs: with: result-encoding: string script: | - const { repo: { owner, repo}, runId, serverUrl } = context + const { repo: { owner, repo}, runId, serverUrl } = context const { JOB_NAME, SHA } = process.env const job = await github.rest.actions.listJobsForWorkflowRun({ @@ -3374,7 +3374,7 @@ runs: MATCH=$SPEC echo "Found compatible version: npm@$MATCH" break - fi + fi done if [ -z $MATCH ]; then @@ -3907,7 +3907,7 @@ jobs: id: flags run: | dependabot_dir="\${{ steps.metadata.outputs.directory }}" - if [[ "$dependabot_dir" == "/" ]]; then + if [[ "$dependabot_dir" == "/" || "$dependabot_dir" == "/main" ]]; then echo "workspace=-iwr" >> $GITHUB_OUTPUT else # strip leading slash from directory so it works as a From 4ef5cf6be626cb5265486420634ad231832540ab Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 17 Jul 2024 08:29:17 -0700 Subject: [PATCH 11/18] chore: release 4.23.1 (#463) :robot: I have created a release *beep* *boop* --- ## [4.23.1](https://github.com/npm/template-oss/compare/v4.23.0...v4.23.1) (2024-07-17) ### Bug Fixes * [`ca47705`](https://github.com/npm/template-oss/commit/ca477050dece8e0f4a628abad67ad79e084a298f) [#462](https://github.com/npm/template-oss/pull/462) Use `include-workspace-root` for `/main` in Post Dependabot (#462) (@hashtagchris) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 6 ++++++ package.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 6d801fc2..4bf86e39 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.23.0" + ".": "4.23.1" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c3b14cb..51b6f84c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## [4.23.1](https://github.com/npm/template-oss/compare/v4.23.0...v4.23.1) (2024-07-17) + +### Bug Fixes + +* [`ca47705`](https://github.com/npm/template-oss/commit/ca477050dece8e0f4a628abad67ad79e084a298f) [#462](https://github.com/npm/template-oss/pull/462) Use `include-workspace-root` for `/main` in Post Dependabot (#462) (@hashtagchris) + ## [4.23.0](https://github.com/npm/template-oss/compare/v4.22.0...v4.23.0) (2024-06-27) ### Features diff --git a/package.json b/package.json index e1a0b0bd..518dfb26 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/template-oss", - "version": "4.23.0", + "version": "4.23.1", "description": "templated files used in npm CLI team oss projects", "main": "lib/content/index.js", "bin": { From 87d3ed921f4b180946818558c6fef5817090ebe7 Mon Sep 17 00:00:00 2001 From: Gar Date: Mon, 5 Aug 2024 13:09:00 -0700 Subject: [PATCH 12/18] fix: update codeql runner version (#466) v3 uses a newer nodejs image --- .github/workflows/codeql-analysis.yml | 4 ++-- lib/content/codeql-analysis-yml.hbs | 4 ++-- tap-snapshots/test/apply/source-snapshots.js.test.cjs | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 13efe1b4..15c8efee 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -29,8 +29,8 @@ jobs: git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: javascript - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 diff --git a/lib/content/codeql-analysis-yml.hbs b/lib/content/codeql-analysis-yml.hbs index 78415d3f..cf7601cc 100644 --- a/lib/content/codeql-analysis-yml.hbs +++ b/lib/content/codeql-analysis-yml.hbs @@ -26,8 +26,8 @@ jobs: steps: {{> stepGitYml }} - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: javascript - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 diff --git a/tap-snapshots/test/apply/source-snapshots.js.test.cjs b/tap-snapshots/test/apply/source-snapshots.js.test.cjs index 667ebcf9..bba9adb9 100644 --- a/tap-snapshots/test/apply/source-snapshots.js.test.cjs +++ b/tap-snapshots/test/apply/source-snapshots.js.test.cjs @@ -666,11 +666,11 @@ jobs: git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: javascript - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 .github/workflows/post-dependabot.yml ======================================== @@ -2324,11 +2324,11 @@ jobs: git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: javascript - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 .github/workflows/post-dependabot.yml ======================================== From 6ee703d12a4f1874493ead2be8de207928ca9cb4 Mon Sep 17 00:00:00 2001 From: Chris Sidi Date: Mon, 5 Aug 2024 16:16:56 -0400 Subject: [PATCH 13/18] fix: Don't restrict length for commit message footer (#467) Our breaking change footers related to engine changes are often >100 characters, resulting in commitlint CI failures. Example CI failure: https://github.com/npm/ssri/actions/runs/10169599799/job/28126863705#step:7:12 Associated PR: https://github.com/npm/ssri/pull/137 --- .commitlintrc.js | 1 + lib/content/commitlintrc-js.hbs | 1 + tap-snapshots/test/apply/source-snapshots.js.test.cjs | 2 ++ 3 files changed, 4 insertions(+) diff --git a/.commitlintrc.js b/.commitlintrc.js index e9c80b92..b706e527 100644 --- a/.commitlintrc.js +++ b/.commitlintrc.js @@ -7,5 +7,6 @@ module.exports = { 'header-max-length': [2, 'always', 80], 'subject-case': [0], 'body-max-line-length': [0], + 'footer-max-line-length': [0], }, } diff --git a/lib/content/commitlintrc-js.hbs b/lib/content/commitlintrc-js.hbs index 8b19e3fa..12d63d34 100644 --- a/lib/content/commitlintrc-js.hbs +++ b/lib/content/commitlintrc-js.hbs @@ -5,5 +5,6 @@ module.exports = { 'header-max-length': [2, 'always', 80], 'subject-case': [0], 'body-max-line-length': [0], + 'footer-max-line-length': [0], }, } diff --git a/tap-snapshots/test/apply/source-snapshots.js.test.cjs b/tap-snapshots/test/apply/source-snapshots.js.test.cjs index bba9adb9..5c39d2f1 100644 --- a/tap-snapshots/test/apply/source-snapshots.js.test.cjs +++ b/tap-snapshots/test/apply/source-snapshots.js.test.cjs @@ -17,6 +17,7 @@ module.exports = { 'header-max-length': [2, 'always', 80], 'subject-case': [0], 'body-max-line-length': [0], + 'footer-max-line-length': [0], }, } @@ -1455,6 +1456,7 @@ module.exports = { 'header-max-length': [2, 'always', 80], 'subject-case': [0], 'body-max-line-length': [0], + 'footer-max-line-length': [0], }, } From 6a2200dc746742d9e155df5834b49a779875206e Mon Sep 17 00:00:00 2001 From: Gar Date: Tue, 6 Aug 2024 07:22:19 -0700 Subject: [PATCH 14/18] fix: omit nyc config for all tap versions above 18 (#465) --- lib/config.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/config.js b/lib/config.js index 86ad9fb4..a3912cc0 100644 --- a/lib/config.js +++ b/lib/config.js @@ -169,7 +169,8 @@ const getFullConfig = async ({ cjsExt: esm ? 'cjs' : 'js', deleteJsExt: esm ? 'js' : 'cjs', // tap - tap18: semver.coerce(pkg.pkgJson?.devDependencies?.tap)?.major === 18, + // 18 and up doesn't like nyc-arg + tap18: semver.coerce(pkg.pkgJson?.devDependencies?.tap)?.major >= 18, tap16: semver.coerce(pkg.pkgJson?.devDependencies?.tap)?.major === 16, // booleans to control application of updates isForce, From fa37073fd9a4cc7dea2d783bac7055fb35a3d787 Mon Sep 17 00:00:00 2001 From: Gar Date: Wed, 7 Aug 2024 08:23:52 -0700 Subject: [PATCH 15/18] fix: proper workspace tap config for tap18 and up --- lib/content/package-json.hbs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/content/package-json.hbs b/lib/content/package-json.hbs index 98e7d591..d9523151 100644 --- a/lib/content/package-json.hbs +++ b/lib/content/package-json.hbs @@ -42,7 +42,10 @@ "standard": {{{ del }}}, "tap": { {{#if workspacePaths}} - "test-ignore": "^({{ join workspacePaths "|" }})/", + "exclude": {{#if tap18}}[ + "{{ join workspaceGlobs "," }}" + ]{{else }}{{{ del }}}{{/if}}, + "test-ignore": {{#if tap18}}{{{ del }}}{{else}}"^({{ join workspacePaths "|" }})/"{{/if}}, {{/if}} {{#if typescript}} {{#if tap16}} From bba605f22f7072454fdd7c4999fcc3fe2e6d3aff Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 13 Aug 2024 10:56:53 -0700 Subject: [PATCH 16/18] chore: release 4.23.2 (#468) :robot: I have created a release *beep* *boop* --- ## [4.23.2](https://github.com/npm/template-oss/compare/v4.23.1...v4.23.2) (2024-08-13) ### Bug Fixes * [`fa37073`](https://github.com/npm/template-oss/commit/fa37073fd9a4cc7dea2d783bac7055fb35a3d787) [#469](https://github.com/npm/template-oss/pull/469) proper workspace tap config for tap18 and up (@wraithgar) * [`6a2200d`](https://github.com/npm/template-oss/commit/6a2200dc746742d9e155df5834b49a779875206e) [#465](https://github.com/npm/template-oss/pull/465) omit nyc config for all tap versions above 18 (#465) (@wraithgar) * [`6ee703d`](https://github.com/npm/template-oss/commit/6ee703d12a4f1874493ead2be8de207928ca9cb4) Don't restrict length for commit message footer (#467) (@hashtagchris) * [`87d3ed9`](https://github.com/npm/template-oss/commit/87d3ed921f4b180946818558c6fef5817090ebe7) [#466](https://github.com/npm/template-oss/pull/466) update codeql runner version (#466) (@wraithgar) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 9 +++++++++ package.json | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 4bf86e39..c4b75363 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.23.1" + ".": "4.23.2" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 51b6f84c..cb704790 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## [4.23.2](https://github.com/npm/template-oss/compare/v4.23.1...v4.23.2) (2024-08-13) + +### Bug Fixes + +* [`fa37073`](https://github.com/npm/template-oss/commit/fa37073fd9a4cc7dea2d783bac7055fb35a3d787) [#469](https://github.com/npm/template-oss/pull/469) proper workspace tap config for tap18 and up (@wraithgar) +* [`6a2200d`](https://github.com/npm/template-oss/commit/6a2200dc746742d9e155df5834b49a779875206e) [#465](https://github.com/npm/template-oss/pull/465) omit nyc config for all tap versions above 18 (#465) (@wraithgar) +* [`6ee703d`](https://github.com/npm/template-oss/commit/6ee703d12a4f1874493ead2be8de207928ca9cb4) Don't restrict length for commit message footer (#467) (@hashtagchris) +* [`87d3ed9`](https://github.com/npm/template-oss/commit/87d3ed921f4b180946818558c6fef5817090ebe7) [#466](https://github.com/npm/template-oss/pull/466) update codeql runner version (#466) (@wraithgar) + ## [4.23.1](https://github.com/npm/template-oss/compare/v4.23.0...v4.23.1) (2024-07-17) ### Bug Fixes diff --git a/package.json b/package.json index 518dfb26..1b2d4f7d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/template-oss", - "version": "4.23.1", + "version": "4.23.2", "description": "templated files used in npm CLI team oss projects", "main": "lib/content/index.js", "bin": { From a102a8bc448e0f29de451456b3fc4f563b93b790 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Mon, 26 Aug 2024 13:13:31 -0700 Subject: [PATCH 17/18] fix: no duplicate changelog entries (#471) release-please will re-inject the entire changelog when looking for the existing dependencies section in some cases. Have multiple newlines between sections of the changelog triggers that behavior because it looks for lines that do no start with '*' but it does not account for empty lines --- lib/release/changelog.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/release/changelog.js b/lib/release/changelog.js index 9ee059a7..65af14e7 100644 --- a/lib/release/changelog.js +++ b/lib/release/changelog.js @@ -51,7 +51,7 @@ class Changelog { return '' } - return body.join('\n\n').trim() + return body.join('\n').trim() } } @@ -154,7 +154,7 @@ class ChangelogNotes { const subject = wrapSpecs(commit.bareMessage) entry.push([scope, subject].filter(Boolean).join(' ')) - // A list og the authors github handles or names + // A list of the authors github handles or names if (commit.authors.length) { entry.push(`(${commit.authors.join(', ')})`) } From 68990e6eec10630107ad62f134f891ee1278d87b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 13:49:21 -0700 Subject: [PATCH 18/18] chore: release 4.23.3 (#472) :robot: I have created a release *beep* *boop* --- ## [4.23.3](https://github.com/npm/template-oss/compare/v4.23.2...v4.23.3) (2024-08-26) ### Bug Fixes * [`a102a8b`](https://github.com/npm/template-oss/commit/a102a8bc448e0f29de451456b3fc4f563b93b790) [#471](https://github.com/npm/template-oss/pull/471) no duplicate changelog entries (#471) (@lukekarrys) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 4 ++++ package.json | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index c4b75363..c2955074 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.23.2" + ".": "4.23.3" } diff --git a/CHANGELOG.md b/CHANGELOG.md index cb704790..8041bf1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## [4.23.3](https://github.com/npm/template-oss/compare/v4.23.2...v4.23.3) (2024-08-26) +### Bug Fixes +* [`a102a8b`](https://github.com/npm/template-oss/commit/a102a8bc448e0f29de451456b3fc4f563b93b790) [#471](https://github.com/npm/template-oss/pull/471) no duplicate changelog entries (#471) (@lukekarrys) + ## [4.23.2](https://github.com/npm/template-oss/compare/v4.23.1...v4.23.2) (2024-08-13) ### Bug Fixes diff --git a/package.json b/package.json index 1b2d4f7d..97cc78ea 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/template-oss", - "version": "4.23.2", + "version": "4.23.3", "description": "templated files used in npm CLI team oss projects", "main": "lib/content/index.js", "bin": {