Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions javascript/packages/highlighter/src/diagnostic-renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface DiagnosticRenderOptions {
maxWidth?: number
truncateLines?: boolean
codeUrl?: string
fileUrl?: string
suffix?: string
}

Expand Down Expand Up @@ -142,9 +143,9 @@ export class DiagnosticRenderer {

const shouldWrap = wrapLines && !truncateLines
const shouldTruncate = truncateLines
const fileHeader = `${colorize(path, "cyan")}:${colorize(`${diagnostic.location.start.line}:${diagnostic.location.start.column}`, "cyan")}`

const { codeUrl } = options
const fileHeaderText = `${colorize(path, "cyan")}:${colorize(`${diagnostic.location.start.line}:${diagnostic.location.start.column}`, "cyan")}`
const { codeUrl, fileUrl: fileUrlOption } = options
const fileHeader = fileUrlOption ? hyperlink(fileHeaderText, fileUrlOption) : fileHeaderText

const color = severityColor(diagnostic.severity)
const text = colorize(colorize(diagnostic.severity, color), "bold")
Expand Down
5 changes: 5 additions & 0 deletions javascript/packages/highlighter/src/highlighter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export interface HighlightOptions {
maxWidth?: number
truncateLines?: boolean
codeUrlBuilder?: (code: string) => string
fileUrlBuilder?: (path: string, diagnostic: Diagnostic) => string
suffixBuilder?: (diagnostic: Diagnostic) => string | undefined
}

Expand All @@ -32,6 +33,7 @@ export interface HighlightDiagnosticOptions {
maxWidth?: number
truncateLines?: boolean
codeUrl?: string
fileUrl?: string
suffix?: string
}

Expand Down Expand Up @@ -102,6 +104,7 @@ export class Highlighter {
maxWidth = LineWrapper.getTerminalWidth(),
truncateLines = false,
codeUrlBuilder,
fileUrlBuilder,
suffixBuilder,
} = options

Expand All @@ -111,6 +114,7 @@ export class Highlighter {
for (let i = 0; i < diagnostics.length; i++) {
const diagnostic = diagnostics[i]
const codeUrl = codeUrlBuilder && diagnostic.code ? codeUrlBuilder(diagnostic.code) : undefined
const fileUrl = fileUrlBuilder ? fileUrlBuilder(path, diagnostic) : undefined
const suffix = suffixBuilder ? suffixBuilder(diagnostic) : undefined
const result = this.highlightDiagnostic(path, diagnostic, content, {
contextLines,
Expand All @@ -119,6 +123,7 @@ export class Highlighter {
maxWidth,
truncateLines,
codeUrl,
fileUrl,
suffix,
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { colorize, Highlighter, type ThemeInput, DEFAULT_THEME } from "@herb-too

import { BaseFormatter } from "./base-formatter.js"
import { LineWrapper } from "@herb-tools/highlighter"
import { ruleDocumentationUrl } from "../../urls.js"
import { ruleDocumentationUrl, fileUrl } from "../../urls.js"

import type { Diagnostic } from "@herb-tools/core"
import type { ProcessedFile } from "../file-processor.js"
Expand Down Expand Up @@ -44,6 +44,7 @@ export class DetailedFormatter extends BaseFormatter {
wrapLines: this.wrapLines,
truncateLines: this.truncateLines,
codeUrlBuilder: ruleDocumentationUrl,
fileUrlBuilder: (path) => fileUrl(path),
suffixBuilder: (diagnostic) => autocorrectableSet.has(diagnostic) ? correctableTag : undefined,
})

Expand All @@ -61,6 +62,7 @@ export class DetailedFormatter extends BaseFormatter {
wrapLines: this.wrapLines,
truncateLines: this.truncateLines,
codeUrl,
fileUrl: fileUrl(filename),
suffix,
})
console.log(`\n${formatted}`)
Expand Down
28 changes: 17 additions & 11 deletions javascript/packages/linter/src/cli/formatters/simple-formatter.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { colorize, hyperlink, TextFormatter } from "@herb-tools/highlighter"

import { BaseFormatter } from "./base-formatter.js"
import { ruleDocumentationUrl } from "../../urls.js"
import { ruleDocumentationUrl, fileUrl } from "../../urls.js"

import type { Diagnostic } from "@herb-tools/core"
import type { ProcessedFile } from "../file-processor.js"
Expand All @@ -25,35 +25,41 @@ export class SimpleFormatter extends BaseFormatter {
}

formatFile(filename: string, offenses: Diagnostic[]): void {
console.log(`${colorize(filename, "cyan")}:`)
const filenameText = colorize(filename, "cyan")
const filenameLink = hyperlink(filenameText, fileUrl(filename))
console.log(`${filenameLink}:`)

for (const offense of offenses) {
const isError = offense.severity === "error"
const severity = isError ? colorize("✗", "brightRed") : colorize("⚠", "brightYellow")
const ruleText = `(${offense.code})`
const rule = offense.code ? hyperlink(ruleText, ruleDocumentationUrl(offense.code)) : ruleText
const locationString = `${offense.location.start.line}:${offense.location.start.column}`
const paddedLocation = locationString.padEnd(4)

const { line, column } = offense.location.start
const locationString = `${line}:${column}`
const paddedLocation = colorize(locationString.padEnd(4), "gray")
const message = TextFormatter.highlightBackticks(offense.message)
console.log(` ${colorize(paddedLocation, "gray")} ${severity} ${message} ${rule}`)

console.log(` ${paddedLocation} ${severity} ${message} ${rule}`)
}
}

formatFileProcessed(filename: string, processedFiles: ProcessedFile[]): void {
console.log(`${colorize(filename, "cyan")}:`)
const filenameText = colorize(filename, "cyan")
const filenameLink = hyperlink(filenameText, fileUrl(filename))
console.log(`${filenameLink}:`)

for (const { offense, autocorrectable } of processedFiles) {
const isError = offense.severity === "error"
const severity = isError ? colorize("✗", "brightRed") : colorize("⚠", "brightYellow")
const ruleText = `(${offense.code})`
const rule = offense.code ? hyperlink(ruleText, ruleDocumentationUrl(offense.code)) : ruleText
const locationString = `${offense.location.start.line}:${offense.location.start.column}`
const paddedLocation = locationString.padEnd(4)
const { line, column } = offense.location.start
const locationString = `${line}:${column}`
const paddedLocation = colorize(locationString.padEnd(4), "gray")
const correctable = autocorrectable ? colorize(colorize(" [Correctable]", "green"), "bold") : ""

const message = TextFormatter.highlightBackticks(offense.message)
console.log(` ${colorize(paddedLocation, "gray")} ${severity} ${message} ${rule}${correctable}`)

console.log(` ${paddedLocation} ${severity} ${message} ${rule}${correctable}`)
}
}
}
2 changes: 1 addition & 1 deletion javascript/packages/linter/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export * from "./linter.js"
export * from "./rules/index.js"
export * from "./types.js"
export * from "./urls.js"

export { ruleDocumentationUrl } from "./urls.js"
export { rules } from "./rules.js"
7 changes: 7 additions & 0 deletions javascript/packages/linter/src/urls.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import { resolve } from "node:path"

const DOCS_BASE_URL = "https://herb-tools.dev/linter/rules"

export function ruleDocumentationUrl(ruleId: string): string {
return `${DOCS_BASE_URL}/${ruleId}`
}

export function fileUrl(filePath: string): string {
const absolutePath = resolve(filePath)
return `file://${absolutePath}`
}
Loading