Skip to content

Commit

Permalink
Merge pull request #1041 from chromaui/cody/cap-2199-eslint-add-unico…
Browse files Browse the repository at this point in the history
…rn-config

Add basic `unicorn` setup to ESLint config
  • Loading branch information
codykaup authored Sep 12, 2024
2 parents 4a04431 + 0b68b73 commit da3ab1e
Show file tree
Hide file tree
Showing 76 changed files with 489 additions and 318 deletions.
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

0 comments on commit da3ab1e

Please sign in to comment.