Giter Site home page Giter Site logo

jruby-gradle / jruby-gradle-plugin Goto Github PK

View Code? Open in Web Editor NEW
92.0 11.0 41.0 2.05 MB

A Gradle plugin for working with JRuby projects for fun and profit. Mostly profit.

Home Page: http://jruby-gradle.org

License: Other

Ruby 2.26% Groovy 91.78% Shell 0.09% Java 5.86%

jruby-gradle-plugin's Introduction

JRuby/Gradle plugins

Build Status
Join%20Chat
Figure 1. Gitter

You can also join us on the JRuby/Gradle mailing list

JRuby/Gradle brings the power and flexibility of Gradle to the Ruby ecosystem! With JRuby/Gradle you can specify your Java and Ruby dependencies together, build jar files, run tests, and much more!.

Use of this plugin replaces the need for Rake, Bundler and Warbler.

Note
JRuby/Gradle 2.1 relies on JRuby 9.4 and later.
JRuby/Gradle 2.0 relies on JRuby 9.x and later.

This repository contains the:

  • core (in core-plugin/): Rubygems proxy.

  • base (in base-plugin/): dependency resolution, executing Ruby, etc.

  • jar (in jar-plugin/): packaging JRuby-based .jar files

  • war (in war-plugin/): packaging JRuby-based .war files

Note
More documentation can be found on jruby-gradle.org
Note
The plugins are published at plugins.gradle.org.

jruby-gradle-plugin's People

Contributors

aalmiray avatar abelsromero avatar bbradbury avatar donv avatar earthcitizen avatar ggrossetie avatar joankaradimov avatar lptr avatar michaelwoodson avatar mkristian avatar mojavelinux avatar msnexploder avatar nilbus avatar raelik avatar rtyler avatar stevencregan avatar uwekubosch avatar ysb33r avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jruby-gradle-plugin's Issues

Add project.jrubyexec as a project extension

This will allow for jruby scripts to be executed within another task, without creating a dependency on additional tasks. This is similar to project.exec and project.javaexec. This will also slight differ in behaviour to `JRubyExec`` as task:

  • The version of jruby-complete will be strictly tied to to jruby.defaultVersion. Therefore trying to set jrubyVersion in the jrubyexec closure will cause a failure
  • GEMs and additional JARs will only be taken from the jrubyExec configuration and therefore it will not possible to supply a configuration parameter to the jrubyexec closure.
  • GEMs will be installed to jruby.gemInstallDir. Existing gems will not be overwritten.

As with JRubyExec, args, setArgs and main are illegal within the jrubyexec closure. All other javaexec and JRubyExec methods should work.

NOTE: Once this is done, it might be the time to explore how JRubyScriptingContainer could be used as per ISSUE #21.

Remove dependency on system JRuby

A key for Gradle builds is to be as independent on local installations of tools as possible. (With native builds that is a different matter, but let's try to stick to the first objective)

JRubyPlugin.gemInstall still relies on ruby to be installed locally. I guess it would be better if it can call jruby -S gem install instead. The jruby instance will come from the jruby-complete.jar as set in the build script.

Prototype toll-free Rake integration

(Will require #25)

Just brain dumping some ideas right now:

If build.gradle had a method such as enableRake() that could load a Rakefile from the $CWD and provide wrapper tasks for all the Rake tasks defined.

For example: rake build could turn into the gradle task rakeBuild. rake assets:clean could turn into rakeAssetsClean

Another option would be to just create a task that would create a ScriptingContainer to execute Rake inside of and let Rake handle everything underneath.

Gem installation can prompt for stdin causing an infinite loop

In my particular case having two gems which install the same binstub:

Overwrite the executable? [yN]  protobuffy's executable "protoc-gen-ruby" conflicts with protobuf
Overwrite the executable? [yN]  protobuffy's executable "protoc-gen-ruby" conflicts with protobuf
Overwrite the executable? [yN]  protobuffy's executable "protoc-gen-ruby" conflicts with protobuf
Overwrite the executable? [yN]  protobuffy's executable "protoc-gen-ruby" conflicts with protobuf
Overwrite the executable?
> Building 0% > :jrubyPrepareGems

Tests fail if there are any connectivity problems

Looks like the new tests that came along with #16. I'm hoping @ysb33r can take a whack at this.

com.lookout.jruby.JRubyExecSpec > Running a script that requires a gem FAILED
    org.gradle.api.artifacts.ResolveException: Could not resolve all dependencies for configuration ':jrubyExec'.
        at org.gradle.api.internal.artifacts.ivyservice.ErrorHandlingArtifactDependencyResolver.wrapException(ErrorHandlingArtifactDependencyResolver.java:61)
        at org.gradle.api.internal.artifacts.ivyservice.ErrorHandlingArtifactDependencyResolver.access$000(ErrorHandlingArtifactDependencyResolver.java:35)
        at org.gradle.api.internal.artifacts.ivyservice.ErrorHandlingArtifactDependencyResolver$BrokenResolvedConfiguration.rethrowFailure(ErrorHandlingArtifactDependencyResolver.java:237)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration$ConfigurationFileCollection.getFiles(DefaultConfiguration.java:428)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.getFiles(DefaultConfiguration.java:202)
        at groovy.lang.MetaBeanProperty.getProperty(MetaBeanProperty.java:57)
        at org.gradle.api.internal.BeanDynamicObject$MetaClassAdapter.getProperty(BeanDynamicObject.java:153)
        at org.gradle.api.internal.BeanDynamicObject.getProperty(BeanDynamicObject.java:107)
        at org.gradle.api.internal.CompositeDynamicObject.getProperty(CompositeDynamicObject.java:78)
        at com.lookout.jruby.JRubyExec.exec_closure3(JRubyExec.groovy:142)
        at groovy.lang.Closure.call(Closure.java:423)
        at groovy.lang.Closure.call(Closure.java:439)
        at com.lookout.jruby.JRubyExec.exec(JRubyExec.groovy:140)
        at com.lookout.jruby.JRubyExecSpec.Running a script that requires a gem(JRubyExecSpec.groovy:185)

        Caused by:
        org.gradle.api.internal.artifacts.ivyservice.ivyresolve.ArtifactResolveException: Could not determine artifacts for component 'rubygems:credit_card_validator:1.2.0'
            at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.ErrorHandlingArtifactResolver.resolveModuleArtifacts(ErrorHandlingArtifactResolver.java:42)
            at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.DependencyGraphBuilder$ConfigurationNode.getArtifacts(DependencyGraphBuilder.java:632)
            at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.ResolvedConfigurationDependencyGraphVisitor.getArtifacts(ResolvedConfigurationDependencyGraphVisitor.java:83)
            at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.ResolvedConfigurationDependencyGraphVisitor.attachToParents(ResolvedConfigurationDependencyGraphVisitor.java:72)
            at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.ResolvedConfigurationDependencyGraphVisitor.visitEdge(ResolvedConfigurationDependencyGraphVisitor.java:64)
            at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.CompositeDependencyGraphVisitor.visitEdge(CompositeDependencyGraphVisitor.java:43)
            at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.DependencyGraphBuilder.assembleResult(DependencyGraphBuilder.java:175)
            at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.DependencyGraphBuilder.resolveDependencyGraph(DependencyGraphBuilder.java:84)
            at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.DependencyGraphBuilder.resolve(DependencyGraphBuilder.java:74)
            at org.gradle.api.internal.artifacts.ivyservice.resolveengine.DefaultDependencyResolver$1.execute(DefaultDependencyResolver.java:120)
            at org.gradle.api.internal.artifacts.ivyservice.resolveengine.DefaultDependencyResolver$1.execute(DefaultDependencyResolver.java:86)
            at org.gradle.internal.Transformers$3.transform(Transformers.java:131)
            at org.gradle.api.internal.artifacts.ivyservice.DefaultIvyContextManager.withIvy(DefaultIvyContextManager.java:61)
            at org.gradle.api.internal.artifacts.ivyservice.DefaultIvyContextManager.withIvy(DefaultIvyContextManager.java:39)
            at org.gradle.api.internal.artifacts.ivyservice.resolveengine.DefaultDependencyResolver.resolve(DefaultDependencyResolver.java:86)
            at org.gradle.api.internal.artifacts.ivyservice.CacheLockingArtifactDependencyResolver$1.run(CacheLockingArtifactDependencyResolver.java:42)
            at org.gradle.testfixtures.internal.InMemoryCacheFactory$InMemoryCache.useCache(InMemoryCacheFactory.java:78)
            at org.gradle.api.internal.artifacts.ivyservice.DefaultCacheLockingManager.useCache(DefaultCacheLockingManager.java:63)
            at org.gradle.api.internal.artifacts.ivyservice.CacheLockingArtifactDependencyResolver.resolve(CacheLockingArtifactDependencyResolver.java:40)
            at org.gradle.api.internal.artifacts.ivyservice.SelfResolvingDependencyResolver.resolve(SelfResolvingDependencyResolver.java:45)
            at org.gradle.api.internal.artifacts.ivyservice.ShortcircuitEmptyConfigsArtifactDependencyResolver.resolve(ShortcircuitEmptyConfigsArtifactDependencyResolver.java:55)
            at org.gradle.api.internal.artifacts.ivyservice.ErrorHandlingArtifactDependencyResolver.resolve(ErrorHandlingArtifactDependencyResolver.java:47)
            at org.gradle.api.internal.artifacts.ivyservice.DefaultConfigurationResolver.resolve(DefaultConfigurationResolver.java:46)
            at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.resolveNow(DefaultConfiguration.java:240)
            at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.getResolvedConfiguration(DefaultConfiguration.java:230)
            at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration$ConfigurationFileCollection.getFiles(DefaultConfiguration.java:426)
            ... 10 more

            Caused by:
            org.gradle.internal.resource.transport.http.HttpRequestException: Could not HEAD 'http://rubygems-proxy.torquebox.org/releases/rubygems/credit_card_validator/1.2.0/credit_card_validator-1.2.0.gem'.
                at org.gradle.internal.resource.transport.http.HttpClientHelper.performRequest(HttpClientHelper.java:80)
                at org.gradle.internal.resource.transport.http.HttpClientHelper.performRawHead(HttpClientHelper.java:58)
                at org.gradle.internal.resource.transport.http.HttpClientHelper.performHead(HttpClientHelper.java:62)
                at org.gradle.internal.resource.transport.http.HttpResourceAccessor.getMetaData(HttpResourceAccessor.java:87)
                at org.gradle.internal.resource.transport.DefaultExternalResourceRepository.getResourceMetaData(DefaultExternalResourceRepository.java:60)
                at org.gradle.api.internal.artifacts.repositories.resolver.DefaultExternalResourceArtifactResolver.staticResourceExists(DefaultExternalResourceArtifactResolver.java:74)
                at org.gradle.api.internal.artifacts.repositories.resolver.DefaultExternalResourceArtifactResolver.artifactExists(DefaultExternalResourceArtifactResolver.java:65)
                at org.gradle.api.internal.artifacts.repositories.resolver.MavenResolver$MavenRemoteRepositoryAccess.resolveConfigurationArtifacts(MavenResolver.java:216)
                at org.gradle.api.internal.artifacts.repositories.resolver.ExternalResourceResolver$AbstractRepositoryAccess.resolveModuleArtifacts(ExternalResourceResolver.java:360)
                at org.gradle.api.internal.artifacts.repositories.resolver.ExternalResourceResolver$RemoteRepositoryAccess.resolveModuleArtifacts(ExternalResourceResolver.java:407)
                at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.CacheLockReleasingModuleComponentsRepository$LockReleasingRepositoryAccess$4.run(CacheLockReleasingModuleComponentsRepository.java:79)
                at org.gradle.testfixtures.internal.InMemoryCacheFactory$InMemoryCache.longRunningOperation(InMemoryCacheFactory.java:86)
                at org.gradle.api.internal.artifacts.ivyservice.DefaultCacheLockingManager.longRunningOperation(DefaultCacheLockingManager.java:55)
                at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.CacheLockReleasingModuleComponentsRepository$LockReleasingRepositoryAccess.resolveModuleArtifacts(CacheLockReleasingModuleComponentsRepository.java:77)
                at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.CachingModuleComponentRepository$ResolveAndCacheRepositoryAccess.resolveModuleArtifacts(CachingModuleComponentRepository.java:310)
                at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.BaseModuleComponentRepositoryAccess.resolveModuleArtifacts(BaseModuleComponentRepositoryAccess.java:45)
                at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.RepositoryChainArtifactResolver.resolveModuleArtifacts(RepositoryChainArtifactResolver.java:50)
                at org.gradle.api.internal.artifacts.ivyservice.projectmodule.ProjectArtifactResolver.resolveModuleArtifacts(ProjectArtifactResolver.java:50)
                at org.gradle.api.internal.artifacts.ivyservice.ContextualArtifactResolver$2.execute(ContextualArtifactResolver.java:47)
                at org.gradle.api.internal.artifacts.ivyservice.ContextualArtifactResolver$2.execute(ContextualArtifactResolver.java:45)
                at org.gradle.internal.Transformers$3.transform(Transformers.java:131)
                at org.gradle.api.internal.artifacts.ivyservice.DefaultIvyContextManager.withIvy(DefaultIvyContextManager.java:48)
                at org.gradle.api.internal.artifacts.ivyservice.DefaultIvyContextManager.withIvy(DefaultIvyContextManager.java:39)
                at org.gradle.api.internal.artifacts.ivyservice.ContextualArtifactResolver$4.run(ContextualArtifactResolver.java:63)
                at org.gradle.testfixtures.internal.InMemoryCacheFactory$InMemoryCache.useCache(InMemoryCacheFactory.java:78)
                at org.gradle.api.internal.artifacts.ivyservice.DefaultCacheLockingManager.useCache(DefaultCacheLockingManager.java:63)
                at org.gradle.api.internal.artifacts.ivyservice.ContextualArtifactResolver.executeInContext(ContextualArtifactResolver.java:61)
                at org.gradle.api.internal.artifacts.ivyservice.ContextualArtifactResolver.resolveModuleArtifacts(ContextualArtifactResolver.java:45)
                at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.ErrorHandlingArtifactResolver.resolveModuleArtifacts(ErrorHandlingArtifactResolver.java:40)
                ... 35 more

                Caused by:
                org.apache.http.conn.HttpHostConnectException: Connection to http://s3.amazonaws.com refused
                    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:190)
                    at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:294)
                    at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:640)
                    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:479)
                    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
                    at org.apache.http.impl.client.DecompressingHttpClient.execute(DecompressingHttpClient.java:137)
                    at org.apache.http.impl.client.DecompressingHttpClient.execute(DecompressingHttpClient.java:118)
                    at org.gradle.internal.resource.transport.http.HttpClientHelper.performHttpRequest(HttpClientHelper.java:111)
                    at org.gradle.internal.resource.transport.http.HttpClientHelper.executeGetOrHead(HttpClientHelper.java:87)
                    at org.gradle.internal.resource.transport.http.HttpClientHelper.performRequest(HttpClientHelper.java:78)
                    ... 63 more

                    Caused by:
                    java.net.ConnectException: Operation timed out
                        at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:345)
                        at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
                        at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
                        at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
                        at java.net.Socket.connect(Socket.java:589)
                        at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:127)
                        at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180)
                        ... 72 more

gem install should be passed --ignore-dependencies to avoid hitting Rubygems.org

I missed this a while ago, whoops! Notice the difference here:

Without --ignore-dependencies

[9:22:02] tyler:ruby-gradle-example git:(master*) $ gem install .gemcache/sinatra-1.4.5.gem --install-dir=build/vendor --no-ri --no-rdoc
Fetching: rack-1.5.2.gem (100%)
Fetching: rack-protection-1.5.3.gem (100%)
Successfully installed rack-1.5.2
Successfully installed rack-protection-1.5.3
Successfully installed sinatra-1.4.5
3 gems installed
[9:22:28] tyler:ruby-gradle-example git:(master*) $

With --ignore-dependencies

[9:22:39] tyler:ruby-gradle-example git:(master*) $ gem install .gemcache/sinatra-1.4.5.gem --ignore-dependencies --install-dir=build/vendor --no-ri --no-rdoc
Successfully installed sinatra-1.4.5
1 gem installed
[9:22:47] tyler:ruby-gradle-example git:(master*) $ 

Fixing this behavior will also speed things up quite a bit!

Should jrubyWar task be linked to build task?

Testcase:
[1] Create a simple build script such as this one:

buildscript {
    repositories {
        mavenLocal()
        jcenter()
    }

    dependencies {
        classpath group: 'com.lookout', name: 'jruby-gradle-plugin', version: '2.2.0-SNAPSHOT'
    }
}

apply plugin: 'groovy'
apply plugin: 'maven'
apply plugin: 'com.lookout.jruby'

group = 'FOOBAR'
version = '0.0.0.0.1-SNAPSHOT'

dependencies {
    compile localGroovy()
    gems 'rubygems:coderay:1.1.0'
}

[2] Now do gradle build --info
[3] Inspect build/libs/TMP-0.0.0.0.1-SNAPSHOT.war. It's a broken war
[4] Now do gradle jrubyWar --info
[5] Inspect build/libs/TMP-0.0.0.0.1-SNAPSHOT.war again. Now the war looks pretty decent

Should we somehow link in jrubyWar to build (keeping ISSUE #38 in mind) ?

Combining plugin with maven plugin adds war to install if you don't want it.

Test case - create a simple build script such as

buildscript {
    repositories {
        mavenLocal()
        jcenter()
    }

    dependencies {
        classpath group: 'com.lookout', name: 'jruby-gradle-plugin', version: '2.2.0-SNAPSHOT'
    }
}

apply plugin: 'groovy'
apply plugin: 'maven'
apply plugin: 'com.lookout.jruby'

group = 'FOOBAR'
version = '0.0.0.0.1-SNAPSHOT'

dependencies {
    compile localGroovy()
    gems 'rubygems:coderay:1.1.0'
}

Now do gradle build jrubyJar install --info. Notice the war that gets pushed to the local maven repo. My intent was to only create a runnable jar not a war.

What to do?

  • Maybe create multiple apply statements i.e. apply plugin: 'com.lookout.jruby.war for when you want war functionality.?
  • Maybe have a separate artifacts section in JRubyPluginExtentions which specifies which kind of artifacts will be created?

Issue with using plugin in restricted environments

It just triggered with me today that this code block in JRubyPlugin will cause an issue within restricted environments:

        project.repositories {
            maven {
                // The url is in a closure to ensure that we can overwrite this
                // at runtime and have the right value come through.
                url { project.jruby.gemrepo_url }
            }

            // Required to pull in our warbler-bootstrap dependency
            maven { url 'http://dl.bintray.com/rtyler/jruby' }

            // We'll need jcenter to resolve the jruby .jar deps
            jcenter()
        }

Specifying the repositories, might make it simpler for people to start using the plugin, but in environments where access to repositories are typically restricted to local Artifactory & Nexus instances this will fail. It is probably worthwhile to remove the code block and simply update the README stating which repositories should be added manually to the build script.

Add a JRubyExec task and project extension.

This is along the lines of JavaExec or RhinoShellExec. We would like to have the ability to execute a Ruby script as a task.

As a task:

task myRubyScript( type : JRubyExec ) {
  // The name of the script - This is the only mandatory setting
  script 'path/to/script.rb'

  // Parameters to be passed to the script
  scriptArgs '-x', '-y'

  // workingDir in case if needs to be overrided
  workingDir '/working/dir'

  // Config group for gems that need to be made available to the task
  // Defaults to jrubyExec
 gems 'jrubyExec' 

  // Ability to add additional JVM arguments
  jvmArgs '-Dsomething=that'  

  // Add additional environmental variables
 environment 'FOO' : 'bar', 'TESTPORT', '5959'
}

As a project extension:

task myCustomTaskNeedsRubyLove << {
  project.jrubyexec {
    // parameters similar to JRubyExec
  }
}

Add plugins to jcenter

If plugin is linked into jcenter then the line 25

maven { url 'http://dl.bintray.com/rtyler/jruby' }

in JRubyPlugin.groovy will no longer be required.

Use more than one rubygems repository

I am taking a stab at a better way to define Ruby repositories, especially given that one can host additional rubygem repositories on Bintray. I think this is a much better approach that jruby.gemrepo_url

repositories {
 // Use the default rubygem repo. Using the explicit statement, allows for a non-standard repo to 
 // to be used instead, should circumstances require so.
 rubygemsRelease()

 // Defines an additional repository
  rubygems { 
    name : 'MyBintrayRepo' 
    url : 'http://dl.bintray.com/myBintrayName/myBintrayGemRepo'
  }
}

Gradle should create a gradle.rb which can be executed to provide a extra-Gradle runtime

This should probably be configurable but having a .rb file created dynamically that can set up the load paths and what-not for properly referencing gradle provided gems, etc.

Having such a file should allow for the execution of gem binstubs and other types of scripts without needing to invoke them through Gradle. This can be useful for running pry or a Ruby-based debugger, or other interactive tool, that doesn't fit well into the Gradle execution model.

For example, if I generated a gradle.rb file, assuming it was executable, I should be able to invoke: ./gradle.rb gem list and expect a gem listing output from whatever is installed into the gemInstallDir

Should JRubyExec use the same JVM?

Somewhat related to a comment I made in #15, but I'm wondering if we should skip invoking a secondary JVM for JRubyExec and just use the JRubyScriptingContainer to execute a Ruby script in the JVM executing the Gradle task itself.

//cc @ysb33r @mojavelinux

infinite jvm power

Support exclusions for gems

Like with jars, it's sometimes necessary to exclude a transitive gem from being installed. This plugin should at least one of the following options:

  1. Disable transitivity (i.e., transitive: false, which activates the flag --ignore-dependencies)
  2. Allow individual gems to be excluded by name (group is implied)

jrubywar vs JRubyWar - Some improvements

With the refactoring of jrubyWar to JRubyWar I believe the the newly created task type is not flexible enough. I suggest the following:

  • Only set the main class within the copy method. This allows for aximum flexibility in custom JRubyExec task instances
  • Set the description and group in the jrubyWar task instead. Creators of custom JRubyWar tasks might want to place it in a different group.
  • Add a 'gems' method to JRubyWar. This will in effect add GEMs to webInf and oveall allows the user to control multiple gem sources. Set the default in jrubyWar to jruby.gemInstallDir.

Potential performance improvement in JRubyPrepareGems

Currently gems are installed one by one in an each{} closure. As this invokes a javaexec per GEM, this can sow down quite a bit should a large list of GEMs be provided. I suspect we should be able to pass a list of GEMs and perform the install in a single call-out.

gemInstallDIr should be underneath buildDir

Convention is to write all artefacts and most temporaries to below project.buildDir. I believe we should do the same for gemInstallDir. I don;t think this will affect the wat jrubyWar works.

The fix is easy - just change the JRubyPluginExtension constructor to have an extra statement:

gemInstallDir = "${project.buildDir}/gems/vendor"

Default jar created by jrubyJar only contains a manifest file

Test case:

[1] Create simple build scirpt such as

buildscript {
    repositories {
        mavenLocal()
        jcenter()
    }

    dependencies {
        classpath group: 'com.lookout', name: 'jruby-gradle-plugin', version: '2.2.0-SNAPSHOT'
    }
}

apply plugin: 'groovy'
apply plugin: 'maven'
apply plugin: 'com.lookout.jruby'

group = 'FOOBAR'
version = '0.0.0.0.1-SNAPSHOT'

dependencies {
    compile localGroovy()
    gems 'rubygems:coderay:1.1.0'
}

[2] Run gradle jrubyJar
[3] Inspect the jar in build/lib. It only contains a MANIFEST
[4] Run gradle build jrubyJar. Now the jar is correctly populated.

The default jar task that comes with the java plugin, has a dependency on the classes task. Maybe jrubyJar should too.

jrubyJavaBootstrap script should add the jar/war package itself to the $LOAD_PATH

When printing out $LOAD_PATH from the script running inside a built .jar file with jrubyJavaBootstrap, it apparently isn't including the full path to the jar file itself (see below).

This means we cannot properly load gems that have been packaged into the archive.

build/libs/metron-2.0.null-all.jar
file:/usr/home/tyler/source/lookout/git/metron/build/libs/metron-2.0.null-all.jar!/META-INF/jruby.home/lib/ruby/1.9/site_ruby
file:/usr/home/tyler/source/lookout/git/metron/build/libs/metron-2.0.null-all.jar!/META-INF/jruby.home/lib/ruby/shared
file:/usr/home/tyler/source/lookout/git/metron/build/libs/metron-2.0.null-all.jar!/META-INF/jruby.home/lib/ruby/1.9
Could not find i18n-0.6.9 in any of the sources
Run `bundle install` to install missing gems.

Making GEM extraction more intelligent

Current GEM extraction works on either by overwriting the extracted directory everytime or to skip extraction of the top-level directory of the gem already exists. Although these are good for an initial roll-out, it will eventually either cause UX problems, or in big projects will slow building time.

A possible approach would be to create a read-only gemTree. A gem contains a data.tar.gz file which could be handled as a tarTree. It might be worthwhile looking into.

JRubyExec should not overwrite gems on every run

First implementation was donig this, but retrospectively that it is not good solution. My suggestion is to only do this when --refresh-dependencies is specified on the command-line.

Obviously running the clean task will achieve this too, but that is a severe solution in many cases for the user. I don't believe adding specific gradle rules is worthwhile in the case

`script` for JRubyExec should not be strictly required

In the case of executing rspec we want to just be able to invoke it without a specific file parameter, e.g.

task rspec(type: JRubyExec) {
  jrubyArgs '-S', 'rspec'
  scriptArgs '--color'
}

If script is passed then that means RSpec is going to only look at that one file, instead of considering the entire spec/ directory.

IMHO an empty script option, provided jrubyArgs is present, should be valud

Create JRubyWar task

I think it would be worthwhile to create a JRubyWar task type. The default behaviour could be that as current described in the jrubyWar task. JRubyPlugin will still create the jrubyWar task, but it will be of type JRubyWar instead of War.

This will help in the easier customisation of jruby-based WARs.

Implementation-wise the JRubyWar class will simply derive from War

jrubyJar task misses the default JarMain.class

jrubyJar is is supposed to be made executable by adding in com.lookout.jruby.JarMain as its default main class in order to become runnable. The class is missing from the created jar.

Plugin is unusable without a weird quirk in build script/apply plugin syntax

I tried to apply the base + WAR plugins to my Gradle 2.1+ Rails project a few different ways, mostly without success. The only way I convinced it to work was as follows, but it doesn't seem right - it looks like I am making up for an undeclared dependency in one of your plugins, but obviously I can only do that by using the old Gradle syntax where you can put a plugin on the classpath but never apply it.

It is also not clear which of the many plugins a user of your code should apply - are the com.github plugins only hosted so that they can be downloaded by dependent plugins? Is com.lookout.jruby the standalone packaged version? Or do I need to declare the base + war plugins because the war plugin does not specify its dependencies internally?

Way that works

  • use old Gradle syntax
  • require War plugin + com.lookout.jruby plugin on classpath
  • but only apply the com.lookout.jruby plugin
buildscript {
  repositories { jcenter() }

  dependencies {
    classpath "com.lookout:jruby-gradle-plugin:2.1.0"
    classpath "com.github.jruby-gradle:jruby-gradle-war-plugin:0.1.1"
  }
}

// Base tasks for using Jruby with Gradle
apply plugin: "com.lookout.jruby"

Ways that do not work

Use new Gradle syntax, use com.github.jruby-gradle plugins

plugins {
  id "maven"
  id "com.github.jruby-gradle.base" version "0.1.2"
  id "com.github.jruby-gradle.war" version "0.1.1"
}

This fails because it cannot source a dependency in com.lookout.warbler-bootstrap.

Use new Gradle syntax, use com.lookout.jruby plugin

plugins {
  id "com.lookout.jruby" version "2.1.0"
}

This fails because it cannot source the jrubyWar related packaging tasks which are located in the war plugin.

Use new Gradle syntax, use com.lookout.jruby + war plugin

plugins {
  id "com.lookout.jruby" version "2.1.0"
  id "com.github.jruby-gradle.war" version "0.1.1"
}

This fails because it attempts to apply the war plugin, which in turn applies the base plugin, which then conflicts with the 'jruby' task which has already been defined in 'com.lookout.jruby'.

Create JRubyPrepareGems Task

Create a JRubyPrepareGems tasks modelled on jrubyPrepareGems which are currently in jRubyPlugin.

Refactor jrubyPrepareGems to be based upon JRubyPrepareGems, but with appropriate configuration. Behaviour should not change due to refactoring.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.