Skip to content

Commit

Permalink
fix: OS-agnostic handling of end-of-line characters (#524)
Browse files Browse the repository at this point in the history
* fix: OS-agnostic handling of end-of-line characters

* try stubbing EOL in test
  • Loading branch information
bmish authored May 8, 2024
1 parent 01c3179 commit 4852197
Show file tree
Hide file tree
Showing 10 changed files with 39 additions and 18 deletions.
1 change: 1 addition & 0 deletions jest.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const jestConfig = {
preset: 'ts-jest/presets/default-esm',
testEnvironment: 'node',
testMatch: ['<rootDir>/test/**/*-test.ts'],
setupFiles: ['<rootDir>/test/jest.setup.cjs'],
transform: {
'^.+\\.tsx?$': ['ts-jest', { useESM: true }],
},
Expand Down
3 changes: 2 additions & 1 deletion lib/config-list.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { EOL } from 'node:os';
import {
BEGIN_CONFIG_LIST_MARKER,
END_CONFIG_LIST_MARKER,
Expand Down Expand Up @@ -111,5 +112,5 @@ export function updateConfigsList(
ignoreConfig
);

return `${preList}${BEGIN_CONFIG_LIST_MARKER}\n\n${list}\n\n${END_CONFIG_LIST_MARKER}${postList}`;
return `${preList}${BEGIN_CONFIG_LIST_MARKER}${EOL}${EOL}${list}${EOL}${EOL}${END_CONFIG_LIST_MARKER}${postList}`;
}
11 changes: 7 additions & 4 deletions lib/generator.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { EOL } from 'node:os';
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
import { dirname, join, relative, resolve } from 'node:path';
import { getAllNamedOptions, hasOptions } from './rule-options.js';
Expand Down Expand Up @@ -168,16 +169,18 @@ export async function generate(path: string, options?: GenerateOptions) {
// The rule doc header will be added later.
let newRuleDocContents = [
ruleDocSectionInclude.length > 0
? ruleDocSectionInclude.map((title) => `## ${title}`).join('\n\n')
? ruleDocSectionInclude
.map((title) => `## ${title}`)
.join(`${EOL}${EOL}`)
: undefined,
ruleHasOptions
? `## Options\n\n${BEGIN_RULE_OPTIONS_LIST_MARKER}\n${END_RULE_OPTIONS_LIST_MARKER}`
? `## Options${EOL}${EOL}${BEGIN_RULE_OPTIONS_LIST_MARKER}${EOL}${END_RULE_OPTIONS_LIST_MARKER}`
: undefined,
]
.filter((section) => section !== undefined)
.join('\n\n');
.join(`${EOL}${EOL}`);
if (newRuleDocContents !== '') {
newRuleDocContents = `\n${newRuleDocContents}\n`;
newRuleDocContents = `${EOL}${newRuleDocContents}${EOL}`;
}

mkdirSync(dirname(pathToDoc), { recursive: true });
Expand Down
16 changes: 10 additions & 6 deletions lib/markdown.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { EOL } from 'node:os';

// General helpers for dealing with markdown files / content.

/**
Expand All @@ -12,7 +14,7 @@ export function replaceOrCreateHeader(
newHeader: string,
marker: string
) {
const lines = markdown.split('\n');
const lines = markdown.split(EOL);

const titleLineIndex = lines.findIndex((line) => line.startsWith('# '));
const markerLineIndex = lines.indexOf(marker);
Expand All @@ -22,16 +24,18 @@ export function replaceOrCreateHeader(
// Any YAML front matter or anything else above the title should be kept as-is ahead of the new header.
const preHeader = lines
.slice(0, Math.max(titleLineIndex, dashesLineIndex2 + 1))
.join('\n');
.join(EOL);

// Anything after the marker comment, title, or YAML front matter should be kept as-is after the new header.
const postHeader = lines
.slice(
Math.max(markerLineIndex + 1, titleLineIndex + 1, dashesLineIndex2 + 1)
)
.join('\n');
.join(EOL);

return `${preHeader ? `${preHeader}\n` : ''}${newHeader}\n${postHeader}`;
return `${
preHeader ? `${preHeader}${EOL}` : ''
}${newHeader}${EOL}${postHeader}`;
}

/**
Expand All @@ -42,7 +46,7 @@ export function findSectionHeader(
str: string
): string | undefined {
// Get all the matching strings.
const regexp = new RegExp(`## .*${str}.*\n`, 'giu');
const regexp = new RegExp(`## .*${str}.*${EOL}`, 'giu');
const sectionPotentialMatches = [...markdown.matchAll(regexp)].map(
(match) => match[0]
);
Expand All @@ -64,7 +68,7 @@ export function findSectionHeader(
}

export function findFinalHeaderLevel(str: string) {
const lines = str.split('\n');
const lines = str.split(EOL);
const finalHeader = lines.reverse().find((line) => line.match('^(#+) .+$'));
return finalHeader ? finalHeader.indexOf(' ') : undefined;
}
Expand Down
3 changes: 2 additions & 1 deletion lib/rule-doc-notices.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { EOL } from 'node:os';
import { END_RULE_HEADER_MARKER } from './comment-markers.js';
import {
EMOJI_DEPRECATED,
Expand Down Expand Up @@ -523,5 +524,5 @@ export function generateRuleHeaderLines(
),
'',
END_RULE_HEADER_MARKER,
].join('\n');
].join(EOL);
}
3 changes: 2 additions & 1 deletion lib/rule-list-legend.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { EOL } from 'node:os';
import {
EMOJI_DEPRECATED,
EMOJI_FIXABLE,
Expand Down Expand Up @@ -287,5 +288,5 @@ export function generateLegend(
);
}

return legends.join('\\\n'); // Back slash ensures these end up displayed on separate lines.
return legends.join(`\\${EOL}`); // Back slash ensures these end up displayed on separate lines.
}
7 changes: 4 additions & 3 deletions lib/rule-list.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { EOL } from 'node:os';
import {
BEGIN_RULE_LIST_MARKER,
END_RULE_LIST_MARKER,
Expand Down Expand Up @@ -288,7 +289,7 @@ function generateRuleListMarkdownForRulesAndHeaders(
);
}

return parts.join('\n\n');
return parts.join(`${EOL}${EOL}`);
}

/**
Expand Down Expand Up @@ -546,7 +547,7 @@ export function updateRulesList(
urlRuleDoc
);

const newContent = `${legend ? `${legend}\n\n` : ''}${list}`;
const newContent = `${legend ? `${legend}${EOL}${EOL}` : ''}${list}`;

return `${preList}${BEGIN_RULE_LIST_MARKER}\n\n${newContent}\n\n${END_RULE_LIST_MARKER}${postList}`;
return `${preList}${BEGIN_RULE_LIST_MARKER}${EOL}${EOL}${newContent}${EOL}${EOL}${END_RULE_LIST_MARKER}${postList}`;
}
3 changes: 2 additions & 1 deletion lib/rule-options-list.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { EOL } from 'node:os';
import {
BEGIN_RULE_OPTIONS_LIST_MARKER,
END_RULE_OPTIONS_LIST_MARKER,
Expand Down Expand Up @@ -159,5 +160,5 @@ export function updateRuleOptionsList(
// New rule options list.
const list = generateRuleOptionsListMarkdown(rule);

return `${preList}${BEGIN_RULE_OPTIONS_LIST_MARKER}\n\n${list}\n\n${END_RULE_OPTIONS_LIST_MARKER}${postList}`;
return `${preList}${BEGIN_RULE_OPTIONS_LIST_MARKER}${EOL}${EOL}${list}${EOL}${EOL}${END_RULE_OPTIONS_LIST_MARKER}${postList}`;
}
4 changes: 3 additions & 1 deletion lib/string.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { EOL } from 'node:os';

export function toSentenceCase(str: string) {
return str.replace(/^\w/u, function (txt) {
return txt.charAt(0).toUpperCase() + txt.slice(1).toLowerCase();
Expand All @@ -20,7 +22,7 @@ export function capitalizeOnlyFirstLetter(str: string) {
}

function sanitizeMarkdownTableCell(text: string): string {
return text.replace(/\|/gu, '\\|').replace(/\n/gu, '<br/>');
return text.replace(/\|/gu, '\\|').replace(new RegExp(EOL, 'gu'), '<br/>');
}

export function sanitizeMarkdownTable(
Expand Down
6 changes: 6 additions & 0 deletions test/jest.setup.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const os = require('node:os');
const sinon = require('sinon');

module.exports = function () {
sinon.stub(os, 'EOL').value('\n'); // Stub os.EOL to always be '\n' for testing/snapshot purposes.
};

0 comments on commit 4852197

Please sign in to comment.