mirror of
https://codeberg.org/icewind/haze.git
synced 2026-06-03 09:04:12 +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
|
||||
```
|
||||
|
||||
#### Edit a file in an instance with the local $EDITOR
|
||||
|
||||
```bash
|
||||
haze [match] edit <path>
|
||||
```
|
||||
|
||||
## Federation
|
||||
|
||||
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>,
|
||||
},
|
||||
Version,
|
||||
Edit {
|
||||
filter: Option<String>,
|
||||
path: String,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
|
|
@ -282,6 +286,13 @@ impl HazeArgs {
|
|||
Ok(HazeArgs::Help { command })
|
||||
}
|
||||
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
|
||||
#[strum(serialize = "--version", to_string = "version")]
|
||||
Version,
|
||||
/// Edit a file in the instance with $EDITOR on the host
|
||||
#[strum(props(Args = "[path] file to edit"))]
|
||||
Edit,
|
||||
}
|
||||
|
||||
impl HazeCommand {
|
||||
|
|
@ -384,6 +398,7 @@ impl HazeCommand {
|
|||
| HazeCommand::Pin
|
||||
| HazeCommand::Unpin
|
||||
| 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 petname::petname;
|
||||
use serde_json::Value;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Display;
|
||||
use std::fs;
|
||||
|
|
@ -767,4 +768,28 @@ impl Cloud {
|
|||
pub fn php(&self) -> &PhpVersion {
|
||||
&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 itertools::Itertools;
|
||||
use miette::{IntoDiagnostic, Report, Result, WrapErr};
|
||||
use std::env::vars;
|
||||
use std::env::{var, vars};
|
||||
use std::fs::{create_dir_all, write};
|
||||
use std::io::stdout;
|
||||
use std::os::unix::process::CommandExt;
|
||||
|
|
@ -452,6 +452,17 @@ async fn main() -> Result<ExitCode> {
|
|||
HazeArgs::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)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::config::{HazeConfig, HazeVolumeConfig};
|
||||
use camino::Utf8Path;
|
||||
use camino::{Utf8Path, Utf8PathBuf};
|
||||
use miette::{IntoDiagnostic, Result};
|
||||
use tokio::fs::{create_dir_all, write};
|
||||
|
||||
|
|
@ -7,7 +7,7 @@ use tokio::fs::{create_dir_all, write};
|
|||
pub struct Mapping<'a> {
|
||||
source_type: MappingSourceType,
|
||||
pub source: &'a Utf8Path,
|
||||
target: &'a Utf8Path,
|
||||
pub target: &'a Utf8Path,
|
||||
mapping_type: MappingType,
|
||||
read_only: bool,
|
||||
map: bool,
|
||||
|
|
@ -78,16 +78,20 @@ impl<'a> Mapping<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_volume_arg(&self, id: &str, config: &HazeConfig) -> Option<String> {
|
||||
if !self.map {
|
||||
return None;
|
||||
}
|
||||
let source = match self.source_type {
|
||||
pub fn source(&self, id: &str, config: &HazeConfig) -> Utf8PathBuf {
|
||||
match self.source_type {
|
||||
MappingSourceType::WorkDir => config.work_dir.join(id).join(self.source),
|
||||
MappingSourceType::GlobalWorkDir => config.work_dir.join(self.source),
|
||||
MappingSourceType::Sources => config.sources_root.join(self.source),
|
||||
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 {
|
||||
format!("{}:{}:ro", source, self.target)
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue