Coder Social home page Coder Social logo

arunkumar9t2 / scabbard Goto Github PK

View Code? Open in Web Editor NEW
843.0 11.0 32.0 17.92 MB

🗡 A tool to visualize Dagger 2 dependency graphs

Home Page: https://arunkumar9t2.github.io/scabbard

License: Apache License 2.0

Kotlin 99.41% Dockerfile 0.59%
dagger dagger2 dependency-graph gradle-plugin intellij-plugin kotlin graphviz graph-generation dependency-injection

scabbard's Introduction

Scabbard

A tool to visualize and understand your Dagger 2 dependency graph.

Maven Central

More advanced examples.

Features

  • Visualize entry points, dependency graph, dagger errors, component relationships and scopes in your Dagger 2 setup.

  • Minimal setup - Scabbard's Gradle plugin prepares your project for graph generation and provides ability to customize graph generation behavior.

  • IDE integration - Easily view a @Component or a @Subcomponent graph directly from source code via gutter icons (IntelliJ/Android Studio).

  • Supports both Kotlin and Java.

  • Supports Dagger Hilt and Anvil

Getting Started

For samples, guide and usage instructions please visit the project website.

License

Copyright 2022 Arunkumar

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

scabbard's People

Contributors

alexbeggs avatar arunkumar9t2 avatar elgohr avatar kisty avatar msasikanth avatar neugartf avatar zacsweers avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

scabbard's Issues

Build failed after Scrabbard gradle plugin setup

All builds failed with this error:
Execution failed for task ':app:kaptDebugKotlin'.

My build.gradle (application)

apply plugin: "scabbard.gradle"

android {
   ///
   scabbard {
       enabled true
   }
}

My build.gradle (root)

buildscript {
    repositories {
        google()
        jcenter()
        mavenCentral()
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    ///
    dependencies {
        classpath "gradle.plugin.dev.arunkumar:scabbard-gradle-plugin:0.4.0"
    }
}

scabbard icon doesn't show after Studio plugin installation

hi, thanks for coming up with this!

I have installed the plugin in Android Studio 3.5.3 and also done graphViz installation such that dot -V is returning the version.

I've restarted the Android Studio since doing all the above. Yet I'm unable to get the dagger icon against my dagger subcomponents, components, modules...

What am I missing? Is there any build/run/tools/analyze menu item that will also show up, which I could use instead?

Incompatible with Dagger Hilt?

The graph worked very well with dagger, but I just migrated to dagger hilt and it no longer functions the same. Will you be added support for Hilt in the future? It seems that Hilt will become the main dagger according to Google.

Feature Request - Standalone plugin for showing how injections and providers are connected

This is sort of a selfish request, but I do like scabbard, but I'm looking for something "simpler" at the same time. I found out that https://github.com/square/dagger-intellij-plugin used to do the trick, but it's for Dagger 1.

Is there anyway that there could be a standalone plugin from scabbard that basically ties these points together so you can easily see who is using what? This really stems from me wanting something like https://github.com/square/otto-intellij-plugin for Dagger though. In the otto plugin you can use it to navigate between events posted by Otto.

Curious to hear your thoughts.

Graphs are generated when disabled

Hi, I'm trying to publish a release of my app, but the generated graphs are ending up in the release:

gradle plugin version: 0.1.0

root build.gradle

buildscript {
     ...
    dependencies {
        ...
        classpath "gradle.plugin.dev.arunkumar:scabbard-gradle-plugin:0.1.0"
        ...
    }
}

module build.gradle:

...
apply plugin: "scabbard.gradle"
...
android {
    ...
    buildTypes {
        debug {
            ...
            scabbard {
                enabled true
            }
        }
        release {
            ...
            scabbard {
                enabled false
            }
        }
    }
}

I also have the AS plugin installed.
The apk is built via AS (with a release build type)

I also tried with scabbard {enabled = false} just under the android block but that didn't fix it.
I deleted all the build folders but it regenerates them.

Let me know if you need any more information.

Error after removing scabbard, which cannot be fixed by clean

Cause: loader constraint violation in interface itable initialization: when resolving method "com.android.build.gradle.internal.api.VariantFilter.getBuildType()Lcom/android/builder/model/BuildType;" the class loader (instance of org/gradle/internal/classloader/VisitableURLClassLoader) of the current class, com/android/build/gradle/internal/api/VariantFilter, and the class loader (instance of org/gradle/internal/classloader/VisitableURLClassLoader) for interface com/android/build/api/variant/VariantFilter have different Class objects for the type com/android/builder/model/BuildType used in the signature

build problem when plugin is enabled (dagger.releasablereferences @CanReleaseReferences)

I have this problem when the plugin is enabled.

A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptExecution
java.lang.reflect.InvocationTargetException (no error message)

and when i build with --stacktrace . this is the details.

Caused by: java.lang.NoClassDefFoundError: dagger/releasablereferences/ForReleasableReferences
at dagger.internal.codegen.ForReleasableReferencesValidator.annotations(ForReleasableReferencesValidator.java:69)
at dagger.shaded.auto.common.BasicAnnotationProcessor.getSupportedAnnotationClasses(BasicAnnotationProcessor.java:147)
at dagger.shaded.auto.common.BasicAnnotationProcessor.getSupportedAnnotationTypes(BasicAnnotationProcessor.java:159)
at dagger.shaded.auto.common.BasicAnnotationProcessor.getSupportedAnnotationTypes(BasicAnnotationProcessor.java:103)
at org.jetbrains.kotlin.kapt3.base.incremental.IncrementalProcessor.getSupportedAnnotationTypes(incrementalProcessors.kt)
at org.jetbrains.kotlin.kapt3.base.ProcessorWrapper.getSupportedAnnotationTypes(annotationProcessing.kt:187)
at com.sun.tools.javac.processing.JavacProcessingEnvironment$ProcessorState.(JavacProcessingEnvironment.java:513)
at com.sun.tools.javac.processing.JavacProcessingEnvironment$DiscoveredProcessors$ProcessorStateIterator.next(JavacProcessingEnvironment.java:605)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:698)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1800(JavacProcessingEnvironment.java:91)
at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1043)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1184)
at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1170)
at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1068)
at org.jetbrains.kotlin.kapt3.base.AnnotationProcessingKt.doAnnotationProcessing(annotationProcessing.kt:78)
... 27 more
Caused by: java.lang.ClassNotFoundException: dagger.releasablereferences.ForReleasableReferences
... 42 more

i think it is related to this issue.

Document `doc` registration

In the index.md the following lines appear.

After installation, verify installation by executing dot -V, example:

dot - graphviz version 2.38.0 (20140413.2041)

These instructions are fine as far as they go but it may also be necessary to register the layout engines.
This can be done with the following command (immediately after verifying that dot is installed).

dot -V
dot -c

Build fails with java.lang.OutOfMemoryError for large project

I attempted to use scrabbard on our project and I got an java.lang.OutOfMemoryError

The project is quite large so I kind of expected it. I've included the stacktrace here and can provide other debug output if you want.

17:04:18.895 [ERROR] [org.gradle.api.Task] e: [kapt] An exception occurred: java.lang.OutOfMemoryError: Java heap space
at java.awt.image.DataBufferInt.(DataBufferInt.java:75)
at java.awt.image.Raster.createPackedRaster(Raster.java:467)
at java.awt.image.DirectColorModel.createCompatibleWritableRaster(DirectColorModel.java:1032)
at java.awt.image.BufferedImage.(BufferedImage.java:333)
at guru.nidi.graphviz.engine.SalamanderRasterizer.doRasterize(SalamanderRasterizer.java:34)
at guru.nidi.graphviz.engine.SvgRasterizer.rasterize(SvgRasterizer.java:37)
at guru.nidi.graphviz.engine.Renderer.toImage(Renderer.java:117)
at guru.nidi.graphviz.engine.Renderer.toOutputStream(Renderer.java:95)
at guru.nidi.graphviz.engine.Renderer.lambda$toOutputStream$5(Renderer.java:90)
at guru.nidi.graphviz.engine.Renderer$$Lambda$8355/802917358.apply(Unknown Source)
at guru.nidi.graphviz.engine.EngineResult.mapIO(EngineResult.java:64)
at guru.nidi.graphviz.engine.Renderer.toOutputStream(Renderer.java:88)
at dev.arunkumar.scabbard.plugin.processor.graphviz.GraphVizBindingGraphProcessor.process(GraphVizBindingGraphProcessor.kt:79)
at dev.arunkumar.scabbard.plugin.ScabbardBindingGraphPlugin.visitGraph(ScabbardBindingGraphPlugin.kt:46)
at dagger.internal.codegen.BindingGraphValidator.isValid(BindingGraphValidator.java:56)
at dagger.internal.codegen.BindingGraphValidator.isValid(BindingGraphValidator.java:49)
at dagger.internal.codegen.ComponentProcessingStep.isValid(ComponentProcessingStep.java:247)
at dagger.internal.codegen.ComponentProcessingStep.processRootComponent(ComponentProcessingStep.java:143)
at dagger.internal.codegen.ComponentProcessingStep.process(ComponentProcessingStep.java:123)
at dagger.internal.codegen.ComponentProcessingStep.process(ComponentProcessingStep.java:51)
at dagger.internal.codegen.TypeCheckingProcessingStep.lambda$process$0(TypeCheckingProcessingStep.java:51)
at dagger.internal.codegen.TypeCheckingProcessingStep$$Lambda$8054/1240509433.accept(Unknown Source)
at com.google.common.collect.RegularImmutableMap.forEach(RegularImmutableMap.java:185)
at dagger.internal.codegen.TypeCheckingProcessingStep.process(TypeCheckingProcessingStep.java:48)
at dagger.internal.codegen.ComponentProcessingStep.process(ComponentProcessingStep.java:116)
at dagger.internal.codegen.ComponentProcessingStep.process(ComponentProcessingStep.java:51)
at dagger.internal.codegen.DaggerStatisticsCollectingProcessingStep.process(DaggerStatisticsCollectingProcessingStep.java:52)
at dagger.shaded.auto.common.BasicAnnotationProcessor.process(BasicAnnotationProcessor.java:330)
at dagger.shaded.auto.common.BasicAnnotationProcessor.process(BasicAnnotationProcessor.java:181)
at org.jetbrains.kotlin.kapt3.base.incremental.IncrementalProcessor.process(incrementalProcessors.kt)
at org.jetbrains.kotlin.kapt3.base.ProcessorWrapper.process(annotationProcessing.kt:147)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:794)

Render Component Tree

In addition to current graphs, we could provide option to render component tree like Uber does with RIBS.

Example:

Steps:

  • Add a separate processor
  • ComponentPath has parent and child information, use that create a custom tree data structure
  • Create a graph with rankdir = TB

Build fails while updating the generated graph image

From what I understand from the stacktrace, it's the path that's looking for doesn't exist because of the naming/path naming conventions or something.
It's complaining about:

<path/to/project>/build/tmp/kapt3/classes/devDebug/ie/my/package/di/activities/ListActivityBindingModule_BindListFragment/ListFragmentSubcomponent/ie.my.package.di.activities.ListActivityBindingModule_BindListFragment.ListFragmentSubcomponent.png

But the actual directory structure on the disk is slightly different:
<path/to/project>/build/tmp/kapt3/classes/devDebug/ie/my/package/di/activities/ListActivityBindingModule_BindListFragment.ListFragmentSubcomponent/ie.my.package.di.activities.ListActivityBindingModule_BindListFragment.ListFragmentSubcomponent.png

I have the following setup:

scabbard {
    enabled true
    failOnError true
    fullBindingGraphValidation true
}

I'm using the kapt plugin in a java+kotlin project. Applying the scabbard plugin directly to a single module only.

Below's the entire stacktrace:

e: [kapt] An exception occurred: java.lang.RuntimeException: Scabbard processor failed
at dev.arunkumar.scabbard.plugin.processor.graphviz.GraphVizBindingGraphProcessor.process(GraphVizBindingGraphProcessor.kt:342)
at dev.arunkumar.scabbard.plugin.ScabbardBindingGraphPlugin.visitGraph(ScabbardBindingGraphPlugin.kt:46)
at dagger.internal.codegen.validation.BindingGraphValidator.runPlugins(BindingGraphValidator.java:100)
at dagger.internal.codegen.validation.BindingGraphValidator.visitPlugins(BindingGraphValidator.java:90)
at dagger.internal.codegen.validation.BindingGraphValidator.isValid(BindingGraphValidator.java:64)
at dagger.internal.codegen.validation.ModuleValidator.validateModuleBindings(ModuleValidator.java:642)
at dagger.internal.codegen.validation.ModuleValidator.validateUncached(ModuleValidator.java:248)
at dagger.internal.codegen.validation.ModuleValidator.lambda$validate$0(ModuleValidator.java:176)
at dagger.internal.codegen.base.Util.reentrantComputeIfAbsent(Util.java:33)
at dagger.internal.codegen.validation.ModuleValidator.validate(ModuleValidator.java:176)
at dagger.internal.codegen.validation.ModuleValidator.validate(ModuleValidator.java:170)
at dagger.internal.codegen.ModuleProcessingStep.process(ModuleProcessingStep.java:109)
at dagger.internal.codegen.ModuleProcessingStep.process(ModuleProcessingStep.java:58)
at dagger.internal.codegen.validation.TypeCheckingProcessingStep.lambda$process$0(TypeCheckingProcessingStep.java:51)
at com.google.common.collect.RegularImmutableMap.forEach(RegularImmutableMap.java:185)
at dagger.internal.codegen.validation.TypeCheckingProcessingStep.process(TypeCheckingProcessingStep.java:48)
at dagger.internal.codegen.ModuleProcessingStep.process(ModuleProcessingStep.java:100)
at dagger.internal.codegen.ModuleProcessingStep.process(ModuleProcessingStep.java:58)
at dagger.internal.codegen.statistics.DaggerStatisticsCollectingProcessingStep.process(DaggerStatisticsCollectingProcessingStep.java:52)
at dagger.shaded.auto.common.BasicAnnotationProcessor.process(BasicAnnotationProcessor.java:330)
at dagger.shaded.auto.common.BasicAnnotationProcessor.process(BasicAnnotationProcessor.java:181)
at org.jetbrains.kotlin.kapt3.base.incremental.IncrementalProcessor.process(incrementalProcessors.kt)
at org.jetbrains.kotlin.kapt3.base.ProcessorWrapper.process(annotationProcessing.kt:132)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:794)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:705)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1800(JavacProcessingEnvironment.java:91)
at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1035)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1176)
at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1170)
at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1068)
at org.jetbrains.kotlin.kapt3.base.AnnotationProcessingKt.doAnnotationProcessing(annotationProcessing.kt:80)
at org.jetbrains.kotlin.kapt3.base.AnnotationProcessingKt.doAnnotationProcessing$default(annotationProcessing.kt:36)
at org.jetbrains.kotlin.kapt3.AbstractKapt3Extension.runAnnotationProcessing(Kapt3Extension.kt:223)
at org.jetbrains.kotlin.kapt3.AbstractKapt3Extension.analysisCompleted(Kapt3Extension.kt:187)
at org.jetbrains.kotlin.kapt3.ClasspathBasedKapt3Extension.analysisCompleted(Kapt3Extension.kt:98)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM$analyzeFilesWithJavaIntegration$2.invoke(TopDownAnalyzerFacadeForJVM.kt:95)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:105)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:80)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:395)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:65)
at org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport.analyzeAndReport(AnalyzerWithCompilerReport.kt:107)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze(KotlinToJVMBytecodeCompiler.kt:386)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:118)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:166)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:56)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:84)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:42)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:104)
at org.jetbrains.kotlin.daemon.CompileServiceImpl$compile$1$1$2.invoke(CompileServiceImpl.kt:442)
at org.jetbrains.kotlin.daemon.CompileServiceImpl$compile$1$1$2.invoke(CompileServiceImpl.kt:102)
at org.jetbrains.kotlin.daemon.CompileServiceImpl$doCompile$$inlined$ifAlive$lambda$2.invoke(CompileServiceImpl.kt:1005)
at org.jetbrains.kotlin.daemon.CompileServiceImpl$doCompile$$inlined$ifAlive$lambda$2.invoke(CompileServiceImpl.kt:102)
at org.jetbrains.kotlin.daemon.common.DummyProfiler.withMeasure(PerfUtils.kt:138)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.checkedCompile(CompileServiceImpl.kt:1047)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.doCompile(CompileServiceImpl.kt:1004)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:441)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357)
at sun.rmi.transport.Transport$1.run(Transport.java:200)
at sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:573)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:834)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.RuntimeException: Scabbard processor failed
at dev.arunkumar.scabbard.plugin.processor.graphviz.GraphVizBindingGraphProcessor.process(GraphVizBindingGraphProcessor.kt:320)
... 72 more
Caused by: javax.annotation.processing.FilerException: Attempt to reopen a file for path <path/to/project>/build/tmp/kapt3/classes/devDebug/ie/my/package/di/activities/ListActivityBindingModule_BindListFragment/ListFragmentSubcomponent/ie.my.package.di.activities.ListActivityBindingModule_BindListFragment.ListFragmentSubcomponent.png
at com.sun.tools.javac.processing.JavacFiler.checkFileReopening(JavacFiler.java:535)
at com.sun.tools.javac.processing.JavacFiler.createResource(JavacFiler.java:431)
at dev.arunkumar.scabbard.plugin.output.DefaultOutputManager.createOutputFiles(DefaultOutputManager.kt:24)
at dev.arunkumar.scabbard.plugin.processor.graphviz.GraphVizBindingGraphProcessor.process(GraphVizBindingGraphProcessor.kt:74)
... 72 more

Refactor Scabbard Gradle Plugin extension

Context

Summary

Scabbard's Gradle plugin currently relies on Groovy meta-programming to configure the extension, which makes it hard/confusing for Kotlin users as the syntax can be weird due to typing issues.

Background

Early development versions did use standard plugin configuration design like

scabbard { //this : ScabbardPluginExtension
}

However this caused issues when reading user configured values from extension and configuring the project. Scabbard mainly does two things:

  1. Add scabbard's processor dependency to project
  2. Delegate user configured values as compiler options to annotation processors (scabbard's and dagger's)

This example from Gradle does not apply here because extension.message is only used on doLast {} which is well into execution phase and by then Gradle would have configured the extension and user defined values would have been read.

In Scabbard's case, we need to execute 1 and 2 above in configuration phase but after gradle configures ScabbardPluginExtension. Current problems:

  • If 1 and 2 are executed immediately when plugin is applied i.e in Plugin.apply(project), user defined properties are not read since scabbard { } block is not available yet.
  • If 1 and 2 are executed in afterEvaluate {} then user defined properties are read which is good but can't apply annotation processor options anymore (details).

Workaround

We need to execute 1 and 2 above as and when Gradle configures the extension, one way to do that is to use Configurable interface and do 1 and 2 in configure(closure: Closure<*>) block. While this works, the syntax is unpleasant since type information is lost.

What other are doing

  • Realm plugin also adds project dependencies and to solve the user defined values reading problem, they register a listener and execute dependencies logic everytime it changes.
  • Intellij plugin seems to track execution state with project.state.executed and then determine if dependencies can be applied.

Current solution.

  1. Groovy
     scabbard {
         enabled true
     }
  2. Kotlin
    scabbard.configure(closureOf<ScabbardSpec> {
      enabled(true)
    })

Nice to have

scabbard { // this : ScabbardPluginExtension
   // properties from extension
}

Consider generating files to `StandardLocation.SOURCE_OUTPUT`

Context

Currently Scabbard writes the visualization files to StandardLocation.CLASS_OUTPUT. We could consider generating the files to StandardLocation.SOURCE_OUTPUT instead for the following reasons.

  • StandardLocation.SOURCE_OUTPUT is known to IntelliJ as source root so by default it will be indexed as opposed to CLASS_OUTPUT which may not be indexed, at least for Kotlin the generated file path is /tmp/kapt3/ which is a bit non conventional.
  • Consistency with other source generating processors and provides ability to query the directory from IntelliJ APIS such as ProjectRootManager.

Add gutter logic to consider images generated from Hilt.

Scabbard already works with Hilt but the naming convention for generated images have changed. Particularly @AndroidEntryPoint and @EntryPoint.

Need to update gutter logic to look for these new annotations and map them to generated component images just like how @ContributesAndroidInjector support works currently.

ScabbardPluginExtension is not configurable from Kotlin

We have a Gradle plugin that manages setup of our standard project configurations and is written in Kotlin. Most Gradle plugins use a simple interface or abstract class for their plugin extension, but scabbard appears to use an undocumented Configurable Gradle API that accepts an untyped Closure. The result is we can't configure this extension from Kotlin as the underlying ScabbardSpec is not accessible outside of groovy's magic duck typing.

I'd recommend using a standard plugin API, unless Configurable offers some specific functionality that scabbard needs.

e: [kapt] An exception occurred: java.lang.NoClassDefFoundError: dagger/releasablereferences/ForReleasableReferences

I'm trying to test this out in my project, and I'm getting the error while building:

e: [kapt] An exception occurred: java.lang.NoClassDefFoundError: dagger/releasablereferences/ForReleasableReferences

The longer error in the build event KaptDebugKotlin is

org.gradle.api.GradleException: Compilation error. See log for more details
	at org.jetbrains.kotlin.gradle.tasks.TasksUtilsKt.throwGradleExceptionIfError(tasksUtils.kt:14)
	at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:122)
	at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunner.runCompilerAsync(GradleKotlinCompilerRunner.kt:148)
	at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunner.runCompilerAsync(GradleKotlinCompilerRunner.kt:143)
	at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunner.runJvmCompilerAsync(GradleKotlinCompilerRunner.kt:83)
	at org.jetbrains.kotlin.gradle.internal.KaptWithKotlincTask.compile(KaptWithKotlincTask.kt:98)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:103)
	at org.gradle.api.internal.project.taskfactory.IncrementalTaskInputsTaskAction.doExecute(IncrementalTaskInputsTaskAction.java:46)
	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:41)
	at org.gradle.api.internal.project.taskfactory.AbstractIncrementalTaskAction.execute(AbstractIncrementalTaskAction.java:25)
	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:28)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$5.run(ExecuteActionsTaskExecuter.java:404)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:402)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:394)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:92)
	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:393)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:376)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.access$200(ExecuteActionsTaskExecuter.java:80)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.execute(ExecuteActionsTaskExecuter.java:213)
	at org.gradle.internal.execution.steps.ExecuteStep.lambda$execute$0(ExecuteStep.java:32)
	at java.util.Optional.map(Optional.java:215)
	at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:32)
	at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:26)
	at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:58)
	at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:35)
	at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:48)
	at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:33)
	at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:39)
	at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:73)
	at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:54)
	at org.gradle.internal.execution.steps.CatchExceptionStep.execute(CatchExceptionStep.java:35)
	at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:51)
	at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:45)
	at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:31)
	at org.gradle.internal.execution.steps.CacheStep.executeWithoutCache(CacheStep.java:201)
	at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:70)
	at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:45)
	at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:49)
	at org.gradle.internal.execution.steps.StoreSnapshotsStep.execute(StoreSnapshotsStep.java:43)
	at org.gradle.internal.execution.steps.StoreSnapshotsStep.execute(StoreSnapshotsStep.java:32)
	at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:38)
	at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:24)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:96)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$0(SkipUpToDateStep.java:89)
	at java.util.Optional.map(Optional.java:215)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:54)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:38)
	at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:77)
	at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:37)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:36)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:26)
	at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:90)
	at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:48)
	at org.gradle.internal.execution.impl.DefaultWorkExecutor.execute(DefaultWorkExecutor.java:33)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:120)
	at org.gradle.api.internal.tasks.execution.ResolveBeforeExecutionStateTaskExecuter.execute(ResolveBeforeExecutionStateTaskExecuter.java:75)
	at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:62)
	at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:108)
	at org.gradle.api.internal.tasks.execution.ResolveBeforeExecutionOutputsTaskExecuter.execute(ResolveBeforeExecutionOutputsTaskExecuter.java:67)
	at org.gradle.api.internal.tasks.execution.ResolveAfterPreviousExecutionStateTaskExecuter.execute(ResolveAfterPreviousExecutionStateTaskExecuter.java:46)
	at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:94)
	at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
	at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:95)
	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:73)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:49)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:416)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:406)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:102)
	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:49)
	at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:43)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:355)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:343)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:336)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:322)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker$1.execute(DefaultPlanExecutor.java:134)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker$1.execute(DefaultPlanExecutor.java:129)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:202)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:193)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:129)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
	at java.lang.Thread.run(Thread.java:748)

The versions of dagger I'm using are:

  kaptTest "com.google.dagger:dagger-compiler:2.14.1"
  kapt "com.google.dagger:dagger:2.25.3"
  kapt "com.google.dagger:dagger-android-support:2.14.1"
  kapt "com.google.dagger:dagger-compiler:2.14.1"
  kapt "com.google.dagger:dagger-android-processor:2.14.1"

The place where i'm enabling scabbard in my build.gradle is:

buildscript {
  repositories {
    maven { url 'https://maven.fabric.io/public' }
    maven { url "https://plugins.gradle.org/m2/" }
  }

  dependencies {
    classpath 'io.fabric.tools:gradle:1.31.0'
    classpath "gradle.plugin.dev.arunkumar:scabbard-gradle-plugin:0.2.0"
  }
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply plugin: "scabbard.gradle"

  scabbard {
    enabled true
  }

e: [kapt] An exception occurred: java.lang.NoSuchFieldError: SUBCOMPONENT_BUILDER

When building, I get the following error:

> Task :app:kaptInternalDebugKotlin e: [kapt] An exception occurred: java.lang.NoSuchFieldError: SUBCOMPONENT_BUILDER at dagger.internal.codegen.BindingGraphConverter$Traverser.visitComponent(BindingGraphConverter.java:115) at dagger.internal.codegen.ComponentTreeTraverser.traverseComponents(ComponentTreeTraverser.java:69) at dagger.internal.codegen.BindingGraphConverter.convert(BindingGraphConverter.java:66) at dagger.internal.codegen.ComponentProcessingStep.isValid(ComponentProcessingStep.java:153) at dagger.internal.codegen.ComponentProcessingStep.process(ComponentProcessingStep.java:135) at dagger.internal.codegen.ComponentProcessingStep.process(ComponentProcessingStep.java:47) at dagger.internal.codegen.TypeCheckingProcessingStep.lambda$process$0(TypeCheckingProcessingStep.java:51) at com.google.common.collect.SingletonImmutableBiMap.forEach(SingletonImmutableBiMap.java:65) at dagger.internal.codegen.TypeCheckingProcessingStep.process(TypeCheckingProcessingStep.java:48) at dagger.internal.codegen.ComponentProcessingStep.process(ComponentProcessingStep.java:114) at dagger.internal.codegen.ComponentProcessingStep.process(ComponentProcessingStep.java:47) at dagger.shaded.auto.common.BasicAnnotationProcessor.process(BasicAnnotationProcessor.java:330) at dagger.shaded.auto.common.BasicAnnotationProcessor.process(BasicAnnotationProcessor.java:181) at org.jetbrains.kotlin.kapt3.base.incremental.IncrementalProcessor.process(incrementalProcessors.kt) at org.jetbrains.kotlin.kapt3.base.ProcessorWrapper.process(annotationProcessing.kt:147) at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:794) at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:705) at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1800(JavacProcessingEnvironment.java:91) at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1035) at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1176) at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1170) at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1068) at org.jetbrains.kotlin.kapt3.base.AnnotationProcessingKt.doAnnotationProcessing(annotationProcessing.kt:79) at org.jetbrains.kotlin.kapt3.base.AnnotationProcessingKt.doAnnotationProcessing$default(annotationProcessing.kt:35) at org.jetbrains.kotlin.kapt3.AbstractKapt3Extension.runAnnotationProcessing(Kapt3Extension.kt:224) at org.jetbrains.kotlin.kapt3.AbstractKapt3Extension.analysisCompleted(Kapt3Extension.kt:187) at org.jetbrains.kotlin.kapt3.ClasspathBasedKapt3Extension.analysisCompleted(Kapt3Extension.kt:98) at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM$analyzeFilesWithJavaIntegration$2.invoke(TopDownAnalyzerFacadeForJVM.kt:97) at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:107) at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:82) at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:557) at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:82) at org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport.analyzeAndReport(AnalyzerWithCompilerReport.kt:107) at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze(KotlinToJVMBytecodeCompiler.kt:548) at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:177) at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:165) at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:55) at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:84) at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:42) at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:104) at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1558) at sun.reflect.GeneratedMethodAccessor102.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357) at sun.rmi.transport.Transport$1.run(Transport.java:200) at sun.rmi.transport.Transport$1.run(Transport.java:197) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Transport.java:196) at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:573) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:834) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)

Provide option to render single graph

Splitting the graphs by component is nice and keeps graphs readable, but on small projects rendering a single graph would still bring value. Should consider providing option to render single graph.

Standalone Android Studio Sample

Hi there,

Could you please provide a standalone sample for Android/Hilt integration?

I cannot seem to add/enable scabbard in my project and the provided samples in this repositories have some dependencies to this own project like gradle apply to other gradle files that I have no idea what it is:

apply from: "../../gradle/scabbard-local-processor.gradle"

For my problem, it seems the gradle plugin is not even triggered/executed. There's nothing related to scabbard in the build log.

When I add failOnError, it even said:

warning: The following options were not recognized by any processor: '[scabbard.failOnError, kapt.kotlin.generated]'

My gradle plugins are (if it helps any):

apply plugin: 'com.android.application'
apply plugin: 'com.google.protobuf'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'scabbard.gradle'
apply plugin: 'dagger.hilt.android.plugin'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.firebase-perf'
apply plugin: 'com.google.firebase.crashlytics'

Provide simple sample

Could you please provide a simple sample app for groovy to get started easily? The docs are not naturally intuitive.
As it is, I have not been able to generate the graph and I am not sure if it is the library itself or a wrong setup.

Could not set unknown property 'enabled' for object of type dev.arunkumar.scabbard.gradle.DefaultScabbardSpec.

buildscript {
    repositories {
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath "gradle.plugin.dev.arunkumar:scabbard-gradle-plugin:0.1.0"
    }
}

apply plugin: "com.android.application"
apply plugin: "kotlin-android"
apply plugin: "kotlin-kapt"
apply plugin: "scabbard.gradle"

android {
    compileSdkVersion compileSdk

    defaultConfig {
        applicationId "sk.dagger.playground"
        minSdkVersion minSdk
        targetSdkVersion targetSdk
        versionCode appVersionCode
        versionName appVersionName
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    signingConfigs {
        release {
            def signingFolder = "../signing"
            def propertiesFile = file("${signingFolder}/signing.properties")
            if (propertiesFile.exists()) {
                def props = new Properties()
                props.load(new FileInputStream(propertiesFile))

                keyAlias props["keyAlias"]
                keyPassword props["keyPassword"]
                storeFile file("${signingFolder}/${props["storeFile"]}")
                storePassword props["storePassword"]
            }
        }
    }

    buildTypes {
        debug {
        }
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
            signingConfig signingConfigs.release
        }
    }

}

scabbard {
    enabled = true
}

dependencies {
    implementation deps.androidx.appCompat
    implementation deps.androidx.preferences
    implementation deps.androidx.recyclerView
    implementation deps.material

    implementation deps.dagger.runtime
    kapt deps.dagger.compiler

    implementation deps.rx.java
    implementation deps.rx.android
    implementation deps.rx.kotlin

    implementation deps.okhttp.client
    implementation deps.moshi.client
    implementation deps.retrofit.client
    implementation deps.retrofit.rxjavaAdapter
    implementation deps.retrofit.moshiConverter

    implementation deps.glide.client

    implementation deps.conductor.runtime
    implementation deps.jsr310
    implementation deps.kotlin

    implementation project(":features:invite")
    implementation project(":features:chat")
    implementation project(":libs:gallery")
    implementation project(":libs:giphy")
    implementation project(":base")

    testImplementation deps.test.junit

    androidTestImplementation "androidx.test:core:1.2.0"
    androidTestImplementation "androidx.test:runner:1.2.0"
    androidTestImplementation "androidx.test:rules:1.2.0"
    androidTestImplementation "androidx.test.espresso:espresso-core:3.2.0"

}

Make Gradle plugin Android Variant aware.

Currently the gradle plugin is not Android aware and adds processor to app level instead of variant level. Should consider making it such that it is variant aware and only adds scabbard to debug build types.

  • Add dependency on AGP
  • Change application logic to only consider variant.buildType = 'debug.
  • Consider providing a variantFilter DSL like Keeper does.

Provide option to open SVG images in browser.

Since 0.2.0, we have option to render svgs and they are made interactive by using hyperlink spec, however the SVG has to be manually opened in the browser for navigation as IntelliJ viewer does not support it.

Should consider providing option to open in browser when clicking SVG gutter.

Gradle sync failing when scabbard plugin is added

Project build.gradle

buildscript {
  repositories {
    maven {
      url "https://plugins.gradle.org/m2/"
    }
  }
  dependencies {
    classpath "gradle.plugin.dev.arunkumar:scabbard-gradle-plugin:0.5.0"
  }
}

apply plugin: "scabbard.gradle"

gradle version: 6.1.1
android gradle plugin version: 4.0.0
dagger hilt version: 2.31-alpha
androidX hilt version: 1.0.0-alpha03

stacktrace:

* What went wrong:
A problem occurred evaluating root project 'customer-mobile'.
> Failed to apply plugin [id 'scabbard.gradle']
   > Could not create an instance of type dev.arunkumar.scabbard.gradle.ScabbardPluginExtension.
      > 'void kotlin.jvm.internal.MutablePropertyReference1Impl.<init>(java.lang.Class, java.lang.String, java.lang.String, int)'

* Try:
Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Exception is:
org.gradle.api.GradleScriptException: A problem occurred evaluating root project 'customer-mobile'.
	at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:93)
	at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl$2.run(DefaultScriptPluginFactory.java:237)
	at org.gradle.configuration.ProjectScriptTarget.addConfiguration(ProjectScriptTarget.java:77)
	at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl.apply(DefaultScriptPluginFactory.java:242)
	at org.gradle.configuration.BuildOperationScriptPlugin$1$1.run(BuildOperationScriptPlugin.java:69)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:402)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:394)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:92)
	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
	at org.gradle.configuration.BuildOperationScriptPlugin$1.execute(BuildOperationScriptPlugin.java:66)
	at org.gradle.configuration.BuildOperationScriptPlugin$1.execute(BuildOperationScriptPlugin.java:63)
	at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.apply(DefaultUserCodeApplicationContext.java:49)
	at org.gradle.configuration.BuildOperationScriptPlugin.apply(BuildOperationScriptPlugin.java:63)
	at org.gradle.configuration.project.BuildScriptProcessor$1.run(BuildScriptProcessor.java:45)
	at org.gradle.internal.Factories$1.create(Factories.java:26)
	at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withMutableState(DefaultProjectStateRegistry.java:212)
	at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withMutableState(DefaultProjectStateRegistry.java:193)
	at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:42)
	at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:26)
	at org.gradle.configuration.project.ConfigureActionsProjectEvaluator.evaluate(ConfigureActionsProjectEvaluator.java:35)
	at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject$1.run(LifecycleProjectEvaluator.java:107)
	at org.gradle.internal.Factories$1.create(Factories.java:26)
	at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:189)
	at org.gradle.internal.work.StopShieldingWorkerLeaseService.withLocks(StopShieldingWorkerLeaseService.java:40)
	at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withProjectLock(DefaultProjectStateRegistry.java:238)
	at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withMutableState(DefaultProjectStateRegistry.java:232)
	at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withMutableState(DefaultProjectStateRegistry.java:193)
	at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject.run(LifecycleProjectEvaluator.java:96)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:402)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:394)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:92)
	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
	at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:68)
	at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:699)
	at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:142)
	at org.gradle.execution.TaskPathProjectEvaluator.configure(TaskPathProjectEvaluator.java:36)
	at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:62)
	at org.gradle.configuration.DefaultProjectsPreparer.prepareProjects(DefaultProjectsPreparer.java:61)
	at org.gradle.configuration.BuildOperatingFiringProjectsPreparer$ConfigureBuild.run(BuildOperatingFiringProjectsPreparer.java:52)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:402)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:394)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:92)
	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
	at org.gradle.configuration.BuildOperatingFiringProjectsPreparer.prepareProjects(BuildOperatingFiringProjectsPreparer.java:40)
	at org.gradle.initialization.DefaultGradleLauncher.prepareProjects(DefaultGradleLauncher.java:207)
	at org.gradle.initialization.DefaultGradleLauncher.doClassicBuildStages(DefaultGradleLauncher.java:145)
	at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:130)
	at org.gradle.initialization.DefaultGradleLauncher.executeTasks(DefaultGradleLauncher.java:110)
	at org.gradle.internal.invocation.GradleBuildController$1.execute(GradleBuildController.java:60)
	at org.gradle.internal.invocation.GradleBuildController$1.execute(GradleBuildController.java:57)
	at org.gradle.internal.invocation.GradleBuildController$3.create(GradleBuildController.java:85)
	at org.gradle.internal.invocation.GradleBuildController$3.create(GradleBuildController.java:78)
	at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:189)
	at org.gradle.internal.work.StopShieldingWorkerLeaseService.withLocks(StopShieldingWorkerLeaseService.java:40)
	at org.gradle.internal.invocation.GradleBuildController.doBuild(GradleBuildController.java:78)
	at org.gradle.internal.invocation.GradleBuildController.run(GradleBuildController.java:57)
	at org.gradle.tooling.internal.provider.runner.ClientProvidedPhasedActionRunner.run(ClientProvidedPhasedActionRunner.java:60)
	at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
	at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
	at org.gradle.launcher.exec.BuildOutcomeReportingBuildActionRunner.run(BuildOutcomeReportingBuildActionRunner.java:63)
	at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
	at org.gradle.launcher.exec.BuildCompletionNotifyingBuildActionRunner.run(BuildCompletionNotifyingBuildActionRunner.java:39)
	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:51)
	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:45)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:416)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:406)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:102)
	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:45)
	at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:50)
	at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:47)
	at org.gradle.composite.internal.DefaultRootBuildState.run(DefaultRootBuildState.java:80)
	at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:47)
	at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:31)
	at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:42)
	at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:28)
	at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:78)
	at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:52)
	at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:60)
	at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:38)
	at org.gradle.tooling.internal.provider.SessionScopeBuildActionExecuter.execute(SessionScopeBuildActionExecuter.java:68)
	at org.gradle.tooling.internal.provider.SessionScopeBuildActionExecuter.execute(SessionScopeBuildActionExecuter.java:38)
	at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:37)
	at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:26)
	at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:43)
	at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:29)
	at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:60)
	at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:32)
	at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:55)
	at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:41)
	at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:48)
	at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:32)
	at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:68)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:39)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:27)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:35)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:78)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:75)
	at org.gradle.util.Swapper.swap(Swapper.java:38)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:75)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:63)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:82)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:52)
	at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
Caused by: org.gradle.api.internal.plugins.PluginApplicationException: Failed to apply plugin [id 'scabbard.gradle']
	at org.gradle.api.internal.plugins.DefaultPluginManager.doApply(DefaultPluginManager.java:167)
	at org.gradle.api.internal.plugins.DefaultPluginManager.apply(DefaultPluginManager.java:136)
	at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.applyType(DefaultObjectConfigurationAction.java:162)
	at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.access$200(DefaultObjectConfigurationAction.java:41)
	at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction$3.run(DefaultObjectConfigurationAction.java:96)
	at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.execute(DefaultObjectConfigurationAction.java:185)
	at org.gradle.api.internal.project.AbstractPluginAware.apply(AbstractPluginAware.java:49)
	at org.gradle.api.internal.project.ProjectScript.apply(ProjectScript.java:37)
	at org.gradle.api.Script$apply.callCurrent(Unknown Source)
	at build_dnvg1bcbhg8da4iaauszfdmnj.run(/home/nirmal/Desktop/modularization/customer-mobile/build.gradle:23)
	at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:91)
	... 130 more
Caused by: org.gradle.api.reflect.ObjectInstantiationException: Could not create an instance of type dev.arunkumar.scabbard.gradle.ScabbardPluginExtension.
	at org.gradle.internal.instantiation.generator.DependencyInjectingInstantiator.doCreate(DependencyInjectingInstantiator.java:69)
	at org.gradle.internal.instantiation.generator.DependencyInjectingInstantiator.newInstanceWithDisplayName(DependencyInjectingInstantiator.java:50)
	at org.gradle.internal.extensibility.DefaultConvention.instantiate(DefaultConvention.java:216)
	at org.gradle.internal.extensibility.DefaultConvention.create(DefaultConvention.java:125)
	at dev.arunkumar.scabbard.gradle.ScabbardGradlePlugin.apply(ScabbardGradlePlugin.kt:39)
	at dev.arunkumar.scabbard.gradle.ScabbardGradlePlugin.apply(ScabbardGradlePlugin.kt:34)
	at org.gradle.api.internal.plugins.ImperativeOnlyPluginTarget.applyImperative(ImperativeOnlyPluginTarget.java:43)
	at org.gradle.api.internal.plugins.RuleBasedPluginTarget.applyImperative(RuleBasedPluginTarget.java:51)
	at org.gradle.api.internal.plugins.DefaultPluginManager.addPlugin(DefaultPluginManager.java:181)
	at org.gradle.api.internal.plugins.DefaultPluginManager.access$300(DefaultPluginManager.java:51)
	at org.gradle.api.internal.plugins.DefaultPluginManager$AddPluginBuildOperation.run(DefaultPluginManager.java:276)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:402)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:394)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:92)
	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
	at org.gradle.api.internal.plugins.DefaultPluginManager$2.execute(DefaultPluginManager.java:159)
	at org.gradle.api.internal.plugins.DefaultPluginManager$2.execute(DefaultPluginManager.java:156)
	at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.apply(DefaultUserCodeApplicationContext.java:49)
	at org.gradle.api.internal.plugins.DefaultPluginManager.doApply(DefaultPluginManager.java:156)
	... 140 more
Caused by: java.lang.NoSuchMethodError: 'void kotlin.jvm.internal.MutablePropertyReference1Impl.<init>(java.lang.Class, java.lang.String, java.lang.String, int)'
	at dev.arunkumar.scabbard.gradle.ScabbardPluginExtension.<clinit>(ScabbardPluginExtension.kt)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at org.gradle.internal.instantiation.generator.AsmBackedClassGenerator$InvokeConstructorStrategy.newInstance(AsmBackedClassGenerator.java:1858)
	at org.gradle.internal.instantiation.generator.AbstractClassGenerator$GeneratedClassImpl$GeneratedConstructorImpl.newInstance(AbstractClassGenerator.java:430)
	at org.gradle.internal.instantiation.generator.DependencyInjectingInstantiator.doCreate(DependencyInjectingInstantiator.java:64)
	... 161 more

0.3.0 fails to build with kapt

> Task :log-sync:kaptReleaseKotlin FAILED
[WARN] Issue detected with dagger.internal.codegen.ComponentProcessor. Expected 1 originating source file when generating /Users/zsweers/dev/slack/slack-android-ng/log-sync/build/tmp/kapt3/classes/release/scabbard/full_slack.logsync.di.LogSyncBaseModule.svg, but detected 0: [].
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
error: cannot access Metrics
  class file for slack.telemetry.Metrics not found
  Consult the following stack trace for details.
  com.sun.tools.javac.code.Symbol$CompletionFailure: class file for slack.telemetry.Metrics not found
> Task :tooling:flipper:plugins:ms-event:plugin:kaptReleaseKotlin
[WARN] Issue detected with dagger.internal.codegen.ComponentProcessor. Expected 1 originating source file when generating /Users/zsweers/dev/slack/slack-android-ng/tooling/flipper/plugins/ms-event/plugin/build/tmp/kapt3/classes/release/scabbard/full_slack.tooling.flipper.plugins.msevent.plugin.MsEventFlipperPluginModule.dot, but detected 0: [].
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

> Task :model:kaptReleaseKotlin
warning: The following options were not recognized by any processor: '[scabbard.failOnError, scabbard.outputFormat, kapt.kotlin.generated, dagger.fullBindingGraphValidation]'
FAILURE: Build failed with an exception.

Unclear documentation.

Hi. I'm trying to use this tool and I stumble across some issues.
First of all, it's unclear from https://arunkumar9t2.github.io/scabbard/ this page how exactly to install the tool.
Where should I put all the gradle lines? Root or project gradle?
Does the plugin works alone, or I need to setup gradle files also?

Also, filepath for generated files is wrong for me.
I found generated files by this path
./app/build/intermediates/javac/debug/classes/scabbard

Also, even I've installed the plugin I'm unable to find the icon to run the generation.

Thank you!

Scabbard applies itself even when dagger is not present/used

This leads to warnings in kapt when it doesn't run

warning: The following options were not recognized by any processor: '[scabbard.failOnError, scabbard.outputFormat, kapt.kotlin.generated, dagger.fullBindingGraphValidation]'
> Task :calendar-api-model:kaptReleaseKotlin
warning: The following options were not recognized by any processor: '[scabbard.failOnError, scabbard.outputFormat, kapt.kotlin.generated, dagger.fullBindingGraphValidation]'

Highlight nodes declared via @BindsInstance differently

Currently bindings exposed via @BindsInstance are not differentiated in graph and rendered like any other node. Might be worth highlighting this via color or label.

Notes:
Could use binding.kind() = BindingKind.BOUND_INSTANCE to check for this.

Dump all generated images to central directory

We want to bundle the generated .png files with our internal documentation. It would be helpful if they were all in a single director, w/out having to navigate through the project to find and move them.

kapt is not listed as a dependency in Installation paragraph

There's no info about kapt presence in a project on Installation paragraph. If you try to use the plugin in a project without kotlin-kapt you get an error:

A problem occurred evaluating script.
> Configuration with name 'kapt' not found.

I think it's better to explicitly list kapt as a requirement in this section.

Add gutter icons for @ContributesAndroidInjector

Context

Summary

We currently target @Component, @Subcomponent and @Provides alone to find the generated graph and add gutter icons. @ContributesAndroidInjector is another annotation part of dagger.android that generates a @Subcomponent internally. Currently to see the graph of this activity/fragment, we have to open the generated subcomponent and then look for Scabbard gutter icons to open graph. This could be expedited by adding icons to methods annotated with @ContributesAndroidInjector directly.

Implementation

@ContributesAndroidInjector annotated method will always have a concrete return type for which the subcomponent will be generated. The generated subcomponent name contains the types name prefixed with some path and keywords. Should be simple to infer the generated png name with full qualified package name of the binding method.

Add dot command validation in Gradle plugin

Right now dot command is required for scabbard to be useful. We could build a validation step in Gradle plugin that checks for availability of dot and fails the build. Additionally providing commands to install dot in messages would be nice.

Build fails resolving transitive dependency

Would a newer version of kittinunf/Result in scabbard solve this problem?

> Task :app:kaptGenerateStubsDevDebugKotlin FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:kaptGenerateStubsDevDebugKotlin'.
> Could not resolve all files for configuration ':app:kapt'.
   > Could not find com.github.kittinunf.result:result:3.0.0.
     Searched in the following locations:
       - https://dl.google.com/dl/android/maven2/com/github/kittinunf/result/result/3.0.0/result-3.0.0.pom
       - https://repo.maven.apache.org/maven2/com/github/kittinunf/result/result/3.0.0/result-3.0.0.pom
       - https://kotlin.bintray.com/kotlinx/com/github/kittinunf/result/result/3.0.0/result-3.0.0.pom
       - https://oss.sonatype.org/content/repositories/snapshots/com/github/kittinunf/result/result/3.0.0/result-3.0.0.pom
     Required by:
         project :app > dev.arunkumar:scabbard-processor:0.5.0

Display objects from component dependency differently

Part of our overall object graph looks like this:

io orionlabs android feature media di MediaComponent

Some of these objects in the graph are coming from a component dependency:

@Component(
        modules = {
                MediaModule.class
        },
        dependencies = {
                SomeOtherComponent.class
        }
)
public interface MediaComponent {...}

You can probably infer which ones are coming from SomeOtherComponent based on package name. It would be nice if these were either color coded differently than those supplied by MediaModule, or maybe even put them in another box inside "object graph".

Support for creating top down graph

It will be nice to have an option to create a top-down graph that starts with the application component at the top and goes down to entry points at bottom of the graph.

Support incremental annotation processing

I remember seeing something somewhere that scabbard disables it (though didn't see anything obvious in code about this). Would be good to have the reasons documented and filing an issue for tracking it. Feel free to close if it's a technical limitation, but would be good to add this in the FAQ

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.