From 7988e0e187ae4a22c836a35837925dee915f19b3 Mon Sep 17 00:00:00 2001 From: Elouan Da Costa Peixoto Date: Mon, 28 Jul 2025 23:22:27 +0200 Subject: [PATCH 01/15] feat: enhance init codebase --- src/init/mod.rs | 16 ++++++++++++++++ src/main.rs | 4 +++- src/nxfs/nxs.rs | 2 +- 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 src/init/mod.rs diff --git a/src/init/mod.rs b/src/init/mod.rs new file mode 100644 index 0000000..4f92959 --- /dev/null +++ b/src/init/mod.rs @@ -0,0 +1,16 @@ +use std::env; + +use crate::{plugins, 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..922614b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,6 +14,8 @@ 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 @@ -103,7 +105,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(), 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 { From bb684e97ee4c081c18365a5ce9190c2cc90961a3 Mon Sep 17 00:00:00 2001 From: Elouan Da Costa Peixoto Date: Mon, 28 Jul 2025 23:22:45 +0200 Subject: [PATCH 02/15] refactor: remove unused project structure --- src/projects/mod.rs | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/src/projects/mod.rs b/src/projects/mod.rs index a1b47c0..e8c5b68 100644 --- a/src/projects/mod.rs +++ b/src/projects/mod.rs @@ -8,9 +8,7 @@ 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 todo::choose_todo; use update::update_project_properties; pub mod delete; @@ -41,32 +39,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 { From f20699427026f4e2d977adce647ac24417a1c539 Mon Sep 17 00:00:00 2001 From: Elouan Da Costa Peixoto Date: Mon, 28 Jul 2025 23:38:36 +0200 Subject: [PATCH 03/15] fix: import all needed fn and mod --- src/init/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/init/mod.rs b/src/init/mod.rs index 4f92959..3db9ac8 100644 --- a/src/init/mod.rs +++ b/src/init/mod.rs @@ -1,6 +1,6 @@ use std::env; -use crate::{plugins, utils::log::log_from_log_level}; +use crate::{nxfs, utils::log::log_from_log_level}; pub fn init_command() { let args: Vec = env::args().collect(); From 1a441ccf4afbe18dd881e4a4012c060790a2f622 Mon Sep 17 00:00:00 2001 From: Elouan Da Costa Peixoto Date: Mon, 28 Jul 2025 23:59:10 +0200 Subject: [PATCH 04/15] feat: add basic plugins command and plugins health check --- plugins/README.md | 1 + src/main.rs | 4 ++++ src/nxfs/config.rs | 9 ++++++++ src/plugins/mod.rs | 51 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+) create mode 100644 plugins/README.md create mode 100644 src/plugins/mod.rs diff --git a/plugins/README.md b/plugins/README.md new file mode 100644 index 0000000..23736cf --- /dev/null +++ b/plugins/README.md @@ -0,0 +1 @@ +# Here's the plugins directory used for plugin system diff --git a/src/main.rs b/src/main.rs index 922614b..e98143a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -33,6 +33,7 @@ enum Commands { Hello, Update, Config, + Plugins, Upgrade, Help, Version, @@ -57,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: @@ -95,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, @@ -115,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/plugins/mod.rs b/src/plugins/mod.rs new file mode 100644 index 0000000..03d8cff --- /dev/null +++ b/src/plugins/mod.rs @@ -0,0 +1,51 @@ +use std::{env, fs}; + +use lrncore::usage_exit::command_usage; + +use crate::{nxfs::config::{parse_config_file, LogLevel}, utils::log::log_from_log_level}; + +fn plugins_help() -> &'static str { + (r" +Usage: nyx plugins [subcommand] [arguments] [options] + +Subcommands: + check 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()); + } + } + // 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"); + } +} From b885eb071c18cacbcca6ba75d92ab0c6aa1d53c4 Mon Sep 17 00:00:00 2001 From: Elouan Da Costa Peixoto Date: Tue, 29 Jul 2025 00:04:59 +0200 Subject: [PATCH 05/15] feat: update .gitignore --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index f75f7c4..4470ee4 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,7 @@ # Build target/ src/data/* -.nxfs \ No newline at end of file +.nxfs +plugins/* +# Include plugins README.md +!plugins/README.md From 6e2bca4a6b5906885193b2a10cb2c84d278c5702 Mon Sep 17 00:00:00 2001 From: Elouan Da Costa Peixoto Date: Thu, 31 Jul 2025 00:30:27 +0200 Subject: [PATCH 06/15] feat: add parsing plugin file and basic plugin struct --- src/plugins/mod.rs | 41 +++++++++++++++++++++++++++++++++++++++++ src/plugins/parser.rs | 22 ++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 src/plugins/parser.rs diff --git a/src/plugins/mod.rs b/src/plugins/mod.rs index 03d8cff..96e1491 100644 --- a/src/plugins/mod.rs +++ b/src/plugins/mod.rs @@ -1,9 +1,42 @@ use std::{env, fs}; use lrncore::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)] +pub struct Plugin { + pub plugin: PluginSection, + pub core: CoreSection, + pub commands: CommandsSection, +} + +#[derive(Deserialize)] +pub struct PluginSection { + pub name: String, + pub version: String, + pub enabled: bool, +} + +#[derive(Deserialize)] +pub struct CoreSection { + pub build_command: bool, + pub clean_command: bool, + pub run_command: bool, +} + +#[derive(Deserialize)] +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] @@ -40,6 +73,14 @@ fn health_plugins() { 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 diff --git a/src/plugins/parser.rs b/src/plugins/parser.rs new file mode 100644 index 0000000..8fe51eb --- /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) +} From c06e1048a83a913567d19b8c461ff2d8f05aae6c Mon Sep 17 00:00:00 2001 From: Elouan Da Costa Peixoto Date: Fri, 1 Aug 2025 03:20:51 +0200 Subject: [PATCH 07/15] feat: add basic creation of project with new plugin system --- src/plugins/mod.rs | 50 ++++- src/projects/mod.rs | 97 +-------- src/projects/templates/mod.rs | 369 ---------------------------------- src/utils/mod.rs | 14 +- 4 files changed, 50 insertions(+), 480 deletions(-) delete mode 100644 src/projects/templates/mod.rs diff --git a/src/plugins/mod.rs b/src/plugins/mod.rs index 96e1491..51a6759 100644 --- a/src/plugins/mod.rs +++ b/src/plugins/mod.rs @@ -1,40 +1,46 @@ -use std::{env, fs}; +use std::{ + env, fs, + process::{Child, Command}, +}; use lrncore::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}; +use crate::{ + nxfs::config::{parse_config_file, LogLevel}, + utils::log::log_from_log_level, +}; pub mod parser; -#[derive(Deserialize)] +#[derive(Deserialize, Debug)] pub struct Plugin { pub plugin: PluginSection, pub core: CoreSection, pub commands: CommandsSection, } -#[derive(Deserialize)] +#[derive(Deserialize, Debug)] pub struct PluginSection { pub name: String, pub version: String, pub enabled: bool, } -#[derive(Deserialize)] +#[derive(Deserialize, Debug)] pub struct CoreSection { pub build_command: bool, pub clean_command: bool, pub run_command: bool, } -#[derive(Deserialize)] +#[derive(Deserialize, Debug)] pub struct CommandsSection { pub init_command: Vec, pub build_command: Vec, pub clean_command: Vec, - pub run_command: Vec + pub run_command: Vec, } fn plugins_help() -> &'static str { @@ -72,12 +78,18 @@ fn health_plugins() { 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()); + 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()); + log_from_log_level( + LogLevel::Warn, + format!("Failed to parse plugin: {each}").as_str(), + ); eprintln!("{e}"); } } @@ -85,8 +97,26 @@ fn health_plugins() { } // 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()); + 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) { + 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/projects/mod.rs b/src/projects/mod.rs index e8c5b68..a00c433 100644 --- a/src/projects/mod.rs +++ b/src/projects/mod.rs @@ -1,13 +1,14 @@ 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::{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 lrncore::path::change_work_dir; use std::env; use todo::choose_todo; use update::update_project_properties; @@ -106,95 +107,9 @@ fn new_project(name: &str) { } 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"), - } + println!("{:?}", env::current_dir()); + let plugin = parse_plugin_file(tech).expect("Failed to load plugin"); + run_init_command(plugin); list::create_repo_or_not(tech); } -// 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 { From 8b5ed0a858a131be0e8712943482a423d2bf2ada Mon Sep 17 00:00:00 2001 From: Elouan Da Costa Peixoto Date: Fri, 1 Aug 2025 04:02:03 +0200 Subject: [PATCH 08/15] fix: use correct path when creating new project but still error when adding existing project --- src/plugins/mod.rs | 9 +++++---- src/projects/list/mod.rs | 24 ++++++++++++------------ src/projects/mod.rs | 13 +++++++------ 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/plugins/mod.rs b/src/plugins/mod.rs index 51a6759..97f3900 100644 --- a/src/plugins/mod.rs +++ b/src/plugins/mod.rs @@ -1,9 +1,8 @@ use std::{ - env, fs, - process::{Child, Command}, + env, fs, path::PathBuf, process::{Child, Command} }; -use lrncore::usage_exit::command_usage; +use lrncore::{path::change_work_dir, usage_exit::command_usage}; use parser::parse_plugin_file; use serde::Deserialize; @@ -107,7 +106,8 @@ fn health_plugins() { } /// Run init command from given plugin -pub fn run_init_command(plugin: Plugin) { +pub fn run_init_command(plugin: Plugin, 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) @@ -115,6 +115,7 @@ pub fn run_init_command(plugin: Plugin) { .spawn() .expect("Failed to fork process"); let wait_command = command.wait().expect("Failed to wait forked process"); + println!("debug: {:?}", env::current_dir()); if !wait_command.success() { log_from_log_level(LogLevel::Error, "Failed to run init command"); } 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 a00c433..06f6acb 100644 --- a/src/projects/mod.rs +++ b/src/projects/mod.rs @@ -2,6 +2,7 @@ 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::path::PathBuf; use std::{fs, process::exit}; pub mod list; pub mod update; @@ -9,7 +10,7 @@ use copy::copy_command; use delete::select_remove_project; use list::{add_existing_project_to_list, list_projects}; use lrncore::path::change_work_dir; -use std::env; +use std::env::{self, current_dir}; use todo::choose_todo; use update::update_project_properties; pub mod delete; @@ -100,16 +101,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) { - println!("{:?}", env::current_dir()); +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); - list::create_repo_or_not(tech); + run_init_command(plugin, path.clone()); + list::create_repo_or_not(tech, path.to_str().expect("Failed to cast pathbuf to str")); } From 44661a292c853db84cce85009848fa7446ddbf52 Mon Sep 17 00:00:00 2001 From: Elouan Da Costa Peixoto Date: Thu, 21 Aug 2025 00:08:08 +0200 Subject: [PATCH 09/15] feat(plugins): pass project name args to init command from plugins --- src/plugins/mod.rs | 2 +- src/projects/mod.rs | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/plugins/mod.rs b/src/plugins/mod.rs index 97f3900..1f92bc7 100644 --- a/src/plugins/mod.rs +++ b/src/plugins/mod.rs @@ -106,7 +106,7 @@ fn health_plugins() { } /// Run init command from given plugin -pub fn run_init_command(plugin: Plugin, path: PathBuf) { +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); diff --git a/src/projects/mod.rs b/src/projects/mod.rs index 06f6acb..603778b 100644 --- a/src/projects/mod.rs +++ b/src/projects/mod.rs @@ -9,7 +9,6 @@ pub mod update; use copy::copy_command; use delete::select_remove_project; use list::{add_existing_project_to_list, list_projects}; -use lrncore::path::change_work_dir; use std::env::{self, current_dir}; use todo::choose_todo; use update::update_project_properties; @@ -110,7 +109,7 @@ fn new_project(name: &str) { 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, path.clone()); + run_init_command(plugin, name, path.clone()); list::create_repo_or_not(tech, path.to_str().expect("Failed to cast pathbuf to str")); } From 805d5a893ebef944471c4a41d7b53ac86dd2e457 Mon Sep 17 00:00:00 2001 From: Elouan Da Costa Peixoto Date: Thu, 4 Sep 2025 21:43:55 +0200 Subject: [PATCH 10/15] chore: bump version to 2.2.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/main.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5771d82..7c84396 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -415,7 +415,7 @@ dependencies = [ [[package]] name = "nyx" -version = "2.11.0" +version = "2.2.0" dependencies = [ "bincode", "chrono", diff --git a/Cargo.toml b/Cargo.toml index d5cfcfc..6eb4a0b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nyx" -version = "2.11.0" +version = "2.2.0" edition = "2021" authors = ["Elouan DA COSTA PEIXOTO "] description = "A CLI tool for managing your projects." diff --git a/src/main.rs b/src/main.rs index e98143a..236c95d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,7 +20,7 @@ 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.2.0"; enum Commands { Init, CatNxs, From 2cdec6a05c042027533e6172ce500094873827ab Mon Sep 17 00:00:00 2001 From: Elouan Da Costa Peixoto Date: Thu, 4 Sep 2025 21:48:29 +0200 Subject: [PATCH 11/15] feat(docs): add usage and example in the plugins README --- plugins/README.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/plugins/README.md b/plugins/README.md index 23736cf..8d55088 100644 --- a/plugins/README.md +++ b/plugins/README.md @@ -1 +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 = [] +``` From cca5293b0f7b6c7965c36c8cd061519949c6ee24 Mon Sep 17 00:00:00 2001 From: Elouan Da Costa Peixoto Date: Thu, 4 Sep 2025 21:52:30 +0200 Subject: [PATCH 12/15] feat(git): add misc section with ALL possible path for fucking DS_Store files >:( --- .gitignore | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitignore b/.gitignore index 4470ee4..7062fdd 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,9 @@ src/data/* plugins/* # Include plugins README.md !plugins/README.md + +# misc +.DS_Store +plugins/.DS_Store +src/.DS_Store +src/*/.DS_Store From debdc5d666ce04598d15dc53ff10cb7e2523147e Mon Sep 17 00:00:00 2001 From: Elouan Da Costa Peixoto Date: Thu, 4 Sep 2025 21:58:48 +0200 Subject: [PATCH 13/15] fix(plugins): set name params to unused to avoid warning compilation failed and used it in futur update --- src/plugins/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/mod.rs b/src/plugins/mod.rs index 1f92bc7..d10b81a 100644 --- a/src/plugins/mod.rs +++ b/src/plugins/mod.rs @@ -106,7 +106,7 @@ fn health_plugins() { } /// Run init command from given plugin -pub fn run_init_command(plugin: Plugin, name: &str, path: PathBuf) { +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); From d42aba46e0029bef2a2d924a835a85a7c25c5fd6 Mon Sep 17 00:00:00 2001 From: Elouan Da Costa Peixoto Date: Thu, 4 Sep 2025 22:08:47 +0200 Subject: [PATCH 14/15] fix: version to 2.12.0 instead of 2.2.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/main.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7c84396..a71b664 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -415,7 +415,7 @@ dependencies = [ [[package]] name = "nyx" -version = "2.2.0" +version = "2.12.0" dependencies = [ "bincode", "chrono", diff --git a/Cargo.toml b/Cargo.toml index 6eb4a0b..dced863 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nyx" -version = "2.2.0" +version = "2.12.0" edition = "2021" authors = ["Elouan DA COSTA PEIXOTO "] description = "A CLI tool for managing your projects." diff --git a/src/main.rs b/src/main.rs index 236c95d..03a768c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,7 +20,7 @@ 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.2.0"; +const VERSION: &str = "2.12.0"; enum Commands { Init, CatNxs, From 827829e332d0fa69dd29654f4ca52236f589e0f8 Mon Sep 17 00:00:00 2001 From: Elouan Da Costa Peixoto Date: Thu, 4 Sep 2025 23:29:45 +0200 Subject: [PATCH 15/15] fix: inconsistence in code between command and help commands --- src/main.rs | 2 +- src/plugins/mod.rs | 3 +-- src/plugins/parser.rs | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main.rs b/src/main.rs index 03a768c..7079ba1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -58,7 +58,7 @@ Commands: hello Display helpful information about today upgrade Update the current version of NYX config Manage nyx configuration - Plugins Manage plugins + plugins Manage plugins help Show this help message Options: diff --git a/src/plugins/mod.rs b/src/plugins/mod.rs index d10b81a..d4f84ff 100644 --- a/src/plugins/mod.rs +++ b/src/plugins/mod.rs @@ -47,7 +47,7 @@ fn plugins_help() -> &'static str { Usage: nyx plugins [subcommand] [arguments] [options] Subcommands: - check Check plugins health + health Check plugins health Options: -h, --help Show this help message @@ -115,7 +115,6 @@ pub fn run_init_command(plugin: Plugin, _name: &str, path: PathBuf) { .spawn() .expect("Failed to fork process"); let wait_command = command.wait().expect("Failed to wait forked process"); - println!("debug: {:?}", env::current_dir()); if !wait_command.success() { log_from_log_level(LogLevel::Error, "Failed to run init command"); } diff --git a/src/plugins/parser.rs b/src/plugins/parser.rs index 8fe51eb..faf35fa 100644 --- a/src/plugins/parser.rs +++ b/src/plugins/parser.rs @@ -9,7 +9,7 @@ use super::Plugin; 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 = + 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,