Created
January 13, 2021 08:12
-
-
Save vlad-velciov/fb933746e81bca6c46ca4d2346795aa9 to your computer and use it in GitHub Desktop.
A small tool to convert a file that has lots of export statements to a normalized .env file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# frozen_string_literal: true | |
require 'digest/md5' | |
# TODO option to install git hook on pull | |
# TODO option to uninstall git hook on pull | |
# TODO option to install files in a .git/info/exclude | |
TIER_TO_FILENAME={ | |
'dev' => ['.env.development', 'development.env'], | |
'test' => ['.env.test', 'test.env'], | |
'aio' => ['.env.aio', 'aio.env'] | |
}.freeze | |
def source_zshrc | |
log 'Sourcing ~/.zsrhc...' | |
`source ~/.zshrc` | |
end | |
def convert_environment(environment) | |
file_with_exports, dot_env_file = TIER_TO_FILENAME[environment] | |
convert_file(file_with_exports, dot_env_file) | |
end | |
def convert_file(file_with_exports, dot_env_file) | |
report_if_file_was_changed(dot_env_file) do | |
run_source(file_with_exports) | |
var_names = get_var_names(file_with_exports) | |
write_env_vars(var_names, dot_env_file) | |
end | |
end | |
def run_source(file) | |
log "Sourcing file #{file}..." | |
source_env_from file | |
end | |
# System commands are run in a separate shell which is closed | |
# after execution. That is why we are printing the environment vars | |
# and using them afterwards. | |
def get_sourced_vars(file) | |
local_envs = "AWS_ACCESS_KEY_ID=#{ENV['AWS_ACCESS_KEY_ID']} AWS_SECRET_ACCESS_KEY=#{ENV['AWS_SECRET_ACCESS_KEY']}" | |
env = `#{local_envs} source #{file}; printenv` | |
key_value_array = env | |
.split(/\n/) | |
.map {|l| l.split(/=/)} | |
.map do |l| | |
if l.length > 2 | |
[l[0], l[1..-1].join('=')] | |
else | |
l | |
end | |
end | |
Hash[ key_value_array ] | |
end | |
def source_env_from(file) | |
get_sourced_vars(file).each {|k,v| ENV[k] = v } | |
end | |
def get_var_names(file) | |
log "Getting all variable names..." | |
var_names = [] | |
text=File.open(file).read | |
text.gsub!(/\r\n?/, "\n") | |
text.each_line.with_index do |line, line_num| | |
next if !line.include?('export') | |
next if line =~ /^#/ | |
export_part = line.split('=')[0] | |
var_name = export_part.split(' ')[1] | |
next unless var_name | |
var_names << var_name | |
end | |
var_names | |
end | |
def write_env_vars(var_names, new_file) | |
log "Writing variables to #{new_file}..." | |
File.open(new_file, "w+") do |f| | |
var_names.each do |var_name| | |
f.puts "#{var_name}=#{ENV[var_name]}" | |
end | |
end | |
end | |
def get_var_value(var_name) | |
if default_name = detect_override(var_name) | |
ENV[var_name] ? ENV[var_name] : ENV[default_name] | |
else | |
ENV[var_name] | |
end | |
end | |
# TODO do this | |
def detect_override(var_name) | |
value = ENV[var_name] | |
if value =~ /^\$\{/ | |
true | |
else | |
false | |
end | |
end | |
def get_existing_envs | |
envs = [] | |
['dev', 'test', 'aio'].each do |env| | |
envs << env if env_file_present?(env) | |
end | |
envs | |
end | |
def env_file_present?(env) | |
file, _ = TIER_TO_FILENAME[env] | |
File.exist?(file) | |
end | |
def log(string, level = :debug) | |
colors = { | |
debug: 33, | |
success: 32 | |
} | |
puts colorize string, colors[level] | |
end | |
def colorize(string, color_code) | |
"\e[#{color_code}m#{string}\e[0m" | |
end | |
def report_if_file_was_changed(file) | |
initial_hahs = file_hash(file) | |
yield | |
final_hash = file_hash(file) | |
if initial_hahs == final_hash | |
log 'No changes were found. Same file.' | |
else | |
log 'Changes were found. New file generated' | |
end | |
log "\n" | |
end | |
def file_hash(file) | |
if File.exist? file | |
Digest::MD5.hexdigest(File.read(file)) | |
else | |
"" | |
end | |
end | |
def main | |
source_zshrc | |
existing_envs = get_existing_envs | |
if existing_envs.empty? | |
log 'No environmental files(e.g.: .env.development) were found. Goodbye.' | |
exit | |
end | |
existing_envs.each { |environment| convert_environment(environment) } | |
log 'Done', :success | |
end | |
main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment