Advance Linter for go-like grammar languages.
tlin is an linter designed for both Go and gno programming languages. It leverages the functionality of golangci-lint as its main linting engine, providing powerful code analysis for go-like grammar languages.
Inspired by Rust's clippy, tlin aims to provide additional code improvement suggestions beyond the default golangci-lint rules.
- Support for Go (.go) and Gno (.gno) files
- Ability to add custom lint rules
- Additional code improvement suggestion, such as detecting unnecessary code
- Auto-fixing for some lint rules
- Cyclomatic complexity analysis
- Requirements:
- Go: 1.22 or higher
- latest version of gno
- GNU Make 3.81 or higher (for building)
To install tlin CLI, follow these steps:
- Clone the repository
git clone https://github.com/gnolang/tlin
- Move to the cloned directory
cd tlin
- Install the CLI
go install ./cmd/tlin
that's it! You can now use the tlin
command in your terminal.
tlin <path>
Replace <path>
with the file or directory path you want to analyze.
To check the current directory, run:
tlin .
tlin supports a configuration file (.tlin.yaml
) to customize its behavior. You can generate a default configuration file by running:
tlin -init
This command will create a .tlin.yaml
file in the current directory with the following content:
# .tlin.yaml
name: tlin
rules:
You can customize the configuration file to enable or disable specific lint rules, set cyclomatic complexity thresholds, and more.
# .tlin.yaml
name: tlin
rules:
useless-break:
severity: WARNING
deprecated-function:
severity: OFF
Our linter allows addition of custom lint rules beyond the default golangci-lint rules. To add a new lint rule, follow these steps:
⚠️ Must update relevant tests if you have added a new rule or formatter.
-
Create an RFC (Request for Comments) document for your proposed lint rule:
- Describe the purpose and motivation for the new rule. You can find template in RFC
- Provide examples of code that the rule will flag.
- Explain any potential edge cases or considerations.
- Outline the proposed implementation approach.
-
Open a new issue in the tlin repository and attach your RFC document.
-
Wait for community feedback and maintainer approval. Be prepared to iterate on your RFC based on feedback.
-
Once the RFC is approved, proceed with the implementation:
a. Implement the
LintRule
interface for your new rule:type NewRule struct{} func (r *NewRule) Check(filename string, node *ast.File) ([]types.Issue, error) { // Implement your lint rule logic here // return a slice of Issues and any error encountered }
b. Register your new rule in the
registerAllRules
and mayberegisterDefaultRules
method of theEngine
struct ininternal/engine.go
:func (e *Engine) registerDefaultRules() { e.rules = append(e.rules, &GolangciLintRule{}, // ... &NewRule{}, // Add your new rule here ) }
func (e *Engine) registerAllRules() { e.rules = append(e.rules, &GolangciLintRule{}, // ... &NewRule{}, // Add your new rule here ) }
-
(Optional) If your rule requires special formatting, create a new formatter in the
formatter
package:a. Create a new file (e.g.,
formatter/new_rule.go
).b. Implement the
IssueFormatter
interface for your new rule:type NewRuleFormatter struct{} func (f *NewRuleFormatter) Format( issue types.Issue, snippet *internal.SourceCode, ) string { // Implement formatting logic for new rule here. }
c. Add the new formatter to the
GetFormatter
function informatter/fmt.go
.func GetFormatter(rule string) IssueFormatter { switch rule { // ... case "new_rule": // Add your new rule here return &NewRuleFormatter{} default: return &DefaultFormatter{} } }
-
Add comprehensive tests for your new rule and formatter.
-
Update the documentation to include information about the new rule.
-
Submit a pull request with your implementation, tests, and documentation updates.
By following these steps, you can propose, discuss, and add new lint rules in a structured manner, ensuring they are properly integrated into the tlin project.
tlin supports several flags to customize its behavior:
-timeout <duration>
: Set a timeout for the linter (default: 5m). Example:-timeout 1m30s
-cyclo
: Run cyclomatic complexity analysis-threshold <int>
: Set cyclomatic complexity threshold (default: 10)-ignore <rules>
: Comma-separated list of lint rules to ignore-cfg
: Run control flow graph analysis-func <name>
: Specify function name for CFG analysis-fix
: Automatically fix issues-dry-run
: Run in dry-run mode (show fixes without applying them)-confidence <float>
: Set confidence threshold for auto-fixing (0.0 to 1.0, default: 0.75)-o <path>
: Write output to a file instead of stdout-json-output
: Output results in JSON format-init
: Initialize a new tlin configuration file in the current directory-c <path>
: Specify a custom configuration file
We welcome all forms of contributions, including bug reports, feature requests, and pull requests. Please feel free to open an issue or submit a pull request.
- @GodDrinkTeJAVA - Project name (
tlin
) suggestion
This project is distributed under the MIT License. See LICENSE
for more information.