VeasMKII
VeasMKII

Reputation: 405

Gradle Manifest.MF

What I'm looking to do is combine both a pre-created manifest.mf file from my project with the dynamically created manifest file from the jar task in gradle.

Is there any way to do this? Currently I'm generating my manifest files entirely:-

jar.doFirst {
    manifest {
        def requiredProjects = ''
        configurations.compile.getAllDependencies().withType(ProjectDependency).each {dep->
            def dependantProjects = dep.getDependencyProject()
            def projects = project(dependantProjects.path).libsDir.list().findAll{it.endsWith('.jar')}
            projects.removeAll(projects.findAll{it.endsWith('test.jar')})
            def requiredProject = projects.join(' ')
            requiredProjects +=  requiredProject.replaceAll(/ /,'%20') + ' '
            logger.info 'Required Project: ' + requiredProject
        }
        logger.info 'Required requiredProjects: ' + requiredProjects

        def compileFiles = configurations.compile.files{ it instanceof ExternalDependency }.collect  {
            File file = it
            "lib/${file.name}"
        }.join(' ')

        def manifestPath = requiredProjects + compileFiles
        logger.info 'Manifest: '+ manifestPath
        attributes 'Class-Path': manifestPath
        attributes 'Build-date': new Date();
        attributes 'Application-Version': project.version
    }
}

I know that I'll have a /META-INF/MANIFEST.MF file.

Originally I was using the OSGI plugin for Gradle, but this seems to ignore the manifest file and generate a huge mess.

Edit

I've looked into this quite a bit, thanks to carlo I've found the following code will allow me to read an existing MANIFEST.MF:-

jar {
        onlyIf { !compileJava.source.empty } 
        manifest {
            // benutze das im Projekt vorliegende File, falls vorhanden:
            def manif = "${projectDir}/META-INF/MANIFEST.MF"
            if (new File(manif).exists()) {                
                from (manif) {
                    eachEntry { details ->                        
                        if (details.key == 'Bundle-Vendor') {
                                                    details.value = 'xyz GmbH'
                        }
                    }
                }                                    
            }
            else {
                logger.info(project.name + " doesn't have a META-INF/MANIFEST.MF.")  
                manifest.attributes provider: xyz GmbH'
                manifest.attributes project: project.name
                manifest.attributes Build: new Date()
            }
        }
        // copy if we have these:        
        from file ('plugin.xml')            
        from file ('plugin.properties')    
        into ('icons') {    // if any ...
            from fileTree('icons')
        }
    }

http://forums.gradle.org/gradle/topics/how_to_deal_with_eclipse_projects_and_manifest_files

I've also found a project called 'wuff' which aims to help building OSGi projects with Gradle.

https://github.com/akhikhl/wuff

Upvotes: 6

Views: 6624

Answers (1)

VeasMKII
VeasMKII

Reputation: 405

In the end I've managed to get what I wanted using the following code:-

jar.doFirst {
    manifest {
        def manifestFile = "${projectDir}/META-INF/MANIFEST.MF"
        if ( new File( manifestFile ).exists() )
            from ( manifestFile )
        def requiredProjects = ''
        configurations.compile.getAllDependencies().withType(ProjectDependency).each {dep->
            def dependantProjects = dep.getDependencyProject()
            def projects = project(dependantProjects.path).libsDir.list().findAll{it.endsWith('.jar')}
            projects.removeAll(projects.findAll{it.endsWith('test.jar')})
            def requiredProject = projects.join(' ')
            requiredProjects +=  requiredProject.replaceAll(/ /,'%20') + ' '
            logger.info 'Required Project: ' + requiredProject
        }
        logger.info 'Required requiredProjects: ' + requiredProjects

        def compileFiles = configurations.compile.files{ it instanceof ExternalDependency }.collect  {
            File file = it
            "lib/${file.name}"
        }.join(' ')

        def manifestPath = requiredProjects + compileFiles
        logger.info 'Manifest: '+ manifestPath
        attributes 'Class-Path': manifestPath
        attributes 'Build-date': new Date();
        attributes 'Application-Version': project.version
    }
}

The important lines being :-

def manifestFile = "${projectDir}/META-INF/MANIFEST.MF"
if ( new File( manifestFile ).exists() )
    from ( manifestFile )

This allows me to inherit any existing /META-INF/MANIFEST.MF file and also include classpath dependencies dynamically managed by gradle.

Upvotes: 3

Related Questions