1
0
Fork 0
mirror of https://codeberg.org/icewind/haze.git synced 2026-06-03 09:04:12 +02:00

add formatting command

This commit is contained in:
Robin Appelman 2021-06-23 16:50:09 +02:00
commit 2627bb9427
6 changed files with 125 additions and 13 deletions

View file

@ -42,6 +42,9 @@ pub enum HazeArgs {
Open {
filter: Option<String>,
},
Fmt {
path: String,
},
}
#[derive(Debug, Clone, Eq, PartialEq)]
@ -144,6 +147,13 @@ impl HazeArgs {
})
}
HazeCommand::Open => Ok(HazeArgs::Open { filter }),
HazeCommand::Fmt => {
let path = args
.next()
.map(S::into)
.ok_or_else(|| Report::msg("No path provided"))?;
Ok(HazeArgs::Fmt { path })
}
}
}
}
@ -160,6 +170,7 @@ pub enum HazeCommand {
Clean,
Logs,
Open,
Fmt,
}
impl FromStr for HazeCommand {
@ -177,6 +188,8 @@ impl FromStr for HazeCommand {
"clean" => Ok(HazeCommand::Clean),
"logs" => Ok(HazeCommand::Logs),
"open" => Ok(HazeCommand::Open),
"fmt" => Ok(HazeCommand::Fmt),
"format" => Ok(HazeCommand::Fmt),
_ => Err(Report::msg(format!("Unknown command: {}", s))),
}
}
@ -195,6 +208,7 @@ impl HazeCommand {
HazeCommand::Clean => false,
HazeCommand::Logs => true,
HazeCommand::Open => true,
HazeCommand::Fmt => false,
}
}
}

View file

@ -1,6 +1,6 @@
use crate::config::HazeConfig;
use crate::database::Database;
use crate::exec::{exec, exec_tty};
use crate::exec::{exec, exec_tty, ExitCode};
use crate::mapping::{default_mappings, Mapping};
use crate::php::PhpVersion;
use crate::service::Service;
@ -15,7 +15,7 @@ use petname::petname;
use std::collections::HashMap;
use std::fmt::Display;
use std::fs;
use std::io::stdout;
use std::io::{stdout, Write};
use std::iter::Peekable;
use std::net::IpAddr;
use std::os::unix::fs::MetadataExt;
@ -302,7 +302,7 @@ impl Cloud {
docker: &mut Docker,
cmd: Vec<S>,
tty: bool,
) -> Result<i64> {
) -> Result<ExitCode> {
if tty {
exec_tty(docker, &self.id, "haze", cmd, vec![]).await
} else {
@ -310,6 +310,15 @@ impl Cloud {
}
}
pub async fn exec_with_output<S: Into<String>>(
&self,
docker: &mut Docker,
cmd: Vec<S>,
output: Option<impl Write>,
) -> Result<ExitCode> {
exec(docker, &self.id, "haze", cmd, vec![], output).await
}
pub async fn list(
docker: &mut Docker,
filter: Option<String>,

View file

@ -1,4 +1,4 @@
use crate::exec::{exec, exec_tty};
use crate::exec::{exec, exec_tty, ExitCode};
use crate::image::pull_image;
use bollard::container::{Config, CreateContainerOptions, NetworkingConfig};
use bollard::models::{EndpointSettings, HostConfig};
@ -215,7 +215,7 @@ impl Database {
cloud_id: &str,
cmd: Vec<S>,
tty: bool,
) -> Result<i64> {
) -> Result<ExitCode> {
let container = match self.family() {
DatabaseFamily::Sqlite => cloud_id.to_string(),
_ => format!("{}-db", cloud_id.to_string()),
@ -227,7 +227,7 @@ impl Database {
}
}
pub async fn exec(&self, docker: &mut Docker, cloud_id: &str, root: bool) -> Result<i64> {
pub async fn exec(&self, docker: &mut Docker, cloud_id: &str, root: bool) -> Result<ExitCode> {
match self.family() {
DatabaseFamily::Sqlite => {
exec_tty(

View file

@ -1,7 +1,7 @@
use bollard::container::LogsOptions;
use bollard::exec::{CreateExecOptions, ResizeExecOptions, StartExecResults};
use bollard::Docker;
use color_eyre::{eyre::WrapErr, Result};
use color_eyre::{eyre::WrapErr, Report, Result};
use futures_util::StreamExt;
use std::io::{stdout, Read, Write};
use std::time::Duration;
@ -17,7 +17,7 @@ pub async fn exec_tty<S1: AsRef<str>, S2: Into<String>>(
user: &str,
cmd: Vec<S2>,
env: Vec<&str>,
) -> Result<i64> {
) -> Result<ExitCode> {
let stdout = stdout();
if !is_tty(&stdout) {
@ -88,7 +88,8 @@ pub async fn exec_tty<S1: AsRef<str>, S2: Into<String>>(
.inspect_exec(&message.id)
.await?
.exit_code
.unwrap_or_default())
.unwrap_or_default()
.into())
}
pub async fn exec<S1: AsRef<str>, S2: Into<String>>(
@ -98,7 +99,7 @@ pub async fn exec<S1: AsRef<str>, S2: Into<String>>(
cmd: Vec<S2>,
env: Vec<&str>,
mut std_out: Option<impl Write>,
) -> Result<i64> {
) -> Result<ExitCode> {
let cmd = cmd.into_iter().map(S2::into).collect();
let env = env.into_iter().map(String::from).collect();
let config = CreateExecOptions {
@ -131,7 +132,8 @@ pub async fn exec<S1: AsRef<str>, S2: Into<String>>(
.inspect_exec(&message.id)
.await?
.exit_code
.unwrap_or_default())
.unwrap_or_default()
.into())
}
pub async fn container_logs(docker: &Docker, container: &str, count: usize) -> Result<Vec<String>> {
@ -150,3 +152,29 @@ pub async fn container_logs(docker: &Docker, container: &str, count: usize) -> R
}
Ok(logs)
}
pub struct ExitCode(i64);
impl ExitCode {
pub fn is_ok(&self) -> Result<()> {
match self.0 {
0 => Ok(()),
code => Err(Report::msg(format!(
"Command failed with exit code {}",
code
))),
}
}
}
impl PartialEq<i64> for ExitCode {
fn eq(&self, other: &i64) -> bool {
&self.0 == other
}
}
impl From<i64> for ExitCode {
fn from(code: i64) -> Self {
ExitCode(code)
}
}

View file

@ -1,5 +1,5 @@
use crate::args::{ExecService, HazeArgs};
use crate::cloud::Cloud;
use crate::cloud::{Cloud, CloudOptions};
use crate::config::HazeConfig;
use crate::exec::container_logs;
use crate::service::Service;
@ -203,6 +203,67 @@ async fn main() -> Result<()> {
cloud.exec(&mut docker, args, false).await?;
cloud.destroy(&mut docker).await?;
}
HazeArgs::Fmt { path } => {
let cloud = Cloud::create(&mut docker, CloudOptions::default(), &config).await?;
let mut out_buffer = Vec::<u8>::with_capacity(1024);
println!("Waiting for servers to start");
cloud.wait_for_start(&mut docker).await?;
println!("Installing composer");
if let Err(e) = cloud
.exec_with_output(
&mut docker,
vec!["composer", "install"],
Some(&mut out_buffer),
)
.await
.and_then(|c| c.is_ok())
{
eprintln!("{}", String::from_utf8_lossy(&out_buffer));
cloud.destroy(&mut docker).await?;
return Err(e);
}
out_buffer.clear();
println!("Formatting");
if let Err(e) = cloud
.exec(
&mut docker,
vec!["composer", "run", "cs:fix", path.as_str()],
false,
)
.await
{
cloud.destroy(&mut docker).await?;
return Err(e);
}
println!("Cleanup");
if let Err(e) = cloud
.exec_with_output(
&mut docker,
vec!["git", "clean", "-fd", "lib/composer"],
Some(&mut out_buffer),
)
.await
.and_then(|c| c.is_ok())
{
eprintln!("{}", String::from_utf8_lossy(&out_buffer));
cloud.destroy(&mut docker).await?;
return Err(e);
}
if let Err(e) = cloud
.exec_with_output(
&mut docker,
vec!["git", "checkout", "lib/composer"],
Some(&mut out_buffer),
)
.await
.and_then(|c| c.is_ok())
{
eprintln!("{}", String::from_utf8_lossy(&out_buffer));
cloud.destroy(&mut docker).await?;
return Err(e);
}
cloud.destroy(&mut docker).await?;
}
};
Ok(())

View file

@ -152,7 +152,7 @@ pub fn default_mappings<'a>() -> impl IntoIterator<Item = Mapping<'a>> {
.file()
.read_only(),
];
std::array::IntoIter::new(mappings)
IntoIterator::into_iter(mappings)
}
#[derive(Debug, Copy, Clone)]