Skip to content

Commit

Permalink
Merge pull request #9630 from Schlogen/3.0.x
Browse files Browse the repository at this point in the history
Update to support a plugin.groovy config in plugins
  • Loading branch information
graemerocher committed Feb 3, 2016
2 parents 0b14236 + 892e520 commit 10f431f
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ class GroovyConfigPropertySourceLoader implements PropertySourceLoader {
final String[] fileExtensions = ['groovy'] as String[]

@Override
PropertySource<?> load(String name, Resource resource, String profile) throws IOException {
PropertySource<?> load(String name, Resource resource, String profile) {
load(name, resource, profile, [])
}

PropertySource<?> load(String name, Resource resource, String profile, List<String> filteredKeys) throws IOException {
def env = Environment.current.name
if(profile == null || env == profile) {

Expand All @@ -55,6 +59,11 @@ class GroovyConfigPropertySourceLoader implements PropertySourceLoader {
appVersion: Metadata.getCurrent().getApplicationVersion() )
try {
def configObject = configSlurper.parse(resource.URL)

filteredKeys?.each { key ->
configObject.remove(key)
}

def propertySource = new NavigableMap()
propertySource.merge(configObject, false)
return new NavigableMapPropertySource(name, propertySource)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import groovy.lang.GroovyObjectSupport;
import org.grails.config.yaml.YamlPropertySourceLoader;
import org.grails.core.AbstractGrailsClass;
import org.grails.core.cfg.GroovyConfigPropertySourceLoader;
import org.grails.core.legacy.LegacyGrailsApplication;
import org.grails.plugins.support.WatchPattern;
import org.slf4j.Logger;
Expand All @@ -49,6 +50,8 @@ public abstract class AbstractGrailsPlugin extends GroovyObjectSupport implement

public static final String PLUGIN_YML = "plugin.yml";
public static final String PLUGIN_YML_PATH = "/" + PLUGIN_YML;
public static final String PLUGIN_GROOVY = "plugin.groovy";
public static final String PLUGIN_GROOVY_PATH = "/" + PLUGIN_GROOVY;
private static final List<String> DEFAULT_CONFIG_IGNORE_LIST = Arrays.asList("dataSource", "hibernate");
private static Resource basePluginResource = null;
protected PropertySource<?> propertySource;
Expand Down Expand Up @@ -84,12 +87,19 @@ public AbstractGrailsPlugin(Class<?> pluginClass, GrailsApplication application)
this.grailsApplication = application;
this.pluginClass = pluginClass;
Resource resource = readPluginConfiguration(pluginClass);

if(resource != null && resource.exists()) {
YamlPropertySourceLoader propertySourceLoader = new YamlPropertySourceLoader();
final String filename = resource.getFilename();
try {
this.propertySource = propertySourceLoader.load(GrailsNameUtils.getLogicalPropertyName(pluginClass.getSimpleName(), "GrailsPlugin") + "-plugin.yml", resource, null, false, DEFAULT_CONFIG_IGNORE_LIST);
if (filename.equals(PLUGIN_YML)) {
YamlPropertySourceLoader propertySourceLoader = new YamlPropertySourceLoader();
this.propertySource = propertySourceLoader.load(GrailsNameUtils.getLogicalPropertyName(pluginClass.getSimpleName(), "GrailsPlugin") + "-" + PLUGIN_YML, resource, null, false, DEFAULT_CONFIG_IGNORE_LIST);
} else if (filename.equals(PLUGIN_GROOVY)) {
GroovyConfigPropertySourceLoader propertySourceLoader = new GroovyConfigPropertySourceLoader();
this.propertySource = propertySourceLoader.load(GrailsNameUtils.getLogicalPropertyName(pluginClass.getSimpleName(), "GrailsPlugin") + "-" + PLUGIN_GROOVY, resource, null, DEFAULT_CONFIG_IGNORE_LIST);
}
} catch (IOException e) {
LOG.warn("Error loading plugin.yml for plugin: " + pluginClass.getName() +": " + e.getMessage(), e);
LOG.warn("Error loading " + filename + " for plugin: " + pluginClass.getName() +": " + e.getMessage(), e);
}
}
}
Expand All @@ -113,15 +123,28 @@ public boolean isEnabled(String[] profiles) {
}

protected Resource readPluginConfiguration(Class<?> pluginClass) {
final URL urlToPluginYml = IOUtils.findResourceRelativeToClass(pluginClass, PLUGIN_YML_PATH);
Resource ymlResource = getConfigurationResource(pluginClass, PLUGIN_YML_PATH);
Resource groovyResource = getConfigurationResource(pluginClass, PLUGIN_GROOVY_PATH);

Boolean groovyResourceExists = groovyResource != null && groovyResource.exists();

Resource urlResource = urlToPluginYml != null ? new UrlResource(urlToPluginYml) : null;
if(urlResource != null && urlResource.exists()) {
return urlResource;
if(ymlResource != null && ymlResource.exists()) {
if (groovyResourceExists) {
throw new RuntimeException("A plugin may define a plugin.yml or a plugin.groovy, but not both");
}
return ymlResource;
}
if(groovyResourceExists) {
return groovyResource;
}
return null;
}

protected Resource getConfigurationResource(Class<?> pluginClass, String path) {
final URL urlToConfig = IOUtils.findResourceRelativeToClass(pluginClass, path);
return urlToConfig != null ? new UrlResource(urlToConfig) : null;
}

public String getFileSystemName() {
return getFileSystemShortName() + '-' + getVersion();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import grails.core.DefaultGrailsApplication
import org.grails.plugins.BinaryGrailsPlugin
import org.grails.plugins.BinaryGrailsPluginDescriptor
import org.springframework.core.io.ByteArrayResource
import org.springframework.core.io.FileSystemResource
import org.springframework.core.io.Resource

import spock.lang.Shared
import spock.lang.Specification

class BinaryPluginSpec extends Specification {

def "Test creation of a binary plugin"() {
given:
def str = '''
@Shared
String testBinary = '''
<plugin name='testBinary'>
<class>org.codehaus.groovy.grails.plugins.TestBinaryGrailsPlugin</class>
<resources>
Expand All @@ -21,10 +21,9 @@ class BinaryPluginSpec extends Specification {
</plugin>
'''

def xml = new XmlSlurper().parseText(str)

def "Test creation of a binary plugin"() {
when:
def descriptor = new BinaryGrailsPluginDescriptor(new ByteArrayResource(str.getBytes('UTF-8')), ['org.codehaus.groovy.grails.plugins.TestBinaryResource'])
def descriptor = new BinaryGrailsPluginDescriptor(new ByteArrayResource(testBinary.getBytes('UTF-8')), ['org.codehaus.groovy.grails.plugins.TestBinaryResource'])
def binaryPlugin = new BinaryGrailsPlugin(TestBinaryGrailsPlugin, descriptor, new DefaultGrailsApplication())

then:
Expand All @@ -36,20 +35,8 @@ class BinaryPluginSpec extends Specification {


def "Test load static resource from binary plugin"() {
given:
def str = '''
<plugin name='testBinary'>
<class>org.codehaus.groovy.grails.plugins.TestBinaryGrailsPlugin</class>
<resources>
<resource>org.codehaus.groovy.grails.plugins.TestBinaryResource</resource>
</resources>
</plugin>
'''

def xml = new XmlSlurper().parseText(str)

when:
def resource = new MockBinaryPluginResource(str.getBytes('UTF-8'))
def resource = new MockBinaryPluginResource(testBinary.getBytes('UTF-8'))
def descriptor = new BinaryGrailsPluginDescriptor(resource, ['org.codehaus.groovy.grails.plugins.TestBinaryResource'])
resource.relativesResources['static/css/main.css'] = new ByteArrayResource(''.bytes)
def binaryPlugin = new BinaryGrailsPlugin(TestBinaryGrailsPlugin, descriptor, new DefaultGrailsApplication())
Expand All @@ -63,6 +50,68 @@ class BinaryPluginSpec extends Specification {
then:
cssResource == null
}

def "Test plugin with both plugin.yml and plugin.groovy throws exception"() {
when:
def descriptor = new BinaryGrailsPluginDescriptor(new ByteArrayResource(testBinary.getBytes('UTF-8')), ['org.codehaus.groovy.grails.plugins.TestBinaryResource'])
MockConfigBinaryGrailsPlugin.YAML_EXISTS = true
MockConfigBinaryGrailsPlugin.GROOVY_EXISTS = true
new MockConfigBinaryGrailsPlugin(descriptor)

then:
thrown(RuntimeException)
}

def "Test plugin with only plugin.yml"() {
when:
def descriptor = new BinaryGrailsPluginDescriptor(new ByteArrayResource(testBinary.getBytes('UTF-8')), ['org.codehaus.groovy.grails.plugins.TestBinaryResource'])
MockConfigBinaryGrailsPlugin.YAML_EXISTS = true
MockConfigBinaryGrailsPlugin.GROOVY_EXISTS = false
def binaryPlugin = new MockConfigBinaryGrailsPlugin(descriptor)

then:
binaryPlugin.propertySource.getProperty('foo') == "bar"
}

def "Test plugin with only plugin.groovy"() {
when:
def descriptor = new BinaryGrailsPluginDescriptor(new ByteArrayResource(testBinary.getBytes('UTF-8')), ['org.codehaus.groovy.grails.plugins.TestBinaryResource'])
MockConfigBinaryGrailsPlugin.YAML_EXISTS = false
MockConfigBinaryGrailsPlugin.GROOVY_EXISTS = true
def binaryPlugin = new MockConfigBinaryGrailsPlugin(descriptor)

then:
binaryPlugin.propertySource.getProperty('bar') == "foo"
}

}

class MockConfigBinaryGrailsPlugin extends BinaryGrailsPlugin {
static Boolean YAML_EXISTS = false
static Boolean GROOVY_EXISTS = false

MockConfigBinaryGrailsPlugin(BinaryGrailsPluginDescriptor descriptor) {
super(TestBinaryGrailsPlugin, descriptor, new DefaultGrailsApplication())
}

protected Resource getConfigurationResource(Class<?> pluginClass, String path) {
String tempDir = System.getProperty("java.io.tmpdir")
if (YAML_EXISTS && path == PLUGIN_YML_PATH) {
File file = new File(tempDir, "plugin.yml")
file.write("foo: bar")
return new FileSystemResource(file)
}
if (GROOVY_EXISTS && path == PLUGIN_GROOVY_PATH) {
File file = new File(tempDir, "plugin.groovy")
file.write("bar = 'foo'")
return new FileSystemResource(file)
}
return null
}

public String getVersion() {
super.getVersion()
}
}

class TestBinaryGrailsPlugin {
Expand Down Expand Up @@ -91,3 +140,4 @@ class MyView extends Script {
return "Good"
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class GrailsPluginGradlePlugin extends GrailsGradlePlugin {
void apply(Project project) {
super.apply(project)

checkForConfigurationClash(project)

configureAstSources(project)

configureProjectNameAndVersionASTMetadata(project)
Expand Down Expand Up @@ -237,6 +239,14 @@ withConfig(configuration) {
}
}

protected void checkForConfigurationClash(Project project) {
File yamlConfig = new File(project.projectDir,"grails-app/conf/plugin.yml")
File groovyConfig = new File(project.projectDir,"grails-app/conf/plugin.groovy")
if (yamlConfig.exists() && groovyConfig.exists()) {
throw new RuntimeException("A plugin may define a plugin.yml or a plugin.groovy, but not both")
}
}

@CompileStatic
static class ExplodedDir implements PublishArtifact {
final String extension = ""
Expand Down

0 comments on commit 10f431f

Please sign in to comment.