@@ -53,6 +53,7 @@ pub struct SetWorkspaceConfigOptions {
53
53
pub struct WorkspaceConfig {
54
54
pub root : WorkspaceMemberConfig ,
55
55
pub members : HashMap < String , WorkspaceMemberConfig > ,
56
+ pub patches : HashMap < String , LockfilePatchContent > ,
56
57
}
57
58
58
59
#[ derive( Default , Debug , Clone , PartialEq , Eq ) ]
@@ -64,7 +65,8 @@ pub struct WorkspaceMemberConfig {
64
65
#[ derive( Debug , Clone , PartialEq , Eq ) ]
65
66
pub struct NpmPackageLockfileInfo {
66
67
pub serialized_id : StackString ,
67
- pub integrity : String ,
68
+ /// Will be `None` for patch packages.
69
+ pub integrity : Option < String > ,
68
70
pub dependencies : Vec < NpmPackageDependencyLockfileInfo > ,
69
71
pub optional_dependencies : Vec < NpmPackageDependencyLockfileInfo > ,
70
72
pub os : Vec < SmallStackString > ,
@@ -80,7 +82,8 @@ pub struct NpmPackageDependencyLockfileInfo {
80
82
81
83
#[ derive( Debug , Clone , Serialize , Deserialize , Hash , PartialEq , Eq ) ]
82
84
pub struct NpmPackageInfo {
83
- pub integrity : String ,
85
+ /// Will be `None` for patch packages.
86
+ pub integrity : Option < String > ,
84
87
#[ serde( default ) ]
85
88
pub dependencies : BTreeMap < StackString , StackString > ,
86
89
#[ serde( default ) ]
@@ -180,18 +183,34 @@ impl WorkspaceMemberConfigContent {
180
183
}
181
184
}
182
185
186
+ #[ derive( Debug , Default , Clone , Deserialize , PartialEq , Eq ) ]
187
+ #[ serde( rename_all = "camelCase" ) ]
188
+ pub struct LockfilePatchContent {
189
+ #[ serde( default ) ]
190
+ #[ serde( skip_serializing_if = "Vec::is_empty" ) ]
191
+ pub dependencies : HashSet < JsrDepPackageReq > ,
192
+ #[ serde( default ) ]
193
+ #[ serde( skip_serializing_if = "Vec::is_empty" ) ]
194
+ pub peer_dependencies : HashSet < JsrDepPackageReq > ,
195
+ #[ serde( default ) ]
196
+ #[ serde( skip_serializing_if = "HashMap::is_empty" ) ]
197
+ pub peer_dependencies_meta : HashMap < String , serde_json:: Value > ,
198
+ }
199
+
183
200
#[ derive( Debug , Default , Clone , Deserialize ) ]
184
201
#[ serde( rename_all = "camelCase" ) ]
185
202
pub ( crate ) struct WorkspaceConfigContent {
186
203
#[ serde( default , flatten) ]
187
204
pub root : WorkspaceMemberConfigContent ,
188
205
#[ serde( default ) ]
189
206
pub members : HashMap < String , WorkspaceMemberConfigContent > ,
207
+ #[ serde( default ) ]
208
+ pub patches : HashMap < String , LockfilePatchContent > ,
190
209
}
191
210
192
211
impl WorkspaceConfigContent {
193
212
pub fn is_empty ( & self ) -> bool {
194
- self . root . is_empty ( ) && self . members . is_empty ( )
213
+ self . root . is_empty ( ) && self . members . is_empty ( ) && self . patches . is_empty ( )
195
214
}
196
215
197
216
fn get_all_dep_reqs ( & self ) -> impl Iterator < Item = & JsrDepPackageReq > {
@@ -265,7 +284,7 @@ impl LockfileContent {
265
284
#[ derive( Debug , Deserialize ) ]
266
285
#[ serde( rename_all = "camelCase" ) ]
267
286
struct RawNpmPackageInfo {
268
- pub integrity : String ,
287
+ pub integrity : Option < String > ,
269
288
#[ serde( default ) ]
270
289
pub dependencies : Vec < StackString > ,
271
290
#[ serde( default ) ]
@@ -699,6 +718,40 @@ impl Lockfile {
699
718
// to !self.has_content_changed after populating it with this information
700
719
let allow_content_changed =
701
720
self . has_content_changed || !self . content . is_empty ( ) ;
721
+
722
+ let has_any_patch_changed = options. config . patches . len ( )
723
+ != self . content . workspace . patches . len ( )
724
+ || !options. config . patches . is_empty ( )
725
+ && options. config . patches . iter ( ) . all ( |( patch, new) | {
726
+ let Some ( existing) = self . content . workspace . patches . get_mut ( patch)
727
+ else {
728
+ return true ;
729
+ } ;
730
+ new != existing
731
+ } ) ;
732
+
733
+ // if a patch changes, it's quite complicated to figure out how to get it to redo
734
+ // npm resolution just for that part, so for now, clear out all the npm dependencies
735
+ // if any patch changes
736
+ if has_any_patch_changed {
737
+ self . has_content_changed = true ;
738
+ self . content . packages . npm . clear ( ) ;
739
+ self
740
+ . content
741
+ . packages
742
+ . specifiers
743
+ . retain ( |k, _| match k. kind {
744
+ deno_semver:: package:: PackageKind :: Jsr => true ,
745
+ deno_semver:: package:: PackageKind :: Npm => false ,
746
+ } ) ;
747
+ self . content . workspace . patches . clear ( ) ;
748
+ self
749
+ . content
750
+ . workspace
751
+ . patches
752
+ . extend ( options. config . patches ) ;
753
+ }
754
+
702
755
let old_deps = self
703
756
. content
704
757
. workspace
@@ -1215,7 +1268,7 @@ mod tests {
1215
1268
// already in lockfile
1216
1269
let npm_package = NpmPackageLockfileInfo {
1217
1270
serialized_id : "[email protected] " . into ( ) ,
1218
- integrity : "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" . to_string ( ) ,
1271
+ integrity : Some ( "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" . to_string ( ) ) ,
1219
1272
dependencies : vec ! [ ] ,
1220
1273
optional_dependencies : vec ! [ ] ,
1221
1274
os : vec ! [ ] ,
@@ -1228,7 +1281,7 @@ mod tests {
1228
1281
// insert package that exists already, but has slightly different properties
1229
1282
let npm_package = NpmPackageLockfileInfo {
1230
1283
serialized_id : "[email protected] " . into ( ) ,
1231
- integrity : "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" . to_string ( ) ,
1284
+ integrity : Some ( "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" . to_string ( ) ) ,
1232
1285
dependencies : vec ! [ ] ,
1233
1286
optional_dependencies : vec ! [ ] ,
1234
1287
os : vec ! [ ] ,
@@ -1241,7 +1294,7 @@ mod tests {
1241
1294
lockfile. has_content_changed = false ;
1242
1295
let npm_package = NpmPackageLockfileInfo {
1243
1296
serialized_id : "[email protected] " . into ( ) ,
1244
- integrity : "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" . to_string ( ) ,
1297
+ integrity : Some ( "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" . to_string ( ) ) ,
1245
1298
dependencies : vec ! [ ] ,
1246
1299
optional_dependencies : vec ! [ ] ,
1247
1300
os : vec ! [ ] ,
@@ -1259,7 +1312,7 @@ mod tests {
1259
1312
1260
1313
let npm_package = NpmPackageLockfileInfo {
1261
1314
serialized_id : "[email protected] " . into ( ) ,
1262
- integrity : "sha512-foobar" . to_string ( ) ,
1315
+ integrity : Some ( "sha512-foobar" . to_string ( ) ) ,
1263
1316
dependencies : vec ! [ ] ,
1264
1317
optional_dependencies : vec ! [ ] ,
1265
1318
os : vec ! [ ] ,
0 commit comments