Throw away element from ListProperty

I have a ListProperty that contains some values set by a convention plugin. In my build, I’d like to drop one of the values. I can’t really figure out how to do this. I’ve tried using flatMap, but I run into stack overflow errors.

I have a project extension that contains some list:

interface SomeExtension {
    ListProperty<String> getSomeList()
}

extensions.add('someExtension', SomeExtension)

A convention plugin adds elements to this list:

someExtension.someList.add 'foo'
someExtension.someList.add 'bar'
someExtension.someList.add 'baz'

I would like to remove the bar element from the list and just keep foor and baz. I figured that using flatMap() is the way to go:

someExtension.someList = someExtension.someList.flatMap { it != 'bar' ? [it] : [] }

When I try to print the contents of the list, I get a stack overflow error:

println "result:"
println someExtension.someList.get()

I’m guessing there’s some kind of recursion going on here, but I don’t understand why.

Here’s the full build.gradle file:

interface SomeExtension {
    ListProperty<String> getSomeList()
}

extensions.add('someExtension', SomeExtension)

// Add some elements to list, assume that this is code in a convention plugin
someExtension.someList.add 'foo'
someExtension.someList.add 'bar'
someExtension.someList.add 'baz'

// Try to drop one of the elements added by the convention plugin
someExtension.someList = someExtension.someList.flatMap { it != 'bar' ? [it] : [] }

println "result:"
println someExtension.someList.get()

You set someList to a provider that is based on the current value of someList, that is exactly the cycle that causes the stack overflow.
What you are after is the update method that almost made it to 8.6, but was removed and now hopefully gets reintroduced as replace in 8.8: Property (Gradle API 8.8-20240328002759+0000)