1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use std::collections::HashMap;
use anyhow::{anyhow, Result};
use crate::configuration_file::ConfigurationFile;
use crate::monorepo_manifest::MonorepoManifest;
use crate::package_manifest::DependencyGroup;
#[derive(Clone)]
struct UnpinnedDependency {
name: String,
actual: String,
expected: String,
}
pub fn pin_version_numbers_in_internal_packages(opts: crate::opts::Pin) -> Result<()> {
let lerna_manifest = MonorepoManifest::from_directory(&opts.root)?;
let mut package_manifest_by_package_name =
lerna_manifest.package_manifests_by_package_name()?;
let package_version_by_package_name: HashMap<String, String> = package_manifest_by_package_name
.values()
.map(|package| {
(
package.contents.name.to_owned(),
package.contents.version.to_owned(),
)
})
.collect();
let mut exit_code = 0;
for package_manifest in package_manifest_by_package_name.values_mut() {
let mut dependencies_to_update: Vec<UnpinnedDependency> = Vec::new();
for dependency_group in DependencyGroup::VALUES.iter() {
if let Some(mut unpinned_dependencies) = package_manifest
.get_dependency_group_mut(dependency_group)
.map(|dependencies| -> Vec<UnpinnedDependency> {
dependencies
.into_iter()
.filter_map(
|(dependency_name, dependency_version)| -> Option<UnpinnedDependency> {
package_version_by_package_name
.get(dependency_name)
.and_then(|internal_dependency_declared_version| {
let used_dependency_version = dependency_version
.as_str()
.expect(
"Expected each dependency version to be a string",
)
.to_owned();
match used_dependency_version
.eq(internal_dependency_declared_version)
{
true => None,
false => {
*dependency_version = serde_json::Value::String(
internal_dependency_declared_version.to_owned(),
);
Some(UnpinnedDependency {
name: dependency_name.to_owned(),
actual: used_dependency_version,
expected: internal_dependency_declared_version
.to_owned(),
})
}
}
})
},
)
.collect()
})
{
dependencies_to_update.append(&mut unpinned_dependencies)
}
}
if !dependencies_to_update.is_empty() {
if opts.check_only {
exit_code = 1;
println!(
"File contains unexpected dependency versions: {:?}",
package_manifest.path()
);
for dependency in dependencies_to_update {
println!(
"\tdependency: {:?}\texpected: {:?}\tgot: {:?}",
dependency.name, dependency.expected, dependency.actual
);
}
} else {
package_manifest.write()?;
}
}
}
if opts.check_only && exit_code != 0 {
return Err(anyhow!(
"Found unexpected dependency versions for internal packages"
));
}
Ok(())
}