Skip to content

Commit 710c424

Browse files
author
Vyacheslav
authored
Merge pull request hyperledger-indy#668 from hyperledger/feature/payments
Feature Payments
2 parents 20777cd + 408b1fe commit 710c424

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+7258
-308
lines changed

Jenkinsfile.cd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ def windowsTesting() {
266266
"PATH=$WORKSPACE\\libindy\\prebuilt\\lib;$PATH",
267267
"RUST_BACKTRACE=1"
268268
]) {
269+
bat "cargo build --release"
269270
bat "cargo test --release --no-run"
270271

271272
echo "Windows Libindy Test: Run tests"

Jenkinsfile.ci

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ def windowsTesting() {
4545
"PATH=$WORKSPACE\\libindy\\prebuilt\\lib;$PATH",
4646
"RUST_BACKTRACE=1"
4747
]) {
48+
bat "cargo build"
4849
bat "cargo test --no-run"
4950

5051
echo "Windows Libindy Test: Run tests"
@@ -113,6 +114,7 @@ def macosTesting() {
113114
setupRust()
114115
setupBrewPackages()
115116
sh "cargo build"
117+
sh "cargo test --no-run"
116118
// TODO testing
117119
}
118120

cli/Cargo.lock

Lines changed: 39 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cli/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@ name = "indy-cli"
33
version = "0.1.0"
44
authors = ["Vyacheslav Gudkov <[email protected]>"]
55

6+
[features]
7+
payments_cli_tests = []
8+
69
[dependencies]
710
ansi_term = "0.10"
811
chrono = "0.4"
912
env_logger = "0.4"
1013
unescape = "0.1"
1114
lazy_static = "0.2"
1215
libc = "0.2"
16+
libloading = "0.5.0"
1317
linefeed = "0.3"
1418
log = "0.3"
1519
prettytable-rs = "0.6.7"

cli/src/command_executor.rs

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
extern crate rpassword;
2+
extern crate libloading;
23

34
use unescape::unescape;
45

@@ -140,6 +141,7 @@ pub struct CommandContext {
140141
is_exit: RefCell<bool>,
141142
int_values: RefCell<HashMap<&'static str, i32>>,
142143
string_values: RefCell<HashMap<&'static str, String>>,
144+
plugins: RefCell<HashMap<String, libloading::Library>>,
143145
}
144146

145147
#[allow(dead_code)] //FIXME
@@ -151,6 +153,7 @@ impl CommandContext {
151153
is_exit: RefCell::new(false),
152154
int_values: RefCell::new(HashMap::new()),
153155
string_values: RefCell::new(HashMap::new()),
156+
plugins: RefCell::new(HashMap::new()),
154157
}
155158
}
156159

@@ -210,6 +213,11 @@ impl CommandContext {
210213
pub fn get_string_value(&self, key: &'static str) -> Option<String> {
211214
self.string_values.borrow().get(key).map(String::to_owned)
212215
}
216+
217+
pub fn add_plugin(&self, plugin_name: &str, plugin: libloading::Library) {
218+
//TODO check already exists. Also check libindy
219+
self.plugins.borrow_mut().insert(plugin_name.to_string(), plugin);
220+
}
213221
}
214222

215223
pub type CommandParams = HashMap<&'static str, String>;
@@ -345,6 +353,24 @@ impl CommandExecutor {
345353
completes
346354
}
347355

356+
fn rest_command_params(command: &Command, params: &Vec<&str>, word: &str) -> Vec<(String, char)> {
357+
let mut completes: Vec<(String, char)> = Vec::new();
358+
359+
let command_params = command
360+
.metadata()
361+
.params();
362+
363+
let param_names: Vec<(String, char)> = command_params
364+
.iter()
365+
.filter(|param_meta| !params.contains(&param_meta.name) && param_meta.name.starts_with(word))
366+
.map(|param_meta| ((*param_meta.name).to_owned(), '='))
367+
.collect();
368+
369+
completes.extend(param_names);
370+
371+
completes
372+
}
373+
348374
fn command_names(commands: &HashMap<&'static str, Command>, word: &str) -> Vec<(String, char)> {
349375
commands
350376
.iter()
@@ -403,6 +429,10 @@ impl CommandExecutor {
403429
}
404430
(Some(first_word), Some(second_word), None) => {
405431
match (first_word, second_word) {
432+
(_, sub_command) if sub_command == "help" => {}
433+
(command, params) if self.commands.contains_key(command) => {
434+
completes.extend(CommandExecutor::rest_command_params(&self.commands[command], &vec![params], word));
435+
}
406436
(command, sub_command) if self.grouped_commands.contains_key(command) &&
407437
CommandExecutor::is_subcommand(&self.grouped_commands, command, sub_command) => {
408438
let (_, ref commands) = self.grouped_commands[command];
@@ -420,6 +450,14 @@ impl CommandExecutor {
420450
_ => {}
421451
}
422452
}
453+
(Some(first_word), None, Some(params)) => {
454+
match (first_word, &params) {
455+
(command, params) if self.commands.contains_key(command) => {
456+
completes.extend(CommandExecutor::rest_command_params(&self.commands[command], params, word));
457+
}
458+
_ => {}
459+
}
460+
}
423461
(Some(first_word), Some(second_word), Some(params)) => {
424462
match (first_word, second_word, &params) {
425463
(_, _, ref params) if "help".starts_with(params[0]) => {
@@ -431,17 +469,7 @@ impl CommandExecutor {
431469
CommandExecutor::is_subcommand(&self.grouped_commands, command, sub_command) => {
432470
let (_, ref commands) = self.grouped_commands[command];
433471
let sub_command = commands.get(sub_command).unwrap();
434-
let command_params = sub_command
435-
.metadata()
436-
.params();
437-
438-
let param_names: Vec<(String, char)> = command_params
439-
.iter()
440-
.filter(|param_meta| !params.contains(&param_meta.name) && param_meta.name.starts_with(word))
441-
.map(|param_meta| ((*param_meta.name).to_owned(), '='))
442-
.collect();
443-
444-
completes.extend(param_names);
472+
completes.extend(CommandExecutor::rest_command_params(&sub_command, params, word));
445473
}
446474
_ => {}
447475
}
@@ -714,11 +742,18 @@ impl CommandExecutor {
714742
fn _split_arguments(s: &str) -> (Option<&str>, Option<&str>, Option<Vec<&str>>) {
715743
let mut parts = s.trim().split_whitespace();
716744
let first_word = parts.next();
717-
let second_word = parts.next();
718-
let params = parts
745+
let mut second_word = parts.next();
746+
let mut params = parts
719747
.map(|s| s.split("=").collect::<Vec<&str>>()[0])
720748
.collect::<Vec<&str>>();
721749

750+
if let Some(s_word) = second_word {
751+
if s_word.contains("=") {
752+
params.insert(0, s_word.split("=").collect::<Vec<&str>>()[0]);
753+
second_word = None;
754+
}
755+
}
756+
722757
(first_word, second_word, if params.is_empty() { None } else { Some(params) })
723758
}
724759

cli/src/commands/common.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
extern crate libloading;
2+
3+
use libindy::ErrorCode;
4+
15
use command_executor::{Command, CommandContext, CommandParams, CommandMetadata, CommandResult};
26
use commands::get_str_param;
37

@@ -84,6 +88,49 @@ pub mod prompt_command {
8488
}
8589
}
8690

91+
pub mod load_plugin_command {
92+
use super::*;
93+
94+
command!(CommandMetadata::build("load-plugin", "Load plugin in Libindy")
95+
.add_required_param("library", "Name of plugin (can be absolute or relative path)")
96+
.add_required_param("initializer", "Name of plugin init function")
97+
.add_example("load-plugin library=libsovtoken initializer=sovtoken_init")
98+
.finalize());
99+
100+
fn execute(_ctx: &CommandContext, params: &CommandParams) -> CommandResult {
101+
trace!("execute >> params: {:?}", params);
102+
103+
let library = get_str_param("library", params).map_err(error_err!())?;
104+
let initializer = get_str_param("initializer", params).map_err(error_err!())?;
105+
106+
let res = load_plugin(_ctx, library, initializer)?;
107+
108+
trace!("execute << {:?}", res);
109+
110+
Ok(res)
111+
}
112+
}
113+
114+
pub fn load_plugin(ctx: &CommandContext, library: &str, initializer: &str) -> Result<(), ()> {
115+
let lib = libloading::Library::new(library)
116+
.map_err(|_| println_err!("Plugin not found: \"{:?}\"", library))?;
117+
118+
unsafe {
119+
let init_func: libloading::Symbol<unsafe extern fn() -> ErrorCode> = lib.get(initializer.as_bytes())
120+
.map_err(|_| println_err!("Init function not found"))?;
121+
122+
match init_func() {
123+
ErrorCode::Success => println_succ!("Plugin has been loaded: \"{}\"", library),
124+
_ => println_err!("Plugin has not been loaded: \"{}\"", library)
125+
}
126+
}
127+
128+
//TODO think more about behaviour in case of init_func failed
129+
ctx.add_plugin(library, lib);
130+
131+
Ok(())
132+
}
133+
87134
pub mod exit_command {
88135
use super::*;
89136

@@ -98,4 +145,38 @@ pub mod exit_command {
98145
trace!("execute << {:?}", res);
99146
res
100147
}
148+
}
149+
150+
#[cfg(test)]
151+
pub mod tests {
152+
use super::*;
153+
154+
pub const NULL_PAYMENT_METHOD: &'static str = "null";
155+
pub const NULL_PAYMENT_PLUGIN: &'static str = "libnullpay.so";
156+
pub const NULL_PAYMENT_PLUGIN_INIT_FUNCTION: &'static str = "nullpay_init";
157+
158+
mod load {
159+
use super::*;
160+
161+
#[test]
162+
#[cfg(feature = "payments_cli_tests")]
163+
pub fn load_works() {
164+
let ctx = CommandContext::new();
165+
166+
let cmd = load_plugin_command::new();
167+
let mut params = CommandParams::new();
168+
params.insert("library", NULL_PAYMENT_PLUGIN.to_string());
169+
params.insert("initializer", NULL_PAYMENT_PLUGIN_INIT_FUNCTION.to_string());
170+
cmd.execute(&ctx, &params).unwrap();
171+
}
172+
}
173+
174+
pub fn load_null_payment_plugin(ctx: &CommandContext) -> () {
175+
let lib = libloading::Library::new(NULL_PAYMENT_PLUGIN).unwrap();
176+
unsafe {
177+
let init_func: libloading::Symbol<unsafe extern fn() -> ErrorCode> = lib.get(NULL_PAYMENT_PLUGIN_INIT_FUNCTION.as_bytes()).unwrap();
178+
init_func();
179+
}
180+
ctx.add_plugin(NULL_PAYMENT_PLUGIN, lib)
181+
}
101182
}

cli/src/commands/did.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ pub mod rotate_key_command {
228228
handle_transaction_response(response)?;
229229
}
230230
Err(err) => {
231-
handle_transaction_error(err, Some(&did), Some(&pool_name), Some(&wallet_name))?;
231+
handle_transaction_error(err, Some(&did), Some(&pool_name), Some(&wallet_name));
232232
}
233233
};
234234

0 commit comments

Comments
 (0)