diff --git a/.idea/modules.xml b/.idea/modules.xml
index c8e2197a4e9..35a9784378c 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -9,6 +9,7 @@
+
diff --git a/.idea/modules/plugin-lang-ruby.iml b/.idea/modules/plugin-lang-ruby.iml
new file mode 100644
index 00000000000..9fc335d1585
--- /dev/null
+++ b/.idea/modules/plugin-lang-ruby.iml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/plugins/lang/ruby/build.gradle b/plugins/lang/ruby/build.gradle
new file mode 100644
index 00000000000..4ad215f83f1
--- /dev/null
+++ b/plugins/lang/ruby/build.gradle
@@ -0,0 +1,145 @@
+dependsOn(':elasticsearch')
+
+apply plugin: 'java'
+apply plugin: 'maven'
+
+archivesBaseName = "elasticsearch-lang-ruby"
+
+explodedDistDir = new File(distsDir, 'exploded')
+
+configurations.compile.transitive = true
+configurations.testCompile.transitive = true
+
+// no need to use the resource dir
+sourceSets.main.resources.srcDirs 'src/main/java'
+sourceSets.test.resources.srcDirs 'src/test/java'
+
+// add the source files to the dist jar
+//jar {
+// from sourceSets.main.allSource
+//}
+
+configurations {
+ dists
+ distLib {
+ visible = false
+ transitive = false
+ }
+}
+
+dependencies {
+ compile project(':elasticsearch')
+
+ compile('org.jruby:jruby-complete:1.5.3')
+ distLib('org.jruby:jruby-complete:1.5.3') { transitive = false }
+
+ testCompile project(':test-testng')
+ testCompile('org.testng:testng:5.10:jdk15') { transitive = false }
+ testCompile 'org.hamcrest:hamcrest-all:1.1'
+}
+
+test {
+ useTestNG()
+ jmvArgs = ["-ea", "-Xmx1024m"]
+ suiteName = project.name
+ listeners = ["org.elasticsearch.util.testng.Listeners"]
+ systemProperties["es.test.log.conf"] = System.getProperty("es.test.log.conf", "log4j-gradle.properties")
+}
+
+task explodedDist(dependsOn: [jar], description: 'Builds the plugin zip file') << {
+ [explodedDistDir]*.mkdirs()
+
+ copy {
+ from configurations.distLib
+ into explodedDistDir
+ }
+
+ // remove elasticsearch files (compile above adds the elasticsearch one)
+ ant.delete { fileset(dir: explodedDistDir, includes: "elasticsearch-*.jar") }
+
+ copy {
+ from libsDir
+ into explodedDistDir
+ }
+
+ ant.delete { fileset(dir: explodedDistDir, includes: "elasticsearch-*-javadoc.jar") }
+ ant.delete { fileset(dir: explodedDistDir, includes: "elasticsearch-*-sources.jar") }
+}
+
+task zip(type: Zip, dependsOn: ['explodedDist']) {
+ from(explodedDistDir) {
+ }
+}
+
+task release(dependsOn: [zip]) << {
+ ant.delete(dir: explodedDistDir)
+ copy {
+ from distsDir
+ into(new File(rootProject.distsDir, "plugins"))
+ }
+}
+
+configurations {
+ deployerJars
+}
+
+dependencies {
+ deployerJars "org.apache.maven.wagon:wagon-http:1.0-beta-2"
+}
+
+task sourcesJar(type: Jar, dependsOn: classes) {
+ classifier = 'sources'
+ from sourceSets.main.allSource
+}
+
+task javadocJar(type: Jar, dependsOn: javadoc) {
+ classifier = 'javadoc'
+ from javadoc.destinationDir
+}
+
+jar {
+// from sourceSets.main.allJava
+ manifest {
+ attributes("Implementation-Title": "ElasticSearch", "Implementation-Version": rootProject.version, "Implementation-Date": buildTimeStr)
+ }
+}
+
+
+artifacts {
+ archives sourcesJar
+ archives javadocJar
+}
+
+uploadArchives {
+ repositories.mavenDeployer {
+ configuration = configurations.deployerJars
+ repository(url: rootProject.mavenRepoUrl) {
+ authentication(userName: rootProject.mavenRepoUser, password: rootProject.mavenRepoPass)
+ }
+ snapshotRepository(url: rootProject.mavenSnapshotRepoUrl) {
+ authentication(userName: rootProject.mavenRepoUser, password: rootProject.mavenRepoPass)
+ }
+
+ pom.project {
+ inceptionYear '2009'
+ name 'elasticsearch-plugins-lang-ruby'
+ description 'Ruby Plugin for ElasticSearch'
+ licenses {
+ license {
+ name 'The Apache Software License, Version 2.0'
+ url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+ distribution 'repo'
+ }
+ }
+ scm {
+ connection 'git://github.com/elasticsearch/elasticsearch.git'
+ developerConnection 'git@github.com:elasticsearch/elasticsearch.git'
+ url 'http://github.com/elasticsearch/elasticsearch'
+ }
+ }
+
+ pom.whenConfigured {pom ->
+ pom.dependencies = pom.dependencies.findAll {dep -> dep.scope != 'test' } // removes the test scoped ones
+ }
+ }
+}
\ No newline at end of file
diff --git a/plugins/lang/ruby/src/main/java/es-plugin.properties b/plugins/lang/ruby/src/main/java/es-plugin.properties
new file mode 100644
index 00000000000..693f0d3bb4c
--- /dev/null
+++ b/plugins/lang/ruby/src/main/java/es-plugin.properties
@@ -0,0 +1 @@
+plugin=org.elasticsearch.plugin.ruby.RubyPlugin
diff --git a/plugins/lang/ruby/src/main/java/org/elasticsearch/plugin/ruby/RubyPlugin.java b/plugins/lang/ruby/src/main/java/org/elasticsearch/plugin/ruby/RubyPlugin.java
new file mode 100644
index 00000000000..ffd1a9ded82
--- /dev/null
+++ b/plugins/lang/ruby/src/main/java/org/elasticsearch/plugin/ruby/RubyPlugin.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to Elastic Search and Shay Banon under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. Elastic Search licenses this
+ * file to you 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.elasticsearch.plugin.ruby;
+
+import org.elasticsearch.common.inject.Module;
+import org.elasticsearch.plugins.AbstractPlugin;
+import org.elasticsearch.script.ScriptModule;
+
+/**
+ * @author kimchy (shay.banon)
+ */
+public class RubyPlugin extends AbstractPlugin {
+
+ @Override public String name() {
+ return "lang-ruby";
+ }
+
+ @Override public String description() {
+ return "Ruby plugin allowing to add javascript scripting support";
+ }
+
+ @Override public void processModule(Module module) {
+ if (module instanceof ScriptModule) {
+// ((ScriptModule) module).addScriptEngine(JavaScriptScriptEngineService.class);
+ }
+ }
+}
diff --git a/plugins/lang/ruby/src/main/java/org/elasticsearch/script/ruby/RubyScriptEngineService.java b/plugins/lang/ruby/src/main/java/org/elasticsearch/script/ruby/RubyScriptEngineService.java
new file mode 100644
index 00000000000..0158e416ab5
--- /dev/null
+++ b/plugins/lang/ruby/src/main/java/org/elasticsearch/script/ruby/RubyScriptEngineService.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to Elastic Search and Shay Banon under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. Elastic Search licenses this
+ * file to you 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.elasticsearch.script.ruby;
+
+import org.elasticsearch.common.component.AbstractComponent;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.script.ExecutableScript;
+import org.elasticsearch.script.ScriptEngineService;
+import org.jruby.embed.EmbedEvalUnit;
+import org.jruby.embed.ScriptingContainer;
+
+import java.util.Map;
+
+/**
+ * @author kimchy (shay.banon)
+ */
+// Need to figure out how to execute compiled scripts in the most optimized manner (passing paramters to them).
+public class RubyScriptEngineService extends AbstractComponent implements ScriptEngineService {
+
+ private final ScriptingContainer container;
+
+ @Inject public RubyScriptEngineService(Settings settings) {
+ super(settings);
+
+ this.container = new ScriptingContainer();
+ container.setClassLoader(settings.getClassLoader());
+ }
+
+ @Override public String[] types() {
+ return new String[]{"ruby"};
+ }
+
+ @Override public Object compile(String script) {
+ return container.parse(script);
+ }
+
+ @Override public ExecutableScript executable(Object compiledScript, Map vars) {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ @Override public Object execute(Object compiledScript, Map vars) {
+ EmbedEvalUnit unit = (EmbedEvalUnit) compiledScript;
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ @Override public void close() {
+ container.clear();
+ }
+}
diff --git a/settings.gradle b/settings.gradle
index 3c5a14b03eb..d122a1c63c6 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -15,6 +15,7 @@ include 'plugins-mapper-attachments'
include 'plugins-lang-groovy'
include 'plugins-lang-javascript'
+//include 'plugins-lang-ruby' #disabled for now ...
include 'plugins-transport-memcached'
include 'plugins-transport-thrift'