Skip to content

Commit 3641fa4

Browse files
committed
feat(core): complete removal of banned custom types
1 parent 5e58309 commit 3641fa4

2 files changed

Lines changed: 257 additions & 4 deletions

File tree

src/instance.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -279,13 +279,40 @@ impl Instance {
279279
pub fn remove(&self) {
280280
match self.descriptor.dependency_type.strategy {
281281
Strategy::NameAndVersionProps => {
282-
debug!("@TODO: remove instance for NameAndVersionProps");
282+
let path_to_prop = &self.descriptor.dependency_type.path;
283+
if let Some(parent_path) = path_to_prop.rfind('/') {
284+
let parent_path = &path_to_prop[..parent_path];
285+
let prop_name = &path_to_prop[parent_path.len() + 1..];
286+
if let Some(Value::Object(obj)) = self.descriptor.package.borrow_mut().contents.borrow_mut().pointer_mut(parent_path) {
287+
obj.remove(prop_name);
288+
}
289+
} else if path_to_prop == "/" {
290+
debug!("Cannot remove root property for NameAndVersionProps");
291+
}
283292
}
284293
Strategy::NamedVersionString => {
285-
debug!("@TODO: remove instance for NamedVersionString");
294+
let path_to_prop = &self.descriptor.dependency_type.path;
295+
if let Some(parent_path) = path_to_prop.rfind('/') {
296+
let parent_path = &path_to_prop[..parent_path];
297+
let prop_name = &path_to_prop[parent_path.len() + 1..];
298+
if let Some(Value::Object(obj)) = self.descriptor.package.borrow_mut().contents.borrow_mut().pointer_mut(parent_path) {
299+
obj.remove(prop_name);
300+
}
301+
} else if path_to_prop == "/" {
302+
debug!("Cannot remove root property for NamedVersionString");
303+
}
286304
}
287305
Strategy::UnnamedVersionString => {
288-
debug!("@TODO: remove instance for UnnamedVersionString");
306+
let path_to_prop = &self.descriptor.dependency_type.path;
307+
if let Some(parent_path) = path_to_prop.rfind('/') {
308+
let parent_path = &path_to_prop[..parent_path];
309+
let prop_name = &path_to_prop[parent_path.len() + 1..];
310+
if let Some(Value::Object(obj)) = self.descriptor.package.borrow_mut().contents.borrow_mut().pointer_mut(parent_path) {
311+
obj.remove(prop_name);
312+
}
313+
} else if path_to_prop == "/" {
314+
debug!("Cannot remove root property for UnnamedVersionString");
315+
}
289316
}
290317
Strategy::VersionsByName => {
291318
let path_to_obj = &self.descriptor.dependency_type.path;

src/visit_packages/banned_test.rs

Lines changed: 227 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use {
22
crate::{
3-
instance_state::{FixableInstance::*, InstanceState, SuspectInstance::*},
3+
instance_state::{FixableInstance::*, InstanceState, SuspectInstance::*, ValidInstance::*},
44
test::{
55
builder::TestBuilder,
66
expect::{expect, ExpectedInstance},
@@ -54,3 +54,229 @@ fn refuses_to_ban_local_version() {
5454
},
5555
]);
5656
}
57+
58+
#[test]
59+
fn removes_instance_with_name_and_version_props_strategy() {
60+
let ctx = TestBuilder::new()
61+
.with_config(json!({
62+
"customTypes": {
63+
"customPackage": {
64+
"strategy": "name~version",
65+
"namePath": "customName",
66+
"path": "customVersion"
67+
}
68+
}
69+
}))
70+
.with_packages(vec![json!({
71+
"name": "package-a",
72+
"version": "1.0.0",
73+
"customName": "my-custom-package",
74+
"customVersion": "2.1.0"
75+
})])
76+
.with_version_group(json!({
77+
"dependencies": ["my-custom-package"],
78+
"dependencyTypes": ["customPackage"],
79+
"isBanned": true
80+
}))
81+
.build_and_visit();
82+
83+
expect(&ctx).to_have_instances(vec![
84+
ExpectedInstance {
85+
state: InstanceState::valid(IsLocalAndValid),
86+
dependency_name: "package-a",
87+
id: "package-a in /version of package-a",
88+
actual: "1.0.0",
89+
expected: Some("1.0.0"),
90+
overridden: None,
91+
},
92+
ExpectedInstance {
93+
state: InstanceState::fixable(IsBanned),
94+
dependency_name: "my-custom-package",
95+
id: "my-custom-package in /customVersion of package-a",
96+
actual: "2.1.0",
97+
expected: Some(""),
98+
overridden: None,
99+
},
100+
]);
101+
}
102+
103+
#[test]
104+
fn removes_instance_with_named_version_string_strategy() {
105+
let ctx = TestBuilder::new()
106+
.with_config(json!({
107+
"customTypes": {
108+
"packageManager": {
109+
"strategy": "name@version",
110+
"path": "packageManager"
111+
}
112+
}
113+
}))
114+
.with_packages(vec![json!({
115+
"name": "package-a",
116+
"version": "1.0.0",
117+
"packageManager": "pnpm@7.27.0"
118+
})])
119+
.with_version_group(json!({
120+
"dependencies": ["pnpm"],
121+
"dependencyTypes": ["packageManager"],
122+
"isBanned": true
123+
}))
124+
.build_and_visit();
125+
126+
expect(&ctx).to_have_instances(vec![
127+
ExpectedInstance {
128+
state: InstanceState::valid(IsLocalAndValid),
129+
dependency_name: "package-a",
130+
id: "package-a in /version of package-a",
131+
actual: "1.0.0",
132+
expected: Some("1.0.0"),
133+
overridden: None,
134+
},
135+
ExpectedInstance {
136+
state: InstanceState::fixable(IsBanned),
137+
dependency_name: "pnpm",
138+
id: "pnpm in /packageManager of package-a",
139+
actual: "7.27.0",
140+
expected: Some(""),
141+
overridden: None,
142+
},
143+
]);
144+
}
145+
146+
#[test]
147+
fn removes_instance_with_unnamed_version_string_strategy() {
148+
let ctx = TestBuilder::new()
149+
.with_config(json!({
150+
"customTypes": {
151+
"nodeVersion": {
152+
"strategy": "version",
153+
"path": "engines.node"
154+
}
155+
}
156+
}))
157+
.with_packages(vec![json!({
158+
"name": "package-a",
159+
"version": "1.0.0",
160+
"engines": {
161+
"node": ">=16.0.0"
162+
}
163+
})])
164+
.with_version_group(json!({
165+
"dependencies": ["nodeVersion"],
166+
"dependencyTypes": ["nodeVersion"],
167+
"isBanned": true
168+
}))
169+
.build_and_visit();
170+
171+
expect(&ctx).to_have_instances(vec![
172+
ExpectedInstance {
173+
state: InstanceState::valid(IsLocalAndValid),
174+
dependency_name: "package-a",
175+
id: "package-a in /version of package-a",
176+
actual: "1.0.0",
177+
expected: Some("1.0.0"),
178+
overridden: None,
179+
},
180+
ExpectedInstance {
181+
state: InstanceState::fixable(IsBanned),
182+
dependency_name: "nodeVersion",
183+
id: "nodeVersion in /engines/node of package-a",
184+
actual: ">=16.0.0",
185+
expected: Some(""),
186+
overridden: None,
187+
},
188+
]);
189+
}
190+
191+
#[test]
192+
fn removes_instance_with_versions_by_name_strategy() {
193+
let ctx = TestBuilder::new()
194+
.with_packages(vec![json!({
195+
"name": "package-a",
196+
"version": "1.0.0",
197+
"dependencies": {
198+
"react": "18.0.0",
199+
"lodash": "4.17.21"
200+
}
201+
})])
202+
.with_version_group(json!({
203+
"dependencies": ["react"],
204+
"isBanned": true
205+
}))
206+
.build_and_visit();
207+
208+
expect(&ctx).to_have_instances(vec![
209+
ExpectedInstance {
210+
state: InstanceState::valid(IsLocalAndValid),
211+
dependency_name: "package-a",
212+
id: "package-a in /version of package-a",
213+
actual: "1.0.0",
214+
expected: Some("1.0.0"),
215+
overridden: None,
216+
},
217+
ExpectedInstance {
218+
state: InstanceState::fixable(IsBanned),
219+
dependency_name: "react",
220+
id: "react in /dependencies of package-a",
221+
actual: "18.0.0",
222+
expected: Some(""),
223+
overridden: None,
224+
},
225+
ExpectedInstance {
226+
state: InstanceState::valid(IsNonSemverButIdentical),
227+
dependency_name: "lodash",
228+
id: "lodash in /dependencies of package-a",
229+
actual: "4.17.21",
230+
expected: Some("4.17.21"),
231+
overridden: None,
232+
},
233+
]);
234+
}
235+
236+
#[test]
237+
fn removes_nested_property_with_unnamed_version_string_strategy() {
238+
let ctx = TestBuilder::new()
239+
.with_config(json!({
240+
"customTypes": {
241+
"customConfig": {
242+
"strategy": "version",
243+
"path": "custom.config.version"
244+
}
245+
}
246+
}))
247+
.with_packages(vec![json!({
248+
"name": "package-a",
249+
"version": "1.0.0",
250+
"custom": {
251+
"config": {
252+
"version": "2.5.0",
253+
"other": "keep-this"
254+
}
255+
}
256+
})])
257+
.with_version_group(json!({
258+
"dependencies": ["customConfig"],
259+
"dependencyTypes": ["customConfig"],
260+
"isBanned": true
261+
}))
262+
.build_and_visit();
263+
264+
expect(&ctx).to_have_instances(vec![
265+
ExpectedInstance {
266+
state: InstanceState::valid(IsLocalAndValid),
267+
dependency_name: "package-a",
268+
id: "package-a in /version of package-a",
269+
actual: "1.0.0",
270+
expected: Some("1.0.0"),
271+
overridden: None,
272+
},
273+
ExpectedInstance {
274+
state: InstanceState::fixable(IsBanned),
275+
dependency_name: "customConfig",
276+
id: "customConfig in /custom/config/version of package-a",
277+
actual: "2.5.0",
278+
expected: Some(""),
279+
overridden: None,
280+
},
281+
]);
282+
}

0 commit comments

Comments
 (0)