use std::io::Read as _;
use helm_schema_ast::DefineIndex;
use tracing::instrument;
use vfs::VfsPath;
use super::types::ChartContext;
use super::{FileRole, list_chart_files};
use crate::error::EngineResult;
#[instrument(skip_all)]
pub fn build_define_index(
charts: &[ChartContext],
include_tests: bool,
) -> EngineResult<DefineIndex> {
let mut index = DefineIndex::new();
for chart in charts {
let chart_files = list_chart_files(&chart.chart_dir, include_tests)?;
for path in chart_files
.iter()
.filter(|file| file.has_role(FileRole::DefineIndexTemplate))
.map(|file| &file.path)
{
index.add_file_source(
&define_source_logical_path(chart, path),
&path.read_to_string()?,
);
}
for path in chart_files
.iter()
.filter(|file| file.has_role(FileRole::FilesGetSource))
.map(|file| &file.path)
{
if let Some(source) = read_utf8_files_get_source(path)? {
index.add_file_source(&files_get_relative_path(&chart.chart_dir, path), &source);
}
}
}
Ok(index)
}
fn read_utf8_files_get_source(path: &VfsPath) -> EngineResult<Option<String>> {
let mut bytes = Vec::new();
path.open_file()?.read_to_end(&mut bytes)?;
Ok(String::from_utf8(bytes).ok())
}
fn chart_relative_path(chart_dir: &VfsPath, path: &VfsPath) -> String {
let abs = path.as_str();
let root = chart_dir.as_str().trim_end_matches('/');
abs.strip_prefix(root)
.and_then(|path| path.strip_prefix('/'))
.unwrap_or(abs)
.to_string()
}
fn define_source_logical_path(chart: &ChartContext, path: &VfsPath) -> String {
let relative = chart_relative_path(&chart.chart_dir, path);
if chart.values_prefix.is_empty() {
return relative;
}
format!("charts/{}/{relative}", chart.values_prefix.join("/charts/"))
}
fn files_get_relative_path(chart_dir: &VfsPath, path: &VfsPath) -> String {
let abs = path.as_str();
let root = chart_dir.as_str().trim_end_matches('/');
abs.strip_prefix(root)
.and_then(|path| path.strip_prefix('/'))
.or_else(|| abs.find("/files/").map(|index| &abs[(index + 1)..]))
.or_else(|| abs.find("files/").map(|index| &abs[index..]))
.unwrap_or(abs)
.to_string()
}