Skip to content

Commit

Permalink
Breaking: use ESM and drop Node.js < 14
Browse files Browse the repository at this point in the history
CommonJS modules can no longer `require('hallmark')`. They must use
ESM themselves, or a dynamic `import()`. For further guidance please
see https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c

As for the `hallmark` CLI: in Node.js versions older than 14 it is
now a noop.

Needed for #80.
Depends on tape-testing/tape#571
  • Loading branch information
vweevers committed Nov 14, 2021
1 parent 0082679 commit 2f64070
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 99 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node: [10, 12, 14, 16]
node: [14, 16]
runs-on: ${{ matrix.os }}
name: ${{ matrix.os }} / Node ${{ matrix.node }}
steps:
Expand Down
26 changes: 12 additions & 14 deletions cli.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
#!/usr/bin/env node
'use strict'

if (process.version.match(/^v(\d+)\./)[1] < 10) {
console.error('hallmark: Node 10 or greater is required. `hallmark` did not run.')
process.exit(0)
}
import subarg from 'subarg'
import fs from 'node:fs'
import * as hallmark from './index.js'

const argv = require('subarg')(process.argv.slice(2), {
const argv = subarg(process.argv.slice(2), {
boolean: ['fix', 'help', 'version', 'commits'],
string: ['report'],
default: {
Expand All @@ -25,16 +23,17 @@ const argv = require('subarg')(process.argv.slice(2), {
if (argv.help) {
usage(0)
} else if (argv.version) {
console.log(require('./package.json').version)
const fp = new URL('./package.json', import.meta.url)
console.log(JSON.parse(fs.readFileSync(fp, 'utf8')).version)
} else {
const { commits, _: rest, ...options } = argv

if (rest[0] === 'lint') {
options.files = files(rest.slice(1))
require('./index.js').lint(options, done)
hallmark.lint(options, done)
} else if (rest[0] === 'fix') {
options.files = files(rest.slice(1))
require('./index.js').fix(options, done)
hallmark.fix(options, done)
} else if (rest[0] === 'bump') {
console.error("Error: the 'bump' command has been renamed to 'cc add'.\n")
usage(1)
Expand All @@ -43,7 +42,7 @@ if (argv.help) {
const target = rest[2]
if (!target) usage(1)
options.files = files(rest.slice(3))
require('./index.js').cc.add(target, { ...options, commits }, done)
hallmark.cc.add(target, { ...options, commits }, done)
} else {
console.error('Error: unknown command.')
usage(1)
Expand All @@ -52,7 +51,7 @@ if (argv.help) {
// Old usage (no commands)
// TODO: deprecate?
options.files = files(rest)
require('./index.js')[options.fix ? 'fix' : 'lint'](options, done)
hallmark[options.fix ? 'fix' : 'lint'](options, done)
}
}

Expand All @@ -66,9 +65,8 @@ function done (err, result) {
}

function usage (exitCode) {
const fs = require('fs')
const path = require('path')
const usage = fs.readFileSync(path.join(__dirname, 'USAGE'), 'utf8').trim()
const fp = new URL('./USAGE', import.meta.url)
const usage = fs.readFileSync(fp, 'utf8').trim()

if (exitCode) {
console.error(usage)
Expand Down
12 changes: 12 additions & 0 deletions compat/cli.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env node
'use strict'

// Must be CommonJS to support Node.js < 12.20
if (process.version.match(/^v(\d+)\./)[1] < 14) {
// Return silently to support hallmark in 'npm test'
console.error('Skipping hallmark: Node 14 or greater is required.')
process.exit(0)
}

// Wrapped again to avoid 'Unexpected token import'
require('./import-cli.cjs')
6 changes: 6 additions & 0 deletions compat/import-cli.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'use strict'

import('../cli.js').catch(function (err) {
console.error(err)
process.exit(1)
})
84 changes: 45 additions & 39 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
'use strict'

const deglob = require('deglob')
const find = require('find-file-up')
const Githost = require('find-githost')
const engine = require('unified-engine')
const color = require('supports-color').stdout
const fromCallback = require('catering').fromCallback
const processor = require('remark')
const path = require('path')
const fs = require('fs')
import deglob from 'deglob'
import find from 'find-file-up'
import Githost from 'find-githost'
import engine from 'unified-engine'
import { stdout as color } from 'supports-color'
import { fromCallback } from 'catering'
import defaultReporter from 'vfile-reporter-shiny'
import processor from 'remark'
import remarkCommonChangelog from 'remark-common-changelog'
import remarkGithub from 'remark-github'
import remarkAutolinkReferences from 'remark-autolink-references'
import remarkToc from 'remark-toc'
import remarkCollapse from 'remark-collapse'
import path from 'node:path'
import fs from 'node:fs'
import linter from './lint.js'

const kPromise = Symbol('promise')

Expand Down Expand Up @@ -46,7 +51,7 @@ function hallmark (options, callback) {
reporter = reporter._[0]
}
} else {
reporter = require('vfile-reporter-shiny')
reporter = defaultReporter
}

const paddedTable = rc.paddedTable !== false
Expand All @@ -73,23 +78,23 @@ function hallmark (options, callback) {
reporter,
reporterOptions,
plugins: [
[require('remark-common-changelog'), { cwd, fix, pkg, repository, ...changelog }],
[require('remark-github'), { repository }],
[remarkCommonChangelog, { cwd, fix, pkg, repository, ...changelog }],
[remarkGithub, { repository }],

// Does nothing unless configured
rc.autolinkReferences
? [require('remark-autolink-references'), {
? [remarkAutolinkReferences, {
...rc.autolinkReferences,
fix
}]
: null,

// TODO: https://github.com/vweevers/hallmark/issues/36
toc ? [require('remark-toc'), { tight: true }] : null,
toc ? [require('remark-collapse'), collapseToc()] : null,
toc ? [remarkToc, { tight: true }] : null,
toc ? [remarkCollapse, collapseToc()] : null,

fix ? fixers : null,
require('./lint.js')({ fix, repository, paddedTable, validateLinks }),
linter({ fix, repository, paddedTable, validateLinks }),
plugins
].filter(Boolean),
settings: {
Expand Down Expand Up @@ -121,7 +126,7 @@ function hallmark (options, callback) {
return callback[kPromise]
}

exports.lint = function (options, callback) {
export function lint (options, callback) {
if (typeof options === 'function') {
callback = options
options = {}
Expand All @@ -130,7 +135,7 @@ exports.lint = function (options, callback) {
return hallmark({ ...options, fix: false }, callback)
}

exports.fix = function (options, callback) {
export function fix (options, callback) {
if (typeof options === 'function') {
callback = options
options = {}
Expand All @@ -139,28 +144,29 @@ exports.fix = function (options, callback) {
return hallmark({ ...options, fix: true }, callback)
}

exports.cc = {}
exports.cc.add = function (target, options, callback) {
if (!target) {
throw new TypeError('First argument "target" is required')
} else if (typeof target !== 'string') {
throw new TypeError('First argument "target" must be a string')
}
export const cc = {
add: function (target, options, callback) {
if (!target) {
throw new TypeError('First argument "target" is required')
} else if (typeof target !== 'string') {
throw new TypeError('First argument "target" must be a string')
}

if (typeof options === 'function') {
callback = options
options = {}
} else if (options == null) {
options = {}
}
if (typeof options === 'function') {
callback = options
options = {}
} else if (options == null) {
options = {}
}

const changelog = {
commits: options.commits !== false,
...options.changelog,
add: target
}
const changelog = {
commits: options.commits !== false,
...options.changelog,
add: target
}

return hallmark({ ...options, changelog, fix: true }, callback)
return hallmark({ ...options, changelog, fix: true }, callback)
}
}

function read (file, cwd) {
Expand Down
66 changes: 44 additions & 22 deletions lint.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,37 @@
module.exports = function ({ fix, repository, paddedTable, validateLinks }) {
import remarkLint from 'remark-lint'
import remarkLintNoUndefinedReferences from 'remark-lint-no-undefined-references'
import remarkLintNoUnusedDefinitions from 'remark-lint-no-unused-definitions'
import remarkLintNoDuplicateDefinitions from 'remark-lint-no-duplicate-definitions'
import remarkLintNoInlinePadding from 'remark-lint-no-inline-padding'
import remarkLintBlockquoteIndentation from 'remark-lint-blockquote-indentation'
import remarkLintCheckboxContentIndent from 'remark-lint-checkbox-content-indent'
import remarkLintFinalNewline from 'remark-lint-final-newline'
import remarkLintListItemBulletIndent from 'remark-lint-list-item-bullet-indent'
import remarkLintListItemIndent from 'remark-lint-list-item-indent'
import remarkLintNoAutoLinkWithoutProtocol from 'remark-lint-no-auto-link-without-protocol'
import remarkLintNoBlockquoteWithoutMarker from 'remark-lint-no-blockquote-without-marker'
import remarkLintNoLiteralUrls from 'remark-lint-no-literal-urls'
import remarkLintNoHeadingContentIndent from 'remark-lint-no-heading-content-indent'
import remarkLintHardBreakSpaces from 'remark-lint-hard-break-spaces'
import remarkLintCodeBlockStyle from 'remark-lint-code-block-style'
import remarkLintTableCellPadding from 'remark-lint-table-cell-padding'
import remarkLintTablePipes from 'remark-lint-table-pipes'
import remarkLintCheckboxCharacterStyle from 'remark-lint-checkbox-character-style'
import remarkLintDefinitionCase from 'remark-lint-definition-case'
import remarkValidateLinks from 'remark-validate-links'

export default function ({ fix, repository, paddedTable, validateLinks }) {
const preset = {
plugins: [
require('remark-lint'),
remarkLint,

// These are not automatically fixed by remark-stringify
require('remark-lint-no-undefined-references'),
require('remark-lint-no-unused-definitions'),
require('remark-lint-no-duplicate-definitions'),
require('remark-lint-no-inline-padding'),
[require('remark-lint-blockquote-indentation'), 2], // Means 1 space.
require('remark-lint-checkbox-content-indent')
remarkLintNoUndefinedReferences,
remarkLintNoUnusedDefinitions,
remarkLintNoDuplicateDefinitions,
remarkLintNoInlinePadding,
[remarkLintBlockquoteIndentation, 2], // Means 1 space.
remarkLintCheckboxContentIndent

// TBD
// require('remark-lint-no-shortcut-reference-image'),
Expand All @@ -19,32 +41,32 @@ module.exports = function ({ fix, repository, paddedTable, validateLinks }) {

if (!fix) {
preset.plugins.push(
require('remark-lint-final-newline'),
require('remark-lint-list-item-bullet-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-literal-urls'),
require('remark-lint-no-heading-content-indent'),
require('remark-lint-hard-break-spaces'),
[require('remark-lint-code-block-style'), 'fenced'],
remarkLintFinalNewline,
remarkLintListItemBulletIndent,
[remarkLintListItemIndent, 'space'],
remarkLintNoAutoLinkWithoutProtocol,
remarkLintNoBlockquoteWithoutMarker,
remarkLintNoLiteralUrls,
remarkLintNoHeadingContentIndent,
remarkLintHardBreakSpaces,
[remarkLintCodeBlockStyle, 'fenced'],

// TODO: support fixed-width columns (https://github.com/remarkjs/remark-lint/issues/217)
paddedTable ? [require('remark-lint-table-cell-padding'), 'padded'] : null,
paddedTable ? [remarkLintTableCellPadding, 'padded'] : null,

require('remark-lint-table-pipes'),
[require('remark-lint-checkbox-character-style'), {
remarkLintTablePipes,
[remarkLintCheckboxCharacterStyle, {
checked: 'x', unchecked: ' '
}],
require('remark-lint-definition-case')
remarkLintDefinitionCase
)
}

// Temporarily allow skipping link validation, because remark does not parse
// HTML anchors - as used in various Level readme's. Those readme's should be
// updated to use markdown only.
if (validateLinks) {
preset.plugins.push([require('remark-validate-links'), {
preset.plugins.push([remarkValidateLinks, {
// If we don't pass this, remark-validate-links tries to get the repo url
// from `git remote -v` which is not desirable for forks.
repository: repository || false
Expand Down
16 changes: 9 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@
"description": "Markdown Style Guide, with linter and automatic fixer",
"author": "Vincent Weevers",
"license": "GPL-3.0",
"bin": "cli.js",
"main": "index.js",
"bin": "compat/cli.cjs",
"type": "module",
"exports": "./index.js",
"scripts": {
"test": "standard && depcheck && node cli.js && tape test/*.js",
"test": "standard && depcheck --ignores subarg && node cli.js && tape test/*.js",
"hallmark": "node cli.js --fix",
"check-licenses": "npm-consider install --test --production"
},
"files": [
"CHANGELOG.md",
"cli.js",
"compat",
"index.js",
"lint.js",
"USAGE"
Expand Down Expand Up @@ -56,12 +58,12 @@
"vfile-reporter-shiny": "^0.1.2"
},
"devDependencies": {
"depcheck": "^1.2.0",
"depcheck": "^1.4.2",
"git-pull-or-clone": "^2.0.1",
"npm-consider": "^1.7.0",
"standard": "^16.0.4",
"tape": "^5.0.1",
"tempy": "0.2.1"
"tape": "github:substack/tape#d487add",
"tempy": "^2.0.0"
},
"repository": {
"type": "git",
Expand All @@ -84,7 +86,7 @@
"unified"
],
"engines": {
"node": ">=6"
"node": ">=14"
},
"config": {
"allowedLicenseTypes": [
Expand Down
Loading

0 comments on commit 2f64070

Please sign in to comment.