Skip to content

Commit ba0a393

Browse files
authored
Merge pull request #1230 from mikrostew/yarn3-hooks
Add "format" to yarn.index hook
2 parents 97f4d47 + eee41af commit ba0a393

File tree

11 files changed

+372
-40
lines changed

11 files changed

+372
-40
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"node": {
3+
"index": {
4+
"prefix": "http://localhost/node/index/",
5+
"format": "github"
6+
}
7+
},
8+
"npm": {
9+
"index": {
10+
"prefix": "http://localhost/npm/index/",
11+
"format": "github"
12+
}
13+
},
14+
"yarn": {
15+
"index": {
16+
"prefix": "http://localhost/yarn/index/",
17+
"format": "github"
18+
}
19+
}
20+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"node": {
3+
"index": {
4+
"prefix": "http://localhost/node/index/",
5+
"format": "npm"
6+
}
7+
},
8+
"npm": {
9+
"index": {
10+
"prefix": "http://localhost/npm/index/",
11+
"format": "npm"
12+
}
13+
},
14+
"yarn": {
15+
"index": {
16+
"prefix": "http://localhost/yarn/index/",
17+
"format": "npm"
18+
}
19+
}
20+
}

crates/volta-core/src/error/kind.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,11 @@ pub enum ErrorKind {
170170
version: String,
171171
},
172172

173+
/// Thrown when a format other than "npm" or "github" is given for yarn.index in the hooks
174+
InvalidRegistryFormat {
175+
format: String,
176+
},
177+
173178
/// Thrown when a tool name is invalid per npm's rules.
174179
InvalidToolName {
175180
name: String,
@@ -811,6 +816,14 @@ To {action} the package '{version}', please use an explicit version such as '{ve
811816
write!(f, "{}\n\n{}", error, wrapped_cta)
812817
}
813818

819+
ErrorKind::InvalidRegistryFormat { format } => write!(
820+
f,
821+
"Unrecognized index registry format: '{}'
822+
823+
Please specify either 'npm' or 'github' for the format.",
824+
format
825+
),
826+
814827
ErrorKind::InvalidToolName { name, errors } => {
815828
let indentation = " ";
816829
let wrapped = match text_width() {
@@ -1438,6 +1451,7 @@ impl ErrorKind {
14381451
ErrorKind::InvalidHookOutput { .. } => ExitCode::ExecutionFailure,
14391452
ErrorKind::InvalidInvocation { .. } => ExitCode::InvalidArguments,
14401453
ErrorKind::InvalidInvocationOfBareVersion { .. } => ExitCode::InvalidArguments,
1454+
ErrorKind::InvalidRegistryFormat { .. } => ExitCode::ConfigurationError,
14411455
ErrorKind::InvalidToolName { .. } => ExitCode::InvalidArguments,
14421456
ErrorKind::LockAcquireError => ExitCode::FileSystemError,
14431457
ErrorKind::NoBundledNpm { .. } => ExitCode::ConfigurationError,

crates/volta-core/src/hook/mod.rs

Lines changed: 132 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::path::Path;
99
use crate::error::{Context, ErrorKind, Fallible};
1010
use crate::layout::volta_home;
1111
use crate::project::Project;
12-
use crate::tool::{Node, Npm, Tool, Yarn};
12+
use crate::tool::{Node, Npm, Tool};
1313
use lazycell::LazyCell;
1414
use log::debug;
1515

@@ -50,7 +50,7 @@ impl LazyHookConfig {
5050
pub struct HookConfig {
5151
node: Option<ToolHooks<Node>>,
5252
npm: Option<ToolHooks<Npm>>,
53-
yarn: Option<ToolHooks<Yarn>>,
53+
yarn: Option<YarnHooks>,
5454
events: Option<EventHooks>,
5555
}
5656

@@ -66,6 +66,16 @@ pub struct ToolHooks<T: Tool> {
6666
phantom: PhantomData<T>,
6767
}
6868

69+
/// Volta hooks for Yarn
70+
pub struct YarnHooks {
71+
/// The hook for resolving the URL for a distro version
72+
pub distro: Option<tool::DistroHook>,
73+
/// The hook for resolving the URL for the latest version
74+
pub latest: Option<tool::MetadataHook>,
75+
/// The hook for resolving the Tool Index URL
76+
pub index: Option<tool::YarnIndexHook>,
77+
}
78+
6979
impl<T: Tool> ToolHooks<T> {
7080
/// Extends this ToolHooks with another, giving precendence to the current instance
7181
fn merge(self, other: Self) -> Self {
@@ -78,6 +88,17 @@ impl<T: Tool> ToolHooks<T> {
7888
}
7989
}
8090

91+
impl YarnHooks {
92+
/// Extends this YarnHooks with another, giving precendence to the current instance
93+
fn merge(self, other: Self) -> Self {
94+
Self {
95+
distro: self.distro.or(other.distro),
96+
latest: self.latest.or(other.latest),
97+
index: self.index.or(other.index),
98+
}
99+
}
100+
}
101+
81102
macro_rules! merge_hooks {
82103
($self:ident, $other:ident, $field:ident) => {
83104
match ($self.$field, $other.$field) {
@@ -97,7 +118,7 @@ impl HookConfig {
97118
self.npm.as_ref()
98119
}
99120

100-
pub fn yarn(&self) -> Option<&ToolHooks<Yarn>> {
121+
pub fn yarn(&self) -> Option<&YarnHooks> {
101122
self.yarn.as_ref()
102123
}
103124

@@ -199,6 +220,26 @@ impl HookConfig {
199220
}
200221
}
201222

223+
/// Format of the registry used for Yarn (Npm or Github)
224+
#[derive(PartialEq, Debug)]
225+
pub enum RegistryFormat {
226+
Npm,
227+
Github,
228+
}
229+
230+
impl RegistryFormat {
231+
pub fn from_str(raw_format: &str) -> Fallible<RegistryFormat> {
232+
match raw_format {
233+
"npm" => Ok(RegistryFormat::Npm),
234+
"github" => Ok(RegistryFormat::Github),
235+
other => Err(ErrorKind::InvalidRegistryFormat {
236+
format: String::from(other),
237+
}
238+
.into()),
239+
}
240+
}
241+
}
242+
202243
/// Volta hooks related to events.
203244
pub struct EventHooks {
204245
/// The hook for publishing events, if any.
@@ -217,7 +258,7 @@ impl EventHooks {
217258
#[cfg(test)]
218259
pub mod tests {
219260

220-
use super::{tool, HookConfig, Publish};
261+
use super::{tool, HookConfig, Publish, RegistryFormat};
221262
use std::path::PathBuf;
222263

223264
fn fixture_path(fixture_dir: &str) -> PathBuf {
@@ -284,9 +325,12 @@ pub mod tests {
284325
);
285326
assert_eq!(
286327
yarn.index,
287-
Some(tool::MetadataHook::Bin {
288-
bin: "/bin/to/yarn/index".to_string(),
289-
base_path: fixture_dir,
328+
Some(tool::YarnIndexHook {
329+
format: RegistryFormat::Github,
330+
metadata: tool::MetadataHook::Bin {
331+
bin: "/bin/to/yarn/index".to_string(),
332+
base_path: fixture_dir,
333+
},
290334
})
291335
);
292336
assert_eq!(
@@ -335,9 +379,10 @@ pub mod tests {
335379
);
336380
assert_eq!(
337381
yarn.index,
338-
Some(tool::MetadataHook::Prefix(
339-
"http://localhost/yarn/index/".to_string()
340-
))
382+
Some(tool::YarnIndexHook {
383+
format: RegistryFormat::Github,
384+
metadata: tool::MetadataHook::Prefix("http://localhost/yarn/index/".to_string())
385+
})
341386
);
342387
}
343388

@@ -380,8 +425,71 @@ pub mod tests {
380425
);
381426
assert_eq!(
382427
yarn.index,
383-
Some(tool::MetadataHook::Template(
384-
"http://localhost/yarn/index/{{version}}/".to_string()
428+
Some(tool::YarnIndexHook {
429+
format: RegistryFormat::Github,
430+
metadata: tool::MetadataHook::Template(
431+
"http://localhost/yarn/index/{{version}}/".to_string()
432+
)
433+
})
434+
);
435+
}
436+
437+
#[test]
438+
fn test_from_str_format_npm() {
439+
let fixture_dir = fixture_path("hooks");
440+
let format_npm_file = fixture_dir.join("format_npm.json");
441+
let hooks = HookConfig::from_file(&format_npm_file).unwrap().unwrap();
442+
let yarn = hooks.yarn.unwrap();
443+
let node = hooks.node.unwrap();
444+
let npm = hooks.npm.unwrap();
445+
assert_eq!(
446+
yarn.index,
447+
Some(tool::YarnIndexHook {
448+
format: RegistryFormat::Npm,
449+
metadata: tool::MetadataHook::Prefix("http://localhost/yarn/index/".to_string())
450+
})
451+
);
452+
// node and npm don't have format
453+
assert_eq!(
454+
node.index,
455+
Some(tool::MetadataHook::Prefix(
456+
"http://localhost/node/index/".to_string()
457+
))
458+
);
459+
assert_eq!(
460+
npm.index,
461+
Some(tool::MetadataHook::Prefix(
462+
"http://localhost/npm/index/".to_string()
463+
))
464+
);
465+
}
466+
467+
#[test]
468+
fn test_from_str_format_github() {
469+
let fixture_dir = fixture_path("hooks");
470+
let format_github_file = fixture_dir.join("format_github.json");
471+
let hooks = HookConfig::from_file(&format_github_file).unwrap().unwrap();
472+
let yarn = hooks.yarn.unwrap();
473+
let node = hooks.node.unwrap();
474+
let npm = hooks.npm.unwrap();
475+
assert_eq!(
476+
yarn.index,
477+
Some(tool::YarnIndexHook {
478+
format: RegistryFormat::Github,
479+
metadata: tool::MetadataHook::Prefix("http://localhost/yarn/index/".to_string())
480+
})
481+
);
482+
// node and npm don't have format
483+
assert_eq!(
484+
node.index,
485+
Some(tool::MetadataHook::Prefix(
486+
"http://localhost/node/index/".to_string()
487+
))
488+
);
489+
assert_eq!(
490+
npm.index,
491+
Some(tool::MetadataHook::Prefix(
492+
"http://localhost/npm/index/".to_string()
385493
))
386494
);
387495
}
@@ -436,9 +544,12 @@ pub mod tests {
436544
);
437545
assert_eq!(
438546
yarn.index,
439-
Some(tool::MetadataHook::Template(
440-
"http://localhost/yarn/index/{{version}}/".to_string()
441-
))
547+
Some(tool::YarnIndexHook {
548+
format: RegistryFormat::Github,
549+
metadata: tool::MetadataHook::Template(
550+
"http://localhost/yarn/index/{{version}}/".to_string()
551+
)
552+
})
442553
);
443554
assert_eq!(
444555
merged_hooks.events.expect("No events config found").publish,
@@ -492,9 +603,12 @@ pub mod tests {
492603
);
493604
assert_eq!(
494605
yarn.index,
495-
Some(tool::MetadataHook::Template(
496-
"http://localhost/yarn/index/{{version}}/".to_string()
497-
))
606+
Some(tool::YarnIndexHook {
607+
format: RegistryFormat::Github,
608+
metadata: tool::MetadataHook::Template(
609+
"http://localhost/yarn/index/{{version}}/".to_string()
610+
)
611+
})
498612
);
499613
assert_eq!(
500614
merged_hooks.events.expect("No events config found").publish,

0 commit comments

Comments
 (0)