Commit 2b785125 authored by Éloïs's avatar Éloïs

[ref] core: externalize cli app definition

parent 095b184e
Pipeline #5428 canceled with stages
in 35 seconds
......@@ -127,7 +127,7 @@ tests:win64:stable:
- cargo test --package durs-blockchain-dal --target=x86_64-pc-windows-gnu
- cargo test --package durs-message --target=x86_64-pc-windows-gnu
- cargo test --package durs-blockchain --target=x86_64-pc-windows-gnu
- cargo test --package duniter-core --target=x86_64-pc-windows-gnu
- cargo test --package durs-core --target=x86_64-pc-windows-gnu
#- cargo test --package durs-skeleton-module --target=x86_64-pc-windows-gnu
tests:linux64:beta:
......
......@@ -284,28 +284,6 @@ dependencies = [
"dup-crypto-tests-tools 0.1.0",
]
[[package]]
name = "duniter-core"
version = "0.1.0-a0.1"
dependencies = [
"dirs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"duniter-network 0.1.0-a0.1",
"dup-crypto 0.6.0",
"durs-blockchain 0.1.0-a0.1",
"durs-conf 0.1.0-a0.1",
"durs-message 0.1.0-a0.1",
"durs-module 0.1.0-a0.1",
"durs-network-documents 0.3.1",
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.86 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.86 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)",
"simplelog 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"structopt 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "duniter-network"
version = "0.1.0-a0.1"
......@@ -347,7 +325,9 @@ dependencies = [
name = "durs"
version = "0.1.1-a1"
dependencies = [
"duniter-core 0.1.0-a0.1",
"duniter-network 0.1.0-a0.1",
"durs-core 0.1.0-a0.1",
"durs-module 0.1.0-a0.1",
"durs-tui 0.1.0-a0.1",
"durs-ws2p 0.1.0-a0.1",
"durs-ws2p-v1-legacy 0.1.0-a0.1",
......@@ -429,6 +409,29 @@ dependencies = [
"serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "durs-core"
version = "0.1.0-a0.1"
dependencies = [
"dirs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"duniter-network 0.1.0-a0.1",
"dup-crypto 0.6.0",
"durs-blockchain 0.1.0-a0.1",
"durs-common-tools 0.1.0",
"durs-conf 0.1.0-a0.1",
"durs-message 0.1.0-a0.1",
"durs-module 0.1.0-a0.1",
"durs-network-documents 0.3.1",
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.86 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.86 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)",
"simplelog 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"structopt 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "durs-message"
version = "0.1.0-a0.1"
......
......@@ -12,7 +12,9 @@ categories = ["command-line-utilities", "network-programming"]
edition = "2018"
[dependencies]
duniter-core = { path = "../../lib/core/core" }
duniter-network = { path = "../../lib/core/network" }
durs-core = { path = "../../lib/core/core" }
durs-module = { path = "../../lib/core/module" }
#durs-skeleton = { path = "../../lib/modules/skeleton" }
durs-ws2p = { path = "../../lib/modules/ws2p/ws2p" }
durs-ws2p-v1-legacy = { path = "../../lib/modules/ws2p-v1-legacy" }
......
// Copyright (C) 2018 The Durs Project Developers.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//! Command line options for classic Durs nodes (no specialization).
use duniter_network::cli::sync::SyncOpt;
use durs_core::commands::dbex::DbExOpt;
use durs_core::commands::keys::KeysOpt;
use durs_core::commands::modules::{DisableOpt, EnableOpt, ListModulesOpt};
use durs_core::commands::reset::ResetOpt;
use durs_core::commands::start::StartOpt;
use durs_core::commands::{
DursCommand, DursCommandEnum, DursCoreCommand, DursCoreOptions, ExecutableModuleCommand,
};
use durs_core::errors::DursCoreError;
use durs_core::DursCore;
use durs_ws2p_v1_legacy::{WS2PModule, WS2POpt};
use log::Level;
use std::path::PathBuf;
use structopt::StructOpt;
#[derive(StructOpt, Debug)]
#[structopt(
name = "durs",
raw(setting = "structopt::clap::AppSettings::ColoredHelp")
)]
/// Durs command line options
pub struct DursCliOpt {
/// Durs subcommand
#[structopt(subcommand)]
cmd: DursCliSubCommand,
/// Path where user profiles are persisted
#[structopt(long = "profiles-path", parse(from_os_str))]
profiles_path: Option<PathBuf>,
/// Keypairs file path
#[structopt(long = "keypairs-file", parse(from_os_str))]
keypairs_file: Option<PathBuf>,
/// Set log level. (Defaults to INFO).
/// Available levels: [ERROR, WARN, INFO, DEBUG, TRACE]
#[structopt(short = "l", long = "logs", raw(next_line_help = "true"))]
logs_level: Option<Level>,
/// Print logs in standard output
#[structopt(long = "log-stdout")]
log_stdout: bool,
/// Set a custom user profile name
#[structopt(short = "p", long = "profile-name")]
profile_name: Option<String>,
}
impl ExecutableModuleCommand for DursCliOpt {
/// Execute command
fn execute_module_command(self, options: DursCoreOptions) -> Result<(), DursCoreError> {
match self.cmd {
DursCliSubCommand::Ws2p1(module_opts) => {
DursCore::execute_module_command::<WS2PModule>(
options,
module_opts,
env!("CARGO_PKG_NAME"),
env!("CARGO_PKG_VERSION"),
)
}
_ => unreachable!(),
}
}
}
impl DursCliOpt {
/// Into Durs command
pub fn into_durs_command(self) -> DursCommand<DursCliOpt> {
let options = DursCoreOptions {
keypairs_file: self.keypairs_file.clone(),
logs_level: self.logs_level,
log_stdout: self.log_stdout,
profile_name: self.profile_name.clone(),
profiles_path: self.profiles_path.clone(),
};
match self.cmd {
DursCliSubCommand::DbExOpt(opts) => DursCommand {
options,
command: DursCommandEnum::Core(DursCoreCommand::DbExOpt(opts)),
},
DursCliSubCommand::DisableOpt(opts) => DursCommand {
options,
command: DursCommandEnum::Core(DursCoreCommand::DisableOpt(opts)),
},
DursCliSubCommand::EnableOpt(opts) => DursCommand {
options,
command: DursCommandEnum::Core(DursCoreCommand::EnableOpt(opts)),
},
DursCliSubCommand::KeysOpt(opts) => DursCommand {
options,
command: DursCommandEnum::Core(DursCoreCommand::KeysOpt(opts)),
},
DursCliSubCommand::ListModulesOpt(opts) => DursCommand {
options,
command: DursCommandEnum::Core(DursCoreCommand::ListModulesOpt(opts)),
},
DursCliSubCommand::ResetOpt(opts) => DursCommand {
options,
command: DursCommandEnum::Core(DursCoreCommand::ResetOpt(opts)),
},
DursCliSubCommand::StartOpt(opts) => DursCommand {
options,
command: DursCommandEnum::Core(DursCoreCommand::StartOpt(opts)),
},
DursCliSubCommand::SyncOpt(opts) => DursCommand {
options,
command: DursCommandEnum::Core(DursCoreCommand::SyncOpt(opts)),
},
_ => DursCommand {
options,
command: DursCommandEnum::Other(self),
},
}
}
}
#[derive(StructOpt, Debug, Clone)]
/// Classic Durs nodes subcommand
pub enum DursCliSubCommand {
/// Database explorer
#[structopt(
name = "dbex",
raw(setting = "structopt::clap::AppSettings::ColoredHelp")
)]
DbExOpt(DbExOpt),
/// Disable a module
#[structopt(name = "disable")]
DisableOpt(DisableOpt),
/// Enable a module
#[structopt(name = "enable")]
EnableOpt(EnableOpt),
/// Keys operations
#[structopt(
name = "keys",
author = "inso <inso@tuta.io>",
raw(setting = "structopt::clap::AppSettings::ColoredHelp")
)]
KeysOpt(KeysOpt),
/// List available modules
#[structopt(name = "modules")]
ListModulesOpt(ListModulesOpt),
/// Reset data or conf or all
#[structopt(
name = "reset",
raw(setting = "structopt::clap::AppSettings::ColoredHelp")
)]
ResetOpt(ResetOpt),
/// Start node
#[structopt(name = "start")]
StartOpt(StartOpt),
/// Synchronize
#[structopt(name = "sync")]
SyncOpt(SyncOpt),
/// WS2P1 module subcommand
#[structopt(name = "ws2p1")]
Ws2p1(WS2POpt),
}
// Copyright (C) 2018 The Duniter Project Developers.
// Copyright (C) 2018 The Durs Project Developers.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
......@@ -13,7 +13,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//! Main function for classic duniter-rust nodes (no specialization).
//! Main function for classic Durs nodes (no specialization).
#![deny(
missing_docs,
......@@ -27,39 +27,57 @@
unused_qualifications
)]
pub mod cli;
mod init;
pub use duniter_core::cli::DursOpt;
pub use duniter_core::*;
use crate::cli::DursCliOpt;
use crate::init::init;
use durs_core::durs_plug;
use log::error;
use structopt::StructOpt;
#[cfg(unix)]
pub use durs_tui::TuiModule;
use init::init;
//pub use durs_skeleton::SkeletonModule;
pub use durs_ws2p_v1_legacy::WS2PModule;
pub use durs_ws2p_v1_legacy::{WS2PModule, WS2POpt};
//pub use durs_ws2p::WS2Pv2Module;
use log::error;
use structopt::StructOpt;
/// Main function
/// Durs command line edition, main function
#[cfg(unix)]
#[cfg(not(target_arch = "arm"))]
fn main() {
init();
durs_core_server!(
durs_inject_cli![WS2PModule /*, SkeletonModule ,DasaModule*/],
durs_plug!([WS2PModule], [TuiModule /*, SkeletonModule ,DasaModule*/])
)
if let Err(err) = DursCliOpt::from_args()
.into_durs_command()
.execute(durs_plug!(
[WS2PModule],
[TuiModule /*, SkeletonModule ,DasaModule*/]
))
{
println!("{}", err);
error!("{}", err);
}
}
#[cfg(unix)]
#[cfg(target_arch = "arm")]
fn main() {
init();
durs_core_server!(
durs_inject_cli![WS2PModule],
durs_plug!([WS2PModule], [TuiModule])
)
if let Err(err) = DursCliOpt::from_args()
.into_durs_command()
.execute(durs_plug!([WS2PModule], [TuiModule /*, SkeletonModule*/]))
{
println!("{}", err);
error!("{}", err);
}
}
#[cfg(windows)]
fn main() {
init();
durs_core_server!(durs_inject_cli![WS2PModule], durs_plug!([WS2PModule], []))
if let Err(err) = DursCliOpt::from_args()
.into_durs_command()
.execute(durs_plug!([WS2PModule], []))
{
println!("{}", err);
error!("{}", err);
}
}
......@@ -90,12 +90,19 @@ pub fn show_keys(key_pairs: DuniterKeyPairs) {
/// Save keys after a command run
pub fn save_keypairs(
profiles_path: &Option<PathBuf>,
profile_name: &str,
profile_path: PathBuf,
keypairs_file_path: &Option<PathBuf>,
key_pairs: DuniterKeyPairs,
) {
let conf_keys_path = keypairs_filepath(profiles_path, profile_name);
write_keypairs_file(&conf_keys_path, &key_pairs).expect("could not write keypairs file");
) -> Result<(), std::io::Error> {
let conf_keys_path: PathBuf = if let Some(keypairs_file_path) = keypairs_file_path {
keypairs_file_path.to_path_buf()
} else {
let mut conf_keys_path = profile_path;
conf_keys_path.push(crate::constants::KEYPAIRS_FILENAME);
conf_keys_path
};
write_keypairs_file(&conf_keys_path, &key_pairs)?;
Ok(())
}
fn question_prompt(question: &str, answers: Vec<String>) -> Result<String, WizardError> {
......
......@@ -441,12 +441,8 @@ pub fn get_user_datas_folder() -> &'static str {
/// Returns the path to the folder containing the currency datas of the running profile
#[inline]
pub fn datas_path(
profiles_path: &Option<PathBuf>,
profile_name: &str,
currency: &CurrencyName,
) -> PathBuf {
let mut datas_path = get_profile_path(profiles_path, profile_name);
pub fn datas_path(profile_path: PathBuf, currency: &CurrencyName) -> PathBuf {
let mut datas_path = profile_path;
datas_path.push(currency.to_string());
if !datas_path.as_path().exists() {
fs::create_dir(datas_path.as_path()).expect("Impossible to create currency dir !");
......@@ -502,12 +498,9 @@ pub fn keypairs_filepath(profiles_path: &Option<PathBuf>, profile: &str) -> Path
/// Load configuration.
pub fn load_conf(
profile: &str,
profiles_path: &Option<PathBuf>,
mut profile_path: PathBuf,
keypairs_file_path: &Option<PathBuf>,
) -> (DuRsConf, DuniterKeyPairs) {
let mut profile_path = get_profile_path(profiles_path, profile);
// Load conf
let (conf, keypairs) = load_conf_at_path(profile_path.clone(), keypairs_file_path);
......
[package]
name = "duniter-core"
name = "durs-core"
version = "0.1.0-a0.1"
authors = ["librelois <elois@ifee.fr>"]
description = "Duniter-rs core."
description = "Durs core."
license = "AGPL-3.0"
edition = "2018"
[lib]
path = "lib.rs"
path = "src/lib.rs"
[dependencies]
dirs = "1.0.2"
durs-blockchain = { path = "../../modules/blockchain/blockchain" }
durs-common-tools = { path = "../../tools/common-tools" }
durs-conf = { path = "../conf" }
dup-crypto = { path = "../../tools/crypto" }
durs-message = { path = "../message" }
......
......@@ -15,6 +15,7 @@
//! Crate containing Duniter-rust core.
use crate::errors::DursCoreError;
use durs_conf::ChangeGlobalConf;
use durs_module::DursConfTrait;
use std::path::PathBuf;
......@@ -24,7 +25,7 @@ pub fn change_global_conf<DC: DursConfTrait>(
profile_path: &PathBuf,
conf: &mut DC,
user_request: ChangeGlobalConf,
) {
) -> Result<(), DursCoreError> {
match user_request {
ChangeGlobalConf::ChangeCurrency(_) => {}
ChangeGlobalConf::DisableModule(module_id) => conf.disable(module_id),
......@@ -34,7 +35,5 @@ pub fn change_global_conf<DC: DursConfTrait>(
// Write new conf
durs_conf::write_conf_file(&durs_conf::get_conf_path(profile_path), conf)
.expect("IOError : Fail to update conf ");
println!("Configuration successfully updated.");
.map_err(DursCoreError::FailUpdateConf)
}
......@@ -15,6 +15,13 @@
//! Durs-core cli : dbex subcommands.
use crate::commands::DursExecutableCoreCommand;
use crate::dbex;
use crate::errors::DursCoreError;
use crate::DursCore;
use durs_blockchain::{DBExQuery, DBExTxQuery, DBExWotQuery};
use durs_conf::DuRsConf;
#[derive(StructOpt, Debug, Clone)]
#[structopt(
name = "dbex",
......@@ -91,3 +98,49 @@ pub struct BalanceOpt {
/// public key or uid
pub address: String,
}
impl DursExecutableCoreCommand for DbExOpt {
fn execute(self, durs_core: DursCore<DuRsConf>) -> Result<(), DursCoreError> {
let profile_path = durs_core.soft_meta_datas.profile_path;
match self.subcommand {
DbExSubCommand::DistanceOpt(distance_opts) => dbex(
profile_path,
&durs_core.soft_meta_datas.conf,
self.csv,
&DBExQuery::WotQuery(DBExWotQuery::AllDistances(distance_opts.reverse)),
),
DbExSubCommand::MemberOpt(member_opts) => dbex(
profile_path,
&durs_core.soft_meta_datas.conf,
self.csv,
&DBExQuery::WotQuery(DBExWotQuery::MemberDatas(member_opts.uid)),
),
DbExSubCommand::MembersOpt(members_opts) => {
if members_opts.expire {
dbex(
profile_path,
&durs_core.soft_meta_datas.conf,
self.csv,
&DBExQuery::WotQuery(DBExWotQuery::ExpireMembers(members_opts.reverse)),
);
} else {
dbex(
profile_path,
&durs_core.soft_meta_datas.conf,
self.csv,
&DBExQuery::WotQuery(DBExWotQuery::ListMembers(members_opts.reverse)),
);
}
}
DbExSubCommand::BalanceOpt(balance_opts) => dbex(
profile_path,
&durs_core.soft_meta_datas.conf,
self.csv,
&DBExQuery::TxQuery(DBExTxQuery::Balance(balance_opts.address)),
),
}
Ok(())
}
}
......@@ -15,6 +15,12 @@
//! Durs-core cli : keys subcommands.
use crate::commands::DursExecutableCoreCommand;
use crate::errors::DursCoreError;
use crate::DursCore;
use durs_conf::keys::*;
use durs_conf::DuRsConf;
#[derive(StructOpt, Debug, Clone)]
#[structopt(
name = "keys",
......@@ -125,3 +131,46 @@ pub struct WizardOpt {}
#[derive(StructOpt, Debug, Copy, Clone)]
/// ShowOpt
pub struct ShowOpt {}
impl DursExecutableCoreCommand for KeysOpt {
fn execute(self, durs_core: DursCore<DuRsConf>) -> Result<(), DursCoreError> {
let profile_path = durs_core.soft_meta_datas.profile_path;
let keypairs_file = durs_core.options.keypairs_file;
let keypairs = durs_core.keypairs;
match self.subcommand {
KeysSubCommand::Wizard(_) => {
let new_keypairs = key_wizard(keypairs).unwrap();
save_keypairs(profile_path, &keypairs_file, new_keypairs)
.map_err(DursCoreError::FailWriteKeypairsFile)
}
KeysSubCommand::Modify(modify_opt) => match modify_opt.subcommand {
ModifySubCommand::NetworkSaltPassword(network_opt) => {
let new_keypairs =
modify_network_keys(&network_opt.salt, &network_opt.password, keypairs);
save_keypairs(profile_path, &keypairs_file, new_keypairs)
.map_err(DursCoreError::FailWriteKeypairsFile)
}
ModifySubCommand::MemberSaltPassword(member_opt) => {
let new_keypairs =
modify_member_keys(&member_opt.salt, &member_opt.password, keypairs);
save_keypairs(profile_path, &keypairs_file, new_keypairs)
.map_err(DursCoreError::FailWriteKeypairsFile)
}
},
KeysSubCommand::Clear(clear_opt) => {
let new_keypairs = clear_keys(
clear_opt.network || clear_opt.all,
clear_opt.member || clear_opt.all,
keypairs,
);
save_keypairs(profile_path, &keypairs_file, new_keypairs)
.map_err(DursCoreError::FailWriteKeypairsFile)
}
KeysSubCommand::Show(_) => {
show_keys(keypairs);
Ok(())
}
}
}
}
......@@ -21,79 +21,93 @@ pub mod modules;
pub mod reset;
pub mod start;
pub use crate::cli::keys::KeysOpt;
pub use crate::dbex::*;
pub use crate::modules::*;
pub use crate::reset::*;
pub use crate::start::*;
use crate::errors::DursCoreError;
use crate::{durs_exec_core_cmd, DursCore};
pub use dbex::*;
pub use duniter_network::cli::sync::SyncOpt;
use durs_conf::DuRsConf;
pub use keys::KeysOpt;
use log::Level;
pub use modules::*;
pub use reset::*;
pub use start::*;
use std::path::PathBuf;
#[derive(StructOpt, Debug)]
#[structopt(
name = "durs",
raw(setting = "structopt::clap::AppSettings::ColoredHelp")
)]
/// Durs command line options
pub struct DursOpt {
/// CoreSubCommand
#[structopt(subcommand)]
cmd: CoreSubCommand,
/// Path where user profiles are persisted
#[structopt(long = "profiles-path", parse(from_os_str))]
profiles_path: Option<PathBuf>,