...
This commit is contained in:
parent
78db13d738
commit
4be9445702
@ -11,6 +11,7 @@ categories = ["os", "filesystem", "api-bindings"]
|
||||
readme = "README.md"
|
||||
|
||||
[dependencies]
|
||||
tera = "1.19.0" # Template engine for text rendering
|
||||
# Cross-platform functionality
|
||||
libc = "0.2"
|
||||
cfg-if = "1.0"
|
||||
|
66
src/examples/template_example.rs
Normal file
66
src/examples/template_example.rs
Normal file
@ -0,0 +1,66 @@
|
||||
use std::collections::HashMap;
|
||||
use std::error::Error;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use tempfile::NamedTempFile;
|
||||
|
||||
use sal::text::TemplateBuilder;
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
// Create a temporary template file for our examples
|
||||
let temp_file = NamedTempFile::new()?;
|
||||
let template_content = "Hello, {{ name }}! Welcome to {{ place }}.\n\
|
||||
{% if show_greeting %}Glad to have you here!{% endif %}\n\
|
||||
Your items:\n\
|
||||
{% for item in items %} - {{ item }}{% if not loop.last %}\n{% endif %}{% endfor %}\n";
|
||||
std::fs::write(temp_file.path(), template_content)?;
|
||||
|
||||
println!("Created temporary template at: {}", temp_file.path().display());
|
||||
|
||||
// Example 1: Simple variable replacement
|
||||
println!("\n--- Example 1: Simple variable replacement ---");
|
||||
let mut builder = TemplateBuilder::open(temp_file.path())?;
|
||||
builder = builder
|
||||
.add_var("name", "John")
|
||||
.add_var("place", "Rust")
|
||||
.add_var("show_greeting", true)
|
||||
.add_var("items", vec!["apple", "banana", "cherry"]);
|
||||
|
||||
let result = builder.render()?;
|
||||
println!("Rendered template:\n{}", result);
|
||||
|
||||
// Example 2: Using a HashMap for variables
|
||||
println!("\n--- Example 2: Using a HashMap for variables ---");
|
||||
let mut vars = HashMap::new();
|
||||
vars.insert("name", "Alice");
|
||||
vars.insert("place", "Template World");
|
||||
|
||||
let mut builder = TemplateBuilder::open(temp_file.path())?;
|
||||
builder = builder
|
||||
.add_vars(vars)
|
||||
.add_var("show_greeting", false)
|
||||
.add_var("items", vec!["laptop", "phone", "tablet"]);
|
||||
|
||||
let result = builder.render()?;
|
||||
println!("Rendered template with HashMap:\n{}", result);
|
||||
|
||||
// Example 3: Rendering to a file
|
||||
println!("\n--- Example 3: Rendering to a file ---");
|
||||
let output_file = NamedTempFile::new()?;
|
||||
|
||||
let mut builder = TemplateBuilder::open(temp_file.path())?;
|
||||
builder = builder
|
||||
.add_var("name", "Bob")
|
||||
.add_var("place", "File Output")
|
||||
.add_var("show_greeting", true)
|
||||
.add_var("items", vec!["document", "spreadsheet", "presentation"]);
|
||||
|
||||
builder.render_to_file(output_file.path())?;
|
||||
println!("Template rendered to file: {}", output_file.path().display());
|
||||
|
||||
// Read the output file to verify
|
||||
let output_content = std::fs::read_to_string(output_file.path())?;
|
||||
println!("Content of the rendered file:\n{}", output_content);
|
||||
|
||||
Ok(())
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
|
||||
use rhai::{Engine, EvalAltResult, Array, Dynamic, Map};
|
||||
use std::collections::HashMap;
|
||||
use crate::virt::buildah::{self, BuildahError, Image, Builder};
|
||||
use crate::virt::buildah::{self, BuildahError, Image, Builder, ContentOperations};
|
||||
use crate::process::CommandResult;
|
||||
|
||||
/// Register Buildah module functions with the Rhai engine
|
||||
@ -150,12 +150,26 @@ pub fn builder_config(builder: &mut Builder, options: Map) -> Result<CommandResu
|
||||
|
||||
/// Write content to a file in the container
|
||||
pub fn builder_write_content(builder: &mut Builder, content: &str, dest_path: &str) -> Result<CommandResult, Box<EvalAltResult>> {
|
||||
bah_error_to_rhai_error(builder.write_content(content, dest_path))
|
||||
if let Some(container_id) = builder.container_id() {
|
||||
bah_error_to_rhai_error(ContentOperations::write_content(container_id, content, dest_path))
|
||||
} else {
|
||||
Err(Box::new(EvalAltResult::ErrorRuntime(
|
||||
"No container ID available".into(),
|
||||
rhai::Position::NONE
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
/// Read content from a file in the container
|
||||
pub fn builder_read_content(builder: &mut Builder, source_path: &str) -> Result<String, Box<EvalAltResult>> {
|
||||
bah_error_to_rhai_error(builder.read_content(source_path))
|
||||
if let Some(container_id) = builder.container_id() {
|
||||
bah_error_to_rhai_error(ContentOperations::read_content(container_id, source_path))
|
||||
} else {
|
||||
Err(Box::new(EvalAltResult::ErrorRuntime(
|
||||
"No container ID available".into(),
|
||||
rhai::Position::NONE
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
// Builder static methods
|
||||
|
@ -1,7 +1,9 @@
|
||||
mod dedent;
|
||||
mod fix;
|
||||
mod replace;
|
||||
mod template;
|
||||
|
||||
pub use dedent::*;
|
||||
pub use fix::*;
|
||||
pub use replace::*;
|
||||
pub use replace::*;
|
||||
pub use template::*;
|
@ -210,9 +210,9 @@ mod tests {
|
||||
#[test]
|
||||
fn test_template_rendering() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Create a temporary template file
|
||||
let mut temp_file = NamedTempFile::new()?;
|
||||
writeln!(temp_file, "Hello, {{ name }}! Welcome to {{ place }}.")?;
|
||||
temp_file.flush()?;
|
||||
let temp_file = NamedTempFile::new()?;
|
||||
let template_content = "Hello, {{ name }}! Welcome to {{ place }}.\n";
|
||||
fs::write(temp_file.path(), template_content)?;
|
||||
|
||||
// Create a template builder and add variables
|
||||
let mut builder = TemplateBuilder::open(temp_file.path())?;
|
||||
@ -230,10 +230,9 @@ mod tests {
|
||||
#[test]
|
||||
fn test_template_with_multiple_vars() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Create a temporary template file
|
||||
let mut temp_file = NamedTempFile::new()?;
|
||||
writeln!(temp_file, "{% if show_greeting %}Hello, {{ name }}!{% endif %}")?;
|
||||
writeln!(temp_file, "{% for item in items %}{{ item }}{% if not loop.last %}, {% endif %}{% endfor %}")?;
|
||||
temp_file.flush()?;
|
||||
let temp_file = NamedTempFile::new()?;
|
||||
let template_content = "{% if show_greeting %}Hello, {{ name }}!{% endif %}\n{% for item in items %}{{ item }}{% if not loop.last %}, {% endif %}{% endfor %}\n";
|
||||
fs::write(temp_file.path(), template_content)?;
|
||||
|
||||
// Create a template builder and add variables
|
||||
let mut builder = TemplateBuilder::open(temp_file.path())?;
|
||||
@ -273,13 +272,13 @@ mod tests {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_render_to_file() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Create a temporary template file
|
||||
let mut temp_file = NamedTempFile::new()?;
|
||||
writeln!(temp_file, "{{ message }}")?;
|
||||
temp_file.flush()?;
|
||||
let temp_file = NamedTempFile::new()?;
|
||||
let template_content = "{{ message }}\n";
|
||||
fs::write(temp_file.path(), template_content)?;
|
||||
|
||||
|
||||
// Create an output file
|
||||
let output_file = NamedTempFile::new()?;
|
||||
|
@ -11,6 +11,8 @@ pub struct Builder {
|
||||
container_id: Option<String>,
|
||||
/// Base image
|
||||
image: String,
|
||||
/// Debug mode
|
||||
debug: bool,
|
||||
}
|
||||
|
||||
impl Builder {
|
||||
@ -37,6 +39,7 @@ impl Builder {
|
||||
name: name.to_string(),
|
||||
container_id: Some(container_id),
|
||||
image: image.to_string(),
|
||||
debug: false,
|
||||
})
|
||||
},
|
||||
Err(BuildahError::CommandFailed(error_msg)) => {
|
||||
@ -58,6 +61,7 @@ impl Builder {
|
||||
name: name.to_string(),
|
||||
container_id: Some(container_id),
|
||||
image: image.to_string(),
|
||||
debug: false,
|
||||
})
|
||||
} else {
|
||||
// Couldn't extract container ID
|
||||
@ -85,6 +89,17 @@ impl Builder {
|
||||
&self.name
|
||||
}
|
||||
|
||||
/// Get the debug mode
|
||||
pub fn debug(&self) -> bool {
|
||||
self.debug
|
||||
}
|
||||
|
||||
/// Set the debug mode
|
||||
pub fn set_debug(&mut self, debug: bool) -> &mut Self {
|
||||
self.debug = debug;
|
||||
self
|
||||
}
|
||||
|
||||
/// Get the base image
|
||||
pub fn image(&self) -> &str {
|
||||
&self.image
|
||||
|
70
src/virt/buildah/content.rs
Normal file
70
src/virt/buildah/content.rs
Normal file
@ -0,0 +1,70 @@
|
||||
use crate::process::CommandResult;
|
||||
use crate::virt::buildah::{execute_buildah_command, BuildahError};
|
||||
use std::fs::File;
|
||||
use std::io::{Read, Write};
|
||||
use tempfile::NamedTempFile;
|
||||
|
||||
/// Functions for working with file content in buildah containers
|
||||
pub struct ContentOperations;
|
||||
|
||||
impl ContentOperations {
|
||||
/// Write content to a file in the container
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `container_id` - The container ID
|
||||
/// * `content` - The content to write
|
||||
/// * `dest_path` - Destination path in the container
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// * `Result<CommandResult, BuildahError>` - Command result or error
|
||||
pub fn write_content(container_id: &str, content: &str, dest_path: &str) -> Result<CommandResult, BuildahError> {
|
||||
// Create a temporary file
|
||||
let mut temp_file = NamedTempFile::new()
|
||||
.map_err(|e| BuildahError::Other(format!("Failed to create temporary file: {}", e)))?;
|
||||
|
||||
// Write content to the temporary file
|
||||
temp_file.write_all(content.as_bytes())
|
||||
.map_err(|e| BuildahError::Other(format!("Failed to write to temporary file: {}", e)))?;
|
||||
|
||||
// Flush the file to ensure content is written
|
||||
temp_file.flush()
|
||||
.map_err(|e| BuildahError::Other(format!("Failed to flush temporary file: {}", e)))?;
|
||||
|
||||
// Copy the temporary file to the container
|
||||
let temp_path = temp_file.path().to_string_lossy().to_string();
|
||||
execute_buildah_command(&["copy", container_id, &temp_path, dest_path])
|
||||
}
|
||||
|
||||
/// Read content from a file in the container
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `container_id` - The container ID
|
||||
/// * `source_path` - Source path in the container
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// * `Result<String, BuildahError>` - File content or error
|
||||
pub fn read_content(container_id: &str, source_path: &str) -> Result<String, BuildahError> {
|
||||
// Create a temporary file
|
||||
let temp_file = NamedTempFile::new()
|
||||
.map_err(|e| BuildahError::Other(format!("Failed to create temporary file: {}", e)))?;
|
||||
|
||||
let temp_path = temp_file.path().to_string_lossy().to_string();
|
||||
|
||||
// Copy the file from the container to the temporary file
|
||||
execute_buildah_command(&["copy", container_id, source_path, &temp_path])?;
|
||||
|
||||
// Read the content from the temporary file
|
||||
let mut file = File::open(temp_file.path())
|
||||
.map_err(|e| BuildahError::Other(format!("Failed to open temporary file: {}", e)))?;
|
||||
|
||||
let mut content = String::new();
|
||||
file.read_to_string(&mut content)
|
||||
.map_err(|e| BuildahError::Other(format!("Failed to read from temporary file: {}", e)))?;
|
||||
|
||||
Ok(content)
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ mod containers;
|
||||
mod images;
|
||||
mod cmd;
|
||||
mod builder;
|
||||
mod content;
|
||||
#[cfg(test)]
|
||||
mod containers_test;
|
||||
|
||||
@ -52,4 +53,5 @@ pub use builder::Builder;
|
||||
pub use containers::*;
|
||||
#[deprecated(since = "0.2.0", note = "Use Builder methods instead")]
|
||||
pub use images::*;
|
||||
pub use cmd::*;
|
||||
pub use cmd::*;
|
||||
pub use content::ContentOperations;
|
Loading…
Reference in New Issue
Block a user