This message was deleted.
# plugin-development
s
This message was deleted.
c
you’d typically want a provider, not a resolved property. e.g.
myInstallTask.whateverProperty.map { … }
, which will be deferred until execution time, avoiding that error message. Also - if you follow this route - the dependsOn is no longer required, as the provider propagates the task dependency,.
k
Well, moving this all inside a
project.afterEvaluate
really didn't have any effect, either. I think I'm just misusing/abusing the
DirectoryProperty
. Not sure how else to go about this. I don't want to
resolvedDir.get()
too early.
c
project.afterEvaluate
is a code smell - causes far more problems than it solves.
Something like this:
Copy code
project.pluginManager.withPlugin(OTHER_PLUGIN) {
            val install = project.findProperty("myInstall") as InstallPluginExtension
            val myInstallTask = tasks.named("myInstall")
            cmakeDebug.configure {
                // not necessary
                // dependsOn(myInstallTask)
                includeDirs.from(myInstallTask.resolvedDir.map { it.dir("include") } )
                linkFiles.from(myInstall.resolvedDir.map { it.dir("debug/lib") })
            }
👍 1
k
Ahh. Yes, that seems much better. I was overthinking this trying to use the extension. Should just use the
OutputDirectory
. Much saner approach.
v
Definitely, someone could have configured the task directly instead of the extension so by taking the extension value you maybe take the wrong one. Besides getting the proper implicit task dependency of course.
Does this all just need to be moved to a
project.afterEvaluate
?
Almost all usages of it are a smell and should be avoided.
And, really feels a little dirty to put a
#withPlugin
closure there.
pluginManager.withPlugin
is never dirty, you want to configure an extension a plugin adds or use a task a plugin registers, then react to the plugin being applied (or if you always need it, then explicitly apply it), no need to feel dirty. Explicit
dependsOn
on the other hand are also almost always a code smell (unless there is a lifecycle task on the left-hand side of it)
k
It seems like I am still misusing
DirectoryProperty
. I have a much cleaner task wiring thanks to the suggestions, yesterday. But, my error has just propagated to the
task
.
Copy code
> Cannot query the value of this provider because it has no value available.
  The value of this provider is derived from:
    - task ':myInstall' property 'dir'
So, why is this trying to resolve the property so early, rather than mapping to it?
Copy code
project.pluginManager.withPlugin(INSTALL_PLUGIN) {
            val myInstallTask = tasks.findByName("myInstall") as Install
            cmakeDebug.configure {
                includeDirs.from(myInstallTask.dir.map { it.dir("include") })
                linkFiles.from(myInstallTask.dir.map { it.dir("debug/lib") })
            }
I must be struggling to understand the proper usage of
#from
and
#map
in this context.
public abstract ConfigurableFileCollection from( Object... paths )
Adds a set of source paths to this collection. The given paths are evaluated as per org.gradle.api.Project.files(Object...).
ConfigurableFileCollection files( Object... paths )
Returns a ConfigurableFileCollection containing the given files. You can pass any of the following types to this method:
...
A Provider of any supported type. The provider's value is recursively converted to files. If the provider represents an output of a task, that task is executed if the file collection is used as an input to another task.
public abstract <S> Provider<S> map( org.gradle.api.Transformer<? extends S, ? super T> transformer )
Returns a new Provider whose value is the value of this provider transformed using the given function.
The new provider will be live, so that each time it is queried, it queries this provider and applies the transformation to the result. Whenever this provider has no value, the new provider will also have no value and the transformation will not be called.
Hmm. It says that it is live, but doesn't say it will throw an error if it has no value. So,
#from
requires an immediate value at invocation?
v
Live means that it is not resolved once when you create it, but that it always shows the state that is valid at the time you query it. From a quick look I don't see an error, but it is probably in code you did not show. Can you provide an MCVE?
t
BTW, you don't need the
map
here,
myInstallTask.dir.dir("include")
should do the same AFAICT
g
And better to use something like
val myInstallTaskProvider = tasks.named<Install>("myInstall")
with
myInstallTaskProvider.flatMap { it.dir.dir("include") }
to avoid realizing all tasks on
tasks.findByName
👍 1