CLI - Advanced Gradle testing
Gradle is a very powerful and flexible build system. As a result, analyzing Gradle projects in order to detect its dependencies is not an easy task: the exact set of dependencies is influenced by a number of parameters you need to take into account.
Each Gradle build can consist of several sub-projects (each sub-project has
build.gradle, the root project is the one that has
settings.gradle in it). By default, sub-projects depend on the root project (e.g. "apps" depend on "base"), but it can be configured otherwise.
By default, Snyk CLI scans only the current project (either the one in the current folder or the one that is specified by
--file=path/to/build.gradle). To scan all subprojects at once (recommended), use the
--all-sub-projects flag (in case of
snyk monitor, they will be uploaded as separate projects to the Registry).
To scan only a specific project
myapp, specify the
--gradle-sub-project=myapp option (or
A Gradle build produces several build "configurations": there's a
compileOnly configuration for development dependencies,
compile configuration that includes compile and runtime dependencies,
test... configurations that include test dependencies; Android builds can have "debug" and "release" configurations of all kinds).
By default, the
snyk command line tool merges all the configurations and gets the sum total of the dependencies. Sometimes this is either undesired (you might want to exclude test and service tasks) or does not work at all (see below about Android build variants).
--configuration-matching option can help you to select only certain configurations. It takes a Java regular expression (case-insensitive) as a parameter. If only one configuration matches, it will be used to scan the project. If several configurations match, they all will be merged and resolved together.
--configuration-matching=^compile$will match only
- different sub-projects might have different configurations, so in some cases you will have to scan them individually, instead of using the
- in older versions of the
snykcommand line tool, you could specify the desired configuration like this:
snyk test -- --configuration=myconf. This syntax is now deprecated and might be removed in future versions.
Android Build Variants
Android Gradle builds allow you to configure several "variants": https://developer.android.com/studio/build/build-variants. This becomes a problem if some of your sub-projects depend on other sub-project that have variants, like this:
Then snyk test or snyk monitor command will fail with an error from Gradle, which will contain a message like:
Cannot choose between the following configurations of project :mymodulewithvariants
Cannot choose between the following variants of project :mymodulewithvariants
Could not select value from candidates
The most common variant conflicts are due to different build types (
release) or "product flavors" (which are specific to your project). Those conflicts can be solved in one of the following ways:
Suggest configuration attributes: a Gradle configuration would select the dependency variants using its attributes. In the error message, the
snyk command line tool will tell you about available attribute values, and the error details from Gradle will tell you about which dependency variants would match which attributes. You can then add the attribute filter option. E.g.
--configuration-attributes=buildtype:release,usage:java-runtime,mode:demowould match the variants using:
- flavor dimension
mode**selecting the flavor
Use a specific configuration(s): if you know of a build configuration that has all the required attributes, you can specify it instead, e.g.
--configuration-matching=prodReleaseRuntimeClasspath . However, this method will fail if not all of the tested subprojects have the same configurations.
Explicitly specify the dependency configuration: finally, you can modify intra-project dependencies in your
build.gradle file(s) to use a specific configuration:
implementation project(path: ':mymodulewithvariants', configuration: 'default')