chore(manager/haskell-cabal): fix pkg name extraction

Packages cannot start with a hyphen.

But they can start with a number:
- https://hackage.haskell.org/package/3d-graphics-examples

They can be a single uppercase character:
- https://hackage.haskell.org/package/H

They can be a single lowercase character:
- https://hackage.haskell.org/package/j
This commit is contained in:
Janus Troelsen 2024-12-17 11:19:46 -06:00
parent 87d580d9e4
commit 38e5febd6d
2 changed files with 62 additions and 6 deletions

View file

@ -1,4 +1,5 @@
import {
countPackageNameLength,
countPrecedingIndentation,
extractNamesAndRanges,
findExtents,
@ -6,6 +7,28 @@ import {
} from './extract';
describe('modules/manager/haskell-cabal/extract', () => {
describe('countPackageNameLength', () => {
it.each`
input | expected
${'-'} | ${null}
${'-j'} | ${null}
${'-H'} | ${null}
${'j-'} | ${null}
${'3-'} | ${null}
${'-3'} | ${null}
${'3'} | ${null}
${'æ'} | ${null}
${'æe'} | ${null}
${'j'} | ${1}
${'H'} | ${1}
${'0ad'} | ${3}
${'3d'} | ${2}
`('matches $input', ({ input, expected }) => {
const maybeIndex = countPackageNameLength(input);
expect(maybeIndex).toStrictEqual(expected);
});
});
describe('countPrecedingIndentation()', () => {
it.each`
content | index | expected

View file

@ -3,7 +3,41 @@ import { regEx } from '../../../util/regex';
const buildDependsRegex = regEx(
/(?<buildDependsFieldName>build-depends[ \t]*:)/i,
);
const pkgNameRegex = regEx(/[A-z0-9-]+/);
function isNonASCII(str: string): bool {
for (let i = 0; i < str.length; i++) {
if (str.charCodeAt(i) > 127) {
return true;
}
}
return false;
}
export function countPackageNameLength(input: string): number | null {
if (input.length < 1 || isNonASCII(input)) {
return null;
}
if (!regEx(/^[A-Za-z0-9]/).test(input[0])) {
// Must start with letter or number
return null;
}
let idx = 1;
while (idx < input.length) {
if (regEx(/[A-Za-z0-9-]/).test(input[idx])) {
idx++;
} else {
break;
}
}
if (!regEx(/[A-Za-z]/).test(input.slice(0, idx))) {
// Must contain a letter
return null;
}
if (idx - 1 < input.length && input[idx - 1] === '-') {
// Can't end in a hyphen
return null;
}
return idx;
}
export interface CabalDependency {
packageName: string;
@ -130,13 +164,12 @@ export function findDepends(
export function splitSingleDependency(
input: string,
): { name: string; range: string } | null {
const matchObj = pkgNameRegex.exec(input);
if (matchObj === null) {
const match = countPackageNameLength(input);
if (match === null) {
return null;
}
const match = matchObj.index;
const name: string = matchObj[0];
const range = input.slice(match + name.length).trim();
const name: string = input.slice(0, match);
const range = input.slice(match).trim();
return { name, range };
}