Skip to content

Commit

Permalink
feat(plugins): add plugin for xo config
Browse files Browse the repository at this point in the history
Adds a plugin for [xo](https://github.com/xojs/xo#config). Essentially its an opinionated wrapper
around eslint with a bunch of bundled rules and plugins, and the config object is just the eslint
config object with some extra options. So to keep it consistent with the eslint plugin and avoid
duplication I've just used the eslint helper to parse out any additional eslint plugins that have
been added in the xo config.
  • Loading branch information
bbeesley committed May 3, 2024
1 parent 386e395 commit 2dbbcd2
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 0 deletions.
9 changes: 9 additions & 0 deletions packages/knip/fixtures/plugins/xo/.xo-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
space: true,
prettier: true,
plugins: ['unused-imports'],
parserOptions: {emitDecoratorMetadata: true},
rules: {
'func-names': ['error', 'always'],
},
};
10 changes: 10 additions & 0 deletions packages/knip/fixtures/plugins/xo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "@fixtures/xo",
"devDependencies": {
"xo": "^0.24.0"
},
"xo": {
"space": true,
"plugins": ["eslint-comments"]
}
}
8 changes: 8 additions & 0 deletions packages/knip/fixtures/plugins/xo/xo-config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const mySharedConfig = require('glob');

module.exports = {
...mySharedConfig,
rules: {
'func-names': 'off',
},
};
4 changes: 4 additions & 0 deletions packages/knip/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,10 @@
"title": "wrangler plugin configuration (https://github.com/webpro/knip/blob/main/src/plugins/wrangler/README.md)",
"$ref": "#/definitions/plugin"
},
"xo": {
"title": "xo plugin configuration (https://github.com/webpro/knip/blob/main/src/plugins/xo/README.md)",
"$ref": "#/definitions/plugin"
},
"yorkie": {
"title": "yorkie plugin configuration (https://github.com/webpro/knip/blob/main/src/plugins/yorkie/README.md)",
"$ref": "#/definitions/plugin"
Expand Down
1 change: 1 addition & 0 deletions packages/knip/src/ConfigurationValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export const pluginSchema = z.union([
]);

const pluginsSchema = z.object({
xo: pluginSchema,
astro: pluginSchema,
angular: pluginSchema,
ava: pluginSchema,
Expand Down
1 change: 1 addition & 0 deletions packages/knip/src/plugins/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,4 @@ export { default as webpack } from './webpack/index.js';
export { default as wireit } from './wireit/index.js';
export { default as wrangler } from './wrangler/index.js';
export { default as yorkie } from './yorkie/index.js';
export { default as xo } from './xo/index.js';
34 changes: 34 additions & 0 deletions packages/knip/src/plugins/xo/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { EnablerPatterns } from '#p/types/config.js';
import type { IsPluginEnabled, Plugin, ResolveConfig } from '#p/types/plugins.js';
import { hasDependency } from '#p/util/plugin.js';
import { getDependenciesDeep } from '../eslint/helpers.js';
import type { XOConfig } from './types.js';

// link to xo docs: https://github.com/xojs/xo#config

const title = 'xo';

const enablers: EnablerPatterns = ['xo'];

const isEnabled: IsPluginEnabled = ({ dependencies, config }) =>
hasDependency(dependencies, enablers) || 'xo' in config;

const packageJsonPath = 'xo';
const config: string[] = ['{.,}xo-config.{js,cjs,json,}', 'package.json'];

const entry: string[] = ['{.,}xo-config.{js,cjs}'];

const resolveConfig: ResolveConfig<XOConfig> = async (config, options) => {
const dependencies = await getDependenciesDeep(config, options);
return [...dependencies];
};

export default {
title,
enablers,
isEnabled,
packageJsonPath,
entry,
config,
resolveConfig,
} satisfies Plugin;
15 changes: 15 additions & 0 deletions packages/knip/src/plugins/xo/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { ESLintConfig } from '../eslint/types.js';

export type XOConfig = ESLintConfig & {
envs?: string[] | undefined;
globals?: string[] | undefined;
parser?: string | undefined;
plugins?: string[];
ignores?: string[] | undefined;
nodeVersion?: string | boolean | undefined;
prettier?: boolean | undefined;
printConfig?: string | undefined;
semicolon?: boolean | undefined;
space?: boolean | number | undefined;
webpack?: boolean | object | undefined;
};
27 changes: 27 additions & 0 deletions packages/knip/test/plugins/xo.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { test } from 'bun:test';
import assert from 'node:assert/strict';
import { main } from '../../src/index.js';
import { resolve } from '../../src/util/path.js';
import baseArguments from '../helpers/baseArguments.js';
import baseCounters from '../helpers/baseCounters.js';

const cwd = resolve('fixtures/plugins/xo');

test('Find dependencies with the xo plugin', async () => {
const { issues, counters } = await main({
...baseArguments,
cwd,
});

assert(issues.unlisted['.xo-config.js']['eslint-plugin-unused-imports']);
assert(issues.unlisted['xo-config.cjs']['glob']);
assert(issues.unlisted['package.json']['eslint-plugin-eslint-comments']);

assert.deepEqual(counters, {
...baseCounters,
devDependencies: 1,
processed: 2,
unlisted: 3,
total: 2,
});
});

0 comments on commit 2dbbcd2

Please sign in to comment.