diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..0fc3716 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +build +out +*.iml +*.ipr +*.iws +.idea +.gradle diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..aad5725 --- /dev/null +++ b/README.md @@ -0,0 +1,54 @@ +# Gradle GAE plugin + +The plugin provides tasks for uploading, downloading, running and managing Google App Engine projects in any given +Gradle build. It extends the War plugin. + +## Usage + +To use the GAE plugin, include in your build script: + + apply plugin: 'gae' + +The plugin JAR and the App Engine tools SDK library need to be defined in the classpath of your build script. You can +either get the plugin from the GitHub download section or upload it to your local repository. The following code snippet +shows an example: + + buildscript { + repositories { + add(new org.apache.ivy.plugins.resolver.URLResolver()) { + name = "GitHub" + addArtifactPattern 'http://cloud.github.com/downloads/bmuschko/gradle-gae-plugin/[module]-[revision].[ext]' + } + mavenCentral() + } + + dependencies { + classpath 'com.google.appengine:appengine-tools-sdk:1.4.2' + classpath ':gradle-gae-plugin:0.1' + } + } + +*Note:* The plugin requires you to set the environment variable _APPENGINE_HOME_ or the system property _google.appengine.sdk_ +pointing to your current Google App Engine SDK installation. In case you have both variables set the system property takes +precedence over the environment variable. + +## Tasks + +The GAE plugin defines the following tasks: + +* `gaeRun`: Starts a local development server running your project code. +* `gaeEnhance`: Enhances DataNucleus classes by using byte-code manipulation to make your normal Java classes "persistable". +* `gaeUpload`: Uploads files for an application given the application's root directory. The application ID and version are taken from the appengine-web.xml file. +* `gaeRollback`: Undoes a partially completed update for the given application. +* `gaeUpdateIndexes`: Updates datastore indexes in App Engine to include newly added indexes. +* `gaeVacuumIndexes`: Deletes unused indexes in App Engine server. +* `gaeUpdateQueues`: Updates the task queue configuration (queue.xml) in App Engine. +* `gaeUpdateDos`: Updates the DoS protection configuration for the app, based on the dos.xml file. +* `gaeUpdateCron`: Updates the schedule task (cron) configuration for the app, based on the cron.xml file. +* `gaeCronInfo`: Verifies and prints the scheduled task (cron) configuration. +* `gaeLogs`: Retrieves log data for the application running on App Engine. +* `gaeVersion`: Prints detailed version information about the SDK, Java and the operating system. + +## Project layout + +The GAE plugin uses the same layout as the War plugin. \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100755 index 0000000..3d1df77 --- /dev/null +++ b/build.gradle @@ -0,0 +1,50 @@ +apply plugin: 'groovy' +apply plugin: 'idea' + +sourceCompatibility = 1.5 +targetCompatibility = 1.5 +version = '0.1' +ant.property(environment: 'env') + +if(!ant.properties['env.GRADLE_HOME']) { + throw new Exception('Please set $GRADLE_HOME') +} + +def gradleHomeDir = System.getenv().get('GRADLE_HOME') + +repositories { + mavenCentral() +} + +dependencies { + groovy 'org.codehaus.groovy:groovy:1.7.+' + compile gradleApi() + compile group: 'com.google.appengine', name: 'appengine-tools-sdk', version: '1.4.2' + testCompile "junit:junit:4.+" +} + +jar { + manifest { + attributes 'Implementation-Title': 'Gradle GAE plugin', + 'Implementation-Version': version, + 'Built-By': System.getProperty("user.name"), + 'Built-Date': new Date(), + 'Built-JDK': System.getProperty("java.version") + } +} + +ideaProject { + javaVersion = '1.6' + + withXml { provider -> + def node = provider.asNode() + + // Use GIT + def vcsConfig = node.component.find { it.'@name' == 'VcsDirectoryMappings' } + vcsConfig.mapping[0].'@vcs' = 'Git' + + // Set Gradle home + def gradleSettings = node.appendNode('component', [name: 'GradleSettings']) + gradleSettings.appendNode('option', [name: 'SDK_HOME', value: gradleHomeDir]) + } +} diff --git a/src/main/groovy/org/gradle/api/plugins/gae/GaePlugin.groovy b/src/main/groovy/org/gradle/api/plugins/gae/GaePlugin.groovy new file mode 100755 index 0000000..e5b6f02 --- /dev/null +++ b/src/main/groovy/org/gradle/api/plugins/gae/GaePlugin.groovy @@ -0,0 +1,168 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.gradle.api.plugins.gae + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.plugins.WarPlugin +import org.gradle.api.plugins.WarPluginConvention +import org.gradle.api.plugins.gae.task.GaeEnhanceTask +import org.gradle.api.plugins.gae.task.GaeRunTask +import org.gradle.api.plugins.gae.task.GaeWebAppDirTask +import org.gradle.api.plugins.gae.task.appcfg.* + +/** + *

A {@link Plugin} that provides tasks for uploading, running and managing of Google App Engine projects.

+ * + * @author Benjamin Muschko + */ +class GaePlugin implements Plugin { + static final String GAE_RUN = "gaeRun" + static final String GAE_ENHANCE = "gaeEnhance" + static final String GAE_UPLOAD = "gaeUpload" + static final String GAE_ROLLBACK = "gaeRollback" + static final String GAE_UPDATE_INDEXES = "gaeUpdateIndexes" + static final String GAE_VACUUM_INDEXES = "gaeVacuumIndexes" + static final String GAE_UPDATE_TASK_QUEUES = "gaeUpdateQueues" + static final String GAE_UPDATE_DOS = "gaeUpdateDos" + static final String GAE_UPDATE_CRON = "gaeUpdateCron" + static final String GAE_CRON_INFO = "gaeCronInfo" + static final String GAE_LOGS = "gaeLogs" + static final String GAE_VERSION = "gaeVersion" + + @Override + public void apply(Project project) { + project.plugins.apply(WarPlugin.class) + GaePluginConvention gaePluginConvention = new GaePluginConvention() + project.convention.plugins.appengine = gaePluginConvention + + configureWebAppDir(project) + configureEmail(project, gaePluginConvention) + configureGaeRun(project, gaePluginConvention) + configureGaeEnhance(project) + configureGaeUpload(project) + configureGaeRollback(project) + configureGaeUpdateIndexes(project) + configureGaeVacuumIndexes(project) + configureGaeUpdateTaskQueues(project) + configureGaeUpdateDoS(project) + configureGaeUpdateCron(project) + configureGaeCronInfo(project) + configureGaeDownloadLogs(project) + configureGaeVersion(project) + } + + private void configureWebAppDir(final Project project) { + project.tasks.withType(GaeWebAppDirTask.class).whenTaskAdded { GaeWebAppDirTask gaeWebAppDirTask -> + gaeWebAppDirTask.conventionMapping.map("webAppSourceDirectory") { getWarConvention(project).webAppDir } + } + } + + private void configureEmail(final Project project, GaePluginConvention gaePluginConvention) { + project.tasks.withType(GaeAppConfigTaskTemplate.class).whenTaskAdded { GaeAppConfigTaskTemplate gaeAppConfigTaskTemplate -> + gaeAppConfigTaskTemplate.conventionMapping.map("email") { gaePluginConvention.email } + gaeAppConfigTaskTemplate.conventionMapping.map("server") { gaePluginConvention.server } + gaeAppConfigTaskTemplate.conventionMapping.map("host") { gaePluginConvention.host } + gaeAppConfigTaskTemplate.conventionMapping.map("passIn") { gaePluginConvention.passIn } + gaeAppConfigTaskTemplate.conventionMapping.map("httpProxy") { gaePluginConvention.httpProxy } + gaeAppConfigTaskTemplate.conventionMapping.map("httpsProxy") { gaePluginConvention.httpsProxy } + } + } + + private void configureGaeRun(final Project project, GaePluginConvention gaePluginConvention) { + project.tasks.withType(GaeRunTask.class).whenTaskAdded { GaeRunTask gaeRunTask -> + gaeRunTask.conventionMapping.map("httpPort") { gaePluginConvention.httpPort } + } + + GaeRunTask gaeRunTask = project.tasks.add(GAE_RUN, GaeRunTask.class) + gaeRunTask.description = "Starts up a local App Engine development server." + gaeRunTask.group = WarPlugin.WEB_APP_GROUP + } + + private void configureGaeEnhance(final Project project) { + project.tasks.withType(GaeEnhanceTask.class).whenTaskAdded { GaeEnhanceTask gaeEnhanceTask -> + gaeEnhanceTask.conventionMapping.map("sourceDirectories") { project.sourceSets.main.allSource.sourceTrees.srcDirs.flatten() as Set } + } + + GaeEnhanceTask gaeEnhanceTask = project.tasks.add(GAE_ENHANCE, GaeEnhanceTask.class) + gaeEnhanceTask.description = "Enhances DataNucleus classes." + gaeEnhanceTask.group = "Compilation" + } + + private void configureGaeUpload(final Project project) { + GaeUploadTask gaeUploadTask = project.tasks.add(GAE_UPLOAD, GaeUploadTask.class) + gaeUploadTask.description = "Uploads your application to App Engine." + gaeUploadTask.group = WarPlugin.WEB_APP_GROUP + } + + private void configureGaeRollback(final Project project) { + GaeRollbackTask gaeRollbackTask = project.tasks.add(GAE_ROLLBACK, GaeRollbackTask.class) + gaeRollbackTask.description = "Undoes a partially completed update for the given application." + gaeRollbackTask.group = WarPlugin.WEB_APP_GROUP + } + + private void configureGaeUpdateIndexes(final Project project) { + GaeUpdateIndexesTask gaeUpdateIndexesTask = project.tasks.add(GAE_UPDATE_INDEXES, GaeUpdateIndexesTask.class) + gaeUpdateIndexesTask.description = "Updates indexes on App Engine." + gaeUpdateIndexesTask.group = WarPlugin.WEB_APP_GROUP + } + + private void configureGaeVacuumIndexes(final Project project) { + GaeVacuumIndexesTask gaeVacuumIndexesTask = project.tasks.add(GAE_VACUUM_INDEXES, GaeVacuumIndexesTask.class) + gaeVacuumIndexesTask.description = "Deletes unused indexes on App Engine." + gaeVacuumIndexesTask.group = WarPlugin.WEB_APP_GROUP + } + + private void configureGaeUpdateTaskQueues(final Project project) { + GaeUpdateQueuesTask gaeUpdateQueuesTask = project.tasks.add(GAE_UPDATE_TASK_QUEUES, GaeUpdateQueuesTask.class) + gaeUpdateQueuesTask.description = "Updates task queues on App Engine." + gaeUpdateQueuesTask.group = WarPlugin.WEB_APP_GROUP + } + + private void configureGaeUpdateDoS(final Project project) { + GaeUpdateDoSTask gaeUpdateDoSTask = project.tasks.add(GAE_UPDATE_DOS, GaeUpdateDoSTask.class) + gaeUpdateDoSTask.description = "Updates DoS protection configuration on App Engine." + gaeUpdateDoSTask.group = WarPlugin.WEB_APP_GROUP + } + + private void configureGaeUpdateCron(final Project project) { + GaeUpdateCronTask gaeUpdateCronTask = project.tasks.add(GAE_UPDATE_CRON, GaeUpdateCronTask.class) + gaeUpdateCronTask.description = "Updates scheduled tasks definition (known as cron jobs) on App Engine." + gaeUpdateCronTask.group = WarPlugin.WEB_APP_GROUP + } + + private void configureGaeCronInfo(final Project project) { + GaeCronInfoTask gaeCronInfoTask = project.tasks.add(GAE_CRON_INFO, GaeCronInfoTask.class) + gaeCronInfoTask.description = "Get cron information from App Engine." + gaeCronInfoTask.group = WarPlugin.WEB_APP_GROUP + } + + private void configureGaeDownloadLogs(final Project project) { + GaeDownloadLogsTask gaeDownloadLogsTask = project.tasks.add(GAE_LOGS, GaeDownloadLogsTask.class) + gaeDownloadLogsTask.description = "Download logs from App Engine." + gaeDownloadLogsTask.group = WarPlugin.WEB_APP_GROUP + } + + private void configureGaeVersion(final Project project) { + GaeVersionTask gaeVersionTask = project.tasks.add(GAE_VERSION, GaeVersionTask.class) + gaeVersionTask.description = "Prints detailed version information about the SDK, Java and the operating system." + gaeVersionTask.group = WarPlugin.WEB_APP_GROUP + } + + private WarPluginConvention getWarConvention(Project project) { + project.convention.getPlugin(WarPluginConvention.class) + } +} diff --git a/src/main/groovy/org/gradle/api/plugins/gae/GaePluginConvention.groovy b/src/main/groovy/org/gradle/api/plugins/gae/GaePluginConvention.groovy new file mode 100755 index 0000000..84caec7 --- /dev/null +++ b/src/main/groovy/org/gradle/api/plugins/gae/GaePluginConvention.groovy @@ -0,0 +1,36 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.gradle.api.plugins.gae + +/** + * Defines App Engine plugin convention. + * + * @author Benjamin Muschko + */ +class GaePluginConvention { + Integer httpPort = 8080 + String email + String server + String host + boolean passIn + String httpProxy + String httpsProxy + + def gae(Closure closure) { + closure.delegate = this + closure() + } +} diff --git a/src/main/groovy/org/gradle/api/plugins/gae/task/AbstractGaeTask.groovy b/src/main/groovy/org/gradle/api/plugins/gae/task/AbstractGaeTask.groovy new file mode 100755 index 0000000..56d19cb --- /dev/null +++ b/src/main/groovy/org/gradle/api/plugins/gae/task/AbstractGaeTask.groovy @@ -0,0 +1,90 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.gradle.api.plugins.gae.task + +import org.gradle.api.InvalidUserDataException +import org.gradle.api.internal.ConventionTask +import org.gradle.api.tasks.TaskAction +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +abstract class AbstractGaeTask extends ConventionTask { + static final Logger LOGGER = LoggerFactory.getLogger(AbstractGaeTask.class) + final String APPENGINE_HOME_ENV_PROP_KEY = "APPENGINE_HOME" + final String APPENGINE_SDK_ROOT_SYS_PROP_KEY = "appengine.sdk.root" + final String JAVA_CLASSPATH_SYS_PROP_KEY = "java.class.path" + + @TaskAction + protected void start() { + validateConfiguration() + executeTask() + } + + @Override + void validateConfiguration() { + validateAppEngineSdkRoot() + validateAppEngineToolsApiJar() + } + + private void validateAppEngineSdkRoot() { + setAppEngineSdkRoot() + def appEngineSdkRoot = System.getProperty(APPENGINE_SDK_ROOT_SYS_PROP_KEY) + + if(!appEngineSdkRoot) { + throw new InvalidUserDataException("""The App Engine SDK root was not set. Please make sure you set the environment + variable '${APPENGINE_HOME_ENV_PROP_KEY}' system property '${APPENGINE_SDK_ROOT_SYS_PROP_KEY}'!""") + } + else { + if(!new File(appEngineSdkRoot).isDirectory()) { + throw new InvalidUserDataException("Set App Engine SDK root directory does not exist: '${appEngineSdkRoot}'!") + } + } + + LOGGER.info "App Engine SDK root = ${appEngineSdkRoot}" + } + + private void setAppEngineSdkRoot() { + def appEngineSdkRoot = System.getProperty(APPENGINE_SDK_ROOT_SYS_PROP_KEY) + + if(!appEngineSdkRoot) { + def appEngineHomeEnvVariable = System.getenv(APPENGINE_HOME_ENV_PROP_KEY) + + if(appEngineHomeEnvVariable) { + System.setProperty APPENGINE_SDK_ROOT_SYS_PROP_KEY, appEngineHomeEnvVariable + } + } + } + + private void validateAppEngineToolsApiJar() { + def fileSeparator = System.getProperty("file.separator") + def pathSeparator = File.pathSeparator + def appEngineSdkRoot = System.getProperty(APPENGINE_SDK_ROOT_SYS_PROP_KEY) + def javaClasspath = System.getProperty(JAVA_CLASSPATH_SYS_PROP_KEY) + def appEngineToolsApiJar = "${appEngineSdkRoot}${fileSeparator}lib${fileSeparator}appengine-tools-api.jar" + + if(!new File(appEngineSdkRoot).exists()) { + throw new InvalidUserDataException("Required library 'appengine-tools-api.jar' could not be found in specified path: '${appEngineToolsApiJar}'!") + } + + if(!javaClasspath.contains(appEngineToolsApiJar)) { + System.setProperty JAVA_CLASSPATH_SYS_PROP_KEY, "${javaClasspath}${pathSeparator}${appEngineToolsApiJar}" + } + + LOGGER.info "Java classpath = ${System.getProperty('java.class.path')}" + } + + abstract void executeTask() +} diff --git a/src/main/groovy/org/gradle/api/plugins/gae/task/GaeEnhanceTask.groovy b/src/main/groovy/org/gradle/api/plugins/gae/task/GaeEnhanceTask.groovy new file mode 100644 index 0000000..b1dba18 --- /dev/null +++ b/src/main/groovy/org/gradle/api/plugins/gae/task/GaeEnhanceTask.groovy @@ -0,0 +1,90 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.gradle.api.plugins.gae.task + +import com.google.appengine.tools.enhancer.EnhancerTask +import org.apache.tools.ant.Project +import org.apache.tools.ant.types.FileSet +import org.gradle.api.GradleException +import org.gradle.api.tasks.InputFiles +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +/** + * Google App Engine task enhancing DataNucleus classes. + * + * @see Documentation + * @author Benjamin Muschko + */ +class GaeEnhanceTask extends GaeWebAppDirTask { + static final Logger logger = LoggerFactory.getLogger(GaeEnhanceTask.class) + private Set sourceDirectories + + @Override + void executeTask() { + enhanceClasses() + } + + private void enhanceClasses() { + try { + logger.info "Enhancing DataNucleus classes..." + + def enhancerTask = new EnhancerTask() + enhancerTask.setEnhancerName "Gradle GAE plugin enhancer" + enhancerTask.setProject createProject() + + getSourceDirectories().each { sourceDir -> + if(sourceDir.exists()) { + logger.info "Adding source dir '$sourceDir' for enhancement process." + def fileSet = new FileSet() + fileSet.setDir(sourceDir) + enhancerTask.addFileSet(fileSet) + } + else { + logger.debug "Available source directory '$sourceDir' does not exist. It will not be used for the enhancement process." + } + } + + enhancerTask.execute() + } + catch(Exception e) { + throw new GradleException("An error occurred enhancing DataNucleus classes.", e) + } + finally { + logger.info "Finished enhancing DataNucleus classes." + } + } + + private Project createProject() { + def project = new Project() + + project.with { + setName "GAE project" + init() + } + + project + } + + @InputFiles + public Set getSourceDirectories() { + sourceDirectories + } + + public void setSourceDirectories(Set sourceDirectories) { + this.sourceDirectories = sourceDirectories + } +} diff --git a/src/main/groovy/org/gradle/api/plugins/gae/task/GaeRunTask.groovy b/src/main/groovy/org/gradle/api/plugins/gae/task/GaeRunTask.groovy new file mode 100755 index 0000000..774c7de --- /dev/null +++ b/src/main/groovy/org/gradle/api/plugins/gae/task/GaeRunTask.groovy @@ -0,0 +1,61 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.gradle.api.plugins.gae.task + +import com.google.appengine.tools.KickStart +import org.gradle.api.GradleException +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +/** + * Google App Engine task starting up a local development server. + * + * @see Documentation + * @author Benjamin Muschko + */ +class GaeRunTask extends GaeWebAppDirTask { + static final Logger logger = LoggerFactory.getLogger(GaeRunTask.class) + private Integer httpPort + + @Override + void executeTask() { + startLocalDevelopmentServer() + } + + void startLocalDevelopmentServer() { + try { + logger.info "Starting local development server..." + + String[] params = ["com.google.appengine.tools.development.DevAppServerMain", "--port=" + getHttpPort(), getWebAppSourceDirectory().getCanonicalPath()] as String[] + KickStart.main(params) + } + catch(Exception e) { + throw new GradleException("An error occurred starting the local development server.", e) + } + finally { + logger.info "Local development server exiting." + } + } + + public Integer getHttpPort() { + httpPort + } + + public void setHttpPort(Integer httpPort) { + this.httpPort = httpPort + } +} + diff --git a/src/main/groovy/org/gradle/api/plugins/gae/task/GaeWebAppDirTask.groovy b/src/main/groovy/org/gradle/api/plugins/gae/task/GaeWebAppDirTask.groovy new file mode 100755 index 0000000..05c156d --- /dev/null +++ b/src/main/groovy/org/gradle/api/plugins/gae/task/GaeWebAppDirTask.groovy @@ -0,0 +1,59 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.gradle.api.plugins.gae.task + +import org.gradle.api.InvalidUserDataException +import org.gradle.api.tasks.InputDirectory +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +/** + * Abstract Google App Engine task that requires setting the web application dir. + * + * @author Benjamin Muschko + */ +abstract class GaeWebAppDirTask extends AbstractGaeTask { + static final Logger logger = LoggerFactory.getLogger(GaeWebAppDirTask.class) + private File webAppSourceDirectory + + @Override + void validateConfiguration(){ + super.validateConfiguration() + + try { + if(!getWebAppSourceDirectory() || !getWebAppSourceDirectory().exists()) { + throw new InvalidUserDataException("Webapp source directory " + + (getWebAppSourceDirectory() == null ? "null" : getWebAppSourceDirectory().getCanonicalPath()) + + " does not exist") + } + else { + logger.info "Webapp source directory = ${getWebAppSourceDirectory().getCanonicalPath()}" + } + } + catch(IOException e) { + throw new InvalidUserDataException("Webapp source directory does not exist", e) + } + } + + @InputDirectory + public File getWebAppSourceDirectory() { + webAppSourceDirectory + } + + public void setWebAppSourceDirectory(File webAppSourceDirectory) { + this.webAppSourceDirectory = webAppSourceDirectory + } +} diff --git a/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeAppConfigTaskTemplate.groovy b/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeAppConfigTaskTemplate.groovy new file mode 100755 index 0000000..73330d1 --- /dev/null +++ b/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeAppConfigTaskTemplate.groovy @@ -0,0 +1,137 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.gradle.api.plugins.gae.task.appcfg + +import com.google.appengine.tools.admin.AppCfg +import org.gradle.api.GradleException +import org.gradle.api.plugins.gae.task.GaeWebAppDirTask +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +/** + * Abstract Google App Engine task used for application configuration. + * + * @author Benjamin Muschko + */ +abstract class GaeAppConfigTaskTemplate extends GaeWebAppDirTask { + static final Logger LOGGER = LoggerFactory.getLogger(GaeAppConfigTaskTemplate.class) + private String email + private String server + private String host + private boolean passIn + private String httpProxy + private String httpsProxy + + @Override + void executeTask() { + try { + LOGGER.info startLogMessage() + + def params = [] + addCommonParams(params) + params.addAll getParams() + LOGGER.info "Using params = $params" + + AppCfg.main(params as String[]) + } + catch(Exception e) { + throw new GradleException(errorLogMessage(), e) + } + finally { + LOGGER.info finishLogMessage() + } + } + + private void addCommonParams(params) { + LOGGER.info "PASS IN : ${getPassIn()}" + if(getEmail()) { + params << "--email=${getEmail()}" + } + + if(getServer()) { + params << "--server=${getServer()}" + } + + if(getHost()) { + params << "--host=${getHost()}" + } + + if(getPassIn()) { + params << "--passin" + } + + if(getHttpProxy()) { + params << "--proxy=${getHttpProxy()}" + } + + if(getHttpsProxy()) { + params << "--proxy_https=${getHttpsProxy()}" + } + } + + public String getEmail() { + email + } + + public void setEmail(String email) { + this.email = email + } + + public String getServer() { + server + } + + public void setServer(String server) { + this.server = server + } + + public String getHost() { + host + } + + public void setHost(String host) { + this.host = host + } + + public boolean getPassIn() { + passIn + } + + public void setPassIn(boolean passIn) { + this.passIn = passIn + } + + public String getHttpProxy() { + httpProxy + } + + public void setHttpProxy(String httpProxy) { + this.httpProxy = httpProxy + } + + public String getHttpsProxy() { + httpsProxy + } + + public void setHttpsProxy(String httpsProxy) { + this.httpsProxy = httpsProxy + } + + abstract String startLogMessage() + abstract String errorLogMessage() + abstract String finishLogMessage() + abstract List getParams() +} diff --git a/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeCronInfoTask.groovy b/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeCronInfoTask.groovy new file mode 100755 index 0000000..5fd0721 --- /dev/null +++ b/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeCronInfoTask.groovy @@ -0,0 +1,46 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.gradle.api.plugins.gae.task.appcfg + +/** + * Google App Engine task pulling cron information from the server. + * + * @see Documentation + * @author Benjamin Muschko + */ +class GaeCronInfoTask extends GaeAppConfigTaskTemplate { + final String COMMAND = "cron_info" + + @Override + String startLogMessage() { + "Starting getting cron information..." + } + + @Override + String errorLogMessage() { + "An error occurred getting cron information." + } + + @Override + String finishLogMessage() { + "Finished getting cron information." + } + + @Override + List getParams() { + [COMMAND, getWebAppSourceDirectory().getCanonicalPath()] + } +} \ No newline at end of file diff --git a/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeDownloadLogsTask.groovy b/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeDownloadLogsTask.groovy new file mode 100755 index 0000000..a86452b --- /dev/null +++ b/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeDownloadLogsTask.groovy @@ -0,0 +1,46 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.gradle.api.plugins.gae.task.appcfg + +/** + * Google App Engine task downloading application logs from the server. + * + * @see Documentation + * @author Benjamin Muschko + */ +class GaeDownloadLogsTask extends GaeAppConfigTaskTemplate { + final String COMMAND = "request_logs" + + @Override + String startLogMessage() { + "Starting downloading logs process..." + } + + @Override + String errorLogMessage() { + "An error occurred downloading logs from App Engine." + } + + @Override + String finishLogMessage() { + "Finished downloading logs process." + } + + @Override + List getParams() { + [COMMAND, getWebAppSourceDirectory().getCanonicalPath(), "somefile.txt"] + } +} diff --git a/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeRollbackTask.groovy b/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeRollbackTask.groovy new file mode 100644 index 0000000..1c97e29 --- /dev/null +++ b/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeRollbackTask.groovy @@ -0,0 +1,45 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.gradle.api.plugins.gae.task.appcfg + +/** + * Google App Engine task undoing a partially completed update for the given application. + * + * @author Benjamin Muschko + */ +class GaeRollbackTask extends GaeAppConfigTaskTemplate { + final String COMMAND = "rollback" + + @Override + String startLogMessage() { + "Starting to rollback update..." + } + + @Override + String errorLogMessage() { + "An error occurred rolling back update." + } + + @Override + String finishLogMessage() { + "Finished rolling back update." + } + + @Override + List getParams() { + [COMMAND, getWebAppSourceDirectory().getCanonicalPath()] + } +} \ No newline at end of file diff --git a/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeUpdateCronTask.groovy b/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeUpdateCronTask.groovy new file mode 100755 index 0000000..d9f2203 --- /dev/null +++ b/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeUpdateCronTask.groovy @@ -0,0 +1,46 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.gradle.api.plugins.gae.task.appcfg + +/** + * Google App Engine task updating cron definition on the server. + * + * @see Documentation + * @author Benjamin Muschko + */ +class GaeUpdateCronTask extends GaeAppConfigTaskTemplate { + final String COMMAND = "update_cron" + + @Override + String startLogMessage() { + "Starting updating scheduled tasks..." + } + + @Override + String errorLogMessage() { + "An error occurred updating scheduled tasks." + } + + @Override + String finishLogMessage() { + "Finished updating scheduled tasks." + } + + @Override + List getParams() { + [COMMAND, getWebAppSourceDirectory().getCanonicalPath()] + } +} \ No newline at end of file diff --git a/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeUpdateDoSTask.groovy b/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeUpdateDoSTask.groovy new file mode 100755 index 0000000..56d1be9 --- /dev/null +++ b/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeUpdateDoSTask.groovy @@ -0,0 +1,46 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.gradle.api.plugins.gae.task.appcfg + +/** + * Google App Engine task updating DoS protection configuration on the server. + * + * @see Documentation + * @author Benjamin Muschko + */ +class GaeUpdateDoSTask extends GaeAppConfigTaskTemplate { + final String COMMAND = "update_cron" + + @Override + String startLogMessage() { + "Starting updating DoS protection configuration..." + } + + @Override + String errorLogMessage() { + "An error occurred updating DoS protection configuration." + } + + @Override + String finishLogMessage() { + "Finished updating DoS protection configuration." + } + + @Override + List getParams() { + [COMMAND, getWebAppSourceDirectory().getCanonicalPath()] + } +} \ No newline at end of file diff --git a/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeUpdateIndexesTask.groovy b/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeUpdateIndexesTask.groovy new file mode 100755 index 0000000..7b20c26 --- /dev/null +++ b/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeUpdateIndexesTask.groovy @@ -0,0 +1,46 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.gradle.api.plugins.gae.task.appcfg + +/** + * Google App Engine task updating indexes on the server. + * + * @see Documentation + * @author Benjamin Muschko + */ +class GaeUpdateIndexesTask extends GaeAppConfigTaskTemplate { + final String COMMAND = "update_indexes" + + @Override + String startLogMessage() { + "Starting updating indexes..." + } + + @Override + String errorLogMessage() { + "An error occurred updating indexes." + } + + @Override + String finishLogMessage() { + "Finished updating indexes." + } + + @Override + List getParams() { + [COMMAND, getWebAppSourceDirectory().getCanonicalPath()] + } +} diff --git a/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeUpdateQueuesTask.groovy b/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeUpdateQueuesTask.groovy new file mode 100755 index 0000000..597b730 --- /dev/null +++ b/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeUpdateQueuesTask.groovy @@ -0,0 +1,47 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.gradle.api.plugins.gae.task.appcfg + +/** + * Google App Engine task updating task queue configuration on the server. + * + * @see Documentation + * @author Benjamin Muschko + */ +class GaeUpdateQueuesTask extends GaeAppConfigTaskTemplate { + final String COMMAND = "update_queues" + + @Override + String startLogMessage() { + "Starting updating task queues..." + } + + @Override + String errorLogMessage() { + "An error occurred updating task queues." + } + + @Override + String finishLogMessage() { + "Finished updating task queues." + } + + @Override + List getParams() { + [COMMAND, getWebAppSourceDirectory().getCanonicalPath()] + } +} + diff --git a/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeUploadTask.groovy b/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeUploadTask.groovy new file mode 100755 index 0000000..4850ef6 --- /dev/null +++ b/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeUploadTask.groovy @@ -0,0 +1,46 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.gradle.api.plugins.gae.task.appcfg + +/** + * Google App Engine task uploading your application to the server. + * + * @see Documentation + * @author Benjamin Muschko + */ +class GaeUploadTask extends GaeAppConfigTaskTemplate { + final String COMMAND = "update" + + @Override + String startLogMessage() { + "Starting upload process..." + } + + @Override + String errorLogMessage() { + "An error occurred uploading the application to App Engine." + } + + @Override + String finishLogMessage() { + "Finished uploading process." + } + + @Override + List getParams() { + [COMMAND, getWebAppSourceDirectory().getCanonicalPath()] + } +} diff --git a/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeVacuumIndexesTask.groovy b/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeVacuumIndexesTask.groovy new file mode 100755 index 0000000..93c377b --- /dev/null +++ b/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeVacuumIndexesTask.groovy @@ -0,0 +1,46 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.gradle.api.plugins.gae.task.appcfg + +/** + * Google App Engine task deleting unused indexes on the server. + * + * @see Documentation + * @author Benjamin Muschko + */ +class GaeVacuumIndexesTask extends GaeAppConfigTaskTemplate { + final String COMMAND = "vacuum_indexes" + + @Override + String startLogMessage() { + "Starting deleting unused indexes..." + } + + @Override + String errorLogMessage() { + "An error occurred deleting unused indexes." + } + + @Override + String finishLogMessage() { + "Finished deleting unused indexes." + } + + @Override + List getParams() { + [COMMAND, getWebAppSourceDirectory().getCanonicalPath()] + } +} diff --git a/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeVersionTask.groovy b/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeVersionTask.groovy new file mode 100644 index 0000000..78daf0c --- /dev/null +++ b/src/main/groovy/org/gradle/api/plugins/gae/task/appcfg/GaeVersionTask.groovy @@ -0,0 +1,45 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.gradle.api.plugins.gae.task.appcfg + +/** + * Google App Engine task printing detailed version information about the SDK, Java and the operating system. + * + * @author Benjamin Muschko + */ +class GaeVersionTask extends GaeAppConfigTaskTemplate { + final String COMMAND = "version" + + @Override + String startLogMessage() { + "Starting to get version information..." + } + + @Override + String errorLogMessage() { + "An error occurred getting version information." + } + + @Override + String finishLogMessage() { + "Finished to get version information." + } + + @Override + List getParams() { + [COMMAND] + } +} diff --git a/src/main/resources/META-INF/gradle-plugins/gae.properties b/src/main/resources/META-INF/gradle-plugins/gae.properties new file mode 100755 index 0000000..bed522e --- /dev/null +++ b/src/main/resources/META-INF/gradle-plugins/gae.properties @@ -0,0 +1,16 @@ +# +# Copyright 2011 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +implementation-class=org.gradle.api.plugins.gae.GaePlugin