diff --git a/Cargo.lock b/Cargo.lock index a04d77c56..699445984 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -359,6 +359,15 @@ name = "difference" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "dir" +version = "0.1.0" +dependencies = [ + "app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore-bigint 0.2.1", + "journaldb 0.1.0", +] + [[package]] name = "docopt" version = "0.8.1" @@ -785,6 +794,7 @@ dependencies = [ name = "ethstore" version = "0.2.0" dependencies = [ + "dir 0.1.0", "ethcore-bigint 0.2.1", "ethcrypto 0.1.0", "ethkey 0.3.0", @@ -809,6 +819,7 @@ dependencies = [ name = "ethstore-cli" version = "0.1.0" dependencies = [ + "dir 0.1.0", "docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethstore 0.2.0", "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1882,6 +1893,7 @@ dependencies = [ "clap 2.26.2 (registry+https://github.com/rust-lang/crates.io-index)", "ctrlc 1.1.1 (git+https://github.com/paritytech/rust-ctrlc.git)", "daemonize 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "dir 0.1.0", "docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.9.0", diff --git a/Cargo.toml b/Cargo.toml index a79dafd3f..7c21668a4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -58,6 +58,7 @@ parity-updater = { path = "updater" } parity-version = { path = "util/version" } parity-whisper = { path = "whisper" } path = { path = "util/path" } +dir = { path = "util/dir" } panic_hook = { path = "panic_hook" } keccak-hash = { path = "util/hash" } migration = { path = "util/migration" } diff --git a/ethcore/src/account_provider/mod.rs b/ethcore/src/account_provider/mod.rs index 498c84bbf..0241179a8 100755 --- a/ethcore/src/account_provider/mod.rs +++ b/ethcore/src/account_provider/mod.rs @@ -28,7 +28,7 @@ use ethstore::{ SimpleSecretStore, SecretStore, Error as SSError, EthStore, EthMultiStore, random_string, SecretVaultRef, StoreAccountRef, OpaqueSecret, }; -use ethstore::dir::MemoryDirectory; +use ethstore::accounts_dir::MemoryDirectory; use ethstore::ethkey::{Address, Message, Public, Secret, Random, Generator}; use ethjson::misc::AccountMeta; use hardware_wallet::{Error as HardwareError, HardwareWalletManager, KeyPath, TransactionInfo}; diff --git a/ethstore/Cargo.toml b/ethstore/Cargo.toml index 23c02973f..1adea2c70 100755 --- a/ethstore/Cargo.toml +++ b/ethstore/Cargo.toml @@ -19,6 +19,7 @@ itertools = "0.5" parking_lot = "0.4" ethcrypto = { path = "../ethcrypto" } ethcore-bigint = { path = "../util/bigint" } +dir = { path = "../util/dir" } smallvec = "0.4" parity-wordlist = "1.0" tempdir = "0.3" diff --git a/ethstore/cli/Cargo.toml b/ethstore/cli/Cargo.toml index 24d1c9a8f..4a065fdaa 100644 --- a/ethstore/cli/Cargo.toml +++ b/ethstore/cli/Cargo.toml @@ -11,6 +11,7 @@ serde = "1.0" serde_derive = "1.0" parking_lot = "0.4" ethstore = { path = "../" } +dir = { path = '../../util/dir' } panic_hook = { path = "../../panic_hook" } [[bin]] diff --git a/ethstore/cli/src/main.rs b/ethstore/cli/src/main.rs index 798c7e599..e9cd4975a 100644 --- a/ethstore/cli/src/main.rs +++ b/ethstore/cli/src/main.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +extern crate dir; extern crate docopt; extern crate ethstore; extern crate num_cpus; @@ -30,7 +31,7 @@ use std::io::Read; use std::{env, process, fs, fmt}; use docopt::Docopt; -use ethstore::dir::{paths, KeyDirectory, RootDiskDirectory}; +use ethstore::accounts_dir::{KeyDirectory, RootDiskDirectory}; use ethstore::ethkey::Address; use ethstore::{EthStore, SimpleSecretStore, SecretStore, import_accounts, PresaleWallet, SecretVaultRef, StoreAccountRef}; @@ -157,11 +158,11 @@ fn main() { fn key_dir(location: &str) -> Result, Error> { let dir: Box = match location { - "geth" => Box::new(RootDiskDirectory::create(paths::geth(false))?), - "geth-test" => Box::new(RootDiskDirectory::create(paths::geth(true))?), + "geth" => Box::new(RootDiskDirectory::create(dir::geth(false))?), + "geth-test" => Box::new(RootDiskDirectory::create(dir::geth(true))?), path if path.starts_with("parity") => { let chain = path.split('-').nth(1).unwrap_or("ethereum"); - let path = paths::parity(chain); + let path = dir::parity(chain); Box::new(RootDiskDirectory::create(path)?) }, path => Box::new(RootDiskDirectory::create(path)?), diff --git a/ethstore/src/dir/disk.rs b/ethstore/src/accounts_dir/disk.rs similarity index 99% rename from ethstore/src/dir/disk.rs rename to ethstore/src/accounts_dir/disk.rs index ebd67de2e..d164cb6bb 100755 --- a/ethstore/src/dir/disk.rs +++ b/ethstore/src/accounts_dir/disk.rs @@ -290,8 +290,7 @@ mod test { extern crate tempdir; use std::{env, fs}; - use super::RootDiskDirectory; - use dir::{KeyDirectory, VaultKey}; + use super::{KeyDirectory, RootDiskDirectory, VaultKey}; use account::SafeAccount; use ethkey::{Random, Generator}; use self::tempdir::TempDir; diff --git a/ethstore/src/dir/memory.rs b/ethstore/src/accounts_dir/memory.rs similarity index 100% rename from ethstore/src/dir/memory.rs rename to ethstore/src/accounts_dir/memory.rs diff --git a/ethstore/src/dir/mod.rs b/ethstore/src/accounts_dir/mod.rs similarity index 99% rename from ethstore/src/dir/mod.rs rename to ethstore/src/accounts_dir/mod.rs index b6e168f6e..ec72d05da 100755 --- a/ethstore/src/dir/mod.rs +++ b/ethstore/src/accounts_dir/mod.rs @@ -22,7 +22,6 @@ use {SafeAccount, Error}; mod disk; mod memory; mod vault; -pub mod paths; /// `VaultKeyDirectory::set_key` error #[derive(Debug)] diff --git a/ethstore/src/dir/vault.rs b/ethstore/src/accounts_dir/vault.rs similarity index 99% rename from ethstore/src/dir/vault.rs rename to ethstore/src/accounts_dir/vault.rs index a7b351643..b270bb181 100755 --- a/ethstore/src/dir/vault.rs +++ b/ethstore/src/accounts_dir/vault.rs @@ -284,7 +284,7 @@ mod test { use std::fs; use std::io::Write; use std::path::PathBuf; - use dir::VaultKey; + use super::VaultKey; use super::{VAULT_FILE_NAME, check_vault_name, make_vault_dir_path, create_vault_file, read_vault_file, VaultDiskDirectory}; use self::tempdir::TempDir; diff --git a/ethstore/src/dir/paths.rs b/ethstore/src/dir/paths.rs deleted file mode 100644 index db3178cff..000000000 --- a/ethstore/src/dir/paths.rs +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity 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 General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -//! Common tools paths. - -use std::env; -use std::path::PathBuf; - -fn home() -> PathBuf { - env::home_dir().expect("Failed to get home dir") -} - -/// Geth path -pub fn geth(testnet: bool) -> PathBuf { - let mut base = geth_base(); - if testnet { - base.push("testnet"); - } - base.push("keystore"); - base -} - -/// Parity path for specific chain -pub fn parity(chain: &str) -> PathBuf { - let mut base = parity_base(); - base.push(chain); - base -} - -#[cfg(target_os = "macos")] -fn parity_base() -> PathBuf { - let mut home = home(); - home.push("Library"); - home.push("Application Support"); - home.push("io.parity.ethereum"); - home.push("keys"); - home -} - -#[cfg(windows)] -fn parity_base() -> PathBuf { - let mut home = home(); - home.push("AppData"); - home.push("Roaming"); - home.push("Parity"); - home.push("Ethereum"); - home.push("keys"); - home -} - -#[cfg(not(any(target_os = "macos", windows)))] -fn parity_base() -> PathBuf { - let mut home = home(); - home.push(".local"); - home.push("share"); - home.push("io.parity.ethereum"); - home.push("keys"); - home -} - -#[cfg(target_os = "macos")] -fn geth_base() -> PathBuf { - let mut home = home(); - home.push("Library"); - home.push("Ethereum"); - home -} - -#[cfg(windows)] -fn geth_base() -> PathBuf { - let mut home = home(); - home.push("AppData"); - home.push("Roaming"); - home.push("Ethereum"); - home -} - -#[cfg(not(any(target_os = "macos", windows)))] -fn geth_base() -> PathBuf { - let mut home = home(); - home.push(".ethereum"); - home -} diff --git a/ethstore/src/ethstore.rs b/ethstore/src/ethstore.rs index 07e7dd879..3e1953421 100755 --- a/ethstore/src/ethstore.rs +++ b/ethstore/src/ethstore.rs @@ -23,7 +23,7 @@ use std::time::{Instant, Duration}; use crypto::KEY_ITERATIONS; use random::Random; use ethkey::{self, Signature, Address, Message, Secret, Public, KeyPair, ExtendedKeyPair}; -use dir::{KeyDirectory, VaultKeyDirectory, VaultKey, SetKeyError}; +use accounts_dir::{KeyDirectory, VaultKeyDirectory, VaultKey, SetKeyError}; use account::SafeAccount; use presale::PresaleWallet; use json::{self, Uuid, OpaqueKeyFile}; @@ -684,7 +684,7 @@ impl SimpleSecretStore for EthMultiStore { mod tests { extern crate tempdir; - use dir::{KeyDirectory, MemoryDirectory, RootDiskDirectory}; + use accounts_dir::{KeyDirectory, MemoryDirectory, RootDiskDirectory}; use ethkey::{Random, Generator, KeyPair}; use secret_store::{SimpleSecretStore, SecretStore, SecretVaultRef, StoreAccountRef, Derivation}; use super::{EthStore, EthMultiStore}; diff --git a/ethstore/src/import.rs b/ethstore/src/import.rs index 2b2c34eb1..2aaef51f5 100644 --- a/ethstore/src/import.rs +++ b/ethstore/src/import.rs @@ -19,7 +19,8 @@ use std::path::Path; use std::fs; use ethkey::Address; -use dir::{paths, KeyDirectory, RootDiskDirectory, DiskKeyFileManager, KeyFileManager}; +use accounts_dir::{KeyDirectory, RootDiskDirectory, DiskKeyFileManager, KeyFileManager}; +use dir; use Error; /// Import an account from a file. @@ -54,7 +55,7 @@ pub fn import_accounts(src: &KeyDirectory, dst: &KeyDirectory) -> Result Vec
{ - RootDiskDirectory::at(paths::geth(testnet)) + RootDiskDirectory::at(dir::geth(testnet)) .load() .map(|d| d.into_iter().map(|a| a.address).collect()) .unwrap_or_else(|_| Vec::new()) @@ -62,7 +63,7 @@ pub fn read_geth_accounts(testnet: bool) -> Vec
{ /// Import specific `desired` accounts from the Geth keystore into `dst`. pub fn import_geth_accounts(dst: &KeyDirectory, desired: HashSet
, testnet: bool) -> Result, Error> { - let src = RootDiskDirectory::at(paths::geth(testnet)); + let src = RootDiskDirectory::at(dir::geth(testnet)); let accounts = src.load()?; let existing_accounts = dst.load()?.into_iter().map(|a| a.address).collect::>(); diff --git a/ethstore/src/lib.rs b/ethstore/src/lib.rs index 65935f89c..39ec857dc 100755 --- a/ethstore/src/lib.rs +++ b/ethstore/src/lib.rs @@ -19,6 +19,7 @@ #![warn(missing_docs)] extern crate crypto as rcrypto; +extern crate dir; extern crate itertools; extern crate libc; extern crate parking_lot; @@ -41,7 +42,7 @@ extern crate log; #[macro_use] extern crate serde_derive; -pub mod dir; +pub mod accounts_dir; pub mod ethkey; mod account; diff --git a/ethstore/tests/api.rs b/ethstore/tests/api.rs index a70163895..fb24ff336 100755 --- a/ethstore/tests/api.rs +++ b/ethstore/tests/api.rs @@ -21,7 +21,7 @@ mod util; use ethstore::{EthStore, SimpleSecretStore, SecretVaultRef, StoreAccountRef}; use ethstore::ethkey::{Random, Generator, Secret, KeyPair, verify_address}; -use ethstore::dir::RootDiskDirectory; +use ethstore::accounts_dir::RootDiskDirectory; use util::TransientDir; #[test] diff --git a/ethstore/tests/util/transient_dir.rs b/ethstore/tests/util/transient_dir.rs index 45e2aab09..dcc65ec69 100755 --- a/ethstore/tests/util/transient_dir.rs +++ b/ethstore/tests/util/transient_dir.rs @@ -17,7 +17,7 @@ use std::path::PathBuf; use std::{env, fs}; use rand::{Rng, OsRng}; -use ethstore::dir::{KeyDirectory, RootDiskDirectory}; +use ethstore::accounts_dir::{KeyDirectory, RootDiskDirectory}; use ethstore::{Error, SafeAccount}; pub fn random_dir() -> PathBuf { diff --git a/parity/account.rs b/parity/account.rs index ed4f9b40a..3db1844a1 100644 --- a/parity/account.rs +++ b/parity/account.rs @@ -16,7 +16,7 @@ use std::path::PathBuf; use ethcore::ethstore::{EthStore, SecretStore, import_account, import_accounts, read_geth_accounts}; -use ethcore::ethstore::dir::RootDiskDirectory; +use ethcore::ethstore::accounts_dir::RootDiskDirectory; use ethcore::ethstore::SecretVaultRef; use ethcore::account_provider::{AccountProvider, AccountProviderSettings}; use helpers::{password_prompt, password_from_file}; diff --git a/parity/cli/usage.rs b/parity/cli/usage.rs index 388afd1c1..91524c165 100644 --- a/parity/cli/usage.rs +++ b/parity/cli/usage.rs @@ -154,7 +154,7 @@ macro_rules! usage { use std::io::{Read, Write}; use parity_version::version; use clap::{Arg, App, SubCommand, AppSettings, ArgMatches as ClapArgMatches, Error as ClapError, ErrorKind as ClapErrorKind}; - use helpers::replace_home; + use dir::helpers::replace_home; use std::ffi::OsStr; use std::collections::HashMap; diff --git a/parity/configuration.rs b/parity/configuration.rs index f777ef983..1ab1ad7c0 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -39,8 +39,9 @@ use rpc::{IpcConfiguration, HttpConfiguration, WsConfiguration, UiConfiguration} use rpc_apis::ApiSet; use parity_rpc::NetworkSettings; use cache::CacheConfig; -use helpers::{to_duration, to_mode, to_block_id, to_u256, to_pending_set, to_price, replace_home, replace_home_and_local, -geth_ipc_path, parity_ipc_path, to_bootnodes, to_addresses, to_address, to_gas_limit, to_queue_strategy}; +use helpers::{to_duration, to_mode, to_block_id, to_u256, to_pending_set, to_price, geth_ipc_path, parity_ipc_path, +to_bootnodes, to_addresses, to_address, to_gas_limit, to_queue_strategy}; +use dir::helpers::{replace_home, replace_home_and_local}; use params::{ResealPolicy, AccountsConfig, GasPricerConfig, MinerExtras, SpecType}; use ethcore_logger::Config as LogConfig; use dir::{self, Directories, default_hypervisor_path, default_local_path, default_data_path}; @@ -1866,7 +1867,7 @@ mod tests { let base_path = ::dir::default_data_path(); let local_path = ::dir::default_local_path(); - assert_eq!(std.directories().cache, ::helpers::replace_home_and_local(&base_path, &local_path, ::dir::CACHE_PATH)); + assert_eq!(std.directories().cache, dir::helpers::replace_home_and_local(&base_path, &local_path, ::dir::CACHE_PATH)); assert_eq!(base.directories().cache, "/test/cache"); } } diff --git a/parity/dapps.rs b/parity/dapps.rs index 45bc9fdc4..6f82a6ada 100644 --- a/parity/dapps.rs +++ b/parity/dapps.rs @@ -18,13 +18,13 @@ use std::path::PathBuf; use std::sync::Arc; use dir::default_data_path; +use dir::helpers::replace_home; use ethcore::client::{Client, BlockChainClient, BlockId}; use ethcore::transaction::{Transaction, Action}; use ethsync::LightSync; use futures::{future, IntoFuture, Future}; use hash_fetch::fetch::Client as FetchClient; use hash_fetch::urlhint::ContractClient; -use helpers::replace_home; use light::client::LightChainClient; use light::on_demand::{self, OnDemand}; use node_health::{SyncStatus, NodeHealth}; diff --git a/parity/helpers.rs b/parity/helpers.rs index 88ff333d9..5283b47c8 100644 --- a/parity/helpers.rs +++ b/parity/helpers.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use std::{io, env}; +use std::io; use std::io::{Write, BufReader, BufRead}; use std::time::Duration; use std::fs::File; @@ -27,6 +27,7 @@ use ethcore::client::{Mode, BlockId, VMType, DatabaseCompactionProfile, ClientCo use ethcore::miner::{PendingSet, GasLimit, PrioritizationStrategy}; use cache::CacheConfig; use dir::DatabaseDirectories; +use dir::helpers::replace_home; use upgrade::{upgrade, upgrade_data_paths}; use migration::migrate; use ethsync::{validate_node_url, self}; @@ -135,19 +136,6 @@ pub fn to_price(s: &str) -> Result { s.parse::().map_err(|_| format!("Invalid transaciton price 's' given. Must be a decimal number.")) } -/// Replaces `$HOME` str with home directory path. -pub fn replace_home(base: &str, arg: &str) -> String { - // the $HOME directory on mac os should be `~/Library` or `~/Library/Application Support` - let r = arg.replace("$HOME", env::home_dir().unwrap().to_str().unwrap()); - let r = r.replace("$BASE", base); - r.replace("/", &::std::path::MAIN_SEPARATOR.to_string()) -} - -pub fn replace_home_and_local(base: &str, local: &str, arg: &str) -> String { - let r = replace_home(base, arg); - r.replace("$LOCAL", local) -} - /// Flush output buffer. pub fn flush_stdout() { io::stdout().flush().expect("stdout is flushable; qed"); diff --git a/parity/main.rs b/parity/main.rs index c8ea6ead8..54c56ff8d 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -24,6 +24,7 @@ extern crate ctrlc; extern crate docopt; #[macro_use] extern crate clap; +extern crate dir; extern crate env_logger; extern crate fdlimit; extern crate futures; @@ -102,7 +103,6 @@ mod configuration; mod dapps; mod ipfs; mod deprecated; -mod dir; mod helpers; mod informant; mod light_helpers; diff --git a/parity/presale.rs b/parity/presale.rs index 5ac7d00fd..216ff66a8 100644 --- a/parity/presale.rs +++ b/parity/presale.rs @@ -15,7 +15,7 @@ // along with Parity. If not, see . use ethcore::ethstore::{PresaleWallet, EthStore}; -use ethcore::ethstore::dir::RootDiskDirectory; +use ethcore::ethstore::accounts_dir::RootDiskDirectory; use ethcore::account_provider::{AccountProvider, AccountProviderSettings}; use helpers::{password_prompt, password_from_file}; use params::SpecType; diff --git a/parity/rpc.rs b/parity/rpc.rs index d17b77ccd..1f7cd2af2 100644 --- a/parity/rpc.rs +++ b/parity/rpc.rs @@ -21,7 +21,8 @@ use std::collections::HashSet; use dapps; use dir::default_data_path; -use helpers::{parity_ipc_path, replace_home}; +use dir::helpers::replace_home; +use helpers::parity_ipc_path; use jsonrpc_core::MetaIoHandler; use parity_reactor::TokioRemote; use parity_rpc::informant::{RpcStats, Middleware}; diff --git a/parity/run.rs b/parity/run.rs index eb9521020..369c63b5c 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -894,7 +894,7 @@ fn print_running_environment(spec_name: &String, dirs: &Directories, db_dirs: &D fn prepare_account_provider(spec: &SpecType, dirs: &Directories, data_dir: &str, cfg: AccountsConfig, passwords: &[String]) -> Result { use ethcore::ethstore::EthStore; - use ethcore::ethstore::dir::RootDiskDirectory; + use ethcore::ethstore::accounts_dir::RootDiskDirectory; let path = dirs.keys_path(data_dir); upgrade_key_location(&dirs.legacy_keys_path(cfg.testnet), &path); diff --git a/parity/secretstore.rs b/parity/secretstore.rs index ee818fa62..161042d3c 100644 --- a/parity/secretstore.rs +++ b/parity/secretstore.rs @@ -17,11 +17,11 @@ use std::collections::BTreeMap; use std::sync::Arc; use dir::default_data_path; +use dir::helpers::replace_home; use ethcore::account_provider::AccountProvider; use ethcore::client::Client; use ethkey::{Secret, Public}; use ethsync::SyncProvider; -use helpers::replace_home; use util::Address; /// This node secret key. diff --git a/parity/upgrade.rs b/parity/upgrade.rs index 49f18d571..fcea2560e 100644 --- a/parity/upgrade.rs +++ b/parity/upgrade.rs @@ -24,7 +24,7 @@ use std::io; use std::io::{Read, Write}; use std::path::{PathBuf, Path}; use dir::{DatabaseDirectories, default_data_path}; -use helpers::replace_home; +use dir::helpers::replace_home; use journaldb::Algorithm; #[derive(Debug)] diff --git a/rpc/src/v1/tests/mocked/parity_accounts.rs b/rpc/src/v1/tests/mocked/parity_accounts.rs index b3ea644fa..74fddcc7e 100644 --- a/rpc/src/v1/tests/mocked/parity_accounts.rs +++ b/rpc/src/v1/tests/mocked/parity_accounts.rs @@ -18,7 +18,7 @@ use std::sync::Arc; use ethcore::account_provider::{AccountProvider, AccountProviderSettings}; use ethstore::EthStore; -use ethstore::dir::RootDiskDirectory; +use ethstore::accounts_dir::RootDiskDirectory; use devtools::RandomTempPath; use jsonrpc_core::IoHandler; diff --git a/util/dir/Cargo.toml b/util/dir/Cargo.toml new file mode 100644 index 000000000..ee6dc638a --- /dev/null +++ b/util/dir/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "dir" +version = "0.1.0" +authors = ["Parity Technologies "] + +[dependencies] +ethcore-bigint = { path = "../bigint" } +journaldb = { path = "../journaldb" } +app_dirs = "1.1.1" diff --git a/util/dir/src/helpers.rs b/util/dir/src/helpers.rs new file mode 100644 index 000000000..95f8090c8 --- /dev/null +++ b/util/dir/src/helpers.rs @@ -0,0 +1,32 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! Directory helper functions +use std::env; + +/// Replaces `$HOME` str with home directory path. +pub fn replace_home(base: &str, arg: &str) -> String { + // the $HOME directory on mac os should be `~/Library` or `~/Library/Application Support` + let r = arg.replace("$HOME", env::home_dir().unwrap().to_str().unwrap()); + let r = r.replace("$BASE", base); + r.replace("/", &::std::path::MAIN_SEPARATOR.to_string()) +} + +/// Replaces `$HOME` str with home directory path and `$LOCAL` with local path. +pub fn replace_home_and_local(base: &str, local: &str, arg: &str) -> String { + let r = replace_home(base, arg); + r.replace("$LOCAL", local) +} diff --git a/parity/dir.rs b/util/dir/src/lib.rs similarity index 70% rename from parity/dir.rs rename to util/dir/src/lib.rs index a7b676bc7..6e751420a 100644 --- a/parity/dir.rs +++ b/util/dir/src/lib.rs @@ -14,27 +14,31 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use std::fs; +#![warn(missing_docs)] + +//! Dir utilities for platform-specific operations +extern crate app_dirs; +extern crate ethcore_bigint as bigint; +extern crate journaldb; + +pub mod helpers; +use std::{env, fs}; use std::path::{PathBuf, Path}; use bigint::hash::{H64, H256}; use journaldb::Algorithm; use helpers::{replace_home, replace_home_and_local}; use app_dirs::{AppInfo, get_app_root, AppDataType}; +// re-export platform-specific functions +use platform::*; -#[cfg(target_os = "macos")] const AUTHOR: &'static str = "Parity"; -#[cfg(target_os = "macos")] const PRODUCT: &'static str = "io.parity.ethereum"; -#[cfg(target_os = "macos")] const PRODUCT_HYPERVISOR: &'static str = "io.parity.ethereum-updates"; -#[cfg(target_os = "windows")] const AUTHOR: &'static str = "Parity"; -#[cfg(target_os = "windows")] const PRODUCT: &'static str = "Ethereum"; -#[cfg(target_os = "windows")] const PRODUCT_HYPERVISOR: &'static str = "EthereumUpdates"; -#[cfg(not(any(target_os = "windows", target_os = "macos")))] const AUTHOR: &'static str = "parity"; -#[cfg(not(any(target_os = "windows", target_os = "macos")))] const PRODUCT: &'static str = "io.parity.ethereum"; -#[cfg(not(any(target_os = "windows", target_os = "macos")))] const PRODUCT_HYPERVISOR: &'static str = "io.parity.ethereum-updates"; - +/// Platform-specific chains path - Windows only #[cfg(target_os = "windows")] pub const CHAINS_PATH: &'static str = "$LOCAL/chains"; +/// Platform-specific chains path #[cfg(not(target_os = "windows"))] pub const CHAINS_PATH: &'static str = "$BASE/chains"; +/// Platform-specific cache path - Windows only #[cfg(target_os = "windows")] pub const CACHE_PATH: &'static str = "$LOCAL/cache"; +/// Platform-specific cache path #[cfg(not(target_os = "windows"))] pub const CACHE_PATH: &'static str = "$BASE/cache"; // this const is irrelevent cause we do have migrations now, @@ -42,13 +46,21 @@ use app_dirs::{AppInfo, get_app_root, AppDataType}; const LEGACY_CLIENT_DB_VER_STR: &'static str = "5.3"; #[derive(Debug, PartialEq)] +/// Parity local data directories pub struct Directories { + /// Base dir pub base: String, + /// Database dir pub db: String, + /// Cache dir pub cache: String, + /// Dir to store keys pub keys: String, + /// Signer dir pub signer: String, + /// Dir to store dapps pub dapps: String, + /// Secrets dir pub secretstore: String, } @@ -69,6 +81,7 @@ impl Default for Directories { } impl Directories { + /// Create local directories pub fn create_dirs(&self, dapps_enabled: bool, signer_enabled: bool, secretstore_enabled: bool) -> Result<(), String> { fs::create_dir_all(&self.base).map_err(|e| e.to_string())?; fs::create_dir_all(&self.db).map_err(|e| e.to_string())?; @@ -104,6 +117,7 @@ impl Directories { dir } + /// Legacy keys path // TODO: remove in 1.7 pub fn legacy_keys_path(&self, testnet: bool) -> PathBuf { let mut dir = Path::new(&self.base).to_path_buf(); @@ -115,6 +129,7 @@ impl Directories { dir } + /// Get the keys path pub fn keys_path(&self, spec_name: &str) -> PathBuf { let mut dir = PathBuf::from(&self.keys); dir.push(spec_name); @@ -123,11 +138,17 @@ impl Directories { } #[derive(Debug, PartialEq)] +/// Database directories for the given fork. pub struct DatabaseDirectories { + /// Base path pub path: String, + /// Legacy path pub legacy_path: String, + /// Genesis hash pub genesis_hash: H256, + /// Name of current fork pub fork_name: Option, + /// Name of current spec pub spec_name: String, } @@ -140,12 +161,14 @@ impl DatabaseDirectories { dir } + /// Spec root directory for the given fork. pub fn spec_root_path(&self) -> PathBuf { let mut dir = Path::new(&self.path).to_path_buf(); dir.push(&self.spec_name); dir } + /// Generic client path pub fn client_path(&self, pruning: Algorithm) -> PathBuf { let mut dir = self.db_root_path(); dir.push(pruning.as_internal_name_str()); @@ -153,6 +176,7 @@ impl DatabaseDirectories { dir } + /// DB root path, named after genesis hash pub fn db_root_path(&self) -> PathBuf { let mut dir = self.spec_root_path(); dir.push("db"); @@ -160,6 +184,7 @@ impl DatabaseDirectories { dir } + /// DB path pub fn db_path(&self, pruning: Algorithm) -> PathBuf { let mut dir = self.db_root_path(); dir.push(pruning.as_internal_name_str()); @@ -174,7 +199,7 @@ impl DatabaseDirectories { dir } - /// Get user defaults path + /// Get user defaults path, legacy way // TODO: remove in 1.7 pub fn legacy_user_defaults_path(&self) -> PathBuf { let mut dir = self.legacy_fork_path(); @@ -182,7 +207,7 @@ impl DatabaseDirectories { dir } - /// Get user defaults path + /// Get snapshot path, legacy way // TODO: remove in 1.7 pub fn legacy_snapshot_path(&self) -> PathBuf { let mut dir = self.legacy_fork_path(); @@ -190,7 +215,7 @@ impl DatabaseDirectories { dir } - /// Get user defaults path + /// Get user defaults path, legacy way // TODO: remove in 1.7 pub fn legacy_network_path(&self) -> PathBuf { let mut dir = self.legacy_fork_path(); @@ -198,6 +223,7 @@ impl DatabaseDirectories { dir } + /// Get user defauls path pub fn user_defaults_path(&self) -> PathBuf { let mut dir = self.spec_root_path(); dir.push("user_defaults"); @@ -219,21 +245,119 @@ impl DatabaseDirectories { } } +/// Default data path pub fn default_data_path() -> String { let app_info = AppInfo { name: PRODUCT, author: AUTHOR }; get_app_root(AppDataType::UserData, &app_info).map(|p| p.to_string_lossy().into_owned()).unwrap_or_else(|_| "$HOME/.parity".to_owned()) } +/// Default local path pub fn default_local_path() -> String { let app_info = AppInfo { name: PRODUCT, author: AUTHOR }; get_app_root(AppDataType::UserCache, &app_info).map(|p| p.to_string_lossy().into_owned()).unwrap_or_else(|_| "$HOME/.parity".to_owned()) } +/// Default hypervisor path pub fn default_hypervisor_path() -> String { let app_info = AppInfo { name: PRODUCT_HYPERVISOR, author: AUTHOR }; get_app_root(AppDataType::UserData, &app_info).map(|p| p.to_string_lossy().into_owned()).unwrap_or_else(|_| "$HOME/.parity-hypervisor".to_owned()) } +/// Get home directory. +fn home() -> PathBuf { + env::home_dir().expect("Failed to get home dir") +} + +/// Geth path +pub fn geth(testnet: bool) -> PathBuf { + let mut base = geth_base(); + if testnet { + base.push("testnet"); + } + base.push("keystore"); + base +} + +/// Parity path for specific chain +pub fn parity(chain: &str) -> PathBuf { + let mut base = parity_base(); + base.push(chain); + base +} + +#[cfg(target_os = "macos")] +mod platform { + use std::path::PathBuf; + pub const AUTHOR: &'static str = "Parity"; + pub const PRODUCT: &'static str = "io.parity.ethereum"; + pub const PRODUCT_HYPERVISOR: &'static str = "io.parity.ethereum-updates"; + + pub fn parity_base() -> PathBuf { + let mut home = super::home(); + home.push("Library"); + home.push("Application Support"); + home.push("io.parity.ethereum"); + home.push("keys"); + home + } + + pub fn geth_base() -> PathBuf { + let mut home = super::home(); + home.push("Library"); + home.push("Ethereum"); + home + } +} + +#[cfg(windows)] +mod platform { + use std::path::PathBuf; + pub const AUTHOR: &'static str = "Parity"; + pub const PRODUCT: &'static str = "Ethereum"; + pub const PRODUCT_HYPERVISOR: &'static str = "EthereumUpdates"; + + pub fn parity_base() -> PathBuf { + let mut home = super::home(); + home.push("AppData"); + home.push("Roaming"); + home.push("Parity"); + home.push("Ethereum"); + home.push("keys"); + home + } + + pub fn geth_base() -> PathBuf { + let mut home = super::home(); + home.push("AppData"); + home.push("Roaming"); + home.push("Ethereum"); + home + } +} + +#[cfg(not(any(target_os = "macos", windows)))] +mod platform { + use std::path::PathBuf; + pub const AUTHOR: &'static str = "parity"; + pub const PRODUCT: &'static str = "io.parity.ethereum"; + pub const PRODUCT_HYPERVISOR: &'static str = "io.parity.ethereum-updates"; + + pub fn parity_base() -> PathBuf { + let mut home = super::home(); + home.push(".local"); + home.push("share"); + home.push("io.parity.ethereum"); + home.push("keys"); + home + } + + pub fn geth_base() -> PathBuf { + let mut home = super::home(); + home.push(".ethereum"); + home + } +} + #[cfg(test)] mod tests { use super::Directories;