ci: Preparing the repo to go public
This commit is contained in:
+1
-1
@@ -1,5 +1,5 @@
|
||||
use crate::command::preview_command;
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use anyhow::{Context, Result, anyhow};
|
||||
use gman::config::{Config, ProviderConfig, RunConfig};
|
||||
use gman::providers::SecretProvider;
|
||||
use heck::ToSnakeCase;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use clap::{
|
||||
crate_authors, crate_description, crate_name, crate_version, CommandFactory, Parser, ValueEnum,
|
||||
CommandFactory, Parser, ValueEnum, crate_authors, crate_description, crate_name, crate_version,
|
||||
};
|
||||
use std::ffi::OsString;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use clap::Subcommand;
|
||||
use crossterm::execute;
|
||||
use crossterm::terminal::{disable_raw_mode, LeaveAlternateScreen};
|
||||
use crossterm::terminal::{LeaveAlternateScreen, disable_raw_mode};
|
||||
use gman::config::load_config;
|
||||
use heck::ToSnakeCase;
|
||||
use std::io::{self, IsTerminal, Read, Write};
|
||||
|
||||
+18
-14
@@ -25,7 +25,7 @@ use anyhow::Result;
|
||||
use log::debug;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::serde_as;
|
||||
use serde_with::{skip_serializing_none, DisplayFromStr};
|
||||
use serde_with::{DisplayFromStr, skip_serializing_none};
|
||||
use std::borrow::Cow;
|
||||
use std::path::PathBuf;
|
||||
use validator::{Validate, ValidationError};
|
||||
@@ -188,19 +188,23 @@ pub struct Config {
|
||||
}
|
||||
|
||||
fn default_provider_exists(config: &Config) -> Result<(), ValidationError> {
|
||||
if let Some(default) = &config.default_provider {
|
||||
if config.providers.iter().any(|p| p.name.as_deref() == Some(default)) {
|
||||
Ok(())
|
||||
} else {
|
||||
let mut err = ValidationError::new("default_provider_missing");
|
||||
err.message = Some(Cow::Borrowed(
|
||||
"The default_provider does not match any configured provider names",
|
||||
));
|
||||
Err(err)
|
||||
}
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
if let Some(default) = &config.default_provider {
|
||||
if config
|
||||
.providers
|
||||
.iter()
|
||||
.any(|p| p.name.as_deref() == Some(default))
|
||||
{
|
||||
Ok(())
|
||||
} else {
|
||||
let mut err = ValidationError::new("default_provider_missing");
|
||||
err.message = Some(Cow::Borrowed(
|
||||
"The default_provider does not match any configured provider names",
|
||||
));
|
||||
Err(err)
|
||||
}
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
|
||||
+4
-4
@@ -20,15 +20,15 @@
|
||||
//! The `config` and `providers` modules power the CLI. They can be embedded
|
||||
//! in other programs, but many functions interact with the user or the
|
||||
//! filesystem. Prefer `no_run` doctests for those.
|
||||
use anyhow::{anyhow, bail, Context, Result};
|
||||
use anyhow::{Context, Result, anyhow, bail};
|
||||
use argon2::{
|
||||
password_hash::{rand_core::RngCore, SaltString},
|
||||
Algorithm, Argon2, Params, Version,
|
||||
password_hash::{SaltString, rand_core::RngCore},
|
||||
};
|
||||
use base64::{engine::general_purpose::STANDARD as B64, Engine as _};
|
||||
use base64::{Engine as _, engine::general_purpose::STANDARD as B64};
|
||||
use chacha20poly1305::{
|
||||
aead::{Aead, KeyInit, OsRng},
|
||||
Key, XChaCha20Poly1305, XNonce,
|
||||
aead::{Aead, KeyInit, OsRng},
|
||||
};
|
||||
use secrecy::{ExposeSecret, SecretString};
|
||||
use zeroize::Zeroize;
|
||||
|
||||
+25
-14
@@ -4,9 +4,9 @@ use dialoguer::Confirm;
|
||||
use dialoguer::theme::ColorfulTheme;
|
||||
use indoc::formatdoc;
|
||||
use log::debug;
|
||||
use std::{env, fs};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Command, Stdio};
|
||||
use std::{env, fs};
|
||||
use validator::Validate;
|
||||
|
||||
#[derive(Debug, Validate, Clone)]
|
||||
@@ -41,11 +41,17 @@ pub fn sync_and_push(opts: &SyncOpts<'_>) -> Result<()> {
|
||||
.with_context(|| "get default vault path")?;
|
||||
let repo_vault = repo_dir.join("vault.yml");
|
||||
if default_vault.exists() && !repo_vault.exists() {
|
||||
fs::rename(&default_vault, &repo_vault)
|
||||
.with_context(|| format!("move {} -> {}", default_vault.display(), repo_vault.display()))?;
|
||||
fs::rename(&default_vault, &repo_vault).with_context(|| {
|
||||
format!(
|
||||
"move {} -> {}",
|
||||
default_vault.display(),
|
||||
repo_vault.display()
|
||||
)
|
||||
})?;
|
||||
} else if !repo_vault.exists() {
|
||||
// Ensure an empty vault exists to allow initial commits
|
||||
fs::write(&repo_vault, "{}\n").with_context(|| format!("create {}", repo_vault.display()))?;
|
||||
fs::write(&repo_vault, "{}\n")
|
||||
.with_context(|| format!("create {}", repo_vault.display()))?;
|
||||
}
|
||||
|
||||
let git = resolve_git(opts.git_executable.as_ref())?;
|
||||
@@ -250,7 +256,7 @@ fn stage_vault_only(git: &Path, repo: &Path) -> Result<()> {
|
||||
|
||||
fn fetch_and_pull(git: &Path, repo: &Path, branch: &str) -> Result<()> {
|
||||
// Fetch all refs from origin (safe even if branch doesn't exist remotely)
|
||||
run_git(git, repo, &["fetch", "origin", "--prune"])
|
||||
run_git(git, repo, &["fetch", "origin", "--prune"])
|
||||
.with_context(|| "Failed to fetch changes from remote")?;
|
||||
|
||||
let origin_ref = format!("origin/{branch}");
|
||||
@@ -265,19 +271,16 @@ fn fetch_and_pull(git: &Path, repo: &Path, branch: &str) -> Result<()> {
|
||||
.with_context(|| "Failed to checkout remote branch over local state")?;
|
||||
run_git(git, repo, &["reset", "--hard", &origin_ref])
|
||||
.with_context(|| "Failed to hard reset to remote branch")?;
|
||||
run_git(git, repo, &["clean", "-fd"]).with_context(|| "Failed to clean untracked files")?;
|
||||
run_git(git, repo, &["clean", "-fd"])
|
||||
.with_context(|| "Failed to clean untracked files")?;
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// If we have local history and the remote branch exists, fast-forward.
|
||||
if remote_has_branch {
|
||||
run_git(
|
||||
git,
|
||||
repo,
|
||||
&["merge", "--ff-only", &origin_ref],
|
||||
)
|
||||
.with_context(|| "Failed to merge remote changes")?;
|
||||
run_git(git, repo, &["merge", "--ff-only", &origin_ref])
|
||||
.with_context(|| "Failed to merge remote changes")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -286,7 +289,12 @@ fn has_remote_branch(git: &Path, repo: &Path, branch: &str) -> bool {
|
||||
Command::new(git)
|
||||
.arg("-C")
|
||||
.arg(repo)
|
||||
.args(["show-ref", "--verify", "--quiet", &format!("refs/remotes/origin/{}", branch)])
|
||||
.args([
|
||||
"show-ref",
|
||||
"--verify",
|
||||
"--quiet",
|
||||
&format!("refs/remotes/origin/{}", branch),
|
||||
])
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.status()
|
||||
@@ -399,7 +407,10 @@ mod tests {
|
||||
#[test]
|
||||
fn test_repo_name_from_url() {
|
||||
assert_eq!(repo_name_from_url("git@github.com:user/vault.git"), "vault");
|
||||
assert_eq!(repo_name_from_url("https://github.com/user/test-vault.git"), "test-vault");
|
||||
assert_eq!(
|
||||
repo_name_from_url("https://github.com/user/test-vault.git"),
|
||||
"test-vault"
|
||||
);
|
||||
assert_eq!(repo_name_from_url("ssh://git@example.com/x/y/z.git"), "z");
|
||||
assert_eq!(repo_name_from_url("git@example.com:ns/repo"), "repo");
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use anyhow::{anyhow, bail, Context};
|
||||
use anyhow::{Context, anyhow, bail};
|
||||
use secrecy::{ExposeSecret, SecretString};
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
@@ -6,20 +6,20 @@ use std::path::{Path, PathBuf};
|
||||
use zeroize::Zeroize;
|
||||
|
||||
use crate::config::ProviderConfig;
|
||||
use crate::providers::git_sync::{repo_name_from_url, sync_and_push, SyncOpts};
|
||||
use crate::providers::SecretProvider;
|
||||
use crate::providers::git_sync::{SyncOpts, repo_name_from_url, sync_and_push};
|
||||
use crate::{
|
||||
ARGON_M_COST_KIB, ARGON_P, ARGON_T_COST, HEADER, KDF, KEY_LEN, NONCE_LEN, SALT_LEN, VERSION,
|
||||
};
|
||||
use anyhow::Result;
|
||||
use argon2::{Algorithm, Argon2, Params, Version};
|
||||
use base64::{engine::general_purpose::STANDARD as B64, Engine as _};
|
||||
use base64::{Engine as _, engine::general_purpose::STANDARD as B64};
|
||||
use chacha20poly1305::aead::rand_core::RngCore;
|
||||
use chacha20poly1305::{
|
||||
aead::{Aead, KeyInit, OsRng},
|
||||
Key, XChaCha20Poly1305, XNonce,
|
||||
aead::{Aead, KeyInit, OsRng},
|
||||
};
|
||||
use dialoguer::{theme, Input};
|
||||
use dialoguer::{Input, theme};
|
||||
use log::{debug, error};
|
||||
use serde::Deserialize;
|
||||
use theme::ColorfulTheme;
|
||||
|
||||
@@ -16,7 +16,7 @@ pub mod local;
|
||||
|
||||
use crate::config::ProviderConfig;
|
||||
use crate::providers::local::LocalProvider;
|
||||
use anyhow::{anyhow, Result};
|
||||
use anyhow::{Result, anyhow};
|
||||
use serde::Deserialize;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::str::FromStr;
|
||||
|
||||
Reference in New Issue
Block a user