Skip to content

CLI Tool

DevOps Engineering Style Guide provides a standalone CLI tool (devops-style) for checking and enforcing style standards across your codebase.

Overview

The CLI wraps multiple linters and formatters into a single, consistent interface with:

  • Multi-language support (Python, TypeScript, Bash, YAML, Terraform, and more)
  • Automatic configuration discovery
  • Auto-fix capabilities
  • CI/CD-friendly output formats (JSON, SARIF)
  • Custom plugin support

Installation

# Install globally via npm
npm install -g devops-engineering-style-guide

# Or use with npx (no installation)
npx devops-engineering-style-guide check

# Or use via Docker
docker run --rm -v $(pwd):/workspace ghcr.io/tydukes/coding-style-guide:latest validate

Quick Start

# Initialize configuration
devops-style init

# Check all files
devops-style check

# Auto-fix issues
devops-style fix

# Check specific files
devops-style check "src/**/*.py"

Commands

Check Command

Validates files against style guide standards.

# Check all files
devops-style check

# Check specific patterns
devops-style check "src/**/*.ts" "lib/**/*.py"

# Filter by language
devops-style check --language python

# Output as JSON for tooling
devops-style check --format json

# Output as SARIF for GitHub Code Scanning
devops-style check --format sarif > results.sarif

# Strict mode (warnings become errors)
devops-style check --strict

# Quiet mode (errors only)
devops-style check --quiet

# Check and fix in one command
devops-style check --fix

Fix Command

Auto-fixes style violations where possible.

# Fix all files
devops-style fix

# Preview changes without modifying files
devops-style fix --dry-run

# Fix specific language
devops-style fix --language typescript

# Output fix results as JSON
devops-style fix --format json

Init Command

Creates a configuration file in your project.

# Standard configuration
devops-style init

# Minimal configuration
devops-style init --template minimal

# Strict configuration (all linters enabled)
devops-style init --template strict

# Overwrite existing
devops-style init --force

List Command

Shows available linters and their status.

# List all linters
devops-style list

# Filter by language
devops-style list --language python

# JSON output
devops-style list --format json

Configuration

Configuration File Locations

The CLI searches for configuration in this order:

  1. .dukestylerc
  2. .dukestylerc.json
  3. .dukestylerc.yaml
  4. .dukestylerc.yml
  5. dukestyle.config.js
  6. .devops-style.json
  7. .devops-style.yaml
  8. package.json (dukestyle key)

Configuration Schema

# .dukestyle.yaml

# Extends another configuration (optional)
extends:
  - "devops-engineering-style-guide/config/strict"

# Language configurations
languages:
  python:
    enabled: true
    extensions:
      - .py
      - .pyi
    linters:
      black:
        enabled: true
        configFile: pyproject.toml
      flake8:
        enabled: true
        configFile: .flake8
    formatters:
      - black

  typescript:
    enabled: true
    extensions:
      - .ts
      - .tsx
      - .js
      - .jsx
    linters:
      eslint:
        enabled: true
        configFile: .eslintrc.js
      prettier:
        enabled: true
    formatters:
      - prettier

  bash:
    enabled: true
    extensions:
      - .sh
      - .bash
    linters:
      shellcheck:
        enabled: true

  yaml:
    enabled: true
    extensions:
      - .yml
      - .yaml
    linters:
      yamllint:
        enabled: true
        configFile: .yamllint.yaml

  markdown:
    enabled: true
    extensions:
      - .md
    linters:
      markdownlint:
        enabled: true
        configFile: .markdownlint.json

  terraform:
    enabled: true
    extensions:
      - .tf
      - .tfvars
    linters:
      terraform-fmt:
        enabled: true
      terraform-validate:
        enabled: true
      tflint:
        enabled: false

  dockerfile:
    enabled: true
    extensions:
      - Dockerfile
    linters:
      hadolint:
        enabled: true

# Files to ignore
ignore:
  - "**/node_modules/**"
  - "**/dist/**"
  - "**/.git/**"
  - "**/__pycache__/**"
  - "**/.venv/**"
  - "**/.terraform/**"

# Caching
cache: true
cacheLocation: .dukestyle-cache

# Custom plugins
plugins:
  - name: my-custom-plugin
    path: ./plugins/my-plugin.js

Supported Languages

Language Linters Auto-Fix
Python black, flake8 Yes (black)
TypeScript eslint, prettier Yes
JavaScript eslint, prettier Yes
Bash shellcheck No
YAML yamllint No
JSON prettier Yes
Markdown markdownlint Partial
Terraform terraform fmt, tflint Yes (fmt)
Dockerfile hadolint No

CI/CD Integration

GitHub Actions

name: Style Check

on: [push, pull_request]

jobs:
  style:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install CLI
        run: npm install -g devops-engineering-style-guide

      - name: Run style check
        run: devops-style check --format sarif > style-results.sarif

      - name: Upload SARIF results
        uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: style-results.sarif

GitLab CI/CD

style-check:
  image: node:20-alpine
  stage: test
  script:
    - npm install -g devops-engineering-style-guide
    - devops-style check --format json > gl-code-quality-report.json
  artifacts:
    reports:
      codequality: gl-code-quality-report.json
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

Pre-commit Hook

# .pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: devops-style
        name: Dukes Style Check
        entry: devops-style check
        language: system
        pass_filenames: false

Custom Plugins

Extend the CLI with custom linters and rules.

Plugin Structure

// plugins/my-plugin.js
export default {
  name: 'my-plugin',
  version: '1.0.0',

  // Custom linters
  linters: [
    {
      name: 'my-linter',
      language: 'python',

      async check(files, config) {
        const results = [];
        for (const file of files) {
          const content = await fs.readFile(file, 'utf-8');
          const issues = analyzeFile(content);
          results.push({
            file,
            language: 'python',
            issues,
            fixable: issues.filter(i => i.fixable).length,
          });
        }
        return results;
      },

      async fix(files, config) {
        // Implement fix logic
      },
    },
  ],

  // Custom rules
  rules: [
    {
      name: 'my-plugin/no-print',
      description: 'Disallow print statements',
      language: 'python',

      check(content, file) {
        const issues = [];
        const lines = content.split('\n');
        lines.forEach((line, index) => {
          if (line.match(/\bprint\s*\(/)) {
            issues.push({
              line: index + 1,
              column: line.indexOf('print') + 1,
              message: 'Avoid using print() in production code',
              rule: 'my-plugin/no-print',
              severity: 'warning',
              fixable: false,
            });
          }
        });
        return issues;
      },
    },
  ],
};

Plugin Configuration

# .dukestyle.yaml
plugins:
  - name: my-plugin
    path: ./plugins/my-plugin.js
    options:
      severity: error
      exclude:
        - "**/tests/**"

Output Formats

Text (Default)

Human-readable format for terminal output.

src/main.py
  10:5  warning  Line too long (120 > 100)  (E501)
  25:1  error    Undefined name 'foo'  (F821) [fixable]

src/utils.py
  5:1   warning  File would be reformatted  (black/format) [fixable]

✖ 3 files checked, 1 error, 2 warnings, 2 fixable with --fix (150ms)

JSON

Machine-readable format for CI/CD integration.

{
  "results": [
    {
      "file": "src/main.py",
      "language": "python",
      "issues": [
        {
          "line": 10,
          "column": 5,
          "message": "Line too long (120 > 100)",
          "rule": "E501",
          "severity": "warning",
          "fixable": false
        }
      ],
      "fixable": 0
    }
  ],
  "summary": {
    "files": 3,
    "errors": 1,
    "warnings": 2,
    "fixable": 2,
    "duration": 150
  }
}

SARIF

GitHub Code Scanning compatible format.

devops-style check --format sarif > results.sarif

Exit Codes

Code Meaning
0 No errors found
1 Style violations found
2 Configuration or runtime error

Comparison with Docker Container

Feature CLI Tool Docker Container
Installation npm install -g docker pull
Speed Faster (no container overhead) Slower startup
Dependencies Must install linters All included
Customization Full plugin support Limited
CI/CD Native Volume mounts

Use the CLI for:

  • Local development
  • Custom plugins
  • Fast feedback loops
  • CI/CD with existing linter installations

Use Docker for:

  • Consistent environments
  • No local dependencies
  • One-time validation
  • Isolation requirements

Troubleshooting

Linter Not Found

# Check linter availability
devops-style list

# Install missing linters
pip install black flake8
npm install -g eslint prettier

Configuration Not Loading

# Debug configuration discovery
devops-style check --debug

Slow Performance

# Enable caching
devops-style check  # Cache enabled by default

# Clear cache if needed
rm -rf .dukestyle-cache