add install
This commit is contained in:
parent
b94e5b3394
commit
e17db09859
@ -1,4 +1,4 @@
|
|||||||
use std::{path::PathBuf};
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
deps,
|
deps,
|
||||||
@ -27,11 +27,11 @@ impl Cli {
|
|||||||
|
|
||||||
let path = matches.get_one::<String>("path");
|
let path = matches.get_one::<String>("path");
|
||||||
if let Some(p) = path {
|
if let Some(p) = path {
|
||||||
let validated_path = PathBuf::from(p);
|
let path = PathBuf::from(p);
|
||||||
if !validated_path.exists() {
|
if !path.exists() {
|
||||||
eyre::bail!("no char.toml exists at --path")
|
eyre::bail!("no char.toml exists at --path")
|
||||||
}
|
}
|
||||||
self.deps.parser.set_path(validated_path);
|
self.deps.parser.set_path(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
match matches.subcommand() {
|
match matches.subcommand() {
|
||||||
|
29
src/context/mod.rs
Normal file
29
src/context/mod.rs
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
15
src/deps.rs
15
src/deps.rs
@ -1,9 +1,6 @@
|
|||||||
use std::{
|
use std::{ops::Deref, sync::Arc};
|
||||||
ops::{Deref},
|
|
||||||
sync::Arc,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::parser::Parser;
|
use crate::{parser::Parser, services::downloader::Downloader};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Deps {
|
pub struct Deps {
|
||||||
@ -13,14 +10,16 @@ pub struct Deps {
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct InnerDeps {
|
pub struct InnerDeps {
|
||||||
pub parser: Parser,
|
pub parser: Parser,
|
||||||
|
pub downloader: Downloader,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Deps {
|
impl Default for Deps {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
let parser = Parser::default();
|
||||||
|
let downloader = Downloader::new(parser.clone());
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
inner: Arc::new(InnerDeps {
|
inner: Arc::new(InnerDeps { parser, downloader }),
|
||||||
parser: Parser::default(),
|
|
||||||
}),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@ mod deps;
|
|||||||
mod models;
|
mod models;
|
||||||
mod parser;
|
mod parser;
|
||||||
mod resolvers;
|
mod resolvers;
|
||||||
|
mod services;
|
||||||
|
mod context;
|
||||||
|
|
||||||
fn main() -> eyre::Result<()> {
|
fn main() -> eyre::Result<()> {
|
||||||
color_eyre::install()?;
|
color_eyre::install()?;
|
||||||
|
@ -7,9 +7,9 @@ type Dependencies = Vec<String>;
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
pub struct Conf {
|
pub struct Conf {
|
||||||
plan: String,
|
pub plan: String,
|
||||||
dependencies: Option<Dependencies>,
|
pub dependencies: Option<Dependencies>,
|
||||||
overrides: Option<Overrides>,
|
pub overrides: Option<Overrides>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
|
@ -19,22 +19,38 @@ impl Parser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_path(&self, _path: PathBuf) {
|
pub fn set_path(&self, path: PathBuf) {
|
||||||
let _writer = self.path.write().unwrap();
|
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 read_path = self.path.read().unwrap();
|
||||||
let path = match read_path.clone() {
|
let path = match read_path.clone() {
|
||||||
Some(p) => p,
|
Some(p) => p,
|
||||||
None => todo!(), // find using git later on
|
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 =
|
let contents =
|
||||||
std::fs::read_to_string(&path).context("char.toml doesn't exist at that path")?;
|
std::fs::read_to_string(&path).context("char.toml doesn't exist at that path")?;
|
||||||
|
|
||||||
contents.parse::<Char>()
|
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 {
|
impl Default for Parser {
|
||||||
|
@ -2,6 +2,7 @@ use crate::deps;
|
|||||||
|
|
||||||
use super::{DynResolver, Resolver};
|
use super::{DynResolver, Resolver};
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Install {
|
pub struct Install {
|
||||||
deps: deps::Deps,
|
deps: deps::Deps,
|
||||||
@ -21,9 +22,7 @@ impl Resolver for Install {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn matches(&self, _args: &clap::ArgMatches) -> eyre::Result<()> {
|
fn matches(&self, _args: &clap::ArgMatches) -> eyre::Result<()> {
|
||||||
let char = self.deps.parser.parse()?;
|
self.deps.downloader.download()?;
|
||||||
|
|
||||||
dbg!(char);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
96
src/services/downloader.rs
Normal file
96
src/services/downloader.rs
Normal 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
1
src/services/mod.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub mod downloader;
|
Loading…
Reference in New Issue
Block a user