Gradle神秘地运行Build任务?

时间:2015-11-18 19:12:44

标签: gradle

这对我的理智充满挑战。我有以下build.gradle

import org.gradle.api.tasks.Exec
import org.apache.tools.ant.taskdefs.condition.Os

defaultTasks 'build'

// not specifying .cmd on windows will attempt to
// run the extensionless executable which will fail
ext {
  npmCommand = Os.isFamily(Os.FAMILY_WINDOWS) ? 'npm.cmd' : 'npm'
  tscCommand = Os.isFamily(Os.FAMILY_WINDOWS) ? 'tsc.cmd' : 'tsc'
}

// Get the path for the locally installed binaries
task npmBin << {
    new ByteArrayOutputStream().withStream { os ->
        exec {
            executable = npmCommand
            args = ['bin']
            standardOutput = os
        }
        ext.binPath = os.toString().trim() + File.separator
    }
}

task copyVendor(type: Copy) {
  from 'node_modules/systemjs/dist/system.src.js',
       'node_modules/angular2/bundles/angular2.dev.js',
       'node_modules/angular2/bundles/http.dev.js'
  into 'build/app/scripts/vendor'
}

task copyNonTS(type: Copy) {
  from('app') {
    exclude '**/*.ts', '**/*.js.map'
  }
    filter { line -> line.replaceAll('(node_modules\\/systemjs\\/dist)|(node_modules\\/angular2\\/bundles)', 'app/scripts/vendor') }
  into 'build/app'
}

// Install packages from package.json
task npm(type: Exec) {
    description = "Grab NodeJS dependencies (from package.json)"
    commandLine = [npmCommand, "install"]
    inputs.file "package.json"
    outputs.dir "node_modules"

    tasks.npmBin.execute()
}

task cleanDev(type: Delete) {
    outputs.upToDateWhen { false }
  delete fileTree(dir: 'app', include: ['**/*.js', '**/*.js.map'])
}

task delOutput(type: Delete) {
    outputs.upToDateWhen { false }
    println "DELETING"
    delete 'build/'
}

task clean(type: Delete) {
    outputs.upToDateWhen { false }
    cleanDev.execute()
    delOutput.execute()
}

task build(dependsOn: 'npm', type: Exec) {
    println "BUILDING"
    if (file(new File("${npmBin.binPath}${tscCommand}")).isFile()) {
        // runs non-globally installed tsc from node_modules
        commandLine "${npmBin.binPath}${tscCommand}"
    } else {
        // runs globally installed tsc
        commandLine = [tscCommand]
    }
  copyVendor.execute()
  copyNonTS.execute()
}

不知何故,当我运行gradle delOutput时,我得到以下输出:

DELETING
BUILDING
:delOutput

BUILD SUCCESSFUL

Total time: 2.012 secs

为什么当我运行这个看起来很小,原子,无依赖性的任务时,我的构建任务会运行吗?它删除我的构建文件夹,然后立即调用构建任务再次运行(输出“BUILDING”显而易见)。

这里发生了什么?

编辑:

forum post同意这里所说的内容。但是,如果我有一个type: Exec的任务,那么我必须在配置阶段指定commandLine,这样做似乎总是执行命令,无论我是否真的想要运行任务。如何在运行任务时仅运行commandLine

1 个答案:

答案 0 :(得分:1)

task hello << {
    println 'Hello world!'
}

的简写
task hello {
    doLast {
        println 'Hello world!'
    }
}

如果您没有doLast,则任务将在配置阶段运行,而不是在您明确调用时运行。

将您的任务定义从task build(){更改为task build()<<{

编辑您的修改:

这样的事情对你有用吗?

task hello {

    def commandline = 'something' //in the config phase

    doLast {
        println 'Executing!' //in the exec phase
    }
}