DEV Community

Khue Pham
Khue Pham Subscriber

Posted on

Environment File (.env) Checker and Syncer for ReactJS / NodeJS Project

This bash script provides functionality to check and sync environment files in your project.
Image description

Features

  1. Checks .env files against a template (.env.template)

  2. Identifies missing variables in .env files

  3. Offers to sync .env files with the template

  4. Skips syncing content for specified files

Usage

Source code in my Github repository here:
Check file here: misc/check_env_files.sh at main ยท khuepm/misc

  1. Place the script (check_env_files.sh) in your project root directory.

  2. Ensure you have a .env.template file with all required environment variables.

  3. Make the script executable:

    chmod +x checkenv.sh

    1. Run the script:

    ./checkenv.sh

    1. (optional) Add to package.json to check every start yarn

    {
    โ€ฆ
    scripts: {
    "prestart": "sh checkenv.sh",
    }
    }

What it does

  1. Checking Environment Files:
  • The script checks all .env* files in the current directory against .env.template.

  • It displays missing variables in each file.

  • A summary of errors (if any) is shown for each file.

2. Syncing Environment Files:

  • If errors are found, the script offers to sync .env files with .env.template.

  • If you choose to sync (by entering โ€˜yโ€™), the script will:

  • Comment out variables not present in the template

  • Add new variables from the template

  • keep existing variables: preserving the current value and adding a comment with the template value

Configuration

  • The script uses .env.template as the reference. Ensure this file contains all required variables for your project.

Note

After syncing, the script cleans the yarn cache. You may want to adjust or remove this step based on your project needs.

  • Comment out yarn cache clean

How do I created it?

1. Initial Setup:

#!/bin/bash template=".env.template" # Check if the template file exists if [ ! -f "$template" ]; then echo "Error: $template not found" return 1 fi 
Enter fullscreen mode Exit fullscreen mode

This section sets up the script and defines the template file. It also checks if the template file exists.

2. check_env_files() function:

# Use for later step, a flag to notice when we need to sync the .env errors_found=false check_env_files() { files_not_to_check=(".env.template") # Get all .env files in the current directory files_to_check=($(find . -maxdepth 1 -type f -name '.env*')) # Remove files that are in files_not_to_check for file in "${files_not_to_check[@]}"; do files_to_check=(${files_to_check[@]/$file}) done # Remove any empty elements files_to_check=(${files_to_check[@]}) # Get terminal height and width terminal_height=$(tput lines) terminal_width=$(tput cols) # Variables to store output and result output="" result="" # Function to update the screen, keep to notice text at the bottom of screen update_screen() { # Clear the screen tput clear # Print the output echo "$output" # Move cursor to the bottom and print the result tput cup $((terminal_height - 3)) 0 printf '%*s\n' "$terminal_width" '' | tr ' ' '-' echo "$result" printf '%*s\n' "$terminal_width" '' | tr ' ' '-' # Move cursor back to the top tput cup 0 0 } for file in "${files_to_check[@]}"; do if [ -f "$file" ]; then output+="\n" output+="Checking $file...\n\n" error_count=0 while IFS= read -r line || [[ -n "$line" ]]; do key=$(echo "$line" | cut -d'=' -f1) if ! grep -q "^$key=" "$file"; then output+="\033[31m ๐Ÿ’” Missing in $file: $key\033[0m\n" ((error_count++)) errors_found=true fi update_screen done < "$template" # Update final result output+="\n\n==========================================\n" if [ $error_count -gt 0 ]; then result+="\n\033[31mโŒ Done checking $file with $error_count error(s)\033[0m\n" output+="$result" else result+="\n\033[32mโœ… Done checking $file with no errors\033[0m\n" output+="$result" fi update_screen output+="\n" # Add a small delay to make the result visible at first check # Remove if you want to see the result immediately if [ "$file" = "${files_to_check[0]}" ]; then sleep 1 fi else #output+="\033[33m๐ŸŸ  Check $file: $file not found, skipping\033[0m\n" #result+="\033[33mโš ๏ธ $file not found, skipping\033[0m\n" update_screen fi done # Clear the result at the end result="" update_screen # Reset terminal settings tput rmcup # Exit alternate screen buffer tput cnorm # Show cursor tput sgr0 # Reset all attributes # Clear the screen and move cursor to top-left clear tput cup 0 0 # Display final output echo "$output" } 
Enter fullscreen mode Exit fullscreen mode

This function is responsible for checking .env files against the template. It does the following:

  • Finds all .env files in the current directory

  • Removes files that should not be checked

  • Sets up a dynamic terminal display

  • Checks each .env file against the template, highlighting missing keys

  • Updates the screen with progress and results

The problem when template has an empty line or a comment line, the checker will not work property. So I need to adjust it a little bit:

 ... while IFS= read -r line || [[ -n "$line" ]]; do # Skip empty lines and comment lines if [[ -z "$line" || "$line" =~ ^[[:space:]]*# ]]; then continue fi ... 
Enter fullscreen mode Exit fullscreen mode

3. sync_env_files() function:

This function synchronizes .env files with the template. It:

  • Finds all .env files to sync

  • For each file:

  • Comments out lines not in the template

  • Updates existing keys with new values from the template

  • Adds new keys from the template

    sync_env_files() {
    # Get all .env files in the current directory
    files_to_sync=($(find . -maxdepth 1 -type f -name '.env*'))

    # Exclude .env.template from files to sync
    files_to_sync=(${files_to_sync[@]/$template})

    # Remove any empty elements
    files_to_sync=(${files_to_sync[@]})

    # Sync files
    for file in "${files_to_sync[@]}"; do
    if [ -f "$file" ]; then

     # Check if the file is in the list of files not to sync echo "Syncing $file with $template..." # Comment lines not in template while IFS= read -r line || [[ -n "$line" ]]; do if [[ $line =~ ^[[:space:]]*# || -z $line ]]; then continue # Skip comments and empty lines fi key=$(echo "$line" | cut -d'=' -f1) if ! grep -q "^$key=" "$template"; then sed -i '' "s|^$key=.*|# $line # Not in template|" "$file" echo "\033[31m Commented: $key (not in template)\033[0m" fi done < "$file" while IFS= read -r line || [[ -n "$line" ]]; do if [[ $line =~ ^[[:space:]]*# || -z $line ]]; then continue # Skip comments and empty lines fi key=$(echo "$line" | cut -d'=' -f1) value=$(echo "$line" | cut -d'=' -f2-) if grep -q "^$key=" "$file"; then # Key exists, check if value is different current_value=$(grep "^$key=" "$file" | cut -d'=' -f2-) if [ "$current_value" != "$value" ]; then # Value is different, update it sed -i '' "/# $key=.*# Updated from template/d" "$file" sed -i '' "s|^$key=.*|# $key=$value # Updated from template\n$key=$current_value|" "$file" echo "\033[33m Updated: $key\033[0m" else echo " Skipped: $key (value unchanged)" fi else # Key doesn't exist, add it echo "$key=$value # Added from template" >> "$file" echo "\033[32m Added: $key\033[0m" fi done < "$template" echo "Finished syncing $file" echo fi 

    done
    }

4. Main execution flow:

# Call the function check_env_files if [ "$errors_found" = true ]; then # Ask user if they want to sync files # If yes, call sync_env_files() # After sync successfully, do clean the cache # If no, cancel the operation else echo "No errors found in .env files. Sync not needed." fi 
Enter fullscreen mode Exit fullscreen mode

This section calls the check_env_files() function and then, based on whether errors were found, either prompts the user to sync the files or informs them that no sync is needed.

Key features of this script:

  • Dynamic terminal display for real-time progress updates

  • Color-coded output for easy reading (red for errors, green for success, yellow for warnings)

  • Careful handling of existing values in .env files during sync

  • Option to sync files only if errors are found

This script is useful for maintaining consistency across multiple .env files in a project, ensuring that all required environment variables are present and up-to-date.

ReactJS #ReactNative #.env #.env.template #uptodate-env-file

Top comments (0)