Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: Key "rules": Key "header/header": should NOT have more than 0 items. #57

Closed
firefoxNX opened this issue Jun 8, 2024 · 9 comments · May be fixed by #58
Closed

Error: Key "rules": Key "header/header": should NOT have more than 0 items. #57

firefoxNX opened this issue Jun 8, 2024 · 9 comments · May be fixed by #58

Comments

@firefoxNX
Copy link

using eslint version 9.4.0 with eslint-plugin-header gives this error -

Error: Key "rules": Key "header/header":
	Value ["block",{"pattern":"Copyright \\d{4}, CompanyName, Inc.  All rights reserved.","template":"Copyright 2024, CompanyName, Inc.  All rights reserved."}] should NOT have more than 0 items.

    at RuleValidator.validate (/Users/vineet/Documents/learn_eslint/node_modules/eslint/lib/config/rule-validator.js:170:27)
    at [finalizeConfig] (/Users/vineet/Documents/learn_eslint/node_modules/eslint/lib/config/flat-config-array.js:317:23)
    at FlatConfigArray.getConfigWithStatus (/Users/vineet/Documents/learn_eslint/node_modules/@eslint/config-array/dist/cjs/index.cjs:1145:55)
    at FlatConfigArray.getConfig (/Users/vineet/Documents/learn_eslint/node_modules/@eslint/config-array/dist/cjs/index.cjs:1163:15)
    at ESLint.calculateConfigForFile (/Users/vineet/Documents/learn_eslint/node_modules/eslint/lib/eslint/eslint.js:1169:24)
    at async ESLint.isPathIgnored (/Users/vineet/Documents/learn_eslint/node_modules/eslint/lib/eslint/eslint.js:1191:24)

see https://github.com/firefoxNX/learn_eslint to reproduce the issue.

@tonyganchev
Copy link

Also reproducing this issue.

@tonyganchev
Copy link

Seems that ESLint now mandates that meta.schema field is mandatory for rules with options: https://eslint.org/docs/latest/extend/custom-rules. I went ahead and set schema: false before

and linting passed. I can probably prepare a better fix that actually validates the schema.

@tonyganchev
Copy link

#58 - I have a PR to disable schema validation

@firefoxNX
Copy link
Author

Thanks @tonyganchev. I verified and its working after disabling schema validation.

@Stuk - can you please review the fix?

@tonyganchev
Copy link

I've published a fork at https://www.npmjs.com/package/@tony.ganchev/eslint-plugin-header containing my fix.

@gavinbarron
Copy link

I just spent a little time this afternoon looking at this.
Building it using JSONSchema Draft 2020-12 looks something like this:

{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "$id": "https://json-schema.org/draft/2020-12/schema-enum",
    "type": "array",
    "minItems": 1,
    "maxItems": 3,
    "prefixItems": [
      { 
        "oneOf": [{
        	"type": "string",
        	"enum": ["block", "inline"]
        },{
          "type": "string",
          "pattern": "[.*]*.*.js"
        }]
      },
      {
        "oneOf": [{
        	"type": "string",
        },{
          "type": "array",
          "prefixItems": [
            {
              "oneOf": [
                {
                  "type": "object",
                  "properties": {
                    "pattern": {
                      "type": "string"
                    },
                    "template": {
                    	"type": "string"
                    }
                  },
                  "required": ["pattern"]
                },
                {"type": "string"}
              ]
            },
            {"type": "string"}
          ]
        }]
      },
      {
      	"type": "number",
          "minimum": 0
      }
    ]
}

deribaucourt added a commit to savoirfairelinux/vscode-bitbake that referenced this issue Sep 18, 2024
The latest release is not yet compatible with our version of ESLint.
While awaiting the next release, we'll use a fork which has the fix.

See Stuk/eslint-plugin-header#57
deribaucourt added a commit to savoirfairelinux/vscode-bitbake that referenced this issue Sep 19, 2024
The latest release is not yet compatible with our version of ESLint.
While awaiting the next release, we'll use a fork which has the fix.

See Stuk/eslint-plugin-header#57
deribaucourt added a commit to savoirfairelinux/vscode-bitbake that referenced this issue Sep 24, 2024
The latest release is not yet compatible with our version of ESLint.
While awaiting the next release, we'll use a fork which has the fix.

See Stuk/eslint-plugin-header#57
deribaucourt added a commit to yoctoproject/vscode-bitbake that referenced this issue Sep 26, 2024
The latest release is not yet compatible with our version of ESLint.
While awaiting the next release, we'll use a fork which has the fix.

See Stuk/eslint-plugin-header#57
@Laffery
Copy link

Laffery commented Sep 27, 2024

I add the following code in the eslint.config.js as workaround

const pluginHeader = require('eslint-plugin-header');

+ pluginHeader.rules.header.meta.schema = false;

@firefoxNX
Copy link
Author

Closing because @Laffery's workaround works!

@its-dibo
Copy link

its-dibo commented Dec 31, 2024

I add the following code in the eslint.config.js as workaround

const pluginHeader = require('eslint-plugin-header');

+ pluginHeader.rules.header.meta.schema = false;

I feel this is a good solution, and I want to apply it for require-path-exists/exists rule

this is what I tried to do

this is the source code of the rule

source code

import fs from 'fs-plus';
import path from 'path';
import { execFileSync } from 'child_process';
import builtinModules from 'builtin-modules';
import resolve from 'resolve';

function getCurrentFilePath(context) {
  let filename = context.getFilename();
  if (!fs.isAbsolute(filename)) {
    filename = path.join(process.cwd(), filename);
  }

  return path.dirname(filename);
}

const webpackConfigCache = {};
function getWebpackConfig(fromDir) {
  const pathname = path.resolve(fromDir);
  if (webpackConfigCache[pathname]) {
    return webpackConfigCache[pathname];
  }

  if (!fs.existsSync(pathname)) {
    throw new Error(`Webpack config does not exists at ${pathname}.`);
  }

  const webpackConfigLoadCode = [
    'try {',
    `  var config = JSON.stringify(require('${pathname}'));`,
    '  console.log(config);',
    '} catch (e) {',
    `  console.log('{ "parseError": ' + JSON.stringify(e.message) + ' }');`,
    '}'
  ].join('');

  let result = execFileSync(process.argv[0], [ '-e', webpackConfigLoadCode ]);
  result = result.toString().trim();

  if (!result) {
    throw new Error(`Webpack config is empty at ${pathname}.`);
  }

  result = JSON.parse(result);
  if (result.parseError) {
    throw new Error(`Cannot load Webpack config: ${result.parseError}`);
  }

  webpackConfigCache[pathname] = result;

  return result;
}

function getWebpackAliases(webpackConfigPath) {
  const webpackConfig = getWebpackConfig(webpackConfigPath);

  let alias = {};
  if (typeof webpackConfig.resolve === 'object') {
    if (typeof webpackConfig.resolve.alias === 'object') {
      alias = webpackConfig.resolve.alias;
    }
  }

  return alias;
}

function testModulePath(value, fileDir, aliases = {}, extensions = []) {
  if (builtinModules.indexOf(value) >= 0) {
    return;
  }

  if (aliases[value] !== undefined) {
    value = aliases[value];
  } else {
    for (const key of Object.keys(aliases)) {
      if (value.startsWith(`${key}/`)) {
        value = value.replace(`${key}/`, `${aliases[key]}/`);
        break;
      }
    }
  }

  try {
    resolve.sync(value, {
      basedir: fileDir,
      extensions,
      paths: process.env.NODE_PATH
        ? [process.env.NODE_PATH]
        : undefined
    });
  } catch (e) {
    return e.message;
  }
}

function testRequirePath(fileName, node, context, config) {
  for (let value of fileName.split('!')) {
    const fileDir = getCurrentFilePath(context);
    if (!fileDir) {
      continue;
    }

    try {
      let result = testModulePath(value, fileDir, config.aliases, config.extensions);
      if (result) {
        context.report(node, result, {});
      }
    } catch (e) {
      context.report(node, `Unexpected error in eslint-plugin-require-path-exists: ${e.message}\n${e.stack}`, {});
    }
  }
}

export const exists = context => {
  let pluginSettings = {};
  if (context && context.options && typeof context.options[0] === 'object') {
    pluginSettings = context.options[0];
  }

  const config = {
    extensions: Array.isArray(pluginSettings.extensions) ? pluginSettings.extensions : [ '', '.js', '.json', '.node' ],
    webpackConfigPath: pluginSettings.webpackConfigPath === undefined ? null : pluginSettings.webpackConfigPath,
    aliases: {}
  };

  if (config.webpackConfigPath !== null) {
    config.aliases = getWebpackAliases(config.webpackConfigPath);
  }

  return {
    ImportDeclaration(node) {
      testRequirePath(node.source.value, node, context, config);
    },

    CallExpression(node) {
      if (node.callee.name !== 'require' || !node.arguments.length || typeof node.arguments[0].value !== 'string' || !node.arguments[0].value) {
        return;
      }

      testRequirePath(node.arguments[0].value, node, context, config);
    }
  };
};

as you can see:
1- the rule is a function that return the rule
2- there is no meta property

@Laffery

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants