From ebc8c3241f266711046627242735bb5efec94265 Mon Sep 17 00:00:00 2001 From: Will Harney <62956339+wjhsf@users.noreply.github.com> Date: Mon, 22 Jan 2024 14:56:03 -0500 Subject: [PATCH] chore: improve license header checks @W-14846456 (#3951) * chore(scripts): run header check on commit Fail faster than waiting for CI! * fix(scripts): update copyright header check to permit new company name In 2022, Salesforce changed from "salesforce.com, inc." to "Salesforce, Inc." https://investor.salesforce.com/press-releases/press-release-details/2022/Salesforce-Changes-Legal-Name-to-Salesforce-Inc/default.aspx * chore: remove file that doesn't exist from ignore patterns * chore(lint): add copyright header enforcement to eslint This enables auto-fixes, which is an improvment over the check-license-headers.js script. * chore(scripts): add check-license-headers to package.json scripts * fix: check license headers for all files, not just js/ts * chore: remove check-license-headers script Headers are enforced for JS/TS files using eslint. Other file types don't need enforcement. * chore(lint): remove overrides covered by .eslintignore * chore(lint): remove unnecessary rule exception * style: revert to 2-space indent * style: revert to original formatting * chore(scripts): remove package.json script for removed script file --- .eslintrc | 32 +++- .github/workflows/unit.yml | 2 - package.json | 1 + .../__tests__/modules/x/htmlVoid/htmlVoid.js | 6 + .../htmlVoidAdjacentText.js | 6 + .../htmlVoidHtmlNamespace.js | 6 + .../__tests__/modules/x/svgPath/svgPath.js | 6 + .../template-compiler/src/shared/utils.ts | 4 +- scripts/release/version.js | 1 - scripts/tasks/check-license-headers.js | 154 ------------------ yarn.lock | 7 + 11 files changed, 63 insertions(+), 162 deletions(-) delete mode 100644 scripts/tasks/check-license-headers.js diff --git a/.eslintrc b/.eslintrc index f9d030e4c5..bd3b0b18bb 100644 --- a/.eslintrc +++ b/.eslintrc @@ -10,7 +10,8 @@ "jest", "@lwc/lwc-internal", "@typescript-eslint", - "import" + "import", + "header" ], "extends": [ "eslint:recommended", @@ -104,7 +105,22 @@ "name": "@lwc/features", "importNames": ["lwcRuntimeFlags", "runtimeFlags", "default"], "message": "Do not directly import runtime flags from @lwc/features. Use the global lwcRuntimeFlags variable instead." - }] + }], + "header/header": [ + 2, + "block", + [ + "", + { + "pattern": "^ \\* Copyright \\(c\\) \\d{4}, ([sS]alesforce.com, inc|Salesforce, Inc)\\.$", + "template": " * Copyright (c) 2024, Salesforce, Inc." + }, + " * All rights reserved.", + " * SPDX-License-Identifier: MIT", + " * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT", + " " + ] + ] }, "overrides": [ @@ -185,6 +201,16 @@ "benchmark": true, "run": true } - } + }, + { + "files": [ + "packages/@lwc/integration-tests/src/**/!(*.spec.js)", + "packages/@lwc/integration-karma/test/**", + "packages/@lwc/integration-karma/test-hydration/**" + ], + "rules": { + "header/header": "off" + } + } ] } diff --git a/.github/workflows/unit.yml b/.github/workflows/unit.yml index ae9d5dcef2..c8143d86e6 100644 --- a/.github/workflows/unit.yml +++ b/.github/workflows/unit.yml @@ -48,8 +48,6 @@ jobs: - name: Install chromedriver v119 run: yarn add -W chromedriver@^119 - - name: Check missing file headers - run: node ./scripts/tasks/check-license-headers.js - name: Check package.json integrity run: node ./scripts/tasks/check-and-rewrite-package-json.js --test - name: Verify @lwc/shared is tree-shakable diff --git a/package.json b/package.json index 9d5808c254..9eba6bbff5 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "bytes": "^3.1.2", "es-module-lexer": "^1.4.1", "eslint": "^8.56.0", + "eslint-plugin-header": "^3.1.1", "eslint-plugin-import": "^2.29.1", "eslint-plugin-jest": "^27.6.0", "glob": "^10.3.10", diff --git a/packages/@lwc/engine-server/src/__tests__/modules/x/htmlVoid/htmlVoid.js b/packages/@lwc/engine-server/src/__tests__/modules/x/htmlVoid/htmlVoid.js index 0679d2bc10..a6e5603e10 100644 --- a/packages/@lwc/engine-server/src/__tests__/modules/x/htmlVoid/htmlVoid.js +++ b/packages/@lwc/engine-server/src/__tests__/modules/x/htmlVoid/htmlVoid.js @@ -1,3 +1,9 @@ +/* + * Copyright (c) 2024, Salesforce, Inc. + * All rights reserved. + * SPDX-License-Identifier: MIT + * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT + */ import { LightningElement } from 'lwc'; export default class extends LightningElement { diff --git a/packages/@lwc/engine-server/src/__tests__/modules/x/htmlVoidAdjacentText/htmlVoidAdjacentText.js b/packages/@lwc/engine-server/src/__tests__/modules/x/htmlVoidAdjacentText/htmlVoidAdjacentText.js index 0679d2bc10..a6e5603e10 100644 --- a/packages/@lwc/engine-server/src/__tests__/modules/x/htmlVoidAdjacentText/htmlVoidAdjacentText.js +++ b/packages/@lwc/engine-server/src/__tests__/modules/x/htmlVoidAdjacentText/htmlVoidAdjacentText.js @@ -1,3 +1,9 @@ +/* + * Copyright (c) 2024, Salesforce, Inc. + * All rights reserved. + * SPDX-License-Identifier: MIT + * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT + */ import { LightningElement } from 'lwc'; export default class extends LightningElement { diff --git a/packages/@lwc/engine-server/src/__tests__/modules/x/htmlVoidHtmlNamespace/htmlVoidHtmlNamespace.js b/packages/@lwc/engine-server/src/__tests__/modules/x/htmlVoidHtmlNamespace/htmlVoidHtmlNamespace.js index 0679d2bc10..a6e5603e10 100644 --- a/packages/@lwc/engine-server/src/__tests__/modules/x/htmlVoidHtmlNamespace/htmlVoidHtmlNamespace.js +++ b/packages/@lwc/engine-server/src/__tests__/modules/x/htmlVoidHtmlNamespace/htmlVoidHtmlNamespace.js @@ -1,3 +1,9 @@ +/* + * Copyright (c) 2024, Salesforce, Inc. + * All rights reserved. + * SPDX-License-Identifier: MIT + * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT + */ import { LightningElement } from 'lwc'; export default class extends LightningElement { diff --git a/packages/@lwc/engine-server/src/__tests__/modules/x/svgPath/svgPath.js b/packages/@lwc/engine-server/src/__tests__/modules/x/svgPath/svgPath.js index 0679d2bc10..a6e5603e10 100644 --- a/packages/@lwc/engine-server/src/__tests__/modules/x/svgPath/svgPath.js +++ b/packages/@lwc/engine-server/src/__tests__/modules/x/svgPath/svgPath.js @@ -1,3 +1,9 @@ +/* + * Copyright (c) 2024, Salesforce, Inc. + * All rights reserved. + * SPDX-License-Identifier: MIT + * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT + */ import { LightningElement } from 'lwc'; export default class extends LightningElement { diff --git a/packages/@lwc/template-compiler/src/shared/utils.ts b/packages/@lwc/template-compiler/src/shared/utils.ts index 46b9a7dcf5..f01ec38c4e 100644 --- a/packages/@lwc/template-compiler/src/shared/utils.ts +++ b/packages/@lwc/template-compiler/src/shared/utils.ts @@ -1,11 +1,11 @@ -import { DASHED_TAGNAME_ELEMENT_SET } from './constants'; - /* * Copyright (c) 2018, salesforce.com, inc. * All rights reserved. * SPDX-License-Identifier: MIT * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT */ +import { DASHED_TAGNAME_ELEMENT_SET } from './constants'; + export function toPropertyName(attr: string) { let prop = ''; let shouldUpperCaseNext = false; diff --git a/scripts/release/version.js b/scripts/release/version.js index 0d6e7fb017..1f1aa01057 100755 --- a/scripts/release/version.js +++ b/scripts/release/version.js @@ -1,5 +1,4 @@ #!/usr/bin/env node - /* * Copyright (c) 2018, salesforce.com, inc. * All rights reserved. diff --git a/scripts/tasks/check-license-headers.js b/scripts/tasks/check-license-headers.js deleted file mode 100644 index 2555327503..0000000000 --- a/scripts/tasks/check-license-headers.js +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2018, salesforce.com, inc. - * All rights reserved. - * SPDX-License-Identifier: MIT - * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT - */ - -// Borrowed from https://github.com/facebook/jest - -/** - * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -'use strict'; - -const fs = require('fs'); -const { execSync } = require('child_process'); -const { isBinaryFileSync } = require('isbinaryfile'); - -const getFileContents = (path) => fs.readFileSync(path, { encoding: 'utf-8' }); -const isDirectory = (path) => fs.lstatSync(path).isDirectory(); -const createRegExp = (pattern) => new RegExp(pattern); - -const IGNORED_EXTENSIONS = [ - 'lock', - 'patch', - 'exe', - 'bin', - 'cfg', - 'config', - 'conf', - // 'html', // might have LWC components we want the header on - 'md', - 'markdown', - 'opam', - 'osm', - 'descr', - 'rst', - 'json', - 'key', - 'ini', - 'plist', - 'snap', - 'svg', - 'txt', - 'xcodeproj', - 'xcscheme', - 'xml', - 'yaml', - 'yml', - 'textile', - 'tsv', - 'csv', - 'pem', - 'csr', - 'der', - 'crt', - 'cert', - 'cer', - 'p7b', - 'iml', - 'org', - 'podspec', - 'modulemap', - 'pch', - 'lproj', - 'xcworkspace', - 'storyboard', - 'tvml', - 'xib', - 'pbxproj', - 'xcworkspacedata', - 'xccheckout', - 'xcsettings', - 'strings', - 'ipynb', - 'htm', - 'toml', -].map((extension) => createRegExp(`.${extension}$`)); - -const GENERIC_IGNORED_PATTERNS = [ - '(^|/)\\.[^/]+(/|$)', - - //'third[_\\-. ]party/', // to be on the safe side - '^node[_\\-. ]modules/', - 'gradlew\\.bat$', - 'gradlew$', - 'gradle/wrapper/', - '.idea/', - '__init__\\.py$', - '^Setup.hs$', - '^(readme|README|Readme)\\..*$', - 'Cargo\\.toml$', - '^Cartfile.*$', - '^.*\\.xcodeproj/$', - '^.*\\.xcworkspace/$', - '^.*\\.lproj/$', - '^.*\\.bundle/$', - '^MANIFEST\\.in$', -].map(createRegExp); - -const CUSTOM_IGNORED_PATTERNS = [ - // add anything repo specific here - 'babel.config.js', - 'playground/', - '/fixtures/', - '/@lwc/integration-tests/src/(.(?!.*.spec.js$))*$', - '/@lwc/integration-karma/test/.*$', - '/@lwc/integration-karma/test-hydration/.*$', - '/@lwc/engine-server/src/__tests__/modules/.*$', -].map(createRegExp); - -const IGNORED_PATTERNS = [ - ...IGNORED_EXTENSIONS, - ...GENERIC_IGNORED_PATTERNS, - ...CUSTOM_IGNORED_PATTERNS, -]; - -const INCLUDED_PATTERNS = [ - // Any file with an extension - /\.[^/]+$/, -]; - -const COPYRIGHT_HEADER_RE = /Copyright (\(c\))? [0-9]{4}, (s|S)alesforce.com, inc./; - -function needsCopyrightHeader(file) { - const contents = getFileContents(file); - return contents.trim().length > 0 && !COPYRIGHT_HEADER_RE.test(contents); -} - -function check() { - const allFiles = execSync('git ls-files', { encoding: 'utf-8' }).trim().split('\n'); - - const invalidFiles = allFiles.filter( - (file) => - INCLUDED_PATTERNS.some((pattern) => pattern.test(file)) && - !IGNORED_PATTERNS.some((pattern) => pattern.test(file)) && - !isDirectory(file) && - !isBinaryFileSync(file) && - needsCopyrightHeader(file) - ); - - if (invalidFiles.length > 0) { - console.log(`Salesforce copyright header check failed for the following files: - ${invalidFiles.join('\n ')} -Please include the header or add an exception for the file in \`scripts/check-license-headers.js\``); - process.exit(1); - } -} - -check(); diff --git a/yarn.lock b/yarn.lock index 9602cd9182..6e85be39ed 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1265,9 +1265,11 @@ "@lwc/eslint-plugin-lwc-internal@link:./scripts/eslint-plugin": version "0.0.0" + uid "" "@lwc/jest-utils-lwc-internals@link:./scripts/jest/utils": version "0.0.0" + uid "" "@mapbox/node-pre-gyp@^1.0.0": version "1.0.11" @@ -4935,6 +4937,11 @@ eslint-module-utils@^2.8.0: dependencies: debug "^3.2.7" +eslint-plugin-header@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-header/-/eslint-plugin-header-3.1.1.tgz#6ce512432d57675265fac47292b50d1eff11acd6" + integrity sha512-9vlKxuJ4qf793CmeeSrZUvVClw6amtpghq3CuWcB5cUNnWHQhgcqy5eF8oVKFk1G3Y/CbchGfEaw3wiIJaNmVg== + eslint-plugin-import@^2.29.1: version "2.29.1" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz#d45b37b5ef5901d639c15270d74d46d161150643"