generated from pure_sagacity/rust-starter
bug fixes, but every cmd works!
This commit is contained in:
@@ -1,14 +1,16 @@
|
|||||||
use diesel::prelude::*;
|
use diesel::prelude::*;
|
||||||
use dotenvy::dotenv;
|
use dotenvy::dotenv;
|
||||||
use std::env;
|
|
||||||
|
|
||||||
pub mod models;
|
pub mod models;
|
||||||
pub mod schema;
|
pub mod schema;
|
||||||
|
|
||||||
pub fn establish_connection() -> SqliteConnection {
|
pub fn establish_connection(url: String) -> SqliteConnection {
|
||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
|
|
||||||
let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
|
let resolved_path = std::fs::canonicalize(&url)
|
||||||
SqliteConnection::establish(&database_url)
|
.map(|p| p.to_string_lossy().into_owned())
|
||||||
.unwrap_or_else(|_| panic!("Error connecting to {}", database_url))
|
.unwrap_or(url);
|
||||||
|
|
||||||
|
SqliteConnection::establish(&resolved_path)
|
||||||
|
.unwrap_or_else(|_| panic!("Error connecting to {}", &resolved_path))
|
||||||
}
|
}
|
||||||
|
|||||||
+47
-24
@@ -112,6 +112,9 @@ pub enum Commands {
|
|||||||
|
|
||||||
#[arg(short = 's', long = "shell", default_value = "sh")]
|
#[arg(short = 's', long = "shell", default_value = "sh")]
|
||||||
shell: Option<String>,
|
shell: Option<String>,
|
||||||
|
|
||||||
|
#[arg(short = 'c', long = "command")]
|
||||||
|
command: Option<String>,
|
||||||
},
|
},
|
||||||
#[command(alias = "add")]
|
#[command(alias = "add")]
|
||||||
Set {
|
Set {
|
||||||
@@ -194,11 +197,13 @@ pub enum ProjectCommands {
|
|||||||
Delete { name: String },
|
Delete { name: String },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DB_URL: &str = "/Users/Maaz/Documents/Git/harbor/crates/cli/harbor.db";
|
||||||
|
|
||||||
pub mod interactions {
|
pub mod interactions {
|
||||||
use super::db::establish_connection;
|
use super::DB_URL;
|
||||||
use super::db::models::Project;
|
use super::db::{establish_connection, models::Project};
|
||||||
use crate::Environment;
|
use crate::Environment;
|
||||||
use crate::db::schema::secrets::config;
|
use crate::db::schema::projects::id;
|
||||||
use diesel::dsl::{insert_into, update};
|
use diesel::dsl::{insert_into, update};
|
||||||
use diesel::result::{DatabaseErrorKind, Error as DieselError};
|
use diesel::result::{DatabaseErrorKind, Error as DieselError};
|
||||||
use diesel::{ExpressionMethods, OptionalExtension, QueryDsl, RunQueryDsl, SelectableHelper};
|
use diesel::{ExpressionMethods, OptionalExtension, QueryDsl, RunQueryDsl, SelectableHelper};
|
||||||
@@ -216,7 +221,7 @@ pub mod interactions {
|
|||||||
|
|
||||||
pub fn project_exists(proj_name: &str) -> Result<bool> {
|
pub fn project_exists(proj_name: &str) -> Result<bool> {
|
||||||
use super::db::schema::projects::dsl::{name, projects};
|
use super::db::schema::projects::dsl::{name, projects};
|
||||||
let mut conn = establish_connection();
|
let mut conn = establish_connection(DB_URL.to_string());
|
||||||
|
|
||||||
let existing_project = projects
|
let existing_project = projects
|
||||||
.filter(name.eq(proj_name))
|
.filter(name.eq(proj_name))
|
||||||
@@ -229,7 +234,7 @@ pub mod interactions {
|
|||||||
|
|
||||||
pub fn create_project(proj_name: &str) -> Result<()> {
|
pub fn create_project(proj_name: &str) -> Result<()> {
|
||||||
use super::db::schema::projects::dsl::{created_at, id, name, projects};
|
use super::db::schema::projects::dsl::{created_at, id, name, projects};
|
||||||
let mut conn = establish_connection();
|
let mut conn = establish_connection(DB_URL.to_string());
|
||||||
|
|
||||||
if project_exists(proj_name)? {
|
if project_exists(proj_name)? {
|
||||||
return construct_error("Project already exists");
|
return construct_error("Project already exists");
|
||||||
@@ -255,7 +260,7 @@ pub mod interactions {
|
|||||||
|
|
||||||
pub fn delete_project(proj_name: &str) -> Result<()> {
|
pub fn delete_project(proj_name: &str) -> Result<()> {
|
||||||
use super::db::schema::projects::dsl::{name, projects};
|
use super::db::schema::projects::dsl::{name, projects};
|
||||||
let mut conn = establish_connection();
|
let mut conn = establish_connection(DB_URL.to_string());
|
||||||
|
|
||||||
if !project_exists(proj_name)? {
|
if !project_exists(proj_name)? {
|
||||||
return construct_error("Project does not exist");
|
return construct_error("Project does not exist");
|
||||||
@@ -268,7 +273,7 @@ pub mod interactions {
|
|||||||
|
|
||||||
pub fn get_projects() -> Result<Vec<Project>> {
|
pub fn get_projects() -> Result<Vec<Project>> {
|
||||||
use super::db::schema::projects::dsl::projects;
|
use super::db::schema::projects::dsl::projects;
|
||||||
let mut conn = establish_connection();
|
let mut conn = establish_connection(DB_URL.to_string());
|
||||||
|
|
||||||
let results = projects
|
let results = projects
|
||||||
.select(Project::as_select())
|
.select(Project::as_select())
|
||||||
@@ -277,18 +282,28 @@ pub mod interactions {
|
|||||||
Ok(results)
|
Ok(results)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn secret_exists() -> Result<bool> {
|
pub fn secret_exists(
|
||||||
use super::db::schema::secrets::dsl::{id, secrets};
|
proj_id: &str,
|
||||||
let mut conn = establish_connection();
|
secret_name: &str,
|
||||||
|
environment: Environment,
|
||||||
|
) -> Result<bool> {
|
||||||
|
use super::db::schema::secrets::dsl::{config, id, name, project_id, secrets};
|
||||||
|
let mut conn = establish_connection(DB_URL.to_string());
|
||||||
|
|
||||||
let existing_secret = secrets.select(id).first::<String>(&mut conn).optional()?;
|
let existing_secret = secrets
|
||||||
|
.filter(project_id.eq(proj_id))
|
||||||
|
.filter(name.eq(secret_name))
|
||||||
|
.filter(config.eq(environment))
|
||||||
|
.select(id)
|
||||||
|
.first::<String>(&mut conn)
|
||||||
|
.optional()?;
|
||||||
|
|
||||||
Ok(existing_secret.is_some())
|
Ok(existing_secret.is_some())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_project_id(proj_name: &str) -> Result<String> {
|
pub fn get_project_id(proj_name: &str) -> Result<String> {
|
||||||
use super::db::schema::projects::dsl::{id, name, projects};
|
use super::db::schema::projects::dsl::{id, name, projects};
|
||||||
let mut conn = establish_connection();
|
let mut conn = establish_connection(DB_URL.to_string());
|
||||||
|
|
||||||
let project_id = projects
|
let project_id = projects
|
||||||
.filter(name.eq(proj_name))
|
.filter(name.eq(proj_name))
|
||||||
@@ -313,17 +328,20 @@ pub mod interactions {
|
|||||||
non: crypto::Nonce,
|
non: crypto::Nonce,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
use super::db::schema::secrets::dsl::{
|
use super::db::schema::secrets::dsl::{
|
||||||
config, created_at, name, nonce, project_id, secret, secrets,
|
config, created_at, id, name, nonce, project_id, secret, secrets,
|
||||||
};
|
};
|
||||||
let mut conn = establish_connection();
|
let mut conn = establish_connection(DB_URL.to_string());
|
||||||
|
|
||||||
|
if secret_exists(proj_id, secret_name, conf)? {
|
||||||
|
return Err(Box::new(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::AlreadyExists,
|
||||||
|
"Secret already exists",
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
if secret_exists()? {
|
|
||||||
update(secrets.filter(name.eq(secret_name)))
|
|
||||||
.set(secret.eq(secret_value))
|
|
||||||
.execute(&mut conn)?;
|
|
||||||
} else {
|
|
||||||
insert_into(secrets)
|
insert_into(secrets)
|
||||||
.values((
|
.values((
|
||||||
|
id.eq(Uuid::new_v4().to_string()),
|
||||||
name.eq(secret_name),
|
name.eq(secret_name),
|
||||||
secret.eq(secret_value),
|
secret.eq(secret_value),
|
||||||
project_id.eq(proj_id),
|
project_id.eq(proj_id),
|
||||||
@@ -332,7 +350,6 @@ pub mod interactions {
|
|||||||
created_at.eq(chrono::Utc::now().naive_utc()),
|
created_at.eq(chrono::Utc::now().naive_utc()),
|
||||||
))
|
))
|
||||||
.execute(&mut conn)?;
|
.execute(&mut conn)?;
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -342,7 +359,7 @@ pub mod interactions {
|
|||||||
environment: Environment,
|
environment: Environment,
|
||||||
) -> Result<Vec<(String, Vec<u8>, Vec<u8>)>> {
|
) -> Result<Vec<(String, Vec<u8>, Vec<u8>)>> {
|
||||||
use super::db::schema::secrets::dsl::{config, name, nonce, project_id, secret, secrets};
|
use super::db::schema::secrets::dsl::{config, name, nonce, project_id, secret, secrets};
|
||||||
let mut conn = establish_connection();
|
let mut conn = establish_connection(DB_URL.to_string());
|
||||||
|
|
||||||
let results = secrets
|
let results = secrets
|
||||||
.filter(project_id.eq(proj_id))
|
.filter(project_id.eq(proj_id))
|
||||||
@@ -354,10 +371,16 @@ pub mod interactions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_secret(secret_name: &str) -> Result<()> {
|
pub fn delete_secret(secret_name: &str) -> Result<()> {
|
||||||
use super::db::schema::secrets::dsl::{name, secrets};
|
use super::db::schema::secrets::dsl::{id, name, secrets};
|
||||||
let mut conn = establish_connection();
|
let mut conn = establish_connection(DB_URL.to_string());
|
||||||
|
|
||||||
if !secret_exists()? {
|
let existing_secret = secrets
|
||||||
|
.filter(name.eq(secret_name))
|
||||||
|
.select(id)
|
||||||
|
.first::<String>(&mut conn)
|
||||||
|
.optional()?;
|
||||||
|
|
||||||
|
if existing_secret.is_none() {
|
||||||
return Err(Box::new(std::io::Error::new(
|
return Err(Box::new(std::io::Error::new(
|
||||||
std::io::ErrorKind::NotFound,
|
std::io::ErrorKind::NotFound,
|
||||||
"Secret does not exist",
|
"Secret does not exist",
|
||||||
|
|||||||
+16
-16
@@ -45,13 +45,6 @@ fn main() {
|
|||||||
let config_path = root.join(".harbor.toml");
|
let config_path = root.join(".harbor.toml");
|
||||||
let has_config = config_path.exists();
|
let has_config = config_path.exists();
|
||||||
|
|
||||||
if !has_config {
|
|
||||||
eprintln!(
|
|
||||||
"{}",
|
|
||||||
"Warning: .harbor.toml not found. Some commands are disabled.".yellow()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
match cli.command {
|
match cli.command {
|
||||||
Some(c) => match c {
|
Some(c) => match c {
|
||||||
_ if requires_config(&c) && !has_config => {
|
_ if requires_config(&c) && !has_config => {
|
||||||
@@ -223,11 +216,6 @@ fn main() {
|
|||||||
cmd.env(key, value);
|
cmd.env(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmd.spawn().is_err() {
|
|
||||||
eprintln!("Error executing command: {:?}", after);
|
|
||||||
process::exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if cmd.status().is_err() {
|
if cmd.status().is_err() {
|
||||||
eprintln!("Error waiting for command to finish: {:?}", after);
|
eprintln!("Error waiting for command to finish: {:?}", after);
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
@@ -347,7 +335,11 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Commands::Shell { environment, shell } => {
|
Commands::Shell {
|
||||||
|
environment,
|
||||||
|
shell,
|
||||||
|
command,
|
||||||
|
} => {
|
||||||
let config = require_config(&root);
|
let config = require_config(&root);
|
||||||
let environment: Environment = match environment {
|
let environment: Environment = match environment {
|
||||||
Some(env) => match env.parse::<Environment>() {
|
Some(env) => match env.parse::<Environment>() {
|
||||||
@@ -372,11 +364,16 @@ fn main() {
|
|||||||
|
|
||||||
let shell = shell
|
let shell = shell
|
||||||
.or_else(|| std::env::var("SHELL").ok())
|
.or_else(|| std::env::var("SHELL").ok())
|
||||||
.or_else(|| Some("sh".into()))
|
.or_else(|| Some("/bin/sh".into()))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut cmd = process::Command::new(&shell);
|
let mut cmd = process::Command::new(&shell);
|
||||||
|
|
||||||
|
if let Some(command) = command {
|
||||||
|
cmd.arg("-c");
|
||||||
|
cmd.arg(command);
|
||||||
|
}
|
||||||
|
|
||||||
let secrets = match get_project_secrets(&proj_id, environment) {
|
let secrets = match get_project_secrets(&proj_id, environment) {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -422,12 +419,15 @@ fn main() {
|
|||||||
cmd.env(key, value);
|
cmd.env(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmd.spawn().is_err() {
|
let mut child = match cmd.spawn() {
|
||||||
|
Ok(c) => c,
|
||||||
|
Err(_) => {
|
||||||
eprintln!("Error executing command: {:?}", &shell);
|
eprintln!("Error executing command: {:?}", &shell);
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if cmd.status().is_err() {
|
if child.wait().is_err() {
|
||||||
eprintln!("Error waiting for command to finish: {:?}", &shell);
|
eprintln!("Error waiting for command to finish: {:?}", &shell);
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
sqlite
|
sqlite
|
||||||
];
|
];
|
||||||
|
|
||||||
|
env.RUST_BACKTRACE = "1";
|
||||||
|
|
||||||
languages.rust = {
|
languages.rust = {
|
||||||
enable = true;
|
enable = true;
|
||||||
lsp.enable = true;
|
lsp.enable = true;
|
||||||
|
|||||||
Reference in New Issue
Block a user