Skip to content

Commit

Permalink
fix: work around non-mergeable configs in Android builds (#59)
Browse files Browse the repository at this point in the history
  • Loading branch information
kyegupov authored Apr 12, 2019
1 parent f949cee commit 13fe11a
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 10 deletions.
24 changes: 22 additions & 2 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,14 +273,34 @@ async function getAllDeps(root, targetFile, options): Promise<JsonDepsScriptResu
// intentionally empty
}
const orange = chalk.rgb(255, 128, 0);
const blackOnYellow = chalk.bgYellowBright.black;
gradleVersionOutput = orange(gradleVersionOutput);
const subProcessError = orange(error.message);
const mainErrorMessage = `Error running Gradle dependency analysis.
let mainErrorMessage = `Error running Gradle dependency analysis.
Please ensure you are calling the \`snyk\` command with correct arguments.
If the problem persists, contact [email protected], providing the full error
message from above, starting with ===== DEBUG INFORMATION START =====.`;
const blackOnYellow = chalk.bgYellowBright.black;

// Special case for Android, where merging the configurations is sometimes
// impossible.
// There are no automated tests for this yet (setting up Android SDK is quite problematic).
// See test/manual/README.md

if (/Cannot choose between the following configurations/.test(error.message)
|| /Could not select value from candidates/.test(error.message)) {
mainErrorMessage = `Error running Gradle dependency analysis.
It seems like you are scanning an Android build with ambiguous dependency variants.
We cannot automatically resolve dependencies for such builds.
We recommend converting your subproject dependency specifications from the form of
implementation project(":mymodule")
to
implementation project(path: ':mymodule', configuration: 'default')
or running Snyk CLI tool for a specific configuration, e.g.:
snyk test --all-sub-projects -- --configuration=releaseRuntimeClasspath`;
}

error.message = `${blackOnYellow('===== DEBUG INFORMATION START =====')}
${orange(gradleVersionOutput)}
Expand Down
25 changes: 17 additions & 8 deletions lib/init.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import groovy.json.JsonOutput
// generate a merged configuration of all the available configurations,
// and then list the dependencies as a tree.

// It's the responsibility of the caller to pick the project(s) they are
// It's the responsibility of the caller to pick the project(s) they are
// interested in from the results.

// CLI usages:
Expand Down Expand Up @@ -44,7 +44,7 @@ import groovy.json.JsonOutput
// only ever run it once, for the "starting" project.
def snykMergedDepsConfExecuted = false
allprojects { everyProj ->
task snykResolvedDepsJson {
task snykResolvedDepsJson {
def onlyConf = project.hasProperty('configuration') ? configuration : null

def depsToDict
Expand All @@ -66,17 +66,26 @@ allprojects { everyProj ->
def result = ['defaultProject': task.project.name, 'projects': projectsDict]
if (!snykMergedDepsConfExecuted) {
allprojects.each { proj ->
def snykConf = null
if (proj.configurations.size() > 0) {
if (proj.configurations.findAll({ it.name == 'snykMergedDepsConf'}).size() == 0) {
def snykConf = proj.configurations.create('snykMergedDepsConf')
if (onlyConf != null) {
// We select one existing configuration, with its attributes.
snykConf = proj.configurations.getByName(onlyConf)
} else if (proj.configurations.findAll({ it.name == 'snykMergedDepsConf'}).size() == 0) {
// We create a new, "merged" configuration here. It has no attributes, which might be
// a problem for Android builds, where a resolution of a dependency "variant"
// is often dependent on configuration attributes (such as BuildType or Usage).
snykConf = proj.configurations.create('snykMergedDepsConf')
proj.configurations
.findAll({ it.name != 'snykMergedDepsConf' && (onlyConf == null || it.name == onlyConf) })
.each { snykConf.extendsFrom(it) }
projectsDict[proj.name] = [
'targetFile': findProject(proj.path).buildFile.toString(),
'depDict': depsToDict(snykConf.resolvedConfiguration.firstLevelModuleDependencies)
]
}
}
if (snykConf != null) {
projectsDict[proj.name] = [
'targetFile': findProject(proj.path).buildFile.toString(),
'depDict': depsToDict(snykConf.resolvedConfiguration.firstLevelModuleDependencies)
]
} else {
projectsDict[proj.name] = [
'targetFile': findProject(proj.path).buildFile.toString()
Expand Down
7 changes: 7 additions & 0 deletions test/manual/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
## Android build issues

Since installing Android SDK is quite a hassle, there's no automated test for the Android Build Type problem
(https://snyksec.atlassian.net/browse/BST-528).

Instead, please install Androd Studio or SDK on your own
and run `snyk test` on https://github.com/snyk-fixtures/android-cannot-auto-resolve to test

0 comments on commit 13fe11a

Please sign in to comment.