mirror of
https://codeberg.org/icewind/haze.git
synced 2026-06-04 01:24:09 +02:00
edit command
This commit is contained in:
parent
7a96e6cd71
commit
43481a5960
5 changed files with 70 additions and 9 deletions
|
|
@ -215,6 +215,12 @@ This is indented to run a local
|
||||||
haze update
|
haze update
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Edit a file in an instance with the local $EDITOR
|
||||||
|
|
||||||
|
```bash
|
||||||
|
haze [match] edit <path>
|
||||||
|
```
|
||||||
|
|
||||||
## Federation
|
## Federation
|
||||||
|
|
||||||
Multiple instances can reach each other by using their instance name as domain
|
Multiple instances can reach each other by using their instance name as domain
|
||||||
|
|
|
||||||
15
src/args.rs
15
src/args.rs
|
|
@ -77,6 +77,10 @@ pub enum HazeArgs {
|
||||||
command: Option<HazeCommand>,
|
command: Option<HazeCommand>,
|
||||||
},
|
},
|
||||||
Version,
|
Version,
|
||||||
|
Edit {
|
||||||
|
filter: Option<String>,
|
||||||
|
path: String,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
|
|
@ -282,6 +286,13 @@ impl HazeArgs {
|
||||||
Ok(HazeArgs::Help { command })
|
Ok(HazeArgs::Help { command })
|
||||||
}
|
}
|
||||||
HazeCommand::Version => Ok(HazeArgs::Version),
|
HazeCommand::Version => Ok(HazeArgs::Version),
|
||||||
|
HazeCommand::Edit => Ok(HazeArgs::Edit {
|
||||||
|
filter,
|
||||||
|
path: args
|
||||||
|
.next()
|
||||||
|
.ok_or_else(|| Report::msg("No path provided"))?
|
||||||
|
.into(),
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -368,6 +379,9 @@ pub enum HazeCommand {
|
||||||
/// Show version number
|
/// Show version number
|
||||||
#[strum(serialize = "--version", to_string = "version")]
|
#[strum(serialize = "--version", to_string = "version")]
|
||||||
Version,
|
Version,
|
||||||
|
/// Edit a file in the instance with $EDITOR on the host
|
||||||
|
#[strum(props(Args = "[path] file to edit"))]
|
||||||
|
Edit,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HazeCommand {
|
impl HazeCommand {
|
||||||
|
|
@ -384,6 +398,7 @@ impl HazeCommand {
|
||||||
| HazeCommand::Pin
|
| HazeCommand::Pin
|
||||||
| HazeCommand::Unpin
|
| HazeCommand::Unpin
|
||||||
| HazeCommand::Env
|
| HazeCommand::Env
|
||||||
|
| HazeCommand::Edit
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
25
src/cloud.rs
25
src/cloud.rs
|
|
@ -15,6 +15,7 @@ use futures_util::future::try_join_all;
|
||||||
use miette::{IntoDiagnostic, Report, Result, WrapErr};
|
use miette::{IntoDiagnostic, Report, Result, WrapErr};
|
||||||
use petname::petname;
|
use petname::petname;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
use std::borrow::Cow;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
@ -767,4 +768,28 @@ impl Cloud {
|
||||||
pub fn php(&self) -> &PhpVersion {
|
pub fn php(&self) -> &PhpVersion {
|
||||||
&self.options.php
|
&self.options.php
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_local_path(&self, config: &HazeConfig, path: &str) -> Option<Utf8PathBuf> {
|
||||||
|
let path = if path.starts_with('/') {
|
||||||
|
Cow::Borrowed(path)
|
||||||
|
} else {
|
||||||
|
format!("/var/www/html/{path}").into()
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut mappings = config
|
||||||
|
.volume
|
||||||
|
.iter()
|
||||||
|
.map(Mapping::from)
|
||||||
|
.chain(default_mappings())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
mappings.sort_by_key(|mapping| usize::MAX - mapping.target.as_str().len());
|
||||||
|
|
||||||
|
for mapping in mappings {
|
||||||
|
if let Some(rel_path) = path.strip_prefix(mapping.target.as_str()) {
|
||||||
|
let rel_path = rel_path.trim_matches('/');
|
||||||
|
return Some(mapping.source(&self.id, config).join(rel_path));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
13
src/main.rs
13
src/main.rs
|
|
@ -16,7 +16,7 @@ use crate::service::{RedisTls, Service};
|
||||||
use bollard::Docker;
|
use bollard::Docker;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use miette::{IntoDiagnostic, Report, Result, WrapErr};
|
use miette::{IntoDiagnostic, Report, Result, WrapErr};
|
||||||
use std::env::vars;
|
use std::env::{var, vars};
|
||||||
use std::fs::{create_dir_all, write};
|
use std::fs::{create_dir_all, write};
|
||||||
use std::io::stdout;
|
use std::io::stdout;
|
||||||
use std::os::unix::process::CommandExt;
|
use std::os::unix::process::CommandExt;
|
||||||
|
|
@ -452,6 +452,17 @@ async fn main() -> Result<ExitCode> {
|
||||||
HazeArgs::Help { command } => {
|
HazeArgs::Help { command } => {
|
||||||
help(command);
|
help(command);
|
||||||
}
|
}
|
||||||
|
HazeArgs::Edit { filter, path } => {
|
||||||
|
let cloud = Cloud::get_by_filter(&docker, filter, &config).await?;
|
||||||
|
let path = cloud
|
||||||
|
.get_local_path(&config, &path)
|
||||||
|
.ok_or_else(|| Report::msg(format!("{path} not found on the instance")))?;
|
||||||
|
let editor = var("EDITOR").map_err(|_| Report::msg("$EDITOR not set"))?;
|
||||||
|
let err = Command::new(editor).arg(path).exec(); // this never exists without error
|
||||||
|
return Err(err)
|
||||||
|
.into_diagnostic()
|
||||||
|
.wrap_err("Failed to start $EDITOR");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(ExitCode::SUCCESS)
|
Ok(ExitCode::SUCCESS)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::config::{HazeConfig, HazeVolumeConfig};
|
use crate::config::{HazeConfig, HazeVolumeConfig};
|
||||||
use camino::Utf8Path;
|
use camino::{Utf8Path, Utf8PathBuf};
|
||||||
use miette::{IntoDiagnostic, Result};
|
use miette::{IntoDiagnostic, Result};
|
||||||
use tokio::fs::{create_dir_all, write};
|
use tokio::fs::{create_dir_all, write};
|
||||||
|
|
||||||
|
|
@ -7,7 +7,7 @@ use tokio::fs::{create_dir_all, write};
|
||||||
pub struct Mapping<'a> {
|
pub struct Mapping<'a> {
|
||||||
source_type: MappingSourceType,
|
source_type: MappingSourceType,
|
||||||
pub source: &'a Utf8Path,
|
pub source: &'a Utf8Path,
|
||||||
target: &'a Utf8Path,
|
pub target: &'a Utf8Path,
|
||||||
mapping_type: MappingType,
|
mapping_type: MappingType,
|
||||||
read_only: bool,
|
read_only: bool,
|
||||||
map: bool,
|
map: bool,
|
||||||
|
|
@ -78,16 +78,20 @@ impl<'a> Mapping<'a> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_volume_arg(&self, id: &str, config: &HazeConfig) -> Option<String> {
|
pub fn source(&self, id: &str, config: &HazeConfig) -> Utf8PathBuf {
|
||||||
if !self.map {
|
match self.source_type {
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let source = match self.source_type {
|
|
||||||
MappingSourceType::WorkDir => config.work_dir.join(id).join(self.source),
|
MappingSourceType::WorkDir => config.work_dir.join(id).join(self.source),
|
||||||
MappingSourceType::GlobalWorkDir => config.work_dir.join(self.source),
|
MappingSourceType::GlobalWorkDir => config.work_dir.join(self.source),
|
||||||
MappingSourceType::Sources => config.sources_root.join(self.source),
|
MappingSourceType::Sources => config.sources_root.join(self.source),
|
||||||
MappingSourceType::Absolute => self.source.into(),
|
MappingSourceType::Absolute => self.source.into(),
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_volume_arg(&self, id: &str, config: &HazeConfig) -> Option<String> {
|
||||||
|
if !self.map {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let source = self.source(id, config);
|
||||||
Some(if self.read_only {
|
Some(if self.read_only {
|
||||||
format!("{}:{}:ro", source, self.target)
|
format!("{}:{}:ro", source, self.target)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue