mirror of
https://codeberg.org/icewind/haze.git
synced 2026-10-01 08:44:09 +02:00
parent
c5c2bdbf50
commit
125b68e08a
7 changed files with 207 additions and 9 deletions
94
src/script.rs
Normal file
94
src/script.rs
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
use std::fs::read_to_string;
|
||||
|
||||
use bollard::Docker;
|
||||
use camino::Utf8PathBuf;
|
||||
use miette::{Context, IntoDiagnostic, Report, Result};
|
||||
use strum::EnumString;
|
||||
|
||||
use crate::{
|
||||
cloud::CloudOptions,
|
||||
config::HazeConfig,
|
||||
get_forward_env,
|
||||
mapping::{Mapping, MappingSourceType},
|
||||
setup,
|
||||
};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, EnumString)]
|
||||
#[strum(serialize_all = "lowercase")]
|
||||
pub enum ScriptMode {
|
||||
Shell,
|
||||
Start,
|
||||
}
|
||||
|
||||
pub async fn run_script(
|
||||
path: String,
|
||||
config: &HazeConfig,
|
||||
docker: &Docker,
|
||||
mode_override: Option<ScriptMode>,
|
||||
) -> Result<()> {
|
||||
let path: Utf8PathBuf = Utf8PathBuf::from(path)
|
||||
.canonicalize()
|
||||
.into_diagnostic()
|
||||
.wrap_err("Failed to normalize script path")?
|
||||
.try_into()
|
||||
.into_diagnostic()
|
||||
.wrap_err("Non-utf8 script path")?;
|
||||
let contents = read_to_string(&path)
|
||||
.into_diagnostic()
|
||||
.wrap_err_with(|| format!("Failed to read script file {path}"))?;
|
||||
let (mut options, mode) = parse_script(&contents, config)
|
||||
.wrap_err_with(|| format!("Failed to parse script file {path}"))?;
|
||||
let mode = mode_override.unwrap_or(mode);
|
||||
|
||||
let target_path = Utf8PathBuf::from(format!("/{}", path.file_name().unwrap()));
|
||||
let shell = if path.extension() == Some("nu") {
|
||||
"nu"
|
||||
} else {
|
||||
"bash"
|
||||
};
|
||||
|
||||
options.mappings.push(
|
||||
Mapping::owned(
|
||||
MappingSourceType::Absolute,
|
||||
path.clone(),
|
||||
target_path.clone(),
|
||||
)
|
||||
.read_only()
|
||||
.dont_create(),
|
||||
);
|
||||
|
||||
let cloud = setup(docker, options, &config).await?;
|
||||
cloud
|
||||
.exec(
|
||||
&docker,
|
||||
vec![shell.to_string(), target_path.into_string()],
|
||||
true,
|
||||
get_forward_env(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
if mode == ScriptMode::Shell {
|
||||
cloud.destroy(&docker, &config).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn parse_script(script: &str, config: &HazeConfig) -> Result<(CloudOptions, ScriptMode)> {
|
||||
let (options, mode) = script
|
||||
.lines()
|
||||
.find_map(|line| line.strip_prefix("#! haze "))
|
||||
.and_then(
|
||||
|line| match (line.strip_prefix("shell"), line.strip_prefix("start")) {
|
||||
(Some(shell_options), None) => Some((shell_options.trim(), ScriptMode::Shell)),
|
||||
(None, Some(script_options)) => Some((script_options.trim(), ScriptMode::Start)),
|
||||
_ => None,
|
||||
},
|
||||
)
|
||||
.ok_or_else(|| Report::msg("No '#! haze shell' or '#! haze start' found in script"))?;
|
||||
let mut options = options.split(' ').peekable();
|
||||
|
||||
let options =
|
||||
CloudOptions::parse(config, &mut options).wrap_err("Failed to parse shell options")?;
|
||||
Ok((options, mode))
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue