Skip to content

Commit

Permalink
Add huak-toolchain (first-pass) (#798)
Browse files Browse the repository at this point in the history
  • Loading branch information
cnpryer authored Nov 6, 2023
1 parent d8e75ad commit 95c733e
Show file tree
Hide file tree
Showing 39 changed files with 1,915 additions and 111 deletions.
15 changes: 14 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ license = "MIT"
clap = { version = "4.4.2", features = ["cargo", "derive"] }
colored = "2.0.4"
glob = "0.3.1"
hex = "0.4.3"
human-panic = "1.1.5"
lazy_static = "1.4.0"
pep440_rs = "0.3.11"
pep508_rs = "0.2.1"
regex = "1.10.2"
sha2 = "0.10.8"
tempfile = "3.7.1"
termcolor = "1.2.0"
thiserror = "1.0.48"
Expand Down
3 changes: 2 additions & 1 deletion crates/huak-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "huak"
version = "0.0.19"
version = "0.0.19-alpha1"
description = "A Python package manager written in Rust and inspired by Cargo."
repository = "https://github.com/cnpryer/huak.git"
homepage = "https://github.com/cnpryer/huak.git"
Expand All @@ -20,6 +20,7 @@ colored.workspace = true
huak-home = { path = "../huak-home" }
huak-package-manager = { path = "../huak-package-manager"}
huak-python-manager = { path = "../huak-python-manager" }
huak-toolchain = { path = "../huak-toolchain" }
human-panic.workspace = true
# included to build PyPi Wheels (see .github/workflow/README.md)
openssl = { version = "0.10.57", features = ["vendored"], optional = true }
Expand Down
100 changes: 88 additions & 12 deletions crates/huak-cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use huak_package_manager::{
Verbosity, WorkspaceOptions,
};
use huak_python_manager::RequestedVersion;
use huak_toolchain::{Channel, LocalTool};
use std::{env::current_dir, path::PathBuf, process::ExitCode, str::FromStr};
use termcolor::ColorChoice;

Expand Down Expand Up @@ -156,6 +157,12 @@ enum Commands {
#[arg(last = true)]
trailing: Option<Vec<String>>,
},
/// Manage toolchains.
#[clap(alias = "tc")]
Toolchain {
#[command(subcommand)]
command: Toolchain,
},
/// Update the project's dependencies.
Update {
#[arg(num_args = 0..)]
Expand Down Expand Up @@ -188,21 +195,69 @@ enum Python {

#[derive(Subcommand)]
enum Toolchain {
/// List available toolchains.
List,
/// Use an available toolchain.
Use {
/// The version of Python to use.
#[arg(required = true)]
version: RequestedVersion,
/// Add a tool to a toolchain.
Add {
/// A tool to add.
tool: LocalTool,
/// Add a tool to a specific channel.
#[arg(long, required = false)]
channel: Option<Channel>,
},
/// Display information about a toolchain.
Info {
/// The toolchain channel to display information for.
#[arg(long, required = false)]
channel: Option<Channel>,
},
/// Install a toolchain.
Install {
/// The version of Python to install.
#[arg(required = true)]
version: RequestedVersion,
/// The toolchain channel to install.
#[arg(required = false)]
channel: Option<Channel>,
/// The path to install a toolchain to.
target: PathBuf,
#[arg(required = false)]
target: Option<PathBuf>, // TODO(cnpryer): Could default to home dir toolchains dir.
},
/// List available toolchains.
List,
/// Remove a tool from a toolchain.
Remove {
/// A tool to add.
tool: LocalTool,
/// Remove a tool from a specific channel.
#[arg(long, required = false)]
channel: Option<Channel>,
},
/// Run a tool installed to a toolchain.
Run {
/// The tool to run.
tool: LocalTool,
/// The toolchain channel to run a tool from.
#[arg(long, required = false)]
channel: Option<Channel>,
/// Args to run the tool with.
#[arg(num_args = 1.., required = false)]
trailing: Option<Vec<String>>,
},
/// Uninstall a toolchain.
Uninstall {
/// The toolchain channel to uninstall.
#[arg(required = false)]
channel: Option<Channel>,
},
/// Update the current toolchain.
Update {
/// A tool to update.
#[arg(required = false)]
tool: Option<LocalTool>, // TODO(cnpryer): Either include @version or add version arg.
/// The toolchain channel to update.
#[arg(long, required = false)]
channel: Option<Channel>,
},
/// Use an available toolchain.
Use {
/// The toolchain channel to use.
channel: Channel,
},
}

Expand Down Expand Up @@ -345,6 +400,7 @@ fn exec_command(cmd: Commands, config: &mut Config) -> HuakResult<()> {
};
test(config, &options)
}
Commands::Toolchain { command } => toolchain(command, config),
Commands::Update {
dependencies,
trailing,
Expand Down Expand Up @@ -459,7 +515,7 @@ fn python(command: Python, config: &Config) -> HuakResult<()> {
match command {
Python::List => ops::list_python(config),
Python::Use { version } => ops::use_python(&version, config),
Python::Install { version } => ops::install_python(&version),
Python::Install { version } => ops::install_python(version),
}
}

Expand All @@ -475,6 +531,26 @@ fn test(config: &Config, options: &TestOptions) -> HuakResult<()> {
ops::test_project(config, options)
}

fn toolchain(command: Toolchain, config: &Config) -> HuakResult<()> {
match command {
Toolchain::Add { tool, channel } => ops::add_tool(&tool, channel, config),
Toolchain::Info { channel } => ops::toolchain_info(channel.as_ref(), config),
Toolchain::Install { channel, target } => ops::install_toolchain(channel, target, config),
Toolchain::List => ops::list_toolchains(config),
Toolchain::Remove { tool, channel } => ops::remove_tool(&tool, channel.as_ref(), config),
Toolchain::Run {
tool,
channel,
trailing,
} => ops::run_tool(&tool, channel.as_ref(), trailing, config),
Toolchain::Uninstall { channel } => ops::uninstall_toolchain(channel.as_ref(), config),
Toolchain::Update { tool, channel } => {
ops::update_toolchain(tool, channel.as_ref(), config)
}
Toolchain::Use { channel } => ops::use_toolchain(&channel, config),
}
}

fn update(
dependencies: Option<Vec<String>>,
config: &Config,
Expand Down
29 changes: 28 additions & 1 deletion crates/huak-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@ mod cli;
use clap::Parser;
use cli::Cli;
use colored::Colorize;
use huak_home::huak_home_dir;
use human_panic::setup_panic;
use std::process::{exit, ExitCode};
use std::{
env,
fs::create_dir_all,
process::{exit, ExitCode},
};

mod error;

Expand All @@ -16,6 +21,28 @@ mod error;
pub fn main() -> ExitCode {
setup_panic!();

// Get home directory path.
let Some(home) = huak_home_dir() else {
eprintln!(
"{}{} failed to resolve huak's home directory",
"error".red(),
":".bold()
);
return ExitCode::FAILURE;
};

// If the home directory doesn't exist then spawn one. We only report an error if the
// spawn fails due to anything other than the directory already existing.
if !home.exists() {
if let Err(e) = create_dir_all(home) {
if e.kind() != std::io::ErrorKind::AlreadyExists {
eprintln!("{}{} {}", "error".red(), ":".bold(), e);
return ExitCode::FAILURE;
}
}
}

// Capture and run CLI input.
match Cli::parse().run() {
Ok(0) => ExitCode::SUCCESS,
// Lazy-like exit of a subprocess failure. TODO: https://github.com/cnpryer/huak/issues/631
Expand Down
3 changes: 2 additions & 1 deletion crates/huak-cli/tests/snapshots/r#mod__tests__help-2.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
source: crates/huak_cli/tests/mod.rs
source: crates/huak-cli/tests/mod.rs
info:
program: huak
args:
Expand Down Expand Up @@ -29,6 +29,7 @@ Commands:
remove Remove dependencies from the project
run Run a command within the project's environment context
test Test the project's Python code
toolchain Manage toolchains
update Update the project's dependencies
version Display the version of the project
help Print this message or the help of the given subcommand(s)
Expand Down
3 changes: 2 additions & 1 deletion crates/huak-cli/tests/snapshots/r#mod__tests__help.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
source: crates/huak_cli/tests/mod.rs
source: crates/huak-cli/tests/mod.rs
info:
program: huak
args:
Expand Down Expand Up @@ -29,6 +29,7 @@ Commands:
remove Remove dependencies from the project
run Run a command within the project's environment context
test Test the project's Python code
toolchain Manage toolchains
update Update the project's dependencies
version Display the version of the project
help Print this message or the help of the given subcommand(s)
Expand Down
7 changes: 5 additions & 2 deletions crates/huak-home/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::path::PathBuf;
use std::{env, path::PathBuf};

/// Huak's home directory is located at ~/.huak.
///
Expand All @@ -11,7 +11,10 @@ use std::path::PathBuf;
/// On windows the `USERPROFILE` environment variable is used if it exists.
#[must_use]
pub fn huak_home_dir() -> Option<PathBuf> {
home_dir().map(|p| p.join(".huak"))
env::var("HUAK_HOME")
.ok()
.map(PathBuf::from)
.or(home_dir().map(|p| p.join(".huak")))
}

#[cfg(windows)]
Expand Down
3 changes: 3 additions & 0 deletions crates/huak-package-manager/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ regex.workspace = true
huak-python-manager = { path = "../huak-python-manager" }
huak-home = { path = "../huak-home" }
lazy_static.workspace = true
huak-toolchain = { path = "../huak-toolchain" }
hex.workspace = true
sha2.workspace = true

[dev-dependencies]
huak-dev = { path = "../huak-dev" }
Expand Down
3 changes: 1 addition & 2 deletions crates/huak-package-manager/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::path::PathBuf;

use huak_home::huak_home_dir;
use std::path::PathBuf;

use crate::{sys::Terminal, workspace::Workspace, TerminalOptions};

Expand Down
12 changes: 12 additions & 0 deletions crates/huak-package-manager/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use thiserror::Error as ThisError;

pub type HuakResult<T> = Result<T, Error>;

// TODO(cnpryer): If errors are given "a problem..." prompts there could be redundancy in messages.
// These prompts feel more like application experience than library needs.
#[derive(ThisError, Debug)]
pub enum Error {
#[error("a problem with argument parsing occurred: {0}")]
Expand All @@ -22,8 +24,16 @@ pub enum Error {
HuakConfigurationError(String),
#[error("a problem occurred resolving huak's home directory")]
HuakHomeNotFound,
#[error("a toolchain cannot be found")]
ToolchainNotFound,
#[error("{0}")] // See TODO note above.
ToolchainError(#[from] huak_toolchain::Error),
#[error("a toolchain already exists: {0}")]
LocalToolchainExists(PathBuf),
#[error("a problem with huak's internals occurred: {0}")]
InternalError(String),
#[error("a checksum is invalid: {0}")]
InvalidChecksum(String),
#[error("a version number could not be parsed: {0}")]
InvalidVersionString(String),
#[error("a problem occurred with json deserialization: {0}")]
Expand Down Expand Up @@ -60,6 +70,8 @@ pub enum Error {
TOMLDeserializationError(#[from] toml::de::Error),
#[error("a problem with toml serialization occurred {0}")]
TOMLSerializationError(#[from] toml::ser::Error),
#[error("{0}")]
TOMLEditError(#[from] toml_edit::TomlError),
#[error("a problem with toml deserialization occurred: {0}")]
TOMLEditDeserializationError(#[from] toml_edit::de::Error),
#[error("a problem with toml serialization occurred {0}")]
Expand Down
4 changes: 2 additions & 2 deletions crates/huak-package-manager/src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ pub fn copy_dir<T: Into<PathBuf>>(from: T, to: T, options: &CopyDirOptions) -> R

if from.is_dir() {
for entry in fs::read_dir(from)?.filter_map(Result::ok) {
let entry_path = entry.path();
if options.exclude.contains(&entry_path) {
let entry_as_path = entry.path();
if options.exclude.contains(&entry_as_path) {
continue;
}

Expand Down
1 change: 1 addition & 0 deletions crates/huak-package-manager/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ mod metadata;
pub mod ops;
mod package;
mod python_environment;
mod settings;
mod sys;
mod workspace;

Expand Down
Loading

0 comments on commit 95c733e

Please sign in to comment.