Help copying JS dependencies with Gradle

I have the following Gradle task. I’m trying to put my multiplatform outputs into an unpacked WAR directory so I can run it in a Java servlet container in my dev environment. It fails because that last clause (2) puts its files not in $dest/static but in static. It also affects the (1) clause, so that it (1) puts its files in static/static instead of $dest/static. Anyone know how to write this copy?

task devWar(type: Copy) {
    String wildflyHome = "/Dev/Wildfly/wildfly-servlet-18.0.0.Final"
    String dest = "${wildflyHome}/standalone/deployments/app1.war"
    dependsOn jvmMainClasses, jsMainClasses
    from(kotlin.targets.jvm.compilations.main.output.allOutputs.files) {
        into "WEB-INF/classes"
    }
    from(kotlin.targets.jvm.compilations.main.compileDependencyFiles) {
        into "WEB-INF/lib"
    }

    // (1)
    from(jsCompilations.main.output) {
        exclude "*.scss"
        into 'static'
    }

    // (2) This gets the js files like kotlinx-coroutines-core.js or 
    // kotlinx-serialization-runtime-js.js. They are in jar files like 
    // kotlinx-coroutines-core-js-1.2.1.jar
    from(provider {
        kotlin.targets.js.compilations.main.runtimeDependencyFiles.each {
            from zipTree(it.absolutePath).matching {
                include '*.js'
                into "static"
            }
            exclude '*.jar'
        }
    })

    from('src/webapp')
    into dest
}

You need to separate out the two scopes. Effectively now you are nesting. Instead put all the stuff related to dest in a lambda:

  into dest {
    from('src/webapp')
    // etc.
  }
  into 'static' {
    from (jsCompilations.main.output) {
      exclude "*.scss"
    }
    // etc.
  }

Thank you for the response, but I’m unable to get it to work.

I tried this, but it wouldn’t run:

into dest {
    from('src/webapp')
}

The error was unhelpful: No signature of method: java.lang.String.call() is applicable for argument types: (build_97zuv8kxtx5ps6i509ahu8prc$_run_closure6$_closure38) values: [build_97zuv8kxtx5ps6i509ahu8prc$_run_closure6$_closure38@31ee2f4f] Possible solutions: wait(), chars(), any(), wait(long), each(groovy.lang.Closure), take(int)

I guessed it wanted parens, so I went with:

into(dest) {
    from('src/webapp')
}

That failed with: No value has been specified for property ‘destinationDir’.

So I added a line to set that…

destinationDir = file(dest)
into(dest) {
    from('src/webapp')
}

But that put files not in /path/to/app1.war/path/to/app1.war/WEB-INF, as opposed to just /path/to/app1.war/WEB-INF as desired.

So I tried this instead:

destinationDir = file(dest)
into(".") {
    from('src/webapp')
}

Which works, fine. But as soon as I add back the problem area, the from(provider...),

destinationDir = file(dest)
into(".") {
    from('src/webapp')
    ...
    from(provider {
        kotlin.targets.js.compilations.main.runtimeDependencyFiles.each {
            from zipTree(it.absolutePath).matching {
                include '*.js'
                into "static"
            }
            exclude '*.jar'
        }
    })
}

It does the same thing as before. Some things go into the dest directory (the exploded war) as desired. But some go into static, outside the war, in gradle`s current directory (the project directory).