{"id":13771155,"url":"https://github.com/Quasilyte/go-consistent","last_synced_at":"2025-05-11T03:33:06.937Z","repository":{"id":47055053,"uuid":"145749701","full_name":"quasilyte/go-consistent","owner":"quasilyte","description":"Source code analyzer that helps you to make your Go programs more consistent.","archived":false,"fork":false,"pushed_at":"2025-02-12T21:11:01.000Z","size":85,"stargazers_count":344,"open_issues_count":21,"forks_count":17,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-14T02:58:29.106Z","etag":null,"topics":["best-practices","consistency","consistency-checking","dev-tools","go","golang","linter","source-code-analysis"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/quasilyte.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-08-22T18:51:02.000Z","updated_at":"2025-03-08T21:42:44.000Z","dependencies_parsed_at":"2025-03-16T20:00:49.701Z","dependency_job_id":"8cbd1c04-8dbe-4570-83d8-69009b7530e2","html_url":"https://github.com/quasilyte/go-consistent","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quasilyte%2Fgo-consistent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quasilyte%2Fgo-consistent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quasilyte%2Fgo-consistent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quasilyte%2Fgo-consistent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/quasilyte","download_url":"https://codeload.github.com/quasilyte/go-consistent/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253514352,"owners_count":21920327,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["best-practices","consistency","consistency-checking","dev-tools","go","golang","linter","source-code-analysis"],"created_at":"2024-08-03T17:00:48.402Z","updated_at":"2025-05-11T03:33:06.632Z","avatar_url":"https://github.com/quasilyte.png","language":"Go","readme":"# go-consistent\n\n[![Build Status](https://travis-ci.org/quasilyte/go-consistent.svg?branch=master)](https://travis-ci.org/quasilyte/go-consistent)\n[![tag](https://img.shields.io/github/tag/quasilyte/go-consistent.svg)](https://github.com/quasilyte/go-consistent/releases)\n![Go Version](https://img.shields.io/badge/Go-%3E%3D%201.18-%23007d9c)\n[![GoDoc](https://pkg.go.dev/badge/github.com/quasilyte/go-consistent)](http://pkg.go.dev/github.com/quasilyte/go-consistent)\n[![Go](https://github.com/quasilyte/go-consistent/actions/workflows/go.yml/badge.svg)](https://github.com/quasilyte/go-consistent/actions/workflows/go.yml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/quasilyte/go-consistent)](https://goreportcard.com/report/github.com/quasilyte/go-consistent)\n[![License](https://img.shields.io/github/license/quasilyte/go-consistent)](./LICENSE)\n\nSource code analyzer that helps you to make your Go programs more consistent.\n\n## Quick start / Installation\n\nThis install the `go-consistent` binary:\n\n```bash\ngo install github.com/quasilyte/go-consistent\n```\n\nIf go install location is under your system `$PATH`, `go-consistent` command should be available after that.\u003cbr\u003e\nThis should print the help message:\n\n```bash\ngo-consistent --help\n```\n\nYou can pass package names and separate Go filenames to the `go-consistent` tool:\n\n```bash\ngo-consistent foo.go bar.go mypkg\n```\n\nYou can also use `std`, `./...` and other conventional targets that are normally\nunderstood by Go tools.\n\n* If you want to check consistency of a single file or package, just provide their name\n* If you want to check the whole project, you should pass **all** its packages as an arguments\n\nTo check the entire project, run `go-consistent` like this:\n\n```bash\ngo-consistent -v ./...\n```\n\n## Overview\n\nTo understand what `go-consistent` does, take a look at these 3 lines of code:\n\n```go\nlit1 := map[K]V{}\nlit2 := map[K]V{}\nm := make(map[K]V)\n```\n\n`lit1`, `lit2` and `m` are initialized to an empty, non-nil map.\nThe problem is that you have at least 2 ways to do it:\n\n1. `lit1` and `lit2` use the first option, the map literal\n2. `m` uses the second option, the `make` function\n\nNeither of these are the \"best\", but on the package or project level, you might want to prefer\nonly one of them, for consistency reasons.\n\n`go-consistent` tool detects that map literal used more frequently (2 vs 1) in the example above,\nso it suggest you to replace `m` initialization expression to use map literal instead of `make` function.\n\nThere are many similar cases where you have 2 or more options of expressing the same thing in Go,\n`go-consistent` tries to handle as much patterns as possible.\n\n### Project traits\n\n* Zero-configuration. Defaults should be good enough for most users.\n  Other configuration is performed using command line arguments.\n* Can handle projects of any size. This means that there should be no significant\n  memory consumption growth with the increased number of packages being checked.\n  There can be \"fast, but memory-hungry\" option that can work best for small-average projects,\n  but it should be always possible to check huge projects on the developer machine.\n\n### Complete list of checks performed\n\nCheckers that require types info:\n\n1. [zero val ptr alloc](#zero-val-ptr-alloc)\n1. [empty slice](#empty-slice)\n1. [empty map](#empty-map)\n1. [untyped const coerce](#untyped-const-coerce)\n1. [non-zero length test](#non-zero-length-test)\n\nCheckers that do not require types info:\n\n1. [unit import](#unit-import)\n1. [hex lit](#hex-lit)\n1. [range check](#range-check)\n1. [and-not](#and-not)\n1. [float lit](#float-lit)\n1. [label case](#label-case)\n1. [arg list parens](#arg-list-parens)\n1. [default case order](#default-case-order)\n\n#### unit import\n\n```go\n// A: no parenthesis\nimport \"fmt\"\n\n// B: with parenthesis\nimport (\n\t\"fmt\"\n)\n```\n\n#### zero val ptr alloc\n\n```go\n// A: new call\nnew(T)\nnew([]T)\n\n// B: address of literal\n\u0026T{}\n\u0026[]T{}\n```\n\n#### empty slice\n\n```go\n// A: make call\nmake([]T, 0)\n\n// B: slice literal\n[]T{}\n```\n\n#### empty map\n\n```go\n// A: make call\nmake(map[K]V)\n\n// B: map literal\nmap[K]V{}\n```\n\n#### hex lit\n\n```go\n// A: lower case a-f digits\n0xff\n\n// B: upper case A-F digits\n0xFF\n```\n\n#### range check\n\n```go\n// A: left-aligned\nx \u003e low \u0026\u0026 x \u003c high\n\n// B: center-aligned\nlow \u003c x \u0026\u0026 x \u003c high\n```\n\n#### and-not\n\n```go\n// A: using \u0026^ operator (no space)\nx \u0026^ y\n\n// B: using \u0026 and ^ (with space)\nx \u0026 ^y\n```\n\n#### float lit\n\n```go\n// A: explicit int/frac parts\n0.0\n1.0\n\n// B: implicit int/frac parts\n.0\n1.\n```\n\n#### label case\n\n```go\n// A: all upper case\nLABEL_NAME:\n\n// B: upper camel case\nLabelName:\n\n// C: lower camel case\nlabelName:\n```\n\n#### untyped const coerce\n\n```go\n// A: LHS type\nvar x int32 = 10\nconst y float32 = 1.6\n\n// B: RHS type\nvar x = int32(10)\nconst y = float32(1.6)\n```\n\n#### arg list parens\n\n```go\n// A: closing parenthesis on the same line\nmultiLineCall(\n\ta,\n\tb,\n\tc)\n\n// B: closing parenthesis on the next line\nmultiLineCall(\n\ta,\n\tb,\n\tc,\n)\n```\n\n#### non-zero length test\n\n```go\n// A: compare as \"number of elems not equal to zero\"\nlen(xs) != 0\n\n// B: compare as \"more than 0 elements\"\nlen(xs) \u003e 0\n\n// C: compare as \"at least 1 element\"\nlen(xs) \u003e= 1\n```\n\n#### default case order\n\n```go\n// A: default case is the first one\nswitch {\ndefault:\n\treturn \"?\"\ncase x \u003e 10:\n\treturn \"more than 10\"\n}\n\n// B: default case is the last one\nswitch {\ncase x \u003e 10:\n\treturn \"more than 10\"\ndefault:\n\treturn \"?\"\n}\n```\n","funding_links":[],"categories":["Linters","Programming Languages"],"sub_categories":["Style and Patterns Checking"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FQuasilyte%2Fgo-consistent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FQuasilyte%2Fgo-consistent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FQuasilyte%2Fgo-consistent/lists"}