⚡️Lightning-fast linter for .env files. Written in Rust 🦀

dotenv-linter

⚡️ Lightning-fast linter for .env files. Written in Rust 🦀

GitHub Actions Coverage Status License Releases

Dotenv-linter can check / fix / compare .env files for problems that may cause the application to malfunction.

Available checks:

     Duplicated Key
     Ending Blank Line
     Extra Blank Line
     Incorrect delimiter
     Key without value
     Leading character
     Lowercase key
     Quote character
     Space character
     Substitution Key
     Trailing whitespace
     Unordered Key

What is a .env file?

     💡  A .env file or dotenv file is a simple text file containing all the environment variables of a project.
    Storing configuration in the environment variables is one of the tenets of the Manifesto of Twelve-Factor App.
    The .env file has a simple key-value format, for example: FOO=BAR.
    More information you can find in articles in English and Russian.

The key features:

     ⚡️  Lightning-fast because it is written in Rust 🦀
     💣  Can be used on any project regardless of the programming language 💥
     🚀  Can be integrated with reviewdog and other CI services (including GitHub Actions and Super-Linter) 🔥

Articles about dotenv-linter:

Dotenv-linter is created & supported by Evrone. What else we develop with Rust.

👨‍💻 Installation

Pre-compiled binary

# Linux / macOS / Windows (MINGW and etc). Installs it into ./bin/ by default
$ curl -sSfL https://raw.githubusercontent.com/dotenv-linter/dotenv-linter/master/install.sh | sh -s

# Or a shorter way
$ curl -sSfL https://git.io/JLbXn | sh -s

# Specify installation directory and version
$ curl -sSfL https://git.io/JLbXn | sh -s -- -b usr/local/bin v2.0.0

# Alpine Linux (using wget)
$ wget -q -O - https://git.io/JLbXn | sh -s

You can find other installation methods here: https://dotenv-linter.github.io/#/installation

🚀 Usage

Check

By default, dotenv-linter checks all .env files in the current directory:

$ dotenv-linter
Checking .env
.env:2 DuplicatedKey: The FOO key is duplicated
.env:3 UnorderedKey: The BAR key should go before the FOO key

Checking .env.test
.env.test:1 LeadingCharacter: Invalid leading character detected

Found 3 problems

🛠 Fix

It can also fix the found warnings with the fix command:

$ dotenv-linter fix
Fixing .env
Original file was backed up to: ".env_1601378896"

.env:2 DuplicatedKey: The BAR key is duplicated
.env:3 LowercaseKey: The foo key should be in uppercase

All warnings are fixed. Total: 2

🤲 Compare

In addition, dotenv-linter can compare .env files with each other and output the difference between them:

$ dotenv-linter compare .env .env.example
Comparing .env
Comparing .env.example
.env is missing keys: BAR
.env.example is missing keys: FOO

Other use cases you can find on the documentation site (https://dotenv-linter.github.io):

🚦 Continuous Integration

dotenv-linter can also be used with CI services such as: GitHub Actions and Circle CI.

🚧 Benchmark

Benchmarking dotenv-linter/dotenv-linter and wemake-services/dotenv-linter has done using the hyperfine utility:

Command Mean [ms] Min [ms] Max [ms] Relative
dotenv-linter/dotenv-linter .env 2.7 ± 0.4 2.0 4.3 1.00
wemake-services/dotenv-linter .env 162.6 ± 12.1 153.0 201.3 60.83 ± 10.20
Content of .env file used for benchmarking
 SPACED=

KEY = VALUE

SECRET="my value"

SECRET=Already defined

kebab-case-name=1
snake_case_name=2

✌️ Mentorship

Dotenv-linter is not just a linter for .env files — it is also a contributor-friendly open-source project with the purpose of helping others learn Rust using a simple, but useful tool. 😊

In addition to studying Rust, this project has another goal — to promote love for open-source, help you with the first steps in it and give an opportunity to contribute to the open-source project written in Rust. ❤️

We act as a mentor within this project and help developers follow the path of a novice contributor from start to the top. 🤗

🤝 Contributing

If you've ever wanted to contribute to open source, now you have a great opportunity:

👍 Similar projects

Contributors

This project exists thanks to all the people who contribute. [Contribute].

♥️ Sponsors

Sponsored by Evrone

Become a financial contributor and help us sustain our community.

📃 License

MIT

Owner
dotenv-linter
⚡️Lightning-fast linter for .env files. Written in Rust 🦀
dotenv-linter
Comments
  • Autofix

    Autofix

    I have implemented automatic correction of the contents of files based on the results of the check. When displaying, all warnings are marked as Fixed or Unfixed. If all warnings are fixed, exit code is 0.

    Just one kind of checks is fixable for now (LowercaseKey), but I have create the scaffold for implementing all kinds of checks.

    The CLI key for the autofix mode is -f/--fix.

    A few comments about the design:

    The separate trait Fix was made for fixes (I tried to keep some symmetry with checks), but it is possible to expand the trait Check itself with this functions too.

    There are two groups of fixes: some can be implemented by working only with the line that caused warning, for others you need to work with the entire line collection.

    The Fix trait allows you to work with both groups of fixes due to default function implementations.

    ✔ Checklist:

    • [x] This PR has been added to CHANGELOG.md (at the top of the list);
    • [x] Tests for the changes have been added (for bug fixes / features);
    • [x] Docs have been added / updated (for bug fixes / features).
  • WIP build: create docker arm64 image

    WIP build: create docker arm64 image

    Closes #449

    I hope this will work with GH-actions and the ubuntu-latest container. I used this locally to test some kubernetes stuff on different environments (arm64 and amd64 nodes) and it worked.

    Docker Buildx is included in Docker Desktop and Docker Linux packages when installed using the DEB or RPM packages.

    If you want to know more: https://docs.docker.com/buildx/working-with-buildx/

    ✔ Checklist:

    • [x] Commit messages have been written in Conventional Commits format;
    • [x] This PR has been added to CHANGELOG.md (at the top of the list);
    • [x] Tests for the changes have been added (for bug fixes / features);
    • [x] Docs have been added / updated on the dotenv-linter.github.io (for bug fixes / features).
  • Color output and --no-color option

    Color output and --no-color option

    This commit if included will:

    1. Adds color to warnings,
    2. Adds a --no-color option to switch off colored output,
    3. Adds a test case to cover --no-color option

    ✔ Checklist:

    • [x] This PR has been added to CHANGELOG.md (at the top of the list);
    • [x] Tests for the changes have been added (for bug fixes / features);
    • [ ] Docs have been added / updated (for bug fixes / features).
  • Add docs

    Add docs

    Used docsify to create the docs.

    You can take a look at the docs here where I pushed my fork branch.

    ✔ Checklist:

    • [x] This PR has been added to CHANGELOG.md (at the top of the list);
  • Add compare command

    Add compare command

    A proof of concept how comparing could work. I think this isn't the cleanest implementation and needs some abstraction work in terms of types, and duplicate work between compare and run but I wanted to see if it can work and how it could work.

    We didn't already agreed that this feature needed to be added to the tool, but I liked the idea, found some time and had fun playing around with it.

    So this could be the starting point of a discussion and further investigation of that topic.

    What do you think?

    Check this feature:

    # creating test data
    echo HELLO=value >> .env
    echo HELLO=value >> .env.local
    echo WORLD=value >> .env
    
    # running
    dotenv-linter --compare .env .env.local
    # or
    cargo run -- --compare .env .env.local
    
  • Release v3.0.0

    Release v3.0.0

    What should be included in the new release v3.0.0.

    Features:

    • [x] Color output and --no-color option (#307)
    • [x] Display file names being scanned (#311)
    • [x] Add compare command (#282)
    • [x] Make an output on-the-fly (#335)
    • [x] Add support export prefix (#337)
    • [x] Add support multi-line values (#339)

    Improvements:

    • [x] Breaking changes: Using subcommands instead of flags (#333)
    • [x] Fix a bug with QuoteCharacterChecker and values with whitespaces (#343)
    • [x] Not all problems are found (#345)

    Infrastructure:

    Site:

    • [x] Add action-misspell (https://github.com/dotenv-linter/dotenv-linter.github.io/issues/17)
    • [x] Change flags to subcommands (https://github.com/dotenv-linter/dotenv-linter.github.io/issues/16)

    GitHub Action:

    • [x] Add action-shellcheck (https://github.com/dotenv-linter/action-dotenv-linter/issues/17)
    • [x] Add action-misspell (https://github.com/dotenv-linter/action-dotenv-linter/issues/16)
    • [x] Add --no-color flag (https://github.com/dotenv-linter/action-dotenv-linter/issues/21)

    What do you think should be included in the new release?

    /cc @dotenv-linter/core

  • UnorderedKey fix

    UnorderedKey fix

    PR for https://github.com/dotenv-linter/dotenv-linter/issues/252.

    ✔ Checklist:

    • [x] This PR has been added to CHANGELOG.md (at the top of the list);
    • [x] Tests for the changes have been added (for bug fixes / features);
    • [x] Docs have been added / updated (for bug fixes / features).
  • Provide more short way to install dotenv-linter

    Provide more short way to install dotenv-linter

    Implemented a script for more short way to install dotenv-linter (#112).

    The advantage of the solution is its cross-platform. The script is executed with curl/wget and even under Windows (checked on MINGW).

    Complexity is the process of automatically declaring an environment variable. In some cases, this is only possible manually at the moment.

    This is a working version, I also tested on Alpine Linux.

    But I would like to hear any ideas for improving or changing the approach.

    Perhaps when we come to a final decision, it makes sense to create a separate repository. Although for installing binaries with a script, it looks suitable in this repo, so far it is not more than 1 file.

    ✔ Checklist:

    • [X] This PR has been added to CHANGELOG.md (at the top of the list);
    • [X] Docs have been added / updated (for bug fixes / features).
  • Use Rc for Warning to reduce memory consumption

    Use Rc for Warning to reduce memory consumption

    Description

    The Warning struct has the LineEntry field which clones in every checks, e.g.: DuplicatedKeyChecker.

    Use the Rc type for Warning to reduce memory consumption.

    Similar issue: https://github.com/dotenv-linter/dotenv-linter/issues/388

  • Provide dotenv-linter in the Arch User Repository

    Provide dotenv-linter in the Arch User Repository

    The Arch User Repository is like a package repository for Arch linux maintained by it's users. I would be happy to set it up there so that any arch user can simply install it with:

    <your-aur-helper> -S dotenv-linter (-S is mostly the command to install a package, in case your aur helper does it differently you need to substitute this command.

    If that would be desired I would be happy to go :)

  • Shows files that were linted

    Shows files that were linted

    This PR adds functionality to show the files that were linted as part of a dotenv-linter run. It does so by introducing a new struct Warnings which is basically a wrapper around Vec<Warning> to also include information about the paths related to the warnings.

    This PR also fixes tests as a result of the added functionality, and some refactoring.

    Below shows the output from running dotenv-linter with different args:

    $ cargo run
    Checking ".env"
    .env:1 LowercaseKey: The hi key should be in uppercase
    .env:3 ExtraBlankLine: Extra blank line detected
    .env:4 LowercaseKey: The hi3 key should be in uppercase
    
    Checking ".env_2/.env"
    .env_2/.env:2 ExtraBlankLine: Extra blank line detected
    .env_2/.env:3 LowercaseKey: The hi key should be in uppercase
    .env_2/.env:4 DuplicatedKey: The hi key is duplicated
    .env_2/.env:4 LowercaseKey: The hi key should be in uppercase
    
    Found 7 problems
    
    $ cargo run -- -q
    .env:1 LowercaseKey: The hi key should be in uppercase
    .env:3 ExtraBlankLine: Extra blank line detected
    .env:4 LowercaseKey: The hi3 key should be in uppercase
    .env_2/.env:2 ExtraBlankLine: Extra blank line detected
    .env_2/.env:3 LowercaseKey: The hi key should be in uppercase
    .env_2/.env:4 DuplicatedKey: The hi key is duplicated
    .env_2/.env:4 LowercaseKey: The hi key should be in uppercase
    
    $ cargo run -- -f
    Checking ".env"
    Original file was backed up to: ".env_1601943961"
    
    .env:1 LowercaseKey: The hi key should be in uppercase
    .env:3 ExtraBlankLine: Extra blank line detected
    .env:4 LowercaseKey: The hi3 key should be in uppercase
    
    Checking ".env_2/.env"
    Original file was backed up to: ".env_2/.env_1601943961"
    
    .env_2/.env:2 ExtraBlankLine: Extra blank line detected
    .env_2/.env:3 LowercaseKey: The hi key should be in uppercase
    .env_2/.env:4 DuplicatedKey: The hi key is duplicated
    .env_2/.env:4 LowercaseKey: The hi key should be in uppercase
    
    All warnings are fixed. Total: 7
    
    $ cargo run -- -f -q
    Original file was backed up to: ".env_1601943979"
    Original file was backed up to: ".env_2/.env_1601943979"
    
    All warnings are fixed. Total: 7
    
    $ cargo run -- -f --no-backup
    Checking ".env"
    .env:1 LowercaseKey: The hi key should be in uppercase
    .env:3 ExtraBlankLine: Extra blank line detected
    .env:4 LowercaseKey: The hi3 key should be in uppercase
    
    Checking ".env_2/.env"
    .env_2/.env:2 ExtraBlankLine: Extra blank line detected
    .env_2/.env:3 LowercaseKey: The hi key should be in uppercase
    .env_2/.env:4 DuplicatedKey: The hi key is duplicated
    .env_2/.env:4 LowercaseKey: The hi key should be in uppercase
    
    All warnings are fixed. Total: 7
    
    $ cargo run -- -f -q --no-backup
    
    All warnings are fixed. Total: 7
    

    ✔ Checklist:

    • [x] This PR has been added to CHANGELOG.md (at the top of the list);
    • [x] Tests for the changes have been added (for bug fixes / features);
    • [x] Docs have been added / updated (for bug fixes / features).

    Closes #268

  • Support skipping specific checks with an environment variable

    Support skipping specific checks with an environment variable

    Clap supports accepting multiple values in a single environment variable:

    https://docs.rs/clap/3.1.10/clap/struct.Arg.html#method.env

    This could be used to implement something like this:

    DOTENV_LINTER_SKIP=QuoteCharacter,UnorderedKey dotenv-linter
    
  • Confusing behaviour when using --skip

    Confusing behaviour when using --skip

    If I pass --skip SpecificCheck, it eats all of the remaining arguments. If I do the traditional Unix thing of specifying flags before arguments, like so:

    dotenv-linter --skip QuoteCharacter my/folder/.env
    

    It completely ignores the fact that I passed a custom filename, and only checks for a .env file in the current folder. If such a file exists, it checks it. If no such file exists, it exits with a success status code (0).

    If I pass the flag after the list of files to check, everything works as expected:

    dotenv-linter my/folder/.env --skip QuoteCharacter
    

    It turns out I can make the first example work by doing this:

    dotenv-linter --skip QuoteCharacter -- my/folder/.env
    

    However this is uncommon for a CLI app, and isn't mentioned as a supported behaviour in the documentation. Also I don't see any tests that cover the case of skipping checks while also passing a custom list of files.

    I think the ideal solution would be to allow flags to be passed in any order. Skipping multiple checks should require passing --skip multiple times.

  • Add environment variable for --not-check-updates

    Add environment variable for --not-check-updates

    In certain environments, it may not be feasible to control all invocations of dotenv-linter. However the environment can typically still be controlled (and usually more easily even if invocations can be controlled). It would be nice if there was a way to set this with an environment variable.

  • Question: is there a way to filter certain comparisons?

    Question: is there a way to filter certain comparisons?

    If you have .env and .env.example files, it makes sense to compare both files to have the same keys. If you have .env and .env.local, it is quite normal to not have all keys in the .env.local file, but the keys might still have to be the same (even when sometimes a .env.local file might have completely different keys as well).

    Is there a way to tell the compare command about the second situation, to compare a local overwrite file to the keys in the actual .env file?

Library for setting values to structs' fields from env, flags, files or default tag

Configuration is a library for injecting values recursively into structs - a convenient way of setting up a configuration object. Available features:

Dec 7, 2022
A simple tool that utilizes already existing libraries such as joho/godotenv to add .env-files to global path

Go dotenv A simple tool that utilizes already existing libraries such as joho/godotenv to add .env-files to global path. Created as a practical way to

Nov 15, 2021
Tmpl - A tool to apply variables from cli, env, JSON/TOML/YAML files to templates

tmpl allows to apply variables from JSON/TOML/YAML files, environment variables or CLI arguments to template files using Golang text/template and functions from the Sprig project.

Nov 14, 2022
Genv is a library for Go (golang) that makes it easy to read and use environment variables in your projects. It also allows environment variables to be loaded from the .env file.

genv Genv is a library for Go (golang) that makes it easy to read and use environment variables in your projects. It also allows environment variables

Dec 21, 2022
A Go port of Ruby's dotenv library (Loads environment variables from `.env`.)

GoDotEnv A Go (golang) port of the Ruby dotenv project (which loads env vars from a .env file) From the original Library: Storing configuration in the

Jan 5, 2023
Light weight, extensible configuration management library for Go. Built in support for JSON, TOML, YAML, env, command line, file, S3 etc. Alternative to viper.
Light weight, extensible configuration management library for Go. Built in support for JSON, TOML, YAML, env, command line, file, S3 etc. Alternative to viper.

koanf (pronounced conf; a play on the Japanese Koan) is a library for reading configuration from different sources in different formats in Go applicat

Jan 8, 2023
formicidate is a small tool for Go application can update the value of environment variables in a .env file with code

formicidae Update .env files in Go with code. What is fomicidae? formicidate is a small tool for Go application. You can update the value of environme

Jan 23, 2022
Library providing routines to merge and validate JSON, YAML and/or TOML files
Library providing routines to merge and validate JSON, YAML and/or TOML files

CONFLATE Library providing routines to merge and validate JSON, YAML, TOML files and/or structs (godoc) Typical use case: Make your application config

Sep 26, 2022
🛠 A configuration library for Go that parses environment variables, JSON files, and reloads automatically on SIGHUP
🛠 A configuration library for Go that parses environment variables, JSON files, and reloads automatically on SIGHUP

config A small configuration library for Go that parses environment variables, JSON files, and reloads automatically on SIGHUP. Example func main() {

Dec 11, 2022
A golang package for parsing ini-style configuration files

Mini Mini is a simple ini configuration file parser. The ini syntax supported includes: The standard name=value Comments on new lines starting with #

Jan 7, 2023
Manage local application configuration files using templates and data from etcd or consul

confd confd is a lightweight configuration management tool focused on: keeping local configuration files up-to-date using data stored in etcd, consul,

Dec 27, 2022
Quickly read variables from environment files

go-quick-env Quickly read variables from environment files The best way to import environment variables to your code, is by using .env files. This lib

May 11, 2021
Read files into environment variables and execute command

read-file-to-env -- Read files into environment variables and execute command Example use: read-file-to-env -one-line=HOST=/etc/hostname sh -c 'echo h

Nov 12, 2021
Generate initial configuration files for Go.

Generate initial configuration files for Go.

Mar 26, 2022
parser for configuration files

config-loader config-loader supports to load config files and convert to map values. Supported format json Usage import ( "fmt" "github.com/tharun2

Nov 27, 2021
Golang library for reading properties from configuration files in JSON and YAML format or from environment variables.

go-config Golang library for reading properties from configuration files in JSON and YAML format or from environment variables. Usage Create config in

Aug 22, 2022
Config files for my GitHub profile.

hcltm Threat Modeling with HCL Overview There are many different ways in which a threat model can be documented. From a simple text file, to more in-d

Dec 7, 2021
Config files for my GitHub profile.
Config files for my GitHub profile.

swag ?? English ∙ 简体中文 Swag converts Go annotations to Swagger Documentation 2.0. We've created a variety of plugins for popular Go web frameworks. Th

Dec 7, 2021
Automatically generate Go Code from dotenv files.

goenvgen Automatically generate Go Code from dotenv files. This cli automatically determines the type information from the dotenv information and gene

Dec 3, 2021