Skip to content
Snippets Groups Projects
Select Git revision
  • 3cecb00938a2bc6cfdf001ddb066f7e83ea2570e
  • master default protected
  • elois-ci-refactor protected
  • gtest
  • hugo/gtest
  • json-output
  • nostr
  • 48-error-base-58-requirement-is-violated
  • no-rename
  • hugo/tx-comments
  • poka/dev
  • hugo/dev
  • tuxmain/mail
  • test-gtest
  • 0.4.3-gtest-RC1
  • 0.4.3-RC2
  • 0.4.3-RC1
  • 0.4.2
  • 0.4.1
  • 0.4.0
  • 0.3.0
  • 0.2.17
  • 0.2.16
  • 0.2.15
  • 0.2.14
  • 0.2.13
  • 0.2.12
  • 0.2.10
  • 0.2.9
  • 0.2.8
  • 0.2.7
  • 0.2.6
  • 0.2.5
33 results

main.rs

Blame
    • Nicolas80's avatar
      3cecb009
      gcli command auto completion and arm64 build · 3cecb009
      Nicolas80 authored
      - Added detailed instructions for generating the completion script and registering it for your shell when calling `gcli completion --help`
      - Added that information in the CHANGELOG.md
      - Moved `indoc` crate dependency in Cargo.toml to make it explicit it's now also used outside of tests.
      3cecb009
      History
      gcli command auto completion and arm64 build
      Nicolas80 authored
      - Added detailed instructions for generating the completion script and registering it for your shell when calling `gcli completion --help`
      - Added that information in the CHANGELOG.md
      - Moved `indoc` crate dependency in Cargo.toml to make it explicit it's now also used outside of tests.
    main.rs 7.68 KiB
    mod commands;
    mod conf;
    mod data;
    mod database;
    mod display;
    mod entities;
    mod indexer;
    mod inputs;
    mod keys;
    mod runtime_config;
    mod utils;
    
    use anyhow::anyhow;
    use clap::builder::OsStr;
    use clap::{CommandFactory, Parser};
    use clap_complete::{generate, Shell};
    use codec::Encode;
    use colored::Colorize;
    use data::*;
    use display::DisplayEvent;
    use indoc::indoc;
    use keys::*;
    use runtime_config::*;
    use serde::{Deserialize, Serialize};
    use std::io;
    use std::str::FromStr;
    use subxt::{
    	blocks::ExtrinsicEvents,
    	config::DefaultExtrinsicParamsBuilder,
    	events::StaticEvent,
    	ext::sp_core::{sr25519, Pair as _},
    	tx::{DefaultPayload, PairSigner, Payload, TxStatus},
    };
    use utils::*;
    
    // alias
    pub type StaticPayload<Calldata> = DefaultPayload<Calldata>;
    
    /// define command line arguments
    #[derive(Clone, clap::Parser, Debug, Default)]
    #[clap(author, version, about, long_about = None)]
    pub struct Args {
    	/// Subcommands
    	#[clap(subcommand)]
    	pub subcommand: Subcommand,
    	/// Overwrite indexer endpoint
    	#[clap(short, long, conflicts_with_all=["no_indexer","network"])]
    	indexer: Option<String>,
    	/// Do not use indexer
    	#[clap(long)]
    	no_indexer: bool,
    	/// Secret key format (seed, substrate, g1v1)
    	#[clap(short = 'S', long)]
    	secret_format: Option<SecretFormat>,
    	/// Secret key or BIP39 mnemonic (only used when secret format is compatible)
    	/// (eventually followed by derivation path)
    	#[clap(short, long)]
    	secret: Option<String>,
    	/// Crypto scheme to use (sr25519, ed25519)
    	#[clap(short = 'c', long, required = false, default_value = CryptoScheme::Ed25519)]
    	crypto_scheme: CryptoScheme,
    	/// SS58 Address
    	#[clap(short, conflicts_with = "name")]
    	address: Option<AccountId>,
    	/// Name of an SS58 Address in the vault
    	#[clap(short = 'v')]
    	name: Option<String>,
    	/// Overwrite duniter websocket RPC endpoint
    	#[clap(short, long, conflicts_with = "network")]
    	url: Option<String>,
    	/// Target network (local, gdev, gtest...)
    	#[clap(short, long)]
    	network: Option<String>,
    	/// prevent waiting for extrinsic completion
    	#[clap(long)]
    	no_wait: bool,
    	/// Output format (human, json, ...)
    	#[clap(short = 'o', long, default_value = OutputFormat::Human)]
    	output_format: OutputFormat,
    }
    
    // TODO derive the fromstr implementation
    /// secret format
    #[derive(Clone, Copy, Debug, Eq, PartialEq, Default)]
    enum OutputFormat {
    	/// Human
    	#[default]
    	Human,
    	/// JSON
    	Json,
    }
    impl FromStr for OutputFormat {
    	type Err = std::io::Error;
    
    	fn from_str(s: &str) -> std::io::Result<Self> {
    		match s {
    			"human" => Ok(OutputFormat::Human),
    			"json" => Ok(OutputFormat::Json),
    			_ => Err(std::io::Error::from(std::io::ErrorKind::InvalidInput)),
    		}
    	}
    }
    impl From<OutputFormat> for &'static str {
    	fn from(val: OutputFormat) -> &'static str {
    		match val {
    			OutputFormat::Human => "human",
    			OutputFormat::Json => "json",
    		}
    	}
    }
    impl From<OutputFormat> for OsStr {
    	fn from(val: OutputFormat) -> OsStr {
    		OsStr::from(Into::<&str>::into(val))
    	}
    }
    
    /// define subcommands
    #[derive(Clone, Debug, clap::Subcommand, Default)]
    pub enum Subcommand {
    	/// Nothing
    	#[default]
    	#[clap(hide = true)]
    	Nothing,
    	/// Account (balance, transfer...)
    	#[clap(subcommand)]
    	Account(commands::account::Subcommand),
    	/// Identity (get, create, confirm, revoke...)
    	#[clap(subcommand)]
    	Identity(commands::identity::Subcommand),
    	/// Smith (certify, go-online, go-offline...)
    	#[clap(subcommand)]
    	Smith(commands::smith::Subcommand),
    	/// Sudo (set key, sudo calls...)
    	#[clap(hide = true)]
    	#[clap(subcommand)]
    	Sudo(commands::sudo::Subcommand),
    	/// Tech (list members, proposals, vote...)
    	#[clap(subcommand)]
    	Tech(commands::collective::Subcommand),
    	/// Universal Dividend (claim...)
    	#[clap(subcommand)]
    	Ud(commands::ud::Subcommand),
    	/// Oneshot account (balance, create, consume...)
    	#[clap(subcommand)]
    	Oneshot(commands::oneshot::Subcommand),
    	/// Blockchain (current block, runtime info...)
    	#[clap(subcommand)]
    	Blockchain(commands::blockchain::Subcommand),
    	/// Indexer (check, latest block)
    	#[clap(subcommand)]
    	Indexer(indexer::Subcommand),
    	/// Config (show, save...)
    	#[clap(subcommand)]
    	Config(conf::Subcommand),
    	/// Key management (import, generate, list...)
    	#[clap(subcommand)]
    	Vault(commands::vault::Subcommand),
    	/// Cesium
    	#[clap(subcommand, hide = true)]
    	Cesium(commands::cesium::Subcommand),
    	/// Publish a new git tag with actual version
    	#[clap(hide = true)]
    	Publish,
    	/// Generate a completions script for a specified shell (use `completion --help` for more info)
    	#[clap(long_about = indoc! {r#"Generate a completions script for a specified shell.
    
    		The base completion scripts for `bash`, `zsh` or `fish` are already registered when installing the `.deb` package.
    		If you did not/could not install the `.deb` package we can generate the script and then configure the shell to use it.
    
    		Example for `bash`:
    		  mkdir -p ~/.local/share/gcli
    		  gcli completion --shell bash > ~/.local/share/gcli/completion.bash
    		  # Direct test - gcli should have the completion after the source command
    		  source ~/.local/share/gcli/completion.bash
    
    		  # Persisting the configuration in the shell configuration file, add this at the end of your `~/.bashrc` file
    		  [[ -f $HOME/.local/share/gcli/completion.bash ]] && source $HOME/.local/share/gcli/completion.bash
    		  # Might need to reopen the shell for the configuration to be applied
    
    		Example for `zsh`:
    		  mkdir -p ~/.local/share/gcli
    		  gcli completion --shell zsh > ~/.local/share/gcli/completion.zsh
    		  # Direct test - gcli should have the completion after the source command
    		  source ~/.local/share/gcli/completion.zsh
    
    		  # Persisting the configuration in the shell configuration file, add this at the end of your `~/.zshrc` file
    		  [[ -f $HOME/.local/share/gcli/completion.zsh ]] && source $HOME/.local/share/gcli/completion.zsh
    		  # Might need to reopen the shell for the configuration to be applied
    		"#})]
    	Completion {
    		/// target shell
    		#[clap(long)]
    		shell: Shell,
    	},
    }
    
    /// main function
    #[tokio::main(flavor = "current_thread")]
    async fn main() -> Result<(), GcliError> {
    	// init logger
    	env_logger::init();
    
    	// parse argument and initialize data
    	let data = Data::new(Args::parse()).await?;
    
    	// match subcommands
    	let result = match data.args.subcommand.clone() {
    		// handle shell completions
    		Subcommand::Completion { shell } => {
    			let mut app = Args::command();
    			generate(shell, &mut app, "gcli", &mut io::stdout());
    			return Ok(());
    		}
    		Subcommand::Nothing => Ok(()),
    		Subcommand::Account(subcommand) => {
    			commands::account::handle_command(data, subcommand).await
    		}
    		Subcommand::Identity(subcommand) => {
    			commands::identity::handle_command(data, subcommand).await
    		}
    		Subcommand::Smith(subcommand) => commands::smith::handle_command(data, subcommand).await,
    		Subcommand::Sudo(subcommand) => commands::sudo::handle_command(data, subcommand).await,
    		Subcommand::Tech(subcommand) => {
    			commands::collective::handle_command(data, subcommand).await
    		}
    		Subcommand::Ud(subcommand) => commands::ud::handle_command(data, subcommand).await,
    		Subcommand::Oneshot(subcommand) => {
    			commands::oneshot::handle_command(data, subcommand).await
    		}
    		Subcommand::Blockchain(subcommand) => {
    			commands::blockchain::handle_command(data, subcommand).await
    		}
    		Subcommand::Indexer(subcommand) => indexer::handle_command(data, subcommand).await,
    		Subcommand::Config(subcommand) => conf::handle_command(data, subcommand).await,
    		Subcommand::Vault(subcommand) => commands::vault::handle_command(data, subcommand).await,
    		Subcommand::Cesium(subcommand) => commands::cesium::handle_command(data, subcommand).await,
    		Subcommand::Publish => commands::publish::handle_command().await,
    	};
    	if let Err(ref e) = result {
    		println!("{}", e.to_string().red())
    	}
    	// still return result for detailed error message
    	// println!();
    	// result
    	Ok(())
    }