Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"editor.formatOnSave": true
}
"editor.formatOnSave": true,
"rust-analyzer.cargo.features": "all"
}
47 changes: 46 additions & 1 deletion crates/volta-core/src/error/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ pub enum ErrorKind {
command: String,
},

/// Thrown when pnpm is not set at the command-line
NoCommandLinePnpm,

/// Thrown when Yarn is not set at the command-line
NoCommandLineYarn,

Expand All @@ -209,7 +212,7 @@ pub enum ErrorKind {

NoLocalDataDir,

/// Thrown when a user tries to pin a Yarn or npm version before pinning a Node version.
/// Thrown when a user tries to pin a pnpm/Yarn or npm version before pinning a Node version.
NoPinnedNodeVersion {
tool: String,
},
Expand All @@ -223,6 +226,9 @@ pub enum ErrorKind {
/// Thrown when Yarn is not set in a project
NoProjectYarn,

/// Thrown when pnpm is not set in a project
NoProjectPnpm,

/// Thrown when no shell profiles could be found
NoShellProfile {
env_profile: String,
Expand All @@ -235,6 +241,9 @@ pub enum ErrorKind {
/// Thrown when default Yarn is not set
NoDefaultYarn,

/// Thrown when default pnpm is not set
NoDefaultPnpm,

/// Thrown when `npm link` is called with a package that isn't available
NpmLinkMissingPackage {
package: String,
Expand Down Expand Up @@ -330,6 +339,11 @@ pub enum ErrorKind {
tool: String,
},

/// Thrown when there is no pnpm version matching a requested semver specifier.
PnpmVersionNotFound {
matching: String,
},

/// Thrown when executing a project-local binary fails
ProjectLocalBinaryExecError {
command: String,
Expand Down Expand Up @@ -856,6 +870,12 @@ format
Please ensure you have a Node version selected with `volta {} node` (see `volta help {0}` for more info).",
command
),
ErrorKind::NoCommandLinePnpm => write!(
f,
"No pnpm version specified.

Use `volta run --pnpm` to select a version (see `volta help run` for more info)."
),
ErrorKind::NoCommandLineYarn => write!(
f,
"No Yarn version specified.
Expand Down Expand Up @@ -912,6 +932,12 @@ To run any Node command, first set a default version using `volta install node`"
"No Node version found in this project.

Use `volta pin node` to select a version (see `volta help pin` for more info)."
),
ErrorKind::NoProjectPnpm => write!(
f,
"No pnpm version found in this project.

Use `volta pin pnpm` to select a version (see `volta help pin` for more info)."
),
ErrorKind::NoProjectYarn => write!(
f,
Expand All @@ -932,6 +958,12 @@ Please create one of these and try again; or you can edit your profile manually
"Not in a node package.

Use `volta install` to select a default version of a tool."
),
ErrorKind::NoDefaultPnpm => write!(
f,
"pnpm is not available.

Use `volta install pnpm` to select a default version (see `volta help install` for more info)."
),
ErrorKind::NoDefaultYarn => write!(
f,
Expand Down Expand Up @@ -1096,6 +1128,13 @@ Please supply a spec in the format `<tool name>[@<version>]`.",
{}",
tool, PERMISSIONS_CTA
),
ErrorKind::PnpmVersionNotFound { matching } => write!(
f,
r#"Could not find pnpm version matching "{}" in the version registry.

Please verify that the version is correct."#,
matching
),
ErrorKind::ProjectLocalBinaryExecError { command } => write!(
f,
"Could not execute `{}`
Expand Down Expand Up @@ -1299,12 +1338,14 @@ Please ensure it is installed with `{} {0}`"#,
package,
match manager {
PackageManager::Npm => "npm i -g",
PackageManager::Pnpm => "pnpm add -g",
PackageManager::Yarn => "yarn global add",
}
),
ErrorKind::UpgradePackageWrongManager { package, manager } => {
let (name, command) = match manager {
PackageManager::Npm => ("npm", "npm update -g"),
PackageManager::Pnpm => ("pnpm", "pnpm update -g"),
PackageManager::Yarn => ("Yarn", "yarn global upgrade"),
};
write!(
Expand Down Expand Up @@ -1455,6 +1496,7 @@ impl ErrorKind {
ErrorKind::InvalidToolName { .. } => ExitCode::InvalidArguments,
ErrorKind::LockAcquireError => ExitCode::FileSystemError,
ErrorKind::NoBundledNpm { .. } => ExitCode::ConfigurationError,
ErrorKind::NoCommandLinePnpm => ExitCode::ConfigurationError,
ErrorKind::NoCommandLineYarn => ExitCode::ConfigurationError,
ErrorKind::NoDefaultNodeVersion { .. } => ExitCode::ConfigurationError,
ErrorKind::NodeVersionNotFound { .. } => ExitCode::NoVersionMatch,
Expand All @@ -1464,9 +1506,11 @@ impl ErrorKind {
ErrorKind::NoPinnedNodeVersion { .. } => ExitCode::ConfigurationError,
ErrorKind::NoPlatform => ExitCode::ConfigurationError,
ErrorKind::NoProjectNodeInManifest => ExitCode::ConfigurationError,
ErrorKind::NoProjectPnpm => ExitCode::ConfigurationError,
ErrorKind::NoProjectYarn => ExitCode::ConfigurationError,
ErrorKind::NoShellProfile { .. } => ExitCode::EnvironmentError,
ErrorKind::NotInPackage => ExitCode::ConfigurationError,
ErrorKind::NoDefaultPnpm => ExitCode::ConfigurationError,
ErrorKind::NoDefaultYarn => ExitCode::ConfigurationError,
ErrorKind::NpmLinkMissingPackage { .. } => ExitCode::ConfigurationError,
ErrorKind::NpmLinkWrongManager { .. } => ExitCode::ConfigurationError,
Expand All @@ -1490,6 +1534,7 @@ impl ErrorKind {
ErrorKind::ParsePackageConfigError => ExitCode::UnknownError,
ErrorKind::ParsePlatformError => ExitCode::ConfigurationError,
ErrorKind::PersistInventoryError { .. } => ExitCode::FileSystemError,
ErrorKind::PnpmVersionNotFound { .. } => ExitCode::NoVersionMatch,
ErrorKind::ProjectLocalBinaryExecError { .. } => ExitCode::ExecutionFailure,
ErrorKind::ProjectLocalBinaryNotFound { .. } => ExitCode::FileSystemError,
ErrorKind::PublishHookBothUrlAndBin => ExitCode::ConfigurationError,
Expand Down
9 changes: 8 additions & 1 deletion crates/volta-core/src/hook/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::path::Path;
use crate::error::{Context, ErrorKind, Fallible};
use crate::layout::volta_home;
use crate::project::Project;
use crate::tool::{Node, Npm, Tool};
use crate::tool::{Node, Npm, Pnpm, Tool};
use lazycell::LazyCell;
use log::debug;

Expand Down Expand Up @@ -50,6 +50,7 @@ impl LazyHookConfig {
pub struct HookConfig {
node: Option<ToolHooks<Node>>,
npm: Option<ToolHooks<Npm>>,
pnpm: Option<ToolHooks<Pnpm>>,
yarn: Option<YarnHooks>,
events: Option<EventHooks>,
}
Expand Down Expand Up @@ -118,6 +119,10 @@ impl HookConfig {
self.npm.as_ref()
}

pub fn pnpm(&self) -> Option<&ToolHooks<Pnpm>> {
self.pnpm.as_ref()
}

pub fn yarn(&self) -> Option<&YarnHooks> {
self.yarn.as_ref()
}
Expand Down Expand Up @@ -182,6 +187,7 @@ impl HookConfig {
Self {
node: None,
npm: None,
pnpm: None,
yarn: None,
events: None,
}
Expand Down Expand Up @@ -214,6 +220,7 @@ impl HookConfig {
Self {
node: merge_hooks!(self, other, node),
npm: merge_hooks!(self, other, npm),
pnpm: merge_hooks!(self, other, pnpm),
yarn: merge_hooks!(self, other, yarn),
events: merge_hooks!(self, other, events),
}
Expand Down
5 changes: 4 additions & 1 deletion crates/volta-core/src/hook/serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::path::Path;
use super::tool;
use super::RegistryFormat;
use crate::error::{ErrorKind, Fallible, VoltaError};
use crate::tool::{Node, Npm, Tool};
use crate::tool::{Node, Npm, Pnpm, Tool};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
Expand Down Expand Up @@ -129,6 +129,7 @@ impl TryFrom<RawPublishHook> for super::Publish {
pub struct RawHookConfig {
pub node: Option<RawToolHooks<Node>>,
pub npm: Option<RawToolHooks<Npm>>,
pub pnpm: Option<RawToolHooks<Pnpm>>,
pub yarn: Option<RawYarnHooks>,
pub events: Option<RawEventHooks>,
}
Expand Down Expand Up @@ -172,11 +173,13 @@ impl RawHookConfig {
pub fn into_hook_config(self, base_dir: &Path) -> Fallible<super::HookConfig> {
let node = self.node.map(|n| n.into_tool_hooks(base_dir)).transpose()?;
let npm = self.npm.map(|n| n.into_tool_hooks(base_dir)).transpose()?;
let pnpm = self.pnpm.map(|p| p.into_tool_hooks(base_dir)).transpose()?;
let yarn = self.yarn.map(|y| y.into_yarn_hooks(base_dir)).transpose()?;
let events = self.events.map(|e| e.try_into()).transpose()?;
Ok(super::HookConfig {
node,
npm,
pnpm,
yarn,
events,
})
Expand Down
10 changes: 10 additions & 0 deletions crates/volta-core/src/inventory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ pub fn npm_versions() -> Fallible<BTreeSet<Version>> {
volta_home().and_then(|home| read_versions(home.npm_image_root_dir()))
}

/// Checks if a given pnpm version image is available on the local machine
pub fn pnpm_available(version: &Version) -> Fallible<bool> {
volta_home().map(|home| home.pnpm_image_dir(&version.to_string()).exists())
}

/// Collects a set of all pnpm versions fetched on the local machine
pub fn pnpm_versions() -> Fallible<BTreeSet<Version>> {
volta_home().and_then(|home| read_versions(home.pnpm_image_root_dir()))
}

/// Checks if a given Yarn version image is available on the local machine
pub fn yarn_available(version: &Version) -> Fallible<bool> {
volta_home().map(|home| home.yarn_image_dir(&version.to_string()).exists())
Expand Down
7 changes: 7 additions & 0 deletions crates/volta-core/src/platform/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ pub struct Image {
pub node: Sourced<Version>,
/// The custom version of npm, if any. `None` represents using the npm that is bundled with Node
pub npm: Option<Sourced<Version>>,
/// The pinned version of pnpm, if any.
pub pnpm: Option<Sourced<Version>>,
/// The pinned version of Yarn, if any.
pub yarn: Option<Sourced<Version>>,
}
Expand All @@ -27,6 +29,11 @@ impl Image {
bins.push(home.npm_image_bin_dir(&npm_str));
}

if let Some(pnpm) = &self.pnpm {
let pnpm_str = pnpm.value.to_string();
bins.push(home.pnpm_image_bin_dir(&pnpm_str));
}

if let Some(yarn) = &self.yarn {
let yarn_str = yarn.value.to_string();
bins.push(home.yarn_image_bin_dir(&yarn_str));
Expand Down
29 changes: 25 additions & 4 deletions crates/volta-core/src/platform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::fmt;

use crate::error::{ErrorKind, Fallible};
use crate::session::Session;
use crate::tool::{Node, Npm, Yarn};
use crate::tool::{Node, Npm, Pnpm, Yarn};
use semver::Version;

mod image;
Expand Down Expand Up @@ -161,6 +161,7 @@ impl<T> Default for InheritOption<T> {
pub struct PlatformSpec {
pub node: Version,
pub npm: Option<Version>,
pub pnpm: Option<Version>,
pub yarn: Option<Version>,
}

Expand All @@ -170,6 +171,7 @@ impl PlatformSpec {
Platform {
node: Sourced::with_default(self.node.clone()),
npm: self.npm.clone().map(Sourced::with_default),
pnpm: self.pnpm.clone().map(Sourced::with_default),
yarn: self.yarn.clone().map(Sourced::with_default),
}
}
Expand All @@ -179,6 +181,7 @@ impl PlatformSpec {
Platform {
node: Sourced::with_project(self.node.clone()),
npm: self.npm.clone().map(Sourced::with_project),
pnpm: self.pnpm.clone().map(Sourced::with_project),
yarn: self.yarn.clone().map(Sourced::with_project),
}
}
Expand All @@ -188,6 +191,7 @@ impl PlatformSpec {
Platform {
node: Sourced::with_binary(self.node.clone()),
npm: self.npm.clone().map(Sourced::with_binary),
pnpm: self.pnpm.clone().map(Sourced::with_binary),
yarn: self.yarn.clone().map(Sourced::with_binary),
}
}
Expand All @@ -198,6 +202,7 @@ impl PlatformSpec {
pub struct CliPlatform {
pub node: Option<Version>,
pub npm: InheritOption<Version>,
pub pnpm: InheritOption<Version>,
pub yarn: InheritOption<Version>,
}

Expand All @@ -207,6 +212,7 @@ impl CliPlatform {
Platform {
node: self.node.map_or(base.node, Sourced::with_command_line),
npm: self.npm.map(Sourced::with_command_line).inherit(base.npm),
pnpm: self.pnpm.map(Sourced::with_command_line).inherit(base.pnpm),
yarn: self.yarn.map(Sourced::with_command_line).inherit(base.yarn),
}
}
Expand All @@ -220,6 +226,7 @@ impl From<CliPlatform> for Option<Platform> {
Some(node) => Some(Platform {
node: Sourced::with_command_line(node),
npm: base.npm.map(Sourced::with_command_line).into(),
pnpm: base.pnpm.map(Sourced::with_command_line).into(),
yarn: base.yarn.map(Sourced::with_command_line).into(),
}),
}
Expand All @@ -231,6 +238,7 @@ impl From<CliPlatform> for Option<Platform> {
pub struct Platform {
pub node: Sourced<Version>,
pub npm: Option<Sourced<Version>>,
pub pnpm: Option<Sourced<Version>>,
pub yarn: Option<Sourced<Version>>,
}

Expand All @@ -239,12 +247,20 @@ impl Platform {
///
/// Active platform is determined by first looking at the Project Platform
///
/// - If it exists and has a Yarn version, then we use the project platform
/// - If it exists but doesn't have a Yarn version, then we merge the two,
/// pulling Yarn from the user default platform, if available
/// - If there is a project platform then we use it
/// - If there is no pnpm/Yarn version in the project platform, we pull
/// pnpm/Yarn from the default platform if available, and merge the two
/// platforms into a final one
/// - If there is no Project platform, then we use the user Default Platform
pub fn current(session: &mut Session) -> Fallible<Option<Self>> {
if let Some(mut platform) = session.project_platform()?.map(PlatformSpec::as_project) {
if platform.pnpm.is_none() {
platform.pnpm = session
.default_platform()?
.and_then(|default_platform| default_platform.pnpm.clone())
.map(Sourced::with_default);
}

if platform.yarn.is_none() {
platform.yarn = session
.default_platform()?
Expand All @@ -268,13 +284,18 @@ impl Platform {
Npm::new(version.clone()).ensure_fetched(session)?;
}

if let Some(Sourced { value: version, .. }) = &self.pnpm {
Pnpm::new(version.clone()).ensure_fetched(session)?;
}

if let Some(Sourced { value: version, .. }) = &self.yarn {
Yarn::new(version.clone()).ensure_fetched(session)?;
}

Ok(Image {
node: self.node,
npm: self.npm,
pnpm: self.pnpm,
yarn: self.yarn,
})
}
Expand Down
Loading