Skip to content

Commit

Permalink
New: (zenflux-eslint) - Reorganize ESLint configuration and utilities
Browse files Browse the repository at this point in the history
Migrated ESLint configuration, plugin, and utility functions to the `src` directory. Added new command-line utility `z-lint.js` and example configuration `example-config-extend.js` in `bin`. Updated functions to include custom rule `@zenflux/no-relative-imports`.
  • Loading branch information
iNewLegend committed Oct 4, 2024
1 parent a536e69 commit be22a94
Show file tree
Hide file tree
Showing 12 changed files with 409 additions and 137 deletions.
39 changes: 12 additions & 27 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,23 @@
import { zLintGetDefaultConfig } from "@zenflux/eslint";
import { zLintGetConfig } from "@zenflux/eslint";
import util from "node:util";

/** @type {import('eslint').Linter.FlatConfig[]} */
export const tests = [
/** @type {import("eslint").Linter.FlatConfig[]} */
const config = [
{
ignores: [
"**/eslint.config.*",
"**/*jest.config.ts",
"**/vite.config.*",
"**/*.cjs"
],
},
{
files: [
"packages/*/test/**/*.{ts,tsx}",
],
rules: {
"no-restricted-imports": [
"error",
{
"patterns": [ {
group: [
"@",
],
message: "Please use relative imports",
} ]
}
],
},
},
];

/** @type {import("eslint").Linter.FlatConfig[]} */
const config = [
...zLintGetDefaultConfig(),
...tests,
...( await zLintGetConfig() ),
];

if ( process.argv.includes( "--print-config" ) ) {
console.log( util.inspect( config, { depth: null } ) );
process.exit( 0 )
}

export default config;

13 changes: 13 additions & 0 deletions packages/zenflux-eslint/bin/example-config-extend.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/* eslint.config.js */
import { zLintGetConfig } from '@zenflux/eslint';

/** @type {import("eslint").Linter.FlatConfig[]} */
const config = [
...( await zLintGetConfig( {
workspaces: [ "." ],
files: [ 'src/**/*.{ts,tsx}' ],
excludeProjectsWithConfig: false,
} ) ),
];

export default config;
52 changes: 52 additions & 0 deletions packages/zenflux-eslint/bin/z-lint.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/bin/env node
import process from "node:process";
import fs from "node:fs";
import path from "node:path";
import child_process from "node:child_process";

import { zLintGetProjectsPathsWithConfig } from "@zenflux/eslint";
import { fileURLToPath } from "node:url";

const hasConfig = !! ( await zLintGetProjectsPathsWithConfig( [ process.env.PWD ] ) ).length;

if ( hasConfig ) {
console.log( "Use `eslint .` with following `eslint.config.js` file:\n" );

// Print content of `./example-config-extend.js`.
console.log( fs.readFileSync(
path.join( path.dirname( fileURLToPath( import.meta.url ) ), "example-config-extend.js" ), "utf8" )
);

process.exit( 0 );
}

const rootPackagePath = path.dirname( __Z_ESLINT_CONFIG__.zRootPackagePath );

// Run `eslint` on `process.env.PWD` from `rootPackagePath`.
process.chdir( rootPackagePath );

const isWithinBun = typeof Bun !== "undefined";

const isInspectConfig = process.argv.includes( "--inspect-config" );

const shouldRunViaBun = ! isInspectConfig && ! isWithinBun && await ( async function () {
return !! await child_process.exec( 'bun --version', { stdio: 'ignore' } );
}() );

const command = [
isInspectConfig ? "" : "time",
"(",
shouldRunViaBun ? "bunx --bun eslint" : "eslint",
`${ process.argv.includes( "--print-config" ) ? "" : process.env.PWD }`,
...process.argv.slice( 2 ),
")"
].join( " " );

console.log( `@z-lint running: ${ "`" + command + "`" }` );

child_process.execSync( command, {
stdio: "inherit",
env: {
...process.env,
}
} );
13 changes: 0 additions & 13 deletions packages/zenflux-eslint/jsconfig.json

This file was deleted.

18 changes: 9 additions & 9 deletions packages/zenflux-eslint/package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
{
"$schema": "https://raw.githubusercontent.com/SchemaStore/schemastore/master/src/schemas/json/package.json",
"name": "@zenflux/eslint",
"author": "Leonid Vinikov <[email protected]> (https://github.com/iNewLegend)",
"type": "module",
"version": "0.1.0",
"main": ".eslintrc.js",
"version": "0.1.2",
"main": "src/main.js",
"types": "types/main.d.ts",
"bin": {
"@z-lint": "bin/z-lint.js"
},
"repository": {
"type": "git",
"url": "https://github.com/zenflux/zenflux.git",
Expand All @@ -14,15 +17,12 @@
"access": "public"
},
"dependencies": {
"eslint": "^9.10.0",
"@eslint/compat": "latest",
"@eslint/eslintrc": "latest",
"@types/eslint": "latest",
"@typescript-eslint/eslint-plugin": "latest",
"@typescript-eslint/parser": "latest",
"typescript-eslint": "latest",
"@zenflux/utils": "workspace:*",
"eslint": "latest",
"eslint-import-resolver-typescript": "latest",
"eslint-plugin-import": "latest"
},
"packageManager": "[email protected]"
}
}
32 changes: 19 additions & 13 deletions packages/zenflux-eslint/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,25 @@ Via package manager, `bun install @zenflux/eslint`
## 💻 Usage
```javascript
// eslint.config.js
import path from "node:path";

import { fileURLToPath } from "node:url";

import { zLintGetDefaultConfig, zLintSetRootPackagePath } from "@zenflux/eslint";

zLintSetRootPackagePath( path.resolve(
path.dirname( fileURLToPath( import.meta.url ) ),
"package.json"
) );

const config = zLintGetDefaultConfig();
import { zLintGetConfig } from "@zenflux/eslint";
import util from "node:util";

/** @type {import("eslint").Linter.FlatConfig[]} */
const config = [
{
ignores: [
"**/eslint.config.*",
"**/*jest.config.ts",
"**/vite.config.*",
],
},
...( await zLintGetConfig() ),
];

if ( process.argv.includes( "--print-config" ) ) {
console.log( util.inspect( config, { depth: null } ) );
process.exit( 0 )
}

export default config;

```
Original file line number Diff line number Diff line change
@@ -1,69 +1,24 @@
/**
* @author Leonid Vinikov <[email protected]>
*/
import fs from "node:fs";
import path from "node:path";

import * as TSLintParser from "@typescript-eslint/parser";

import TypeScriptPlugin from "@typescript-eslint/eslint-plugin";

import ImportPlugin from "eslint-plugin-import";

import { fixupPluginRules } from "@eslint/compat";

import { fileURLToPath } from "node:url";

import { zFindRootPackageJsonPath } from "@zenflux/utils/src/workspace";

const workingPath = path.dirname( fileURLToPath( import.meta.url ) );
import TSLint from "typescript-eslint";

globalThis.__Z_ESLINT_CONFIG__ = globalThis.__Z_ESLINT_CONFIG__ ?? {
zRootPackagePath: zFindRootPackageJsonPath(),
zPackagePath: path.resolve( workingPath, "./package.json" ),
};

const ZenFluxPlugin = ( await import( "@zenflux/eslint/plugin.js" ) ).default;

/**
* Sets the root package path.
*
* @param {string} zRootPackagePath - The path to the workspace `package.json`.
*
* @return {void}
*/
export function zLintSetRootPackagePath( zRootPackagePath ) {
globalThis.__Z_ESLINT_CONFIG__.zRootPackagePath = zRootPackagePath;
}
import ImportPlugin from "eslint-plugin-import";

/**
* Retrieves the workspaces from the provided workspace path.
*
* @param {string} [rootPkgPath=__Z_ESLINT_CONFIG__.zRootPackagePath] - The path to the root package.
*
* @return {Array} - An array containing the retrieved workspaces.
*/
export function zLintGetWorkspaces( rootPkgPath = __Z_ESLINT_CONFIG__.zRootPackagePath ) {
return Object.values(
JSON.parse( fs.readFileSync( rootPkgPath ) ).workspaces
);
}
const ZenFluxPlugin = ( await import( "./plugin.js" ) ).default;

/**
* Returns the default configuration for eslint.
* @param {string[]} files
* @param {string[]} workspaces
*
* @param {Array<String>} [workspaces=zLintGetWorkspaces()] - The list of workspaces to include in the configuration.
*
* @return {import('eslint').Linter.FlatConfig[]} The default configuration for zLint.
* @returns {import("../types/default-config.d.ts").ESLintTSLintCompatible[]}
*/
export function zLintGetDefaultConfig( workspaces = zLintGetWorkspaces() ) {
export function zLintDefaultConfig( files, workspaces ) {
return [
{
files: workspaces.map( ( p ) => `${ p.startsWith( "." ) ? p.substring( 1 ) : p + "/" }**/*.{ts,tsx}` ),

files,
languageOptions: {
// Specifies the parser to use for linting (TypeScript)
"parser": TSLintParser,
parser: TSLint.parser,

parserOptions: {
"ecmaVersion": "latest",
Expand All @@ -75,7 +30,7 @@ export function zLintGetDefaultConfig( workspaces = zLintGetWorkspaces() ) {

// Specifies ESLint plugins used in this configuration
plugins: {
"@typescript-eslint": TypeScriptPlugin,
"@typescript-eslint": TSLint.plugin,
"import": fixupPluginRules( ImportPlugin ),
"@zenflux": ZenFluxPlugin,
},
Expand Down Expand Up @@ -149,7 +104,7 @@ export function zLintGetDefaultConfig( workspaces = zLintGetWorkspaces() ) {
"@typescript-eslint/consistent-type-imports": "error",
"@typescript-eslint/no-import-type-side-effects": "error",

"import/consistent-type-specifier-style" : "error",
"import/consistent-type-specifier-style": "error",

// Disable named-as-default rule for import
"import/no-named-as-default": "off",
Expand Down Expand Up @@ -225,20 +180,31 @@ export function zLintGetDefaultConfig( workspaces = zLintGetWorkspaces() ) {
],
},
},
{
ignores: [
"**/*.js",
"**/*.d.ts",

// "**/zenflux.*.config.ts",

"**/dist/**",
"**/bin/**",
"**/zenflux.config.ts",
"**/node_modules/**",
"**/.backups/**",
],
}
];
}

/**
* Generates a default set of file and directory patterns to be excluded,
* with an option to add additional patterns.
*
* @param {string[]} addToExclude - An optional array of additional file patterns to exclude.
* @return {string[]} An array containing the default and additional exclusion patterns.
*/
export function zLintDefaultExclude( addToExclude = [] ) {
return [
"**/*.js",
"**/*.d.ts",

// "**/zenflux.*.config.ts",

"**/dist/**",
"**/bin/**",
"**/zenflux.config.ts",
"**/node_modules/**",
"**/.backups/**",

... addToExclude,
]
}

export default zLintDefaultConfig;
Loading

0 comments on commit be22a94

Please sign in to comment.