Initial commit
This commit is contained in:
277
skills/clj-kondo/README.md
Normal file
277
skills/clj-kondo/README.md
Normal file
@@ -0,0 +1,277 @@
|
||||
# clj-kondo Skill
|
||||
|
||||
A comprehensive skill for using clj-kondo, the fast and accurate Clojure linter, including guidance on writing custom hooks for domain-specific linting rules.
|
||||
|
||||
## Contents
|
||||
|
||||
- **SKILL.md** - Complete documentation covering usage, configuration, built-in linters, and custom hooks
|
||||
- **QUICK_REFERENCE.md** - Quick reference for common configurations and hook patterns
|
||||
- **INDEX.md** - Navigation guide and learning path
|
||||
- **examples.clj** - Runnable hook examples
|
||||
|
||||
## What is clj-kondo?
|
||||
|
||||
clj-kondo is a static analyzer and linter for Clojure that provides:
|
||||
|
||||
- Fast, native binary with instant startup
|
||||
- Comprehensive built-in linting rules
|
||||
- Custom hooks for domain-specific linting
|
||||
- Zero configuration required (but highly customizable)
|
||||
- IDE integration (VS Code, Emacs, IntelliJ, Vim)
|
||||
- CI/CD ready
|
||||
- Cross-platform support (Linux, macOS, Windows)
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
# macOS/Linux
|
||||
brew install clj-kondo/brew/clj-kondo
|
||||
|
||||
# Manual installation
|
||||
curl -sLO https://raw.githubusercontent.com/clj-kondo/clj-kondo/master/script/install-clj-kondo
|
||||
chmod +x install-clj-kondo
|
||||
./install-clj-kondo
|
||||
```
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```bash
|
||||
# Lint a file
|
||||
clj-kondo --lint src/myapp/core.clj
|
||||
|
||||
# Lint a directory
|
||||
clj-kondo --lint src
|
||||
|
||||
# Lint with JSON output
|
||||
clj-kondo --lint src --config '{:output {:format :json}}'
|
||||
```
|
||||
|
||||
### Configuration
|
||||
|
||||
Create `.clj-kondo/config.edn`:
|
||||
|
||||
```clojure
|
||||
{:linters {:unused-binding {:level :warning}
|
||||
:unused-namespace {:level :warning}
|
||||
:unresolved-symbol {:level :error}}
|
||||
:output {:pattern "{{LEVEL}} {{filename}}:{{row}}:{{col}} {{message}}"}}
|
||||
```
|
||||
|
||||
### Creating Your First Hook
|
||||
|
||||
1. **Create hook file** at `.clj-kondo/hooks/my_hooks.clj`:
|
||||
|
||||
```clojure
|
||||
(ns hooks.my-hooks
|
||||
(:require [clj-kondo.hooks-api :as api]))
|
||||
|
||||
(defn deprecation-warning [{:keys [node]}]
|
||||
{:findings [{:message "This function is deprecated"
|
||||
:type :deprecated-api
|
||||
:row (api/row node)
|
||||
:col (api/col node)
|
||||
:level :warning}]})
|
||||
```
|
||||
|
||||
2. **Register hook** in `.clj-kondo/config.edn`:
|
||||
|
||||
```clojure
|
||||
{:hooks {:analyze-call {mylib/old-fn hooks.my-hooks/deprecation-warning}}}
|
||||
```
|
||||
|
||||
3. **Test it**:
|
||||
|
||||
```bash
|
||||
clj-kondo --lint src
|
||||
```
|
||||
|
||||
## What This Skill Covers
|
||||
|
||||
### Basic Usage
|
||||
- Installation and setup
|
||||
- Command-line usage
|
||||
- Output formats
|
||||
- Cache management
|
||||
|
||||
### Configuration
|
||||
- Configuration file structure
|
||||
- Linter levels and options
|
||||
- Local and global configuration
|
||||
- Inline suppressions
|
||||
- Configuration merging
|
||||
|
||||
### Built-in Linters
|
||||
- Namespace and require linters
|
||||
- Binding and symbol linters
|
||||
- Function and arity linters
|
||||
- Collection and syntax linters
|
||||
- Type checking linters
|
||||
|
||||
### Custom Hooks (Advanced)
|
||||
- What hooks are and when to use them
|
||||
- Hook architecture and API
|
||||
- `:analyze-call` hooks for custom warnings
|
||||
- `:macroexpand` hooks for DSL support
|
||||
- Node API reference
|
||||
- Practical hook examples:
|
||||
- Deprecation warnings
|
||||
- Argument validation
|
||||
- DSL expansion
|
||||
- Thread-safety checks
|
||||
- Required keys validation
|
||||
- Testing hooks
|
||||
- Distributing hooks with libraries
|
||||
|
||||
### Integration
|
||||
- IDE setup (VS Code, Emacs, IntelliJ, Vim)
|
||||
- CI/CD integration (GitHub Actions, GitLab CI)
|
||||
- Pre-commit hooks
|
||||
|
||||
### Best Practices
|
||||
- Team configuration
|
||||
- Gradual adoption for legacy code
|
||||
- Performance optimization
|
||||
- Thoughtful suppression
|
||||
|
||||
## Key Features Covered
|
||||
|
||||
### Built-in Linting
|
||||
- Unused bindings and namespaces
|
||||
- Unresolved symbols
|
||||
- Invalid function arities
|
||||
- Duplicate map/set keys
|
||||
- Type mismatches
|
||||
- Syntax errors
|
||||
- Code style issues
|
||||
|
||||
### Custom Hooks
|
||||
- API deprecation warnings
|
||||
- Domain-specific validations
|
||||
- Custom DSL support
|
||||
- Team convention enforcement
|
||||
- Advanced static analysis
|
||||
|
||||
### Developer Experience
|
||||
- Real-time IDE feedback
|
||||
- Minimal configuration
|
||||
- Fast performance
|
||||
- Clear error messages
|
||||
- Extensibility
|
||||
|
||||
## Common Use Cases
|
||||
|
||||
### 1. Basic Project Linting
|
||||
|
||||
```bash
|
||||
# Initial setup
|
||||
cd my-project
|
||||
clj-kondo --lint "$(clojure -Spath)" --dependencies --parallel --copy-configs
|
||||
|
||||
# Regular linting
|
||||
clj-kondo --lint src test
|
||||
```
|
||||
|
||||
### 2. Deprecation Warnings
|
||||
|
||||
Create hooks to warn about deprecated APIs:
|
||||
|
||||
```clojure
|
||||
;; .clj-kondo/hooks/deprecation.clj
|
||||
(defn warn-old-api [{:keys [node]}]
|
||||
{:findings [{:message "Use new-api instead"
|
||||
:level :warning
|
||||
:row (api/row node)
|
||||
:col (api/col node)}]})
|
||||
```
|
||||
|
||||
### 3. DSL Linting
|
||||
|
||||
Expand custom macros for better analysis:
|
||||
|
||||
```clojure
|
||||
;; .clj-kondo/hooks/dsl.clj
|
||||
(defn expand-defentity [{:keys [node]}]
|
||||
(let [[_ name & body] (:children node)]
|
||||
{:node (api/list-node
|
||||
[(api/token-node 'def) name (api/map-node body)])}))
|
||||
```
|
||||
|
||||
### 4. Team Standards
|
||||
|
||||
Enforce consistent aliases:
|
||||
|
||||
```clojure
|
||||
{:linters {:consistent-alias {:level :warning
|
||||
:aliases {clojure.string str
|
||||
clojure.set set}}}}
|
||||
```
|
||||
|
||||
## Learning Path
|
||||
|
||||
1. **Start with README.md** (this file) - Quick overview
|
||||
2. **Install clj-kondo** - Get it running
|
||||
3. **Read SKILL.md "Getting Started"** - Basic usage
|
||||
4. **Try basic linting** - Run on your code
|
||||
5. **Configure for your project** - Customize linters
|
||||
6. **Study built-in linters** - Understand what's checked
|
||||
7. **Learn hook basics** - Read "Custom Hooks" section
|
||||
8. **Write your first hook** - Start with deprecation warning
|
||||
9. **Explore advanced hooks** - Study examples
|
||||
10. **Integrate with IDE/CI** - Set up automation
|
||||
|
||||
## Hook Examples Preview
|
||||
|
||||
### Simple Deprecation Hook
|
||||
|
||||
```clojure
|
||||
(defn deprecation [{:keys [node]}]
|
||||
{:findings [{:message "Deprecated: use new-fn"
|
||||
:type :deprecated
|
||||
:row (api/row node)
|
||||
:col (api/col node)}]})
|
||||
```
|
||||
|
||||
### Argument Validation Hook
|
||||
|
||||
```clojure
|
||||
(defn validate-args [{:keys [node]}]
|
||||
(let [args (rest (:children node))]
|
||||
(when (< (count args) 2)
|
||||
{:findings [{:message "Requires at least 2 arguments"
|
||||
:type :invalid-args
|
||||
:row (api/row node)
|
||||
:col (api/col node)}]})))
|
||||
```
|
||||
|
||||
### Macro Expansion Hook
|
||||
|
||||
```clojure
|
||||
(defn expand-defroute [{:keys [node]}]
|
||||
(let [[_ method path & handlers] (:children node)]
|
||||
{:node (api/list-node
|
||||
[(api/token-node 'def)
|
||||
(api/token-node (gensym "route"))
|
||||
(api/map-node [method path (api/vector-node handlers)])])}))
|
||||
```
|
||||
|
||||
## Why Use This Skill?
|
||||
|
||||
- **Comprehensive**: Covers all clj-kondo features including advanced hooks
|
||||
- **Practical**: Real-world examples and patterns
|
||||
- **Well-structured**: Easy navigation from basics to advanced topics
|
||||
- **Hook-focused**: Extensive coverage of custom hook development
|
||||
- **Production-ready**: Best practices for teams and CI/CD
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [Official GitHub Repository](https://github.com/clj-kondo/clj-kondo)
|
||||
- [Configuration Reference](https://github.com/clj-kondo/clj-kondo/blob/master/doc/config.md)
|
||||
- [Hooks Documentation](https://github.com/clj-kondo/clj-kondo/blob/master/doc/hooks.md)
|
||||
- [Linters Reference](https://github.com/clj-kondo/clj-kondo/blob/master/doc/linters.md)
|
||||
- [Hook Examples Repository](https://github.com/clj-kondo/clj-kondo/tree/master/examples)
|
||||
|
||||
## License
|
||||
|
||||
This skill documentation is provided as educational material. The clj-kondo tool is distributed under the EPL License (same as Clojure).
|
||||
Reference in New Issue
Block a user