albuch / sbt-dependency-check

SBT Plugin for OWASP DependencyCheck. Monitor your dependencies and report if there are any publicly known vulnerabilities (e.g. CVEs). :rainbow:

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support providing settings via Global and ThisBuild

nigredo-tori opened this issue · comments

Is your feature request related to a problem? Please describe.

Currently all the settings are rigidly defined at the project level (foo := defaultFoo in projectSettings). This means that the users can only override each of them at the project level - so Global/foo and ThisBuild/foo are ignored. This is inconvenient for multi-project builds, where it makes sense to provide project-wide overrides in local.sbt.

Describe the solution you'd like

Most of the defaults don't depend on the other project settings (e.g. foo := baseDirectory.value), and don't use extra scoping (e.g. aggregate in foo) . We should move those to globalSettings as described here. For the other settings we should only provide the default if there's no previous value:

foo := foo.?.value.getOrElse(defaultFoo)

Thanks for the suggestion, I need to think a little bit more about this proposal as we're currently only supporting the dependencyCheckSkip..... settings to be overrideable in child projects (due to how the dependencyCheckAggregate task is supposed to work).

Could you describe a little bit more how your multi project setup looks like (e.g stripped down build.sbt) and what you want to achieve by running different configurations per project?

Could you describe a little bit more how your multi project setup looks like (e.g stripped down build.sbt) and what you want to achieve by running different configurations per project?

Imagine a project like this:

val foo = project
val bar = project
val root = project.aggregate(foo, bar)

Let's say I want to override the data directory (or any other setting) on my machine. For that I would have to do this in local.sbt:

// depending on how the build is set up, we might need to redefine `foo` etc.
// as `LocalProject`s - but let's skip that here.
foo / dependencyCheckDataDirectory := myDataDirectory
bar / dependencyCheckDataDirectory := myDataDirectory
root / dependencyCheckDataDirectory := myDataDirectory

I might choose to only override one of those - but in that case the three dependencyCheck tasks' behavior becomes inconsistent.

Instead of the boilerplate above, I'd like to be able to do this:

ThisBuild / dependencyCheckDataDirectory := myDataDirectory

I've had a short look at it and how we currently support individual settings for multi projects.
Right now sbt-dependency-check only supports individual settings if run with dependencyCheck creating individual reports per project.
dependencyCheckAggregate and the new dependencyCheckAnyProject coming next release (see #95) only allow to configure settings on the project where the task is executed and not it's dependecies/aggregates so you wouldn't need to configure a setting multiple times if you always run the task on the same (e.g. root) project.
I want to make sure that I fully understand your use case: do you want to create individual reports per project in a multi project setup and why?

@albuch, sorry it took me a while to get back to this.

dependencyCheckAggregate and the new dependencyCheckAnyProject coming next release (see #95) only allow to configure settings on the project where the task is executed and not it's dependecies/aggregates so you wouldn't need to configure a setting multiple times if you always run the task on the same (e.g. root) project.

It's not always convenient to run the check for the whole project. When working with a multiproject build, I'm often working in a context of one or another submodule, and in that case doing dependencyCheck is more intuitive then root/dependencyCheckAggregate. But that's just convenience.

I want to make sure that I fully understand your use case: do you want to create individual reports per project in a multi project setup and why?

Individual reports are not the goal. It's just that I have a convenience AutoPlugin that sets up various code quality tools (including sbt-dependency-check) for any subproject it's enabled in. The implementation uses dependencyCheck (as the path of the least resistance), which means I have multiple subprojects (with this plugin) with no good/idiomatic way to specify local (as in, specific to my machine) values for sbt-dependency-check settings across subprojects. It's not the most orthodox setup, but it works.

As an aside, I'll probably have to do something in my plugin to run dependencyCheckAggregate for root - even with tagging, I have encountered some odc.mv.db locking issues which I don't want to have to deal with. This is complicated by the fact that I aggregate a subproject that does not have JvmPlugin enabled, and dependencyCheckAggregate chokes on that (since there is no configuration settings). But I don't have the time to figure that out right now, so I'll have to stick with dependencyCheck for a while.

This is complicated by the fact that I aggregate a subproject that does not have JvmPlugin enabled, and dependencyCheckAggregate chokes on that (since there is no configuration settings).

I'll adress this with a fix for #122

Hi @nigredo-tori,

For the other settings we should only provide the default if there's no previous value:

I don't see the point: the defaults that are currently set are needed because there are no defaults by the underlying core library as they are build system dependend.
Overriding a setting on the project level will always have precedence over the default value, that's how Scope delegation works. A value from your build.sbt will always have precedence over a default value from sbt-dependency-checks projectSettings.
Please let me know if I'm missing something here. Otherwise my PR should be got to go.

@albuch, in that quote I was talking about the defaults that are, by their nature, local to a project. In your PR, those are

dependencyCheckOutputDirectory := Some(crossTarget.value),
dependencyCheckScanSet := Seq(baseDirectory.value / "src/main/resources"),

We can't reduce those to Global settings.

I don't see the point: the defaults that are currently set are needed because there are no defaults by the underlying core library as they are build system dependend.

I wasn't arguing about adding new defaults, just about massaging the existing ones.

Overriding a setting on the project level will always have precedence over the default value, that's how Scope delegation works.

Scope delegation is not involved here. dependencyCheckOutputDirectory settings in the plugin and in build.sbt (on project level) have to use the same scope.

A value from your build.sbt will always have precedence over a default value from sbt-dependency-checks projectSettings.

Probably. I can imagine a situation with user code in a separate AutoPlugin setting dependencyCheckOutputDirectory, but not defining a dependency on DependencyCheckPlugin - in which case the resulting value of dependencyCheckOutputDirectory would depend on the order in which SBT happens to apply the plugins. Though that does sound as an unlikely scenario/use case, so I'm probably overthinking it.

All an all, I'm perfectly happy with just moving the "simple" defaults to Global, as you have done in your PR.

Thanks for your explanation. In my day to day work I only see rather simple project setups, so I highly value input from a point of view of more complex setups.
I suggest to release it like it currently is and address other more special use cases if any come up later.
I'll update the docs for this PR and prepare a v3.0.0 release.