Skip to content

Commit 58060a2

Browse files
committed
re-implement some ArchUnit code to support treating package-info as a class dependency when scanning
since TNG/ArchUnit#1565 has not been merged in a timely manner, we need a custom implementation on our end to fix this issue until it is finally merged.
1 parent 0048cbf commit 58060a2

File tree

11 files changed

+1143
-26
lines changed

11 files changed

+1143
-26
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ Rules can be sourced from OSS libraries or private internal libraries.
1616
### Runner Plugin
1717
[![Gradle Plugin Portal](https://img.shields.io/gradle-plugin-portal/v/com.netflix.nebula.archrules.runner?style=for-the-badge&color=01AF01)](https://plugins.gradle.org/plugin/com.netflix.nebula.archrules.runner)
1818

19+
### Aggregate Console Report Plugin
20+
[![Gradle Plugin Portal](https://img.shields.io/gradle-plugin-portal/v/com.netflix.nebula.archrules.aggregate?style=for-the-badge&color=01AF01)](https://plugins.gradle.org/plugin/com.netflix.nebula.archrules.aggregate)
21+
1922

2023
## Authoring Rules
2124

nebula-archrules-core/src/main/java/com/netflix/nebula/archrules/core/Runner.java

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
package com.netflix.nebula.archrules.core;
22

33
import com.tngtech.archunit.core.domain.JavaClasses;
4-
import com.tngtech.archunit.core.importer.ClassFileImporter;
4+
import com.tngtech.archunit.core.importer.ClassFileImporterWithPackage;
55
import com.tngtech.archunit.core.importer.Location;
66
import com.tngtech.archunit.core.importer.Locations;
77
import com.tngtech.archunit.lang.ArchRule;
88
import com.tngtech.archunit.lang.ConditionEvents;
99
import com.tngtech.archunit.lang.EvaluationResult;
1010

11-
import java.net.MalformedURLException;
12-
import java.net.URI;
13-
import java.net.URL;
1411
import java.util.*;
1512
import java.util.stream.Collectors;
1613

@@ -52,22 +49,7 @@ public static EvaluationResult check(ArchRule rule, Class<?>... classesToCheck)
5249
.map(Locations::ofClass)
5350
.flatMap(Collection::stream)
5451
.collect(Collectors.toSet());
55-
List<URL> uris = Arrays.stream(classesToCheck)
56-
.map(clazz -> clazz.getPackage().getName())
57-
.map(Locations::ofPackage)
58-
.flatMap(it -> it.stream().map(Location::asURI))
59-
.map(u -> URI.create(u.toASCIIString() + "package-info.class"))
60-
.map(uri -> {
61-
try {
62-
return uri.toURL();
63-
} catch (MalformedURLException e) {
64-
return null;
65-
}
66-
})
67-
.filter(Objects::nonNull)
68-
.collect(Collectors.toList());
69-
locs.addAll(Locations.of(uris));
70-
final JavaClasses classes = new ClassFileImporter()
52+
final JavaClasses classes = new ClassFileImporterWithPackage()
7153
.importLocations(locs);
7254
return check(rule, classes);
7355
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.tngtech.archunit.core.domain;
2+
3+
import java.util.Arrays;
4+
5+
/**
6+
* logic from <a href="https://github.com/TNG/ArchUnit/pull/1565">package dependency scanning</a>
7+
*/
8+
public class DomainObjectCreationContextWithPackage {
9+
10+
public static void completePackage(JavaClass javaClass, ImportContext importContext) {
11+
JavaPackage javaPackage = JavaPackage.from(Arrays.asList(
12+
javaClass,
13+
importContext.resolveClass(javaClass.getPackageName() + ".package-info")));
14+
javaClass.setPackage(javaPackage);
15+
}
16+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.tngtech.archunit.core.importer;
2+
3+
import com.tngtech.archunit.core.domain.JavaClasses;
4+
import com.tngtech.archunit.thirdparty.com.google.common.collect.Iterables;
5+
import org.slf4j.Logger;
6+
import org.slf4j.LoggerFactory;
7+
8+
import java.nio.file.Path;
9+
import java.nio.file.Paths;
10+
import java.util.ArrayList;
11+
import java.util.Collection;
12+
import java.util.List;
13+
14+
import static java.util.Arrays.stream;
15+
import static java.util.stream.Collectors.toSet;
16+
17+
/**
18+
* copy of <a href="https://github.com/TNG/ArchUnit/blob/main/archunit/src/main/java/com/tngtech/archunit/core/importer/ClassFileImporter.java">ClassFileImporter</a>
19+
* changed to use custom elements for package info resolution
20+
*/
21+
public class ClassFileImporterWithPackage {
22+
private static final Logger LOG = LoggerFactory.getLogger(ClassFileImporterWithPackage.class);
23+
private final ImportOptions importOptions;
24+
25+
public ClassFileImporterWithPackage() {
26+
this(new ImportOptions());
27+
}
28+
29+
public ClassFileImporterWithPackage(Collection<ImportOption> importOptions) {
30+
this(new ImportOptions().with(importOptions));
31+
}
32+
33+
private ClassFileImporterWithPackage(ImportOptions importOptions) {
34+
this.importOptions = importOptions;
35+
}
36+
37+
public JavaClasses importLocations(Collection<Location> locations) {
38+
List<ClassFileSource> sources = new ArrayList<>();
39+
for (Location location : locations) {
40+
tryAdd(sources, location);
41+
}
42+
return new ClassFileProcessorWithPackage().process(unify(sources));
43+
}
44+
45+
public JavaClasses importPaths(String... paths) {
46+
return importPaths(stream(paths).map(Paths::get).collect(toSet()));
47+
}
48+
49+
public JavaClasses importPaths(Collection<Path> paths) {
50+
return importLocations(paths.stream().map(Location::of).collect(toSet()));
51+
}
52+
53+
private void tryAdd(List<ClassFileSource> sources, Location location) {
54+
try {
55+
sources.add(location.asClassFileSource(importOptions));
56+
} catch (Exception e) {
57+
LOG.warn(String.format("Couldn't derive %s from %s",
58+
ClassFileSource.class.getSimpleName(), location), e);
59+
}
60+
}
61+
62+
private ClassFileSource unify(List<ClassFileSource> sources) {
63+
return Iterables.concat(sources)::iterator;
64+
}
65+
}

0 commit comments

Comments
 (0)