2015-04-30 31 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

相关问题