Skip to content

Commit

Permalink
Refactor installation directory (#44)
Browse files Browse the repository at this point in the history
  • Loading branch information
ofek authored Jun 25, 2023
1 parent 1dbb416 commit 2d7724b
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 119 deletions.
46 changes: 26 additions & 20 deletions src/app.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,42 @@
use std::env;
use std::path::{Path, PathBuf};
use std::path::PathBuf;

use anyhow::{Context, Result};
use base64::{engine::general_purpose::STANDARD_NO_PAD, Engine as _};
use directories::ProjectDirs;
use once_cell::sync::OnceCell;

static PLATFORM_DIRS: OnceCell<ProjectDirs> = OnceCell::new();
static INSTALLATION_DIRECTORY: OnceCell<PathBuf> = OnceCell::new();

fn platform_dirs() -> &'static ProjectDirs {
PLATFORM_DIRS
.get()
.expect("platform directories are not initialized")
}

pub fn install_dir() -> &'static PathBuf {
INSTALLATION_DIRECTORY
.get()
.expect("installation directory is not initialized")
}

pub fn initialize() -> Result<()> {
let platform_dirs = ProjectDirs::from("", "", "pyapp")
let platform_directories = ProjectDirs::from("", "", "pyapp")
.with_context(|| "unable to find platform directories")?;
PLATFORM_DIRS
.set(platform_dirs)
.set(platform_directories)
.expect("could not set platform directories");

let installation_directory = platform_dirs()
.data_local_dir()
.join(project_name())
.join(distribution_id())
.join(project_version());
INSTALLATION_DIRECTORY
.set(installation_directory)
.expect("could not set installation directory");

Ok(())
}

Expand Down Expand Up @@ -143,34 +159,24 @@ pub fn metadata_template() -> String {
env!("PYAPP_METADATA_TEMPLATE").into()
}

pub fn python_path(installation_directory: &Path) -> PathBuf {
installation_directory.join(installation_python_path())
pub fn python_path() -> PathBuf {
install_dir().join(installation_python_path())
}

pub fn site_packages_path(installation_directory: &Path) -> PathBuf {
installation_directory.join(installation_site_packages_path())
pub fn site_packages_path() -> PathBuf {
install_dir().join(installation_site_packages_path())
}

pub fn cache_directory() -> PathBuf {
pub fn cache_dir() -> PathBuf {
platform_dirs().cache_dir().to_path_buf()
}

pub fn storage_directory() -> PathBuf {
platform_dirs().data_local_dir().join(project_name())
}

pub fn installation_directory() -> PathBuf {
storage_directory()
.join(distribution_id())
.join(project_version())
}

pub fn distributions_cache() -> PathBuf {
cache_directory().join("distributions")
cache_dir().join("distributions")
}

pub fn external_pip_cache() -> PathBuf {
cache_directory().join("pip")
cache_dir().join("pip")
}

pub fn external_pip_zipapp() -> PathBuf {
Expand Down
5 changes: 2 additions & 3 deletions src/commands/self_cmd/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@ pub struct Cli {}

impl Cli {
pub fn exec(self) -> Result<()> {
let installation_directory = app::installation_directory();
if !installation_directory.is_dir() {
if !app::install_dir().is_dir() {
return Ok(());
}

let site_packages = app::site_packages_path(&installation_directory);
let site_packages = app::site_packages_path();

let expected_prefix = format!("{}-", app::project_name().replace('-', "_"));
let metadata_file = fs::read_dir(site_packages).ok().and_then(|entries| {
Expand Down
7 changes: 3 additions & 4 deletions src/commands/self_cmd/pip.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use anyhow::{Context, Result};
use clap::Args;

use crate::{app, distribution, process};
use crate::{distribution, process};

/// Directly invoke pip with the installed Python
#[derive(Args, Debug)]
Expand All @@ -13,10 +13,9 @@ pub struct Cli {

impl Cli {
pub fn exec(self) -> Result<()> {
let installation_directory = app::installation_directory();
distribution::ensure_ready(&installation_directory)?;
distribution::ensure_ready()?;

let mut command = distribution::pip_base_command(&installation_directory);
let mut command = distribution::pip_base_command();
command.args(self.args);

process::exec(command)
Expand Down
5 changes: 2 additions & 3 deletions src/commands/self_cmd/python.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@ pub struct Cli {

impl Cli {
pub fn exec(self) -> Result<()> {
let installation_directory = app::installation_directory();
distribution::ensure_ready(&installation_directory)?;
distribution::ensure_ready()?;

let mut command = distribution::python_command(&app::python_path(&installation_directory));
let mut command = distribution::python_command(&app::python_path());
command.args(self.args);

process::exec(command)
Expand Down
3 changes: 1 addition & 2 deletions src/commands/self_cmd/python_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ pub struct Cli {}

impl Cli {
pub fn exec(self) -> Result<()> {
let installation_directory = app::installation_directory();
println!("{}", app::python_path(&installation_directory).display());
println!("{}", app::python_path().display());

Ok(())
}
Expand Down
7 changes: 3 additions & 4 deletions src/commands/self_cmd/restore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,13 @@ pub struct Cli {}

impl Cli {
pub fn exec(self) -> Result<()> {
let installation_directory = app::installation_directory();
if installation_directory.is_dir() {
if app::install_dir().is_dir() {
let spinner = terminal::spinner("Removing installation".to_string());
let result = fs::remove_dir_all(&installation_directory);
let result = fs::remove_dir_all(app::install_dir());
spinner.finish_and_clear();
result?;
}
distribution::ensure_ready(&installation_directory)?;
distribution::ensure_ready()?;

Ok(())
}
Expand Down
22 changes: 8 additions & 14 deletions src/commands/self_cmd/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,18 @@ impl Cli {
exit(1);
}

let installation_directory = app::installation_directory();
let existing_installation = installation_directory.is_dir();
let existing_installation = app::install_dir().is_dir();
if !existing_installation {
distribution::materialize(&installation_directory)?;
distribution::materialize()?;
} else if self.restore {
let spinner = terminal::spinner("Removing installation".to_string());
let result = fs::remove_dir_all(&installation_directory);
let result = fs::remove_dir_all(app::install_dir());
spinner.finish_and_clear();
result?;
distribution::materialize(&installation_directory)?;
distribution::materialize()?;
}

let mut command = distribution::pip_install_command(&installation_directory);
let mut command = distribution::pip_install_command();
if self.pre {
command.arg("--pre");
}
Expand All @@ -48,19 +47,14 @@ impl Cli {
let dependency_file = app::project_dependency_file();
let (status, output) = if dependency_file.is_empty() {
command.arg(app::project_name().as_str());
distribution::pip_install(command, wait_message, &installation_directory)?
distribution::pip_install(command, wait_message)?
} else {
distribution::pip_install_dependency_file(
&dependency_file,
command,
wait_message,
&installation_directory,
)?
distribution::pip_install_dependency_file(&dependency_file, command, wait_message)?
};

if !status.success() {
if !existing_installation {
fs::remove_dir_all(&installation_directory).ok();
fs::remove_dir_all(app::install_dir()).ok();
}
println!("{}", output.trim_end());
exit(status.code().unwrap_or(1));
Expand Down
Loading

0 comments on commit 2d7724b

Please sign in to comment.