Skip to content
This repository was archived by the owner on Sep 17, 2023. It is now read-only.

Commit 8ee7ca1

Browse files
committed
feat: add support for npm 7 workspaces
If there is no `lerna.json` manfiest, try reading a list of package files or globs out of a `workspaces` key in the root `package.json` manifest.
1 parent 7bf03c4 commit 8ee7ca1

File tree

5 files changed

+54
-23
lines changed

5 files changed

+54
-23
lines changed

src/lerna_manifest.rs

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,25 @@ struct LernaManifestFile {
1616
packages: Vec<String>,
1717
}
1818

19+
#[derive(Serialize, Deserialize, Debug)]
20+
struct PackageManifestFile {
21+
workspaces: Vec<String>,
22+
}
23+
1924
#[derive(Debug)]
20-
pub struct LernaManifest {
25+
pub struct MonorepoManifest {
2126
pub internal_package_manifests: Vec<PackageManifest>,
2227
}
2328

24-
fn get_internal_package_manifests<P>(
29+
fn get_internal_package_manifests<'a, P, I>(
2530
directory: P,
26-
lerna_manifest_file: &LernaManifestFile,
31+
package_globs: I,
2732
) -> Result<Vec<PackageManifest>, Box<dyn Error>>
2833
where
2934
P: AsRef<Path>,
35+
I: Iterator<Item = &'a String>,
3036
{
31-
let mut package_manifests: Vec<String> = lerna_manifest_file
32-
.packages
33-
.iter()
37+
let mut package_manifests: Vec<String> = package_globs
3438
.map(|package_manifest_glob| {
3539
Path::new(package_manifest_glob)
3640
.join("package.json")
@@ -64,21 +68,48 @@ where
6468
.collect::<Result<Vec<_>, Box<dyn Error>>>()
6569
}
6670

67-
impl LernaManifest {
68-
const FILENAME: &'static str = "lerna.json";
71+
impl MonorepoManifest {
72+
const LERNA_MANIFEST_FILENAME: &'static str = "lerna.json";
73+
const PACKAGE_MANIFEST_FILENAME: &'static str = "package.json";
6974

70-
pub fn from_directory<P>(root: P) -> Result<LernaManifest, Box<dyn Error>>
75+
fn from_lerna_manifest<P>(root: P) -> Result<MonorepoManifest, Box<dyn Error>>
7176
where
7277
P: AsRef<Path>,
7378
{
74-
let file = File::open(root.as_ref().join(Self::FILENAME))?;
79+
let file = File::open(root.as_ref().join(Self::LERNA_MANIFEST_FILENAME))?;
7580
let reader = BufReader::new(file);
76-
let manifest_contents: LernaManifestFile = serde_json::from_reader(reader)?;
77-
Ok(LernaManifest {
78-
internal_package_manifests: get_internal_package_manifests(&root, &manifest_contents)?,
81+
let lerna_manifest_contents: LernaManifestFile = serde_json::from_reader(reader)?;
82+
Ok(MonorepoManifest {
83+
internal_package_manifests: get_internal_package_manifests(
84+
&root,
85+
lerna_manifest_contents.packages.iter(),
86+
)?,
7987
})
8088
}
8189

90+
fn from_package_manifest<P>(root: P) -> Result<MonorepoManifest, Box<dyn Error>>
91+
where
92+
P: AsRef<Path>,
93+
{
94+
let file = File::open(root.as_ref().join(Self::PACKAGE_MANIFEST_FILENAME))?;
95+
let reader = BufReader::new(file);
96+
let package_manifest_contents: PackageManifestFile = serde_json::from_reader(reader)?;
97+
Ok(MonorepoManifest {
98+
internal_package_manifests: get_internal_package_manifests(
99+
&root,
100+
package_manifest_contents.workspaces.iter(),
101+
)?,
102+
})
103+
}
104+
105+
pub fn from_directory<P>(root: P) -> Result<MonorepoManifest, Box<dyn Error>>
106+
where
107+
P: AsRef<Path>,
108+
{
109+
MonorepoManifest::from_lerna_manifest(&root)
110+
.or_else(|_| MonorepoManifest::from_package_manifest(&root))
111+
}
112+
82113
pub fn package_manifests_by_package_name(
83114
&self,
84115
) -> Result<HashMap<String, &PackageManifest>, Box<dyn Error>> {

src/link.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::configuration_file::ConfigurationFile;
88
use crate::io::{
99
write_project_references, TypescriptParentProjectReference, TypescriptProjectReference,
1010
};
11-
use crate::lerna_manifest::LernaManifest;
11+
use crate::lerna_manifest::MonorepoManifest;
1212
use crate::package_manifest::PackageManifest;
1313
use crate::typescript_config::TypescriptConfig;
1414

@@ -59,7 +59,7 @@ fn vecs_match<T: PartialEq>(a: &[T], b: &[T]) -> bool {
5959
// This permits us to build the monorepo from the top down.
6060
fn link_children_packages(
6161
opts: &crate::opts::Link,
62-
lerna_manifest: &LernaManifest,
62+
lerna_manifest: &MonorepoManifest,
6363
) -> Result<bool, Box<dyn Error>> {
6464
let mut is_exit_success = true;
6565

@@ -106,7 +106,7 @@ fn link_children_packages(
106106

107107
fn link_package_dependencies(
108108
opts: &crate::opts::Link,
109-
lerna_manifest: &LernaManifest,
109+
lerna_manifest: &MonorepoManifest,
110110
) -> Result<bool, Box<dyn Error>> {
111111
let package_manifest_by_package_name = lerna_manifest
112112
.package_manifests_by_package_name()
@@ -199,7 +199,7 @@ fn link_package_dependencies(
199199

200200
pub fn link_typescript_project_references(opts: crate::opts::Link) -> Result<(), Box<dyn Error>> {
201201
let lerna_manifest =
202-
LernaManifest::from_directory(&opts.root).expect("Unable to read lerna manifest");
202+
MonorepoManifest::from_directory(&opts.root).expect("Unable to read monorepo manifest");
203203

204204
let is_children_link_success =
205205
link_children_packages(&opts, &lerna_manifest).expect("Unable to link children packages");

src/make_depend.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use askama::Template;
77
use pathdiff::diff_paths;
88

99
use crate::configuration_file::ConfigurationFile;
10-
use crate::lerna_manifest::LernaManifest;
10+
use crate::lerna_manifest::MonorepoManifest;
1111
use crate::package_manifest::PackageManifest;
1212

1313
#[derive(Template)]
@@ -26,7 +26,7 @@ struct MakefileTemplate<'a> {
2626
}
2727

2828
pub fn make_dependency_makefile(opts: crate::opts::MakeDepend) -> Result<(), Box<dyn Error>> {
29-
let lerna_manifest = LernaManifest::from_directory(&opts.root)?;
29+
let lerna_manifest = MonorepoManifest::from_directory(&opts.root)?;
3030
let package_manifest = PackageManifest::from_directory(&opts.root, &opts.package_directory)?;
3131

3232
// determine the complete set of internal dependencies (and self!)

src/pin.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::collections::HashMap;
22
use std::error::Error;
33

44
use crate::configuration_file::ConfigurationFile;
5-
use crate::lerna_manifest::LernaManifest;
5+
use crate::lerna_manifest::MonorepoManifest;
66
use crate::package_manifest::DependencyGroup;
77

88
#[derive(Clone)]
@@ -15,7 +15,7 @@ struct UnpinnedDependency {
1515
pub fn pin_version_numbers_in_internal_packages(
1616
opts: crate::opts::Pin,
1717
) -> Result<(), Box<dyn Error>> {
18-
let lerna_manifest = LernaManifest::from_directory(&opts.root)?;
18+
let lerna_manifest = MonorepoManifest::from_directory(&opts.root)?;
1919
let mut package_manifest_by_package_name = lerna_manifest
2020
.into_package_manifests_by_package_name()
2121
.expect("Unable to read all package manifests");

src/query.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::error::Error;
44
use crate::opts;
55

66
use crate::configuration_file::ConfigurationFile;
7-
use crate::lerna_manifest::LernaManifest;
7+
use crate::lerna_manifest::MonorepoManifest;
88

99
pub fn handle_subcommand(opts: crate::opts::Query) -> Result<(), Box<dyn Error>> {
1010
match opts.subcommand {
@@ -16,7 +16,7 @@ fn query_internal_dependencies(
1616
opts: &crate::opts::InternalDependencies,
1717
) -> Result<(), Box<dyn Error>> {
1818
let lerna_manifest =
19-
LernaManifest::from_directory(&opts.root).expect("Unable to read lerna manifest");
19+
MonorepoManifest::from_directory(&opts.root).expect("Unable to read monorepo manifest");
2020

2121
let package_manifest_by_package_name = lerna_manifest
2222
.package_manifests_by_package_name()

0 commit comments

Comments
 (0)