Skip to content

Commit

Permalink
save
Browse files Browse the repository at this point in the history
  • Loading branch information
oneElectron committed Jun 25, 2024
1 parent ac89b0b commit eba60a2
Show file tree
Hide file tree
Showing 4 changed files with 327 additions and 0 deletions.
90 changes: 90 additions & 0 deletions src/config/cli.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
pub(crate) use clap::{Parser, Subcommand};
use std::path::PathBuf;

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
#[command(propagate_version = true)]
pub(crate) struct Cli {
// Command Line Options structure
#[command(subcommand)]
pub(crate) command: Commands,

/// Path to project
#[arg(short, long)]
pub(crate) path: PathBuf,
}

#[derive(Subcommand, Debug)]
pub(crate) enum Commands {
/// Build ITex project (requires an itex-build.toml file, and pdflatex to be installed)
Build {
/// Do not remove auxiliary build files (for debugging)
#[arg(short, long)]
debug: bool,

/// Whether to build with draft mode enabled
#[arg(long)]
draft: bool,
},

/// Build ITex project in safe mode
#[allow(non_camel_case_types)]
Safe_Build,
/// Count the number of words in the current ITex project (requires texcount to be installed)
Count,
/// Clean auxillary build files
Clean,
/// Initialize LaTex project
Init {
name: String,

/// Disable looking in the os for itex-templates, only looks in . and ..
#[arg(long)]
disable_os_search: bool,

/// The path to itex-templates
#[arg(long)]
search_path: Option<PathBuf>,
},
/// Get info about a template
Info {
/// The name of the template
name: String,

/// Disable searching the OS for the itex-templates folder
#[arg(long)]
disable_os_search: bool,

/// The path to itex-templates
#[arg(long)]
search_path: Option<PathBuf>,
},
/// Get current value of a setting
Get {
/// The name of the option to get
name: Option<String>,
},
/// List installed templates
List {
/// Disable searching the OS for the itex-templates folder
#[arg(long)]
disable_os_search: bool,

/// The path to itex-templates
#[arg(long)]
search_path: Option<PathBuf>,
},
/// Create a new itex build file
#[allow(non_camel_case_types)]
New_Buildfile,
/// Set a setting
Set { name: String, value: String },

#[cfg(feature = "updater")]
/// Update installed templates
Update {
/// remove itex-templates folder
#[arg(long, short)]
remove: bool,
},
}
206 changes: 206 additions & 0 deletions src/config/global.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
#![allow(dead_code)]
use crate::prelude::*;

use console::style;
use itex_derive::itex_settings;
use serde::{Deserialize, Serialize};
use std::fmt;
use std::path::PathBuf;

const DEFAULT_TEX_FILENAME: &str = "main.tex";

#[itex_settings]
#[derive(Deserialize, Serialize, Clone, Debug)]
pub(crate) struct Settings {
tex_filename: Option<String>,
compile_bib: Option<bool>,
debug: Option<bool>,
output_dir: Option<PathBuf>,
build_artifacts_folder: Option<String>,
draft_mode: Option<bool>,
clean: Option<bool>,
}

impl Settings {
pub(crate) fn parse() -> Self {
todo!();
}
}

impl Settings {
pub(crate) fn tex_filename(&self) -> String {
self.tex_filename.clone().unwrap_or(DEFAULT_TEX_FILENAME.to_string())
}

pub(crate) fn compile_bib(&self) -> bool {
self.compile_bib.unwrap_or(true)
}

pub(crate) fn debug(&self) -> bool {
if std::env::var("ITEX_DEBUG").unwrap_or("FALSE".to_string()) == *"TRUE" {
return true;
}

self.debug.unwrap_or(false)
}

pub(crate) fn output_dir(&self) -> PathBuf {
self.output_dir.clone().unwrap_or(PathBuf::from("./out"))
}

pub(crate) fn build_artifacts_folder(&self) -> String {
self.build_artifacts_folder.clone().unwrap_or("itex-build".to_string())
}

pub(crate) fn build_artifacts_path(&self) -> PathBuf {
let mut output: PathBuf = self.output_dir();
output.push(self.build_artifacts_folder());

output
}

pub(crate) fn ensure_build_artifacts_path_exists(&self) {
let build_artifacts_path = self.build_artifacts_path();
if build_artifacts_path.is_dir() {
return;
}
if !self.output_dir().is_dir() {
std::fs::create_dir(self.output_dir()).unwrap();
}

std::fs::create_dir(build_artifacts_path).unwrap();
}

pub(crate) fn draft_mode(&self) -> bool {
self.draft_mode.unwrap_or(false)
}

pub(crate) fn clean(&self) -> bool {
self.clean.unwrap_or(false)
}

pub(crate) fn tex_filename_without_extension(&self) -> String {
self.tex_filename().split('.').next().unwrap().to_string()
}

pub(crate) fn check_tex_filename_is_set(&self) {
if self.tex_filename.is_none() {
println!("{}", style("itex_filename is not set").red().bold());
println!("{}", style("\titex set tex_filename <name of your .tex file>"));

if !PathBuf::from(DEFAULT_TEX_FILENAME).is_file() {
exit!(1);
}
}
}

#[allow(unused)]
pub(crate) fn parse_local() -> Self {
Self::check_not_in_config_folder();
let mut path = std::env::current_dir().unwrap();
path.push("itex-build.toml");

let toml_file: PathBuf = if path.is_file() {
path.to_owned()
} else if path.with_file_name(".itex-build.toml").is_file() {
path.to_owned().with_file_name(".itex-build.toml")
} else {
println!("{}", style("No itex build file found, please create one.").red().bold());
exit!(0);
};

let build_file = std::fs::read_to_string(toml_file);
if build_file.is_err() {
println!("{}", style("Failed to read itex build file").red().bold());
exit!(0);
}
let build_file = build_file.unwrap();

let build_toml: Settings = toml::from_str(build_file.as_str()).unwrap();

build_toml
}

fn prase_global() -> Self {
Self::check_not_in_config_folder();

let mut global_build_toml: Option<Self> = None;

if Self::global_settings_path().is_file() {
let path = Self::global_settings_path();
let global_build_toml_str = std::fs::read_to_string(path).unwrap();
let global_build_toml_err: Result<Settings, toml::de::Error> = toml::from_str(&global_build_toml_str);
if let Ok(global_build_toml_err) = global_build_toml_err {
global_build_toml = Some(global_build_toml_err);
}
}

let mut path = std::env::current_dir().unwrap();
path.push("itex-build.toml");

let toml_file: PathBuf = if path.is_file() {
path.to_owned()
} else if path.with_file_name(".itex-build.toml").is_file() {
path.to_owned().with_file_name(".itex-build.toml")
} else {
println!("{}", style("No itex build file found, please create one.").red().bold());
exit!(0);
};

let build_file = std::fs::read_to_string(toml_file);
if build_file.is_err() {
println!("{}", style("Failed to read itex build file").red().bold());
exit!(0);
}
let build_file = build_file.unwrap();

let build_toml: Settings = toml::from_str(build_file.as_str()).unwrap();

Self::merge_global_and_local(global_build_toml, build_toml)
}

fn check_not_in_config_folder() {
if Self::global_settings_path().parent().unwrap() == std::env::current_dir().unwrap() {
println!(
"{}",
style("Current dir and global config dir are the same.\nPlease do not build in itex config folder")
.red()
.bold()
);
exit!(0);
}
}

fn global_settings_path() -> PathBuf {
#[cfg(unix)]
{
let home = std::env::var("HOME").unwrap();
PathBuf::from(home).join(".config/itex/itex-build.toml")
}

#[cfg(windows)]
{
let home = std::env::var("UserProfile").unwrap();
PathBuf::from(home).join("AppData/Local/ITex/itex-build.toml")
}
}
}

#[cfg(test)]
mod tests {
#[test]
fn check_settings_merge() {
let mut local = super::Settings::empty();
local.build_artifacts_folder = Some("local_build".to_string());
local.compile_bib = Some(false);
let mut global = super::Settings::empty();
global.build_artifacts_folder = Some("global_build".to_string());
global.clean = Some(true);

let output = super::Settings::merge_global_and_local(Some(global), local);

assert_eq!(output.build_artifacts_folder, Some("local_build".to_string()));
assert_eq!(output.compile_bib, Some(false));
assert_eq!(output.clean, Some(true));
}
}
30 changes: 30 additions & 0 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
mod global;
mod cli;

pub(crate) use global::Settings;
pub(crate) use global::get as get_global;
pub(crate) use global::set as set_global;

pub(crate) use cli::Cli;
pub(crate) use cli::Commands as Command;

use clap::Parser;

pub(crate) struct Config {
pub(crate) global: global::Settings,
pub(crate) cli: cli::Cli,
}

impl Config {
pub(crate) fn parse() -> Self {
if std::env::var_os("ITEX_DEBUG").is_some() || (cfg!(debug_assertions) && std::env::var_os("RUST_LOG").is_some()) {
env_logger::init();
}
log::info!("Logging enabled");

Self {
cli: cli::Cli::parse(),
global: global::Settings::parse(),
}
}
}
1 change: 1 addition & 0 deletions src/init2/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

0 comments on commit eba60a2

Please sign in to comment.