Source code for env_check.core

import os
import json
import locale

try:
    import yaml
except ImportError:
    yaml = None

try:
    import tomllib  # Python 3.11+
except ImportError:
    try:
        import toml
    except ImportError:
        toml = None
        tomllib = None

import configparser
import xml.etree.ElementTree as ET

[docs] def generate_schema(env_file=".env", schema_file="schema.json"): schema = {} with open(env_file) as f: for line in f: line = line.strip() if not line or line.startswith("#"): continue key, _, value = line.partition("=") schema[key] = {"required": True, "default": value} with open(schema_file, "w") as f: json.dump(schema, f, indent=2) print(f"Schema saved to {schema_file}")
# def validate_schema(schema_file="schema.json", env_file=".env"): # with open(schema_file) as f: # schema = json.load(f) # with open(env_file) as f: # env_vars = dict(line.strip().split("=", 1) for line in f if "=" in line and not line.startswith("#")) # missing = [key for key, props in schema.items() if props.get("required") and key not in env_vars] # if missing: # print(f"Missing variables: {', '.join(missing)}") # else: # print("All required variables are present")
[docs] def load_schema(schema_file): ext = os.path.splitext(schema_file)[1].lower() with open(schema_file, "rb") as f: if ext in (".json", ""): return json.load(f) elif ext in (".yaml", ".yml"): if not yaml: raise ImportError("PyYAML not installed. Install with `pip install pyyaml`.") return yaml.safe_load(f) elif ext in (".toml",): if tomllib: return tomllib.load(f) elif toml: return toml.load(f) else: raise ImportError("No TOML parser available. Install `toml` or use Python 3.11+.") elif ext in (".ini",): config = configparser.ConfigParser() config.read(schema_file, encoding="utf-8") # Convert ConfigParser to a dict return {section: dict(config[section]) for section in config.sections()} elif ext in (".xml",): tree = ET.parse(f) root = tree.getroot() def xml_to_dict(element): return { "tag": element.tag, "attributes": element.attrib, "text": element.text.strip() if element.text else None, "children": [xml_to_dict(e) for e in element] } return xml_to_dict(root) else: raise ValueError(f"Unsupported schema format: {ext}")
[docs] def validate_schema(schema_file="schema.json", env_file=".env"): schema = load_schema(schema_file) with open(env_file) as f: env_vars = dict( line.strip().split("=", 1) for line in f if "=" in line and not line.startswith("#") ) missing = [ key for key, props in schema.items() if isinstance(props, dict) and props.get("required") and key not in env_vars ] if missing: print(f"Missing variables: {', '.join(missing)}") else: print("All required variables are present")
# def check_unused(env_file=".env", project_path="."): # with open(env_file) as f: # env_vars = [line.strip().split("=")[0] for line in f if "=" in line and not line.startswith("#")] # unused = [] # for var in env_vars: # found = False # for root, _, files in os.walk(project_path): # for file in files: # if file.endswith((".py", ".txt", ".md")): # with open(os.path.join(root, file)) as f: # if var in f.read(): # found = True # break # if found: # break # if not found: # unused.append(var) # if unused: # print(f"Unused variables: {', '.join(unused)}") # else: # print("No unused variables found")
[docs] def check_unused(env_file=".env", project_path="."): # Detect system default encoding (e.g., cp1252 on Windows) system_encoding = locale.getpreferredencoding(False) encodings_to_try = ["utf-8", system_encoding, "latin-1", "utf-16"] # Read environment variables with open(env_file, encoding="utf-8") as f: # .env files are usually utf-8 env_vars = [line.strip().split("=")[0] for line in f if "=" in line and not line.startswith("#")] unused = [] for var in env_vars: found = False for root, _, files in os.walk(project_path): for file in files: if file.endswith((".py", ".txt", ".md")): file_path = os.path.join(root, file) # Try multiple encodings for enc in encodings_to_try: try: with open(file_path, encoding=enc) as f: if var in f.read(): found = True break except UnicodeDecodeError: continue # try next encoding if found: break if found: break if not found: unused.append(var) if unused: print(f"Unused variables: {', '.join(unused)}") else: print("No unused variables found")