Repository: mgechev/revive
Pull request #1089 (2024-10-29 16:16:14)

refactor: simplify tests
This PR simplifies test code.

Explanation:

- `len(revive.lintingRules)` is `0` if `revive.lintingRules` is `nil`.
- The lambda `func(file string) ([]byte, error) { return os.ReadFile(file) }` can be simply `os.ReadFile`.
- Every case has an implicit `break` statement, which is familiar to every Go developer.


Patch:
diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml
index ee880f9..850c70c 100644
--- a/.github/workflows/lint.yaml
+++ b/.github/workflows/lint.yaml
@@ -16,3 +16,5 @@ jobs:
 
     - name: Run Revive Action
       uses: morphy2k/revive-action@v2
+      with:
+        config: revive.toml
diff --git a/README.md b/README.md
index f3032c9..7b1e8fe 100644
--- a/README.md
+++ b/README.md
@@ -56,6 +56,7 @@ Here's how `revive` is different from `golint`:
 - [`DevLake`](https://github.com/apache/incubator-devlake) - Apache DevLake is an open-source dev data platform to ingest, analyze, and visualize the fragmented data from DevOps tools，which can distill insights to improve engineering productivity.
 - [`checker`](https://github.com/cinar/checker) - Checker helps validating user input through rules defined in struct tags or directly through functions.
 - [`milvus`](https://github.com/milvus-io/milvus) - A cloud-native vector database, storage for next generation AI applications.
+- [`indicator`](https://github.com/cinar/indicator) - Indicator provides various technical analysis indicators, strategies, and a backtesting framework.
 
 *Open a PR to add your project*.
 
@@ -548,6 +549,7 @@ List of all available rules. The rules ported from `golint` are left unchanged a
 | [`max-control-nesting`](./RULES_DESCRIPTIONS.md#max-control-nesting) |  int (defaults to 5)  | Sets restriction for maximum nesting of control structures. |    no    |  no   |
 | [`comments-density`](./RULES_DESCRIPTIONS.md#comments-density) |  int (defaults to 0)  | Enforces a minimum comment / code relation |    no    |  no   |
 | [`file-length-limit`](./RULES_DESCRIPTIONS.md#file-length-limit) | map (optional)| Enforces a maximum number of lines per file |    no    |  no   |
+| [`filename-format`](./RULES_DESCRIPTIONS.md#filename-format) | regular expression (optional) | Enforces the formatting of filenames |   no    |  no   |
 
 ## Configurable rules
 
@@ -787,73 +789,81 @@ REVIVE_FORCE_COLOR=1 revive -formatter friendly ./... | tee revive.log
 
 ## Contributors
 
-[<img alt="renovate[bot]" src="https://avatars.githubusercontent.com/in/2740?v=4&s=117" width="117">](https://github.com/renovate[bot]) |[<img alt="mgechev" src="https://avatars.githubusercontent.com/u/455023?v=4&s=117" width="117">](https://github.com/mgechev) |[<img alt="chavacava" src="https://avatars.githubusercontent.com/u/25788468?v=4&s=117" width="117">](https://github.com/chavacava) |[<img alt="renovate-bot" src="https://avatars.githubusercontent.com/u/25180681?v=4&s=117" width="117">](https://github.com/renovate-bot) |[<img alt="xuri" src="https://avatars.githubusercontent.com/u/2809468?v=4&s=117" width="117">](https://github.com/xuri) |[<img alt="denisvmedia" src="https://avatars.githubusercontent.com/u/5462781?v=4&s=117" width="117">](https://github.com/denisvmedia) |
+[<img alt="mgechev" src="https://avatars.githubusercontent.com/u/455023?v=4&s=117" width="117">](https://github.com/mgechev) |[<img alt="chavacava" src="https://avatars.githubusercontent.com/u/25788468?v=4&s=117" width="117">](https://github.com/chavacava) |[<img alt="denisvmedia" src="https://avatars.githubusercontent.com/u/5462781?v=4&s=117" width="117">](https://github.com/denisvmedia) |[<img alt="mfederowicz" src="https://avatars.githubusercontent.com/u/57678185?v=4&s=117" width="117">](https://github.com/mfederowicz) |[<img alt="xuri" src="https://avatars.githubusercontent.com/u/2809468?v=4&s=117" width="117">](https://github.com/xuri) |[<img alt="alexandear" src="https://avatars.githubusercontent.com/u/3228886?v=4&s=117" width="117">](https://github.com/alexandear) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[renovate[bot]](https://github.com/renovate[bot]) |[mgechev](https://github.com/mgechev) |[chavacava](https://github.com/chavacava) |[renovate-bot](https://github.com/renovate-bot) |[xuri](https://github.com/xuri) |[denisvmedia](https://github.com/denisvmedia) |
+[mgechev](https://github.com/mgechev) |[chavacava](https://github.com/chavacava) |[denisvmedia](https://github.com/denisvmedia) |[mfederowicz](https://github.com/mfederowicz) |[xuri](https://github.com/xuri) |[alexandear](https://github.com/alexandear) |
 
-[<img alt="mfederowicz" src="https://avatars.githubusercontent.com/u/57678185?v=4&s=117" width="117">](https://github.com/mfederowicz) |[<img alt="doniacld" src="https://avatars.githubusercontent.com/u/19799268?v=4&s=117" width="117">](https://github.com/doniacld) |[<img alt="Clivern" src="https://avatars.githubusercontent.com/u/1634427?v=4&s=117" width="117">](https://github.com/Clivern) |[<img alt="morphy2k" src="https://avatars.githubusercontent.com/u/4280578?v=4&s=117" width="117">](https://github.com/morphy2k) |[<img alt="bernhardreisenberger" src="https://avatars.githubusercontent.com/u/5809300?v=4&s=117" width="117">](https://github.com/bernhardreisenberger) |[<img alt="alexandear" src="https://avatars.githubusercontent.com/u/3228886?v=4&s=117" width="117">](https://github.com/alexandear) |
+[<img alt="ldez" src="https://avatars.githubusercontent.com/u/5674651?v=4&s=117" width="117">](https://github.com/ldez) |[<img alt="doniacld" src="https://avatars.githubusercontent.com/u/19799268?v=4&s=117" width="117">](https://github.com/doniacld) |[<img alt="Clivern" src="https://avatars.githubusercontent.com/u/1634427?v=4&s=117" width="117">](https://github.com/Clivern) |[<img alt="morphy2k" src="https://avatars.githubusercontent.com/u/4280578?v=4&s=117" width="117">](https://github.com/morphy2k) |[<img alt="bernhardreisenberger" src="https://avatars.githubusercontent.com/u/5809300?v=4&s=117" width="117">](https://github.com/bernhardreisenberger) |[<img alt="dshemin" src="https://avatars.githubusercontent.com/u/11780307?v=4&s=117" width="117">](https://github.com/dshemin) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[mfederowicz](https://github.com/mfederowicz) |[doniacld](https://github.com/doniacld) |[Clivern](https://github.com/Clivern) |[morphy2k](https://github.com/morphy2k) |[bernhardreisenberger](https://github.com/bernhardreisenberger) |[alexandear](https://github.com/alexandear) |
+[ldez](https://github.com/ldez) |[doniacld](https://github.com/doniacld) |[Clivern](https://github.com/Clivern) |[morphy2k](https://github.com/morphy2k) |[bernhardreisenberger](https://github.com/bernhardreisenberger) |[dshemin](https://github.com/dshemin) |
 
-[<img alt="dshemin" src="https://avatars.githubusercontent.com/u/11780307?v=4&s=117" width="117">](https://github.com/dshemin) |[<img alt="butuzov" src="https://avatars.githubusercontent.com/u/651824?v=4&s=117" width="117">](https://github.com/butuzov) |[<img alt="rawen17" src="https://avatars.githubusercontent.com/u/36483900?v=4&s=117" width="117">](https://github.com/rawen17) |[<img alt="sina-devel" src="https://avatars.githubusercontent.com/u/61763643?v=4&s=117" width="117">](https://github.com/sina-devel) |[<img alt="tymonx" src="https://avatars.githubusercontent.com/u/8367378?v=4&s=117" width="117">](https://github.com/tymonx) |[<img alt="mdelah" src="https://avatars.githubusercontent.com/u/4904544?v=4&s=117" width="117">](https://github.com/mdelah) |
+[<img alt="butuzov" src="https://avatars.githubusercontent.com/u/651824?v=4&s=117" width="117">](https://github.com/butuzov) |[<img alt="comdiv" src="https://avatars.githubusercontent.com/u/2387862?v=4&s=117" width="117">](https://github.com/comdiv) |[<img alt="heynemann" src="https://avatars.githubusercontent.com/u/60965?v=4&s=117" width="117">](https://github.com/heynemann) |[<img alt="gsamokovarov" src="https://avatars.githubusercontent.com/u/604618?v=4&s=117" width="117">](https://github.com/gsamokovarov) |[<img alt="mdelah" src="https://avatars.githubusercontent.com/u/4904544?v=4&s=117" width="117">](https://github.com/mdelah) |[<img alt="tymonx" src="https://avatars.githubusercontent.com/u/8367378?v=4&s=117" width="117">](https://github.com/tymonx) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[dshemin](https://github.com/dshemin) |[butuzov](https://github.com/butuzov) |[rawen17](https://github.com/rawen17) |[sina-devel](https://github.com/sina-devel) |[tymonx](https://github.com/tymonx) |[mdelah](https://github.com/mdelah) |
+[butuzov](https://github.com/butuzov) |[comdiv](https://github.com/comdiv) |[heynemann](https://github.com/heynemann) |[gsamokovarov](https://github.com/gsamokovarov) |[mdelah](https://github.com/mdelah) |[tymonx](https://github.com/tymonx) |
 
-[<img alt="ldez" src="https://avatars.githubusercontent.com/u/5674651?v=4&s=117" width="117">](https://github.com/ldez) |[<img alt="gsamokovarov" src="https://avatars.githubusercontent.com/u/604618?v=4&s=117" width="117">](https://github.com/gsamokovarov) |[<img alt="comdiv" src="https://avatars.githubusercontent.com/u/2387862?v=4&s=117" width="117">](https://github.com/comdiv) |[<img alt="heynemann" src="https://avatars.githubusercontent.com/u/60965?v=4&s=117" width="117">](https://github.com/heynemann) |[<img alt="cce" src="https://avatars.githubusercontent.com/u/51567?v=4&s=117" width="117">](https://github.com/cce) |[<img alt="mapreal19" src="https://avatars.githubusercontent.com/u/3055997?v=4&s=117" width="117">](https://github.com/mapreal19) |
+[<img alt="sina-devel" src="https://avatars.githubusercontent.com/u/61763643?v=4&s=117" width="117">](https://github.com/sina-devel) |[<img alt="rawen17" src="https://avatars.githubusercontent.com/u/36483900?v=4&s=117" width="117">](https://github.com/rawen17) |[<img alt="dominiquelefevre" src="https://avatars.githubusercontent.com/u/54854047?v=4&s=117" width="117">](https://github.com/dominiquelefevre) |[<img alt="git-hulk" src="https://avatars.githubusercontent.com/u/4987594?v=4&s=117" width="117">](https://github.com/git-hulk) |[<img alt="shmsr" src="https://avatars.githubusercontent.com/u/51480165?v=4&s=117" width="117">](https://github.com/shmsr) |[<img alt="ytnsym" src="https://avatars.githubusercontent.com/u/57400690?v=4&s=117" width="117">](https://github.com/ytnsym) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[ldez](https://github.com/ldez) |[gsamokovarov](https://github.com/gsamokovarov) |[comdiv](https://github.com/comdiv) |[heynemann](https://github.com/heynemann) |[cce](https://github.com/cce) |[mapreal19](https://github.com/mapreal19) |
+[sina-devel](https://github.com/sina-devel) |[rawen17](https://github.com/rawen17) |[dominiquelefevre](https://github.com/dominiquelefevre) |[git-hulk](https://github.com/git-hulk) |[shmsr](https://github.com/shmsr) |[ytnsym](https://github.com/ytnsym) |
 
-[<img alt="zimmski" src="https://avatars.githubusercontent.com/u/1847950?v=4&s=117" width="117">](https://github.com/zimmski) |[<img alt="shmsr" src="https://avatars.githubusercontent.com/u/51480165?v=4&s=117" width="117">](https://github.com/shmsr) |[<img alt="git-hulk" src="https://avatars.githubusercontent.com/u/4987594?v=4&s=117" width="117">](https://github.com/git-hulk) |[<img alt="ccoVeille" src="https://avatars.githubusercontent.com/u/3875889?v=4&s=117" width="117">](https://github.com/ccoVeille) |[<img alt="tamird" src="https://avatars.githubusercontent.com/u/1535036?v=4&s=117" width="117">](https://github.com/tamird) |[<img alt="markelog" src="https://avatars.githubusercontent.com/u/945528?v=4&s=117" width="117">](https://github.com/markelog) |
+[<img alt="zimmski" src="https://avatars.githubusercontent.com/u/1847950?v=4&s=117" width="117">](https://github.com/zimmski) |[<img alt="mapreal19" src="https://avatars.githubusercontent.com/u/3055997?v=4&s=117" width="117">](https://github.com/mapreal19) |[<img alt="cce" src="https://avatars.githubusercontent.com/u/51567?v=4&s=117" width="117">](https://github.com/cce) |[<img alt="skaji" src="https://avatars.githubusercontent.com/u/1589550?v=4&s=117" width="117">](https://github.com/skaji) |[<img alt="ccoVeille" src="https://avatars.githubusercontent.com/u/3875889?v=4&s=117" width="117">](https://github.com/ccoVeille) |[<img alt="tamird" src="https://avatars.githubusercontent.com/u/1535036?v=4&s=117" width="117">](https://github.com/tamird) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[zimmski](https://github.com/zimmski) |[shmsr](https://github.com/shmsr) |[git-hulk](https://github.com/git-hulk) |[ccoVeille](https://github.com/ccoVeille) |[tamird](https://github.com/tamird) |[markelog](https://github.com/markelog) |
+[zimmski](https://github.com/zimmski) |[mapreal19](https://github.com/mapreal19) |[cce](https://github.com/cce) |[skaji](https://github.com/skaji) |[ccoVeille](https://github.com/ccoVeille) |[tamird](https://github.com/tamird) |
 
-[<img alt="mihaitodor" src="https://avatars.githubusercontent.com/u/788216?v=4&s=117" width="117">](https://github.com/mihaitodor) |[<img alt="dvejmz" src="https://avatars.githubusercontent.com/u/9487006?v=4&s=117" width="117">](https://github.com/dvejmz) |[<img alt="damif94" src="https://avatars.githubusercontent.com/u/29461526?v=4&s=117" width="117">](https://github.com/damif94) |[<img alt="abeltay" src="https://avatars.githubusercontent.com/u/15604207?v=4&s=117" width="117">](https://github.com/abeltay) |[<img alt="zeripath" src="https://avatars.githubusercontent.com/u/1824502?v=4&s=117" width="117">](https://github.com/zeripath) |[<img alt="Groxx" src="https://avatars.githubusercontent.com/u/77197?v=4&s=117" width="117">](https://github.com/Groxx) |
+[<img alt="markelog" src="https://avatars.githubusercontent.com/u/945528?v=4&s=117" width="117">](https://github.com/markelog) |[<img alt="mihaitodor" src="https://avatars.githubusercontent.com/u/788216?v=4&s=117" width="117">](https://github.com/mihaitodor) |[<img alt="dvejmz" src="https://avatars.githubusercontent.com/u/9487006?v=4&s=117" width="117">](https://github.com/dvejmz) |[<img alt="abeltay" src="https://avatars.githubusercontent.com/u/15604207?v=4&s=117" width="117">](https://github.com/abeltay) |[<img alt="damif94" src="https://avatars.githubusercontent.com/u/29461526?v=4&s=117" width="117">](https://github.com/damif94) |[<img alt="Groxx" src="https://avatars.githubusercontent.com/u/77197?v=4&s=117" width="117">](https://github.com/Groxx) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[mihaitodor](https://github.com/mihaitodor) |[dvejmz](https://github.com/dvejmz) |[damif94](https://github.com/damif94) |[abeltay](https://github.com/abeltay) |[zeripath](https://github.com/zeripath) |[Groxx](https://github.com/Groxx) |
+[markelog](https://github.com/markelog) |[mihaitodor](https://github.com/mihaitodor) |[dvejmz](https://github.com/dvejmz) |[abeltay](https://github.com/abeltay) |[damif94](https://github.com/damif94) |[Groxx](https://github.com/Groxx) |
 
-[<img alt="StephenBrown2" src="https://avatars.githubusercontent.com/u/1148665?v=4&s=117" width="117">](https://github.com/StephenBrown2) |[<img alt="qascade" src="https://avatars.githubusercontent.com/u/54154054?v=4&s=117" width="117">](https://github.com/qascade) |[<img alt="ridvansumset" src="https://avatars.githubusercontent.com/u/26631560?v=4&s=117" width="117">](https://github.com/ridvansumset) |[<img alt="rliebz" src="https://avatars.githubusercontent.com/u/5321575?v=4&s=117" width="117">](https://github.com/rliebz) |[<img alt="rdeusser" src="https://avatars.githubusercontent.com/u/5935071?v=4&s=117" width="117">](https://github.com/rdeusser) |[<img alt="rmarku" src="https://avatars.githubusercontent.com/u/1113370?v=4&s=117" width="117">](https://github.com/rmarku) |
+[<img alt="StephenButtolph" src="https://avatars.githubusercontent.com/u/22109487?v=4&s=117" width="117">](https://github.com/StephenButtolph) |[<img alt="StephenBrown2" src="https://avatars.githubusercontent.com/u/1148665?v=4&s=117" width="117">](https://github.com/StephenBrown2) |[<img alt="lsytj0413" src="https://avatars.githubusercontent.com/u/6871552?v=4&s=117" width="117">](https://github.com/lsytj0413) |[<img alt="qascade" src="https://avatars.githubusercontent.com/u/54154054?v=4&s=117" width="117">](https://github.com/qascade) |[<img alt="ridvansumset" src="https://avatars.githubusercontent.com/u/26631560?v=4&s=117" width="117">](https://github.com/ridvansumset) |[<img alt="rliebz" src="https://avatars.githubusercontent.com/u/5321575?v=4&s=117" width="117">](https://github.com/rliebz) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[StephenBrown2](https://github.com/StephenBrown2) |[qascade](https://github.com/qascade) |[ridvansumset](https://github.com/ridvansumset) |[rliebz](https://github.com/rliebz) |[rdeusser](https://github.com/rdeusser) |[rmarku](https://github.com/rmarku) |
+[StephenButtolph](https://github.com/StephenButtolph) |[StephenBrown2](https://github.com/StephenBrown2) |[lsytj0413](https://github.com/lsytj0413) |[qascade](https://github.com/qascade) |[ridvansumset](https://github.com/ridvansumset) |[rliebz](https://github.com/rliebz) |
 
-[<img alt="rnikoopour" src="https://avatars.githubusercontent.com/u/7692789?v=4&s=117" width="117">](https://github.com/rnikoopour) |[<img alt="rafamadriz" src="https://avatars.githubusercontent.com/u/67771985?v=4&s=117" width="117">](https://github.com/rafamadriz) |[<img alt="paco0x" src="https://avatars.githubusercontent.com/u/6123425?v=4&s=117" width="117">](https://github.com/paco0x) |[<img alt="weastur" src="https://avatars.githubusercontent.com/u/10865586?v=4&s=117" width="117">](https://github.com/weastur) |[<img alt="pa-m" src="https://avatars.githubusercontent.com/u/5503106?v=4&s=117" width="117">](https://github.com/pa-m) |[<img alt="cinar" src="https://avatars.githubusercontent.com/u/1754092?v=4&s=117" width="117">](https://github.com/cinar) |
+[<img alt="rdeusser" src="https://avatars.githubusercontent.com/u/5935071?v=4&s=117" width="117">](https://github.com/rdeusser) |[<img alt="rmarku" src="https://avatars.githubusercontent.com/u/1113370?v=4&s=117" width="117">](https://github.com/rmarku) |[<img alt="rnikoopour" src="https://avatars.githubusercontent.com/u/7692789?v=4&s=117" width="117">](https://github.com/rnikoopour) |[<img alt="rafamadriz" src="https://avatars.githubusercontent.com/u/67771985?v=4&s=117" width="117">](https://github.com/rafamadriz) |[<img alt="paco0x" src="https://avatars.githubusercontent.com/u/6123425?v=4&s=117" width="117">](https://github.com/paco0x) |[<img alt="pa-m" src="https://avatars.githubusercontent.com/u/5503106?v=4&s=117" width="117">](https://github.com/pa-m) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[rnikoopour](https://github.com/rnikoopour) |[rafamadriz](https://github.com/rafamadriz) |[paco0x](https://github.com/paco0x) |[weastur](https://github.com/weastur) |[pa-m](https://github.com/pa-m) |[cinar](https://github.com/cinar) |
+[rdeusser](https://github.com/rdeusser) |[rmarku](https://github.com/rmarku) |[rnikoopour](https://github.com/rnikoopour) |[rafamadriz](https://github.com/rafamadriz) |[paco0x](https://github.com/paco0x) |[pa-m](https://github.com/pa-m) |
 
-[<img alt="natefinch" src="https://avatars.githubusercontent.com/u/3185864?v=4&s=117" width="117">](https://github.com/natefinch) |[<img alt="flesser" src="https://avatars.githubusercontent.com/u/510681?v=4&s=117" width="117">](https://github.com/flesser) |[<img alt="y-yagi" src="https://avatars.githubusercontent.com/u/987638?v=4&s=117" width="117">](https://github.com/y-yagi) |[<img alt="techknowlogick" src="https://avatars.githubusercontent.com/u/164197?v=4&s=117" width="117">](https://github.com/techknowlogick) |[<img alt="okhowang" src="https://avatars.githubusercontent.com/u/3352585?v=4&s=117" width="117">](https://github.com/okhowang) |[<img alt="meanguy" src="https://avatars.githubusercontent.com/u/78570571?v=4&s=117" width="117">](https://github.com/meanguy) |
+[<img alt="cinar" src="https://avatars.githubusercontent.com/u/1754092?v=4&s=117" width="117">](https://github.com/cinar) |[<img alt="natefinch" src="https://avatars.githubusercontent.com/u/3185864?v=4&s=117" width="117">](https://github.com/natefinch) |[<img alt="nunnatsa" src="https://avatars.githubusercontent.com/u/60659093?v=4&s=117" width="117">](https://github.com/nunnatsa) |[<img alt="michalhisim" src="https://avatars.githubusercontent.com/u/764249?v=4&s=117" width="117">](https://github.com/michalhisim) |[<img alt="zeripath" src="https://avatars.githubusercontent.com/u/1824502?v=4&s=117" width="117">](https://github.com/zeripath) |[<img alt="y-yagi" src="https://avatars.githubusercontent.com/u/987638?v=4&s=117" width="117">](https://github.com/y-yagi) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[natefinch](https://github.com/natefinch) |[flesser](https://github.com/flesser) |[y-yagi](https://github.com/y-yagi) |[techknowlogick](https://github.com/techknowlogick) |[okhowang](https://github.com/okhowang) |[meanguy](https://github.com/meanguy) |
+[cinar](https://github.com/cinar) |[natefinch](https://github.com/natefinch) |[nunnatsa](https://github.com/nunnatsa) |[michalhisim](https://github.com/michalhisim) |[zeripath](https://github.com/zeripath) |[y-yagi](https://github.com/y-yagi) |
 
-[<img alt="likyh" src="https://avatars.githubusercontent.com/u/3294100?v=4&s=117" width="117">](https://github.com/likyh) |[<img alt="kerneltravel" src="https://avatars.githubusercontent.com/u/437879?v=4&s=117" width="117">](https://github.com/kerneltravel) |[<img alt="jmckenzieark" src="https://avatars.githubusercontent.com/u/70923399?v=4&s=117" width="117">](https://github.com/jmckenzieark) |[<img alt="haya14busa" src="https://avatars.githubusercontent.com/u/3797062?v=4&s=117" width="117">](https://github.com/haya14busa) |[<img alt="fregin" src="https://avatars.githubusercontent.com/u/23256240?v=4&s=117" width="117">](https://github.com/fregin) |[<img alt="ydah" src="https://avatars.githubusercontent.com/u/13041216?v=4&s=117" width="117">](https://github.com/ydah) |
+[<img alt="techknowlogick" src="https://avatars.githubusercontent.com/u/164197?v=4&s=117" width="117">](https://github.com/techknowlogick) |[<img alt="okhowang" src="https://avatars.githubusercontent.com/u/3352585?v=4&s=117" width="117">](https://github.com/okhowang) |[<img alt="meanguy" src="https://avatars.githubusercontent.com/u/78570571?v=4&s=117" width="117">](https://github.com/meanguy) |[<img alt="likyh" src="https://avatars.githubusercontent.com/u/3294100?v=4&s=117" width="117">](https://github.com/likyh) |[<img alt="kerneltravel" src="https://avatars.githubusercontent.com/u/437879?v=4&s=117" width="117">](https://github.com/kerneltravel) |[<img alt="jmckenzieark" src="https://avatars.githubusercontent.com/u/70923399?v=4&s=117" width="117">](https://github.com/jmckenzieark) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[likyh](https://github.com/likyh) |[kerneltravel](https://github.com/kerneltravel) |[jmckenzieark](https://github.com/jmckenzieark) |[haya14busa](https://github.com/haya14busa) |[fregin](https://github.com/fregin) |[ydah](https://github.com/ydah) |
+[techknowlogick](https://github.com/techknowlogick) |[okhowang](https://github.com/okhowang) |[meanguy](https://github.com/meanguy) |[likyh](https://github.com/likyh) |[kerneltravel](https://github.com/kerneltravel) |[jmckenzieark](https://github.com/jmckenzieark) |
 
-[<img alt="WillAbides" src="https://avatars.githubusercontent.com/u/233500?v=4&s=117" width="117">](https://github.com/WillAbides) |[<img alt="heyvito" src="https://avatars.githubusercontent.com/u/77198?v=4&s=117" width="117">](https://github.com/heyvito) |[<img alt="scop" src="https://avatars.githubusercontent.com/u/109152?v=4&s=117" width="117">](https://github.com/scop) |[<img alt="vkrol" src="https://avatars.githubusercontent.com/u/153412?v=4&s=117" width="117">](https://github.com/vkrol) |[<img alt="Jarema" src="https://avatars.githubusercontent.com/u/7369771?v=4&s=117" width="117">](https://github.com/Jarema) |[<img alt="tartale" src="https://avatars.githubusercontent.com/u/9323250?v=4&s=117" width="117">](https://github.com/tartale) |
+[<img alt="haya14busa" src="https://avatars.githubusercontent.com/u/3797062?v=4&s=117" width="117">](https://github.com/haya14busa) |[<img alt="fregin" src="https://avatars.githubusercontent.com/u/23256240?v=4&s=117" width="117">](https://github.com/fregin) |[<img alt="ydah" src="https://avatars.githubusercontent.com/u/13041216?v=4&s=117" width="117">](https://github.com/ydah) |[<img alt="WillAbides" src="https://avatars.githubusercontent.com/u/233500?v=4&s=117" width="117">](https://github.com/WillAbides) |[<img alt="heyvito" src="https://avatars.githubusercontent.com/u/77198?v=4&s=117" width="117">](https://github.com/heyvito) |[<img alt="VincentBaron" src="https://avatars.githubusercontent.com/u/58427099?v=4&s=117" width="117">](https://github.com/VincentBaron) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[WillAbides](https://github.com/WillAbides) |[heyvito](https://github.com/heyvito) |[scop](https://github.com/scop) |[vkrol](https://github.com/vkrol) |[Jarema](https://github.com/Jarema) |[tartale](https://github.com/tartale) |
+[haya14busa](https://github.com/haya14busa) |[fregin](https://github.com/fregin) |[ydah](https://github.com/ydah) |[WillAbides](https://github.com/WillAbides) |[heyvito](https://github.com/heyvito) |[VincentBaron](https://github.com/VincentBaron) |
 
-[<img alt="tmzane" src="https://avatars.githubusercontent.com/u/73077675?v=4&s=117" width="117">](https://github.com/tmzane) |[<img alt="felipedavid" src="https://avatars.githubusercontent.com/u/75049173?v=4&s=117" width="117">](https://github.com/felipedavid) |[<img alt="euank" src="https://avatars.githubusercontent.com/u/2147649?v=4&s=117" width="117">](https://github.com/euank) |[<img alt="Juneezee" src="https://avatars.githubusercontent.com/u/20135478?v=4&s=117" width="117">](https://github.com/Juneezee) |[<img alt="echoix" src="https://avatars.githubusercontent.com/u/27212526?v=4&s=117" width="117">](https://github.com/echoix) |[<img alt="EXHades" src="https://avatars.githubusercontent.com/u/22260242?v=4&s=117" width="117">](https://github.com/EXHades) |
+[<img alt="scop" src="https://avatars.githubusercontent.com/u/109152?v=4&s=117" width="117">](https://github.com/scop) |[<img alt="vkrol" src="https://avatars.githubusercontent.com/u/153412?v=4&s=117" width="117">](https://github.com/vkrol) |[<img alt="KirillSluchaev" src="https://avatars.githubusercontent.com/u/58340009?v=4&s=117" width="117">](https://github.com/KirillSluchaev) |[<img alt="Jarema" src="https://avatars.githubusercontent.com/u/7369771?v=4&s=117" width="117">](https://github.com/Jarema) |[<img alt="tartale" src="https://avatars.githubusercontent.com/u/9323250?v=4&s=117" width="117">](https://github.com/tartale) |[<img alt="tmzane" src="https://avatars.githubusercontent.com/u/73077675?v=4&s=117" width="117">](https://github.com/tmzane) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[tmzane](https://github.com/tmzane) |[felipedavid](https://github.com/felipedavid) |[euank](https://github.com/euank) |[Juneezee](https://github.com/Juneezee) |[echoix](https://github.com/echoix) |[EXHades](https://github.com/EXHades) |
+[scop](https://github.com/scop) |[vkrol](https://github.com/vkrol) |[KirillSluchaev](https://github.com/KirillSluchaev) |[Jarema](https://github.com/Jarema) |[tartale](https://github.com/tartale) |[tmzane](https://github.com/tmzane) |
+
+[<img alt="felipedavid" src="https://avatars.githubusercontent.com/u/75049173?v=4&s=117" width="117">](https://github.com/felipedavid) |[<img alt="euank" src="https://avatars.githubusercontent.com/u/2147649?v=4&s=117" width="117">](https://github.com/euank) |[<img alt="Entuazism" src="https://avatars.githubusercontent.com/u/56657856?v=4&s=117" width="117">](https://github.com/Entuazism) |[<img alt="Juneezee" src="https://avatars.githubusercontent.com/u/20135478?v=4&s=117" width="117">](https://github.com/Juneezee) |[<img alt="echoix" src="https://avatars.githubusercontent.com/u/27212526?v=4&s=117" width="117">](https://github.com/echoix) |[<img alt="EXHades" src="https://avatars.githubusercontent.com/u/22260242?v=4&s=117" width="117">](https://github.com/EXHades) |
+:---: |:---: |:---: |:---: |:---: |:---: |
+[felipedavid](https://github.com/felipedavid) |[euank](https://github.com/euank) |[Entuazism](https://github.com/Entuazism) |[Juneezee](https://github.com/Juneezee) |[echoix](https://github.com/echoix) |[EXHades](https://github.com/EXHades) |
 
 [<img alt="petethepig" src="https://avatars.githubusercontent.com/u/662636?v=4&s=117" width="117">](https://github.com/petethepig) |[<img alt="Dirk007" src="https://avatars.githubusercontent.com/u/17194484?v=4&s=117" width="117">](https://github.com/Dirk007) |[<img alt="yangdiangzb" src="https://avatars.githubusercontent.com/u/16643665?v=4&s=117" width="117">](https://github.com/yangdiangzb) |[<img alt="derekperkins" src="https://avatars.githubusercontent.com/u/3588778?v=4&s=117" width="117">](https://github.com/derekperkins) |[<img alt="bboreham" src="https://avatars.githubusercontent.com/u/8125524?v=4&s=117" width="117">](https://github.com/bboreham) |[<img alt="attiss" src="https://avatars.githubusercontent.com/u/23562566?v=4&s=117" width="117">](https://github.com/attiss) |
 :---: |:---: |:---: |:---: |:---: |:---: |
 [petethepig](https://github.com/petethepig) |[Dirk007](https://github.com/Dirk007) |[yangdiangzb](https://github.com/yangdiangzb) |[derekperkins](https://github.com/derekperkins) |[bboreham](https://github.com/bboreham) |[attiss](https://github.com/attiss) |
 
-[<img alt="Aragur" src="https://avatars.githubusercontent.com/u/11004008?v=4&s=117" width="117">](https://github.com/Aragur) |[<img alt="kulti" src="https://avatars.githubusercontent.com/u/1286683?v=4&s=117" width="117">](https://github.com/kulti) |[<img alt="Abirdcfly" src="https://avatars.githubusercontent.com/u/5100555?v=4&s=117" width="117">](https://github.com/Abirdcfly) |[<img alt="abhinav" src="https://avatars.githubusercontent.com/u/41730?v=4&s=117" width="117">](https://github.com/abhinav) |[<img alt="r-ricci" src="https://avatars.githubusercontent.com/u/52817765?v=4&s=117" width="117">](https://github.com/r-ricci) |[<img alt="nunnatsa" src="https://avatars.githubusercontent.com/u/60659093?v=4&s=117" width="117">](https://github.com/nunnatsa) |
+[<img alt="hatamiarash7" src="https://avatars.githubusercontent.com/u/16325641?v=4&s=117" width="117">](https://github.com/hatamiarash7) |[<img alt="Aragur" src="https://avatars.githubusercontent.com/u/11004008?v=4&s=117" width="117">](https://github.com/Aragur) |[<img alt="amincheloh" src="https://avatars.githubusercontent.com/u/1217397?v=4&s=117" width="117">](https://github.com/amincheloh) |[<img alt="kulti" src="https://avatars.githubusercontent.com/u/1286683?v=4&s=117" width="117">](https://github.com/kulti) |[<img alt="Abirdcfly" src="https://avatars.githubusercontent.com/u/5100555?v=4&s=117" width="117">](https://github.com/Abirdcfly) |[<img alt="abhinav" src="https://avatars.githubusercontent.com/u/41730?v=4&s=117" width="117">](https://github.com/abhinav) |
+:---: |:---: |:---: |:---: |:---: |:---: |
+[hatamiarash7](https://github.com/hatamiarash7) |[Aragur](https://github.com/Aragur) |[amincheloh](https://github.com/amincheloh) |[kulti](https://github.com/kulti) |[Abirdcfly](https://github.com/Abirdcfly) |[abhinav](https://github.com/abhinav) |
+
+[<img alt="r-ricci" src="https://avatars.githubusercontent.com/u/52817765?v=4&s=117" width="117">](https://github.com/r-ricci) |[<img alt="mmcloughlin" src="https://avatars.githubusercontent.com/u/7133685?v=4&s=117" width="117">](https://github.com/mmcloughlin) |[<img alt="mathieu-aubin" src="https://avatars.githubusercontent.com/u/15820228?v=4&s=117" width="117">](https://github.com/mathieu-aubin) |[<img alt="martinsirbe" src="https://avatars.githubusercontent.com/u/13367583?v=4&s=117" width="117">](https://github.com/martinsirbe) |[<img alt="avorima" src="https://avatars.githubusercontent.com/u/15158349?v=4&s=117" width="117">](https://github.com/avorima) |[<img alt="moukoublen" src="https://avatars.githubusercontent.com/u/1380039?v=4&s=117" width="117">](https://github.com/moukoublen) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[Aragur](https://github.com/Aragur) |[kulti](https://github.com/kulti) |[Abirdcfly](https://github.com/Abirdcfly) |[abhinav](https://github.com/abhinav) |[r-ricci](https://github.com/r-ricci) |[nunnatsa](https://github.com/nunnatsa) |
+[r-ricci](https://github.com/r-ricci) |[mmcloughlin](https://github.com/mmcloughlin) |[mathieu-aubin](https://github.com/mathieu-aubin) |[martinsirbe](https://github.com/martinsirbe) |[avorima](https://github.com/avorima) |[moukoublen](https://github.com/moukoublen) |
 
-[<img alt="michalhisim" src="https://avatars.githubusercontent.com/u/764249?v=4&s=117" width="117">](https://github.com/michalhisim) |[<img alt="mathieu-aubin" src="https://avatars.githubusercontent.com/u/15820228?v=4&s=117" width="117">](https://github.com/mathieu-aubin) |[<img alt="martinsirbe" src="https://avatars.githubusercontent.com/u/13367583?v=4&s=117" width="117">](https://github.com/martinsirbe) |[<img alt="avorima" src="https://avatars.githubusercontent.com/u/15158349?v=4&s=117" width="117">](https://github.com/avorima) |[<img alt="very-amused" src="https://avatars.githubusercontent.com/u/44382255?v=4&s=117" width="117">](https://github.com/very-amused) |[<img alt="johnrichardrinehart" src="https://avatars.githubusercontent.com/u/6321578?v=4&s=117" width="117">](https://github.com/johnrichardrinehart) |
+[<img alt="very-amused" src="https://avatars.githubusercontent.com/u/44382255?v=4&s=117" width="117">](https://github.com/very-amused) |[<img alt="johnrichardrinehart" src="https://avatars.githubusercontent.com/u/6321578?v=4&s=117" width="117">](https://github.com/johnrichardrinehart) |[<img alt="walles" src="https://avatars.githubusercontent.com/u/158201?v=4&s=117" width="117">](https://github.com/walles) |[<img alt="jefersonf" src="https://avatars.githubusercontent.com/u/3049540?v=4&s=117" width="117">](https://github.com/jefersonf) |[<img alt="jamesmaidment" src="https://avatars.githubusercontent.com/u/2050324?v=4&s=117" width="117">](https://github.com/jamesmaidment) |[<img alt="jalaziz" src="https://avatars.githubusercontent.com/u/247849?v=4&s=117" width="117">](https://github.com/jalaziz) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[michalhisim](https://github.com/michalhisim) |[mathieu-aubin](https://github.com/mathieu-aubin) |[martinsirbe](https://github.com/martinsirbe) |[avorima](https://github.com/avorima) |[very-amused](https://github.com/very-amused) |[johnrichardrinehart](https://github.com/johnrichardrinehart) |
+[very-amused](https://github.com/very-amused) |[johnrichardrinehart](https://github.com/johnrichardrinehart) |[walles](https://github.com/walles) |[jefersonf](https://github.com/jefersonf) |[jamesmaidment](https://github.com/jamesmaidment) |[jalaziz](https://github.com/jalaziz) |
 
-[<img alt="walles" src="https://avatars.githubusercontent.com/u/158201?v=4&s=117" width="117">](https://github.com/walles) |[<img alt="jefersonf" src="https://avatars.githubusercontent.com/u/3049540?v=4&s=117" width="117">](https://github.com/jefersonf) |[<img alt="jan-xyz" src="https://avatars.githubusercontent.com/u/5249233?v=4&s=117" width="117">](https://github.com/jan-xyz) |[<img alt="jamesmaidment" src="https://avatars.githubusercontent.com/u/2050324?v=4&s=117" width="117">](https://github.com/jamesmaidment) |[<img alt="grongor" src="https://avatars.githubusercontent.com/u/972493?v=4&s=117" width="117">](https://github.com/grongor) |[<img alt="tie" src="https://avatars.githubusercontent.com/u/14792994?v=4&s=117" width="117">](https://github.com/tie) |
+[<img alt="grongor" src="https://avatars.githubusercontent.com/u/972493?v=4&s=117" width="117">](https://github.com/grongor) |[<img alt="tie" src="https://avatars.githubusercontent.com/u/14792994?v=4&s=117" width="117">](https://github.com/tie) |[<img alt="quasilyte" src="https://avatars.githubusercontent.com/u/6286655?v=4&s=117" width="117">](https://github.com/quasilyte) |[<img alt="davidhsingyuchen" src="https://avatars.githubusercontent.com/u/17587061?v=4&s=117" width="117">](https://github.com/davidhsingyuchen) |[<img alt="gfariasalves-ionos" src="https://avatars.githubusercontent.com/u/112630064?v=4&s=117" width="117">](https://github.com/gfariasalves-ionos) |[<img alt="gburanov" src="https://avatars.githubusercontent.com/u/2969603?v=4&s=117" width="117">](https://github.com/gburanov) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[walles](https://github.com/walles) |[jefersonf](https://github.com/jefersonf) |[jan-xyz](https://github.com/jan-xyz) |[jamesmaidment](https://github.com/jamesmaidment) |[grongor](https://github.com/grongor) |[tie](https://github.com/tie) |
+[grongor](https://github.com/grongor) |[tie](https://github.com/tie) |[quasilyte](https://github.com/quasilyte) |[davidhsingyuchen](https://github.com/davidhsingyuchen) |[gfariasalves-ionos](https://github.com/gfariasalves-ionos) |[gburanov](https://github.com/gburanov) |
 
-[<img alt="quasilyte" src="https://avatars.githubusercontent.com/u/6286655?v=4&s=117" width="117">](https://github.com/quasilyte) |[<img alt="davidhsingyuchen" src="https://avatars.githubusercontent.com/u/17587061?v=4&s=117" width="117">](https://github.com/davidhsingyuchen) |[<img alt="gburanov" src="https://avatars.githubusercontent.com/u/2969603?v=4&s=117" width="117">](https://github.com/gburanov) |[<img alt="ginglis13" src="https://avatars.githubusercontent.com/u/43075615?v=4&s=117" width="117">](https://github.com/ginglis13) |
-:---: |:---: |:---: |:---: |
-[quasilyte](https://github.com/quasilyte) |[davidhsingyuchen](https://github.com/davidhsingyuchen) |[gburanov](https://github.com/gburanov) |[ginglis13](https://github.com/ginglis13) |
+[<img alt="ginglis13" src="https://avatars.githubusercontent.com/u/43075615?v=4&s=117" width="117">](https://github.com/ginglis13) |[<img alt="flesser" src="https://avatars.githubusercontent.com/u/510681?v=4&s=117" width="117">](https://github.com/flesser) |
+:---: |:---: |
+[ginglis13](https://github.com/ginglis13) |[flesser](https://github.com/flesser) |
 
 ## License
 
diff --git a/RULES_DESCRIPTIONS.md b/RULES_DESCRIPTIONS.md
index 3ef2acd..fcd4e68 100644
--- a/RULES_DESCRIPTIONS.md
+++ b/RULES_DESCRIPTIONS.md
@@ -39,6 +39,7 @@ List of all available rules.
   - [exported](#exported)
   - [file-header](#file-header)
   - [file-length-limit](#file-length-limit)
+  - [filename-format](#filename-format)
   - [flag-parameter](#flag-parameter)
   - [function-length](#function-length)
   - [function-result-limit](#function-result-limit)
@@ -519,6 +520,18 @@ Example:
   arguments = [{max=100,skipComments=true,skipBlankLines=true}]
 ```
 
+## filename-format
+_Description_: enforces conventions on source file names. By default, the rule enforces filenames of the form `^[_A-Za-z0-9][_A-Za-z0-9-]*.go$`: Optionally, the rule can be configured to enforce other forms.
+
+_Configuration_: (string) regular expression for source filenames.
+
+Example:
+
+```toml
+[rule.filename-format]
+    arguments=["^[_a-z][_a-z0-9]*.go$"]
+```
+
 ## flag-parameter
 
 _Description_: If a function controls the flow of another by passing it information on what to do, both functions are said to be [control-coupled](https://en.wikipedia.org/wiki/Coupling_(computer_programming)#Procedural_programming).
diff --git a/config/config.go b/config/config.go
index 5da64b6..16559f5 100644
--- a/config/config.go
+++ b/config/config.go
@@ -97,6 +97,7 @@ var allRules = append([]lint.Rule{
 	&rule.MaxControlNestingRule{},
 	&rule.CommentsDensityRule{},
 	&rule.FileLengthLimitRule{},
+	&rule.FilenameFormatRule{},
 }, defaultRules...)
 
 var allFormatters = []lint.Formatter{
diff --git a/lint/package.go b/lint/package.go
index 441e0f4..2ab035f 100644
--- a/lint/package.go
+++ b/lint/package.go
@@ -166,17 +166,17 @@ func (p *Package) scanSortable() {
 
 	// bitfield for which methods exist on each type.
 	const (
-		Len = 1 << iota
-		Less
-		Swap
+		bfLen = 1 << iota
+		bfLess
+		bfSwap
 	)
-	nmap := map[string]int{"Len": Len, "Less": Less, "Swap": Swap}
+	nmap := map[string]int{"Len": bfLen, "Less": bfLess, "Swap": bfSwap}
 	has := make(map[string]int)
 	for _, f := range p.files {
 		ast.Walk(&walker{nmap, has}, f.AST)
 	}
 	for typ, ms := range has {
-		if ms == Len|Less|Swap {
+		if ms == bfLen|bfLess|bfSwap {
 			p.sortable[typ] = true
 		}
 	}
diff --git a/revive.toml b/revive.toml
new file mode 100644
index 0000000..3d47522
--- /dev/null
+++ b/revive.toml
@@ -0,0 +1,38 @@
+# This configuration for the revive linter used for linting the revive's codebase itself.
+# See .github/workflows/lint.yaml.
+
+ignoreGeneratedHeader = false
+severity = "warning"
+confidence = 0.8
+errorCode = 1
+warningCode = 1
+
+[rule.bare-return]
+[rule.blank-imports]
+[rule.context-as-argument]
+[rule.context-keys-type]
+[rule.dot-imports]
+[rule.empty-block]
+[rule.empty-lines]
+[rule.error-naming]
+[rule.error-return]
+[rule.error-strings]
+[rule.errorf]
+[rule.exported]
+[rule.increment-decrement]
+[rule.indent-error-flow]
+[rule.line-length-limit]
+    arguments = [200]
+[rule.package-comments]
+[rule.range]
+[rule.receiver-naming]
+[rule.redefines-builtin-id]
+[rule.superfluous-else]
+[rule.time-naming]
+[rule.unexported-naming]
+[rule.unexported-return]
+[rule.unreachable-code]
+[rule.unused-parameter]
+[rule.useless-break]
+[rule.var-declaration]
+[rule.var-naming]
diff --git a/rule/add-constant.go b/rule/add-constant.go
index f7a2447..233f1d8 100644
--- a/rule/add-constant.go
+++ b/rule/add-constant.go
@@ -160,14 +160,14 @@ func (w *lintAddConstantRule) isIgnoredFunc(fName string) bool {
 }
 
 func (w *lintAddConstantRule) checkStrLit(n *ast.BasicLit) {
-	const IgnoreMarker = -1
+	const ignoreMarker = -1
 
 	if w.allowList[kindSTRING][n.Value] {
 		return
 	}
 
 	count := w.strLits[n.Value]
-	mustCheck := count > IgnoreMarker
+	mustCheck := count > ignoreMarker
 	if mustCheck {
 		w.strLits[n.Value] = count + 1
 		if w.strLits[n.Value] > w.strLitLimit {
diff --git a/rule/comments-density.go b/rule/comments-density.go
index 5956fea..c5298ea 100644
--- a/rule/comments-density.go
+++ b/rule/comments-density.go
@@ -53,7 +53,8 @@ func (r *CommentsDensityRule) Apply(file *lint.File, arguments lint.Arguments) [
 			{
 				Node:       file.AST,
 				Confidence: 1,
-				Failure:    fmt.Sprintf("the file has a comment density of %2.f%% (%d comment lines for %d code lines) but expected a minimum of %d%%", density, commentsLines, statementsCount, r.minimumCommentsDensity),
+				Failure: fmt.Sprintf("the file has a comment density of %2.f%% (%d comment lines for %d code lines) but expected a minimum of %d%%",
+					density, commentsLines, statementsCount, r.minimumCommentsDensity),
 			},
 		}
 	}
diff --git a/rule/early-return.go b/rule/early-return.go
index 9c04a1d..62d491f 100644
--- a/rule/early-return.go
+++ b/rule/early-return.go
@@ -21,27 +21,27 @@ func (*EarlyReturnRule) Name() string {
 	return "early-return"
 }
 
-// CheckIfElse evaluates the rule against an ifelse.Chain.
-func (*EarlyReturnRule) CheckIfElse(chain ifelse.Chain, args ifelse.Args) (failMsg string) {
+// CheckIfElse evaluates the rule against an ifelse.Chain and returns a failure message if applicable.
+func (*EarlyReturnRule) CheckIfElse(chain ifelse.Chain, args ifelse.Args) string {
 	if !chain.Else.Deviates() {
 		// this rule only applies if the else-block deviates control flow
-		return
+		return ""
 	}
 
 	if chain.HasPriorNonDeviating && !chain.If.IsEmpty() {
 		// if we de-indent this block then a previous branch
 		// might flow into it, affecting program behaviour
-		return
+		return ""
 	}
 
 	if chain.If.Deviates() {
 		// avoid overlapping with superfluous-else
-		return
+		return ""
 	}
 
 	if args.PreserveScope && !chain.AtBlockEnd && (chain.HasInitializer || chain.If.HasDecls) {
 		// avoid increasing variable scope
-		return
+		return ""
 	}
 
 	if chain.If.IsEmpty() {
diff --git a/rule/filename-format.go b/rule/filename-format.go
new file mode 100644
index 0000000..49fdf9c
--- /dev/null
+++ b/rule/filename-format.go
@@ -0,0 +1,87 @@
+package rule
+
+import (
+	"fmt"
+	"path/filepath"
+	"regexp"
+	"sync"
+	"unicode"
+
+	"github.com/mgechev/revive/lint"
+)
+
+// FilenameFormatRule lints source filenames according to a set of regular expressions given as arguments
+type FilenameFormatRule struct {
+	format *regexp.Regexp
+	sync.Mutex
+}
+
+// Apply applies the rule to the given file.
+func (r *FilenameFormatRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
+	r.configure(arguments)
+
+	filename := filepath.Base(file.Name)
+	if r.format.MatchString(filename) {
+		return nil
+	}
+
+	failureMsg := fmt.Sprintf("Filename %s is not of the format %s.%s", filename, r.format.String(), r.getMsgForNonASCIIChars(filename))
+	return []lint.Failure{{
+		Confidence: 1,
+		Failure:    failureMsg,
+		RuleName:   r.Name(),
+		Node:       file.AST.Name,
+	}}
+}
+
+func (r *FilenameFormatRule) getMsgForNonASCIIChars(str string) string {
+	result := ""
+	for _, c := range str {
+		if c <= unicode.MaxASCII {
+			continue
+		}
+
+		result += fmt.Sprintf(" Non ASCII character %c (%U) found.", c, c)
+	}
+
+	return result
+}
+
+// Name returns the rule name.
+func (*FilenameFormatRule) Name() string {
+	return "filename-format"
+}
+
+var defaultFormat = regexp.MustCompile("^[_A-Za-z0-9][_A-Za-z0-9-]*.go$")
+
+func (r *FilenameFormatRule) configure(arguments lint.Arguments) {
+	r.Lock()
+	defer r.Unlock()
+
+	if r.format != nil {
+		return
+	}
+
+	argsCount := len(arguments)
+	if argsCount == 0 {
+		r.format = defaultFormat
+		return
+	}
+
+	if argsCount > 1 {
+		panic(fmt.Sprintf("rule %q expects only one argument, got %d %v", r.Name(), argsCount, arguments))
+	}
+
+	arg := arguments[0]
+	str, ok := arg.(string)
+	if !ok {
+		panic(fmt.Sprintf("rule %q expects a string argument, got %v of type %T", r.Name(), arg, arg))
+	}
+
+	format, err := regexp.Compile(str)
+	if err != nil {
+		panic(fmt.Sprintf("rule %q expects a valid regexp argument, got %v for %s", r.Name(), err, arg))
+	}
+
+	r.format = format
+}
diff --git a/rule/indent-error-flow.go b/rule/indent-error-flow.go
index 294ceef..ebc1e79 100644
--- a/rule/indent-error-flow.go
+++ b/rule/indent-error-flow.go
@@ -18,27 +18,27 @@ func (*IndentErrorFlowRule) Name() string {
 	return "indent-error-flow"
 }
 
-// CheckIfElse evaluates the rule against an ifelse.Chain.
-func (*IndentErrorFlowRule) CheckIfElse(chain ifelse.Chain, args ifelse.Args) (failMsg string) {
+// CheckIfElse evaluates the rule against an ifelse.Chain and returns a failure message if applicable.
+func (*IndentErrorFlowRule) CheckIfElse(chain ifelse.Chain, args ifelse.Args) string {
 	if !chain.If.Deviates() {
 		// this rule only applies if the if-block deviates control flow
-		return
+		return ""
 	}
 
 	if chain.HasPriorNonDeviating {
 		// if we de-indent the "else" block then a previous branch
 		// might flow into it, affecting program behaviour
-		return
+		return ""
 	}
 
 	if !chain.If.Returns() {
 		// avoid overlapping with superfluous-else
-		return
+		return ""
 	}
 
 	if args.PreserveScope && !chain.AtBlockEnd && (chain.HasInitializer || chain.Else.HasDecls) {
 		// avoid increasing variable scope
-		return
+		return ""
 	}
 
 	return "if block ends with a return statement, so drop this else and outdent its block"
diff --git a/rule/string-format.go b/rule/string-format.go
index 62283cb..ea19eab 100644
--- a/rule/string-format.go
+++ b/rule/string-format.go
@@ -216,7 +216,7 @@ func (w lintStringFormatRule) Visit(node ast.Node) ast.Visitor {
 	for _, rule := range w.rules {
 		for _, scope := range rule.scopes {
 			if scope.funcName == callName {
-				rule.Apply(call)
+				rule.apply(call, scope)
 			}
 		}
 	}
@@ -251,81 +251,73 @@ func (lintStringFormatRule) getCallName(call *ast.CallExpr) (callName string, ok
 
 // #region Linting logic
 
-// Apply a single format rule to a call expression (should be done after verifying the that the call expression matches the rule's scope)
-func (r *stringFormatSubrule) Apply(call *ast.CallExpr) {
-	for _, scope := range r.scopes {
-		if len(call.Args) <= scope.argument {
+// apply a single format rule to a call expression (should be done after verifying the that the call expression matches the rule's scope)
+func (r *stringFormatSubrule) apply(call *ast.CallExpr, scope *stringFormatSubruleScope) {
+	if len(call.Args) <= scope.argument {
+		return
+	}
+
+	arg := call.Args[scope.argument]
+	var lit *ast.BasicLit
+	if len(scope.field) > 0 {
+		// Try finding the scope's Field, treating arg as a composite literal
+		composite, ok := arg.(*ast.CompositeLit)
+		if !ok {
 			return
 		}
-
-		arg := call.Args[scope.argument]
-		var lit *ast.BasicLit
-		if len(scope.field) > 0 {
-			// Try finding the scope's Field, treating arg as a composite literal
-			composite, ok := arg.(*ast.CompositeLit)
+		for _, el := range composite.Elts {
+			kv, ok := el.(*ast.KeyValueExpr)
 			if !ok {
-				return
+				continue
 			}
-			for _, el := range composite.Elts {
-				kv, ok := el.(*ast.KeyValueExpr)
-				if !ok {
-					continue
-				}
-				key, ok := kv.Key.(*ast.Ident)
-				if !ok || key.Name != scope.field {
-					continue
-				}
-
-				// We're now dealing with the exact field in the rule's scope, so if anything fails, we can safely return instead of continuing the loop
-				lit, ok = kv.Value.(*ast.BasicLit)
-				if !ok || lit.Kind != token.STRING {
-					return
-				}
+			key, ok := kv.Key.(*ast.Ident)
+			if !ok || key.Name != scope.field {
+				continue
 			}
-		} else {
-			var ok bool
-			// Treat arg as a string literal
-			lit, ok = arg.(*ast.BasicLit)
+
+			// We're now dealing with the exact field in the rule's scope, so if anything fails, we can safely return instead of continuing the loop
+			lit, ok = kv.Value.(*ast.BasicLit)
 			if !ok || lit.Kind != token.STRING {
 				return
 			}
 		}
-		// Unquote the string literal before linting
-		unquoted := lit.Value[1 : len(lit.Value)-1]
-		r.lintMessage(unquoted, lit)
-	}
-}
-
-func (r *stringFormatSubrule) lintMessage(s string, node ast.Node) {
-	if r.negated {
-		if !r.regexp.MatchString(s) {
+	} else {
+		var ok bool
+		// Treat arg as a string literal
+		lit, ok = arg.(*ast.BasicLit)
+		if !ok || lit.Kind != token.STRING {
 			return
 		}
-		// Fail if the string does match the user's regex
-		var failure string
-		if len(r.errorMessage) > 0 {
-			failure = r.errorMessage
-		} else {
-			failure = fmt.Sprintf("string literal matches user defined regex /%s/", r.regexp.String())
-		}
-		r.parent.onFailure(lint.Failure{
-			Confidence: 1,
-			Failure:    failure,
-			Node:       node,
-		})
+	}
+	// Unquote the string literal before linting
+	unquoted := lit.Value[1 : len(lit.Value)-1]
+	if r.stringIsOK(unquoted) {
 		return
 	}
 
-	// Fail if the string does NOT match the user's regex
-	if r.regexp.MatchString(s) {
-		return
+	r.generateFailure(unquoted, lit)
+}
+
+func (r *stringFormatSubrule) stringIsOK(s string) bool {
+	matches := r.regexp.MatchString(s)
+	if r.negated {
+		return !matches
 	}
+
+	return matches
+}
+
+func (r *stringFormatSubrule) generateFailure(s string, node ast.Node) {
 	var failure string
-	if len(r.errorMessage) > 0 {
+	switch {
+	case len(r.errorMessage) > 0:
 		failure = r.errorMessage
-	} else {
+	case r.negated:
+		failure = fmt.Sprintf("string literal matches user defined regex /%s/", r.regexp.String())
+	case !r.negated:
 		failure = fmt.Sprintf("string literal doesn't match user defined regex /%s/", r.regexp.String())
 	}
+
 	r.parent.onFailure(lint.Failure{
 		Confidence: 1,
 		Failure:    failure,
diff --git a/rule/superfluous-else.go b/rule/superfluous-else.go
index 2aa1b6b..18e8f3b 100644
--- a/rule/superfluous-else.go
+++ b/rule/superfluous-else.go
@@ -2,6 +2,7 @@ package rule
 
 import (
 	"fmt"
+
 	"github.com/mgechev/revive/internal/ifelse"
 	"github.com/mgechev/revive/lint"
 )
@@ -19,27 +20,27 @@ func (*SuperfluousElseRule) Name() string {
 	return "superfluous-else"
 }
 
-// CheckIfElse evaluates the rule against an ifelse.Chain.
-func (*SuperfluousElseRule) CheckIfElse(chain ifelse.Chain, args ifelse.Args) (failMsg string) {
+// CheckIfElse evaluates the rule against an ifelse.Chain and returns a failure message if applicable.
+func (*SuperfluousElseRule) CheckIfElse(chain ifelse.Chain, args ifelse.Args) string {
 	if !chain.If.Deviates() {
 		// this rule only applies if the if-block deviates control flow
-		return
+		return ""
 	}
 
 	if chain.HasPriorNonDeviating {
 		// if we de-indent the "else" block then a previous branch
 		// might flow into it, affecting program behaviour
-		return
+		return ""
 	}
 
 	if chain.If.Returns() {
 		// avoid overlapping with indent-error-flow
-		return
+		return ""
 	}
 
 	if args.PreserveScope && !chain.AtBlockEnd && (chain.HasInitializer || chain.Else.HasDecls) {
 		// avoid increasing variable scope
-		return
+		return ""
 	}
 
 	return fmt.Sprintf("if block ends with %v, so drop this else and outdent its block", chain.If.LongString())
diff --git a/rule/use-any.go b/rule/use-any.go
index bdf3c93..88160c2 100644
--- a/rule/use-any.go
+++ b/rule/use-any.go
@@ -47,7 +47,7 @@ func (w lintUseAny) Visit(n ast.Node) ast.Visitor {
 		Node:       n,
 		Confidence: 1,
 		Category:   "naming",
-		Failure:    "since GO 1.18 'interface{}' can be replaced by 'any'",
+		Failure:    "since Go 1.18 'interface{}' can be replaced by 'any'",
 	})
 
 	return w
diff --git "a/testdata/filenam\320\265-with-non-ascii-char.go" "b/testdata/filenam\320\265-with-non-ascii-char.go"
new file mode 100644
index 0000000..a4c665e
--- /dev/null
+++ "b/testdata/filenam\320\265-with-non-ascii-char.go"
@@ -0,0 +1,3 @@
+package main
+
+// MATCH:1 /Filename filenamе-with-non-ascii-char.go is not of the format ^[_A-Za-z0-9][_A-Za-z0-9-]*.go$. Non ASCII character е (U+0435) found./


Test patch:
diff --git a/revivelib/core_internal_test.go b/revivelib/core_internal_test.go
index ea1f779..a6dcd84 100644
--- a/revivelib/core_internal_test.go
+++ b/revivelib/core_internal_test.go
@@ -18,7 +18,7 @@ func TestReviveCreateInstance(t *testing.T) {
 		t.Fatal("Expected MaxOpenFiles to be 2048")
 	}
 
-	if revive.lintingRules == nil || len(revive.lintingRules) == 0 {
+	if len(revive.lintingRules) == 0 {
 		t.Fatal("Linting rules not loaded.")
 	}
 
diff --git a/test/filename-format_test.go b/test/filename-format_test.go
new file mode 100644
index 0000000..2f0ef76
--- /dev/null
+++ b/test/filename-format_test.go
@@ -0,0 +1,16 @@
+package test
+
+import (
+	"testing"
+
+	"github.com/mgechev/revive/lint"
+	"github.com/mgechev/revive/rule"
+)
+
+func TestLintFilenameFormat(t *testing.T) {
+	testRule(t, "filename-ok-default", &rule.FilenameFormatRule{}, &lint.RuleConfig{})
+
+	testRule(t, "filenamе-with-non-ascii-char", &rule.FilenameFormatRule{}, &lint.RuleConfig{})
+
+	testRule(t, "filename_with_underscores", &rule.FilenameFormatRule{}, &lint.RuleConfig{Arguments: []any{"^[A-Za-z][A-Za-z0-9]*.go$"}})
+}
diff --git a/test/string-format_test.go b/test/string-format_test.go
index 5135ff0..2ca1bd1 100644
--- a/test/string-format_test.go
+++ b/test/string-format_test.go
@@ -171,3 +171,13 @@ func TestStringFormatArgumentParsing(t *testing.T) {
 		})
 	}
 }
+
+func TestStringFormatDuplicatedStrings(t *testing.T) {
+	testRule(t, "string-format-issue-1063", &rule.StringFormatRule{}, &lint.RuleConfig{
+		Arguments: lint.Arguments{[]any{
+			"fmt.Errorf[0],errors.New[0]",
+			"/^([^A-Z]|$)/",
+			"must not start with a capital letter",
+		}},
+	})
+}
diff --git a/test/utils_test.go b/test/utils_test.go
index e376986..c6270db 100644
--- a/test/utils_test.go
+++ b/test/utils_test.go
@@ -40,9 +40,7 @@ func testRule(t *testing.T, filename string, rule lint.Rule, config ...*lint.Rul
 }
 
 func assertSuccess(t *testing.T, baseDir string, fi os.FileInfo, rules []lint.Rule, config map[string]lint.RuleConfig) error {
-	l := lint.New(func(file string) ([]byte, error) {
-		return os.ReadFile(file)
-	}, 0)
+	l := lint.New(os.ReadFile, 0)
 
 	filePath := filepath.Join(baseDir, fi.Name())
 	ps, err := l.Lint([][]string{{filePath}}, rules, lint.Config{
@@ -63,9 +61,7 @@ func assertSuccess(t *testing.T, baseDir string, fi os.FileInfo, rules []lint.Ru
 }
 
 func assertFailures(t *testing.T, baseDir string, fi os.FileInfo, src []byte, rules []lint.Rule, config map[string]lint.RuleConfig) error {
-	l := lint.New(func(file string) ([]byte, error) {
-		return os.ReadFile(file)
-	}, 0)
+	l := lint.New(os.ReadFile, 0)
 
 	ins := parseInstructions(t, filepath.Join(baseDir, fi.Name()), src)
 	if ins == nil {
@@ -173,7 +169,6 @@ func parseInstructions(t *testing.T, filename string, src []byte) []instruction
 					t.Fatalf("At %v:%d: %v", filename, ln, err)
 				}
 				ins = append(ins, jsonInst)
-				break
 			case "classic":
 				match, err := extractPattern(line)
 				if err != nil {
@@ -198,9 +193,7 @@ func parseInstructions(t *testing.T, filename string, src []byte) []instruction
 					Match:       match,
 					Replacement: repl,
 				})
-				break
 			}
-
 		}
 	}
 	return ins
diff --git a/testdata/filename-ok-default.go b/testdata/filename-ok-default.go
new file mode 100644
index 0000000..06ab7d0
--- /dev/null
+++ b/testdata/filename-ok-default.go
@@ -0,0 +1,1 @@
+package main
diff --git a/testdata/filename_with_underscores.go b/testdata/filename_with_underscores.go
new file mode 100644
index 0000000..cbdc6b5
--- /dev/null
+++ b/testdata/filename_with_underscores.go
@@ -0,0 +1,3 @@
+package main
+
+// MATCH:1 /Filename filename_with_underscores.go is not of the format ^[A-Za-z][A-Za-z0-9]*.go$./
diff --git a/testdata/string-format-issue-1063.go b/testdata/string-format-issue-1063.go
new file mode 100644
index 0000000..1cb23c9
--- /dev/null
+++ b/testdata/string-format-issue-1063.go
@@ -0,0 +1,9 @@
+package fixtures
+
+import (
+	"errors"
+)
+
+func ReturnError() error {
+	return errors.New("This is an error.") // MATCH /must not start with a capital letter/
+}
diff --git a/testdata/use-any.go b/testdata/use-any.go
index bc6e647..9891e84 100644
--- a/testdata/use-any.go
+++ b/testdata/use-any.go
@@ -1,19 +1,19 @@
 package pkg
 
-var i interface{} // MATCH /since GO 1.18 'interface{}' can be replaced by 'any'/
+var i interface{} // MATCH /since Go 1.18 'interface{}' can be replaced by 'any'/
 
-type t interface{}   // MATCH /since GO 1.18 'interface{}' can be replaced by 'any'/
-type a = interface{} // MATCH /since GO 1.18 'interface{}' can be replaced by 'any'/
+type t interface{}   // MATCH /since Go 1.18 'interface{}' can be replaced by 'any'/
+type a = interface{} // MATCH /since Go 1.18 'interface{}' can be replaced by 'any'/
 
-func any1(a interface{}) { // MATCH /since GO 1.18 'interface{}' can be replaced by 'any'/
-	m1 := map[interface{}]string{}     // MATCH /since GO 1.18 'interface{}' can be replaced by 'any'/
-	m2 := map[int]interface{}{}        // MATCH /since GO 1.18 'interface{}' can be replaced by 'any'/
-	a := []interface{}{}               // MATCH /since GO 1.18 'interface{}' can be replaced by 'any'/
-	m3 := make(map[int]interface{}, 1) // MATCH /since GO 1.18 'interface{}' can be replaced by 'any'/
-	a2 := make([]interface{}, 2)       // MATCH /since GO 1.18 'interface{}' can be replaced by 'any'/
+func any1(a interface{}) { // MATCH /since Go 1.18 'interface{}' can be replaced by 'any'/
+	m1 := map[interface{}]string{}     // MATCH /since Go 1.18 'interface{}' can be replaced by 'any'/
+	m2 := map[int]interface{}{}        // MATCH /since Go 1.18 'interface{}' can be replaced by 'any'/
+	a := []interface{}{}               // MATCH /since Go 1.18 'interface{}' can be replaced by 'any'/
+	m3 := make(map[int]interface{}, 1) // MATCH /since Go 1.18 'interface{}' can be replaced by 'any'/
+	a2 := make([]interface{}, 2)       // MATCH /since Go 1.18 'interface{}' can be replaced by 'any'/
 }
 
-func any2(a int) interface{} {} // MATCH /since GO 1.18 'interface{}' can be replaced by 'any'/
+func any2(a int) interface{} {} // MATCH /since Go 1.18 'interface{}' can be replaced by 'any'/
 
 var ni interface{ Close() }