CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-solhint

Solidity code linter providing security and style guide validations for smart contract development

Pending
Overview
Eval results
Files

output-formatting.mddocs/

Output Formatting

Multiple formatter functions for different output formats and integration needs. Solhint provides various formatters to present linting results in different formats suitable for human reading, CI/CD integration, and tool consumption.

Capabilities

Stylish Formatter

Default human-readable formatter with colors and clear structure (default formatter).

/**
 * Default human-readable formatter with colors and clear structure
 * @param {Array<Reporter>} reports - Array of Reporter instances
 * @returns {string} Formatted output string with colors and styling
 */
function stylish(reports);

Usage Examples:

const stylish = require('solhint/lib/formatters/stylish');

const reports = [/* Reporter instances */];
const output = stylish(reports);
console.log(output);

// CLI usage
// solhint contracts/*.sol  (uses stylish by default)
// solhint -f stylish contracts/*.sol

Output Format:

contracts/Token.sol
  10:5  error    Explicitly mark visibility in function  func-visibility
  15:8  warning  Line length exceeds 120 characters      max-line-length

✖ 2 problems (1 error, 1 warning)

JSON Formatter

Machine-readable JSON output for programmatic consumption and CI/CD integration.

/**
 * Machine-readable JSON output for programmatic consumption
 * @param {Array<Reporter>} reports - Array of Reporter instances
 * @returns {string} JSON string containing structured results
 */
function json(reports);

Usage Examples:

const json = require('solhint/lib/formatters/json');

const output = json(reports);
const results = JSON.parse(output);

// Process results programmatically
results.forEach(file => {
  console.log(`File: ${file.filePath}`);
  console.log(`Errors: ${file.errorCount}`);
  file.messages.forEach(msg => {
    console.log(`  ${msg.line}:${msg.column} ${msg.message}`);
  });
});

// CLI usage
// solhint -f json contracts/*.sol > results.json

Output Format:

[
  {
    "filePath": "contracts/Token.sol",
    "messages": [
      {
        "line": 10,
        "column": 5,
        "severity": 2,
        "message": "Explicitly mark visibility in function",
        "ruleId": "func-visibility"
      }
    ],
    "errorCount": 1,
    "warningCount": 0
  }
]

Table Formatter

Tabular output format for clear columnar presentation of results.

/**
 * Tabular output format for clear columnar presentation
 * @param {Array<Reporter>} reports - Array of Reporter instances
 * @returns {string} Table-formatted output string
 */
function table(reports);

Usage Examples:

const table = require('solhint/lib/formatters/table');

const output = table(reports);
console.log(output);

// CLI usage
// solhint -f table contracts/*.sol

Output Format:

┌─────────────────────┬──────┬────────┬──────────┬─────────────────────────────────────┬───────────────────┐
│ File                │ Line │ Column │ Severity │ Message                             │ Rule ID           │
├─────────────────────┼──────┼────────┼──────────┼─────────────────────────────────────┼───────────────────┤
│ contracts/Token.sol │ 10   │ 5      │ error    │ Explicitly mark visibility         │ func-visibility   │
│ contracts/Token.sol │ 15   │ 8      │ warning  │ Line length exceeds 120 characters │ max-line-length   │
└─────────────────────┴──────┴────────┴──────────┴─────────────────────────────────────┴───────────────────┘

Compact Formatter

Compact single-line format for each issue, suitable for grep and simple parsing.

/**
 * Compact single-line format for each issue
 * @param {Array<Reporter>} reports - Array of Reporter instances  
 * @returns {string} Compact formatted output string
 */
function compact(reports);

Usage Examples:

const compact = require('solhint/lib/formatters/compact');

const output = compact(reports);
console.log(output);

// CLI usage
// solhint -f compact contracts/*.sol

Output Format:

contracts/Token.sol: line 10, col 5, Error - Explicitly mark visibility in function (func-visibility)
contracts/Token.sol: line 15, col 8, Warning - Line length exceeds 120 characters (max-line-length)

Unix Formatter

Unix-style format compatible with editors and IDEs that parse compiler output.

/**
 * Unix-style format compatible with editors and IDEs
 * @param {Array<Reporter>} reports - Array of Reporter instances
 * @returns {string} Unix-formatted output string
 */
function unix(reports);

Usage Examples:

const unix = require('solhint/lib/formatters/unix');

const output = unix(reports);
console.log(output);

// CLI usage  
// solhint -f unix contracts/*.sol

Output Format:

contracts/Token.sol:10:5: Explicitly mark visibility in function [func-visibility]
contracts/Token.sol:15:8: Line length exceeds 120 characters [max-line-length]

TAP Formatter

Test Anything Protocol (TAP) format for integration with TAP-consuming test runners.

/**
 * Test Anything Protocol (TAP) format for test runners
 * @param {Array<Reporter>} reports - Array of Reporter instances
 * @returns {string} TAP-formatted output string
 */
function tap(reports);

Usage Examples:

const tap = require('solhint/lib/formatters/tap');

const output = tap(reports);
console.log(output);

// CLI usage
// solhint -f tap contracts/*.sol

Output Format:

TAP version 13
1..2
not ok 1 - contracts/Token.sol:10:5: Explicitly mark visibility in function (func-visibility)
not ok 2 - contracts/Token.sol:15:8: Line length exceeds 120 characters (max-line-length)

SARIF Formatter

Static Analysis Results Interchange Format (SARIF) for security tooling and CI/CD integration.

/**
 * Static Analysis Results Interchange Format (SARIF) for security tooling
 * @param {Array<Reporter>} reports - Array of Reporter instances
 * @returns {string} SARIF JSON formatted output string
 */
function sarif(reports);

Usage Examples:

const sarif = require('solhint/lib/formatters/sarif');

const output = sarif(reports);
const sarifData = JSON.parse(output);

// Process SARIF data
console.log('Tool:', sarifData.runs[0].tool.driver.name);
console.log('Results:', sarifData.runs[0].results.length);

// CLI usage
// solhint -f sarif contracts/*.sol > results.sarif

Output Format:

{
  "version": "2.1.0",
  "$schema": "https://json.schemastore.org/sarif-2.1.0.json",
  "runs": [
    {
      "tool": {
        "driver": {
          "name": "solhint",
          "version": "6.0.1",
          "rules": [
            {
              "id": "func-visibility",
              "shortDescription": {
                "text": "Explicitly mark visibility in function"
              }
            }
          ]
        }
      },
      "results": [
        {
          "ruleId": "func-visibility",
          "level": "error",
          "message": {
            "text": "Explicitly mark visibility in function"
          },
          "locations": [
            {
              "physicalLocation": {
                "artifactLocation": {
                  "uri": "contracts/Token.sol"
                },
                "region": {
                  "startLine": 10,
                  "startColumn": 5
                }
              }
            }
          ]
        }
      ]
    }
  ]
}

Formatter Usage Patterns

Programmatic Usage

const { processPath } = require('solhint');
const stylish = require('solhint/lib/formatters/stylish');
const json = require('solhint/lib/formatters/json');

// Process files
const reports = processPath('contracts/**/*.sol');

// Format for human reading
const humanOutput = stylish(reports);
console.log(humanOutput);

// Format for tools
const jsonOutput = json(reports);
fs.writeFileSync('lint-results.json', jsonOutput);

CLI Usage

# Default formatter (stylish)
solhint contracts/*.sol

# Specific formatter
solhint -f json contracts/*.sol

# Save formatted output
solhint -f sarif contracts/*.sol > security-report.sarif
solhint -f json contracts/*.sol > lint-results.json

CI/CD Integration

# GitHub Actions example
- name: Run Solhint
  run: |
    solhint -f json 'contracts/**/*.sol' > lint-results.json
    
- name: Process Results
  run: |
    node -e "
    const results = JSON.parse(require('fs').readFileSync('lint-results.json'));
    const errors = results.reduce((sum, file) => sum + file.errorCount, 0);
    if (errors > 0) process.exit(1);
    "

Custom Formatter Integration

// Create custom formatter wrapper
function customFormatter(reports) {
  const jsonResults = json(reports);
  const data = JSON.parse(jsonResults);
  
  // Custom processing
  return data.map(file => ({
    file: file.filePath,
    issues: file.messages.length,
    critical: file.messages.filter(m => m.severity === 2).length
  }));
}

const reports = processPath('contracts/**/*.sol');
const customOutput = customFormatter(reports);
console.log(JSON.stringify(customOutput, null, 2));

Output Format Comparison

FormatterUse CaseMachine ReadableColorsStructure
stylishDevelopment, terminal outputNoYesHuman-friendly
jsonCI/CD, programmatic processingYesNoStructured data
tableReports, documentationNoNoTabular
compactGrep, simple parsingPartialNoOne-line
unixEditor integrationPartialNoStandard format
tapTest runnersYesNoTAP protocol
sarifSecurity tools, complianceYesNoIndustry standard

Error Handling in Formatters

Formatters handle various edge cases:

  • Empty report arrays
  • Files with no issues
  • Missing file paths
  • Invalid severity levels
  • Unicode characters in messages
  • Very long file paths or messages
// Example error handling
function safeFormat(formatter, reports) {
  try {
    return formatter(reports || []);
  } catch (error) {
    console.error('Formatter error:', error.message);
    return 'Error formatting results';
  }
}

Performance Considerations

  • JSON and SARIF formatters handle large result sets efficiently
  • Stylish formatter is optimized for terminal display
  • Table formatter may be slow with very wide tables
  • Consider streaming for very large outputs in custom integrations

Install with Tessl CLI

npx tessl i tessl/npm-solhint

docs

cli-interface.md

configuration-management.md

core-processing.md

index.md

output-formatting.md

result-reporting.md

rules-system.md

tile.json