Init commit
This commit is contained in:
69
src/source/git.rs
Normal file
69
src/source/git.rs
Normal file
@ -0,0 +1,69 @@
|
||||
use std::fs::{self, rename};
|
||||
|
||||
use crate::helpers::cli::{cli_exec, cli_exec_from_dir};
|
||||
use base64::{engine::general_purpose, Engine as _};
|
||||
|
||||
use super::{ChartLocal, Repo};
|
||||
|
||||
pub(crate) struct Git {
|
||||
git_url: String,
|
||||
git_ref: String,
|
||||
path: String,
|
||||
pub(crate) chart: String,
|
||||
}
|
||||
|
||||
impl From<crate::config::Chart> for Git {
|
||||
fn from(value: crate::config::Chart) -> Self {
|
||||
Git {
|
||||
git_url: value.get_git_repository_url(),
|
||||
git_ref: value.get_git_repository_ref(),
|
||||
path: value.get_git_repository_path(),
|
||||
chart: value.name,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Repo for Git {
|
||||
fn pull(&self, workdir_path: String) -> Result<ChartLocal, Box<dyn std::error::Error>> {
|
||||
let repo_local_name = general_purpose::STANDARD_NO_PAD.encode(self.git_url.clone());
|
||||
let cmd = format!(
|
||||
"git clone {} {}/{}",
|
||||
self.git_url, workdir_path, repo_local_name
|
||||
);
|
||||
cli_exec(cmd)?;
|
||||
|
||||
let cmd = format!(
|
||||
"git -C {}/{} checkout {}",
|
||||
workdir_path, repo_local_name, self.git_ref
|
||||
);
|
||||
cli_exec(cmd)?;
|
||||
|
||||
let old_dir_name = format!(
|
||||
"{}/{}/{}/{}",
|
||||
workdir_path, repo_local_name, self.path, self.chart
|
||||
);
|
||||
let cmd = format!("helm show chart {}", old_dir_name);
|
||||
let helm_stdout = cli_exec(cmd)?;
|
||||
let new_dir_name: String;
|
||||
match serde_yaml::from_str::<super::Version>(&helm_stdout) {
|
||||
Ok(res) => {
|
||||
new_dir_name = format!("{}/{}-{}", workdir_path, self.chart, res.version);
|
||||
rename(old_dir_name, new_dir_name.clone())?;
|
||||
}
|
||||
Err(err) => return Err(Box::from(err)),
|
||||
};
|
||||
|
||||
// Cleaning up
|
||||
fs::remove_dir_all(format!("{}/{}", workdir_path, repo_local_name))?;
|
||||
|
||||
// Get the version
|
||||
let cmd = "helm show chart . | yq '.version'".to_string();
|
||||
let version = cli_exec_from_dir(cmd, new_dir_name.clone())?;
|
||||
Ok(ChartLocal {
|
||||
name: self.chart.clone(),
|
||||
version,
|
||||
path: new_dir_name,
|
||||
repo_url: self.git_url.clone(),
|
||||
})
|
||||
}
|
||||
}
|
105
src/source/helm.rs
Normal file
105
src/source/helm.rs
Normal file
@ -0,0 +1,105 @@
|
||||
use super::{ChartLocal, Repo};
|
||||
use crate::helpers::cli::{cli_exec, cli_exec_from_dir};
|
||||
use base64::{engine::general_purpose, Engine as _};
|
||||
use std::fs::rename;
|
||||
|
||||
pub(crate) enum RepoKind {
|
||||
Default,
|
||||
Oci,
|
||||
}
|
||||
|
||||
const LATEST_VERSION: &str = "latest";
|
||||
|
||||
pub(crate) struct Helm {
|
||||
pub(crate) chart: String,
|
||||
pub(crate) repository_url: String,
|
||||
pub(crate) version: String,
|
||||
}
|
||||
|
||||
impl From<crate::config::Chart> for Helm {
|
||||
fn from(value: crate::config::Chart) -> Self {
|
||||
Helm {
|
||||
chart: value.name.clone(),
|
||||
repository_url: value.get_helm_repository_url(),
|
||||
version: match value.version {
|
||||
Some(res) => res,
|
||||
None => LATEST_VERSION.to_string(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Helm {
|
||||
fn repo_kind_from_url(&self) -> Result<RepoKind, Box<dyn std::error::Error>> {
|
||||
let prefix = self
|
||||
.repository_url
|
||||
.chars()
|
||||
.take_while(|&ch| ch != ':')
|
||||
.collect::<String>();
|
||||
match prefix.as_str() {
|
||||
"oci" => Ok(RepoKind::Oci),
|
||||
"https" | "http" => Ok(RepoKind::Default),
|
||||
_ => Err(Box::from(format!(
|
||||
"repo kind is not defined by the prefix: {}",
|
||||
prefix
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
fn pull_default(&self, workdir_path: String) -> Result<ChartLocal, Box<dyn std::error::Error>> {
|
||||
// Add repo and update
|
||||
let repo_local_name = general_purpose::STANDARD_NO_PAD.encode(self.repository_url.clone());
|
||||
let cmd = format!("helm repo add {} {}", repo_local_name, self.repository_url);
|
||||
cli_exec(cmd)?;
|
||||
cli_exec("helm repo update".to_string())?;
|
||||
|
||||
let args = match self.version.as_str() {
|
||||
LATEST_VERSION => "".to_string(),
|
||||
_ => format!("--version {}", self.version.clone()),
|
||||
};
|
||||
let cmd = format!(
|
||||
"helm pull {}/{} {} --destination {} --untar",
|
||||
repo_local_name, &self.chart, args, workdir_path
|
||||
);
|
||||
cli_exec(cmd)?;
|
||||
|
||||
// Get the version
|
||||
let cmd = format!("helm show chart {}/{}", workdir_path, &self.chart);
|
||||
let helm_stdout = cli_exec(cmd)?;
|
||||
let old_dir_name = format!("{}/{}", workdir_path, &self.chart);
|
||||
let new_dir_name: String;
|
||||
match serde_yaml::from_str::<super::Version>(&helm_stdout) {
|
||||
Ok(res) => {
|
||||
new_dir_name = format!("{}-{}", old_dir_name, res.version);
|
||||
rename(old_dir_name, new_dir_name.clone())?;
|
||||
}
|
||||
Err(err) => return Err(Box::from(err)),
|
||||
};
|
||||
|
||||
//cleaning up
|
||||
let cmd = format!("helm repo remove {}", repo_local_name);
|
||||
cli_exec(cmd)?;
|
||||
|
||||
let cmd = "helm show chart . | yq '.version'".to_string();
|
||||
let version = cli_exec_from_dir(cmd, new_dir_name.clone())?;
|
||||
Ok(ChartLocal {
|
||||
name: self.chart.clone(),
|
||||
version,
|
||||
path: new_dir_name,
|
||||
repo_url: self.repository_url.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Repo for Helm {
|
||||
fn pull(&self, workdir_path: String) -> Result<ChartLocal, Box<dyn std::error::Error>> {
|
||||
let repository_kind = self.repo_kind_from_url()?;
|
||||
let path = match repository_kind {
|
||||
RepoKind::Default => self.pull_default(workdir_path)?,
|
||||
RepoKind::Oci => {
|
||||
todo!()
|
||||
}
|
||||
};
|
||||
Ok(path)
|
||||
}
|
||||
}
|
46
src/source/mod.rs
Normal file
46
src/source/mod.rs
Normal file
@ -0,0 +1,46 @@
|
||||
use crate::config::Chart;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub(crate) mod git;
|
||||
pub(crate) mod helm;
|
||||
|
||||
#[derive(Deserialize, Serialize, Clone)]
|
||||
pub(crate) struct ChartLocal {
|
||||
pub(crate) name: String,
|
||||
pub(crate) version: String,
|
||||
pub(crate) path: String,
|
||||
pub(crate) repo_url: String,
|
||||
}
|
||||
|
||||
impl ChartLocal {
|
||||
pub(crate) fn test(&self) -> String {
|
||||
"test-me-if-you-can".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) trait Repo {
|
||||
fn pull(&self, workdir_path: String) -> Result<ChartLocal, Box<dyn std::error::Error>>;
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
|
||||
pub(crate) struct Version {
|
||||
pub(crate) version: String,
|
||||
}
|
||||
|
||||
pub(crate) fn repo_from_chart(chart: Chart) -> Result<Box<dyn Repo>, Box<dyn std::error::Error>> {
|
||||
match chart.get_repo_kind() {
|
||||
Ok(res) => {
|
||||
return match res {
|
||||
crate::config::RepositoryKind::Helm => {
|
||||
let helm: helm::Helm = chart.into();
|
||||
Ok(Box::new(helm))
|
||||
}
|
||||
crate::config::RepositoryKind::Git => {
|
||||
let git: git::Git = chart.into();
|
||||
Ok(Box::new(git))
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(err) => return Err(Box::from(err)),
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user