plugins {
    id 'base'
}

// Fake NPM task that would normally execute npm with its provided arguments
class NpmTask extends DefaultTask {

    ListProperty<String> args = project.objects.listProperty(String)

    @TaskAction
    void run() {
        project.file("$project.buildDir/bundle.js").withOutputStream { stream ->
            project.file("scripts").listFiles().sort().each {
                stream.write(it.bytes)
            }
        }
    }
}

// tag::bundle-task[]
@CacheableTask                                       // <1>
class BundleTask extends NpmTask {

    @Override @Internal                              // <2>
    ListProperty<String> getArgs() {
        super.getArgs()
    }

    @InputDirectory
    @SkipWhenEmpty
    @PathSensitive(PathSensitivity.RELATIVE)         // <3>
    final DirectoryProperty scripts = project.objects.directoryProperty()

    @InputFiles
    @PathSensitive(PathSensitivity.RELATIVE)         // <4>
    final ConfigurableFileCollection configFiles = project.files()

    @OutputFile
    final RegularFileProperty bundle = project.objects.fileProperty()

    BundleTask() {
        args.addAll("run", "bundle")
        bundle.set(project.layout.buildDirectory.file("bundle.js"))
        scripts.set(project.layout.projectDirectory.dir("scripts"))
        configFiles.from(project.layout.projectDirectory.file("package.json"))
        configFiles.from(project.layout.projectDirectory.file("package-lock.json"))
    }
}

task bundle(type: BundleTask)
// end::bundle-task[]

task printBundle {
    dependsOn bundle
    doLast {
        println file("$buildDir/bundle.js").text
    }
}
