Skip to content

Commit 1586b4d

Browse files
authored
BI-558 - Improve requiredBy field to support path to root (#443)
1 parent 32751e0 commit 1586b4d

File tree

5 files changed

+187
-108
lines changed

5 files changed

+187
-108
lines changed

Diff for: build-info-api/src/main/java/org/jfrog/build/api/Dependency.java

+31-20
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717
package org.jfrog.build.api;
1818

1919
import com.thoughtworks.xstream.annotations.XStreamAlias;
20+
import org.apache.commons.lang.ArrayUtils;
2021

21-
import java.util.List;
22+
import java.util.Arrays;
23+
import java.util.Objects;
2224
import java.util.Set;
2325

2426
/**
@@ -33,7 +35,14 @@ public class Dependency extends BaseBuildFileBean {
3335

3436
private String id;
3537
private Set<String> scopes;
36-
private List<String> requiredBy;
38+
39+
/*
40+
* [["parentIdA", "a1", "a2",... "moduleId"],
41+
* ["parentIdB", "b1", "b2",... "moduleId"],
42+
* ["parentIdC", "c1", "c2",... "moduleId"],
43+
* ...]
44+
*/
45+
private String[][] requiredBy;
3746

3847
/**
3948
* Returns the ID of the dependency
@@ -72,24 +81,33 @@ public void setScopes(Set<String> scopes) {
7281
}
7382

7483
/**
75-
* Returns an ID list of dependencies that directly depend on this dependency. Used for building the module's
76-
* transitive dependency graph. Can be left empty if a root dependency.
84+
* Returns path-to-root dependency lists that directly depend on this dependency.
85+
* Used for building the module's transitive dependency graph. Can be left empty if a root dependency.
7786
*
78-
* @return Required dependency IDs list
87+
* @return dependency path-to-root lists.
7988
*/
80-
public List<String> getRequiredBy() {
89+
public String[][] getRequiredBy() {
8190
return requiredBy;
8291
}
8392

8493
/**
85-
* Sets an ID list of dependencies that directly depend on this dependency.
94+
* Sets path-to-root dependency lists that directly depend on this dependency.
8695
*
87-
* @param requiredBy Required dependency IDs list
96+
* @param requiredBy dependency path-to-root lists
8897
*/
89-
public void setRequiredBy(List<String> requiredBy) {
98+
public void setRequiredBy(String[][] requiredBy) {
9099
this.requiredBy = requiredBy;
91100
}
92101

102+
/**
103+
* Adds an ID of another dependency required by this one to the required dependencies list.
104+
*
105+
* @param pathToModuleRoot - path from parent dependency to the module ID, modules separated
106+
*/
107+
public void addRequiredBy(String[] pathToModuleRoot) {
108+
this.requiredBy = (String[][]) ArrayUtils.add(requiredBy, pathToModuleRoot);
109+
}
110+
93111
@Override
94112
public boolean equals(Object o) {
95113
if (this == o) {
@@ -103,24 +121,17 @@ public boolean equals(Object o) {
103121
}
104122
Dependency that = (Dependency) o;
105123

106-
if (id != null ? !id.equals(that.id) : that.id != null) {
107-
return false;
108-
}
109-
if (requiredBy != null ? !requiredBy.equals(that.requiredBy) : that.requiredBy != null) {
124+
if (!Objects.equals(id, that.id)) {
110125
return false;
111126
}
112-
if (scopes != null ? !scopes.equals(that.scopes) : that.scopes != null) {
127+
if (!Objects.equals(scopes, that.scopes)) {
113128
return false;
114129
}
115-
return true;
130+
return Arrays.deepEquals(requiredBy, that.requiredBy);
116131
}
117132

118133
@Override
119134
public int hashCode() {
120-
int result = super.hashCode();
121-
result = 31 * result + (id != null ? id.hashCode() : 0);
122-
result = 31 * result + (scopes != null ? scopes.hashCode() : 0);
123-
result = 31 * result + (requiredBy != null ? requiredBy.hashCode() : 0);
124-
return result;
135+
return Objects.hash(id, scopes, Arrays.deepHashCode(requiredBy));
125136
}
126137
}

Diff for: build-info-api/src/main/java/org/jfrog/build/api/builder/DependencyBuilder.java

+12-12
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@
1616

1717
package org.jfrog.build.api.builder;
1818

19+
import org.apache.commons.lang.ArrayUtils;
1920
import org.jfrog.build.api.Dependency;
2021

21-
import java.util.*;
22+
import java.util.HashSet;
23+
import java.util.Properties;
24+
import java.util.Set;
2225

2326
/**
2427
* A builder for the dependency class
@@ -35,7 +38,7 @@ public class DependencyBuilder {
3538
private String md5;
3639
private String localPath;
3740
private String remotePath;
38-
private List<String> requiredBy;
41+
private String[][] requiredBy;
3942
private Properties properties;
4043

4144
/**
@@ -161,27 +164,24 @@ public DependencyBuilder remotePath(String remotePath) {
161164
}
162165

163166
/**
164-
* Sets an ID list of other dependencies required by this one
167+
* Sets path-to-root dependency lists that directly depend on this dependency.
165168
*
166-
* @param requiredBy Required dependency IDs list
169+
* @param requiredBy dependency path-to-root lists
167170
* @return Builder instance
168171
*/
169-
public DependencyBuilder requiredBy(List<String> requiredBy) {
172+
public DependencyBuilder requiredBy(String[][] requiredBy) {
170173
this.requiredBy = requiredBy;
171174
return this;
172175
}
173176

174177
/**
175-
* Adds an ID of another dependency required by this one to the required dependencies list
178+
* Adds an ID of another dependency that requires this one to the requiredBy dependencies list.
176179
*
177-
* @param requiredBy Required dependency ID
180+
* @param pathToModuleRoot - path from parent dependency to the module ID, modules separated
178181
* @return Builder instance
179182
*/
180-
public DependencyBuilder addRequiredBy(String requiredBy) {
181-
if (this.requiredBy == null) {
182-
this.requiredBy = new ArrayList<>();
183-
}
184-
this.requiredBy.add(requiredBy);
183+
public DependencyBuilder addRequiredBy(String[] pathToModuleRoot) {
184+
this.requiredBy = (String[][]) ArrayUtils.add(requiredBy, pathToModuleRoot);
185185
return this;
186186
}
187187

Diff for: build-info-api/src/test/java/org/jfrog/build/api/DependencyTest.java

+41-13
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@
1616

1717
package org.jfrog.build.api;
1818

19+
import org.apache.commons.lang.ArrayUtils;
1920
import org.jfrog.build.api.util.CommonUtils;
20-
import org.testng.Assert;
2121
import org.testng.annotations.Test;
2222

23-
import java.util.*;
23+
import java.util.HashMap;
24+
import java.util.Properties;
25+
import java.util.Set;
2426

25-
import static org.testng.Assert.assertEquals;
26-
import static org.testng.Assert.assertNull;
27+
import static org.testng.Assert.*;
2728

2829
/**
2930
* Tests the behavior of the dependency class
@@ -58,7 +59,7 @@ public void testSetters() {
5859
String sha1 = "pop";
5960
String sha256 = "lol";
6061
String md5 = "shmop";
61-
List<String> requiredBy = Collections.singletonList("pitzi");
62+
String[][] requiredBy = new String[][]{{"pitzi"}};
6263

6364
Dependency dependency = new Dependency();
6465
dependency.setId(id);
@@ -78,6 +79,33 @@ public void testSetters() {
7879
assertEquals(dependency.getRequiredBy(), requiredBy, "Unexpected dependency required by.");
7980
}
8081

82+
public void testAddRequiredBy() {
83+
// Create a dependency
84+
Dependency dependency = new Dependency();
85+
assertTrue(ArrayUtils.isEmpty(dependency.getRequiredBy()));
86+
87+
// Add required by A
88+
String[] parentA = new String[]{"a", "b", "c"};
89+
dependency.addRequiredBy(parentA);
90+
assertEquals(ArrayUtils.getLength(dependency.getRequiredBy()), 1);
91+
assertEquals(dependency.getRequiredBy()[0], parentA);
92+
93+
// Add required by B
94+
String[] parentB = new String[]{"b", "c", "d", "e"};
95+
dependency.addRequiredBy(parentB);
96+
assertEquals(ArrayUtils.getLength(dependency.getRequiredBy()), 2);
97+
assertEquals(dependency.getRequiredBy()[0], parentA);
98+
assertEquals(dependency.getRequiredBy()[1], parentB);
99+
100+
// Add required by C
101+
String[] parentC = new String[]{"c", "d"};
102+
dependency.addRequiredBy(parentC);
103+
assertEquals(ArrayUtils.getLength(dependency.getRequiredBy()), 3);
104+
assertEquals(dependency.getRequiredBy()[0], parentA);
105+
assertEquals(dependency.getRequiredBy()[1], parentB);
106+
assertEquals(dependency.getRequiredBy()[2], parentC);
107+
}
108+
81109
public void testEqualsAndHash() {
82110
//Properties are not included in equals\hash
83111
Properties properties = new Properties();
@@ -88,7 +116,7 @@ public void testEqualsAndHash() {
88116
dependency1.setSha1("111");
89117
dependency1.setSha256("11111");
90118
dependency1.setMd5("1111");
91-
dependency1.setRequiredBy(Collections.singletonList("11111"));
119+
dependency1.setRequiredBy(new String[][]{{"11111"}});
92120
dependency1.setScopes(CommonUtils.newHashSet("1", "11"));
93121
dependency1.setProperties(properties);
94122

@@ -98,7 +126,7 @@ public void testEqualsAndHash() {
98126
dependency2.setSha1("111");
99127
dependency2.setSha256("11111");
100128
dependency2.setMd5("1111");
101-
dependency2.setRequiredBy(Collections.singletonList("11111"));
129+
dependency2.setRequiredBy(new String[][]{{"11111"}});
102130
dependency2.setScopes(CommonUtils.newHashSet("1", "11"));
103131
dependency2.setProperties(properties);
104132

@@ -108,21 +136,21 @@ public void testEqualsAndHash() {
108136
dependency3.setSha1("333");
109137
dependency3.setSha256("33333");
110138
dependency3.setMd5("3333");
111-
dependency3.setRequiredBy(Collections.singletonList("33333"));
139+
dependency3.setRequiredBy(new String[][]{{"33333"}});
112140
dependency3.setScopes(CommonUtils.newHashSet("333333", "3333333"));
113141
dependency3.setProperties(properties);
114142

115-
Assert.assertEquals(dependency1, dependency2, "Expected equals == true for equivalent artifacts");
116-
Assert.assertTrue(!dependency1.equals(dependency3), "Expected equals == false for non-equivalent artifacts");
143+
assertEquals(dependency1, dependency2, "Expected equals == true for equivalent artifacts");
144+
assertNotEquals(dependency3, dependency1, "Expected equals == false for non-equivalent artifacts");
117145

118146
HashMap<Dependency, String> testMap = new HashMap<>();
119147
testMap.put(dependency1, "1");
120148
testMap.put(dependency2, "2");
121-
Assert.assertEquals(testMap.size(), 1, "Expected same hashcode for equal artifacts");
122-
Assert.assertEquals(testMap.values().iterator().next(), "2", "Expected insertion of equivalent artifact to" +
149+
assertEquals(testMap.size(), 1, "Expected same hashcode for equal artifacts");
150+
assertEquals(testMap.values().iterator().next(), "2", "Expected insertion of equivalent artifact to" +
123151
" map to replace old one");
124152

125153
testMap.put(dependency3, "3");
126-
Assert.assertEquals(testMap.size(), 2, "Expected artifact to not overwrite existing non-equivalent artifact");
154+
assertEquals(testMap.size(), 2, "Expected artifact to not overwrite existing non-equivalent artifact");
127155
}
128156
}

Diff for: build-info-api/src/test/java/org/jfrog/build/api/builder/DependencyBuilderTest.java

+18-15
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,11 @@
1616

1717
package org.jfrog.build.api.builder;
1818

19+
import org.apache.commons.lang.ArrayUtils;
1920
import org.jfrog.build.api.Dependency;
2021
import org.jfrog.build.api.util.CommonUtils;
2122
import org.testng.annotations.Test;
2223

23-
import java.util.Collections;
24-
import java.util.List;
2524
import java.util.Properties;
2625
import java.util.Set;
2726

@@ -61,7 +60,7 @@ public void testBuilderSetters() {
6160
String sha1 = "pop";
6261
String sha256 = "lol";
6362
String md5 = "shmop";
64-
List<String> requiredBy = Collections.singletonList("pitzi");
63+
String[][] requiredBy = new String[][]{{"pitzi"}};
6564
Properties properties = new Properties();
6665

6766
Dependency dependency = new DependencyBuilder().id(id).type(type).scopes(scopes).sha1(sha1).md5(md5).sha256(sha256)
@@ -82,18 +81,22 @@ public void testBuilderSetters() {
8281
* Validates the dependency values after using the builder add methods
8382
*/
8483
public void testBuilderAddMethods() {
85-
String requiredBy = "requiredMoo";
86-
String propertyKey = "key";
87-
String propertyValue = "value";
84+
String propertyKey = "keyA";
85+
String propertyValue = "valueA";
8886

89-
Dependency dependency = new DependencyBuilder().addRequiredBy(requiredBy).
90-
addProperty(propertyKey, propertyValue).build();
91-
List<String> requiredByList = dependency.getRequiredBy();
92-
assertFalse(requiredByList.isEmpty(), "A dependency requirement should have been added.");
93-
assertEquals(requiredByList.iterator().next(), requiredBy, "Unexpected dependency requirement.");
94-
assertTrue(dependency.getProperties().containsKey(propertyKey),
95-
"A dependency property should have been added.");
96-
assertEquals(dependency.getProperties().get(propertyKey), propertyValue,
97-
"Unexpected dependency property value.");
87+
Dependency dependency = new DependencyBuilder().addProperty(propertyKey, propertyValue).build();
88+
assertTrue(dependency.getProperties().containsKey(propertyKey), "A dependency property should have been added.");
89+
assertEquals(dependency.getProperties().get(propertyKey), propertyValue, "Unexpected dependency property value.");
90+
}
91+
92+
public void testBuilderAddRequiredBy() {
93+
String[] requiredByA = {"A", "to", "module", "root", "moduleID"};
94+
String[] requiredByB = {"B", "C", "to", "module", "root", "moduleID"};
95+
96+
Dependency dependency = new DependencyBuilder().addRequiredBy(requiredByA).addRequiredBy(requiredByB).build();
97+
String[][] requiredByList = dependency.getRequiredBy();
98+
assertEquals(ArrayUtils.getLength(requiredByList), 2);
99+
assertEquals(requiredByList[0], requiredByA, "Unexpected dependency requirement.");
100+
assertEquals(requiredByList[1], requiredByB, "Unexpected dependency requirement.");
98101
}
99102
}

0 commit comments

Comments
 (0)