totally redo config system + install info
install info is now stored in data dir and can be overridden from config file. removed dependency on config crate
This commit is contained in:
parent
a8fc500c5a
commit
fa0f908db8
11 changed files with 171 additions and 107 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -1,4 +1,5 @@
|
||||||
/target
|
/target
|
||||||
|
|
||||||
# testing artifact
|
# testing artifacts
|
||||||
/parsers
|
*.so
|
||||||
|
|
||||||
|
|
20
Cargo.lock
generated
20
Cargo.lock
generated
|
@ -96,7 +96,6 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
"clap-cargo",
|
"clap-cargo",
|
||||||
"config",
|
|
||||||
"crossterm",
|
"crossterm",
|
||||||
"git2",
|
"git2",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
@ -104,6 +103,7 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"toml",
|
||||||
"xdg",
|
"xdg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -163,18 +163,6 @@ version = "1.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "config"
|
|
||||||
version = "0.15.11"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "595aae20e65c3be792d05818e8c63025294ac3cb7e200f11459063a352a6ef80"
|
|
||||||
dependencies = [
|
|
||||||
"pathdiff",
|
|
||||||
"serde",
|
|
||||||
"toml",
|
|
||||||
"winnow",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossterm"
|
name = "crossterm"
|
||||||
version = "0.28.1"
|
version = "0.28.1"
|
||||||
|
@ -596,12 +584,6 @@ dependencies = [
|
||||||
"windows-targets",
|
"windows-targets",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pathdiff"
|
|
||||||
version = "0.2.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "percent-encoding"
|
name = "percent-encoding"
|
||||||
version = "2.3.1"
|
version = "2.3.1"
|
||||||
|
|
|
@ -10,7 +10,6 @@ anstyle = "1.0.10"
|
||||||
anyhow = "1.0.97"
|
anyhow = "1.0.97"
|
||||||
clap = { version = "4.5.32", features = ["derive"] }
|
clap = { version = "4.5.32", features = ["derive"] }
|
||||||
clap-cargo = "0.15.2"
|
clap-cargo = "0.15.2"
|
||||||
config = { version = "0.15.11", default-features = false, features = ["toml"] }
|
|
||||||
crossterm = "0.28.1"
|
crossterm = "0.28.1"
|
||||||
git2 = "0.20.1"
|
git2 = "0.20.1"
|
||||||
lazy_static = "1.5.0"
|
lazy_static = "1.5.0"
|
||||||
|
@ -18,4 +17,5 @@ phf = { version = "0.11.3", features = ["macros"] }
|
||||||
serde = { version = "1.0.219", features = ["derive"] }
|
serde = { version = "1.0.219", features = ["derive"] }
|
||||||
tempfile = "3.19.1"
|
tempfile = "3.19.1"
|
||||||
thiserror = "2.0.12"
|
thiserror = "2.0.12"
|
||||||
|
toml = { version = "0.8.20", default-features = false, features = ["parse"] }
|
||||||
xdg = "2.5.2"
|
xdg = "2.5.2"
|
||||||
|
|
7
chrysopoeia.toml
Normal file
7
chrysopoeia.toml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
data_dir="share"
|
||||||
|
|
||||||
|
# [install]
|
||||||
|
# cc="meoww"
|
||||||
|
|
||||||
|
# [languages]
|
||||||
|
# zig = { url = "https://github.com/tree-sitter-grammars/tree-sitter-ziggggg", files = ["src/parser.c"] }
|
2
share/languages.toml
Normal file
2
share/languages.toml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
zig = { url = "https://github.com/tree-sitter-grammars/tree-sitter-zig", files = ["src/parser.c"] }
|
||||||
|
tcl = { url = "https://github.com/tree-sitter-grammars/tree-sitter-tcl", files = ["src/parser.c", "src/scanner.c"] }
|
|
@ -10,6 +10,7 @@ use clap::ValueEnum;
|
||||||
use crossterm::{ExecutableCommand, cursor::MoveToPreviousLine};
|
use crossterm::{ExecutableCommand, cursor::MoveToPreviousLine};
|
||||||
|
|
||||||
pub const ERROR: Style = AnsiColor::Red.on_default().effects(Effects::BOLD);
|
pub const ERROR: Style = AnsiColor::Red.on_default().effects(Effects::BOLD);
|
||||||
|
pub const WARN: Style = AnsiColor::Yellow.on_default().effects(Effects::BOLD);
|
||||||
pub const GOOD: Style = AnsiColor::Green.on_default().effects(Effects::BOLD);
|
pub const GOOD: Style = AnsiColor::Green.on_default().effects(Effects::BOLD);
|
||||||
pub const NOTE: Style = AnsiColor::Cyan.on_default().effects(Effects::BOLD);
|
pub const NOTE: Style = AnsiColor::Cyan.on_default().effects(Effects::BOLD);
|
||||||
|
|
||||||
|
@ -77,10 +78,20 @@ macro_rules! error {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! note {
|
macro_rules! warning {
|
||||||
($($arg:tt)+) => (
|
($($arg:tt)+) => (
|
||||||
crate::console::console().print(
|
crate::console::console().print(
|
||||||
" tip:",
|
"warning:",
|
||||||
|
&crate::console::WARN,
|
||||||
|
format_args!($($arg)+),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! tip {
|
||||||
|
($($arg:tt)+) => (
|
||||||
|
crate::console::console().print(
|
||||||
|
"tip:",
|
||||||
&crate::console::NOTE,
|
&crate::console::NOTE,
|
||||||
format_args!($($arg)+),
|
format_args!($($arg)+),
|
||||||
)
|
)
|
||||||
|
@ -116,8 +127,4 @@ macro_rules! update {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) use error;
|
pub(crate) use {error, fail, status, tip, update, warning};
|
||||||
pub(crate) use fail;
|
|
||||||
pub(crate) use note;
|
|
||||||
pub(crate) use status;
|
|
||||||
pub(crate) use update;
|
|
||||||
|
|
|
@ -4,17 +4,17 @@ use clap::Args;
|
||||||
use git2::Repository;
|
use git2::Repository;
|
||||||
use tempfile::tempdir;
|
use tempfile::tempdir;
|
||||||
|
|
||||||
use crate::console::{GOOD, NOTE, error, fail, note, status, update};
|
use crate::console::{GOOD, NOTE, error, fail, status, tip, update, warning};
|
||||||
use crate::settings::Settings;
|
use crate::settings::{InstallSettings, Settings};
|
||||||
|
|
||||||
mod cc;
|
mod cc;
|
||||||
mod languages;
|
pub(crate) mod languages;
|
||||||
|
|
||||||
use languages::{InstallInfo, get_install_info, is_installed};
|
use languages::{InstallInfo, Revision, is_installed};
|
||||||
|
|
||||||
#[derive(Debug, Args)]
|
#[derive(Debug, Args)]
|
||||||
pub struct Install {
|
pub struct Install {
|
||||||
/// reinstall already present parsers
|
/// Reinstall already present parsers
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
force: bool,
|
force: bool,
|
||||||
|
|
||||||
|
@ -22,15 +22,13 @@ pub struct Install {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Install {
|
impl Install {
|
||||||
pub fn run(
|
pub fn run(self, mut settings: Settings) -> anyhow::Result<ExitCode> {
|
||||||
self,
|
|
||||||
Settings {
|
|
||||||
parser_dir,
|
|
||||||
compiler,
|
|
||||||
}: Settings,
|
|
||||||
) -> anyhow::Result<ExitCode> {
|
|
||||||
let src_dir = tempdir()?;
|
let src_dir = tempdir()?;
|
||||||
|
|
||||||
|
let parser_dir = settings.parser_dir();
|
||||||
|
let language_defs = settings.language_defs()?;
|
||||||
|
let InstallSettings { compiler } = settings.install;
|
||||||
|
|
||||||
create_dir_all(&parser_dir)?;
|
create_dir_all(&parser_dir)?;
|
||||||
|
|
||||||
// have to use a canonical path bc compiler runs elsewhere
|
// have to use a canonical path bc compiler runs elsewhere
|
||||||
|
@ -51,7 +49,7 @@ impl Install {
|
||||||
if !force && is_installed(language, &parser_dir) {
|
if !force && is_installed(language, &parser_dir) {
|
||||||
status!("Skipping", &NOTE, "{language} (already installed)");
|
status!("Skipping", &NOTE, "{language} (already installed)");
|
||||||
skips += 1;
|
skips += 1;
|
||||||
} else if let Some(info) = get_install_info(language) {
|
} else if let Some(info) = language_defs.get(language) {
|
||||||
if let Err(Error::Fatal(_)) = install_with_status(
|
if let Err(Error::Fatal(_)) = install_with_status(
|
||||||
language,
|
language,
|
||||||
info,
|
info,
|
||||||
|
@ -70,7 +68,7 @@ impl Install {
|
||||||
}
|
}
|
||||||
|
|
||||||
if skips > 0 {
|
if skips > 0 {
|
||||||
note!("try '{NOTE}--force{NOTE:#}' to reinstall parsers");
|
tip!("try '{NOTE}--force{NOTE:#}' to reinstall parsers");
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(if errors > 0 {
|
Ok(if errors > 0 {
|
||||||
|
@ -87,14 +85,18 @@ fn install_with_status(
|
||||||
parser_dir: &Path,
|
parser_dir: &Path,
|
||||||
src_dir: &Path,
|
src_dir: &Path,
|
||||||
compiler: Option<&str>,
|
compiler: Option<&str>,
|
||||||
) -> Result<languages::Revision, Error> {
|
) -> Result<Option<Revision>, Error> {
|
||||||
status!("Installing", &GOOD, "{language}");
|
status!("Installing", &GOOD, "{language}");
|
||||||
|
|
||||||
let res = install(language, install_info, parser_dir, src_dir, compiler);
|
let res = install(language, install_info, parser_dir, src_dir, compiler);
|
||||||
|
|
||||||
match &res {
|
match &res {
|
||||||
Err(e) => fail!("{e}"),
|
Err(e) => fail!("{e}"),
|
||||||
Ok(revision) => update!("Installed", &GOOD, "{language} {revision:.7}"),
|
Ok(Some(revision)) => update!("Installed", &GOOD, "{language} {revision:.7}"),
|
||||||
|
Ok(None) => {
|
||||||
|
update!("Installed", &GOOD, "{language}");
|
||||||
|
warning!("couldn't get version info for {language}")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
|
@ -103,7 +105,7 @@ fn install_with_status(
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
enum Error {
|
enum Error {
|
||||||
#[error("couldn't clone `{0}`")]
|
#[error("couldn't clone `{0}`")]
|
||||||
Clone(&'static str),
|
Clone(String),
|
||||||
|
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Git(#[from] git2::Error),
|
Git(#[from] git2::Error),
|
||||||
|
@ -132,11 +134,15 @@ fn install(
|
||||||
parser_dir: &Path,
|
parser_dir: &Path,
|
||||||
src_dir: &Path,
|
src_dir: &Path,
|
||||||
compiler: Option<&str>,
|
compiler: Option<&str>,
|
||||||
) -> Result<git2::Oid, Error> {
|
) -> Result<Option<Revision>, Error> {
|
||||||
let repo_path = src_dir.join(language);
|
let repo_path = src_dir.join(language);
|
||||||
let repo = Repository::clone(url, &repo_path).map_err(|_| Error::Clone(url))?;
|
let repo = Repository::clone(url, &repo_path).map_err(|_| Error::Clone(url.to_owned()))?;
|
||||||
|
|
||||||
let version = repo.head()?.peel_to_commit()?.id();
|
// it's not fatal if we just can't get the revision info, tho it'd definitely be weird
|
||||||
|
let version = repo
|
||||||
|
.head()
|
||||||
|
.and_then(|head| head.peel_to_commit().map(|c| c.id()))
|
||||||
|
.ok();
|
||||||
|
|
||||||
let output_path = parser_dir.join(language).with_extension(DLL_EXTENSION);
|
let output_path = parser_dir.join(language).with_extension(DLL_EXTENSION);
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ const DEFAULT_COMPILERS: [&str; 3] = ["cc", "gcc", "clang"];
|
||||||
pub struct Build<'a> {
|
pub struct Build<'a> {
|
||||||
compiler: Option<&'a str>,
|
compiler: Option<&'a str>,
|
||||||
dir: Option<&'a Path>,
|
dir: Option<&'a Path>,
|
||||||
inputs: Vec<&'a str>,
|
inputs: Vec<&'a [String]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Build<'a> {
|
impl<'a> Build<'a> {
|
||||||
|
@ -84,10 +84,8 @@ impl<'a> Build<'a> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn input_files(&mut self, files: &[&'a str]) -> &mut Self {
|
pub fn input_files(&mut self, files: &'a [String]) -> &mut Self {
|
||||||
for file in files {
|
self.inputs.push(files);
|
||||||
self.inputs.push(*file);
|
|
||||||
}
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +96,7 @@ impl<'a> Build<'a> {
|
||||||
cmd.current_dir(path);
|
cmd.current_dir(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.args(&self.inputs);
|
cmd.args(self.inputs.iter().flat_map(|s| *s));
|
||||||
cmd.arg("-o").arg(output_path);
|
cmd.arg("-o").arg(output_path);
|
||||||
|
|
||||||
cmd.output()
|
cmd.output()
|
||||||
|
|
|
@ -1,40 +1,33 @@
|
||||||
use std::{env::consts::DLL_EXTENSION, path::Path};
|
use std::{collections::HashMap, env::consts::DLL_EXTENSION, path::Path};
|
||||||
|
|
||||||
use phf::phf_map;
|
use serde::Deserialize;
|
||||||
|
|
||||||
pub(super) type Revision = git2::Oid;
|
pub(super) type Revision = git2::Oid;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct InstallInfo {
|
pub struct InstallInfo {
|
||||||
pub url: &'static str,
|
pub url: String,
|
||||||
pub files: &'static [&'static str],
|
|
||||||
|
pub files: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
static LANGUAGES: phf::Map<&'static str, InstallInfo> = phf_map! {
|
pub type LanguageDefs = HashMap<String, InstallInfo>;
|
||||||
"dockerfile" => InstallInfo{
|
|
||||||
url: "https://github.com/camdencheek/tree-sitter-dockerfile",
|
|
||||||
files: &["src/parser.c", "src/scanner.c"],
|
|
||||||
},
|
|
||||||
"ini" => InstallInfo{
|
|
||||||
url: "https://github.com/justinmk/tree-sitter-ini",
|
|
||||||
files: &["src/parser.c"],
|
|
||||||
},
|
|
||||||
"tcl" => InstallInfo{
|
|
||||||
url: "https://github.com/tree-sitter-grammars/tree-sitter-tcl",
|
|
||||||
files: &["src/parser.c", "src/scanner.c"],
|
|
||||||
},
|
|
||||||
"yaml" => InstallInfo{
|
|
||||||
url: "https://github.com/tree-sitter-grammars/tree-sitter-yaml",
|
|
||||||
files: &["src/parser.c", "src/scanner.c"],
|
|
||||||
},
|
|
||||||
"zig" => InstallInfo{
|
|
||||||
url: "https://github.com/tree-sitter-grammars/tree-sitter-zig",
|
|
||||||
files: &["src/parser.c"],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn get_install_info(language: &str) -> Option<&InstallInfo> {
|
pub struct LanguageDb(Vec<LanguageDefs>);
|
||||||
LANGUAGES.get(language)
|
|
||||||
|
impl LanguageDb {
|
||||||
|
pub fn get(&self, language: &str) -> Option<&InstallInfo> {
|
||||||
|
for source in &self.0 {
|
||||||
|
if let Some(info) = source.get(language) {
|
||||||
|
return Some(info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(sources: Vec<HashMap<String, InstallInfo>>) -> Self {
|
||||||
|
Self(sources)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_installed(language: &str, parser_dir: &Path) -> bool {
|
pub fn is_installed(language: &str, parser_dir: &Path) -> bool {
|
||||||
|
|
36
src/main.rs
36
src/main.rs
|
@ -1,4 +1,7 @@
|
||||||
use std::process::ExitCode;
|
use std::{
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
process::ExitCode,
|
||||||
|
};
|
||||||
|
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
use clap_cargo::style::CLAP_STYLING;
|
use clap_cargo::style::CLAP_STYLING;
|
||||||
|
@ -9,14 +12,18 @@ mod settings;
|
||||||
|
|
||||||
use console::{Color, error};
|
use console::{Color, error};
|
||||||
use install::Install;
|
use install::Install;
|
||||||
use settings::get_settings;
|
use settings::{default_config, get_settings};
|
||||||
|
|
||||||
#[derive(Debug, Parser)]
|
#[derive(Debug, Parser)]
|
||||||
#[command(version, about, long_about = None)]
|
#[command(version, about, long_about = None)]
|
||||||
#[command(styles = CLAP_STYLING)]
|
#[command(styles = CLAP_STYLING)]
|
||||||
struct Cli {
|
struct Cli {
|
||||||
/// when to use terminal colors
|
/// Path to config file
|
||||||
#[arg(short, long, value_enum, default_value_t = Color::Auto)]
|
#[arg(short, long, global = true, value_name = "PATH")]
|
||||||
|
config: Option<PathBuf>,
|
||||||
|
|
||||||
|
/// When to use terminal colors
|
||||||
|
#[arg(long, value_enum, global = true, default_value_t = Color::Auto, value_name="WHEN")]
|
||||||
color: Color,
|
color: Color,
|
||||||
|
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
|
@ -25,12 +32,13 @@ struct Cli {
|
||||||
|
|
||||||
#[derive(Debug, Subcommand)]
|
#[derive(Debug, Subcommand)]
|
||||||
enum Command {
|
enum Command {
|
||||||
|
/// Install parsers
|
||||||
Install(Install),
|
Install(Install),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Command {
|
impl Command {
|
||||||
fn run(self) -> anyhow::Result<ExitCode> {
|
fn run(self, config_path: &Path) -> anyhow::Result<ExitCode> {
|
||||||
let settings = get_settings()?;
|
let settings = get_settings(config_path)?;
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Self::Install(args) => args.run(settings),
|
Self::Install(args) => args.run(settings),
|
||||||
|
@ -39,12 +47,18 @@ impl Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> ExitCode {
|
fn main() -> ExitCode {
|
||||||
let Cli { color, command } = Cli::parse();
|
let Cli {
|
||||||
|
config,
|
||||||
|
color,
|
||||||
|
command,
|
||||||
|
} = Cli::parse();
|
||||||
|
|
||||||
console::init(color);
|
console::init(color);
|
||||||
|
|
||||||
command.run().unwrap_or_else(|e| {
|
command
|
||||||
error!("{e}");
|
.run(&config.unwrap_or_else(default_config))
|
||||||
ExitCode::FAILURE
|
.unwrap_or_else(|e| {
|
||||||
})
|
error!("{e}");
|
||||||
|
ExitCode::FAILURE
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,17 @@
|
||||||
use std::path::PathBuf;
|
use std::{
|
||||||
|
fs::read_to_string,
|
||||||
|
io,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
|
|
||||||
use config::{Config, ConfigError, File};
|
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
console::warning,
|
||||||
|
install::languages::{LanguageDb, LanguageDefs},
|
||||||
|
};
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref XDG: xdg::BaseDirectories =
|
static ref XDG: xdg::BaseDirectories =
|
||||||
xdg::BaseDirectories::with_prefix("chrysopoeia").unwrap();
|
xdg::BaseDirectories::with_prefix("chrysopoeia").unwrap();
|
||||||
|
@ -11,21 +19,67 @@ lazy_static! {
|
||||||
|
|
||||||
#[derive(Debug, Default, Deserialize)]
|
#[derive(Debug, Default, Deserialize)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
#[serde(default = "default_parser_dir")]
|
#[serde(default = "default_data_dir")]
|
||||||
pub parser_dir: PathBuf,
|
pub data_dir: PathBuf,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
pub install: InstallSettings,
|
||||||
|
|
||||||
|
#[serde(rename = "languages")]
|
||||||
|
pub user_language_defs: Option<LanguageDefs>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize)]
|
||||||
|
pub struct InstallSettings {
|
||||||
#[serde(alias = "cc")]
|
#[serde(alias = "cc")]
|
||||||
pub compiler: Option<String>,
|
pub compiler: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_parser_dir() -> PathBuf {
|
fn default_data_dir() -> PathBuf {
|
||||||
XDG.get_data_file("parsers")
|
if cfg!(debug_assertions) {
|
||||||
|
"share".into()
|
||||||
|
} else {
|
||||||
|
XDG.get_data_home()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_settings() -> Result<Settings, ConfigError> {
|
pub fn default_config() -> PathBuf {
|
||||||
Config::builder()
|
if cfg!(debug_assertions) {
|
||||||
.add_source(File::from(XDG.get_config_file("config")).required(false))
|
"chrysopoeia.toml".into()
|
||||||
.add_source(File::with_name("chrysopoeia").required(false))
|
} else {
|
||||||
.build()?
|
XDG.get_config_file("config.toml")
|
||||||
.try_deserialize::<Settings>()
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
pub enum Error {
|
||||||
|
#[error("unable to read config file: {0}")]
|
||||||
|
Io(#[from] io::Error),
|
||||||
|
|
||||||
|
#[error(transparent)]
|
||||||
|
Toml(#[from] toml::de::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_settings(path: &Path) -> Result<Settings, Error> {
|
||||||
|
Ok(toml::from_str(&read_to_string(path)?)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Settings {
|
||||||
|
pub fn parser_dir(&self) -> PathBuf {
|
||||||
|
self.data_dir.join("parsers")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// note: this method moves out of self.user_language_defs
|
||||||
|
pub fn language_defs(&mut self) -> Result<LanguageDb, Error> {
|
||||||
|
let mut sources: Vec<LanguageDefs> = self.user_language_defs.take().into_iter().collect();
|
||||||
|
|
||||||
|
let default_path = self.data_dir.join("languages.toml");
|
||||||
|
|
||||||
|
match read_to_string(&default_path) {
|
||||||
|
Ok(default_defs) => sources.push(toml::from_str(&default_defs)?),
|
||||||
|
Err(e) => warning!("couldn't read language install info from {default_path:?}: {e}"),
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(LanguageDb::new(sources))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue