From 002273b3f44474339a3d5dd28bab05af8abbb3b7 Mon Sep 17 00:00:00 2001 From: "Grigorii K. Shartsev" Date: Mon, 20 Oct 2025 20:27:48 +0200 Subject: [PATCH 1/2] feat: add @nextcloud/copyright/consistent-copyright/header Signed-off-by: Grigorii K. Shartsev --- lib/configs/javascript.ts | 16 ++ lib/index.ts | 1 + lib/plugins/copyright/index.ts | 17 ++ .../rules/consistent-copyright-header.test.ts | 158 ++++++++++++++++++ .../rules/consistent-copyright-header.ts | 73 ++++++++ lib/plugins/copyright/rules/index.ts | 10 ++ 6 files changed, 275 insertions(+) create mode 100644 lib/plugins/copyright/index.ts create mode 100644 lib/plugins/copyright/rules/consistent-copyright-header.test.ts create mode 100644 lib/plugins/copyright/rules/consistent-copyright-header.ts create mode 100644 lib/plugins/copyright/rules/index.ts diff --git a/lib/configs/javascript.ts b/lib/configs/javascript.ts index 222513e1..7d2708d2 100644 --- a/lib/configs/javascript.ts +++ b/lib/configs/javascript.ts @@ -13,6 +13,7 @@ import { GLOB_FILES_TYPESCRIPT, GLOB_FILES_VUE, } from '../globs.ts' +import copyrightPlugin from '../plugins/copyright/index.ts' import nextcloudPlugin from '../plugins/nextcloud/index.ts' /** @@ -89,6 +90,21 @@ export function javascript(options: ConfigOptions): Linter.Config[] { } ), + // Copyright header enforcement + { + name: 'nextcloud/javascript/copyright', + files: [ + ...GLOB_FILES_JAVASCRIPT, + ...GLOB_FILES_TYPESCRIPT, + ], + plugins: { + '@nextcloud/copyright': copyrightPlugin, + }, + rules: { + '@nextcloud/copyright/consistent-copyright-header': 'error', + }, + }, + // Nextcloud specific overwrite { name: 'nextcloud/javascript/rules', diff --git a/lib/index.ts b/lib/index.ts index 8e8cb32e..35b9a3f1 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -69,6 +69,7 @@ export const recommendedVue2Library = createConfig({ export { default as packageJsonPlugin } from './plugins/packageJson.ts' export { default as nextcloudPlugin } from './plugins/nextcloud/index.ts' export { default as l10nPlugin } from './plugins/l10n/index.ts' +export { default as copyrightPlugin } from './plugins/copyright/index.ts' /** * Generate a configuration based on given options diff --git a/lib/plugins/copyright/index.ts b/lib/plugins/copyright/index.ts new file mode 100644 index 00000000..dc6dd974 --- /dev/null +++ b/lib/plugins/copyright/index.ts @@ -0,0 +1,17 @@ +/*! + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import type { ESLint } from 'eslint' + +import { packageVersion } from '../../version.ts' +import { rules } from './rules/index.ts' + +export default { + meta: { + name: '@nextcloud/copyright-plugin', + version: packageVersion, + }, + rules, +} satisfies ESLint.Plugin diff --git a/lib/plugins/copyright/rules/consistent-copyright-header.test.ts b/lib/plugins/copyright/rules/consistent-copyright-header.test.ts new file mode 100644 index 00000000..a58ff8fb --- /dev/null +++ b/lib/plugins/copyright/rules/consistent-copyright-header.test.ts @@ -0,0 +1,158 @@ +/*! + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import { RuleTester } from 'eslint' +import { describe, it } from 'vitest' +import rule from './consistent-copyright-header.ts' + +const ruleTester = new RuleTester({ + languageOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + }, +}) + +describe('consistent-copyright-header', () => { + it('should pass with correct /*! format and empty line after SPDX header', () => { + ruleTester.run('consistent-copyright-header', rule, { + valid: [ + { + code: `/*! + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +console.log('hello')`, + }, + ], + invalid: [], + }) + }) + + it('should pass with correct /*! format and empty line after old copyright comment', () => { + ruleTester.run('consistent-copyright-header', rule, { + valid: [ + { + code: `/*! + * Copyright (c) 2025 Nextcloud GmbH + */ + +console.log('hello')`, + }, + ], + invalid: [], + }) + }) + + it('should pass with no comments', () => { + ruleTester.run('consistent-copyright-header', rule, { + valid: [ + { + code: 'console.log("no comments here")', + }, + ], + invalid: [], + }) + }) + + it('should skip if the first comment is not at the beginning', () => { + ruleTester.run('consistent-copyright-header', rule, { + valid: [ + { + code: `console.log('hello') +/*! + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */`, + }, + ], + invalid: [], + }) + }) + + it('should skip if the first comment is not a copyright comment', () => { + ruleTester.run('consistent-copyright-header', rule, { + valid: [ + { + code: `/** + * A regular JSDoc comment before Foo function + * + * @param bar {any} - Bar + */ +function foo(bar) {}`, + }, + ], + invalid: [], + }) + }) + + it('should fix JSDoc style /** to /*! format', () => { + ruleTester.run('consistent-copyright-header', rule, { + valid: [], + invalid: [ + { + code: `/** + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +console.log('hello')`, + errors: [{ messageId: 'wrongCommentFormat', data: { format: '/**' } }], + output: `/*! + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +console.log('hello')`, + }, + ], + }) + }) + + it('should fix regular /* to /*! format', () => { + ruleTester.run('consistent-copyright-header', rule, { + valid: [], + invalid: [ + { + code: `/* + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +console.log('hello')`, + errors: [{ messageId: 'wrongCommentFormat', data: { format: '/*' } }], + output: `/*! + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +console.log('hello')`, + }, + ], + }) + }) + + it('should add an empty line after copyright without a single newline', () => { + ruleTester.run('consistent-copyright-header', rule, { + valid: [], + invalid: [ + { + code: `/*! + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +console.log('hello')`, + errors: [{ messageId: 'missingEmptyLine' }], + output: `/*! + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +console.log('hello')`, + }, + ], + }) + }) +}) diff --git a/lib/plugins/copyright/rules/consistent-copyright-header.ts b/lib/plugins/copyright/rules/consistent-copyright-header.ts new file mode 100644 index 00000000..fbe0a52c --- /dev/null +++ b/lib/plugins/copyright/rules/consistent-copyright-header.ts @@ -0,0 +1,73 @@ +/*! + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import type { Rule } from 'eslint' + +export default { + meta: { + fixable: 'code', + type: 'layout', + schema: [], + docs: { + description: 'Enforce a copyright header comments to use the legal comment `/*!` format instead of `/**` or `/*`', + }, + messages: { + wrongCommentFormat: 'Copyright header must use the legal comment format `/*!`, not {{ format }}', + missingEmptyLine: 'Copyright header must be followed by an empty line', + }, + }, + + create(context) { + const sourceCode = context.sourceCode + + return { + Program(node) { + const comments = sourceCode.getAllComments() + + // Only check only the very first block comment + if (comments.length === 0 || comments[0].type !== 'Block' || comments[0].range[0] !== 0) { + return + } + + // Only check if it's actually a copyright comment + if (!comments[0].value.toLowerCase().includes('copyright')) { + return + } + + const comment = comments[0] + const commentText = sourceCode.getText(comment as unknown as Rule.Node) + const commentStart = commentText.match(/^\/\*[^\s]*/)![0] + + // Check for correct /*! comment format + if (commentStart !== '/*!') { + context.report({ + node, + messageId: 'wrongCommentFormat', + data: { format: commentStart }, + fix(fixer) { + return fixer.replaceTextRange( + [comment.range[0], comment.range[0] + commentStart.length], + '/*!', + ) + }, + }) + } + + // Check for empty line after copyright comment + const commentEnd = comment.range[1] + const textAfterComment = sourceCode.getText().slice(commentEnd, commentEnd + 2) + if (textAfterComment !== '\n\n') { + context.report({ + node, + messageId: 'missingEmptyLine', + fix(fixer) { + return fixer.insertTextAfterRange([commentEnd, commentEnd], '\n') + }, + }) + } + }, + } + }, +} satisfies Rule.RuleModule diff --git a/lib/plugins/copyright/rules/index.ts b/lib/plugins/copyright/rules/index.ts new file mode 100644 index 00000000..84ef04d4 --- /dev/null +++ b/lib/plugins/copyright/rules/index.ts @@ -0,0 +1,10 @@ +/*! + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import consistentCopyrightHeader from './consistent-copyright-header.ts' + +export const rules = { + 'consistent-copyright-header': consistentCopyrightHeader, +} From 572be2f5e1cac9ea38f58793225fb9da436a931a Mon Sep 17 00:00:00 2001 From: "Grigorii K. Shartsev" Date: Mon, 20 Oct 2025 20:28:32 +0200 Subject: [PATCH 2/2] chore: lint and adjust tests to the new copyright format Signed-off-by: Grigorii K. Shartsev --- build/format-changelog.mjs | 1 + lib/configs/codeStyle.ts | 1 + lib/configs/documentation.ts | 1 + lib/configs/javascript.ts | 1 + lib/configs/json.ts | 1 + lib/configs/node.ts | 1 + lib/configs/typescript.ts | 1 + lib/configs/vue.ts | 1 + lib/configs/vue2.ts | 1 + lib/configs/vue3.ts | 1 + lib/index.ts | 1 + lib/plugins/l10n/rules/enforce-ellipsis.test.ts | 1 + lib/plugins/l10n/rules/enforce-ellipsis.ts | 1 + lib/plugins/l10n/rules/non-breaking-space-vue.test.ts | 1 + lib/plugins/l10n/rules/non-breaking-space.test.ts | 1 + lib/plugins/l10n/rules/non-breaking-space.ts | 1 + lib/plugins/nextcloud-vue/rules/index.ts | 1 + lib/plugins/nextcloud-vue/rules/no-deprecated-exports.ts | 1 + lib/plugins/nextcloud-vue/rules/no-deprecated-props.ts | 1 + lib/plugins/nextcloud-vue/utils/lib-version-parser.test.ts | 1 + lib/plugins/nextcloud-vue/utils/lib-version-parser.ts | 1 + lib/plugins/nextcloud/index.ts | 1 + lib/plugins/nextcloud/rules/index.ts | 1 + lib/plugins/nextcloud/rules/no-deprecations.test.ts | 1 + lib/plugins/nextcloud/rules/no-deprecations.ts | 1 + lib/plugins/nextcloud/rules/no-removed-apis.test.ts | 1 + lib/plugins/nextcloud/rules/no-removed-apis.ts | 1 + lib/plugins/nextcloud/utils/version-parser.test.ts | 1 + lib/version.ts | 1 + tests/config-codestyle.test.ts | 3 ++- tests/config-javascript.test.ts | 5 +++-- tests/config-typescript.test.ts | 3 ++- tests/fixtures/example-fail.js | 3 ++- tests/fixtures/jsdoc.js | 2 +- tests/fixtures/jsdoc.ts | 2 +- tests/fixtures/typescript-like-jsdoc.js | 3 ++- tests/fixtures/use-before-define.ts | 2 +- tests/fixtures/webpack-nonce.js | 3 ++- tests/setup.ts | 3 ++- tests/vitest.d.ts | 2 +- vitest.config.ts | 1 + 41 files changed, 49 insertions(+), 12 deletions(-) diff --git a/build/format-changelog.mjs b/build/format-changelog.mjs index 1d72c474..2482baa1 100644 --- a/build/format-changelog.mjs +++ b/build/format-changelog.mjs @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: CC0-1.0 */ + /* eslint-disable no-console */ import { readFile, writeFile } from 'node:fs/promises' diff --git a/lib/configs/codeStyle.ts b/lib/configs/codeStyle.ts index bd12cbf6..287b0430 100644 --- a/lib/configs/codeStyle.ts +++ b/lib/configs/codeStyle.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import type { Linter } from 'eslint' import type { ConfigOptions } from '../types.d.ts' diff --git a/lib/configs/documentation.ts b/lib/configs/documentation.ts index 38036972..427f2f17 100644 --- a/lib/configs/documentation.ts +++ b/lib/configs/documentation.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import type { Linter } from 'eslint' import type { Settings } from 'eslint-plugin-jsdoc/iterateJsdoc.js' import type { ConfigOptions } from '../types.d.ts' diff --git a/lib/configs/javascript.ts b/lib/configs/javascript.ts index 7d2708d2..cb5fb3a6 100644 --- a/lib/configs/javascript.ts +++ b/lib/configs/javascript.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import type { Linter } from 'eslint' import type { ConfigOptions } from '../types.d.ts' diff --git a/lib/configs/json.ts b/lib/configs/json.ts index 4a30772b..a9996d82 100644 --- a/lib/configs/json.ts +++ b/lib/configs/json.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import type { ESLint, Linter } from 'eslint' import jsonPlugin from '@eslint/json' diff --git a/lib/configs/node.ts b/lib/configs/node.ts index 2f1f04aa..fd64becd 100644 --- a/lib/configs/node.ts +++ b/lib/configs/node.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import type { Linter } from 'eslint' import globals from 'globals' diff --git a/lib/configs/typescript.ts b/lib/configs/typescript.ts index 2e6dd563..ab414b6d 100644 --- a/lib/configs/typescript.ts +++ b/lib/configs/typescript.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import type { Linter } from 'eslint' import type { ConfigOptions } from '../types.d.ts' diff --git a/lib/configs/vue.ts b/lib/configs/vue.ts index bc46bd8e..dad06f56 100644 --- a/lib/configs/vue.ts +++ b/lib/configs/vue.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import type { Linter } from 'eslint' import type { ConfigOptions } from '../types.d.ts' diff --git a/lib/configs/vue2.ts b/lib/configs/vue2.ts index 7099257b..940f862a 100644 --- a/lib/configs/vue2.ts +++ b/lib/configs/vue2.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import type { Linter } from 'eslint' import type { ConfigOptions } from '../types.d.ts' diff --git a/lib/configs/vue3.ts b/lib/configs/vue3.ts index 60eaf420..21483728 100644 --- a/lib/configs/vue3.ts +++ b/lib/configs/vue3.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import type { Linter } from 'eslint' import type { ConfigOptions } from '../types.d.ts' diff --git a/lib/index.ts b/lib/index.ts index 35b9a3f1..6bdff7d0 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import type { ConfigOptions } from './types.d.ts' import { codeStyle } from './configs/codeStyle.ts' diff --git a/lib/plugins/l10n/rules/enforce-ellipsis.test.ts b/lib/plugins/l10n/rules/enforce-ellipsis.test.ts index 79072d94..e6dbd2ad 100644 --- a/lib/plugins/l10n/rules/enforce-ellipsis.test.ts +++ b/lib/plugins/l10n/rules/enforce-ellipsis.test.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import { RuleTester } from 'eslint' import { test } from 'vitest' import rule from './enforce-ellipsis.ts' diff --git a/lib/plugins/l10n/rules/enforce-ellipsis.ts b/lib/plugins/l10n/rules/enforce-ellipsis.ts index 40ede43a..6c857988 100644 --- a/lib/plugins/l10n/rules/enforce-ellipsis.ts +++ b/lib/plugins/l10n/rules/enforce-ellipsis.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import type { Rule } from 'eslint' const defineRule = (r: Rule.RuleModule) => r diff --git a/lib/plugins/l10n/rules/non-breaking-space-vue.test.ts b/lib/plugins/l10n/rules/non-breaking-space-vue.test.ts index 5b821f91..87c49361 100644 --- a/lib/plugins/l10n/rules/non-breaking-space-vue.test.ts +++ b/lib/plugins/l10n/rules/non-breaking-space-vue.test.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + /* eslint-disable @nextcloud-l10n/non-breaking-space */ import { RuleTester } from 'eslint' diff --git a/lib/plugins/l10n/rules/non-breaking-space.test.ts b/lib/plugins/l10n/rules/non-breaking-space.test.ts index 270f3cc4..4af72cd1 100644 --- a/lib/plugins/l10n/rules/non-breaking-space.test.ts +++ b/lib/plugins/l10n/rules/non-breaking-space.test.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + /* eslint-disable @nextcloud-l10n/non-breaking-space */ import { RuleTester } from 'eslint' import { test } from 'vitest' diff --git a/lib/plugins/l10n/rules/non-breaking-space.ts b/lib/plugins/l10n/rules/non-breaking-space.ts index 6a0c2e9a..54ca66a8 100644 --- a/lib/plugins/l10n/rules/non-breaking-space.ts +++ b/lib/plugins/l10n/rules/non-breaking-space.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import type { Rule } from 'eslint' const defineRule = (r: Rule.RuleModule) => r diff --git a/lib/plugins/nextcloud-vue/rules/index.ts b/lib/plugins/nextcloud-vue/rules/index.ts index d0f9019d..51af1647 100644 --- a/lib/plugins/nextcloud-vue/rules/index.ts +++ b/lib/plugins/nextcloud-vue/rules/index.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import noDeprecatedExports from './no-deprecated-exports.ts' import noDeprecatedProps from './no-deprecated-props.ts' diff --git a/lib/plugins/nextcloud-vue/rules/no-deprecated-exports.ts b/lib/plugins/nextcloud-vue/rules/no-deprecated-exports.ts index 8b2124ce..ff59e628 100644 --- a/lib/plugins/nextcloud-vue/rules/no-deprecated-exports.ts +++ b/lib/plugins/nextcloud-vue/rules/no-deprecated-exports.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import type { Rule } from 'eslint' import { createLibVersionValidator } from '../utils/lib-version-parser.ts' diff --git a/lib/plugins/nextcloud-vue/rules/no-deprecated-props.ts b/lib/plugins/nextcloud-vue/rules/no-deprecated-props.ts index 8dc1c519..8f6f68d8 100644 --- a/lib/plugins/nextcloud-vue/rules/no-deprecated-props.ts +++ b/lib/plugins/nextcloud-vue/rules/no-deprecated-props.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import type { Rule } from 'eslint' import * as vueUtils from 'eslint-plugin-vue/lib/utils/index.js' diff --git a/lib/plugins/nextcloud-vue/utils/lib-version-parser.test.ts b/lib/plugins/nextcloud-vue/utils/lib-version-parser.test.ts index d56f6065..6bca9816 100644 --- a/lib/plugins/nextcloud-vue/utils/lib-version-parser.test.ts +++ b/lib/plugins/nextcloud-vue/utils/lib-version-parser.test.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import { fs, vol } from 'memfs' import { join } from 'node:path' import { afterAll, afterEach, beforeAll, describe, expect, it, test, vi } from 'vitest' diff --git a/lib/plugins/nextcloud-vue/utils/lib-version-parser.ts b/lib/plugins/nextcloud-vue/utils/lib-version-parser.ts index f4f067bf..81e2002a 100644 --- a/lib/plugins/nextcloud-vue/utils/lib-version-parser.ts +++ b/lib/plugins/nextcloud-vue/utils/lib-version-parser.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import { lstatSync, readFileSync } from 'node:fs' import { dirname, isAbsolute, join, resolve, sep } from 'node:path' import { gte, minVersion, valid } from 'semver' diff --git a/lib/plugins/nextcloud/index.ts b/lib/plugins/nextcloud/index.ts index 35559232..b930e826 100644 --- a/lib/plugins/nextcloud/index.ts +++ b/lib/plugins/nextcloud/index.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import type { ESLint } from 'eslint' import { packageVersion } from '../../version.ts' diff --git a/lib/plugins/nextcloud/rules/index.ts b/lib/plugins/nextcloud/rules/index.ts index 2cbe13e8..9843a202 100644 --- a/lib/plugins/nextcloud/rules/index.ts +++ b/lib/plugins/nextcloud/rules/index.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import type { Rule } from 'eslint' import noDeprecations from './no-deprecations.ts' diff --git a/lib/plugins/nextcloud/rules/no-deprecations.test.ts b/lib/plugins/nextcloud/rules/no-deprecations.test.ts index 2fc9b689..a662aa91 100644 --- a/lib/plugins/nextcloud/rules/no-deprecations.test.ts +++ b/lib/plugins/nextcloud/rules/no-deprecations.test.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import { RuleTester } from 'eslint' import { describe, test } from 'vitest' import rule from './no-deprecations.ts' diff --git a/lib/plugins/nextcloud/rules/no-deprecations.ts b/lib/plugins/nextcloud/rules/no-deprecations.ts index de73a9fa..c35f02d3 100644 --- a/lib/plugins/nextcloud/rules/no-deprecations.ts +++ b/lib/plugins/nextcloud/rules/no-deprecations.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import type { Rule } from 'eslint' import { createVersionValidator } from '../utils/version-parser.ts' diff --git a/lib/plugins/nextcloud/rules/no-removed-apis.test.ts b/lib/plugins/nextcloud/rules/no-removed-apis.test.ts index 47ad46a2..a8f9c4bd 100644 --- a/lib/plugins/nextcloud/rules/no-removed-apis.test.ts +++ b/lib/plugins/nextcloud/rules/no-removed-apis.test.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import { RuleTester } from 'eslint' import { describe, test } from 'vitest' import rule from './no-removed-apis.ts' diff --git a/lib/plugins/nextcloud/rules/no-removed-apis.ts b/lib/plugins/nextcloud/rules/no-removed-apis.ts index 0d17a69a..a1c86601 100644 --- a/lib/plugins/nextcloud/rules/no-removed-apis.ts +++ b/lib/plugins/nextcloud/rules/no-removed-apis.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import type { Rule, Scope } from 'eslint' import { createVersionValidator } from '../utils/version-parser.ts' diff --git a/lib/plugins/nextcloud/utils/version-parser.test.ts b/lib/plugins/nextcloud/utils/version-parser.test.ts index 550f6d1d..545d68e5 100644 --- a/lib/plugins/nextcloud/utils/version-parser.test.ts +++ b/lib/plugins/nextcloud/utils/version-parser.test.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import type { Rule } from 'eslint' import { fs, vol } from 'memfs' diff --git a/lib/version.ts b/lib/version.ts index e8532adc..6d5a0847 100644 --- a/lib/version.ts +++ b/lib/version.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import packageJson from '../package.json' with { type: 'json' } export const packageVersion: string = packageJson.version diff --git a/tests/config-codestyle.test.ts b/tests/config-codestyle.test.ts index e3dd8b3f..57f90b9a 100644 --- a/tests/config-codestyle.test.ts +++ b/tests/config-codestyle.test.ts @@ -1,7 +1,8 @@ -/** +/*! * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import type { Linter } from 'eslint' import { ESLint } from 'eslint' diff --git a/tests/config-javascript.test.ts b/tests/config-javascript.test.ts index c1ca1b20..f6f11819 100644 --- a/tests/config-javascript.test.ts +++ b/tests/config-javascript.test.ts @@ -1,7 +1,8 @@ -/** +/*! * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import type { Linter } from 'eslint' import { ESLint } from 'eslint' @@ -34,7 +35,7 @@ test('some basic issues should fail', async () => { expect(results).toHaveIssue('@stylistic/semi') expect(results).toHaveIssue({ ruleId: 'no-console', - line: 7, + line: 8, }) }) diff --git a/tests/config-typescript.test.ts b/tests/config-typescript.test.ts index a7f193c4..3da92ed9 100644 --- a/tests/config-typescript.test.ts +++ b/tests/config-typescript.test.ts @@ -1,7 +1,8 @@ -/** +/*! * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import type { Linter } from 'eslint' import { ESLint } from 'eslint' diff --git a/tests/fixtures/example-fail.js b/tests/fixtures/example-fail.js index 40edda91..03643e05 100644 --- a/tests/fixtures/example-fail.js +++ b/tests/fixtures/example-fail.js @@ -1,7 +1,8 @@ -/** +/*! * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + //should fail because of missing space on this comment // and usage of `console` and using a semicolon console.log('some'); diff --git a/tests/fixtures/jsdoc.js b/tests/fixtures/jsdoc.js index f25db619..68b65eb8 100644 --- a/tests/fixtures/jsdoc.js +++ b/tests/fixtures/jsdoc.js @@ -1,4 +1,4 @@ -/** +/*! * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ diff --git a/tests/fixtures/jsdoc.ts b/tests/fixtures/jsdoc.ts index f25db619..68b65eb8 100644 --- a/tests/fixtures/jsdoc.ts +++ b/tests/fixtures/jsdoc.ts @@ -1,4 +1,4 @@ -/** +/*! * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ diff --git a/tests/fixtures/typescript-like-jsdoc.js b/tests/fixtures/typescript-like-jsdoc.js index a76f6f96..215dbf8f 100644 --- a/tests/fixtures/typescript-like-jsdoc.js +++ b/tests/fixtures/typescript-like-jsdoc.js @@ -1,7 +1,8 @@ -/** +/*! * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + /** * Some example with Typescript like JSDoc * diff --git a/tests/fixtures/use-before-define.ts b/tests/fixtures/use-before-define.ts index b297f8c5..535a07db 100644 --- a/tests/fixtures/use-before-define.ts +++ b/tests/fixtures/use-before-define.ts @@ -1,4 +1,4 @@ -/** +/*! * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: MIT */ diff --git a/tests/fixtures/webpack-nonce.js b/tests/fixtures/webpack-nonce.js index 94c218df..b947704a 100644 --- a/tests/fixtures/webpack-nonce.js +++ b/tests/fixtures/webpack-nonce.js @@ -1,6 +1,7 @@ -/** +/*! * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + // ignore camelcase for __webpack_ variables __webpack_nonce__ = 'foo_bar' diff --git a/tests/setup.ts b/tests/setup.ts index 5fa271cb..71564dee 100644 --- a/tests/setup.ts +++ b/tests/setup.ts @@ -1,7 +1,8 @@ -/** +/*! * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + import type { ESLint, Linter } from 'eslint' import { expect } from 'vitest' diff --git a/tests/vitest.d.ts b/tests/vitest.d.ts index c3d8659d..ca28cd96 100644 --- a/tests/vitest.d.ts +++ b/tests/vitest.d.ts @@ -1,4 +1,4 @@ -/** +/*! * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ diff --git a/vitest.config.ts b/vitest.config.ts index d522c17b..f703744c 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: CC0-1.0 */ + import type { UserConfig } from 'vitest/node' export default {