2015-11-18 107 views
1

這是對我的理智的挑戰。我有以下build.gradleGradle神祕地運行生成任務?

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

+0

'defaultTasks'build''可能與此有關?嘗試評論該線。 – RaGe

+0

我試過評論,但沒有區別。我認爲只有在你運行'gradle'並且不指定任務時纔會發揮作用。 –

+1

'任務build(){'應該是'task build()<< {' – RaGe

回答

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 
    } 
} 
+0

這樣做會導致'gradle build'失敗。我被告知'execCommand == null!' –

+0

抱歉讓你掛斷。我認爲我理解了Gradle,昨天所指出的一切都是在我理解的情況下飛行的。誰知道有一個配置階段?!?那麼,顯然不是我。我道歉,你幫我創下了紀錄。 –

+0

NP,如果我說gradle沒有,我會時常說謊,每隔一段時間,都會質疑我對我在幕後工作的認識。無助於這些事情仍然在不斷變化! – RaGe