mirror of
https://github.com/renovatebot/renovate.git
synced 2026-11-01 10:09:50 +00:00
e44c9a2070
* ci: move custom oxlint rules to typescript and alternative API * ci: add to test sharding
69 lines
2.5 KiB
TypeScript
69 lines
2.5 KiB
TypeScript
import { defineRule } from '@oxlint/plugins';
|
|
|
|
/**
|
|
* Modules whose value imports are restricted in `lib/` in favor of the
|
|
* scoped helpers from `lib/util/fs`.
|
|
*/
|
|
const RESTRICTED_MODULES = new Set([
|
|
'fs',
|
|
'node:fs',
|
|
'fs/promises',
|
|
'node:fs/promises',
|
|
'fs-extra',
|
|
'fs-extra/esm',
|
|
]);
|
|
|
|
/*
|
|
* Paths exempt from this rule (via overrides in `.oxlintrc.json`). The
|
|
* `lib/util/fs` helpers scope file access to the `localDir`/`cacheDir` from
|
|
* `GlobalConfig`, so they only make sense for code that runs after those
|
|
* directories are configured and that operates inside them. The following
|
|
* areas legitimately need raw `fs` access:
|
|
*
|
|
* - `lib/util/fs/` implements the helpers themselves.
|
|
* - `lib/logger/` opens log-file streams at user-configured system paths
|
|
* during process bootstrap, before any config exists; `lib/util/fs` also
|
|
* depends on the logger, so the reverse import would be a cycle.
|
|
* - `lib/workers/global/` is process bootstrap: it creates `baseDir` and
|
|
* `cacheDir` themselves and reads/writes user-supplied paths (config
|
|
* files, `writeDiscoveredRepos` output) before `GlobalConfig` is seeded
|
|
* with the directory config the scoped helpers resolve against.
|
|
* - `lib/config-validator.ts` is a standalone CLI entry point that validates
|
|
* arbitrary files without any `GlobalConfig`.
|
|
* - `lib/util/git/` sits beneath the scoped-helper abstraction: it owns the
|
|
* `localDir` lifecycle (clone, emptyDir, symlinks) and manages private-key
|
|
* files with synchronous cleanup on process exit, which the async scoped
|
|
* helpers cannot express.
|
|
* - `lib/instrumentation/` bootstraps OpenTelemetry and writes traces to a
|
|
* user-configured system path (`RENOVATE_TRACING_FILE_EXPORTER_PATH`)
|
|
* outside `localDir`/`cacheDir`, before any `GlobalConfig` exists.
|
|
*/
|
|
|
|
export default defineRule({
|
|
meta: {
|
|
type: 'suggestion',
|
|
messages: {
|
|
preferFsUtil:
|
|
"Use the helpers from 'lib/util/fs' instead of importing '{{module}}' directly: they scope file access to the configured local/cache directories.",
|
|
},
|
|
},
|
|
createOnce(context) {
|
|
return {
|
|
ImportDeclaration(node) {
|
|
// type-only imports don't touch the filesystem
|
|
if (node.importKind === 'type') {
|
|
return;
|
|
}
|
|
const source = node.source.value;
|
|
if (RESTRICTED_MODULES.has(source)) {
|
|
context.report({
|
|
node,
|
|
messageId: 'preferFsUtil',
|
|
data: { module: source },
|
|
});
|
|
}
|
|
},
|
|
};
|
|
},
|
|
});
|