Skip to content

Commit

Permalink
feat: wip
Browse files Browse the repository at this point in the history
  • Loading branch information
aramirezj committed Jan 3, 2025
1 parent 49a0ddd commit b101a0d
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 56 deletions.
3 changes: 2 additions & 1 deletion code-pushup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ export default mergeConfigs(
{
plugins: [
await stylelintPlugin({
configFile: 'packages/plugin-stylelint/mocks/fixtures/basic/.stylelintrc.json',
configFile:
'packages/plugin-stylelint/mocks/fixtures/basic/.stylelintrc.json',
files: 'packages/plugin-stylelint/mocks/fixtures/basic/**/*.css', // Adjust the path to your CSS files
}),
],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"extends": "stylelint-config-standard",
"rules": {
"block-no-empty": null
"block-no-empty": "impossibleValue"
}
}
9 changes: 6 additions & 3 deletions packages/plugin-stylelint/src/lib/runner/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { type LinterOptions } from 'stylelint';
import type { RunnerFunction } from '@code-pushup/models';
import type { Audit, RunnerFunction } from '@code-pushup/models';
import { lintStyles } from './stylelint-runner.js';
import { mapStylelintResultsToAudits } from './utils.js';

export function createRunnerFunction(opt: LinterOptions): RunnerFunction {
export function createRunnerFunction(
opt: LinterOptions,
expectedAudits: Audit[],
): RunnerFunction {
return async () => {
const report = await lintStyles(opt);
return mapStylelintResultsToAudits(report);
return mapStylelintResultsToAudits(report, expectedAudits);
};
}
3 changes: 3 additions & 0 deletions packages/plugin-stylelint/src/lib/runner/model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export type NormalizedStyleLintConfig = {
config: { rules: Record<string, unknown[]> };
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import path from 'node:path';
import { describe, expect, it } from 'vitest';
import { getNormalizedConfigForFile } from './normalize-config';

describe('getNormalizedConfigForFile', () => {
it('should load config from specified configFile and respect the value of specifically set rules', async () => {
const configFile = path.join(
process.cwd(),
'packages/plugin-stylelint/mocks/fixtures/basic/.stylelintrc.json',
);

const parsed = await getNormalizedConfigForFile({ configFile });

expect(parsed.config.rules['block-no-empty']).toStrictEqual([
'impossibleValue',
]); // The default value is [ true ], so having the not even valid value from the config file is correct
});

it('should load config from specified configFile and add default rules', async () => {
const configFile = path.join(
process.cwd(),
'packages/plugin-stylelint/mocks/fixtures/basic/.stylelintrc.json',
);

const parsed = await getNormalizedConfigForFile({ configFile });
expect(Object.keys(parsed.config.rules).length).toBeGreaterThan(1);
});
});
16 changes: 10 additions & 6 deletions packages/plugin-stylelint/src/lib/runner/normalize-config.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import stylelint, {getConfigForFile, type LinterOptions} from "stylelint";
import path from "node:path";
import * as process from "node:process";
import path from 'node:path';
import * as process from 'node:process';
import stylelint, { type LinterOptions, getConfigForFile } from 'stylelint';
import type { NormalizedStyleLintConfig } from './model.js';

export function getNormalizedConfigForFile(options: LinterOptions) {
export function getNormalizedConfigForFile(
options: LinterOptions,
): NormalizedStyleLintConfig {
const _linter = stylelint._createLinter(options);
const configFile = options.configFile ?? path.join(options?.cwd ?? process.cwd(), '.stylelintrc.json');
const configFile =
options.configFile ??
path.join(options?.cwd ?? process.cwd(), '.stylelintrc.json');
return getConfigForFile(_linter, configFile);
}

5 changes: 4 additions & 1 deletion packages/plugin-stylelint/src/lib/runner/stylelint-runner.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import stylelint, { type LinterOptions } from 'stylelint';

// Run Stylelint Programmatically
export async function lintStyles({config, ...options}: Omit<LinterOptions, 'formatter'>) {
export async function lintStyles({
config,
...options
}: Omit<LinterOptions, 'formatter'>) {
try {
// eslint-disable-next-line functional/immutable-data
globalThis.console.assert = globalThis.console.assert || (() => {});
Expand Down
37 changes: 24 additions & 13 deletions packages/plugin-stylelint/src/lib/runner/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
import stylelint, { type LintResult } from 'stylelint';
import type { Audit, AuditReport } from '@code-pushup/models';

export function mapStylelintResultsToAudits(results: LintResult[]): Audit[] {
export function mapStylelintResultsToAudits(
results: LintResult[],
expectedAudits: Audit[],
): Audit[] {
const initialAuditMap = expectedAudits.reduce((map, audit) => {
return map.set(audit.slug, {
...audit,
score: 1,
value: 0,
details: {
issues: [],
},
});
}, new Map<string, AuditReport>());

const auditMap = results.reduce((map, result) => {
const { source, warnings } = result;

Expand All @@ -12,23 +26,18 @@ export function mapStylelintResultsToAudits(results: LintResult[]): Audit[] {
return warnings.reduce((innerMap, warning) => {
const { rule, severity, line, text } = warning;

const existingAudit: AuditReport = innerMap.get(rule) || {
slug: rule,
title: '',
score: 1,
value: 0,
details: {
issues: [],
},
};
const existingAudit = innerMap.get(rule);
if (!existingAudit) {
return innerMap;
}

const updatedAudit: AuditReport = {
...existingAudit,
score: 0, // At least one issue exists
value: existingAudit.value + 1,
details: {
issues: [
...(existingAudit?.details?.issues ?? []),
...(existingAudit.details?.issues ?? []),
{
severity,
message: text,
Expand All @@ -43,9 +52,11 @@ export function mapStylelintResultsToAudits(results: LintResult[]): Audit[] {
},
};

return new Map(innerMap).set(rule, updatedAudit);
return innerMap.set(rule, updatedAudit);
}, map);
}, new Map<string, AuditReport>());
}, initialAuditMap);

console.log('auditMap: ', auditMap);

return [...auditMap.values()];
}
Expand Down
50 changes: 23 additions & 27 deletions packages/plugin-stylelint/src/lib/stylelint-plugin.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import {createRequire} from 'node:module';
import type {LinterOptions} from 'stylelint';
import type {Audit, PluginConfig} from '@code-pushup/models';
import {createRunnerFunction} from './runner/index.js';
import {getNormalizedConfigForFile} from "./runner/normalize-config.js";
import { createRequire } from 'node:module';
import type { LinterOptions } from 'stylelint';
import type { PluginConfig } from '@code-pushup/models';
import { createRunnerFunction } from './runner/index.js';
import { getAudits } from './utils.js';


export type StylelintPluginConfig = Pick<LinterOptions, 'configFile' | 'files'> & {
onlyAudits?: string[]
}
export type StylelintPluginConfig = Pick<
LinterOptions,
'configFile' | 'files'
> & {
onlyAudits?: string[];
};

/**
* Instantiates Code PushUp code stylelint plugin for core config.
Expand Down Expand Up @@ -36,7 +38,7 @@ export async function stylelintPlugin(
'../../package.json',
) as typeof import('../../package.json');

console.log('getNormalizedConfigForFile: ', await getNormalizedConfigForFile(options ?? {}));
const audits = await getAudits(options ?? {});

return {
slug: 'stylelint',
Expand All @@ -46,23 +48,17 @@ export async function stylelintPlugin(
docsUrl: 'https://www.npmjs.com/package/@code-pushup/stylelint-plugin/',
packageName: packageJson.name,
version: packageJson.version,
audits: Object.keys(options?.config?.rules ?? {
'color-no-invalid-hex': true,
}).map(slug => ({
slug,
title: slug,
docsUrl: `https://stylelint.io/user-guide/rules/${slug}`,
})),
runner: createRunnerFunction(options ?? {}),
audits,
runner: createRunnerFunction(options ?? {}, audits),
};
}

async function getAudits(options: StylelintPluginConfig): Promise<Audit[]> {
const {onlyAudits = [], ...rawCfg} = options;
const config = await getNormalizedConfigForFile(rawCfg);
return Object.keys(config.rules).filter(rule => onlyAudits.length > 0 && config.rules[rule] !== false).map(rule => ({
slug: rule,
title: rule,
docsUrl: `https://stylelint.io/user-guide/rules/${rule}`,
}));
}
// async function getAudits(options: StylelintPluginConfig): Promise<Audit[]> {
// const {onlyAudits = [], ...rawCfg} = options;
// const config = await getNormalizedConfigForFile(rawCfg);
// return Object.keys(config.rules).filter(rule => onlyAudits.length > 0 && config.rules[rule] !== false).map(rule => ({
// slug: rule,
// title: rule,
// docsUrl: `https://stylelint.io/user-guide/rules/${rule}`,
// }));
// }
17 changes: 17 additions & 0 deletions packages/plugin-stylelint/src/lib/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { Config, ConfigRuleSettings } from 'stylelint';
import type { Audit, Group } from '@code-pushup/models';
import { truncateDescription, truncateTitle } from '@code-pushup/utils';
import { getNormalizedConfigForFile } from './runner/normalize-config';
import type { StylelintPluginConfig } from './stylelint-plugin';

export async function listAuditsAndGroups(
rules: Config['rules'] = [],
Expand Down Expand Up @@ -35,3 +37,18 @@ export function ruleToAudit(rule: ConfigRuleSettings<any, Object>): Audit {
}),
};
}

export function auditSlugToFullAudit(slug: string): Audit {
return {
slug,
title: slug,
docsUrl: `https://stylelint.io/user-guide/rules/${slug}`,
};
}

export async function getAudits(
options: StylelintPluginConfig,
): Promise<Audit[]> {
const normalizedConfig = await getNormalizedConfigForFile(options);
return Object.keys(normalizedConfig.config.rules).map(auditSlugToFullAudit);
}
6 changes: 3 additions & 3 deletions packages/plugin-stylelint/src/scripts/postinstall/bin.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {patchStylelint} from "./index.js";
import { patchStylelint } from './index.js';

(async () => {
await patchStylelint();
console.log("stylelint patched!");
})()
console.log('stylelint patched!');
})();
2 changes: 1 addition & 1 deletion packages/plugin-stylelint/src/scripts/postinstall/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { resolve } from 'node:path';

const absolutesStylelintPath = resolve(
process.cwd(),
'node_modules/stylelint/lib/index.mjs'
'node_modules/stylelint/lib/index.mjs',
);

export async function patchStylelint(stylelintPath = absolutesStylelintPath) {
Expand Down

0 comments on commit b101a0d

Please sign in to comment.