Skip to content

Commit

Permalink
Project clean up
Browse files Browse the repository at this point in the history
* split sitemesh plugin & example application
* add tests for sitemesh example application
* fix API docs for classes not hosted in this project (see PageRenderer -> ApplicationContext)
* repackage org.sitemesh.grails.plugins to org.grails.plugins
* adopt grails-bom
* remove common-build usage
* doc cleanup
* update minimum grails version
* composite build switch
* simplified docs build
* adopt newer gradle features such as source jars, project.layout, moving away from ant, etc
* update for grails-gradle plugin features in 7.0
* remove unneeded documentation scope
  • Loading branch information
jdaugherty committed Jan 11, 2025
1 parent 2451e07 commit f804d85
Show file tree
Hide file tree
Showing 220 changed files with 593 additions and 1,313 deletions.
404 changes: 9 additions & 395 deletions build.gradle

Large diffs are not rendered by default.

77 changes: 77 additions & 0 deletions docs/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import grails.doc.gradle.PublishGuide

buildscript {
repositories {
mavenLocal()
maven { url "https://repo.grails.org/grails/core" }
}
dependencies {
classpath platform("org.grails:grails-bom:$grailsVersion")
classpath "org.grails:grails-docs"
}
}

version rootProject.version

apply plugin: 'groovy'

//TODO: PublishGuide should eventually ensure the build directory exists
tasks.register('docsBuild') {
doFirst {
project.layout.buildDirectory.get().asFile.mkdirs()
}

// Do not cache this task since the directory must exist if publishGuide is going to run
outputs.upToDateWhen { false }
}

tasks.register('publishGuide', PublishGuide) {
dependsOn 'docsBuild'

group = JavaBasePlugin.DOCUMENTATION_GROUP
description = 'Generate Guide'

targetDir = project.layout.buildDirectory.dir('docs').get().asFile
outputs.dir(targetDir) // ensure gradle understands what this task generates
sourceRepo = "https://github.com/grails/grails-gsp/edit/${githubBranch}/src/main/docs"
sourceDir = project.layout.projectDirectory.dir('src/main/docs').getAsFile()
inputs.dir(sourceDir) // ensure gradle understands what this task creates from
propertiesFiles = [rootProject.layout.projectDirectory.file('gradle.properties').asFile]
asciidoc = true
resourcesDir = project.file('src/main/docs/resources')
properties = [
'safe' : 'UNSAFE', // Make sure any asciidoc security is disabled
'version' : project.version,
'title' : 'Groovy Server Pages (GSP)',
'subtitle' : 'GSP (Groovy Server Pages) - A server-side view rendering technology based on Groovy',
// TODO: The javaee documentation has not been updated to jakarata
'javaee' : 'https://docs.oracle.com/javaee/7/api/',
'jakartaee' : 'https://jakarta.ee/specifications/platform/10/apidocs/',
'javase' : 'https://docs.oracle.com/en/java/javase/17/docs/api/index.html',
'groovyapi' : "https://docs.groovy-lang.org/$groovyVersion/html/gapi/",
'groovyjdk' : "https://docs.groovy-lang.org/$groovyVersion/html/groovy-jdk/",
'grailsapi' : "https://docs.grails.org/$grailsVersion/api/",
'grailsdocs' : "https://docs.grails.org/$grailsVersion/",
'gormapi' : 'http://gorm.grails.org/latest/api/',
'springapi' : 'https://docs.spring.io/spring/docs/current/javadoc-api/',
'commandLineRef': "https://docs.grails.org/$grailsVersion/ref/Command%20Line",
'controllersRef': "https://docs.grails.org/$grailsVersion/ref/Controllers"
] as Properties

doLast {
File destination = project.layout.buildDirectory.file("docs/guide/index.html").get().asFile
destination.delete()

project.layout.buildDirectory.file('docs/guide/single.html').get().asFile.renameTo(destination)
project.layout.buildDirectory.file('docs/index.html').get().asFile.text = '''
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<meta http-equiv="refresh" content="0; url=guide/index.html" />
</head>
</body>
</html>
'''
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@
<tr>
<td id="col1">
<div id="main" class="corner-all">

<div class="project">
<h1>${title.encodeAsHtml()}</h1>
<p></p>
Expand Down
8 changes: 8 additions & 0 deletions examples/sitemesh3/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# SiteMesh 3 Grails Plugin Example
Example using the SiteMesh 3 Grails Plugin on how to use [SiteMesh 3](https://github.com/sitemesh/sitemesh3)

## Want to See the Full Power for Sitemesh 3?
Check out using SiteMesh 3 layouts on GSP and JSP pages, error pages, specifying layouts in controllers, and even applying multiple layouts to the same view!

You can see a working example by running this plugin:
```./gradlew bootRun```
78 changes: 78 additions & 0 deletions examples/sitemesh3/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
buildscript {
repositories {
maven { url "https://repo.grails.org/grails/core" }
}
dependencies {
classpath platform("org.grails:grails-bom:$grailsVersion")
classpath "org.grails:grails-gradle-plugin"
}
}

plugins {
id "war"
id "com.bertramlabs.asset-pipeline" version "5.0.5"
}

apply plugin:"org.grails.grails-web"
apply plugin:"org.grails.grails-gsp"
apply plugin:"org.grails.grails-plugin"

version '0.0.1'
group 'org.sitemesh.grails.plugins.sitemesh3'

apply plugin:"org.grails.grails-web"
apply plugin:"org.grails.grails-gsp"

dependencies {
// for testing purposes
// implementation files('lib/sitemesh-3.1.0-SNAPSHOT.jar', 'lib/spring-boot-starter-sitemesh-3.1.0-SNAPSHOT-plain.jar')
console "org.grails:grails-console"

implementation "org.grails:grails-plugin-databinding"
implementation "org.grails:grails-plugin-i18n"
implementation "org.grails:grails-plugin-interceptors"
implementation "org.grails:grails-plugin-rest"
implementation "org.grails:grails-plugin-services"
implementation "org.grails:grails-plugin-url-mappings"
implementation "org.grails:grails-web-boot"
implementation project(':grails-plugin-gsp')
implementation project(':grails-plugin-sitemesh3')

runtimeOnly "com.bertramlabs.plugins:asset-pipeline-grails"
runtimeOnly "com.h2database:h2"
runtimeOnly "org.apache.tomcat:tomcat-jdbc"
runtimeOnly "org.fusesource.jansi:jansi"
runtimeOnly "org.grails.plugins:hibernate5"
runtimeOnly "org.grails.plugins:scaffolding"
runtimeOnly "org.grails:grails-core"
runtimeOnly "org.grails:grails-logging"
runtimeOnly "org.springframework.boot:spring-boot-autoconfigure"
runtimeOnly "org.springframework.boot:spring-boot-starter-actuator"
runtimeOnly "org.springframework.boot:spring-boot-starter-logging"
runtimeOnly "org.springframework.boot:spring-boot-starter-tomcat"
runtimeOnly "org.springframework.boot:spring-boot-starter-validation"

runtimeOnly "jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api:$jstlVersion"
runtimeOnly "org.glassfish.web:jakarta.servlet.jsp.jstl:$jstlVersion"
runtimeOnly 'org.apache.tomcat.embed:tomcat-embed-jasper:10.1.0' // jsp example

testImplementation 'org.grails:grails-gorm-testing-support'
testImplementation 'org.grails:grails-web-testing-support'
testImplementation 'org.spockframework:spock-core'
integrationTestImplementation testFixtures ("org.grails.plugins:geb")
}

tasks.withType(Test) {
useJUnitPlatform()
}

assets {
minifyJs = true
minifyCss = true
packagePlugin = true
}

bootRun {
String springProfilesActive = 'spring.profiles.active'
systemProperty springProfilesActive, System.getProperty(springProfilesActive)
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,17 @@
</g:else>
</g:if>
<g:else>
<ul class="errors">
<li>An error has occurred</li>
</ul>
<g:if test="${Throwable.isInstance(exception)}">
${(exception as Throwable).message}
</g:if>
<g:elseif test="${request.getAttribute('jakarta.servlet.error.exception')}">
${(request.getAttribute('jakarta.servlet.error.exception') as Throwable).message}
</g:elseif>
<g:else>
<ul class="errors">
<li>An error has occurred</li>
</ul>
</g:else>
</g:else>
</body>
</html>
File renamed without changes.
90 changes: 90 additions & 0 deletions examples/sitemesh3/src/integration-test/groovy/SitemeshSpec.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import geb.navigator.DefaultNavigator
import grails.plugin.geb.ContainerGebConfiguration
import grails.plugin.geb.ContainerGebSpec
import grails.testing.mixin.integration.Integration

@Integration
@ContainerGebConfiguration
class SitemeshSpec extends ContainerGebSpec {

void "forced layout"() {
when:
browser.go 'demo/index'

then:
def container = $('div.container')
container

container.getAttribute("innerHTML").trim() == '''<h1>SiteMesh Example Site: Layout from Controller Demo</h1>
Do you like BootStrap?
<footer>Note: this demo requires an internet connection for BootStrap to show up.</footer>'''
}

void "decorator chaining"() {
when:
browser.go 'demo/chaining'

then:
def container = $('div.container')
container

container.getAttribute("innerHTML").trim() == '''<h1>SiteMesh Example Site: Layout Chaining Demo</h1>
This is so cool.
<footer>Note: this demo requires an internet connection for BootStrap to show up.</footer>'''
}

void "jsp demo"() {
when:
browser.go 'demo/jsp'

then:
def container = $('div.container')
container

container.firstElement().getAttribute("innerHTML").trim() == '''<h1>SiteMesh Example Site: Hello World</h1>
<div id="content" role="main">
<div class="container">
<h1>Hello World, I am a JSP page!</h1>
</div>
</div>
<footer>Note: this demo requires an internet connection for BootStrap to show up.</footer>'''
}

void "text"() {
when:
browser.go 'demo/renderText'

then:
downloadText() == '''<p>Hello World</p>'''
}

void "Controller 500 Example"() {
when:
browser.go 'demo/exception'

then:
browser.driver.pageSource.contains('Whoops, why would you ever want to see an exception??')
}

void "View 500 Example"() {
when:
browser.go 'demo/viewException'

then:
browser.driver.pageSource.contains('Oh Man, this view sucks!')
}

void "404 Error"() {
when:
browser.go 'demo/404'

then:
browser.driver.pageSource.contains('Error: Page Not Found (404)')
}
}
26 changes: 9 additions & 17 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,27 +1,19 @@
title=Groovy Server Pages (GSP)
authors=Puneet Behl
projectVersion=7.0.0-M1
projectDesc=GSP (Groovy Server Pages) - A server-side view rendering technology based on Groovy
projectUrl=https://github.com/grails/grails-gsp
githubSlug=grails/grails-gsp
githubBranch=7.0.x
developers=Puneet Behl, Graeme Rocher
projectVersion=7.0.0-SNAPSHOT

# for docs
githubBranch = 7.0.x

commonsTextVersion=1.13.0
elApiVersion=6.0.1
grailsGradlePluginVersion=7.0.0-SNAPSHOT
grailsVersion=7.0.0-M1
grailsVersion=7.0.0-SNAPSHOT
groovyVersion=4.0.24
jspApiVersion=4.0.0
jstlVersion=3.0.1
servletApiVersion=6.0.0
sitemeshVersion=7.0.0-M1
controllersRef=https://docs.grails.org/latest/ref/Controllers
commandLineRef=https://docs.grails.org/latest/ref/Command%20Line
grailsDocsVersion=7.0.0-SNAPSHOT
testingSupportVersion=4.0.0-SNAPSHOT
junit-jupiter.version=5.8.0
sitemeshLibraryVersion=3.2.2

slf4jPreventExclusion=true

org.gradle.caching=true
org.gradle.parallel=true
org.gradle.daemon=true
org.gradle.jvmArgs=-Dfile.encoding=UTF-8 -Xmx1024M
30 changes: 30 additions & 0 deletions gradle/aggregate-groovydoc.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

tasks.register('cleanDocs', Delete) {
delete rootProject.layout.buildDirectory.dir('docs')
}

tasks.register('aggregateGroovydoc', Groovydoc) {
def groovyDocProjects = rootProject.subprojects.findAll { it.name != 'docs' && !it.name.startsWith('examples') }.findAll { it.file('src/main/groovy').exists() }
dependsOn = [tasks.named('cleanDocs')] + groovyDocProjects.collect { it.tasks.named('groovydoc') }

docTitle = "Groovy Server Pages (GSP) - ${project.name} - ${project.version}"
group = JavaBasePlugin.DOCUMENTATION_GROUP
description = 'Copies Groovy API Documentation for all supporting projects'
destinationDir = project.layout.buildDirectory.dir('docs/api').get().asFile
source = files(groovyDocProjects.collect { Project project -> project.files("src/main/groovy") })
classpath = files(groovyDocProjects.collect { Project project -> project.configurations.compileClasspath })
}

tasks.register('docs') {
group = JavaBasePlugin.DOCUMENTATION_GROUP
dependsOn = ['aggregateGroovydoc', 'docs:publishGuide']
finalizedBy 'copyGuide'
}

tasks.register('copyGuide', Copy) {
group = JavaBasePlugin.DOCUMENTATION_GROUP
from "${rootProject.allprojects.find { it.name == 'docs'}.projectDir}/build/docs"
includes = ['**']
into rootProject.layout.buildDirectory.dir('docs')
includeEmptyDirs = false
}
16 changes: 16 additions & 0 deletions gradle/java-config.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apply plugin: 'idea'
apply plugin: 'java-library'

compileJava.options.release = 17

java {
withSourcesJar()
withJavadocJar()
}

dependencies {
implementation platform("org.grails:grails-bom:$grailsVersion")
api "org.apache.groovy:groovy:$groovyVersion"
compileOnly "jakarta.servlet:jakarta.servlet-api"
compileOnly "jakarta.persistence:jakarta.persistence-api"
}
Loading

0 comments on commit f804d85

Please sign in to comment.