mirror of
https://codeberg.org/icewind/haze.git
synced 2026-06-03 17:14:08 +02:00
add command to checkout branch in all apps
This commit is contained in:
parent
f0bd58a17a
commit
5278f0d295
5 changed files with 191 additions and 0 deletions
13
src/args.rs
13
src/args.rs
|
|
@ -61,6 +61,9 @@ pub enum HazeArgs {
|
|||
filter: Option<String>,
|
||||
},
|
||||
Proxy,
|
||||
Checkout {
|
||||
branch: String,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
|
|
@ -212,6 +215,13 @@ impl HazeArgs {
|
|||
HazeCommand::Pin => Ok(HazeArgs::Pin { filter }),
|
||||
HazeCommand::Unpin => Ok(HazeArgs::Unpin { filter }),
|
||||
HazeCommand::Proxy => Ok(HazeArgs::Proxy),
|
||||
HazeCommand::Checkout => {
|
||||
let branch = args
|
||||
.next()
|
||||
.map(S::into)
|
||||
.ok_or_else(|| Report::msg("No branch provided"))?;
|
||||
Ok(HazeArgs::Checkout { branch })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -234,6 +244,7 @@ pub enum HazeCommand {
|
|||
Pin,
|
||||
Unpin,
|
||||
Proxy,
|
||||
Checkout,
|
||||
}
|
||||
|
||||
impl FromStr for HazeCommand {
|
||||
|
|
@ -258,6 +269,7 @@ impl FromStr for HazeCommand {
|
|||
"pin" => Ok(HazeCommand::Pin),
|
||||
"unpin" => Ok(HazeCommand::Unpin),
|
||||
"proxy" => Ok(HazeCommand::Proxy),
|
||||
"checkout" => Ok(HazeCommand::Checkout),
|
||||
_ => Err(Report::msg(format!("Unknown command: {}", s))),
|
||||
}
|
||||
}
|
||||
|
|
@ -282,6 +294,7 @@ impl HazeCommand {
|
|||
HazeCommand::Pin => true,
|
||||
HazeCommand::Unpin => true,
|
||||
HazeCommand::Proxy => false,
|
||||
HazeCommand::Checkout => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
91
src/git.rs
Normal file
91
src/git.rs
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
use crate::Result;
|
||||
use miette::{miette, IntoDiagnostic};
|
||||
use std::fs::read_dir;
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
use tracing::error;
|
||||
|
||||
pub fn checkout_all<P: AsRef<Path>>(sources_root: P, branch: &str) -> Result<()> {
|
||||
let apps_dir = sources_root.as_ref().join("apps");
|
||||
for app in read_dir(apps_dir).into_diagnostic()? {
|
||||
let app = app.into_diagnostic()?;
|
||||
if app.metadata().into_diagnostic()?.is_dir() {
|
||||
let app_dir = app.path();
|
||||
if has_branch(&app_dir, &branch).unwrap_or_default()
|
||||
&& get_branch(&app_dir).unwrap_or_default().trim() != branch
|
||||
{
|
||||
print!("{}", app.file_name().to_string_lossy());
|
||||
if let Err(e) = checkout(&app_dir, &branch) {
|
||||
println!(": {} ❌", e);
|
||||
} else {
|
||||
println!(" ✓");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn has_branch<P: AsRef<Path>>(repo: P, branch: &str) -> Result<bool> {
|
||||
let output = Command::new("git")
|
||||
.current_dir(repo)
|
||||
.arg("branch")
|
||||
.arg("-a")
|
||||
.output()
|
||||
.into_diagnostic()?;
|
||||
let stdout = String::from_utf8(output.stdout).into_diagnostic()?;
|
||||
let stderr = String::from_utf8(output.stderr).into_diagnostic()?;
|
||||
if output.status.code().unwrap_or_default() != 0 {
|
||||
error!(stdout = stdout, stderr = stderr, "git command failed");
|
||||
}
|
||||
|
||||
for line in stdout.split("\n") {
|
||||
let line = line.trim();
|
||||
if line == branch {
|
||||
return Ok(true);
|
||||
}
|
||||
if let Some((_, part)) = line.rsplit_once('/') {
|
||||
if part == branch {
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
fn checkout<P: AsRef<Path>>(repo: P, branch: &str) -> Result<()> {
|
||||
let output = Command::new("git")
|
||||
.current_dir(repo)
|
||||
.arg("checkout")
|
||||
.arg(branch)
|
||||
.output()
|
||||
.into_diagnostic()?;
|
||||
|
||||
let stdout = String::from_utf8(output.stdout).into_diagnostic()?;
|
||||
let stderr = String::from_utf8(output.stderr).into_diagnostic()?;
|
||||
let code = output.status.code().unwrap_or_default();
|
||||
if code != 0 {
|
||||
if stderr.contains("would be overwritten") {
|
||||
return Err(miette!("uncommited changes"));
|
||||
}
|
||||
error!(
|
||||
stdout = stdout,
|
||||
stderr = stderr,
|
||||
code = code,
|
||||
"git command failed"
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_branch<P: AsRef<Path>>(repo: P) -> Result<String> {
|
||||
let output = Command::new("git")
|
||||
.current_dir(repo)
|
||||
.arg("rev-parse")
|
||||
.arg("--abbrev-ref")
|
||||
.arg("HEAD")
|
||||
.output()
|
||||
.into_diagnostic()?;
|
||||
String::from_utf8(output.stdout).into_diagnostic()
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ use crate::args::{ExecService, HazeArgs};
|
|||
use crate::cloud::{Cloud, CloudOptions};
|
||||
use crate::config::HazeConfig;
|
||||
use crate::exec::container_logs;
|
||||
use crate::git::checkout_all;
|
||||
use crate::network::clear_networks;
|
||||
use crate::php::PhpVersion;
|
||||
use crate::proxy::proxy;
|
||||
|
|
@ -16,6 +17,7 @@ mod cloud;
|
|||
mod config;
|
||||
mod database;
|
||||
mod exec;
|
||||
mod git;
|
||||
mod image;
|
||||
mod mapping;
|
||||
mod network;
|
||||
|
|
@ -26,6 +28,7 @@ mod service;
|
|||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
miette::set_panic_hook();
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
let mut docker = Docker::connect_with_local_defaults()
|
||||
.into_diagnostic()
|
||||
|
|
@ -290,6 +293,9 @@ async fn main() -> Result<()> {
|
|||
HazeArgs::Proxy => {
|
||||
proxy(docker, config).await?;
|
||||
}
|
||||
HazeArgs::Checkout { branch } => {
|
||||
checkout_all(&config.sources_root, &branch)?;
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue