diff --git a/.gitignore b/.gitignore index f75f7c4..7062fdd 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,13 @@ # Build target/ src/data/* -.nxfs \ No newline at end of file +.nxfs +plugins/* +# Include plugins README.md +!plugins/README.md + +# misc +.DS_Store +plugins/.DS_Store +src/.DS_Store +src/*/.DS_Store diff --git a/Cargo.lock b/Cargo.lock index 5771d82..a71b664 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -415,7 +415,7 @@ dependencies = [ [[package]] name = "nyx" -version = "2.11.0" +version = "2.12.0" dependencies = [ "bincode", "chrono", diff --git a/Cargo.toml b/Cargo.toml index d5cfcfc..dced863 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nyx" -version = "2.11.0" +version = "2.12.0" edition = "2021" authors = ["Elouan DA COSTA PEIXOTO "] description = "A CLI tool for managing your projects." diff --git a/plugins/README.md b/plugins/README.md new file mode 100644 index 0000000..8d55088 --- /dev/null +++ b/plugins/README.md @@ -0,0 +1,28 @@ +# Here's the plugins directory used for plugin system + +## Usage + +Add as many plugins as you want and add the name of it to the nyx's config file. The name of the plugin must match the name of the file without file extension. + +## Exampled + +Simple example for a plugin file: + +```toml +[plugin] +name = "rust" +plugin_type = "Simple" +version = "0.1.0" +enabled = true + +[core] +build_command = true +clean_command = true +run_command = true + +[commands] +init_command = ["cargo", "init", "--bin"] +build_command = [] +clean_command = [] +run_command = [] +``` diff --git a/src/init/mod.rs b/src/init/mod.rs new file mode 100644 index 0000000..3db9ac8 --- /dev/null +++ b/src/init/mod.rs @@ -0,0 +1,16 @@ +use std::env; + +use crate::{nxfs, utils::log::log_from_log_level}; + +pub fn init_command() { + let args: Vec = env::args().collect(); + if args.len() <= 2 { + init_nyx(); + } +} + +// Basic init of NYX +fn init_nyx() { + log_from_log_level(crate::nxfs::config::LogLevel::Info, "Initialize NYX.."); + nxfs::nxs::create_data(); +} diff --git a/src/main.rs b/src/main.rs index 3006146..7079ba1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,11 +14,13 @@ pub mod nxfs; use std::env; mod health; mod hello; +mod init; +pub mod plugins; // Current version of NYX // if modified and then running update command it will replace // your current nyx installation with the newer version -const VERSION: &str = "2.11.0"; +const VERSION: &str = "2.12.0"; enum Commands { Init, CatNxs, @@ -31,6 +33,7 @@ enum Commands { Hello, Update, Config, + Plugins, Upgrade, Help, Version, @@ -55,6 +58,7 @@ Commands: hello Display helpful information about today upgrade Update the current version of NYX config Manage nyx configuration + plugins Manage plugins help Show this help message Options: @@ -93,6 +97,7 @@ fn main() { Some("hello") => Commands::Hello, Some("update") => Commands::Update, Some("config") => Commands::Config, + Some("plugins") => Commands::Plugins, Some("upgrade") => Commands::Upgrade, Some("help") => Commands::Help, Some("version") => Commands::Version, @@ -103,7 +108,7 @@ fn main() { }; match command { - Commands::Init => nxfs::nxs::create_data(), + Commands::Init => init::init_command(), Commands::CatNxs => nxfs::nxs::cat_nxs(), Commands::CatNxp { hash } => nxfs::nxp::cat_nxp(hash.as_deref()), Commands::Project => projects::project_command(), @@ -113,6 +118,7 @@ fn main() { Commands::Health => health::health_command(), Commands::Hello => hello::hello_command(), Commands::Config => nxfs::config::config_command(), + Commands::Plugins => plugins::plugins_command(), Commands::Update => update::update_command(), Commands::Upgrade => upgrade::upgrade_bin(), Commands::Help => command_usage(nyx_usage()), diff --git a/src/nxfs/config.rs b/src/nxfs/config.rs index 4598f6d..7ffe636 100644 --- a/src/nxfs/config.rs +++ b/src/nxfs/config.rs @@ -31,6 +31,7 @@ Options: pub struct Config { pub config: ConfigHeader, pub user: ConfigUser, + pub plugins: ConfigPlugins, pub git: ConfigGit, pub behavior: ConfigBehavior, pub ui: ConfigUi, @@ -51,6 +52,11 @@ pub struct ConfigUser { pub update_list: Vec, } +#[derive(Debug, Deserialize, Serialize, Clone)] +pub struct ConfigPlugins { + pub list: Vec +} + #[derive(Debug, Deserialize, Serialize, Clone)] pub struct UserUpdateEntry { pub command: String, @@ -118,6 +124,9 @@ name = '' health_list = [] update_list = [] +[plugins] +list = [] + [git] profile_url = '' diff --git a/src/nxfs/nxs.rs b/src/nxfs/nxs.rs index 1b71fea..0b26fa9 100644 --- a/src/nxfs/nxs.rs +++ b/src/nxfs/nxs.rs @@ -139,7 +139,7 @@ pub fn create_data() { create_nxs_file() } -/// The function `create_nxs_file` creates a NXS file with a NXSHeader and project list. +/// The function `create_nxs_file` creates NXS file with a NXSHeader and project list. fn create_nxs_file() { // NXSHeader let header: NXSHeader = NXSHeader { diff --git a/src/plugins/mod.rs b/src/plugins/mod.rs new file mode 100644 index 0000000..d4f84ff --- /dev/null +++ b/src/plugins/mod.rs @@ -0,0 +1,122 @@ +use std::{ + env, fs, path::PathBuf, process::{Child, Command} +}; + +use lrncore::{path::change_work_dir, usage_exit::command_usage}; +use parser::parse_plugin_file; +use serde::Deserialize; + +use crate::{ + nxfs::config::{parse_config_file, LogLevel}, + utils::log::log_from_log_level, +}; + +pub mod parser; + +#[derive(Deserialize, Debug)] +pub struct Plugin { + pub plugin: PluginSection, + pub core: CoreSection, + pub commands: CommandsSection, +} + +#[derive(Deserialize, Debug)] +pub struct PluginSection { + pub name: String, + pub version: String, + pub enabled: bool, +} + +#[derive(Deserialize, Debug)] +pub struct CoreSection { + pub build_command: bool, + pub clean_command: bool, + pub run_command: bool, +} + +#[derive(Deserialize, Debug)] +pub struct CommandsSection { + pub init_command: Vec, + pub build_command: Vec, + pub clean_command: Vec, + pub run_command: Vec, +} + +fn plugins_help() -> &'static str { + (r" +Usage: nyx plugins [subcommand] [arguments] [options] + +Subcommands: + health Check plugins health + +Options: + -h, --help Show this help message + ") as _ +} + +pub fn plugins_command() { + let args: Vec = env::args().collect(); + if args.len() <= 2 { + command_usage(plugins_help()); + } + match args[2].as_str() { + "health" => health_plugins(), + _ => { + command_usage(plugins_help()); + } + } +} + +// Check plugins installed +fn health_plugins() { + // Load config file + let config = parse_config_file().expect("Failed to parse config file"); + let mut invalid_plugins_number: u8 = 0; + // Iterate over plugins list + for each in config.plugins.list { + let file_path: &str = &format!("plugins/{each}.toml"); + if !fs::exists(file_path).expect("Failed to check path") { + invalid_plugins_number += 1; + log_from_log_level( + LogLevel::Warn, + format!("Failed to load plugin: {each}").as_str(), + ); + } else { + match parse_plugin_file(&each) { + Ok(_) => (), + Err(e) => { + log_from_log_level( + LogLevel::Warn, + format!("Failed to parse plugin: {each}").as_str(), + ); + eprintln!("{e}"); + } + } + } + } + // Log depending on number of invalid plugins + if invalid_plugins_number != 0 { + log_from_log_level( + LogLevel::Warn, + format!("Plugin unabled to be load: {invalid_plugins_number}").as_str(), + ); + } else { + log_from_log_level(LogLevel::Info, "Successfully load all plugins"); + } +} + +/// Run init command from given plugin +pub fn run_init_command(plugin: Plugin, _name: &str, path: PathBuf) { + change_work_dir(path.as_os_str().to_str().expect("Failed to cast pathbuf to os_str to str")); + let mut init_commands_vec: Vec = plugin.commands.init_command; + let bin = init_commands_vec.remove(0); + let mut command: Child = Command::new(bin) + .args(init_commands_vec) + .spawn() + .expect("Failed to fork process"); + let wait_command = command.wait().expect("Failed to wait forked process"); + if !wait_command.success() { + log_from_log_level(LogLevel::Error, "Failed to run init command"); + } + log_from_log_level(LogLevel::Info, "Successfully run init command"); +} diff --git a/src/plugins/parser.rs b/src/plugins/parser.rs new file mode 100644 index 0000000..faf35fa --- /dev/null +++ b/src/plugins/parser.rs @@ -0,0 +1,22 @@ +use lrncore::path::change_work_dir; +use toml::de::Error as toml_error; + +use crate::utils; + +use super::Plugin; + +/// Parse given plugin and return struct +pub fn parse_plugin_file(name: &str) -> Result { + change_work_dir(&utils::env::get_nyx_env_var()); + let file_path: &str = &format!("plugins/{name}.toml"); + let file = + std::fs::read_to_string(file_path).expect("Failed to read the plugin file to string"); + let plugin: Plugin = match toml::from_str(&file) { + Ok(p) => p, + Err(e) => { + println!("Failed to parse the configuration file: {e:?}"); + return Err(e); + } + }; + Ok(plugin) +} diff --git a/src/projects/list/mod.rs b/src/projects/list/mod.rs index 8239e45..322468f 100644 --- a/src/projects/list/mod.rs +++ b/src/projects/list/mod.rs @@ -7,6 +7,7 @@ use crate::utils::get_select_project_option; use crate::utils::log; use lrncore::usage_exit::command_usage; use std::env; +use std::env::current_dir; use std::process::exit; use tabled::settings::Style; use tabled::Table; @@ -55,13 +56,14 @@ pub fn list_projects() { pub fn add_existing_project_to_list() { inquire::set_global_render_config(utils::get_render_config()); let ans = get_select_project_option("Which tech your project is using ?"); + let path = current_dir().expect("Failed to get pwd"); match ans { - Ok(choice) => create_repo_or_not(&choice), + Ok(choice) => create_repo_or_not(&choice, path.as_os_str().to_str().expect("Failed to cast pathbuf to os_str to str")), Err(_) => println!("There was an error, please try again"), } } -pub fn create_repo_or_not(tech: &str) { +pub fn create_repo_or_not(tech: &str, path: &str) { inquire::set_global_render_config(utils::get_render_config()); let choice: Vec<&str> = vec!["Yes", "No"]; let options = utils::get_select_option( @@ -70,17 +72,16 @@ pub fn create_repo_or_not(tech: &str) { ) .unwrap(); match options.as_str() { - "Yes" => create_repo_add_to_list(tech), - "No" => add_project_to_list(tech), + "Yes" => create_repo_add_to_list(tech, path), + "No" => add_project_to_list(tech, path), _ => { println!("There was an error, please try again") } } } -pub fn add_project_to_list(tech: &str) { - let current_dir = lrncore::path::get_current_path(); - let app_name = current_dir.split("/").last().unwrap().to_lowercase(); +pub fn add_project_to_list(tech: &str, path: &str) { + let app_name = path.split("/").last().unwrap().to_lowercase(); let mut repository_user_input: String; repository_user_input = utils::prompt_message( "Enter the url of the github's repository of the project: ", @@ -115,7 +116,7 @@ pub fn add_project_to_list(tech: &str) { let new_app: nxp::NXPContent = nxp::NXPContent { name: (app_name.to_owned()), tech: (tech.to_owned()), - location: (current_dir), + location: (path.to_owned()), repository: repository_user_input, github_project, version, @@ -123,9 +124,8 @@ pub fn add_project_to_list(tech: &str) { nxp::create_new_nxp(new_app); } -fn create_repo_add_to_list(tech: &str) { - let current_dir = lrncore::path::get_current_path(); - let app_name = current_dir.split("/").last().unwrap(); +fn create_repo_add_to_list(tech: &str, path: &str) { + let app_name = path.split("/").last().unwrap(); let choice = vec!["public", "private", "internal"]; let repository_visibility: String = utils::get_select_option("Select the repository visibility:", choice).unwrap(); @@ -164,7 +164,7 @@ fn create_repo_add_to_list(tech: &str) { let new_app: NXPContent = NXPContent { name: (app_name.to_owned()), tech: (tech.to_owned()), - location: (current_dir), + location: (path.to_owned()), repository, github_project, version, diff --git a/src/projects/mod.rs b/src/projects/mod.rs index a1b47c0..603778b 100644 --- a/src/projects/mod.rs +++ b/src/projects/mod.rs @@ -1,16 +1,15 @@ use crate::nxfs::config::LogLevel; +use crate::plugins::parser::parse_plugin_file; +use crate::plugins::run_init_command; use crate::utils::{self, log}; -use std::process::Command; +use std::path::PathBuf; use std::{fs, process::exit}; pub mod list; -mod templates; pub mod update; use copy::copy_command; use delete::select_remove_project; use list::{add_existing_project_to_list, list_projects}; -use serde::{Deserialize, Serialize}; -use std::env; -use tabled::Tabled; +use std::env::{self, current_dir}; use todo::choose_todo; use update::update_project_properties; pub mod delete; @@ -41,32 +40,6 @@ Options: ") as _ } -#[derive(Deserialize, Serialize, Debug, Tabled, Clone, PartialEq)] -pub struct Project { - pub id: String, - pub name: String, - pub tech: String, - pub location: String, - pub repository: String, - pub github_project: String, - pub version: String, - pub todo: String, -} - -#[derive(Tabled)] -#[allow(dead_code)] -pub struct ProjectShort { - pub id: String, - pub name: String, - pub tech: String, - pub location: String, -} - -#[derive(Deserialize, Serialize, Debug)] -pub struct Data { - pub project: Vec, -} - pub fn project_command() { let args: Vec = env::args().collect(); if args.len() <= 2 { @@ -127,102 +100,16 @@ fn new_project(name: &str) { Err(e) => println!("Failed to create directory: {e}"), } lrncore::path::change_work_dir(name); + let path = current_dir().expect("Failed to get pwd"); match option_select { - Ok(choice) => new_project_by_choice(&choice, name), + Ok(choice) => new_project_by_choice(&choice, name, path), Err(_) => println!("There was an error, please try again"), } } -fn new_project_by_choice(tech: &str, name: &str) { - match tech { - tech if tech == "Node.js" => new_nodejs_project(tech), - tech if tech == "Python" => new_python_project(tech), - tech if tech == "Golang" => new_golang_project(name, tech), - tech if tech == "Rust" => new_rust_project(tech), - _ => println!("please select a tech"), - } - list::create_repo_or_not(tech); +fn new_project_by_choice(tech: &str, name: &str, path: PathBuf) { + let plugin = parse_plugin_file(tech).expect("Failed to load plugin"); + run_init_command(plugin, name, path.clone()); + list::create_repo_or_not(tech, path.to_str().expect("Failed to cast pathbuf to str")); } -// tech project - -fn new_nodejs_project(tech: &str) { - let mut npm = Command::new("npm") - .arg("init") - .arg("-y") - .spawn() - .expect("npm command failed to execute"); - let status = npm.wait().expect("Failed to wait on npm process"); - if !status.success() { - panic!("Error init npm app"); - } - let mut ts = Command::new("npm") - .arg("install") - .arg("--save-dev") - .arg("typescript") - .spawn() - .expect("failed to install typescript"); - let ts_status = ts - .wait() - .expect("Failed to wait on typescript install process"); - if !ts_status.success() { - panic!("Error installing typescript"); - } - let mut touch = Command::new("touch") - .arg("tsconfig.json") - .spawn() - .expect("failed to generate tsconfig.json"); - let wait_touch = touch.wait().expect("Failed to wait touch command"); - if !wait_touch.success() { - panic!("Error in the execution of touch command"); - } - templates::new_gitignore(tech); - println!("Successfully generate the new Node.js project") -} - -fn new_python_project(tech: &str) { - let mut python3 = Command::new("python3") - .arg("-m") - .arg("venv") - .arg("./") - .spawn() - .expect("Failed to generate the virtual environment of python"); - let venv_status = python3 - .wait() - .expect("Failed to wait on the generation of venv"); - if !venv_status.success() { - panic!("Error init python virtual environment") - } - templates::new_gitignore(tech); - println!("Successfully generate the new Python project"); -} - -fn new_golang_project(name: &str, tech: &str) { - let mut go_init = Command::new("go") - .arg("mod") - .arg("init") - .arg(name) - .spawn() - .expect("Failed to generate the new Golang project"); - let go_status = go_init - .wait() - .expect("Failed to wait on the generation of the Golang project"); - if !go_status.success() { - panic!("Error init the Golang project"); - } - templates::new_gitignore(tech); -} - -fn new_rust_project(tech: &str) { - let mut cargo_init = Command::new("cargo") - .arg("init") - .spawn() - .expect("Failed to init the new Rust project using cargo."); - let cargo_status = cargo_init - .wait() - .expect("Failed to wait on the generation of the Rust project"); - if !cargo_status.success() { - panic!("Error init the Rust project") - } - templates::new_gitignore(tech); -} diff --git a/src/projects/templates/mod.rs b/src/projects/templates/mod.rs deleted file mode 100644 index 9bb2eed..0000000 --- a/src/projects/templates/mod.rs +++ /dev/null @@ -1,369 +0,0 @@ -use std::{fs, io::Write}; - -static NODEJS_GITIGNORE_TEMPLATE: &str = r#" -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* -.pnpm-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# Snowpack dependency directory (https://snowpack.dev/) -web_modules/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional stylelint cache -.stylelintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variable files -.env -.env.development.local -.env.test.local -.env.production.local -.env.local - -# parcel-bundler cache (https://parceljs.org/) -.cache -.parcel-cache - -# Next.js build output -.next -out - -# Nuxt.js build / generate output -.nuxt -dist - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and not Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# vuepress v2.x temp and cache directory -.temp -.cache - -# Docusaurus cache and generated files -.docusaurus - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port - -# Stores VSCode versions used for testing VSCode extensions -.vscode-test - -# yarn v2 -.yarn/cache -.yarn/unplugged -.yarn/build-state.yml -.yarn/install-state.gz -.pnp.* - "#; - -static PYTHON_GITIGNORE_TEMPLATE: &str = r#" -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -*.py,cover -.hypothesis/ -.pytest_cache/ -cover/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 -db.sqlite3-journal - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -.pybuilder/ -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# IPython -profile_default/ -ipython_config.py - -# pyenv -# For a library or package, you might want to ignore these files since the code is -# intended to run in multiple environments; otherwise, check them in: -# .python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# poetry -# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. -# This is especially recommended for binary packages to ensure reproducibility, and is more -# commonly ignored for libraries. -# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control -#poetry.lock - -# pdm -# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. -#pdm.lock -# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it -# in version control. -# https://pdm.fming.dev/latest/usage/project/#working-with-version-control -.pdm.toml -.pdm-python -.pdm-build/ - -# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm -__pypackages__/ - -# Celery stuff -celerybeat-schedule -celerybeat.pid - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ - -# pytype static type analyzer -.pytype/ - -# Cython debug symbols -cython_debug/ - -# PyCharm -# JetBrains specific template is maintained in a separate JetBrains.gitignore that can -# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore -# and can be added to the global gitignore or merged into this file. For a more nuclear -# option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ -"#; - -static GOLANG_GITIGNORE_TEMPLATE: &str = r#" -# If you prefer the allow list template instead of the deny list, see community template: -# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore -# -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Dependency directories (remove the comment below to include it) -# vendor/ - -# Go workspace file -go.work -go.work.sum - -# env file -.env -"#; - -static RUST_GITIGNORE_TEMPLATE: &str = r#" -# Generated by Cargo -# will have compiled files and executables -debug/ -target/ - -# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries -# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html -Cargo.lock - -# These are backup files generated by rustfmt -**/*.rs.bk - -# MSVC Windows builds of rustc generate these, which store debugging information -*.pdb - -# RustRover -# JetBrains specific template is maintained in a separate JetBrains.gitignore that can -# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore -# and can be added to the global gitignore or merged into this file. For a more nuclear -# option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ -"#; - -pub fn new_gitignore(tech: &str) -> &'static str{ - let file_template: &str = match tech { - "Node.js" => NODEJS_GITIGNORE_TEMPLATE, - "Python" => PYTHON_GITIGNORE_TEMPLATE, - "Golang" => GOLANG_GITIGNORE_TEMPLATE, - "Rust" => RUST_GITIGNORE_TEMPLATE, - _ => "", - }; - let template = &file_template; - let mut file = match fs::File::create(".gitignore") { - Ok(file) => file, - Err(e) => panic!("Failed to create file: {e}"), - }; - file.write_all(template.as_bytes()) - .expect("Failed to write to file"); - template -} diff --git a/src/utils/mod.rs b/src/utils/mod.rs index b073747..a277eaa 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -4,6 +4,7 @@ This module provides various utility functions for the NYX project management to This module is intended to be used internally by the NYX project management tool to handle various utility tasks such as environment variable retrieval, file operations, user prompts, and more. */ +use crate::nxfs::config::parse_config_file; use crate::nxfs::nxp::NXPContent; use std::fs::write; use std::{ @@ -46,16 +47,9 @@ pub fn get_render_config() -> RenderConfig<'static> { render_config } -pub fn get_tech_option() -> Vec<&'static str> { - let options: Vec<&str> = vec![ - "Node.js", - "Python", - "Golang", - "Rust", - "C++", - "Other", - ]; - options +pub fn get_tech_option() -> Vec { + let config = parse_config_file().expect("Failed to parse config file"); + config.plugins.list } pub fn get_select_project_option(prompt: &str) -> std::result::Result {