From 55fe3666963e8dc712fb1eec993b18b3f02d8bff Mon Sep 17 00:00:00 2001 From: SalvadorC Date: Wed, 31 Oct 2018 15:32:23 +0100 Subject: [PATCH 01/12] call-to-gc (new rule) (#90) --- README.md | 3 ++ RULES_DESCRIPTIONS.md | 9 ++++++ config.go | 1 + fixtures/call-to-gc.go | 17 ++++++++++ rule/call-to-gc.go | 70 +++++++++++++++++++++++++++++++++++++++++ test/call-to-gc_test.go | 12 +++++++ 6 files changed, 112 insertions(+) create mode 100644 fixtures/call-to-gc.go create mode 100644 rule/call-to-gc.go create mode 100644 test/call-to-gc_test.go diff --git a/README.md b/README.md index 23aea38..5159477 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,8 @@ Here's how `revive` is different from `golint`: - [Friendly](#friendly) - [Stylish](#stylish) - [Default](#default) + - [Plain](#plain) + - [Unix](#unix) - [Extensibility](#extensibility) - [Custom Rule](#custom-rule) - [Example](#example) @@ -278,6 +280,7 @@ List of all available rules. The rules ported from `golint` are left unchanged a | [`atomic`](./RULES_DESCRIPTIONS.md#atomic) | n/a | Check for common mistaken usages of the `sync/atomic` package | no | no | | [`empty-lines`](./RULES_DESCRIPTIONS.md#empty-lines) | n/a | Warns when there are heading or trailing newlines in a block | no | no | | [`line-lenght-limit`](./RULES_DESCRIPTIONS.md#line-lenght-limit) | int | Specifies the maximum number of characters in a line | no | no | +| [`call-to-gc`](./RULES_DESCRIPTIONS.md#call-to-gc) | n/a | Warns on explicit call to the garbage collector | no | no | ## Configurable rules diff --git a/RULES_DESCRIPTIONS.md b/RULES_DESCRIPTIONS.md index 0522c62..8622d0b 100644 --- a/RULES_DESCRIPTIONS.md +++ b/RULES_DESCRIPTIONS.md @@ -9,6 +9,7 @@ List of all available rules. - [atomic](#atomic) - [blank-imports](#blank-imports) - [bool-literal-in-expr](#bool-literal-in-expr) + - [call-to-gc](#call-to-gc) - [confusing-naming](#confusing-naming) - [confusing-results](#confusing-results) - [constant-logical-expr](#constant-logical-expr) @@ -102,6 +103,14 @@ _Description_: Using Boolean literals (`true`, `false`) in logic expressions may _Configuration_: N/A +## call-to-gc + +_Description_: Explicitly invoking the garbage collector is, except for specific uses in benchmarking, very dubious. + +The garbage collector can be configured through environment variables as described [here](https://golang.org/pkg/runtime/). + +_Configuration_: N/A + ## confusing-naming _Description_: Methods or fields of `struct` that have names different only by capitalization could be confusing. diff --git a/config.go b/config.go index 9f6188d..6f4d4d2 100644 --- a/config.go +++ b/config.go @@ -72,6 +72,7 @@ var allRules = append([]lint.Rule{ &rule.AtomicRule{}, &rule.EmptyLinesRule{}, &rule.LineLengthLimitRule{}, + &rule.CallToGCRule{}, }, defaultRules...) var allFormatters = []lint.Formatter{ diff --git a/fixtures/call-to-gc.go b/fixtures/call-to-gc.go new file mode 100644 index 0000000..ddaf1cd --- /dev/null +++ b/fixtures/call-to-gc.go @@ -0,0 +1,17 @@ +package fixtures + +import ( + "fmt" + "runtime" +) + +func GC() { +} + +func foo() { + fmt.Println("just testing") + GC() + fixtures.GC() + runtime.Goexit() + runtime.GC() // MATCH /explicit call to the garbage collector/ +} diff --git a/rule/call-to-gc.go b/rule/call-to-gc.go new file mode 100644 index 0000000..0612661 --- /dev/null +++ b/rule/call-to-gc.go @@ -0,0 +1,70 @@ +package rule + +import ( + "go/ast" + + "github.com/mgechev/revive/lint" +) + +// CallToGCRule lints calls to the garbage collector. +type CallToGCRule struct{} + +// Apply applies the rule to given file. +func (r *CallToGCRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { + var failures []lint.Failure + onFailure := func(failure lint.Failure) { + failures = append(failures, failure) + } + + var gcTriggeringFunctions = map[string]map[string]bool{ + "runtime": map[string]bool{"GC": true}, + } + + w := lintCallToGC{onFailure, gcTriggeringFunctions} + ast.Walk(w, file.AST) + + return failures +} + +// Name returns the rule name. +func (r *CallToGCRule) Name() string { + return "call-to-gc" +} + +type lintCallToGC struct { + onFailure func(lint.Failure) + gcTriggeringFunctions map[string]map[string]bool +} + +func (w lintCallToGC) Visit(node ast.Node) ast.Visitor { + ce, ok := node.(*ast.CallExpr) + if !ok { + return w // nothing to do, the node is not a call + } + + fc, ok := ce.Fun.(*ast.SelectorExpr) + if !ok { + return nil // nothing to do, the call is not of the form pkg.func(...) + } + + id, ok := fc.X.(*ast.Ident) + + if !ok { + return nil // in case X is not an id (it should be!) + } + + fn := fc.Sel.Name + pkg := id.Name + if !w.gcTriggeringFunctions[pkg][fn] { + return nil // it isn't a call to a GC triggering function + } + + w.onFailure(lint.Failure{ + Confidence: 1, + Node: node, + Category: "bad practice", + Failure: "explicit call to the garbage collector", + }) + + return w +} diff --git a/test/call-to-gc_test.go b/test/call-to-gc_test.go new file mode 100644 index 0000000..a678d83 --- /dev/null +++ b/test/call-to-gc_test.go @@ -0,0 +1,12 @@ +package test + +import ( + "testing" + + "github.com/mgechev/revive/rule" +) + +// TestCallToGC test call-to-gc rule +func TestCallToGC(t *testing.T) { + testRule(t, "call-to-gc", &rule.CallToGCRule{}) +} From 26ec4a53674dcca6c4ca2da3e3eb5d1de1fcf936 Mon Sep 17 00:00:00 2001 From: mgechev Date: Wed, 31 Oct 2018 12:55:27 -0700 Subject: [PATCH 02/12] ci: update travis scripts --- .travis.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index dfcb4e3..b455d67 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,13 +5,15 @@ script: - make build - make test - git clone https://github.com/mgechev/revive.run revive-docs && cd revive-docs -- npm i && npm run build || true +- npm i || true +- npm run build || true - git config --global user.email "mgechev@gmail.com" - git config --global user.name "mgechev" - git add . - git commit -am 'Travis CI deployment' -- git push --force --quiet "https://${GH_TOKEN}@${GH_REF}" +- git push --force --quiet "https://${GH_TOKEN}@${GH_REF}" || true env: global: - GH_REF: github.com/mgechev/revive.run.git - secure: Bp2/fJOVEor5aj3rNwA3+4/wecCmX2mVQ2pQt1AJ1n+pT6MjKYywswTDT6kzK/Cu1bPcfEGh3a7XKieAhIWVKvchoyYVV8J80F76HGyqgSBuzFXvV0c32zFn2LtxQxvmtCNynjmGAV57dHtsxGmHxkX9u8JIJ4J06E2Eq9nuuflTCf5o5gHtaE7P7hQT2WL/JRJVABHUMa0XzsMuUdRNO0OBXGMm+SqiWEcZetf2Vq3tfo2LL4ula99oTKKspg0iRKiauCZZaRxyZG/V3QiR0Rl9nhTVnb6hx6/RFrxru63Pm1FUaK1gIqEq9EUMpZRTddGW77UPp9GSB81/GaUm+e0GNFjUAL2e59t72wMxCQEOT+835hVbeCjgdksg0IDbn7sR/S+rYbiCyxTuCA/4YNlDoEajl9RMxK4culsq35LnibE1x7L4Q/5blD7HwVSMhA33HSDCC5MINwTdWwsdHYiAvFo0RCi5B0GngMzE6/pJxvYhWV3YhKWrgSmhafV1QO3Qu9dCn6P+7KsEVDbUeA8Yxnugd60kQNh2vG7bdTYKaZ6GhfU12zAM15xd2SSrKl6szSAo64CYOTznNFMBMskpm05SubTW1w+xDQy8vGjIHqb6zntiqUhFhTDd326iRYfrQuhAK53XbU1NUFFOyZa8kCTlSsPWDoSOX68oH9Q= + From 6b24cd60a8c7a5e808ef499c6bed69e1b88c0ec1 Mon Sep 17 00:00:00 2001 From: James Maidment Date: Mon, 5 Nov 2018 17:41:25 -0500 Subject: [PATCH 03/12] Fix spelling of length --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5159477..0275f5f 100644 --- a/README.md +++ b/README.md @@ -279,7 +279,7 @@ List of all available rules. The rules ported from `golint` are left unchanged a | [`waitgroup-by-value`](./RULES_DESCRIPTIONS.md#waitgroup-by-value) | n/a | Warns on functions taking sync.WaitGroup as a by-value parameter | no | no | | [`atomic`](./RULES_DESCRIPTIONS.md#atomic) | n/a | Check for common mistaken usages of the `sync/atomic` package | no | no | | [`empty-lines`](./RULES_DESCRIPTIONS.md#empty-lines) | n/a | Warns when there are heading or trailing newlines in a block | no | no | -| [`line-lenght-limit`](./RULES_DESCRIPTIONS.md#line-lenght-limit) | int | Specifies the maximum number of characters in a line | no | no | +| [`line-length-limit`](./RULES_DESCRIPTIONS.md#line-length-limit) | int | Specifies the maximum number of characters in a line | no | no | | [`call-to-gc`](./RULES_DESCRIPTIONS.md#call-to-gc) | n/a | Warns on explicit call to the garbage collector | no | no | ## Configurable rules From 9fccf1407fd6c30be387573cc42c18c13bfb3ecb Mon Sep 17 00:00:00 2001 From: xuri Date: Tue, 6 Nov 2018 10:28:24 +0800 Subject: [PATCH 04/12] Doc updated: fix typo --- RULES_DESCRIPTIONS.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/RULES_DESCRIPTIONS.md b/RULES_DESCRIPTIONS.md index 8622d0b..a57705d 100644 --- a/RULES_DESCRIPTIONS.md +++ b/RULES_DESCRIPTIONS.md @@ -33,7 +33,7 @@ List of all available rules. - [increment-decrement](#increment-decrement) - [indent-error-flow](#indent-error-flow) - [imports-blacklist](#imports-blacklist) - - [line-lenght-limit](#line-lenght-limit) + - [line-length-limit](#line-length-limit) - [max-public-structs](#max-public-structs) - [modifies-parameter](#modifies-parameter) - [modifies-value-receiver](#modifies-value-receiver) @@ -289,7 +289,7 @@ Example: arguments =["crypto/md5", "crypto/sha1"] ``` -## line-lenght-limit +## line-length-limit _Description_: Warns in the presence of code lines longer than a configured maximum. @@ -298,7 +298,7 @@ _Configuration_: (int) maximum line length in characters. Example: ```toml -[line-lenght-limit] +[line-length-limit] arguments =[80] ``` From b4b876c3472d1887975eee69061f155144195963 Mon Sep 17 00:00:00 2001 From: Minko Gechev Date: Sun, 25 Nov 2018 17:56:04 -0800 Subject: [PATCH 05/12] docs: update readme --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 0275f5f..c087921 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,14 @@ Here's how `revive` is different from `golint`: - _Everyone can extend it easily with custom rules or formatters._ - `Revive` provides more rules compared to `golint`. +## Who uses Revive + +- [`tidb`](https://github.com/pingcap/tidb) - TiDB is a distributed HTAP database compatible with the MySQL protocol +- [`ferret`](https://github.com/MontFerret/ferret) - Declarative web scraping +- [`gopass`](https://github.com/gopasspw/gopass) - The slightly more awesome standard unix password manager for teams + +*Open a PR to add your project*. +

From 1338c47ef1c161add19d821c5650b656bb1a87be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C4=B1dvan=20=C5=9E=C3=BCm=C5=9Fet?= Date: Tue, 4 Dec 2018 19:42:55 +0300 Subject: [PATCH 06/12] Update README.md (#95) --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c087921..5f19078 100644 --- a/README.md +++ b/README.md @@ -12,14 +12,14 @@ Fast, configurable, extensible, flexible, and beautiful linter for Go. Drop-in r Here's how `revive` is different from `golint`: -- Allows us to enable or disable rules using a configuration file. -- Allows us to configure the linting rules with a TOML file. +- Allows to enable or disable rules using a configuration file. +- Allows to configure the linting rules with a TOML file. - 2x faster running the same rules as golint. - Provides functionality for disabling a specific rule or the entire linter for a file or a range of lines. - `golint` allows this only for generated files. - Optional type checking. Most rules in golint do not require type checking. If you disable them in the config file, revive will run over 6x faster than golint. - Provides multiple formatters which let us customize the output. -- Allows us to customize the return code for the entire linter or based on the failure of only some rules. +- Allows to customize the return code for the entire linter or based on the failure of only some rules. - _Everyone can extend it easily with custom rules or formatters._ - `Revive` provides more rules compared to `golint`. From 50f3790f328935116bf41b757869719dbd4635d7 Mon Sep 17 00:00:00 2001 From: AragurDEV Date: Tue, 4 Dec 2018 17:45:11 +0100 Subject: [PATCH 07/12] Add gitea to "Who uses Revive" (#94) When merged: https://github.com/go-gitea/gitea/pull/5422 gitea will use revive. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5f19078..ee1ade2 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ Here's how `revive` is different from `golint`: - [`tidb`](https://github.com/pingcap/tidb) - TiDB is a distributed HTAP database compatible with the MySQL protocol - [`ferret`](https://github.com/MontFerret/ferret) - Declarative web scraping - [`gopass`](https://github.com/gopasspw/gopass) - The slightly more awesome standard unix password manager for teams +- [`gitea`](https://github.com/go-gitea/gitea) - Git with a cup of tea, painless self-hosted git service *Open a PR to add your project*. From b4cc152955fbbcd2afafd5df3d46393d621a7fdf Mon Sep 17 00:00:00 2001 From: xuri Date: Mon, 10 Dec 2018 22:05:14 +0800 Subject: [PATCH 08/12] Add excelize and aurora to "Who uses Revive" (#96) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index ee1ade2..58e2692 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,8 @@ Here's how `revive` is different from `golint`: - [`ferret`](https://github.com/MontFerret/ferret) - Declarative web scraping - [`gopass`](https://github.com/gopasspw/gopass) - The slightly more awesome standard unix password manager for teams - [`gitea`](https://github.com/go-gitea/gitea) - Git with a cup of tea, painless self-hosted git service +- [`excelize`](https://github.com/360EntSecGroup-Skylar/excelize) - Go library for reading and writing Microsoft Excelâ„¢ (XLSX) files +- [`aurora`](https://github.com/xuri/aurora) - aurora is a web-based Beanstalk queue server console written in Go *Open a PR to add your project*. From c878d3090df36b2b57f9427ec7ea29be528e19ef Mon Sep 17 00:00:00 2001 From: SalvadorC Date: Fri, 18 Jan 2019 16:33:40 +0100 Subject: [PATCH 09/12] fixes issue #98 (#99) --- fixtures/line-length-limit.go | 10 ++++++++++ lint/file.go | 9 ++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/fixtures/line-length-limit.go b/fixtures/line-length-limit.go index abc1200..7adaa31 100644 --- a/fixtures/line-length-limit.go +++ b/fixtures/line-length-limit.go @@ -5,3 +5,13 @@ import "fmt" func foo(a, b int) { fmt.Printf("single line characters out of limit") // MATCH /line is 105 characters, out of limit 100/ } + +// revive:disable-next-line:line-length-limit +// The length of this comment line is over 80 characters, this is bad for readability. + +// Warn: the testing framework does not allow to check for failures in comments + +func toto() { + // revive:disable-next-line:line-length-limit + fmt.Println("This line is way too long. In my opinion, it should be shortened.") +} diff --git a/lint/file.go b/lint/file.go index c829edb..5e0a779 100644 --- a/lint/file.go +++ b/lint/file.go @@ -127,7 +127,7 @@ type enableDisableConfig struct { } func (f *File) disabledIntervals(rules []Rule) disabledIntervalsMap { - re := regexp.MustCompile(`^\s*revive:(enable|disable)(?:-(line|next-line))?(:|\s|$)`) + re := regexp.MustCompile(`^\s*revive:(enable|disable)(?:-(line|next-line))?(:)?([^\s]*)?(\s|$)`) enabledDisabledRulesMap := make(map[string][]enableDisableConfig) @@ -199,11 +199,10 @@ func (f *File) disabledIntervals(rules []Rule) disabledIntervalsMap { if len(parts) == 0 { return } - str := re.FindString(text) - ruleNamesString := strings.Split(text, str) + ruleNames := []string{} - if len(ruleNamesString) == 2 { - tempNames := strings.Split(ruleNamesString[1], ",") + if len(parts) > 4 { + tempNames := strings.Split(parts[4], ",") for _, name := range tempNames { name = strings.Trim(name, "\n") if len(name) > 0 { From d775d613d00f600886846877db59e0223fc01608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20P=C3=A9rez?= Date: Mon, 21 Jan 2019 14:25:14 +0100 Subject: [PATCH 10/12] Adds missing `rule` in rules examples --- RULES_DESCRIPTIONS.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/RULES_DESCRIPTIONS.md b/RULES_DESCRIPTIONS.md index a57705d..db093ca 100644 --- a/RULES_DESCRIPTIONS.md +++ b/RULES_DESCRIPTIONS.md @@ -81,7 +81,7 @@ _Configuration_: (int) the maximum number of parameters allowed per function. Example: ```toml -[argument-limit] +[rule.argument-limit] arguments =[4] ``` @@ -150,7 +150,7 @@ _Configuration_: (int) the maximum function complexity Example: ```toml -[cyclomatic] +[rule.cyclomatic] arguments =[3] ``` @@ -223,7 +223,7 @@ _Configuration_: (string) the header to look for in source files. Example: ```toml -[file-header] +[rule.file-header] arguments =["This is the text that must appear at the top of source files."] ``` @@ -244,7 +244,7 @@ _Configuration_: (int) the maximum allowed return values Example: ```toml -[function-result-limit] +[rule.function-result-limit] arguments =[3] ``` @@ -298,7 +298,7 @@ _Configuration_: (int) maximum line length in characters. Example: ```toml -[line-length-limit] +[rule.line-length-limit] arguments =[80] ``` @@ -314,7 +314,7 @@ _Configuration_: (int) the maximum allowed public structs Example: ```toml -[max-public-structs] +[rule.max-public-structs] arguments =[3] ``` From 202adf07867851b042587157b433c01070074107 Mon Sep 17 00:00:00 2001 From: SalvadorC Date: Thu, 24 Jan 2019 18:14:43 +0100 Subject: [PATCH 11/12] Fix 102 (#103) Do not require additional newline for disabling multiple rules --- fixtures/disable-annotations2.go | 24 +++++++++++++++++ lint/file.go | 44 +++++++++++++++++--------------- test/disable-annotations_test.go | 4 +++ 3 files changed, 51 insertions(+), 21 deletions(-) create mode 100644 fixtures/disable-annotations2.go diff --git a/fixtures/disable-annotations2.go b/fixtures/disable-annotations2.go new file mode 100644 index 0000000..36cd65b --- /dev/null +++ b/fixtures/disable-annotations2.go @@ -0,0 +1,24 @@ +package fixtures + +func foo1() { + //revive:disable-next-line:var-naming + var invalid_name = 0 + var invalid_name2 = 1 //revive:disable-line:var-naming +} + +func foo2() { + // revive:disable-next-line:var-naming + //revive:disable + var invalid_name = 0 + var invalid_name2 = 1 +} + +func foo3() { + //revive:enable + // revive:disable-next-line:var-naming + var invalid_name = 0 + // not a valid annotation revive:disable-next-line:var-naming + var invalid_name2 = 1 // MATCH /don't use underscores in Go names; var invalid_name2 should be invalidName2/ + /* revive:disable-next-line:var-naming */ + var invalid_name3 = 0 // MATCH /don't use underscores in Go names; var invalid_name3 should be invalidName3/ +} diff --git a/lint/file.go b/lint/file.go index 5e0a779..99dd69c 100644 --- a/lint/file.go +++ b/lint/file.go @@ -127,7 +127,7 @@ type enableDisableConfig struct { } func (f *File) disabledIntervals(rules []Rule) disabledIntervalsMap { - re := regexp.MustCompile(`^\s*revive:(enable|disable)(?:-(line|next-line))?(:)?([^\s]*)?(\s|$)`) + re := regexp.MustCompile(`^//[\s]*revive:(enable|disable)(?:-(line|next-line))?(?::([^\s]+))?[\s]*$`) enabledDisabledRulesMap := make(map[string][]enableDisableConfig) @@ -194,36 +194,38 @@ func (f *File) disabledIntervals(rules []Rule) disabledIntervalsMap { } handleComment := func(filename string, c *ast.CommentGroup, line int) { - text := c.Text() - parts := re.FindStringSubmatch(text) - if len(parts) == 0 { - return - } + comments := c.List + for _, c := range comments { + match := re.FindStringSubmatch(c.Text) + if len(match) == 0 { + return + } - ruleNames := []string{} - if len(parts) > 4 { - tempNames := strings.Split(parts[4], ",") - for _, name := range tempNames { - name = strings.Trim(name, "\n") - if len(name) > 0 { - ruleNames = append(ruleNames, name) + ruleNames := []string{} + if len(match) > 2 { + tempNames := strings.Split(match[3], ",") + for _, name := range tempNames { + name = strings.Trim(name, "\n") + if len(name) > 0 { + ruleNames = append(ruleNames, name) + } } } - } - // TODO: optimize - if len(ruleNames) == 0 { - for _, rule := range rules { - ruleNames = append(ruleNames, rule.Name()) + // TODO: optimize + if len(ruleNames) == 0 { + for _, rule := range rules { + ruleNames = append(ruleNames, rule.Name()) + } } - } - handleRules(filename, parts[2], parts[1] == "enable", line, ruleNames) + handleRules(filename, match[2], match[1] == "enable", line, ruleNames) + } } comments := f.AST.Comments for _, c := range comments { - handleComment(f.Name, c, f.ToPosition(c.Pos()).Line) + handleComment(f.Name, c, f.ToPosition(c.End()).Line) } return getEnabledDisabledIntervals() diff --git a/test/disable-annotations_test.go b/test/disable-annotations_test.go index f29c433..b716734 100644 --- a/test/disable-annotations_test.go +++ b/test/disable-annotations_test.go @@ -10,3 +10,7 @@ import ( func TestDisabledAnnotations(t *testing.T) { testRule(t, "disable-annotations", &rule.ExportedRule{}, &lint.RuleConfig{}) } + +func TestModifiedAnnotations(t *testing.T) { + testRule(t, "disable-annotations2", &rule.VarNamingRule{}, &lint.RuleConfig{}) +} From 6a62ee9f02485eaee8e543da8d49d3e4047c1260 Mon Sep 17 00:00:00 2001 From: Minko Gechev Date: Fri, 1 Mar 2019 11:45:22 -0800 Subject: [PATCH 12/12] Update the list of contributors --- README.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 58e2692..65d5e28 100644 --- a/README.md +++ b/README.md @@ -428,14 +428,19 @@ Currently, type checking is enabled by default. If you want to run the linter wi ## Contributors -[mgechev](https://github.com/mgechev) |[chavacava](https://github.com/chavacava) |[xuri](https://github.com/xuri) |[gsamokovarov](https://github.com/gsamokovarov) |[morphy2k](https://github.com/morphy2k) |[z0mbie42](https://github.com/z0mbie42) | +[mgechev](https://github.com/mgechev) |[chavacava](https://github.com/chavacava) |[xuri](https://github.com/xuri) |[gsamokovarov](https://github.com/gsamokovarov) |[morphy2k](https://github.com/morphy2k) |[tamird](https://github.com/tamird) | :---: |:---: |:---: |:---: |:---: |:---: | -[mgechev](https://github.com/mgechev) |[chavacava](https://github.com/chavacava) |[xuri](https://github.com/xuri) |[gsamokovarov](https://github.com/gsamokovarov) |[morphy2k](https://github.com/morphy2k) |[z0mbie42](https://github.com/z0mbie42) | +[mgechev](https://github.com/mgechev) |[chavacava](https://github.com/chavacava) |[xuri](https://github.com/xuri) |[gsamokovarov](https://github.com/gsamokovarov) |[morphy2k](https://github.com/morphy2k) |[tamird](https://github.com/tamird) | -[tamird](https://github.com/tamird) |[paul-at-start](https://github.com/paul-at-start) |[psapezhko](https://github.com/psapezhko) |[Jarema](https://github.com/Jarema) |[vkrol](https://github.com/vkrol) |[haya14busa](https://github.com/haya14busa) | +[AragurDEV](https://github.com/AragurDEV) |[jamesmaidment](https://github.com/jamesmaidment) |[mapreal19](https://github.com/mapreal19) |[paul-at-start](https://github.com/paul-at-start) |[psapezhko](https://github.com/psapezhko) |[ridvansumset](https://github.com/ridvansumset) | :---: |:---: |:---: |:---: |:---: |:---: | -[tamird](https://github.com/tamird) |[paul-at-start](https://github.com/paul-at-start) |[psapezhko](https://github.com/psapezhko) |[Jarema](https://github.com/Jarema) |[vkrol](https://github.com/vkrol) |[haya14busa](https://github.com/haya14busa) | +[AragurDEV](https://github.com/AragurDEV) |[jamesmaidment](https://github.com/jamesmaidment) |[mapreal19](https://github.com/mapreal19) |[paul-at-start](https://github.com/paul-at-start) |[psapezhko](https://github.com/psapezhko) |[ridvansumset](https://github.com/ridvansumset) | + +[Jarema](https://github.com/Jarema) |[vkrol](https://github.com/vkrol) |[haya14busa](https://github.com/haya14busa) | +:---: |:---: |:---: | +[Jarema](https://github.com/Jarema) |[vkrol](https://github.com/vkrol) |[haya14busa](https://github.com/haya14busa) | ## License MIT +