diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 444eb9c..f045adf 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -111,21 +111,21 @@ jobs: - name: Install binaries shell: pwsh run: | - cargo run -- client --version 0.74.2 - cargo run -- node --version 0.80.3 - cargo run -- testnet --version 0.1.4 + cargo run -- client --version 0.77.27 + cargo run -- node --version 0.83.25 + cargo run -- testnet --version 0.1.29 - name: Check if safe is available in new shell session shell: pwsh run: | - if (!(Test-Path "$env:USERPROFILE\.safe\cli\safe.exe")) { + if (!(Test-Path "$env:USERPROFILE\safe\safe.exe")) { Write-Host "safe.exe does not exist" exit 1 } - if (!(Test-Path "$env:USERPROFILE\.safe\node\safenode.exe")) { + if (!(Test-Path "$env:USERPROFILE\safe\safenode.exe")) { Write-Host "safenode.exe does not exist" exit 1 } - if (!(Test-Path "$env:USERPROFILE\.safe\node\testnet.exe")) { + if (!(Test-Path "$env:USERPROFILE\safe\testnet.exe")) { Write-Host "testnet.exe does not exist" exit 1 } @@ -134,33 +134,39 @@ jobs: # being modified easily, so we need to refer to the binaries with their full paths. # Other manual testing has proven that the changes to the Path environment variable do # take effect. - $output = & "${env:USERPROFILE}\.safe\cli\safe.exe" --version + $output = & "${env:USERPROFILE}\safe\safe.exe" --version $version = $output | Select-String -Pattern "sn_cli (\d+\.\d+\.\d+)" $versionNumber = $version.Matches.Groups[1].Value - if ($versionNumber -eq "0.74.2") { + if ($versionNumber -eq "0.77.27") { Write-Host "The correct version of safe has been installed" } else { Write-Host "The correct version of safe has not been installed" + Write-Host "We expected version 0.77.27" + Write-Host "The downloaded binary has $versionNumber" exit 1 } - $output = & "${env:USERPROFILE}\.safe\node\safenode.exe" --version - $version = $output | Select-String -Pattern "sn_node (\d+\.\d+\.\d+)" + $output = & "${env:USERPROFILE}\safe\safenode.exe" --version + $version = $output | Select-String -Pattern "safenode cli (\d+\.\d+\.\d+)" $versionNumber = $version.Matches.Groups[1].Value - if ($versionNumber -eq "0.80.3") { + if ($versionNumber -eq "0.83.25") { Write-Host "The correct version of safenode has been installed" } else { Write-Host "The correct version of safenode has not been installed" + Write-Host "We expected version 0.83.25" + Write-Host "The downloaded binary has $versionNumber" exit 1 } - $output = & "${env:USERPROFILE}\.safe\node\testnet.exe" --version + $output = & "${env:USERPROFILE}\safe\testnet.exe" --version $version = $output | Select-String -Pattern "testnet (\d+\.\d+\.\d+)" $versionNumber = $version.Matches.Groups[1].Value - if ($versionNumber -eq "0.1.4") { + if ($versionNumber -eq "0.1.29") { Write-Host "The correct version of testnet has been installed" } else { Write-Host "The correct version of testnet has not been installed" + Write-Host "We expected version 0.1.29" + Write-Host "The downloaded binary has $versionNumber" exit 1 } @@ -178,9 +184,9 @@ jobs: - name: Install binaries shell: bash run: | - cargo run -- client --version 0.74.2 - cargo run -- node --version 0.80.3 - cargo run -- testnet --version 0.1.4 + cargo run -- client --version 0.77.27 + cargo run -- node --version 0.83.25 + cargo run -- testnet --version 0.1.29 - name: Check if safe is available in new shell session shell: bash run: | @@ -191,33 +197,39 @@ jobs: # the test does prove that the env file modifies PATH correctly and # that the installs of the binaries are available from their local # locations. - source ~/.safe/env + source ~/.config/safe/env - [[ -f "$HOME/.safe/cli/safe" ]] || { echo "safe not in expected location"; exit 1; } - [[ -f "$HOME/.safe/node/safenode" ]] || { echo "safenode not in expected location"; exit 1; } - [[ -f "$HOME/.safe/node/testnet" ]] || { echo "testnet not in expected location"; exit 1; } + [[ -f "$HOME/.local/bin/safe" ]] || { echo "safe not in expected location"; exit 1; } + [[ -f "$HOME/.local/bin/safenode" ]] || { echo "safenode not in expected location"; exit 1; } + [[ -f "$HOME/.local/bin/testnet" ]] || { echo "testnet not in expected location"; exit 1; } version=$(safe --version | awk '{ print $2 }') - if [[ "$version" == "0.74.2" ]]; then + if [[ "$version" == "0.77.27" ]]; then echo "The correct version of safe has been installed" else echo "The correct version of safe has not been installed" + echo "We expected 0.77.27" + echo "The downloaded binary has $version" exit 1 fi - version=$(safenode --version | awk '{ print $2 }') - if [[ "$version" == "0.80.3" ]]; then + version=$(safenode --version | awk '{ print $3 }') + if [[ "$version" == "0.83.25" ]]; then echo "The correct version of safenode has been installed" else echo "The correct version of safenode has not been installed" + echo "We expected 0.83.25" + echo "The downloaded binary has $version" exit 1 fi version=$(testnet --version | awk '{ print $2 }') - if [[ "$version" == "0.1.4" ]]; then + if [[ "$version" == "0.1.29" ]]; then echo "The correct version of testnet has been installed" else echo "The correct version of testnet has not been installed" + echo "We expected 0.1.29" + echo "The downloaded binary has $version" exit 1 fi @@ -236,9 +248,9 @@ jobs: shell: bash run: | cargo build --release - sudo ./target/release/safeup client --version 0.74.2 - sudo ./target/release/safeup node --version 0.80.3 - sudo ./target/release/safeup testnet --version 0.1.4 + sudo ./target/release/safeup client --version 0.77.27 + sudo ./target/release/safeup node --version 0.83.25 + sudo ./target/release/safeup testnet --version 0.1.29 [[ -f "/usr/local/bin/safe" ]] || { echo "safe not in expected location"; exit 1; } [[ -f "/usr/local/bin/safenode" ]] || { echo "safenode not in expected location"; exit 1; } @@ -247,26 +259,32 @@ jobs: # Due to installation at /usr/local/bin, the binaries should be # immediately available in the same shell session. version=$(safe --version | awk '{ print $2 }') - if [[ "$version" == "0.74.2" ]]; then + if [[ "$version" == "0.77.27" ]]; then echo "The correct version of safe has been installed" else echo "The correct version of safe has not been installed" + echo "We expected 0.77.27" + echo "The downloaded binary has $version" exit 1 fi - version=$(safenode --version | awk '{ print $2 }') - if [[ "$version" == "0.80.3" ]]; then + version=$(safenode --version | awk '{ print $3 }') + if [[ "$version" == "0.83.25" ]]; then echo "The correct version of safenode has been installed" else echo "The correct version of safenode has not been installed" + echo "We expected 0.83.25" + echo "The downloaded binary has $version" exit 1 fi version=$(testnet --version | awk '{ print $2 }') - if [[ "$version" == "0.1.4" ]]; then + if [[ "$version" == "0.1.29" ]]; then echo "The correct version of testnet has been installed" else echo "The correct version of testnet has not been installed" + echo "We expected 0.1.29" + echo "The downloaded binary has $version" exit 1 fi @@ -285,35 +303,41 @@ jobs: - name: Install binaries shell: zsh {0} run: | - cargo run -- client --version 0.74.2 - cargo run -- node --version 0.80.3 - cargo run -- testnet --version 0.1.4 + cargo run -- client --version 0.77.27 + cargo run -- node --version 0.83.25 + cargo run -- testnet --version 0.1.29 [[ -f "/usr/local/bin/safe" ]] || { echo "safe not in expected location"; exit 1; } [[ -f "/usr/local/bin/safenode" ]] || { echo "safenode not in expected location"; exit 1; } [[ -f "/usr/local/bin/testnet" ]] || { echo "testnet not in expected location"; exit 1; } version=$(safe --version | awk '{ print $2 }') - if [[ "$version" == "0.74.2" ]]; then + if [[ "$version" == "0.77.27" ]]; then echo "The correct version of safe has been installed" else echo "The correct version of safe has not been installed" + echo "We expected 0.77.27" + echo "The downloaded binary has $version" exit 1 fi - version=$(safenode --version | awk '{ print $2 }') - if [[ "$version" == "0.80.3" ]]; then + version=$(safenode --version | awk '{ print $3 }') + if [[ "$version" == "0.83.25" ]]; then echo "The correct version of safenode has been installed" else echo "The correct version of safenode has not been installed" + echo "We expected 0.83.25" + echo "The downloaded binary has $version" exit 1 fi version=$(testnet --version | awk '{ print $2 }') - if [[ "$version" == "0.1.4" ]]; then + if [[ "$version" == "0.1.29" ]]; then echo "The correct version of testnet has been installed" else echo "The correct version of testnet has not been installed" + echo "We expected 0.1.29" + echo "The downloaded binary has $version" exit 1 fi @@ -329,5 +353,5 @@ jobs: toolchain: stable override: true - - name: Cargo publish dry run + - name: dry run publish run: cargo publish --dry-run diff --git a/src/install.rs b/src/install.rs index dc995b3..de11ac1 100644 --- a/src/install.rs +++ b/src/install.rs @@ -39,13 +39,10 @@ const VCPP_REDIST_URL: &str = "https://download.microsoft.com/download/9/3/F/93F const SET_PATH_FILE_CONTENT: &str = indoc! {r#" #!/bin/sh case ":${PATH}:" in - *:"$HOME/.safe/cli":*) - ;; - *:"$HOME/.safe/node":*) + *:"$HOME/.local/bin":*) ;; *) - export PATH="$HOME/.safe/cli:$PATH" - export PATH="$HOME/.safe/node:$PATH" + export PATH="$HOME/.local/bin:$PATH" ;; esac "#}; diff --git a/src/main.rs b/src/main.rs index 31430c0..710ffd5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,7 +16,7 @@ use github::GithubReleaseRepository; use install::{AssetType, Settings}; use s3::S3AssetRepository; use std::env::consts::{ARCH, OS}; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; const GITHUB_API_URL: &str = "https://api.github.com"; const ORG_NAME: &str = "maidsafe"; @@ -36,10 +36,10 @@ struct Cli { enum Commands { /// Install the latest version of safe. /// - /// If running as root, the default install path is /usr/local/bin; otherwise it will be - /// ~/.safe/cli. + /// If running without elevated privileges, safe will be installed to $HOME/.local/bin, and + /// the shell profile will be modified to put this location on PATH. /// - /// If running as the current user, the shell profile will be modified to put safe on PATH. + /// Otherwise safe will be installed to /usr/local/bin. Client { /// Override the default installation path. /// @@ -57,10 +57,10 @@ enum Commands { }, /// Install the latest version of safenode. /// - /// If running as root, the default install path is /usr/local/bin; otherwise it will be - /// ~/.safe/node. + /// If running without elevated privileges, safenode will be installed to $HOME/.local/bin, and + /// your shell profile will be modified to put this location on PATH. /// - /// If running as the current user, the shell profile will be modified to put safenode on PATH. + /// Otherwise safenode will be installed to /usr/local/bin. Node { /// Override the default installation path. /// @@ -78,10 +78,10 @@ enum Commands { }, /// Install the latest version of testnet. /// - /// If running as root, the default install path is /usr/local/bin; otherwise it will be - /// ~/.safe/node. + /// If running without elevated privileges, testnet will be installed to $HOME/.local/bin, and + /// your shell profile will be modified to put this location on PATH. /// - /// If running as the current user, the shell profile will be modified to put testnet on PATH. + /// Otherwise testnet will be installed to /usr/local/bin. Testnet { /// Override the default installation path. /// @@ -164,20 +164,14 @@ async fn install( ) -> Result<()> { let platform = get_platform()?; let running_elevated = is_running_elevated(); - let home_dir_path = - dirs_next::home_dir().ok_or_else(|| eyre!("Could not retrieve user's home directory"))?; - let safe_dir_path = home_dir_path.join(".safe"); + let safe_config_dir_path = get_safe_config_dir_path()?; + let dest_dir_path = if let Some(path) = path { path } else if running_elevated { std::path::PathBuf::from("/usr/local/bin") } else { - let dir = match asset_type { - AssetType::Client => "cli", - AssetType::Node => "node", - AssetType::Testnet => "node", - }; - safe_dir_path.join(dir) + get_install_dest_dir_path()? }; let release_repository = GithubReleaseRepository::new(GITHUB_API_URL, ORG_NAME, REPO_NAME); @@ -195,15 +189,13 @@ async fn install( if !running_elevated && !no_modify_shell_profile { install::configure_shell_profile( &dest_dir_path.clone(), - &get_shell_profile_path(&home_dir_path), - &home_dir_path.join(".safe").join("env"), + &get_shell_profile_path()?, + &safe_config_dir_path.join("env"), ) .await? } - let config_dir_path = - dirs_next::config_dir().ok_or_else(|| eyre!("Could not retrieve user's home directory"))?; - let settings_file_path = config_dir_path.join(".safe").join("safeup.json"); + let settings_file_path = safe_config_dir_path.join("safeup.json"); let mut settings = Settings::read(&settings_file_path)?; match asset_type { AssetType::Client => settings.safe_path = bin_path, @@ -264,18 +256,50 @@ fn is_running_elevated() -> bool { } #[cfg(target_os = "linux")] -fn get_shell_profile_path(home_dir_path: &Path) -> PathBuf { - home_dir_path.join(".bashrc") +fn get_shell_profile_path() -> Result { + let home_dir_path = + dirs_next::home_dir().ok_or_else(|| eyre!("Could not retrieve user's home directory"))?; + Ok(home_dir_path.join(".bashrc")) } /// We won't actually end up doing anything on Windows with the shell profile, so we can just /// return back the home directory. #[cfg(target_os = "windows")] -fn get_shell_profile_path(home_dir_path: &Path) -> PathBuf { - home_dir_path.to_path_buf() +fn get_shell_profile_path() -> Result { + let home_dir_path = + dirs_next::home_dir().ok_or_else(|| eyre!("Could not retrieve user's home directory"))?; + Ok(home_dir_path.to_path_buf()) } #[cfg(target_os = "macos")] -fn get_shell_profile_path(home_dir_path: &Path) -> PathBuf { - home_dir_path.join(".zshrc") +fn get_shell_profile_path() -> Result { + let home_dir_path = + dirs_next::home_dir().ok_or_else(|| eyre!("Could not retrieve user's home directory"))?; + Ok(home_dir_path.join(".zshrc")) +} + +fn get_safe_config_dir_path() -> Result { + let config_dir_path = dirs_next::config_dir() + .ok_or_else(|| eyre!("Could not retrieve user's config directory"))?; + let safe_config_dir_path = config_dir_path.join("safe"); + std::fs::create_dir_all(safe_config_dir_path.clone())?; + Ok(safe_config_dir_path) +} + +#[cfg(target_os = "windows")] +fn get_install_dest_dir_path() -> Result { + let home_dir_path = + dirs_next::home_dir().ok_or_else(|| eyre!("Could not retrieve user's home directory"))?; + let safe_dir_path = home_dir_path.join("safe"); + std::fs::create_dir_all(safe_dir_path.clone())?; + Ok(safe_dir_path) +} + +#[cfg(target_family = "unix")] +fn get_install_dest_dir_path() -> Result { + let home_dir_path = + dirs_next::home_dir().ok_or_else(|| eyre!("Could not retrieve user's home directory"))?; + let safe_dir_path = home_dir_path.join(".local").join("bin"); + std::fs::create_dir_all(safe_dir_path.clone())?; + Ok(safe_dir_path) }