1
1
use std:: collections:: HashMap ;
2
- use std:: fs:: File ;
3
- use std:: io:: BufReader ;
4
- use std:: marker:: Sync ;
5
- use std:: path:: Path ;
2
+ use std:: path:: { Path , PathBuf } ;
6
3
7
- use anyhow:: Result ;
4
+ use anyhow:: { Context , Result } ;
8
5
9
6
use globwalk:: { FileType , GlobWalkerBuilder } ;
10
7
8
+ use indoc:: formatdoc;
11
9
use serde:: { Deserialize , Serialize } ;
12
10
13
11
use pariter:: IteratorExt as _;
14
12
15
13
use crate :: configuration_file:: ConfigurationFile ;
14
+ use crate :: io:: read_json_from_file;
16
15
use crate :: package_manifest:: PackageManifest ;
17
16
17
+ #[ derive( Serialize , Deserialize , Debug ) ]
18
+ struct PackageManifestGlob ( String ) ;
19
+
20
+ // REFACTOR: drop the File suffix in this identifier
18
21
#[ derive( Serialize , Deserialize , Debug ) ]
19
22
struct LernaManifestFile {
20
- packages : Vec < String > ,
23
+ packages : Vec < PackageManifestGlob > ,
21
24
}
22
25
26
+ // REFACTOR: drop the File suffix in this identifier
23
27
#[ derive( Serialize , Deserialize , Debug ) ]
24
28
struct PackageManifestFile {
25
- workspaces : Vec < String > ,
29
+ workspaces : Vec < PackageManifestGlob > ,
26
30
}
27
31
28
32
#[ derive( Debug ) ]
29
33
pub struct MonorepoManifest {
30
- pub internal_package_manifests : Vec < PackageManifest > ,
34
+ root : PathBuf ,
35
+ globs : Vec < PackageManifestGlob > ,
31
36
}
32
37
33
- fn get_internal_package_manifests < ' a , P , I > (
34
- directory : P ,
35
- package_globs : I ,
36
- ) -> Result < Vec < PackageManifest > >
37
- where
38
- P : AsRef < Path > + Sync ,
39
- I : Iterator < Item = & ' a String > ,
40
- {
38
+ fn get_internal_package_manifests (
39
+ monorepo_root : & Path ,
40
+ package_globs : & [ PackageManifestGlob ] ,
41
+ ) -> Result < Vec < PackageManifest > > {
41
42
let mut package_manifests: Vec < String > = package_globs
43
+ . iter ( )
42
44
. map ( |package_manifest_glob| {
43
- Path :: new ( package_manifest_glob)
45
+ Path :: new ( & package_manifest_glob. 0 )
44
46
. join ( "package.json" )
45
47
. to_str ( )
46
48
. expect ( "Path not valid UTF-8" )
51
53
// ignore paths to speed up file-system walk
52
54
package_manifests. push ( String :: from ( "!node_modules/" ) ) ;
53
55
54
- let monorepo_root = directory. as_ref ( ) . to_owned ( ) ;
56
+ // Take ownership so we can move this value into the parallel_map
57
+ let monorepo_root = monorepo_root. to_owned ( ) ;
55
58
56
- GlobWalkerBuilder :: from_patterns ( & directory , & package_manifests)
59
+ GlobWalkerBuilder :: from_patterns ( & monorepo_root , & package_manifests)
57
60
. file_type ( FileType :: FILE )
58
61
. min_depth ( 1 )
59
62
. build ( )
@@ -64,14 +67,13 @@ where
64
67
|options| options. threads ( 32 ) ,
65
68
move |dir_entry| {
66
69
PackageManifest :: from_directory (
67
- monorepo_root. clone ( ) ,
70
+ & monorepo_root,
68
71
dir_entry
69
72
. path ( )
70
73
. parent ( )
71
74
. expect ( "Unexpected package in monorepo root" )
72
- . strip_prefix ( monorepo_root. clone ( ) )
73
- . expect ( "Unexpected package in monorepo root" )
74
- . to_owned ( ) ,
75
+ . strip_prefix ( & monorepo_root)
76
+ . expect ( "Unexpected package in monorepo root" ) ,
75
77
)
76
78
} ,
77
79
)
@@ -82,57 +84,63 @@ impl MonorepoManifest {
82
84
const LERNA_MANIFEST_FILENAME : & ' static str = "lerna.json" ;
83
85
const PACKAGE_MANIFEST_FILENAME : & ' static str = "package.json" ;
84
86
85
- fn from_lerna_manifest < P > ( root : P ) -> Result < MonorepoManifest >
86
- where
87
- P : AsRef < Path > + Sync ,
88
- {
89
- let file = File :: open ( root. as_ref ( ) . join ( Self :: LERNA_MANIFEST_FILENAME ) ) ?;
90
- let reader = BufReader :: new ( file) ;
91
- let lerna_manifest_contents: LernaManifestFile = serde_json:: from_reader ( reader) ?;
87
+ fn from_lerna_manifest ( root : & Path ) -> Result < MonorepoManifest > {
88
+ let filename = root. join ( Self :: LERNA_MANIFEST_FILENAME ) ;
89
+ let lerna_manifest: LernaManifestFile =
90
+ read_json_from_file ( & filename) . with_context ( || {
91
+ formatdoc ! (
92
+ "
93
+ Unexpected contents in {:?}
94
+
95
+ I'm trying to parse the following properties and values out
96
+ of this lerna.json file:
97
+
98
+ - packages: string[]
99
+ " ,
100
+ filename
101
+ )
102
+ } ) ?;
92
103
Ok ( MonorepoManifest {
93
- internal_package_manifests : get_internal_package_manifests (
94
- & root,
95
- lerna_manifest_contents. packages . iter ( ) ,
96
- ) ?,
104
+ root : root. to_owned ( ) ,
105
+ globs : lerna_manifest. packages ,
97
106
} )
98
107
}
99
108
100
- fn from_package_manifest < P > ( root : P ) -> Result < MonorepoManifest >
101
- where
102
- P : AsRef < Path > + Sync ,
103
- {
104
- let file = File :: open ( root. as_ref ( ) . join ( Self :: PACKAGE_MANIFEST_FILENAME ) ) ?;
105
- let reader = BufReader :: new ( file) ;
106
- let package_manifest_contents: PackageManifestFile = serde_json:: from_reader ( reader) ?;
109
+ fn from_package_manifest ( root : & Path ) -> Result < MonorepoManifest > {
110
+ let filename = root. join ( Self :: PACKAGE_MANIFEST_FILENAME ) ;
111
+ let package_manifest: PackageManifestFile =
112
+ read_json_from_file ( & filename) . with_context ( || {
113
+ formatdoc ! (
114
+ "
115
+ Unexpected contents in {:?}
116
+
117
+ I'm trying to parse the following properties and values out
118
+ of this package.json file:
119
+
120
+ - workspaces: string[]
121
+ " ,
122
+ filename
123
+ )
124
+ } ) ?;
107
125
Ok ( MonorepoManifest {
108
- internal_package_manifests : get_internal_package_manifests (
109
- & root,
110
- package_manifest_contents. workspaces . iter ( ) ,
111
- ) ?,
126
+ root : root. to_owned ( ) ,
127
+ globs : package_manifest. workspaces ,
112
128
} )
113
129
}
114
130
115
- pub fn from_directory < P > ( root : P ) -> Result < MonorepoManifest >
116
- where
117
- P : AsRef < Path > + Sync ,
118
- {
119
- MonorepoManifest :: from_lerna_manifest ( & root)
120
- . or_else ( |_| MonorepoManifest :: from_package_manifest ( & root) )
131
+ pub fn from_directory ( root : & Path ) -> Result < MonorepoManifest > {
132
+ MonorepoManifest :: from_lerna_manifest ( root)
133
+ . or_else ( |_| MonorepoManifest :: from_package_manifest ( root) )
121
134
}
122
135
123
- pub fn package_manifests_by_package_name ( & self ) -> Result < HashMap < String , & PackageManifest > > {
124
- self . internal_package_manifests
125
- . iter ( )
126
- . map ( |manifest| Ok ( ( manifest. contents . name . to_owned ( ) , manifest) ) )
127
- . collect ( )
136
+ pub fn package_manifests_by_package_name ( & self ) -> Result < HashMap < String , PackageManifest > > {
137
+ Ok ( get_internal_package_manifests ( & self . root , & self . globs ) ?
138
+ . into_iter ( )
139
+ . map ( |manifest| ( manifest. contents . name . to_owned ( ) , manifest) )
140
+ . collect ( ) )
128
141
}
129
142
130
- pub fn into_package_manifests_by_package_name (
131
- self ,
132
- ) -> Result < HashMap < String , PackageManifest > > {
133
- self . internal_package_manifests
134
- . into_iter ( )
135
- . map ( |manifest| Ok ( ( manifest. contents . name . clone ( ) , manifest) ) )
136
- . collect ( )
143
+ pub fn internal_package_manifests ( & self ) -> Result < Vec < PackageManifest > > {
144
+ get_internal_package_manifests ( & self . root , & self . globs )
137
145
}
138
146
}
0 commit comments