Skip to content

Commit

Permalink
Require Node.js 18 and move to ESM
Browse files Browse the repository at this point in the history
  • Loading branch information
sindresorhus committed Oct 13, 2023
1 parent 9adfa76 commit 97613ab
Show file tree
Hide file tree
Showing 41 changed files with 622 additions and 575 deletions.
9 changes: 4 additions & 5 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,14 @@ jobs:
fail-fast: false
matrix:
node-version:
- 16
- 14
- 12
- 20
- 18
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
submodules: true
fetch-depth: 0
- uses: actions/setup-node@v2
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- run: npm install
Expand Down
62 changes: 30 additions & 32 deletions cli.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
#!/usr/bin/env node
'use strict';
const meow = require('meow');
const findReadmeFile = require('./lib/find-readme-file.js');
const awesomeLint = require('./index.js');
import process from 'node:process';
import meow from 'meow';
import findReadmeFile from './lib/find-readme-file.js';
import awesomeLint from './index.js';

const getReporter = name => {
// Check if reporter is an npm package
const getReporter = async name => {
// Check if reporter is an npm package.
try {
return require(name).report;
const {report} = await import(name);
return report;
} catch (error) {
if (error.code === 'MODULE_NOT_FOUND') {
console.error(`No reporter found matching \`${name}\`. Using default reporter (vfile-reporter-pretty).`);
Expand All @@ -17,34 +18,31 @@ const getReporter = name => {
}
};

const main = async () => {
const cli = meow(`
Usage
$ awesome-lint [url|filename]
Options
--reporter, -r Use a custom reporter
`, {
flags: {
reporter: {
type: 'string',
alias: 'r'
}
}
});
const cli = meow(`
Usage
$ awesome-lint [url|filename]
const input = cli.input[0];
Options
--reporter, -r Use a custom reporter
`, {
importMeta: import.meta,
flags: {
reporter: {
type: 'string',
shortFlag: 'r',
},
},
});

const options = {};
const input = cli.input[0];

options.filename = input ? input : findReadmeFile(process.cwd());
const options = {};

const reporterName = cli.flags.reporter;
if (reporterName) {
options.reporter = getReporter(reporterName);
}
options.filename = input ?? findReadmeFile(process.cwd());

await awesomeLint.report(options);
};
const reporterName = cli.flags.reporter;
if (reporterName) {
options.reporter = await getReporter(reporterName);
}

main();
await awesomeLint.report(options);
147 changes: 98 additions & 49 deletions config.js
Original file line number Diff line number Diff line change
@@ -1,62 +1,111 @@
'use strict';
import remarkLint from 'remark-lint';
import blockquoteIndentation from 'remark-lint-blockquote-indentation';
import checkboxCharacterStyle from 'remark-lint-checkbox-character-style';
import checkboxContentIndent from 'remark-lint-checkbox-content-indent';
import codeBlockStyle from 'remark-lint-code-block-style';
import definitionCase from 'remark-lint-definition-case';
import definitionSpacing from 'remark-lint-definition-spacing';
import emphasisMarker from 'remark-lint-emphasis-marker';
import fencedCodeMarker from 'remark-lint-fenced-code-marker';
import fileExtension from 'remark-lint-file-extension';
import finalNewline from 'remark-lint-final-newline';
import hardBreakSpaces from 'remark-lint-hard-break-spaces';
import headingStyle from 'remark-lint-heading-style';
import linkTitleStyle from 'remark-lint-link-title-style';
import listItemBulletIndent from 'remark-lint-list-item-bullet-indent';
import listItemIndent from 'remark-lint-list-item-indent';
import noAutoLinkWithoutProtocol from 'remark-lint-no-auto-link-without-protocol';
import noBlockquoteWithoutMarker from 'remark-lint-no-blockquote-without-marker';
import noEmphasisAsHeading from 'remark-lint-no-emphasis-as-heading';
import noFileNameArticles from 'remark-lint-no-file-name-articles';
import noFileNameConsecutiveDashes from 'remark-lint-no-file-name-consecutive-dashes';
import noFileNameIrregularCharacters from 'remark-lint-no-file-name-irregular-characters';
import noFileNameMixedCase from 'remark-lint-no-file-name-mixed-case';
import noFileNameOuterDashes from 'remark-lint-no-file-name-outer-dashes';
import noHeadingContentIndent from 'remark-lint-no-heading-content-indent';
import noHeadingIndent from 'remark-lint-no-heading-indent';
import noHeadingPunctuation from 'remark-lint-no-heading-punctuation';
import noInlinePadding from 'remark-lint-no-inline-padding';
import noMultipleToplevelHeadings from 'remark-lint-no-multiple-toplevel-headings';
import noShellDollars from 'remark-lint-no-shell-dollars';
import noTableIndentation from 'remark-lint-no-table-indentation';
import noUndefinedReferences from 'remark-lint-no-undefined-references';
import noUnneededFullReferenceImage from 'remark-lint-no-unneeded-full-reference-image';
import noUnneededFullReferenceLink from 'remark-lint-no-unneeded-full-reference-link';
import noUnusedDefinitions from 'remark-lint-no-unused-definitions';
import orderedListMarkerStyle from 'remark-lint-ordered-list-marker-style';
import orderedListMarkerValue from 'remark-lint-ordered-list-marker-value';
import ruleStyle from 'remark-lint-rule-style';
import strongMarker from 'remark-lint-strong-marker';
import tableCellPadding from 'remark-lint-table-cell-padding';
import tablePipeAlignment from 'remark-lint-table-pipe-alignment';
import tablePipes from 'remark-lint-table-pipes';
import unorderedListMarkerStyle from 'remark-lint-unordered-list-marker-style';
import matchPunctuation from 'remark-lint-match-punctuation';
import noRepeatPunctuation from 'remark-lint-no-repeat-punctuation';
import doubleLink from 'remark-lint-double-link';
import customRules from './rules/index.js';

exports.plugins = [
require('remark-lint'),
const plugins = [
remarkLint,

// Official plugins
[require('remark-lint-blockquote-indentation'), 2],
[require('remark-lint-checkbox-character-style'), 'consistent'],
require('remark-lint-checkbox-content-indent'),
[require('remark-lint-code-block-style'), 'fenced'],
require('remark-lint-definition-case'),
require('remark-lint-definition-spacing'),
[require('remark-lint-emphasis-marker'), 'consistent'],
[require('remark-lint-fenced-code-marker'), '`'],
require('remark-lint-file-extension'),
require('remark-lint-final-newline'),
require('remark-lint-hard-break-spaces'),
[require('remark-lint-heading-style'), 'atx'],
[require('remark-lint-link-title-style'), '\''],
require('remark-lint-list-item-bullet-indent'),
[blockquoteIndentation, 2],
[checkboxCharacterStyle, 'consistent'],
checkboxContentIndent,
[codeBlockStyle, 'fenced'],
definitionCase,
definitionSpacing,
[emphasisMarker, 'consistent'],
[fencedCodeMarker, '`'],
fileExtension,
finalNewline,
hardBreakSpaces,
[headingStyle, 'atx'],
[linkTitleStyle, '\''],
// TODO: this rule doesn't properly handle tab indents
// require('remark-lint-list-item-content-indent'),
[require('remark-lint-list-item-indent'), 'space'],
require('remark-lint-no-auto-link-without-protocol'),
require('remark-lint-no-blockquote-without-marker'),
require('remark-lint-no-emphasis-as-heading'),
require('remark-lint-no-file-name-articles'),
require('remark-lint-no-file-name-consecutive-dashes'),
require('remark-lint-no-file-name-irregular-characters'),
require('remark-lint-no-file-name-mixed-case'),
require('remark-lint-no-file-name-outer-dashes'),
require('remark-lint-no-heading-content-indent'),
require('remark-lint-no-heading-indent'),
require('remark-lint-no-heading-punctuation'),
require('remark-lint-no-inline-padding'),
[require('remark-lint-no-multiple-toplevel-headings'), 1],
require('remark-lint-no-shell-dollars'),
require('remark-lint-no-table-indentation'),
require('remark-lint-no-undefined-references'),
require('remark-lint-no-unneeded-full-reference-image'),
require('remark-lint-no-unneeded-full-reference-link'),
require('remark-lint-no-unused-definitions'),
[require('remark-lint-ordered-list-marker-style'), 'consistent'],
[require('remark-lint-ordered-list-marker-value'), 'ordered'],
[require('remark-lint-rule-style'), '---'],
[require('remark-lint-strong-marker'), 'consistent'],
[require('remark-lint-table-cell-padding'), 'consistent'],
require('remark-lint-table-pipe-alignment'),
require('remark-lint-table-pipes'),
[require('remark-lint-unordered-list-marker-style'), 'consistent'],
listItemBulletIndent,
[listItemIndent, 'space'],
noAutoLinkWithoutProtocol,
noBlockquoteWithoutMarker,
noEmphasisAsHeading,
noFileNameArticles,
noFileNameConsecutiveDashes,
noFileNameIrregularCharacters,
noFileNameMixedCase,
noFileNameOuterDashes,
noHeadingContentIndent,
noHeadingIndent,
noHeadingPunctuation,
noInlinePadding,
[noMultipleToplevelHeadings, 1],
noShellDollars,
noTableIndentation,
noUndefinedReferences,
noUnneededFullReferenceImage,
noUnneededFullReferenceLink,
noUnusedDefinitions,
[orderedListMarkerStyle, 'consistent'],
[orderedListMarkerValue, 'ordered'],
[ruleStyle, '---'],
[strongMarker, 'consistent'],
[tableCellPadding, 'consistent'],
tablePipeAlignment,
tablePipes,
[unorderedListMarkerStyle, 'consistent'],

// Third-party plugins
// Disabled as it throws `file.warn is not a function`
// require('remark-lint-no-empty-sections'),

require('remark-lint-match-punctuation'),
require('remark-lint-no-repeat-punctuation'),
require('remark-lint-double-link'),
matchPunctuation,
noRepeatPunctuation,
doubleLink,

// Custom plugins
...require('./rules/index.js')
...customRules,
];

export default plugins;

57 changes: 28 additions & 29 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,51 +1,50 @@
'use strict';
const path = require('path');
const isUrl = require('is-url-superb');
const isGithubUrl = require('is-github-url');
const ora = require('ora');
const remark = require('remark');
const gitClone = require('git-clone');
const globby = require('globby');
const pify = require('pify');
const rmfr = require('rmfr');
const tempy = require('tempy');
const toVfile = require('to-vfile');
const vfileReporterPretty = require('vfile-reporter-pretty');
const config = require('./config.js');
const findReadmeFile = require('./lib/find-readme-file.js');
const codeOfConductRule = require('./rules/code-of-conduct.js');
import process from 'node:process';
import path from 'node:path';
import isUrl from 'is-url-superb';
import isGithubUrl from 'is-github-url';
import ora from 'ora';
import {remark} from 'remark';
import gitClone from 'git-clone';
import {globbySync} from 'globby';
import rmfr from 'rmfr';
import {temporaryDirectory} from 'tempy';
import {readSync as readVFileSync} from 'to-vfile';
import vfileReporterPretty from 'vfile-reporter-pretty';
import config from './config.js';
import findReadmeFile from './lib/find-readme-file.js';
import codeOfConductRule from './rules/code-of-conduct.js';

const lint = options => {
options = {
config,
filename: 'readme.md',
...options
...options,
config: options.config ?? config,
filename: options.filename ?? 'readme.md',
};

const readmeFile = globby.sync(options.filename.replace(/\\/g, '/'), {caseSensitiveMatch: false})[0];
const readmeFile = globbySync(options.filename.replaceAll('\\', '/'), {caseSensitiveMatch: false})[0];

if (!readmeFile) {
return Promise.reject(new Error(`Couldn't find the file ${options.filename}`));
}

const readmeVFile = toVfile.readSync(path.resolve(readmeFile));
const readmeVFile = readVFileSync(path.resolve(readmeFile));
const {dirname} = readmeVFile;
const processTasks = [{
vfile: readmeVFile,
plugins: options.config
plugins: options.config,
}];

const codeOfConductFile = globby.sync(['{code-of-conduct,code_of_conduct}.md', '.github/{code-of-conduct,code_of_conduct}.md'], {caseSensitiveMatch: false, cwd: dirname})[0];
const codeOfConductFile = globbySync(['{code-of-conduct,code_of_conduct}.md', '.github/{code-of-conduct,code_of_conduct}.md'], {caseSensitiveMatch: false, cwd: dirname})[0];
if (codeOfConductFile) {
const codeOfConductVFile = toVfile.readSync(path.resolve(dirname, codeOfConductFile));
const codeOfConductVFile = readVFileSync(path.resolve(dirname, codeOfConductFile));
codeOfConductVFile.repoURL = options.repoURL;
processTasks.push({
vfile: codeOfConductVFile,
plugins: [codeOfConductRule]
plugins: [codeOfConductRule],
});
}

return Promise.all(processTasks.map(({vfile, plugins}) => pify(remark().use(plugins).process)(vfile)));
return Promise.all(processTasks.map(({vfile, plugins}) => remark().use(plugins).process(vfile)));
};

lint.report = async options => {
Expand All @@ -67,8 +66,8 @@ lint._report = async (options, spinner) => {
throw new Error(`Invalid GitHub repo URL: ${options.filename}`);
}

temporary = tempy.directory();
await pify(gitClone)(options.filename, temporary);
temporary = temporaryDirectory();
await gitClone(options.filename, temporary);

const readme = findReadmeFile(temporary);
if (!readme) {
Expand Down Expand Up @@ -112,4 +111,4 @@ lint._report = async (options, spinner) => {
console.log(reporter(vfiles));
};

module.exports = lint;
export default lint;
15 changes: 7 additions & 8 deletions lib/find-author-name.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
'use strict';
const parse = require('parse-github-url');
const readPkg = require('read-pkg');
import parseGitHubUrl from 'parse-github-url';
import {readPackageSync} from 'read-pkg';

module.exports = ({repoURL, dirname}) => {
export default function findAuthorName({repoURL, dirname}) {
if (repoURL) {
return parse(repoURL).owner;
return parseGitHubUrl(repoURL).owner;
}

try {
const json = readPkg.sync({cwd: dirname});
return parse(json.repository.url).owner;
const json = readPackageSync({cwd: dirname});
return parseGitHubUrl(json.repository.url).owner;
} catch {}
};
}
10 changes: 4 additions & 6 deletions lib/find-readme-file.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
'use strict';
import fs from 'node:fs';
import path from 'node:path';

const fs = require('fs');
const path = require('path');

module.exports = directory => {
export default function findReadmeFile(directory) {
const readmeFile = fs.readdirSync(directory).find(filename => (
/readme|readme\.md|readme\.markdown|readme.txt/i.test(filename)
));

if (readmeFile) {
return path.join(fs.realpathSync(directory), readmeFile);
}
};
}
Loading

0 comments on commit 97613ab

Please sign in to comment.