Skip to content

Commit b3c127e

Browse files
committed
PR feedback.
1 parent e3c73ec commit b3c127e

12 files changed

Lines changed: 217 additions & 245 deletions

File tree

api/api.txt

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ package com.autonomousapps {
44
public abstract class AbstractExtension {
55
ctor @javax.inject.Inject public AbstractExtension(org.gradle.api.model.ObjectFactory objects, org.gradle.api.invocation.Gradle gradle);
66
method public final org.gradle.api.file.RegularFileProperty adviceOutput();
7-
method public final org.gradle.api.file.RegularFileProperty typeUsageOutput();
87
method public final void app();
98
method public final void registerPostProcessingTask(org.gradle.api.tasks.TaskProvider<? extends com.autonomousapps.AbstractPostProcessingTask> task);
9+
method public final org.gradle.api.provider.MapProperty<java.lang.String,org.gradle.api.file.RegularFile> typeUsageOutputs();
1010
field public static final String NAME = "dependencyAnalysis";
1111
}
1212

@@ -53,6 +53,13 @@ package com.autonomousapps {
5353
field public static final com.autonomousapps.Flags INSTANCE;
5454
}
5555

56+
@org.gradle.work.DisableCachingByDefault(because="Writes to console") public abstract class ListSourceFilesTask extends org.gradle.api.DefaultTask {
57+
ctor public ListSourceFilesTask();
58+
method @org.gradle.api.tasks.TaskAction public final void action();
59+
method @org.gradle.api.tasks.Nested public abstract org.gradle.api.provider.ListProperty<com.autonomousapps.internal.kotlin.multiplatform.FileCollectionMap> getFiles();
60+
property @org.gradle.api.tasks.Nested public abstract org.gradle.api.provider.ListProperty<com.autonomousapps.internal.kotlin.multiplatform.FileCollectionMap> files;
61+
}
62+
5663
}
5764

5865
package com.autonomousapps.exception {
@@ -212,18 +219,18 @@ package com.autonomousapps.extension {
212219
property @org.gradle.api.tasks.Input public abstract org.gradle.api.provider.Property<java.lang.String> postscript;
213220
}
214221

222+
public abstract class SourceSetsHandler implements org.gradle.api.Named {
223+
ctor @javax.inject.Inject public SourceSetsHandler(String sourceSetName, String projectPath, org.gradle.api.model.ObjectFactory objects);
224+
method public String getName();
225+
}
226+
215227
public abstract class TypeUsageHandler {
216228
ctor @javax.inject.Inject public TypeUsageHandler(org.gradle.api.model.ObjectFactory objects);
217229
method public final void excludePackages(java.lang.String... packages);
218230
method public final void excludeRegex(@org.intellij.lang.annotations.Language("RegExp") java.lang.String... patterns);
219231
method public final void excludeTypes(java.lang.String... types);
220232
}
221233

222-
public abstract class SourceSetsHandler implements org.gradle.api.Named {
223-
ctor @javax.inject.Inject public SourceSetsHandler(String sourceSetName, String projectPath, org.gradle.api.model.ObjectFactory objects);
224-
method public String getName();
225-
}
226-
227234
public final class Undefined extends com.autonomousapps.extension.Behavior {
228235
ctor public Undefined();
229236
ctor public Undefined(java.util.Set<? extends com.autonomousapps.extension.Exclusion> filter = mutableSetOf(), String sourceSetName = "__all");
@@ -519,26 +526,28 @@ package com.autonomousapps.model {
519526
property public String identifier;
520527
}
521528

522-
@com.squareup.moshi.JsonClass(generateAdapter=false) public final class ProjectTypeUsage implements java.lang.Comparable<com.autonomousapps.model.ProjectTypeUsage> {
523-
ctor public ProjectTypeUsage(String projectPath, com.autonomousapps.model.TypeUsageSummary summary, java.util.Map<java.lang.String,java.lang.Integer> internal, java.util.Map<java.lang.String,? extends java.util.Map<java.lang.String,java.lang.Integer>> projectDependencies, java.util.Map<java.lang.String,? extends java.util.Map<java.lang.String,java.lang.Integer>> libraryDependencies);
524-
method public int compareTo(com.autonomousapps.model.ProjectTypeUsage other);
529+
@com.squareup.moshi.JsonClass(generateAdapter=false) public final class ProjectTypeUsage {
530+
ctor public ProjectTypeUsage(String projectPath, com.autonomousapps.model.TypeUsageSummary summary, java.util.Map<java.lang.String,java.lang.Integer> internal, java.util.Map<java.lang.String,? extends java.util.Map<java.lang.String,java.lang.Integer>> projectDependencies, java.util.Map<java.lang.String,? extends java.util.Map<java.lang.String,java.lang.Integer>> libraryDependencies, java.util.Map<java.lang.String,java.lang.Integer> unknownDependencies = emptyMap());
525531
method public String component1();
526532
method public com.autonomousapps.model.TypeUsageSummary component2();
527533
method public java.util.Map<java.lang.String,java.lang.Integer> component3();
528534
method public java.util.Map<java.lang.String,java.util.Map<java.lang.String,java.lang.Integer>> component4();
529535
method public java.util.Map<java.lang.String,java.util.Map<java.lang.String,java.lang.Integer>> component5();
530-
method public com.autonomousapps.model.ProjectTypeUsage copy(String projectPath, com.autonomousapps.model.TypeUsageSummary summary, java.util.Map<java.lang.String,java.lang.Integer> internal, java.util.Map<java.lang.String,? extends java.util.Map<java.lang.String,java.lang.Integer>> projectDependencies, java.util.Map<java.lang.String,? extends java.util.Map<java.lang.String,java.lang.Integer>> libraryDependencies);
536+
method public java.util.Map<java.lang.String,java.lang.Integer> component6();
537+
method public com.autonomousapps.model.ProjectTypeUsage copy(String projectPath, com.autonomousapps.model.TypeUsageSummary summary, java.util.Map<java.lang.String,java.lang.Integer> internal, java.util.Map<java.lang.String,? extends java.util.Map<java.lang.String,java.lang.Integer>> projectDependencies, java.util.Map<java.lang.String,? extends java.util.Map<java.lang.String,java.lang.Integer>> libraryDependencies, java.util.Map<java.lang.String,java.lang.Integer> unknownDependencies);
531538
method public java.util.Map<java.lang.String,java.lang.Integer> getInternal();
532539
method public java.util.Map<java.lang.String,java.util.Map<java.lang.String,java.lang.Integer>> getLibraryDependencies();
533540
method public java.util.Map<java.lang.String,java.util.Map<java.lang.String,java.lang.Integer>> getProjectDependencies();
534541
method public String getProjectPath();
535542
method public com.autonomousapps.model.TypeUsageSummary getSummary();
543+
method public java.util.Map<java.lang.String,java.lang.Integer> getUnknownDependencies();
536544
method public boolean isEmpty();
537545
property public final java.util.Map<java.lang.String,java.lang.Integer> internal;
538546
property public final java.util.Map<java.lang.String,java.util.Map<java.lang.String,java.lang.Integer>> libraryDependencies;
539547
property public final java.util.Map<java.lang.String,java.util.Map<java.lang.String,java.lang.Integer>> projectDependencies;
540548
property public final String projectPath;
541549
property public final com.autonomousapps.model.TypeUsageSummary summary;
550+
property public final java.util.Map<java.lang.String,java.lang.Integer> unknownDependencies;
542551
}
543552

544553
@com.squareup.moshi.JsonClass(generateAdapter=false) public final class TypeUsageSummary {

src/functionalTest/groovy/com/autonomousapps/jvm/TypeUsageSpec.groovy

Lines changed: 10 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,8 @@ final class TypeUsageSpec extends AbstractJvmSpec {
1919
when:
2020
build(gradleVersion, gradleProject.rootDir, 'computeTypeUsageMain')
2121
22-
then: 'has correct summary'
23-
def usage = project.actualTypeUsage()
24-
assertThat(usage.projectPath).isEqualTo(':proj')
25-
assertThat(usage.summary.totalTypes).isGreaterThan(0)
26-
assertThat(usage.summary.totalFiles).isEqualTo(2)
27-
assertThat(usage.summary.internalTypes).isEqualTo(1)
28-
29-
and: 'tracks internal usage'
30-
assertThat(usage.internal).containsKey('com.example.Example')
31-
// Note: Internal class is not tracked because it's defined but never used
32-
33-
and: 'tracks library dependencies'
34-
assertThat(usage.libraryDependencies).isNotEmpty()
35-
36-
and: 'tracks commons-collections usage'
37-
assertThat(usage.libraryDependencies)
38-
.containsKey('org.apache.commons:commons-collections4')
39-
def commonsUsage = usage.libraryDependencies.get('org.apache.commons:commons-collections4')
40-
assertThat(commonsUsage).containsKey('org.apache.commons.collections4.bag.HashBag')
41-
42-
and: 'tracks kotlin stdlib usage'
43-
assert usage.libraryDependencies.keySet().any { it.startsWith('org.jetbrains.kotlin:kotlin-stdlib') }
22+
then:
23+
assertThat(project.actualTypeUsage()).isEqualTo(project.expectedTypeUsage())
4424
4525
where:
4626
gradleVersion << gradleVersions()
@@ -54,46 +34,8 @@ final class TypeUsageSpec extends AbstractJvmSpec {
5434
when:
5535
build(gradleVersion, gradleProject.rootDir, 'computeTypeUsageMain')
5636
57-
then: 'excluded packages are not present'
58-
def usage = project.actualTypeUsage()
59-
def allTypes = usage.libraryDependencies.values()
60-
.collectMany { it.keySet() }
61-
62-
assertThat(allTypes).doesNotContain('org.apache.commons.collections4.bag.HashBag')
63-
64-
and: 'excluded types are not present'
65-
assertThat(allTypes).doesNotContain('kotlin.Unit')
66-
67-
and: 'non-excluded types are still present'
68-
assertThat(usage.internal).containsKey('com.example.Example')
69-
70-
where:
71-
gradleVersion << gradleVersions()
72-
}
73-
74-
def "categorizes dependencies correctly (#gradleVersion)"() {
75-
given:
76-
def project = new TypeUsageProject()
77-
gradleProject = project.gradleProject
78-
79-
when:
80-
build(gradleVersion, gradleProject.rootDir, 'computeTypeUsageMain')
81-
82-
then: 'internal types are in internal map'
83-
def usage = project.actualTypeUsage()
84-
assertThat(usage.internal).isNotEmpty()
85-
assertThat(usage.internal).containsKey('com.example.Example')
86-
87-
and: 'library types are in libraryDependencies map'
88-
assertThat(usage.libraryDependencies).isNotEmpty()
89-
90-
and: 'no project dependencies (single-project)'
91-
assertThat(usage.projectDependencies).isEmpty()
92-
93-
and: 'summary counts match'
94-
assertThat(usage.summary.internalTypes).isEqualTo(usage.internal.size())
95-
assertThat(usage.summary.libraryDependencies).isEqualTo(usage.libraryDependencies.size())
96-
assertThat(usage.summary.projectDependencies).isEqualTo(0)
37+
then:
38+
assertThat(project.actualTypeUsage()).isEqualTo(project.expectedTypeUsage())
9739
9840
where:
9941
gradleVersion << gradleVersions()
@@ -107,88 +49,14 @@ final class TypeUsageSpec extends AbstractJvmSpec {
10749
when:
10850
build(gradleVersion, gradleProject.rootDir, 'computeTypeUsageMain')
10951
110-
then: 'app module tracks project dependencies'
111-
def appUsage = project.actualTypeUsageFor(':app')
112-
assertThat(appUsage.projectPath).isEqualTo(':app')
113-
assertThat(appUsage.projectDependencies).hasSize(2)
114-
assertThat(appUsage.projectDependencies).containsKey(':core')
115-
assertThat(appUsage.projectDependencies).containsKey(':utils')
116-
117-
and: 'app tracks types from core'
118-
def coreTypes = appUsage.projectDependencies[':core']
119-
assertThat(coreTypes).containsKey('com.example.core.UserRepository')
120-
assertThat(coreTypes).containsKey('com.example.core.User')
121-
122-
and: 'app tracks types from utils'
123-
def utilsTypes = appUsage.projectDependencies[':utils']
124-
assertThat(utilsTypes).containsKey('com.example.utils.Logger')
125-
126-
and: 'app tracks library dependencies'
127-
assertThat(appUsage.libraryDependencies).containsKey('org.apache.commons:commons-collections4')
128-
129-
and: 'app tracks internal types'
130-
assertThat(appUsage.internal).containsKey('com.example.app.MainActivity')
131-
132-
where:
133-
gradleVersion << gradleVersions()
134-
}
135-
136-
def "core module tracks its dependencies (#gradleVersion)"() {
137-
given:
138-
def project = new TypeUsageMultiModuleProject()
139-
gradleProject = project.gradleProject
140-
141-
when:
142-
build(gradleVersion, gradleProject.rootDir, 'computeTypeUsageMain')
143-
144-
then: 'core tracks utils as project dependency'
145-
def coreUsage = project.actualTypeUsageFor(':core')
146-
assertThat(coreUsage.projectPath).isEqualTo(':core')
147-
assertThat(coreUsage.projectDependencies).hasSize(1)
148-
assertThat(coreUsage.projectDependencies).containsKey(':utils')
149-
150-
and: 'core tracks Logger from utils'
151-
def utilsTypes = coreUsage.projectDependencies[':utils']
152-
assertThat(utilsTypes).containsKey('com.example.utils.Logger')
153-
154-
and: 'core tracks its own internal types'
155-
assertThat(coreUsage.internal).containsKey('com.example.core.User')
156-
157-
and: 'core has no library dependencies beyond kotlin stdlib'
158-
def nonKotlinLibs = coreUsage.libraryDependencies.keySet().findAll {
159-
!it.startsWith('org.jetbrains')
160-
}
161-
assertThat(nonKotlinLibs).isEmpty()
162-
163-
where:
164-
gradleVersion << gradleVersions()
165-
}
166-
167-
def "utils module has only library dependencies (#gradleVersion)"() {
168-
given:
169-
def project = new TypeUsageMultiModuleProject()
170-
gradleProject = project.gradleProject
171-
172-
when:
173-
build(gradleVersion, gradleProject.rootDir, 'computeTypeUsageMain')
174-
175-
then: 'utils has no project dependencies'
176-
def utilsUsage = project.actualTypeUsageFor(':utils')
177-
assertThat(utilsUsage.projectPath).isEqualTo(':utils')
178-
assertThat(utilsUsage.projectDependencies).isEmpty()
179-
180-
and: 'utils tracks commons-io'
181-
assertThat(utilsUsage.libraryDependencies).containsKey('commons-io:commons-io')
182-
def commonsIoTypes = utilsUsage.libraryDependencies['commons-io:commons-io']
183-
assertThat(commonsIoTypes).containsKey('org.apache.commons.io.FileUtils')
52+
then: 'app module'
53+
assertThat(project.actualTypeUsageFor(':app')).isEqualTo(project.expectedAppTypeUsage())
18454
185-
and: 'utils tracks internal Logger type'
186-
assertThat(utilsUsage.internal).containsKey('com.example.utils.Logger')
55+
and: 'core module'
56+
assertThat(project.actualTypeUsageFor(':core')).isEqualTo(project.expectedCoreTypeUsage())
18757
188-
and: 'summary counts are correct'
189-
assertThat(utilsUsage.summary.projectDependencies).isEqualTo(0)
190-
assertThat(utilsUsage.summary.libraryDependencies).isGreaterThan(0)
191-
assertThat(utilsUsage.summary.internalTypes).isEqualTo(utilsUsage.internal.size())
58+
and: 'utils module'
59+
assertThat(project.actualTypeUsageFor(':utils')).isEqualTo(project.expectedUtilsTypeUsage())
19260
19361
where:
19462
gradleVersion << gradleVersions()

src/functionalTest/groovy/com/autonomousapps/jvm/projects/TypeUsageMultiModuleProject.groovy

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ import com.autonomousapps.AbstractProject
66
import com.autonomousapps.kit.GradleProject
77
import com.autonomousapps.kit.Source
88
import com.autonomousapps.kit.SourceType
9-
import com.autonomousapps.internal.OutputPathsKt
10-
import com.autonomousapps.internal.utils.MoshiUtils
119
import com.autonomousapps.model.ProjectTypeUsage
10+
import com.autonomousapps.model.TypeUsageSummary
1211

12+
import static com.autonomousapps.internal.OutputPathsKt.getTypeUsagePath
13+
import static com.autonomousapps.internal.utils.MoshiUtils.MOSHI
1314
import static com.autonomousapps.kit.gradle.Dependency.project
1415
import static com.autonomousapps.kit.gradle.dependencies.Dependencies.*
1516

@@ -161,9 +162,75 @@ final class TypeUsageMultiModuleProject extends AbstractProject {
161162
]
162163

163164
ProjectTypeUsage actualTypeUsageFor(String projectPath) {
164-
def typeUsage = gradleProject.singleArtifact(projectPath,
165-
OutputPathsKt.getTypeUsagePath('main'))
166-
def adapter = MoshiUtils.MOSHI.adapter(ProjectTypeUsage)
165+
def typeUsage = gradleProject.singleArtifact(projectPath, getTypeUsagePath('main'))
166+
def adapter = MOSHI.adapter(ProjectTypeUsage)
167167
return adapter.fromJson(typeUsage.asPath.text)
168168
}
169+
170+
ProjectTypeUsage expectedAppTypeUsage() {
171+
return new ProjectTypeUsage(
172+
':app',
173+
new TypeUsageSummary(
174+
/* totalTypes */ 8,
175+
/* totalFiles */ 2,
176+
/* internalTypes */ 1,
177+
/* projectDependencies */ 2,
178+
/* libraryDependencies */ 3
179+
),
180+
['com.example.app.MainActivity': 1],
181+
[
182+
':core': ['com.example.core.User': 1, 'com.example.core.UserRepository': 1],
183+
':utils': ['com.example.utils.Logger': 1],
184+
],
185+
[
186+
'org.apache.commons:commons-collections4': ['org.apache.commons.collections4.bag.HashBag': 1],
187+
'org.jetbrains.kotlin:kotlin-stdlib': ['kotlin.Metadata': 2, 'kotlin.jvm.internal.SourceDebugExtension': 1],
188+
'org.jetbrains:annotations': ['org.jetbrains.annotations.NotNull': 2],
189+
],
190+
[:]
191+
)
192+
}
193+
194+
ProjectTypeUsage expectedCoreTypeUsage() {
195+
return new ProjectTypeUsage(
196+
':core',
197+
new TypeUsageSummary(
198+
/* totalTypes */ 7,
199+
/* totalFiles */ 3,
200+
/* internalTypes */ 1,
201+
/* projectDependencies */ 1,
202+
/* libraryDependencies */ 2
203+
),
204+
['com.example.core.User': 2],
205+
[
206+
':utils': ['com.example.utils.Logger': 1],
207+
],
208+
[
209+
'org.jetbrains.kotlin:kotlin-stdlib': ['kotlin.jvm.internal.Intrinsics': 2, 'kotlin.Metadata': 3, 'kotlin.collections.CollectionsKt': 1],
210+
'org.jetbrains:annotations': ['org.jetbrains.annotations.NotNull': 3, 'org.jetbrains.annotations.Nullable': 1],
211+
],
212+
[:]
213+
)
214+
}
215+
216+
ProjectTypeUsage expectedUtilsTypeUsage() {
217+
return new ProjectTypeUsage(
218+
':utils',
219+
new TypeUsageSummary(
220+
/* totalTypes */ 5,
221+
/* totalFiles */ 2,
222+
/* internalTypes */ 1,
223+
/* projectDependencies */ 0,
224+
/* libraryDependencies */ 3
225+
),
226+
['com.example.utils.Logger': 1],
227+
[:],
228+
[
229+
'commons-io:commons-io': ['org.apache.commons.io.FileUtils': 1],
230+
'org.jetbrains.kotlin:kotlin-stdlib': ['kotlin.jvm.internal.Intrinsics': 1, 'kotlin.Metadata': 2],
231+
'org.jetbrains:annotations': ['org.jetbrains.annotations.NotNull': 2],
232+
],
233+
[:]
234+
)
235+
}
169236
}

src/functionalTest/groovy/com/autonomousapps/jvm/projects/TypeUsageProject.groovy

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ import com.autonomousapps.AbstractProject
66
import com.autonomousapps.kit.GradleProject
77
import com.autonomousapps.kit.Source
88
import com.autonomousapps.kit.SourceType
9-
import com.autonomousapps.internal.OutputPathsKt
10-
import com.autonomousapps.internal.utils.MoshiUtils
119
import com.autonomousapps.model.ProjectTypeUsage
10+
import com.autonomousapps.model.TypeUsageSummary
1211

12+
import static com.autonomousapps.internal.OutputPathsKt.getTypeUsagePath
13+
import static com.autonomousapps.internal.utils.MoshiUtils.MOSHI
1314
import static com.autonomousapps.kit.gradle.dependencies.Dependencies.*
1415

1516
final class TypeUsageProject extends AbstractProject {
@@ -65,9 +66,29 @@ final class TypeUsageProject extends AbstractProject {
6566
]
6667

6768
ProjectTypeUsage actualTypeUsage() {
68-
def typeUsage = gradleProject.singleArtifact(':proj',
69-
OutputPathsKt.getTypeUsagePath('main'))
70-
def adapter = MoshiUtils.MOSHI.adapter(ProjectTypeUsage)
69+
def typeUsage = gradleProject.singleArtifact(':proj', getTypeUsagePath('main'))
70+
def adapter = MOSHI.adapter(ProjectTypeUsage)
7171
return adapter.fromJson(typeUsage.asPath.text)
7272
}
73+
74+
ProjectTypeUsage expectedTypeUsage() {
75+
return new ProjectTypeUsage(
76+
':proj',
77+
new TypeUsageSummary(
78+
/* totalTypes */ 4,
79+
/* totalFiles */ 2,
80+
/* internalTypes */ 1,
81+
/* projectDependencies */ 0,
82+
/* libraryDependencies */ 3
83+
),
84+
['com.example.Example': 1],
85+
[:],
86+
[
87+
'org.apache.commons:commons-collections4': ['org.apache.commons.collections4.bag.HashBag': 1],
88+
'org.jetbrains.kotlin:kotlin-stdlib': ['kotlin.Metadata': 2],
89+
'org.jetbrains:annotations': ['org.jetbrains.annotations.NotNull': 2],
90+
],
91+
[:]
92+
)
93+
}
7394
}

0 commit comments

Comments
 (0)