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

Add basic unicorn setup to ESLint config #1041

Merged
merged 6 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions bin-src/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ export const addChromaticScriptToPackageJson = async ({ packageJson, packagePath
},
};
await writeFile(packagePath, json, { spaces: 2 });
} catch (e) {
console.warn(e);
} catch (err) {
console.warn(err);
}
};

Expand Down
8 changes: 4 additions & 4 deletions bin-src/trim-stats-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { outputFile } from 'fs-extra';

import { readStatsFile } from '../node-src/tasks/read-stats-file';

const dedupe = <T>(arr: T[]) => Array.from(new Set(arr));
const dedupe = <T>(arr: T[]) => [...new Set(arr)];
const isUserCode = ({ name, moduleName = name }: { name?: string; moduleName?: string }) =>
moduleName &&
!moduleName.startsWith('(webpack)') &&
!moduleName.match(/(node_modules|webpack\/runtime)\//);
!/(node_modules|webpack\/runtime)\//.test(moduleName);

/**
* Utility to trim down a `preview-stats.json` file to the bare minimum, so that it can be used to
Expand Down Expand Up @@ -41,8 +41,8 @@ export async function main([statsFile = './storybook-static/preview-stats.json']
await outputFile(
targetFile,
JSON.stringify({ modules: trimmedModules }, null, 2)
.replace(/{\n {10}/g, '{ ')
.replace(/\n {8}}/g, ' }')
.replaceAll(/{\n {10}/g, '{ ')
.replaceAll(/\n {8}}/g, ' }')
);

console.log(`Wrote ${targetFile}`);
Expand Down
81 changes: 49 additions & 32 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import prettier from 'eslint-plugin-prettier';
import security from 'eslint-plugin-security';
import simpleImportSort from 'eslint-plugin-simple-import-sort';
import sortClassMembers from 'eslint-plugin-sort-class-members';
// import unicorn from 'eslint-plugin-unicorn';
import unicorn from 'eslint-plugin-unicorn';
import globals from 'globals';
import tseslint from 'typescript-eslint';

Expand Down Expand Up @@ -51,7 +51,7 @@ export default [
// lint comments
comments.recommended,
{
files: ['**/*.js', '**/*.ts'],
files: ['**/*.js', '**/*.ts', '**/*.jsx', '**/*.tsx'],
rules: {
'@eslint-community/eslint-comments/disable-enable-pair': ['error', { allowWholeFile: true }],
},
Expand Down Expand Up @@ -106,37 +106,54 @@ export default [
},
},
// additional lints from unicorn
// unicorn.configs['flat/recommended'],
// {
// rules: {
// 'unicorn/filename-case': ['error', { case: 'camelCase' }],
// // Chromatic uses err as our catch convention.
// // This is baked into pino transforms as well.
// 'unicorn/prevent-abbreviations': [
// 'error',
// {
// allowList: {
// err: true,
// },
// },
// ],
// 'unicorn/catch-error-name': [
// 'error',
// {
// name: 'err',
// ignore: ['^err.*$'],
// },
// ],
// 'unicorn/switch-case-braces': 'off',
// },
// },
unicorn.configs['flat/recommended'],
{
rules: {
// TODO: Switch this to 'error' when we are ready to enforce this rule
'unicorn/filename-case': ['off', { case: 'camelCase' }],
// Chromatic uses err as our catch convention.
// This is baked into pino transforms as well.
'unicorn/prevent-abbreviations': [
'off', // TODO: Switch this to 'error' when we are ready to enforce this rule
{
allowList: {
err: true,
props: true,
ctx: true,
str: true,
args: true,
docsUrl: true,
},
},
],
'unicorn/catch-error-name': [
'error',
{
ignore: ['err'],
},
],
'unicorn/switch-case-braces': 'off',
'unicorn/no-process-exit': 'off',
'unicorn/prefer-node-protocol': 'off', // This will error our Webpack build
// TODO: remove the following lines when we are ready to enforce this rule
'unicorn/no-anonymous-default-export': 'off',
'unicorn/no-null': 'off',
'unicorn/better-regex': 'off',
'unicorn/no-array-reduce': 'off',
'unicorn/no-array-callback-reference': 'off',
'unicorn/prefer-string-raw': 'off',
'unicorn/prefer-module': 'off',
'unicorn/no-array-for-each': 'off',
'unicorn/prefer-spread': 'off',
},
},
// prefer TS to complain when we miss an arg vs. sending an intentional undefined
// {
// files: ['**/*.ts'],
// rules: {
// 'unicorn/no-useless-undefined': 'off',
// },
// },
{
files: ['**/*.ts'],
rules: {
'unicorn/no-useless-undefined': 'off',
},
},
// security related lints
security.configs.recommended,
{
Expand Down
4 changes: 2 additions & 2 deletions isChromatic.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module.exports = function isChromatic(windowArg) {
const windowToCheck = windowArg || (typeof window !== 'undefined' && window);
return !!(
windowToCheck &&
(windowToCheck.navigator.userAgent.match(/Chromatic/) ||
windowToCheck.location.href.match(/chromatic=true/))
(/Chromatic/.test(windowToCheck.navigator.userAgent) ||
/chromatic=true/.test(windowToCheck.location.href))
);
};
4 changes: 2 additions & 2 deletions isChromatic.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export default function isChromatic(windowArg) {
const windowToCheck = windowArg || (typeof window !== 'undefined' && window);
return !!(
windowToCheck &&
(windowToCheck.navigator.userAgent.match(/Chromatic/) ||
windowToCheck.location.href.match(/chromatic=true/))
(/Chromatic/.test(windowToCheck.navigator.userAgent) ||
/chromatic=true/.test(windowToCheck.location.href))
);
}
2 changes: 2 additions & 0 deletions node-src/__mocks__/storybookBaseDir/subdir/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/* eslint-disable unicorn/no-empty-file */
// This file is intentionally left blank
2 changes: 2 additions & 0 deletions node-src/__mocks__/storybookBaseDir/subdir/test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/* eslint-disable unicorn/no-empty-file */
// This file is intentionally left blank
2 changes: 2 additions & 0 deletions node-src/__mocks__/storybookBaseDir/subdir/test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/* eslint-disable unicorn/no-empty-file */
// This file is intentionally left blank
2 changes: 2 additions & 0 deletions node-src/__mocks__/storybookBaseDir/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/* eslint-disable unicorn/no-empty-file */
// This file is intentionally left blank
23 changes: 11 additions & 12 deletions node-src/git/generateGitRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ async function generateCommit(
[name, parentNames]: Line,
commitMap: CommitMap
) {
const parentCommits = []
.concat(parentNames)
.filter((parentName) => commitMap[parentName])
.map((parentName) => commitMap[parentName].hash);
const parentCommits = [parentNames]
.flat()
.filter((parentName) => parentName && commitMap[parentName])
.map((parentName) => parentName && commitMap[parentName].hash);

const randomBranchName = `temp-${Math.random().toString().substring(2)}`;
const randomBranchName = `temp-${Math.random().toString().slice(2)}`;
const commitEnv = `GIT_COMMITTER_DATE='${nextDate()}'`;
// No parent, check out nothing
if (parentCommits.length === 0) {
Expand All @@ -34,15 +34,14 @@ async function generateCommit(
await runGit(`git checkout ${parentCommits[0]}`);

// If more parents, create merge commit
if (parentCommits.length > 1) {
await runGit(`${commitEnv} git merge -m ${name} ${parentCommits.slice(1).join(' ')}`);
} else {
await runGit(`${commitEnv} git commit -m ${name} --allow-empty`);
}
await (parentCommits.length > 1
? runGit(`${commitEnv} git merge -m ${name} ${parentCommits.slice(1).join(' ')}`)
: runGit(`${commitEnv} git commit -m ${name} --allow-empty`));
}
const [hash, committedAt] = (await runGit(`git show --format=%H,%ct`)).stdout.trim().split(',');
const gitShowStr = await runGit(`git show --format=%H,%ct`);
const [hash, committedAt] = gitShowStr.stdout.trim().split(',');

return { hash, committedAt: parseInt(committedAt, 10) };
return { hash, committedAt: Number.parseInt(committedAt, 10) };
}

// Take a repository description in the following format:
Expand Down
2 changes: 1 addition & 1 deletion node-src/git/getChangedFilesWithReplacement.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { getChangedFilesWithReplacement } from './getChangedFilesWithReplacement

vi.mock('./git', () => ({
getChangedFiles: (hash) => {
if (hash.match(/exists/)) return ['changed', 'files'];
if (/exists/.test(hash)) return ['changed', 'files'];
throw new Error(`fatal: bad object ${hash}`);
},
commitExists: (hash) => hash.match(/exists/),
Expand Down
2 changes: 1 addition & 1 deletion node-src/git/getChangedFilesWithReplacement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export async function getChangedFilesWithReplacement(
`Got error fetching commit for #${build.number}(${build.commit}): ${err.message}`
);

if (err.message.match(/(bad object|uncommitted changes)/)) {
if (/(bad object|uncommitted changes)/.test(err.message)) {
const replacementBuild = await findAncestorBuildWithCommit(context, build.number);

if (replacementBuild) {
Expand Down
6 changes: 3 additions & 3 deletions node-src/git/getCommitAndBranch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ beforeEach(() => {
getBranch.mockResolvedValue('main');
getCommit.mockResolvedValue({
commit: '48e0c83fadbf504c191bc868040b7a969a4f1feb',
committedAt: 1640094096000,
committedAt: 1_640_094_096_000,
committerName: 'GitHub',
committerEmail: '[email protected]',
});
Expand All @@ -40,7 +40,7 @@ afterEach(() => {
});

const commitInfo = {
committedAt: 1640131292,
committedAt: 1_640_131_292,
committerName: 'Gert Hengeveld',
committerEmail: '[email protected]',
};
Expand All @@ -51,7 +51,7 @@ describe('getCommitAndBranch', () => {
expect(info).toMatchObject({
branch: 'main',
commit: '48e0c83fadbf504c191bc868040b7a969a4f1feb',
committedAt: 1640094096000,
committedAt: 1_640_094_096_000,
committerName: 'GitHub',
committerEmail: '[email protected]',
slug: undefined,
Expand Down
4 changes: 2 additions & 2 deletions node-src/git/getParentCommits.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ function expectCommitsToEqualNames(hashes, names, { commitMap }) {

async function checkoutCommit(name, branch, { dirname, runGit, commitMap }) {
process.chdir(dirname);
await runGit(`git checkout ${branch !== 'HEAD' ? `-B ${branch}` : ''} ${commitMap[name].hash}`);
await runGit(`git checkout ${branch === 'HEAD' ? '' : `-B ${branch}`} ${commitMap[name].hash}`);

return commitMap[name].hash;
}
Expand All @@ -77,7 +77,7 @@ const repositories: Record<string, Repository> = {};
beforeAll(async () => {
await Promise.all(
Object.keys(descriptions).map(async (key) => {
const dirname = (await tmp.dir({ unsafeCleanup: true, prefix: `chromatictest-` })).path;
const { path: dirname } = await tmp.dir({ unsafeCleanup: true, prefix: `chromatictest-` });
const runGit = makeRunGit(dirname);
const commitMap = await generateGitRepository(runGit, descriptions[key]);
repositories[key] = { dirname, runGit, commitMap };
Expand Down
6 changes: 4 additions & 2 deletions node-src/git/getParentCommits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ async function nextCommits(
${firstCommittedAtSeconds ? `--since ${firstCommittedAtSeconds}` : ''} \
-n ${limit + commitsWithoutBuilds.length} --not ${commitsForCLI(commitsWithBuilds)}`;
log.debug(`running ${command}`);
const commits = (await execGitCommand(command)).split('\n').filter(Boolean);
const commitsString = await execGitCommand(command);
const commits = commitsString.split('\n').filter(Boolean);
log.debug(`command output: ${commits}`);

// Later on we want to know which commits we visited on the way to finding the ancestor commits
Expand Down Expand Up @@ -190,7 +191,8 @@ async function maximallyDescendentCommits({ log }: Pick<Context, 'log'>, commits
// This just filters any commits that are ancestors of other commits
const command = `git rev-list ${commitsForCLI(commits)} --not ${commitsForCLI(parentCommits)}`;
log.debug(`running ${command}`);
const maxCommits = (await execGitCommand(command)).split('\n').filter(Boolean);
const maxCommitsString = await execGitCommand(command);
const maxCommits = maxCommitsString.split('\n').filter(Boolean);
log.debug(`command output: ${maxCommits}`);

return maxCommits;
Expand Down
4 changes: 2 additions & 2 deletions node-src/git/git.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ describe('getCommit', () => {
);
expect(await getCommit()).toEqual({
commit: '19b6c9c5b3d34d9fc55627fcaf8a85bd5d5e5b2a',
committedAt: 1696588814 * 1000,
committedAt: 1_696_588_814 * 1000,
committerEmail: '[email protected]',
committerName: 'Gert Hengeveld',
});
Expand All @@ -48,7 +48,7 @@ gpg: Can't check signature: No public key
);
expect(await getCommit()).toEqual({
commit: '19b6c9c5b3d34d9fc55627fcaf8a85bd5d5e5b2a',
committedAt: 1696588814 * 1000,
committedAt: 1_696_588_814 * 1000,
committerEmail: '[email protected]',
committerName: 'Gert Hengeveld',
});
Expand Down
Loading
Loading