@ -1,75 +1,184 @@
#!/usr/bin/env python
import os
from rich . console import Console
from rich . table import Table
from rich import box
import re
import dotenv
from utils . console import handle_input
console = Console ( )
success = True
def check_env ( ) - > bool :
if not os . path . exists ( " .env.template " ) :
console . print ( " [red]Couldn ' t find .env.template. Unable to check variables. " )
return False
return True
if not os . path . exists ( " .env " ) :
console . print ( " [red]Couldn ' t find the .env file, creating one now. " )
with open ( " .env " , " x " ) as file :
file . write ( " " )
with open ( " .env.template " , " r " ) as template :
# req_envs = [env.split("=")[0] for env in template.readlines() if "=" in env]
matching = { }
explanations = { }
bounds = { }
types = { }
oob_errors = { }
req_envs = [ ]
var_optional = False
for line in template . readlines ( ) :
if " = " in line and var_optional is not True :
if line . startswith ( " # " ) is not True and " = " in line and var_optional is not True :
req_envs . append ( line . split ( " = " ) [ 0 ] )
elif " #OPTIONAL " in line :
var_optional = True
elif line . startswith ( " #MATCH_REGEX " ) :
matching [ req_envs [ - 1 ] ] = line . removeprefix ( " #MATCH_REGEX " ) [ : - 1 ]
var_optional = False
elif line . startswith ( " #OOB_ERROR " ) :
oob_errors [ req_envs [ - 1 ] ] = line . removeprefix ( " #OOB_ERROR " ) [ : - 1 ]
var_optional = False
elif line . startswith ( " #RANGE " ) :
bounds [ req_envs [ - 1 ] ] = tuple (
map (
lambda x : float ( x ) if x != " None " else None ,
line . removeprefix ( " #RANGE " ) [ : - 1 ] . split ( " : " ) ,
)
)
var_optional = False
elif line . startswith ( " #MATCH_TYPE " ) :
types [ req_envs [ - 1 ] ] = eval ( line . removeprefix ( " #MATCH_TYPE " ) [ : - 1 ] . split ( ) [ 0 ] )
var_optional = False
elif line . startswith ( " #EXPLANATION " ) :
explanations [ req_envs [ - 1 ] ] = line . removeprefix ( " #EXPLANATION " ) [ : - 1 ]
var_optional = False
else :
var_optional = False
missing = [ ]
incorrect = [ ]
missing = set ( )
incorrect = set ( )
dotenv . load_dotenv ( )
for env in req_envs :
value = os . getenv ( env )
if value is None :
missing . append ( env )
missing . a d d( env )
continue
if env in matching . keys ( ) :
env , re . match ( matching [ env ] , value ) is None and incorrect . append ( env )
if len ( missing ) :
for i in range ( len ( missing ) ) :
re . match ( matching [ env ] , value ) is None and incorrect . add ( env )
if env in bounds . keys ( ) and env not in types . keys ( ) :
len ( value ) > = bounds [ env ] [ 0 ] or (
len ( bounds [ env ] ) > 1 and bounds [ env ] [ 1 ] > = len ( value )
) or incorrect . add ( env )
continue
if env in types . keys ( ) :
try :
missing [ i ] = missing [ i ] + " : " + explanations [ missing [ i ] ]
except KeyError :
pass
console . print (
f " [red] { ' These variables are ' * ( len ( missing ) > 1 ) or ' This variable is ' } non-optional and missing: \n \n "
+ " \n \n " . join ( missing )
temp = types [ env ] ( value )
if env in bounds . keys ( ) :
( bounds [ env ] [ 0 ] < = temp or incorrect . add ( env ) ) and len ( bounds [ env ] ) > 1 and (
bounds [ env ] [ 1 ] > = temp or incorrect . add ( env )
)
except ValueError :
incorrect . add ( env )
if len ( missing ) :
table = Table (
title = " Missing variables " ,
highlight = True ,
show_lines = True ,
box = box . ROUNDED ,
border_style = " #414868 " ,
header_style = " #C0CAF5 bold " ,
title_justify = " left " ,
title_style = " #C0CAF5 bold " ,
)
table . add_column ( " Variable " , justify = " left " , style = " #7AA2F7 bold " , no_wrap = True )
table . add_column ( " Explanation " , justify = " left " , style = " #BB9AF7 " , no_wrap = False )
table . add_column ( " Type " , justify = " center " , style = " #F7768E " , no_wrap = True )
table . add_column ( " Min " , justify = " right " , style = " #F7768E " , no_wrap = True )
table . add_column ( " Max " , justify = " left " , style = " #F7768E " , no_wrap = True )
for env in missing :
table . add_row (
env ,
explanations [ env ] if env in explanations . keys ( ) else " No explanation given " ,
str ( types [ env ] . __name__ ) if env in types . keys ( ) else " str " ,
str ( bounds [ env ] [ 0 ] ) if env in bounds . keys ( ) and bounds [ env ] [ 1 ] is not None else " " ,
str ( bounds [ env ] [ 1 ] )
if env in bounds . keys ( ) and len ( bounds [ env ] ) > 1 and bounds [ env ] [ 1 ] is not None
else " " ,
)
console . print ( table )
success = False
if len ( incorrect ) :
table = Table (
title = " Incorrect variables " ,
highlight = True ,
show_lines = True ,
box = box . ROUNDED ,
border_style = " #414868 " ,
header_style = " #C0CAF5 bold " ,
title_justify = " left " ,
title_style = " #C0CAF5 bold " ,
)
table . add_column ( " Variable " , justify = " left " , style = " #7AA2F7 bold " , no_wrap = True )
table . add_column ( " Current value " , justify = " left " , style = " #F7768E " , no_wrap = False )
table . add_column ( " Explanation " , justify = " left " , style = " #BB9AF7 " , no_wrap = False )
table . add_column ( " Type " , justify = " center " , style = " #F7768E " , no_wrap = True )
table . add_column ( " Min " , justify = " right " , style = " #F7768E " , no_wrap = True )
table . add_column ( " Max " , justify = " left " , style = " #F7768E " , no_wrap = True )
for env in incorrect :
table . add_row (
env ,
os . getenv ( env ) ,
explanations [ env ] if env in explanations . keys ( ) else " No explanation given " ,
str ( types [ env ] . __name__ ) if env in types . keys ( ) else " str " ,
str ( bounds [ env ] [ 0 ] ) if env in bounds . keys ( ) else " None " ,
str ( bounds [ env ] [ 1 ] ) if env in bounds . keys ( ) and len ( bounds [ env ] ) > 1 else " None " ,
)
missing . add ( env )
console . print ( table )
if success is True :
return True
console . print (
f " [red] { ' These variables are ' * ( len ( incorrect ) > 1 ) or ' This variable is ' } set incorrectly: "
+ " \n " . join ( incorrect )
" [green]Do you want to automatically overwrite incorrect variables and add the missing variables? (y/n) "
)
success = False
# if success is True:
# return True
# console.print("[green]Do you want to enter the missing variables by hand(y/n)")
# if not input().casefold().startswith("y"):
# console.print("[red]Aborting: Unresolved missing variables")
# return success
# with open(".env", "a") as env_file:
# for env in missing:
# pass
return success
if not input ( ) . casefold ( ) . startswith ( " y " ) :
console . print ( " [red]Aborting: Unresolved missing variables " )
return False
if len ( incorrect ) :
with open ( " .env " , " r+ " ) as env_file :
lines = [ ]
for line in env_file . readlines ( ) :
line . split ( " = " ) [ 0 ] . strip ( ) not in incorrect and lines . append ( line )
env_file . seek ( 0 )
env_file . write ( " \n " . join ( lines ) )
env_file . truncate ( )
console . print ( " [green]Successfully removed incorrectly set variables from .env " )
with open ( " .env " , " a " ) as env_file :
for env in missing :
env_file . write (
env
+ " = "
+ ( ' " ' if env not in types . keys ( ) else " " )
+ str (
handle_input (
" [#F7768E bold] " + env + " [#C0CAF5 bold]= " ,
types [ env ] if env in types . keys ( ) else False ,
matching [ env ] if env in matching . keys ( ) else " .* " ,
explanations [ env ]
if env in explanations . keys ( )
else " Incorrect input. Try again. " ,
bounds [ env ] [ 0 ] if env in bounds . keys ( ) else None ,
bounds [ env ] [ 1 ] if env in bounds . keys ( ) and len ( bounds [ env ] ) > 1 else None ,
oob_errors [ env ] if env in oob_errors . keys ( ) else " Input too long/short. " ,
extra_info = " [#C0CAF5 bold]⮶ "
+ (
explanations [ env ] if env in explanations . keys ( ) else " No info available "
) ,
)
)
+ ( ' " ' if env not in types . keys ( ) else " " )
+ " \n "
)
return True
if __name__ == " __main__ " :