add install

This commit is contained in:
Kasper Juul Hermansen 2023-01-22 21:27:24 +01:00
parent b94e5b3394
commit e17db09859
Signed by: kjuulh
GPG Key ID: 57B6E1465221F912
9 changed files with 163 additions and 21 deletions

View File

@ -1,4 +1,4 @@
use std::{path::PathBuf};
use std::path::PathBuf;
use crate::{
deps,
@ -27,11 +27,11 @@ impl Cli {
let path = matches.get_one::<String>("path");
if let Some(p) = path {
let validated_path = PathBuf::from(p);
if !validated_path.exists() {
let path = PathBuf::from(p);
if !path.exists() {
eyre::bail!("no char.toml exists at --path")
}
self.deps.parser.set_path(validated_path);
self.deps.parser.set_path(path);
}
match matches.subcommand() {

29
src/context/mod.rs Normal file
View File

@ -0,0 +1,29 @@
use crate::models::Char;
pub struct Context {}
impl Context {
pub fn new(chars: Vec<Char>) -> Self {
Self {}
}
}
pub struct ContextBuilder {
chars: Vec<Char>,
}
impl ContextBuilder {
pub fn new() -> Self {
Self { chars: vec![] }
}
pub fn add_char(mut self, char: &Char) -> Self {
self.chars.push(char.clone());
self
}
pub fn build(self) -> Context {
Context::new(self.chars)
}
}

View File

@ -1,9 +1,6 @@
use std::{
ops::{Deref},
sync::Arc,
};
use std::{ops::Deref, sync::Arc};
use crate::parser::Parser;
use crate::{parser::Parser, services::downloader::Downloader};
#[derive(Debug, Clone)]
pub struct Deps {
@ -13,14 +10,16 @@ pub struct Deps {
#[derive(Debug, Clone)]
pub struct InnerDeps {
pub parser: Parser,
pub downloader: Downloader,
}
impl Default for Deps {
fn default() -> Self {
let parser = Parser::default();
let downloader = Downloader::new(parser.clone());
Self {
inner: Arc::new(InnerDeps {
parser: Parser::default(),
}),
inner: Arc::new(InnerDeps { parser, downloader }),
}
}
}

View File

@ -3,6 +3,8 @@ mod deps;
mod models;
mod parser;
mod resolvers;
mod services;
mod context;
fn main() -> eyre::Result<()> {
color_eyre::install()?;

View File

@ -7,9 +7,9 @@ type Dependencies = Vec<String>;
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Conf {
plan: String,
dependencies: Option<Dependencies>,
overrides: Option<Overrides>,
pub plan: String,
pub dependencies: Option<Dependencies>,
pub overrides: Option<Overrides>,
}
#[derive(Serialize, Deserialize, Clone, Debug)]

View File

@ -19,22 +19,38 @@ impl Parser {
}
}
pub fn set_path(&self, _path: PathBuf) {
let _writer = self.path.write().unwrap();
pub fn set_path(&self, path: PathBuf) {
let mut writer = self.path.write().unwrap();
*writer = Some(path);
}
pub fn parse(&self) -> eyre::Result<models::Char> {
pub fn get_path(&self) -> eyre::Result<PathBuf> {
let read_path = self.path.read().unwrap();
let path = match read_path.clone() {
Some(p) => p,
None => todo!(), // find using git later on
};
Ok(path)
}
pub fn parse(&self) -> eyre::Result<models::Char> {
let mut path = self.get_path()?;
if !path.ends_with("char.toml") {
path.push("char.toml")
}
let contents =
std::fs::read_to_string(&path).context("char.toml doesn't exist at that path")?;
contents.parse::<Char>()
}
pub fn parse_from(&self, path: &PathBuf) -> eyre::Result<models::Char> {
let contents =
std::fs::read_to_string(path).context("char.toml doesn't exist at that path")?;
contents.parse::<Char>()
}
}
impl Default for Parser {

View File

@ -2,6 +2,7 @@ use crate::deps;
use super::{DynResolver, Resolver};
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct Install {
deps: deps::Deps,
@ -21,9 +22,7 @@ impl Resolver for Install {
}
fn matches(&self, _args: &clap::ArgMatches) -> eyre::Result<()> {
let char = self.deps.parser.parse()?;
dbg!(char);
self.deps.downloader.download()?;
Ok(())
}

View File

@ -0,0 +1,96 @@
use std::{fs::canonicalize, path::PathBuf};
use crate::{
context::{Context, ContextBuilder},
models::{Char, Conf},
parser::Parser,
};
#[derive(Debug, Clone)]
pub struct Downloader {
parser: Parser,
}
#[allow(dead_code)]
impl Downloader {
pub fn new(parser: Parser) -> Self {
Self { parser }
}
/// Unfolds char
/// 1. Download path
/// 2. Parse char in downloaded path
/// 3. Repeat from 1. until there are no more parents
pub fn download(&self) -> eyre::Result<Context> {
let mut context_builder = ContextBuilder::new();
let char = self.parser.parse()?;
context_builder = context_builder.add_char(&char);
let first_char_path = self.parser.get_path()?;
let mut root = std::env::current_dir()?;
root = root.join(&first_char_path);
root.push(".char");
let output = self.create_output_dir(&root)?;
let mut parent_char = char;
let path = first_char_path;
loop {
parent_char = match &parent_char {
Char::Application {
char,
application: _,
config: _,
} => match char {
Some(c) => self.download_plan(c, &path, &output)?,
None => {
break;
}
},
Char::Plan {
char,
plan: _,
config: _,
} => match char {
Some(_c) => todo!(),
None => {
break;
}
},
}
}
Ok(context_builder.build())
}
fn download_plan(
&self,
conf: &Conf,
path: &PathBuf,
output_path: &PathBuf,
) -> eyre::Result<Char> {
let plan = &conf.plan;
// TODO: decide whether it is a file or a git repo
// TODO: Starting with files only, as such implement git repo later
let path_buf = std::path::PathBuf::from(plan);
let path = path.join(path_buf);
if !path.exists() {
eyre::bail!("path doesn't exist: {}", path.to_string_lossy())
}
let path = canonicalize(path)?;
dbg!(path);
dbg!(output_path);
todo!()
}
fn create_output_dir(&self, root: &PathBuf) -> eyre::Result<PathBuf> {
let mut output = root.clone();
output.push("plans");
std::fs::create_dir_all(&output)?;
Ok(output)
}
}

1
src/services/mod.rs Normal file
View File

@ -0,0 +1 @@
pub mod downloader;