eerohele / saxon-gradle

A Gradle plugin for running XSLT transformations with Saxon
MIT License
16 stars 6 forks source link

Plugin doesn't work, inputs are broken #5

Closed jsotuyod closed 7 years ago

jsotuyod commented 7 years ago

Currently, the input attribute is never mapped to the internal options['input'] map entry, meaning even the samples will fail with:

FAILURE: Build failed with an exception.

* Where:
Build file 'saxon-gradle/examples/simple/build.gradle' line: 41

* What went wrong:
A problem occurred evaluating root project 'simple'.
> Cannot convert the provided notation to a File or URI: true.
  The following types/formats are supported:
    - A String or CharSequence path, for example 'src/main/java' or '/usr/include'.
    - A String or CharSequence URI, for example 'file:/usr/include'.
    - A File instance.
    - A URI or URL instance.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
jsotuyod commented 7 years ago

Just figured this one out. The property is mapped, but in a very ugly way, that ends up actually backfiring on the user.

Doing something such as (copied from example on README):

xslt {
  input fileTree(dir: 'input', include: '*.xml')
}

Means, it will first try to resolve fileTree as a method within the xslt task. Thanks to the unscrupulous use of methodMissing, it will "find" such method in the task, and return true, which is passed to input.

The only way for it to work is to make it clear we are not calling a xslt task method by doing project.fileTree (or project.file | project.files | whatever).

Also of note, the current methodMissing is not only breaking expected behavior, but is actually forbidding overwriting a property in a very non-obvious way.

Doing:

xslt {
  input project.file('a-file.xml')
}

// later - maybe based on conditions
xslt.input project.file('b-file.xml')

No errors, one would expect b-file.xml being used, but it's not. The closure created on methodMissing ignores arguments passed to the closure itself, sticking to the argument used when it was created.

A somewhat better implementation would have been:

        Closure cachedMethod = { it ->
            this.options[name] = it
        }

Hope this helps anyone else.

eerohele commented 7 years ago

Thanks for reporting the issue, and apologies for the inconvenience.

The methodMissing approach is certainly ill-advised. It was mostly a quick hack to get support for all of Saxon's command-line options.

Something must've changed in Gradle, though, because the issue you describe definitely didn't exist back when I first wrote the plugin.

In any case, I'll refactor the code not to use methodMissing as soon as I get the chance.

eerohele commented 7 years ago

@jsotuyod: I published version 0.2.1 into the Gradle plugin portal. If you get the chance, can you please give it a go and check whether it resolves your issue?

jsotuyod commented 7 years ago

Confirmed, the issue is fixed in 0.2.1! Thanks for the amazingly quick fix!

eerohele commented 7 years ago

Glad to hear it works. Thanks again for the detailed bug report.