2015-04-30 37 views
1

我是Gradle和Groovy的新手,我希望能解決我的問題。Gradle:如何創建多個jar?

我有幾個包,每個包都需要編譯成一個jar包。
我發現的一個解決方案是創建Jar類型的多個任務,但是我希望避免複製/粘貼,並在每次將新包添加到我的項目時都會生成一個巨大的gradle文件。

我目前的實現是有多個罐子的任務,像這樣的:

task jarFoo(type: Jar) { 
    baseName = "foo" 
    version = "1.0.0" 
    String className = baseName.capitalize() 

    from(sourceSets.main.output) { 
     include "$baseName/**" 
    } 

    from { 
     configurations.compile.collect { 
      it.isDirectory() ? it : zipTree(it) 
     } 
    } 

    manifest { 
     attributes "Implementation-Title": "$className", 
       "Implementation-Version": "$version", 
       "Main-Class": "$baseName.$className" 
    } 
} 

它的工作原理就像一個魅力,但我添加軟件包非常頻繁,我將結束與很多包,所以一很多任務和大量的複製/粘貼代碼。

擺弄build.gradle文件後,我發現我需要擴展從Jar才能創建一個jar。

因此,這裏是迄今爲止該類代碼:

class JarTask extends Jar { 
    String jarName = "default" 
    String jarVersion = "1.0.0" 

    @TaskAction 
    def jar() { 
     baseName = jarName 
     version = jarVersion 
     String className = baseName.capitalize() 

     // Thanks Opal for reminding that sourceSets 
     // is defined in project. 
     from(project.sourceSets.main.output) { 
      include "$baseName/**" 
     } 

     from { 
      configurations.compile.collect { 
       it.isDirectory() ? it : zipTree(it) 
      } 
     } 

     manifest { 
      attributes "Implementation-Title": "$className", 
        "Implementation-Version": "$version", 
        "Main-Class": "$baseName.$className" 
     } 
    } 
} 

task jarFoo(type: JarTask) { 
    jarName = "foo" 
} 

task jarBar(type: JarTask) { 
    jarName = "bar" 
    jarVersion = "1.2.42" 
} 

的問題是,所創建的jar忽略的方法基本上一切:它僅包含含MANIFEST.MF一個符合清單版本被賦予項目名稱,而不是任務中給出的名稱。沒有其他的。

如果需要,您可以在我的GitHub repo(主要是法語)在線查找代碼。

任何想法將真正感激!

+0

我可以'重現它。 – Opal

+0

你的意思是說「優化」代碼適合你嗎? – Gabriel

+0

我編輯了這個問題,添加了一些我在其中完成的工作。 – Gabriel

回答

2

這是另一個更容易的選項,允許傳遞參數。我在這個主題上找到了靈感:https://discuss.gradle.org/t/passing-arguments-to-a-task/8427/20,這聽起來完全像我想要做的。

這裏我們基本上定義了一個返回給定參數的任務的方法。其餘的只是測試是否給出了一個版本,或者已經給出了代碼並且用@Opal很好的幫助進行了修改。

artifacts塊中包含新版本就足以使任務可用。然後,運行gradle jarqcm來構建一個包或者編譯一切。

apply plugin: "idea" 
apply plugin: "java" 

repositories { 
    mavenCentral() 
} 

dependencies { 
    compile "com.intellij:forms_rt:7.0.3" 
    runtime "com.intellij:forms_rt:7.0.3" 
} 

def jarPackage(artifactName, artifactVersion) { 
    if (artifactVersion == "" || artifactVersion == null) { 
     artifactVersion = "1.0.0" 
    } 
    return tasks.create("jar${artifactName}", Jar) { 
     baseName = artifactName 
     version = artifactVersion 
     String className = baseName.capitalize() 

     from(sourceSets.main.output) { 
      include "$baseName/**" 
     } 

     from { 
      configurations.compile.collect { 
       it.isDirectory() ? it : zipTree(it) 
      } 
     } 

     manifest { 
      attributes "Implementation-Title": "$className", 
        "Implementation-Version": "$version", 
        "Main-Class": "$baseName.$className" 
     } 
    } 
} 

artifacts { 
    archives jarPackage("aleatoire", ""), jarPackage("calculatrice", "1.2.3"), jarPackage("copier", ""), 
      jarPackage("qcm", "1.0.0") 
} 
1

編輯後的問題很簡單。對於給定任務沒有屬性sourceSets(在這種情況下爲Jar)。 sourceSetsProject上定義,並且延伸DefaultTask的任何任務均從其父項繼承project字段。所以,你只需要:

from(project.sourceSets.main.output) { 
    include "$baseName/**" 
} 

ANSWER

我希望你明白任務配置執行階段之間的區別。這是發生在這裏的問題。基本上你擴展了Jar任務,因爲所有類型爲Copy的任務都沒有設計爲擴展 - 請參閱here。在任務操作中,您配置要複製的構件,但是配置的時間太晚 - 這是執行階段。可以使用rules來解決問題任務。我修改了腳本,它是:

apply plugin: "idea" 
apply plugin: "java" 

repositories { 
    mavenCentral() 
} 

dependencies { 
    compile "com.intellij:forms_rt:7.0.3" 
    runtime "com.intellij:forms_rt:7.0.3" 
} 

tasks.addRule('Pattern: build<ID>') { String taskName -> 
    if (taskName.startsWith('build')) { 
     task(taskName, type: Jar) { 
      baseName = taskName - 'build' 
      version = '1.0.0' 
      String className = baseName.capitalize()    

      from(sourceSets.main.output) { 
       include "$baseName/**" 
      } 

      from { 
       configurations.compile.collect { 
        it.isDirectory() ? it : zipTree(it) 
       } 
      } 

      manifest { 
       attributes "Implementation-Title": "$className", 
         "Implementation-Version": "$version", 
         "Main-Class": "$baseName.$className" 
      } 
     } 
    } 
} 

artifacts { 
    archives project.tasks['buildqcm'], project.tasks['buildlistage'] //etc 
} 

並且應該簡單地用gradle buildlistage buildqcm來調用。您可以進行額外的驗證,以檢查<ID>傳遞是否位於軟件包列表中,例如希望有助於和抱歉等待這麼久:/

+0

感謝您的回答!它解決了'無法找到屬性'sourceSets''錯誤。但是jar仍然幾乎爲空(只是一個MANIFEST文件),並且包含項目名稱,而不是任務中給出的名稱。任何想法 ? – Gabriel

+0

我編輯了問題的結尾以反映這一點。 – Gabriel

+0

對不起!你解決了這個問題嗎? – Opal

相關問題