Skip to content

Commit

Permalink
GRAILS-3577 - adds honoring the pluginexcludes for resources
Browse files Browse the repository at this point in the history
  • Loading branch information
rvowles committed Sep 8, 2012
1 parent 421b5df commit 8b77053
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 1 deletion.
Expand Up @@ -27,6 +27,7 @@ import org.apache.ivy.core.module.descriptor.DependencyDescriptor
import org.apache.ivy.plugins.resolver.URLResolver
import org.apache.ivy.plugins.resolver.IBiblioResolver
import org.codehaus.groovy.grails.resolve.GrailsRepoResolver
import org.springframework.util.AntPathMatcher

/**
* Generates the plugin.xml descriptor.
Expand All @@ -42,6 +43,7 @@ class PluginDescriptorGenerator {
Resource[] resourceList
List excludes = ["UrlMappings", "DataSource", "BuildConfig", "Config"]
BuildSettings buildSettings
AntPathMatcher antPathMatcher = new AntPathMatcher()

PluginDescriptorGenerator(BuildSettings buildSettings, pluginName, List<Resource> resourceList) {
this.buildSettings = buildSettings
Expand Down Expand Up @@ -80,6 +82,53 @@ class PluginDescriptorGenerator {
generatePluginXml(pluginProps, xml)
}

/* the pluginExcludes are Ant matched from the base of the application, but since the
pluginProps is not necessarily a class and we don't actually know where it is, we need
to go through the resources figuring out what the common resource base is. We are going to assume
a common Grails application layout to fudge this.
*/
private String resourceBaseMatchDirs = ['grails-app', 'web-app', 'scripts', 'test', 'src']
private File findCommonResourceBase() {
if (!resourceList) return null // no resources, won't loop

for (Resource r in resourceList) {
File f = r.file

while (f != null && !resourceBaseMatchDirs.contains(f.name)) {
f = f.parentFile
}

if (f) {
if (f.parentFile == null) { // wonderful, thanks Resource
return new File(f.absolutePath.substring(0, f.absolutePath.lastIndexOf(File.separator)))
} else {
return f.parentFile
}
}
}

GrailsUtil.warn("Unable to determine common resource base when generating plugin.xml")

return null
}

private boolean matchesPluginExcludes(List<String> pluginExcludes, File commonResourceBase, Resource r) {

// if we have no excludes or no common resource base, we don't match
if (!pluginExcludes) return false
if (!commonResourceBase) return false

if (r.file.absolutePath.indexOf(commonResourceBase.absolutePath) == 0) {
String path = r.file.absolutePath.substring(commonResourceBase.absolutePath.length()+1)
for(String pattern : pluginExcludes) {
if (antPathMatcher.match(pattern, path)) return true
}

}

return false
}

protected void generatePluginXml(pluginProps, MarkupBuilder xml) {
// Write the content!
def props = ['author', 'authorEmail', 'title', 'description', 'documentation', 'type', 'packaging']
Expand All @@ -89,6 +138,13 @@ class PluginDescriptorGenerator {

def pluginGrailsVersion = "${GrailsUtil.grailsVersion} > *"

// check to see if we have the property, grab it if so
def pluginExcludes
if (pluginProps['pluginExcludes'])
pluginExcludes = pluginProps.pluginExcludes
else
pluginExcludes = []

if (pluginProps != null) {
if (pluginProps["grailsVersion"]) {
pluginGrailsVersion = pluginProps["grailsVersion"]
Expand All @@ -99,10 +155,12 @@ class PluginDescriptorGenerator {
if (pluginProps[p]) "${p}"(pluginProps[p])
}
xml.resources {
File commonResourceBase = findCommonResourceBase()

for (r in resourceList) {
def matcher = r.URL.toString() =~ ARTEFACT_PATTERN
def name = matcher[0][1].replaceAll('/', /\./)
if (!excludes.contains(name)) {
if (!excludes.contains(name) && !matchesPluginExcludes(pluginExcludes, commonResourceBase, r)) {
xml.resource(name)
}
}
Expand Down
Expand Up @@ -27,6 +27,46 @@ class PluginDescriptorGeneratorSpec extends Specification {
xml.resources.resource[1].text() == 'bar.BarController'
}

def "Test plugin excludes causes no problems when no resources"() {
given:
def generator = new PluginDescriptorGenerator(new BuildSettings(),"foo", [])
when:
def sw = new StringWriter()
generator.generatePluginXml([version:1.0, dependsOn:[core:1.0], author:"Bob", pluginExcludes: ["**/test/**"]], sw)
def xml = new XmlSlurper().parseText(sw.toString())
then:
xml.@name == 'foo'
xml.@version == '1.0'
xml.author.text() == 'Bob'
xml.runtimePluginRequirements.plugin[0].@name == 'core'
xml.runtimePluginRequirements.plugin[0].@version == '1.0'
xml.resources.resource.size() == 0
}

def "Test plugin/excludes is honoured for resources"() {
given:
def generator = new PluginDescriptorGenerator(new BuildSettings(),"foo", [
new FileSystemResource(new File("grails-app/controllers/FooController.groovy")),
new FileSystemResource(new File("grails-app/controllers/test/BarController.groovy")),
new FileSystemResource(new File("grails-app/services/test/MyService.groovy")),
new FileSystemResource(new File("grails-app/services/MyService2.groovy"))
])
when:
def sw = new StringWriter()
generator.generatePluginXml([version:1.0, dependsOn:[core:1.0], author:"Bob", pluginExcludes: ["**/test/**"]], sw)
def xml = new XmlSlurper().parseText(sw.toString())
then:
xml.@name == 'foo'
xml.@version == '1.0'
xml.author.text() == 'Bob'
xml.runtimePluginRequirements.plugin[0].@name == 'core'
xml.runtimePluginRequirements.plugin[0].@version == '1.0'
xml.resources.resource.size() == 2
xml.resources.resource[0].text() == 'FooController'
xml.resources.resource[1].text() == 'MyService2'

}

void "Test that dependencies and repositories are correctly populated from BuildSettings"() {
given:"A plugin descriptor generator with a BuildSettings instance that defines repositories and dependencies"
PluginDescriptorGenerator generator = systemUnderTest()
Expand Down

0 comments on commit 8b77053

Please sign in to comment.