-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge 'upstream/master' into 'core-remove-fs-extra'
- Loading branch information
Showing
9 changed files
with
186 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/** | ||
* We have a custom lint rule for our pnpm-lock.yaml file and naturally ESLint does not natively know how to parse it. | ||
* Rather than using a full yaml parser for this one case (which will need to spend time creating a real AST for the giant | ||
* lock file), we can instead use a custom parser which just immediately returns a dummy AST and then build the reading of | ||
* the lock file into the rule itself. | ||
*/ | ||
module.exports = { | ||
parseForESLint: (code) => ({ | ||
ast: { | ||
type: 'Program', | ||
loc: { start: 0, end: code.length }, | ||
range: [0, code.length], | ||
body: [], | ||
comments: [], | ||
tokens: [], | ||
}, | ||
services: { isPlain: true }, | ||
scopeManager: null, | ||
visitorKeys: { | ||
Program: [], | ||
}, | ||
}), | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
/** | ||
* This file sets you up with structure needed for an ESLint rule. | ||
* | ||
* It leverages utilities from @typescript-eslint to allow TypeScript to | ||
* provide autocompletions etc for the configuration. | ||
* | ||
* Your rule's custom logic will live within the create() method below | ||
* and you can learn more about writing ESLint rules on the official guide: | ||
* | ||
* https://eslint.org/docs/developer-guide/working-with-rules | ||
* | ||
* You can also view many examples of existing rules here: | ||
* | ||
* https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin/src/rules | ||
*/ | ||
|
||
import { ESLintUtils } from '@typescript-eslint/utils'; | ||
import { closeSync, openSync, readSync } from 'node:fs'; | ||
|
||
// NOTE: The rule will be available in ESLint configs as "@nx/workspace-ensure-pnpm-lock-version" | ||
export const RULE_NAME = 'ensure-pnpm-lock-version'; | ||
|
||
export const rule = ESLintUtils.RuleCreator(() => __filename)({ | ||
name: RULE_NAME, | ||
meta: { | ||
type: 'problem', | ||
docs: { | ||
description: ``, | ||
}, | ||
schema: [ | ||
{ | ||
type: 'object', | ||
properties: { | ||
version: { | ||
type: 'string', | ||
}, | ||
}, | ||
additionalProperties: false, | ||
}, | ||
], | ||
messages: { | ||
unparseableLockfileVersion: | ||
'Could not parse lockfile version from pnpm-lock.yaml, the file may be corrupted or the ensure-pnpm-lock-version lint rule may need to be updated.', | ||
incorrectLockfileVersion: | ||
'pnpm-lock.yaml has a lockfileVersion of {{version}}, but {{expectedVersion}} is required.', | ||
}, | ||
}, | ||
defaultOptions: [], | ||
create(context) { | ||
// Read upon creation of the rule, the contents should not change during linting | ||
const lockfileFirstLine = readFirstLineSync('pnpm-lock.yaml'); | ||
// Extract the version number, it will be a string in single quotes | ||
const lockfileVersion = lockfileFirstLine.match( | ||
/lockfileVersion:\s*'([^']+)'/ | ||
)?.[1]; | ||
|
||
const options = context.options as { version: string }[]; | ||
if (!Array.isArray(options) || options.length === 0) { | ||
throw new Error('Expected an array of options with a version property'); | ||
} | ||
const expectedLockfileVersion = options[0].version; | ||
return { | ||
Program(node) { | ||
if (!lockfileVersion) { | ||
context.report({ | ||
node, | ||
messageId: 'unparseableLockfileVersion', | ||
}); | ||
return; | ||
} | ||
|
||
if (lockfileVersion !== expectedLockfileVersion) { | ||
context.report({ | ||
node, | ||
messageId: 'incorrectLockfileVersion', | ||
data: { | ||
version: lockfileVersion, | ||
expectedVersion: expectedLockfileVersion, | ||
}, | ||
}); | ||
} | ||
}, | ||
}; | ||
}, | ||
}); | ||
|
||
/** | ||
* pnpm-lock.yaml is a huge file, so only read the first line as efficiently as possible | ||
* for optimum linting performance. | ||
*/ | ||
function readFirstLineSync(filePath: string) { | ||
const BUFFER_SIZE = 64; // Optimized for the expected line length | ||
const buffer = Buffer.alloc(BUFFER_SIZE); | ||
let line = ''; | ||
let bytesRead: number; | ||
let fd: number; | ||
try { | ||
fd = openSync(filePath, 'r'); | ||
bytesRead = readSync(fd, buffer, 0, BUFFER_SIZE, 0); | ||
line = buffer.toString('utf8', 0, bytesRead).split('\n')[0]; | ||
} catch (err) { | ||
throw err; // Re-throw to allow caller to handle | ||
} finally { | ||
if (fd !== undefined) { | ||
closeSync(fd); | ||
} | ||
} | ||
return line; | ||
} |