Initial commit: env-guard CLI tool with CI/CD
This commit is contained in:
165
src/main.rs
Normal file
165
src/main.rs
Normal file
@@ -0,0 +1,165 @@
|
||||
use clap::{Command, Arg};
|
||||
use anyhow::Result;
|
||||
|
||||
mod config;
|
||||
mod env_parser;
|
||||
mod validation;
|
||||
mod secrets;
|
||||
mod framework;
|
||||
mod commands;
|
||||
|
||||
use commands::{scan, validate, generate, secrets_cmd, init, check};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let matches = Command::new("env-guard")
|
||||
.version("0.1.0")
|
||||
.about("Automatically detect, validate, and secure environment variables")
|
||||
.subcommand_required(false)
|
||||
.arg_required_else_help(true)
|
||||
.subcommand(
|
||||
Command::new("scan")
|
||||
.about("Scan .env files and compare against expected variables")
|
||||
.arg(
|
||||
Arg::new("path")
|
||||
.short('p')
|
||||
.long("path")
|
||||
.value_name("PATH")
|
||||
.help("Path to scan for .env files")
|
||||
.default_value(".")
|
||||
)
|
||||
.arg(
|
||||
Arg::new("schema")
|
||||
.short('s')
|
||||
.long("schema")
|
||||
.value_name("FILE")
|
||||
.help("Path to schema file (.env.schema.json)")
|
||||
)
|
||||
)
|
||||
.subcommand(
|
||||
Command::new("validate")
|
||||
.about("Validate format of environment variable values")
|
||||
.arg(
|
||||
Arg::new("path")
|
||||
.short('p')
|
||||
.long("path")
|
||||
.value_name("FILE")
|
||||
.help("Path to .env file")
|
||||
.default_value(".env")
|
||||
)
|
||||
.arg(
|
||||
Arg::new("strict")
|
||||
.short('S')
|
||||
.long("strict")
|
||||
.help("Enable strict validation")
|
||||
.action(clap::ArgAction::SetTrue)
|
||||
)
|
||||
)
|
||||
.subcommand(
|
||||
Command::new("generate")
|
||||
.about("Generate .env.example file from .env")
|
||||
.arg(
|
||||
Arg::new("path")
|
||||
.short('p')
|
||||
.long("path")
|
||||
.value_name("FILE")
|
||||
.help("Path to .env file")
|
||||
.default_value(".env")
|
||||
)
|
||||
.arg(
|
||||
Arg::new("output")
|
||||
.short('o')
|
||||
.long("output")
|
||||
.value_name("FILE")
|
||||
.help("Output file path")
|
||||
.default_value(".env.example")
|
||||
)
|
||||
)
|
||||
.subcommand(
|
||||
Command::new("secrets")
|
||||
.about("Scan source code for accidentally committed secrets")
|
||||
.arg(
|
||||
Arg::new("path")
|
||||
.short('p')
|
||||
.long("path")
|
||||
.value_name("PATH")
|
||||
.help("Path to scan for secrets")
|
||||
.default_value(".")
|
||||
)
|
||||
.arg(
|
||||
Arg::new("strict")
|
||||
.short('S')
|
||||
.long("strict")
|
||||
.help("Enable strict secret detection")
|
||||
.action(clap::ArgAction::SetTrue)
|
||||
)
|
||||
)
|
||||
.subcommand(
|
||||
Command::new("init")
|
||||
.about("Initialize env-guard with framework detection")
|
||||
.arg(
|
||||
Arg::new("framework")
|
||||
.short('f')
|
||||
.long("framework")
|
||||
.value_name("FRAMEWORK")
|
||||
.help("Framework to use (nextjs, rails, django, node)")
|
||||
)
|
||||
.arg(
|
||||
Arg::new("path")
|
||||
.short('p')
|
||||
.long("path")
|
||||
.value_name("PATH")
|
||||
.help("Path to project directory")
|
||||
.default_value(".")
|
||||
)
|
||||
)
|
||||
.subcommand(
|
||||
Command::new("check")
|
||||
.about("Check .env file for common issues")
|
||||
.arg(
|
||||
Arg::new("path")
|
||||
.short('p')
|
||||
.long("path")
|
||||
.value_name("FILE")
|
||||
.help("Path to .env file")
|
||||
.default_value(".env")
|
||||
)
|
||||
)
|
||||
.get_matches();
|
||||
|
||||
match matches.subcommand() {
|
||||
Some(("scan", sub_matches)) => {
|
||||
let path = sub_matches.get_one::<String>("path").map(|s| s.as_str()).unwrap_or(".");
|
||||
let schema = sub_matches.get_one::<String>("schema").map(|s| s.as_str());
|
||||
scan(path, schema)?;
|
||||
}
|
||||
Some(("validate", sub_matches)) => {
|
||||
let path = sub_matches.get_one::<String>("path").map(|s| s.as_str()).unwrap_or(".env");
|
||||
let strict = sub_matches.get_flag("strict");
|
||||
validate(path, strict)?;
|
||||
}
|
||||
Some(("generate", sub_matches)) => {
|
||||
let path = sub_matches.get_one::<String>("path").map(|s| s.as_str()).unwrap_or(".env");
|
||||
let output = sub_matches.get_one::<String>("output").map(|s| s.as_str());
|
||||
generate(path, output)?;
|
||||
}
|
||||
Some(("secrets", sub_matches)) => {
|
||||
let path = sub_matches.get_one::<String>("path").map(|s| s.as_str()).unwrap_or(".");
|
||||
let strict = sub_matches.get_flag("strict");
|
||||
secrets_cmd(path, strict)?;
|
||||
}
|
||||
Some(("init", sub_matches)) => {
|
||||
let framework = sub_matches.get_one::<String>("framework").map(|s| s.as_str());
|
||||
let path = sub_matches.get_one::<String>("path").map(|s| s.as_str());
|
||||
init(framework, path)?;
|
||||
}
|
||||
Some(("check", sub_matches)) => {
|
||||
let path = sub_matches.get_one::<String>("path").map(|s| s.as_str()).unwrap_or(".env");
|
||||
check(path)?;
|
||||
}
|
||||
_ => {
|
||||
let _ = Command::new("env-guard").print_help();
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user