Idea: provide a standard way to document properties

Hi there.

The tasks task allows listing and describing available tasks. But in large, complex builds, some of these tasks are influenced by properties passed with -P on the command line, or using the gradle.properties file. And, as far as I know, there is no way to describe, or even know about these properties without looking at the source code of the build.

Hence my idea: add a standard extension (not sure it’s the right term, but an example will follow) on Project, and maybe even on Task, that would allow the build script developer, but also the plugins, to list and describe the properties that influence what a project build, or a task, does.

For example:

properties {
  property('externalTestsDisabled', description: 'if this property is set, then tests accessing external web services are disabled')
}

Or, to take an example applicable to the gradle buid itself, its install task could have

task install(type: Install) {
  properties {
    property('gradle_installPath', description: 'the directory where the gradle installaton is created by this task')
  }
}

In addition to gradle tasks, anyone could then execute gradle properties, which would list all the properties declared on the project, and all the properties declared on the tasks, to tell the user which properties are available for projects and tasks. Any task added by any plugin could also document the properties it supports.

What do you think about that?

1 Like

There was a discussion and a PR a while ago about making the @Option annotation public, this will give power to tasks to declare command line arguments e.g: --install-path, instead of having to use project properties.

That option is integrated with the help command and can print all available values.

I am just mentioning cuz I believe you can use as reference for something, not saying you should use that instead of the properties in your custom tasks.

Thanks

I also wish property discoverability and documentation were better supported. gradle properties is essentially dumping the state of the project object which might give you some hints about available override points, but there’s a lot of noise and no guarantee that globally injecting a property with -P is going to work or work as intended.

I think this is the PR. Getting better access to the command-line syntax is cool, but ideally any technique would be widely supported across external configuration mechanisms (command-line, properties files, environment variables) and addressable to subprojects instead of global if necessary. I’d like to be able to ask Gradle for a list of intentionally externally configurable things in some scope and get a list of names and descriptions and be confident in how to express a setting via whatever mechanism I prefer to use.

Configuration in Gradle is somewhat murky to me to begin with. Ext properties are reasonably clear from a Groovy standpoint, but there are also convention properties and plugin extensions and the hoops Kotlin is having to jump through to make things statically typed. Then there’s #726 and this incubating model stuff… I’m pretty happy with what Gradle helps me do, but I don’t think I’ve ever worked with a tool that was trying so hard to outpace my ability to comprehend it. :grinning:

One possible step in this direction is for Gradle to remember all properties accessed through Project.property() and add them to the reports of the properties task.

The output could be something like:

Defined Properties:
foo=bar
baz=qux
and=etcetra, and etcetra

Undefined Properties:
abc
  defaulted to '123' (in 2 usages))
  defaulted to '' (in 1 usage)
flurbDir
  defaulted to '$buildDir/flurb' (in 4 usages)

The “Undefined Properties” section could be lenghty, so it makes sense to ask for it explicitly, i.e. with --show-undefined option. If we want to get fancy, we could have an extra report about property-usage, showing all the locations where a particular property is used.

The other request about providing a way to add documentation for properties, as attractive as it sounds may be a missed train. There are too many plugins out there that already use properties without documenting them.

Furthermore, such documentation mechanism should support extensibility and composability - imagine 2 plugins reacting to the same property (yes, sometimes this may be a desirable thing) - the doc needs to reflect the combination of effects, something that can be achieved by simple concatenation, but perhaps something more sophisticated may be useful (i.e. remember who registered particular piece of documentation).

I’d just like to remind that my original idea is not to list properties that were used/accessed somehow during the configuration phase, and even less during the execution phase of the build.

The idea is to provide a way for the build script author and the plugin authors to document, and display, the properties that can be passed during a build to modify or configure what a build or a task does.
Simply listing them is not really helpful, especially if you need to execute the build to have them listed.

The @Option annotation looks promising, although I don’t exactly know what it allows to do and where. I wouldn’t like for it to be only usable in new custom task classes. I’d like to be able to document properties used in any existing task, like, for example:

    test {
        // ...
        properties {
            property('externalTestsDisabled', description: 'if this property is set, then tests accessing external web services are disabled')
        }
    }