Skip to content

Commit

Permalink
try to autodetect configfile (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
bend-n authored Jan 16, 2023
1 parent 8f93d6c commit 1d3f8d3
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 14 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "godot-package-manager"
version = "1.0.0"
version = "1.0.1"
edition = "2021"
authors = ["bendn <[email protected]>"]
description = "A package manager for godot"
Expand All @@ -24,6 +24,7 @@ toml = "0.5.10"
sha1 = "0.10.5"
console = "0.15.4"
indicatif = "0.17.2"
anyhow = "1.0.68"

[dev-dependencies]
glob = "0.3.0"
Expand Down
57 changes: 46 additions & 11 deletions src/config_file.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::package::Package;
use anyhow::Result;
use console::style;
use serde::Deserialize;
use serde_json::Result;
use std::collections::HashMap;

#[derive(Debug, Default)]
Expand All @@ -22,6 +23,13 @@ struct ConfigWrapper {
packages: HashMap<String, String>,
}

#[derive(Debug, Clone)]
pub enum ConfigType {
JSON,
YAML,
TOML,
}

impl From<ConfigWrapper> for ConfigFile {
fn from(from: ConfigWrapper) -> Self {
Self {
Expand All @@ -35,22 +43,49 @@ impl From<ConfigWrapper> for ConfigFile {
}

impl ConfigFile {
/// Creates a new [ConfigFile] from the given path.
/// Creates a new [ConfigFile] from the given text
/// Panics if the file doesn't exist, or the file cant be parsed as toml, hjson or yaml.
pub fn new(contents: &String) -> Self {
type W = ConfigWrapper;
#[rustfmt::skip]
let mut cfg: ConfigFile =
if let Ok(w) = deser_hjson::from_str::<W>(contents) { w.into() }
else if let Ok(w) = serde_yaml::from_str::<W>(contents) { w.into() }
else if let Ok(w) = toml::from_str::<W>(contents) { w.into() }
else { panic!("Failed to parse the config file") };
if contents.len() == 0 {
panic!("Empty CFG");
}

// definetly not going to backfire
let mut cfg = if contents.as_bytes()[0] == b'{' {
// json gets brute forced first so this isnt really needed
Self::parse(contents, ConfigType::JSON).expect("Parsing CFG from JSON should work")
} else if contents.len() > 3 && contents[..3] == *"---" {
Self::parse(contents, ConfigType::YAML).expect("Parsing CFG from YAML should work")
} else {
for i in [ConfigType::JSON, ConfigType::YAML, ConfigType::TOML].into_iter() {
let res = Self::parse(contents, i.clone());

// im sure theres some kind of idiomatic rust way to do this that i dont know of
if res.is_ok() {
return res.unwrap();
}

println!(
"{:>12} Parsing CFG from {:#?} failed: `{}` (ignore if cfg not written in {:#?})",
crate::print_consts::warn(),
i,
style(res.unwrap_err()).red(),
i
)
}
panic!("Parsing CFG failed (see above warnings to find out why)");
};
cfg.packages.sort();
cfg
}

pub fn from_json(json: &String) -> Result<Self> {
Ok(serde_json::from_str::<ConfigWrapper>(json)?.into())
pub fn parse(txt: &String, t: ConfigType) -> Result<Self> {
type W = ConfigWrapper;
Ok(match t {
ConfigType::TOML => toml::from_str::<W>(txt)?.into(),
ConfigType::JSON => deser_hjson::from_str::<W>(txt)?.into(),
ConfigType::YAML => serde_yaml::from_str::<W>(txt)?.into(),
})
}

/// Creates a lockfile for this config file.
Expand Down
5 changes: 3 additions & 2 deletions src/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,11 +161,11 @@ impl Package {
else if let Ok(c) = get(self.download_dir()) { Some(c) }
else { None };
if let Some(c) = c {
if let Ok(n) = ConfigFile::from_json(&c) {
if let Ok(n) = ConfigFile::parse(&c, crate::config_file::ConfigType::JSON) {
return n;
}
}
ConfigFile::from_json(
ConfigFile::parse(
&ureq::get(&format!(
"https://cdn.jsdelivr.net/npm/{}@{}/package.json",
self.name, self.version,
Expand All @@ -174,6 +174,7 @@ impl Package {
.expect("Getting the package config file should not fail")
.into_string()
.expect("The package config file should be valid text"),
crate::config_file::ConfigType::JSON,
)
.expect("The package config file should be correct/valid JSON")
}
Expand Down

0 comments on commit 1d3f8d3

Please sign in to comment.