Compare commits

...

31 Commits

Author SHA1 Message Date
Schalk W. Cronjé 76aa4fb697
Merge pull request #412 from jruby-gradle/master
Release 2.1.0-alpha.1
2020-10-30 20:57:00 +01:00
Schalk W. Cronjé 2019d0e6ad
Merge pull request #411 from ysb33r/gradle7
Prepare for Gradle's configuration cache
2020-10-30 20:54:53 +01:00
Schalk Cronje 0e904089c8 Prepare for Gradle's configuration cache
- Use the new 1.0.0-alpha.1 Grolifant release that has configuration-cache
  safety built-in.
- Check that no usage of `Project` object will be done after configuration
  phase has ended.
- Maintain compatibility down to Gradle 4.3.
2020-10-29 22:15:06 +01:00
Schalk W. Cronjé fe46be32c9
Merge pull request #402 from ysb33r/master
Finalise 2.0.0 release
2020-01-17 23:38:19 +01:00
Schalk Cronje 5249a5829d Move ruby.gems() first in order of documentation 2020-01-17 23:20:46 +01:00
Schalk Cronje d764de4e8e Update license headers 2020-01-17 23:11:26 +01:00
Schalk Cronje 593f096279 Set version to 2.0.0 2020-01-17 19:23:26 +01:00
Schalk Cronje 6e1be93181 Describe repositories and GEM resolver strategy customisation (#378) 2020-01-17 19:19:04 +01:00
Schalk Cronje 60829c7ce4 Support JRuby Maven GEM proxy (#401) 2020-01-17 18:55:48 +01:00
Schalk W. Cronjé 814c36b2a5
Merge pull request #400 from ysb33r/master
Do not include pre-release GEMs by the default
2019-12-25 19:17:43 +01:00
Schalk Cronje 6fdc2e28bc Do not include pre-release GEMs by default (#393) 2019-12-25 01:06:45 +01:00
Schalk Cronje fb47d655cb Remove Torquebox 2019-12-24 22:27:15 +01:00
Schalk Cronje 8f782494cb Add Guillaume Grossetie to author credits 2019-12-24 21:42:41 +01:00
Schalk Cronje 836837ca4a Static compile JRubyExec 2019-12-24 21:42:13 +01:00
Schalk Cronje a32280d3e0 Revert accidental changed deprecation text messages 2019-12-24 21:06:26 +01:00
Schalk Cronje 7e130116f1 Proposed JRuby version can be optional 2019-12-24 16:14:31 +01:00
Schalk W. Cronjé b308fd2b0d
Merge pull request #399 from ysb33r/master
If the plugin version changes, resolve all dependencies again (#398)
2019-12-24 15:36:50 +01:00
Schalk Cronje d57e2f42de If the plugin version changes, resolve all dependencies again (#398) 2019-12-24 15:19:44 +01:00
Schalk Cronje 7fe59b4621 Prepare to release 2.0.0-alpha.4 2019-12-23 13:53:05 +01:00
Schalk W. Cronjé 2ffe92f845
Merge pull request #396 from Mogztter/issue-394-gem-resolution
resolves #394 fix gem requirements resolution
2019-12-23 13:51:51 +01:00
Schalk W. Cronjé c264d2de8e
Merge pull request #395 from Mogztter/patch-1
HACKING file is an AsciiDoc document
2019-12-23 13:50:53 +01:00
Guillaume Grossetie 1545885ecf resolves #394 fix gem requirements resolution 2019-12-22 21:40:02 +01:00
Guillaume Grossetie 01c7f95c92
HACKING file is an AsciiDoc document 2019-12-22 10:56:52 +01:00
Schalk W. Cronjé d8f1358065
Merge pull request #392 from ysb33r/master
Release 2.0.0-alpha.3
2019-12-20 18:22:21 +01:00
Schalk Cronje ac7db6fe24 Only initialise default jruby version in the project extension (#390) 2019-12-20 18:06:40 +01:00
Schalk Cronje 00522b2cca Always use the java version of a GEM (#391) 2019-12-20 18:03:06 +01:00
Schalk Cronje 44c14bb7f9 Update release process 2019-12-19 23:59:08 +01:00
Schalk W. Cronjé 6dff6c3504
Merge pull request #389 from ysb33r/master
Remove Torquebox
2019-12-19 23:50:38 +01:00
Schalk Cronje a8ffdf8954 Remove all dependency on Torquebox (#388) 2019-12-19 23:28:05 +01:00
Schalk Cronje a7d119e7a4 Merge branch 'master' of https://github.com/jruby-gradle/jruby-gradle-plugin 2019-12-19 14:18:21 +01:00
Schalk Cronje 0d2ccce53e Remove deprecation warnings related to Gradle 5 2019-12-19 12:07:47 +01:00
98 changed files with 1237 additions and 505 deletions

View File

@ -19,4 +19,4 @@ In a similar manner for integration tests one can do `./gradlew integrationTest
Go to `File` -> `Settings` -> `Build, Execution, Deployment` -> `Gradle` -> `Runner`, then check `Delete build/run actions to Gradle` and select `Platform Test Runner`.
On a Mac use `IntelliJ IDEA` -> `Preferences` instead of `File/Settings`.
On a Mac use `IntelliJ IDEA` -> `Preferences` instead of `File/Settings`.

View File

@ -7,7 +7,7 @@ image::https://api.bintray.com/packages/jruby-gradle/plugins/jruby-gradle-plugin
=== Compatibility
This plugin requires link:http://gradle.org[Gradle] 4.0 or better
This plugin requires link:http://gradle.org[Gradle] 4.9 or better
=== Installing

View File

@ -22,7 +22,6 @@ project.afterEvaluate {
// --- up to here
ext {
olderJRubyVersion = '9.2.1.0'
slimVersion = '2.0.2'
leafyVersion = '0.4.0'
}
@ -48,31 +47,27 @@ dependencies {
exclude group: 'org.codehaus.groovy'
}
// NOTE: This is used by JRubyPrepareGemsIntegrationSpec
integrationTestGems "rubygems:slim:${slimVersion}"
// NOTE: This is used by JRubyPrepareJarsIntegrationSpec
integrationTestGems "rubygems:leafy-complete:${leafyVersion}"
// NOTE: If you change this, you will also need to update JRubyExecIntegrationSpec & JRubyExecExtensionIntegrationSpec
integrationTestGems 'rubygems:credit_card_validator:1.1.0'
// NOTE: If you change this, you will also need to update JRubyExecIntegrationSpec
integrationTestGems 'rubygems:rspec:3.1.0'
// NOTE: This should always be an older older version.
// NOTE: This should always be an older older version.
// It is used by JRubyExecIntegrationSpec
integrationTestGems "org.jruby:jruby-complete:${olderJRubyVersion}"
// NOTE: older jruby versions needs this for exec to work properly
integrationTestGems "rubygems:jar-dependencies:0.1.15"
// This is used by JRubyExecExtensionIntegrationSpec
integrationTestGems "org.bouncycastle:bcprov-jdk15on:${bcprovVersion}"
// This is used by JRubyPrepareJarsIntegrationSpec
integrationTestGems "io.dropwizard.metrics:metrics-core:${dropwizardMetricsCoreVersion}"
gradleTest "org.jruby:jruby-complete:${jrubyVersion}"
gradleTest 'rubygems:credit_card_validator:1.1.0'
gradleTest 'org.bouncycastle:bcprov-jdk15on:1.50'
// These are real GEMs which cannot currently be cached
// gradleTest 'rubygems:credit_card_validator:1.1.0'
// integrationTestGems "rubygems:slim:${slimVersion}"
// integrationTestGems "rubygems:leafy-complete:${leafyVersion}"
// integrationTestGems 'rubygems:credit_card_validator:1.1.0'
// integrationTestGems 'rubygems:rspec:3.1.0'
// integrationTestGems "rubygems:jar-dependencies:0.1.15"
}
generateTestConfig {
@ -81,7 +76,10 @@ generateTestConfig {
bcprovVersion: bcprovVersion,
olderJRubyVersion: olderJRubyVersion,
slimVersion: slimVersion,
leafyVersion: leafyVersion
leafyVersion: leafyVersion,
creditCardValidatorVersion : '1.1.0',
dropwizardMetricsCoreVersion : dropwizardMetricsCoreVersion,
rspecVersion : '3.1.0'
}
task copyIntegrationTestJRuby(type: Copy) {

View File

@ -6,8 +6,12 @@ configurations {
jrubyExec
}
repositories {
ruby.gems()
}
dependencies {
jrubyExec ':credit_card_validator:1.1.0@gem'
jrubyExec 'rubygems:credit_card_validator:1.1.0'
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -25,14 +25,16 @@ package com.github.jrubygradle
import com.github.jrubygradle.testhelper.IntegrationSpecification
import org.gradle.testkit.runner.BuildResult
import spock.lang.IgnoreIf
/**
* @author Schalk W. Cronjé
*/
@IgnoreIf({System.getProperty('TESTS_ARE_OFFLINE')})
class JRubyExecExtensionIntegrationSpec extends IntegrationSpecification {
static final String DEFAULT_TASK_NAME = 'inlineJRubyExec'
static final String BCPROV_NAME = 'bcprov-jdk15on'
public static final String DEFAULT_TASK_NAME = 'inlineJRubyExec'
public static final String BCPROV_NAME = 'bcprov-jdk15on'
void "Run a script with minimum parameters"() {
setup:
@ -147,7 +149,7 @@ class JRubyExecExtensionIntegrationSpec extends IntegrationSpecification {
@SuppressWarnings('BuilderMethodWithSideEffects')
private void createJRubyExecProject(String preamble, String jrubyexecConfig) {
buildFile.text = """
${projectWithLocalRepo}
${projectWithRubyGemsRepo}
${preamble}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -151,6 +151,10 @@ class JRubyExecIntegrationSpec extends IntegrationSpecification {
script 'rspec'
"""
File specDir = new File(projectDir,'spec')
specDir.mkdirs()
new File(specDir,'sample.rb').text = ''
when:
BuildResult result = build()
@ -224,7 +228,7 @@ class JRubyExecIntegrationSpec extends IntegrationSpecification {
buildFile.text = """
import com.github.jrubygradle.JRubyExec
${projectWithMavenRepo}
${projectWithRubyGemsRepo}
${preamble ?: ''}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -30,6 +30,7 @@ import spock.lang.IgnoreIf
/**
* @author Schalk W. Cronjé
*/
@IgnoreIf({System.getProperty('TESTS_ARE_OFFLINE')})
class JRubyGenerateGradleRbIntegrationSpec extends IntegrationSpecification {
static final String DEFAULT_TASK_NAME = 'RubyWax'
@ -40,7 +41,7 @@ class JRubyGenerateGradleRbIntegrationSpec extends IntegrationSpecification {
buildFile.text = """
import com.github.jrubygradle.GenerateGradleRb
${projectWithLocalRepo}
${projectWithRubyGemsRepo}
task ${DEFAULT_TASK_NAME} (type: GenerateGradleRb) {
gemInstallDir 'build/gems'

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -30,12 +30,14 @@ import spock.lang.Issue
/**
* @author Schalk W. Cronjé.
* @author Guillaume Grossetie
*/
@IgnoreIf({ IntegrationSpecification.OFFLINE })
class JRubyPrepareGemsIntegrationSpec extends IntegrationSpecification {
static final String DEFAULT_TASK_NAME = 'jrubyPrepare'
String repoSetup = projectWithLocalRepo
String repoSetup = projectWithRubyGemsRepo
String preamble
String dependenciesConfig
@ -53,7 +55,6 @@ class JRubyPrepareGemsIntegrationSpec extends IntegrationSpecification {
new File(projectDir, "gems/slim-${slimVersion}").exists()
}
@IgnoreIf({ IntegrationSpecification.OFFLINE })
void "Check if rack version gets resolved"() {
setup:
withPreamble """repositories.ruby.gems()
@ -72,10 +73,29 @@ class JRubyPrepareGemsIntegrationSpec extends IntegrationSpecification {
then:
// since we need a version range in the setup the
// resolved version here can vary over time
new File(projectDir, "gems/rack-1.6.11").exists()
new File(projectDir, "gems/rack-1.6.13").exists()
}
void "Check if selenium-webdriver version gets resolved"() {
setup:
withPreamble """repositories.ruby.gems()
jrubyPrepare.outputDir = '${pathAsUriStr(projectDir)}'.toURI()
"""
withDependencies """
gems 'rubygems:selenium-webdriver:3.142.6'
gems 'rubygems:webdrivers:4.1.3'
"""
when:
build()
then:
// since we need a version range in the setup the
// resolved version here can vary over time
new File(projectDir, "gems/selenium-webdriver-3.142.6").exists()
}
@IgnoreIf({ IntegrationSpecification.OFFLINE })
void "Check that GEM dependencies are locked"() {
setup:
File lockFile = new File(projectDir, 'gradle/dependency-locks/gems.lockfile')
@ -117,7 +137,6 @@ rubygems:tilt:2.0.9
new File(projectDir, "gems/rack-1.6.10").exists()
}
@IgnoreIf({ IntegrationSpecification.OFFLINE })
void "Check if prerelease gem gets resolved"() {
setup:
withDefaultRepositories()
@ -134,7 +153,6 @@ rubygems:tilt:2.0.9
}
@Issue('https://github.com/jruby-gradle/jruby-gradle-plugin/issues/341')
@IgnoreIf({ IntegrationSpecification.OFFLINE })
void "Make an install-time gem dependency available"() {
setup:
withRubyGemsRepository()

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -24,20 +24,23 @@
package com.github.jrubygradle
import com.github.jrubygradle.testhelper.IntegrationSpecification
import spock.lang.IgnoreIf
/**
* @author Schalk W. Cronjé.
* @author Christian Meier
*/
@IgnoreIf({ IntegrationSpecification.OFFLINE })
class JRubyPrepareJarsIntegrationSpec extends IntegrationSpecification {
def "Check that default 'jrubyPrepare' uses the correct directory for the jars"() {
given:
String testVer = testProperties.dropwizardMetricsCoreVersion
buildFile.text = """
${projectWithLocalRepo}
${projectWithRubyGemsRepo}
dependencies {
gems 'io.dropwizard.metrics:metrics-core:3.1.0'
gems "io.dropwizard.metrics:metrics-core:${testVer}"
}
"""
@ -45,7 +48,11 @@ class JRubyPrepareJarsIntegrationSpec extends IntegrationSpecification {
gradleRunner('jrubyPrepare', '-i').build()
then:
new File(projectDir, 'build/.gems/Jars.lock').text.trim() == 'io.dropwizard.metrics:metrics-core:3.1.0:runtime:'
new File(projectDir, 'build/.gems/jars/io/dropwizard/metrics/metrics-core/3.1.0/metrics-core-3.1.0.jar').exists()
new File(projectDir, 'build/.gems/Jars.lock').text.trim() ==
"io.dropwizard.metrics:metrics-core:${testProperties.dropwizardMetricsCoreVersion}:runtime:"
new File(
projectDir,
"build/.gems/jars/io/dropwizard/metrics/metrics-core/${testVer}/metrics-core-${testVer}.jar"
).exists()
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -23,29 +23,37 @@
*/
package com.github.jrubygradle.testhelper
import org.gradle.testkit.runner.GradleRunner
import org.junit.Rule
import org.junit.rules.TemporaryFolder
import spock.lang.Shared
import spock.lang.Specification
import static com.github.jrubygradle.JRubyExecExtensionIntegrationSpec.BCPROV_NAME
class IntegrationSpecification extends Specification {
static final boolean OFFLINE = System.getProperty('TESTS_ARE_OFFLINE')
public static final boolean OFFLINE = System.getProperty('TESTS_ARE_OFFLINE')
static final String HELLO_WORLD = 'helloWorld.rb'
static final String HELLO_NAME = 'helloName.rb'
static final String REQUIRES_GEM = 'requiresGem.rb'
static final String REQUIRE_THE_A_GEM = 'require-a-gem.rb'
static final String ENV_VARS = 'envVars.rb'
public static final String HELLO_WORLD = 'helloWorld.rb'
public static final String HELLO_NAME = 'helloName.rb'
public static final String REQUIRES_GEM = 'requiresGem.rb'
public static final String REQUIRE_THE_A_GEM = 'require-a-gem.rb'
public static final String ENV_VARS = 'envVars.rb'
@Shared
Map testProperties
@Shared
File flatRepoLocation
@Shared
File mavenRepoLocation
@Shared
Map artifactVersions
@Rule
TemporaryFolder testFolder
@ -57,6 +65,15 @@ class IntegrationSpecification extends Specification {
testProperties = loadTestProperties()
flatRepoLocation = new File(testProperties.flatrepo)
mavenRepoLocation = new File(testProperties.mavenrepo)
artifactVersions = [
'credit_card_validator': testProperties.creditCardValidatorVersion,
'rspec' : testProperties.rspecVersion,
'rspec-core' : testProperties.rspecVersion,
'rspec-support' : testProperties.rspecVersion,
'metrics-core' : testProperties.dropwizardMetricsCoreVersion,
(BCPROV_NAME) : testProperties.bcprovVersion
]
}
void setup() {
@ -73,28 +90,19 @@ class IntegrationSpecification extends Specification {
destination.text = this.class.getResource("/scripts/${name}").text
}
String findDependency(final String organisation, final String artifact, final String extension) {
"'${VersionFinder.findDependency(flatRepoLocation, organisation, artifact, extension)}'"
String ver = artifactVersions[artifact]
if (!ver) {
throw new RuntimeException("No version specified for ${artifact}")
}
"'${organisation ?: 'rubygems'}:${artifact}:${ver}@${extension}'"
}
String pathAsUriStr(final File path) {
path.absoluteFile.toURI().toString()
}
String getProjectWithLocalRepo() {
"""
plugins {
id 'com.github.jruby-gradle.base'
}
repositories {
flatDir {
dirs '${pathAsUriStr(flatRepoLocation)}'.toURI()
}
}
"""
}
String getProjectWithMavenRepo() {
"""
plugins {
@ -138,13 +146,14 @@ class IntegrationSpecification extends Specification {
}
"""
}
GradleRunner gradleRunner(List<String> args) {
GradleRunner.create()
.withProjectDir(projectDir)
.withDebug(true)
.withArguments(args)
.withPluginClasspath()
.forwardOutput()
.withProjectDir(projectDir)
.withDebug(true)
.withArguments(args)
.withPluginClasspath()
.forwardOutput()
}
GradleRunner gradleRunner(String... args) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,6 +1,6 @@
<!--
Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
# Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
# Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
# Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
# Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
# Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
# Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
# Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
# Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
# Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
# Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -29,16 +29,18 @@ import groovy.transform.CompileStatic
import org.apache.tools.ant.filters.ReplaceTokens
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.file.CopySpec
import org.gradle.api.file.FileCopyDetails
import org.gradle.api.file.RelativePath
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
import org.ysb33r.grolifant.api.StringUtils
import org.ysb33r.grolifant.api.core.ProjectOperations
import org.ysb33r.grolifant.api.v4.StringUtils
import static com.github.jrubygradle.internal.JRubyExecUtils.classpathFromConfiguration
/** Generate a LOAD_PATH Ruby file whichi is loadable by Ruby scripts when
/** Generate a LOAD_PATH Ruby file which is loadable by Ruby scripts when
* performing local manual testing.
*
* @author Schalk W. Cronjé
@ -53,6 +55,7 @@ class GenerateGradleRb extends DefaultTask implements JRubyAwareTask {
GenerateGradleRb() {
this.jruby = extensions.create(JRubyPluginExtension.NAME, JRubyPluginExtension, this)
this.projectOperations = ProjectOperations.create(project)
}
void destinationDir(Object dest) {
@ -72,7 +75,7 @@ class GenerateGradleRb extends DefaultTask implements JRubyAwareTask {
}
File getDestinationDir() {
project.file(destinationDir)
projectOperations.file(destinationDir)
}
@OutputFile
@ -86,7 +89,7 @@ class GenerateGradleRb extends DefaultTask implements JRubyAwareTask {
}
File getGemInstallDir() {
project.file(this.gemInstallDir)
projectOperations.file(this.gemInstallDir)
}
@TaskAction
@ -98,27 +101,27 @@ class GenerateGradleRb extends DefaultTask implements JRubyAwareTask {
String path = classpathFromConfiguration(jruby.jrubyConfiguration).join(File.pathSeparator)
String gemDir = getGemInstallDir().absolutePath
String bootstrapName = getBaseName()
String bootstrapTemplate = BOOTSTRAP_TEMPLATE
logger.info("GenerateGradleRb - source: ${source}, destination: ${destination}, baseName: ${baseName}")
project.copy {
from(source) {
/* In the case of this plugin existing in a zip (i.e. the
* plugin jar) our `source` will be a ZipTree, so we only want
* to pull in the template itself
*/
include "**/${GenerateGradleRb.BOOTSTRAP_TEMPLATE}"
}
into destination
fileMode = 0755
includeEmptyDirs = false
rename BOOTSTRAP_TEMPLATE, bootstrapName
// Flatten the file into the destination directory so we don't copy
// the file into: ${destination}/META-INF/gradle-plugins/gradle.rb
eachFile { FileCopyDetails details ->
details.relativePath = new RelativePath(true, [details.name] as String[])
}
projectOperations.copy { CopySpec cs ->
cs.with {
// In the case of this plugin existing in a zip (i.e. the plugin jar) our `source` will be a ZipTree,
// so we only want to pull in the template itself
from(source).include "**/${bootstrapTemplate}"
filter ReplaceTokens, beginToken: '%%', endToken: '%%',
tokens: [GEMFOLDER: gemDir, JRUBYEXEC_CLASSPATH: path]
into destination
fileMode = 0755
includeEmptyDirs = false
rename bootstrapTemplate, bootstrapName
// Flatten the file into the destination directory so we don't copy
// the file into: ${destination}/META-INF/gradle-plugins/gradle.rb
eachFile { FileCopyDetails details ->
details.relativePath = new RelativePath(true, [details.name] as String[])
}
filter ReplaceTokens, beginToken: '%%', endToken: '%%',
tokens: [GEMFOLDER: gemDir, JRUBYEXEC_CLASSPATH: path]
}
}
}
@ -152,4 +155,5 @@ class GenerateGradleRb extends DefaultTask implements JRubyAwareTask {
private Object destinationDir = project.projectDir
private Object gemInstallDir
private final JRubyPluginExtension jruby
private final ProjectOperations projectOperations
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -26,20 +26,23 @@ package com.github.jrubygradle
import com.github.jrubygradle.api.core.JRubyAwareTask
import com.github.jrubygradle.api.core.JRubyExecSpec
import com.github.jrubygradle.internal.JRubyExecUtils
import groovy.transform.CompileStatic
import org.gradle.api.Task
import org.gradle.api.artifacts.Configuration
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.JavaExec
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.TaskContainer
import org.gradle.process.JavaExecSpec
import org.gradle.util.GradleVersion
import org.ysb33r.grolifant.api.core.ProjectOperations
import java.util.concurrent.Callable
import static com.github.jrubygradle.internal.JRubyExecUtils.prepareJRubyEnvironment
import static com.github.jrubygradle.internal.JRubyExecUtils.resolveScript
import static org.ysb33r.grolifant.api.StringUtils.stringize
import static org.ysb33r.grolifant.api.v4.StringUtils.stringize
/** Runs a ruby script using JRuby
*
@ -48,6 +51,7 @@ import static org.ysb33r.grolifant.api.StringUtils.stringize
* @author Christian Meier
*
*/
@CompileStatic
class JRubyExec extends JavaExec implements JRubyAwareTask, JRubyExecSpec {
public static final String MAIN_CLASS = 'org.jruby.Main'
@ -62,35 +66,43 @@ class JRubyExec extends JavaExec implements JRubyAwareTask, JRubyExecSpec {
JRubyExec() {
super()
super.setMain MAIN_CLASS
super.setMain(MAIN_CLASS)
this.jruby = extensions.create(JRubyPluginExtension.NAME, JRubyPluginExtension, this)
this.projectOperations = ProjectOperations.create(project)
this.tasks = project.tasks
inputs.property 'jrubyver', {
inputs.property 'jrubyver', { JRubyPluginExtension jruby ->
jruby.jrubyVersion
}
}.curry(this.jruby)
inputs.property 'gemConfiguration', {
inputs.property 'gemConfiguration', { JRubyPluginExtension jruby ->
jruby.gemConfiguration
}
}.curry(this.jruby)
if (GradleVersion.current() >= GradleVersion.version('4.10')) {
dependsOn(project.provider({ JRubyPluginExtension jpe ->
project.tasks.getByName(jpe.gemPrepareTaskName)
}.curry(this.jruby)))
dependsOn(project.provider({ JRubyPluginExtension jpe, TaskContainer t ->
t.getByName(jpe.gemPrepareTaskName)
}.curry(this.jruby, this.tasks)))
} else {
project.afterEvaluate({ Task t, JRubyPluginExtension jpe ->
t.dependsOn(jpe.gemPrepareTaskName)
}.curry(this, this.jruby))
}
Callable<File> resolveGemWorkDir = { JRubyPluginExtension jpe, TaskContainer t ->
((JRubyPrepare) t.getByName(jpe.gemPrepareTaskName)).outputDir
}.curry(jruby, tasks) as Callable<File>
this.gemWorkDir = project.provider(resolveGemWorkDir)
}
/** Script to execute.
* @return The path to the script (or nul if not set)
* @return The path to the script (or {@code null} if not set)
*/
@Optional
@Input
File getScript() {
resolveScript(project, this.script)
resolveScript(projectOperations, this.script)
}
/** Returns a list of script arguments
@ -174,11 +186,7 @@ class JRubyExec extends JavaExec implements JRubyAwareTask, JRubyExecSpec {
* @return Provider of GEM working directory.
*/
Provider<File> getGemWorkDir() {
Callable<File> resolveGemWorkDir = { JRubyPluginExtension jpe ->
((JRubyPrepare) project.tasks.getByName(jpe.gemPrepareTaskName)).outputDir
}.curry(jruby) as Callable<File>
project.provider(resolveGemWorkDir)
this.gemWorkDir
}
/** If it is required that a JRubyExec task needs to be executed with a different version of JRuby that the
@ -189,7 +197,7 @@ class JRubyExec extends JavaExec implements JRubyAwareTask, JRubyExecSpec {
*/
@Deprecated
String getJrubyVersion() {
deprecated('Use jruby.getJrubyVersion rather getJrubyVersion()')
deprecated('Use jruby.getJrubyVersion() rather getJrubyVersion()')
jruby.jrubyVersion
}
@ -254,7 +262,7 @@ class JRubyExec extends JavaExec implements JRubyAwareTask, JRubyExecSpec {
void exec() {
File gemDir = getGemWorkDir().get()
setEnvironment prepareJRubyEnvironment(this.environment, this.inheritRubyEnv, gemDir)
super.classpath jruby.jrubyConfiguration
super.classpath(jruby.jrubyConfiguration)
super.setArgs(getArgs())
super.exec()
}
@ -263,11 +271,12 @@ class JRubyExec extends JavaExec implements JRubyAwareTask, JRubyExecSpec {
*
* There are three modes of behaviour
* <ul>
* <li> script set. no jrubyArgs, or jrubyArgs does not contain {@code -S} - Normal way to execute script. A check
* <li> script set. no jrubyArgs, or jrubyArgs does not contain {@code -S}: normal way to execute script. A check
* whether the script exists will be performed.
* <li> script set. jrubyArgs contains {@code -S} - If script is not absolute, no check will be performed to see
* <li> script set. jrubyArgs contains {@code -S}: if script is not absolute, no check will be performed to see
* if the script exists and will be assumed that the script can be found using the default ruby path mechanism.
* <li> script not set, but jrubyArgs set - Set up to execute jruby with no script. This should be a rarely used otion.
* <li> script not set, but jrubyArgs set: set up to execute jruby with no script. This should be a rarely used
* option.
* </ul>
*
* @throw {@code org.gradle.api.InvalidUserDataException} if mode of behaviour cannot be determined.
@ -315,5 +324,8 @@ class JRubyExec extends JavaExec implements JRubyAwareTask, JRubyExecSpec {
private Object script
private final List<Object> scriptArgs = []
private final List<Object> jrubyArgs = []
private final ProjectOperations projectOperations
private final TaskContainer tasks
private final Provider<File> gemWorkDir
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -32,7 +32,7 @@ import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.artifacts.Configuration
import static org.ysb33r.grolifant.api.TaskProvider.registerTask
import static org.ysb33r.grolifant.api.v4.TaskProvider.registerTask
/** Base plugin for JRuby.
*
@ -62,7 +62,7 @@ class JRubyPlugin implements Plugin<Project> {
JRubyExecDelegate.addToProject(project, PROJECT_JRUBYEXEC)
registerTask(
project,
project.tasks,
'generateGradleRb',
GenerateGradleRb
).configure(generateGradleRbConfiguration(project))

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -29,16 +29,27 @@ import com.github.jrubygradle.internal.JRubyPrepareUtils
import groovy.transform.CompileStatic
import org.gradle.api.Action
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.UnknownTaskException
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.ConfigurationContainer
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.ResolutionStrategy
import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.api.artifacts.dsl.RepositoryHandler
import org.gradle.api.logging.Logger
import org.gradle.api.plugins.ExtensionAware
import org.gradle.api.provider.Provider
import org.ysb33r.grolifant.api.AbstractCombinedProjectTaskExtension
import org.gradle.api.provider.ProviderFactory
import org.gradle.api.tasks.TaskContainer
import org.ysb33r.grolifant.api.core.ProjectOperations
import org.ysb33r.grolifant.api.v4.AbstractCombinedProjectTaskExtension
import org.ysb33r.grolifant.api.v4.TaskProvider
import java.util.concurrent.Callable
import static org.ysb33r.grolifant.api.StringUtils.stringize
import static com.github.jrubygradle.JRubyPlugin.TASK_GROUP_NAME
import static org.ysb33r.grolifant.api.v4.StringUtils.stringize
/**
* Class providing the jruby DSL extension to the Gradle build script.
@ -50,7 +61,7 @@ import static org.ysb33r.grolifant.api.StringUtils.stringize
*/
@CompileStatic
class JRubyPluginExtension extends AbstractCombinedProjectTaskExtension {
public static final String DEFAULT_JRUBY_VERSION = '9.2.7.0'
public static final String DEFAULT_JRUBY_VERSION = '9.2.9.0'
public static final String NAME = 'jruby'
@ -60,6 +71,14 @@ class JRubyPluginExtension extends AbstractCombinedProjectTaskExtension {
*/
JRubyPluginExtension(Project p) {
super(p)
this.jrubyVersion = DEFAULT_JRUBY_VERSION
this.repositories = p.repositories
this.dependencies = p.dependencies
this.configurations = p.configurations
this.providers = p.providers
this.logger = p.logger
this.tasks = p.tasks
this.projectOperations = ProjectOperations.create(p)
}
/** Task extension constructor
@ -70,6 +89,13 @@ class JRubyPluginExtension extends AbstractCombinedProjectTaskExtension {
*/
JRubyPluginExtension(JRubyAwareTask t) {
super(t, NAME)
this.repositories = t.project.repositories
this.dependencies = t.project.dependencies
this.configurations = t.project.configurations
this.providers = t.project.providers
this.logger = t.project.logger
this.tasks = t.project.tasks
this.projectOperations = ProjectOperations.create(t.project)
}
/** The default version of jruby that will be used.
@ -86,7 +112,8 @@ class JRubyPluginExtension extends AbstractCombinedProjectTaskExtension {
/** Set a new JRuby version to use.
*
* @param v New version to be used. Can be of anything that be be resolved by {@link StringUtils.stringize ( Object o )}
* @param v New version to be used. Can be of anything that be be resolved by
* {@link org.ysb33r.grolifant.api.v4.StringUtils#stringize ( Object o )}
*
* @since 2.0
*/
@ -96,7 +123,8 @@ class JRubyPluginExtension extends AbstractCombinedProjectTaskExtension {
/** Set a new JRuby version to use.
*
* @param v New version to be used. Can be of anything that be be resolved by {@link StringUtils.stringize ( Object o )}
* @param v New version to be used. Can be of anything that be be resolved by
* {@link org.ysb33r.grolifant.api.v4.StringUtils#stringize ( Object o )}
*
* @since 2.0
*/
@ -152,8 +180,8 @@ class JRubyPluginExtension extends AbstractCombinedProjectTaskExtension {
'It is recommended that you explicitly declare your repositories rather than rely on ' +
'this functionality.'
)
project.repositories.jcenter()
((ExtensionAware) (project.repositories)).extensions.getByType(RepositoryHandlerExtension).gems()
repositories.jcenter()
((ExtensionAware) (repositories)).extensions.getByType(RepositoryHandlerExtension).gems()
} else {
deprecated(
'jruby.defaultRepositories are no longer switched on by default - you can safely remove ' +
@ -206,7 +234,7 @@ class JRubyPluginExtension extends AbstractCombinedProjectTaskExtension {
List<Dependency> deps = [createDependency(jrubyCompleteDep)]
Configuration configuration = project.configurations.detachedConfiguration(
Configuration configuration = configurations.detachedConfiguration(
deps.toArray() as Dependency[]
)
@ -220,16 +248,16 @@ class JRubyPluginExtension extends AbstractCombinedProjectTaskExtension {
/** Sets the GEM configuration.
*
* @param c Configuration instance, Character sequence as configuration name, or a {@code Provider<Configuration}.
*/
*/
void setGemConfiguration(final Object c) {
switch (c) {
case Configuration:
this.gemConfiguration = project.provider({ -> c } as Callable<Configuration>)
this.gemConfiguration = providers.provider({ -> c } as Callable<Configuration>)
registerPrepareTask(((Configuration) c).name)
break
case CharSequence:
this.gemConfiguration = project.provider(
{ -> project.configurations.getByName(c.toString()) } as Callable<Configuration>
{ -> configurations.getByName(c.toString()) } as Callable<Configuration>
)
registerPrepareTask(c.toString())
break
@ -247,7 +275,7 @@ class JRubyPluginExtension extends AbstractCombinedProjectTaskExtension {
/** Declarative way of setting the GEM configuration.
*
* @param c Configuration instance, Character sequence as configuration name, or a {@code Provider<Configuration}.
*/
*/
void gemConfiguration(final Object c) {
setGemConfiguration(c)
}
@ -305,29 +333,58 @@ class JRubyPluginExtension extends AbstractCombinedProjectTaskExtension {
}
private void deprecated(String msg) {
project.logger.info("Deprecated feature in ${NAME} extension. ${msg}")
logger.info("Deprecated feature in ${NAME} extension. ${msg}")
}
private Dependency createDependency(final String notation, final Closure configurator = null) {
if (configurator) {
project.dependencies.create(notation, configurator)
dependencies.create(notation, configurator)
} else {
project.dependencies.create(notation)
dependencies.create(notation)
}
}
private void registerPrepareTask(final String configurationName) {
JRubyPrepareUtils.registerPrepareTask(project, configurationName)
this.gemPrepareTaskName = JRubyPrepareUtils.taskName(configurationName)
final String taskName = JRubyPrepareUtils.taskName(configurationName)
final String gemDir = JRubyPrepareUtils.gemRelativePath(configurationName)
try {
TaskProvider.taskByName(tasks, taskName)
} catch (UnknownTaskException e) {
TaskProvider<JRubyPrepare> prepare = TaskProvider.registerTask(tasks, taskName, JRubyPrepare)
ProjectOperations po = this.projectOperations
Action<JRubyPrepare> configurator = new Action<JRubyPrepare>() {
void execute(JRubyPrepare jp) {
jp.with {
group = TASK_GROUP_NAME
description = "Prepare the gems/jars from the `${configurationName}` dependencies"
dependencies(project.configurations.getByName(configurationName))
outputDir = { ->
po.buildDirDescendant(gemDir)
}
}
}
}
prepare.configure(configurator as Action<? extends Task>)
prepare
}
this.gemPrepareTaskName = taskName//JRubyPrepareUtils.taskName(configurationName)
}
private static final String JRUBY_COMPLETE_DEPENDENCY = 'org.jruby:jruby-complete'
private Object jrubyVersion = DEFAULT_JRUBY_VERSION
private Object jrubyVersion
private Provider<Configuration> gemConfiguration
private String gemPrepareTaskName
private boolean taskResolutionStrategiesOnly = false
private final List<Action<ResolutionStrategy>> resolutionsStrategies = []
private final ProjectOperations projectOperations
private final RepositoryHandler repositories
private final ConfigurationContainer configurations
private final DependencyHandler dependencies
private final ProviderFactory providers
private final TaskContainer tasks
private final Logger logger
private boolean defaultRepositoriesCalled = false
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -26,6 +26,9 @@ package com.github.jrubygradle
import com.github.jrubygradle.api.core.AbstractJRubyPrepare
import com.github.jrubygradle.internal.JRubyExecUtils
import groovy.transform.CompileStatic
import org.gradle.api.provider.Provider
import java.util.concurrent.Callable
/** Task for preparing a project-local installation of GEMs & JARs.
*
@ -39,6 +42,9 @@ class JRubyPrepare extends AbstractJRubyPrepare {
JRubyPrepare() {
super()
this.jruby = extensions.create(JRubyPluginExtension.NAME, JRubyPluginExtension, this)
this.jrubyJarLocation = project.provider({ JRubyPluginExtension jrubyExt ->
JRubyExecUtils.jrubyJar(jrubyExt.jrubyConfiguration)
}.curry(this.jruby) as Callable<File>)
}
/** Location of {@code jruby-complete} JAR.
@ -46,10 +52,22 @@ class JRubyPrepare extends AbstractJRubyPrepare {
* @return Path on local filesystem
*/
@Override
protected File getJrubyJarLocation() {
JRubyExecUtils.jrubyJar(this.jruby.jrubyConfiguration)
protected Provider<File> getJrubyJarLocation() {
this.jrubyJarLocation
}
/** Version of JRuby to be used.
*
* This method should not resolve any files to obtain the version.
*
* @return Intended version of JRuby.
*/
@Override
protected String getProposedJRubyVersion() {
jruby.jrubyVersion
}
private final JRubyPluginExtension jruby
private final Provider<File> jrubyJarLocation
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -24,19 +24,24 @@
package com.github.jrubygradle.internal
import com.github.jrubygradle.JRubyPluginExtension
import com.github.jrubygradle.JRubyPrepare
import com.github.jrubygradle.api.core.JRubyExecSpec
import groovy.transform.CompileStatic
import org.gradle.api.Action
import org.gradle.api.Project
import org.gradle.api.file.FileCollection
import org.gradle.api.plugins.ExtensionContainer
import org.gradle.api.tasks.TaskContainer
import org.gradle.process.ExecResult
import org.gradle.process.JavaExecSpec
import org.ysb33r.grolifant.api.ClosureUtils
import org.ysb33r.grolifant.api.core.ProjectOperations
import org.ysb33r.grolifant.api.v4.ClosureUtils
import static com.github.jrubygradle.JRubyExec.MAIN_CLASS
import static com.github.jrubygradle.internal.JRubyExecUtils.buildArgs
import static com.github.jrubygradle.internal.JRubyExecUtils.prepareJRubyEnvironment
import static com.github.jrubygradle.internal.JRubyExecUtils.resolveScript
import static org.ysb33r.grolifant.api.StringUtils.stringize
import static org.ysb33r.grolifant.api.v4.StringUtils.stringize
/** Delegate for running JRuby using {@code project.jrubyexec}.
*
@ -44,6 +49,7 @@ import static org.ysb33r.grolifant.api.StringUtils.stringize
* @author R Tyler Croy
*
*/
@CompileStatic
class JRubyExecDelegate {
static void addToProject(final Project project, final String name) {
@ -64,44 +70,54 @@ class JRubyExecDelegate {
}
ExecResult call(@DelegatesTo(JRubyExecSpec) Closure cfg) {
project.javaexec { JavaExecSpec javaExecSpec ->
ExecSpec execSpec = new ExecSpec(project, javaExecSpec)
projectOperations.javaexec { JavaExecSpec javaExecSpec ->
ExecSpec execSpec = new ExecSpec(projectOperations, javaExecSpec)
ClosureUtils.configureItem(execSpec, cfg)
finaliseJavaExecConfiguration(execSpec, javaExecSpec)
}
}
ExecResult call(Action<JRubyExecSpec> cfg) {
project.javaexec { JavaExecSpec javaExecSpec ->
ExecSpec execSpec = new ExecSpec(project, javaExecSpec)
cfg.execute(spec)
projectOperations.javaexec { JavaExecSpec javaExecSpec ->
ExecSpec execSpec = new ExecSpec(projectOperations, javaExecSpec)
cfg.execute(execSpec)
finaliseJavaExecConfiguration(execSpec, javaExecSpec)
}
}
void finaliseJavaExecConfiguration(ExecSpec execSpec, JavaExecSpec javaExecSpec) {
JRubyPluginExtension jruby = project.extensions.getByType(JRubyPluginExtension)
JRubyPluginExtension jruby = extensions.getByType(JRubyPluginExtension)
javaExecSpec.with {
main = MAIN_CLASS
classpath = jruby.jrubyConfiguration
args = buildArgs([], execSpec.jrubyArgs, execSpec.script, execSpec.scriptArgs)
args = buildArgs(
[],
execSpec.jrubyArgs as List<Object>,
execSpec.script,
execSpec.scriptArgs as List<Object>
)
environment = prepareJRubyEnvironment(
environment,
execSpec.inheritRubyEnv,
project.tasks.getByName(jruby.gemPrepareTaskName).outputDir
((JRubyPrepare)tasks.getByName(jruby.gemPrepareTaskName)).outputDir
)
}
}
private JRubyExecDelegate(Project project) {
this.project = project
this.projectOperations = ProjectOperations.find(project)
this.tasks = project.tasks
this.extensions = project.extensions
}
private final Project project
private final ProjectOperations projectOperations
private final TaskContainer tasks
private final ExtensionContainer extensions
private static class ExecSpec implements JRubyExecSpec {
ExecSpec(Project project, JavaExecSpec spec) {
this.project = project
ExecSpec(ProjectOperations projectOperations, JavaExecSpec spec) {
this.projectOperations = projectOperations
this.javaExecSpec = spec
}
@ -139,12 +155,12 @@ class JRubyExecDelegate {
@Override
void script(Object scr) {
this.script = resolveScript(project, scr)
this.script = resolveScript(projectOperations, scr)
}
@Override
void setScript(Object scr) {
this.script = resolveScript(project, scr)
this.script = resolveScript(projectOperations, scr)
}
@Override
@ -195,6 +211,6 @@ class JRubyExecDelegate {
private final List<String> jrubyArgs = []
private final @Delegate
JavaExecSpec javaExecSpec
private final Project project
private final ProjectOperations projectOperations
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -24,20 +24,17 @@
package com.github.jrubygradle.internal
import com.github.jrubygradle.JRubyPlugin
import com.github.jrubygradle.JRubyPluginExtension
import com.github.jrubygradle.api.gems.GemOverwriteAction
import com.github.jrubygradle.api.gems.GemUtils
import groovy.transform.CompileDynamic
import groovy.transform.CompileStatic
import org.gradle.api.InvalidUserDataException
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.ysb33r.grolifant.api.OperatingSystem
import org.ysb33r.grolifant.api.StringUtils
import org.ysb33r.grolifant.api.core.ProjectOperations
import org.ysb33r.grolifant.api.v4.StringUtils
import java.util.regex.Matcher
import static org.ysb33r.grolifant.api.StringUtils.stringize
import static org.ysb33r.grolifant.api.v4.StringUtils.stringize
/** Utilities for preparation or executing JRuby.
*
@ -120,17 +117,17 @@ class JRubyExecUtils {
/** Resolves a script location object.
*
* @paream project Project context for script.
* @paream project Project operations for script.
* @param script Script to resolve.
* @return Resolved script location. Will be {@code null} if {@code script == null},
*/
static File resolveScript(Project project, Object script) {
static File resolveScript(ProjectOperations projectOperations, Object script) {
if (script) {
File intermediate = script instanceof File ? (File) script : new File(stringize(script))
if (intermediate.absolute) {
intermediate
} else {
intermediate.parentFile ? project.file(script) : intermediate
intermediate.parentFile ? projectOperations.file(script) : intermediate
}
} else {
null
@ -217,58 +214,45 @@ class JRubyExecUtils {
return path.absolutePath + File.pathSeparatorChar + originalPath
}
/**
* Update the given configuration on the project with the appropriate versions
* of JRuby and supplemental dependencies to execute JRuby successfully
*/
static void updateJRubyDependenciesForConfiguration(Project project, String configuration, String version) {
Configuration c = project.configurations.findByName(configuration)
/* Only define this dependency if we don't already have it */
if (!(c.dependencies.find { it.name == JRUBY_COMPLETE })) {
project.dependencies.add(configuration, "org.jruby:jruby-complete:${version}")
}
}
/**
* Prepare the Ruby and Java dependencies for the configured configuration
*
* This method will determine the appropriate dependency overwrite behavior
* from the Gradle invocation. In effect, if the --refresh-dependencies flag
* is used, already installed gems will be overwritten.
*
* @param project The associated Gradle project.
* @param gemWorkDir THe GEM unpack/working directory.
* @param jruby The associated JRuby project or task extension.
* @param gemConfiguration Configuration which contains GEMs for unpacking.
* @param overwrite Overwrite mode.
*
* @since 2.0
*/
static void prepareDependencies(
Project project,
File gemWorkDir,
JRubyPluginExtension jruby,
Configuration gemConfiguration,
GemOverwriteAction overwrite
) {
File gemDir = gemWorkDir.absoluteFile
gemDir.mkdirs()
GemUtils.extractGems(
project,
jruby.jrubyConfiguration,
gemConfiguration,
gemDir,
overwrite
)
GemUtils.setupJars(
gemConfiguration,
gemDir,
overwrite
)
}
// /**
// * Prepare the Ruby and Java dependencies for the configured configuration
// *
// * This method will determine the appropriate dependency overwrite behavior
// * from the Gradle invocation. In effect, if the --refresh-dependencies flag
// * is used, already installed gems will be overwritten.
// *
// * @param project The associated Gradle project.
// * @param gemWorkDir THe GEM unpack/working directory.
// * @param jruby The associated JRuby project or task extension.
// * @param gemConfiguration Configuration which contains GEMs for unpacking.
// * @param overwrite Overwrite mode.
// *
// * @since 2.0
// */
// static void prepareDependencies(
// Project project,
// File gemWorkDir,
// JRubyPluginExtension jruby,
// Configuration gemConfiguration,
// GemOverwriteAction overwrite
// ) {
// File gemDir = gemWorkDir.absoluteFile
//
// gemDir.mkdirs()
//
// GemUtils.extractGems(
// project,
// jruby.jrubyConfiguration,
// gemConfiguration,
// gemDir,
// overwrite
// )
// GemUtils.setupJars(
// gemConfiguration,
// gemDir,
// overwrite
// )
// }
/** Prepare en environment which can be used to execute JRuby.
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -23,17 +23,10 @@
*/
package com.github.jrubygradle.internal
import com.github.jrubygradle.JRubyPrepare
import groovy.transform.CompileStatic
import org.gradle.api.Action
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.UnknownTaskException
import org.ysb33r.grolifant.api.TaskProvider
import static com.github.jrubygradle.JRubyPlugin.DEFAULT_CONFIGURATION
import static com.github.jrubygradle.JRubyPlugin.DEFAULT_PREPARE_TASK
import static com.github.jrubygradle.JRubyPlugin.TASK_GROUP_NAME
/** Utilities to deal with JRubPrepare tasks
*
@ -56,44 +49,11 @@ class JRubyPrepareUtils {
/** GEM working (unpack) relative path by convention.
*
* @param configurationName Name of a GEM configuration.
* @param configurationName Name of a GEM configuration.
* @return Associated relative path to project directory.
*/
static String gemRelativePath(String configurationName) {
configurationName == DEFAULT_CONFIGURATION ? '.gems' :
".gems-${configurationName}"
}
/** Registers (or creates) a JRUbyPrepare tasks based upon a configuration name
*
* @param project Associated project
* @param configurationName
* @return Grolifant {@code TaskProvider}.
*/
static TaskProvider<JRubyPrepare> registerPrepareTask(
final Project project,
final String configurationName
) {
final String taskName = taskName(configurationName)
final String gemDir = gemRelativePath(configurationName)
try {
TaskProvider.taskByName(project, taskName)
} catch (UnknownTaskException e) {
TaskProvider<JRubyPrepare> prepare = TaskProvider.registerTask(project, taskName, JRubyPrepare)
Action<JRubyPrepare> configurator = new Action<JRubyPrepare>() {
void execute(JRubyPrepare jp) {
jp.with {
group = TASK_GROUP_NAME
description = "Prepare the gems/jars from the `${configurationName}` dependencies"
dependencies(project.configurations.getByName(configurationName))
outputDir { "${project.buildDir}/${gemDir}" }
}
}
}
prepare.configure(configurator as Action<? extends Task>)
prepare
}
}
}

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
# Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
# Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
# Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
# Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,6 +1,6 @@
<!--
Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
Permission is hereby granted, free of charge, to any person obtaining

View File

@ -25,6 +25,7 @@ allprojects {
targetCompatibility = '1.8'
ext {
olderJRubyVersion = '9.2.1.0'
spockVersion = "org.spockframework:spock-core:1.2-groovy-2.4"
pluginExtraText = (version.contains('-alpha') || version.contains('-beta')) ?
'(If you need a production-ready version of the JRuby/Gradle plugin use a 1.7.x release instead)': ''
@ -32,12 +33,10 @@ allprojects {
}
subprojects {
apply plugin: 'maven'
repositories {
jcenter()
maven { url torqueboxProxy }
}
if (project.name != 'docs') {
@ -55,8 +54,8 @@ subprojects {
dependencies {
compile localGroovy()
compile gradleApi()
compile 'org.ysb33r.gradle:grolifant:0.12'
gradleTestRuntime 'org.ysb33r.gradle:grolifant:0.12'
compile "org.ysb33r.gradle:grolifant50:${grolifantVersion}"
gradleTestRuntime "org.ysb33r.gradle:grolifant50:${grolifantVersion}"
}
codenarc {
@ -79,10 +78,17 @@ subprojects {
gradleTest {
// https://github.com/jruby-gradle/jruby-gradle-plugin/issues/346
if (JavaVersion.current().java11) {
versions '5.0', '5.4.1'
versions '5.0', '5.4.1', '6.0.1', '6.7'
} else {
versions '4.2', '4.10.2', '5.3.1'
versions '4.10.2', '5.3.1', '6.0.1', '6.7'
if(project.name == 'jruby-gradle-core-plugin' ) {
versions '4.3'
} else {
versions '4.9'
}
}
dependsOn jar
}
@ -100,10 +106,8 @@ subprojects {
ideReport.enabled = true
ideReport.destination = file( "${project.codenarc.reportsDir}/${reportName}.ide.txt")
}
}
idea {
module {
downloadJavadoc = true
@ -114,6 +118,6 @@ subprojects {
task release(type: Exec) {
description 'Create and upload a release'
dependsOn subprojects.collect { ":${it.name}:bintrayUpload" }
dependsOn subprojects.findAll { it.name != 'docs' }.collect { ":${it.name}:bintrayUpload" }
commandLine 'git', 'tag', "v${project.version}"
}

View File

@ -8,3 +8,65 @@ This plugin offers the following functionality:
* Conversion between GEM-style and Ivy-style dependencies notations.
* An abstract task class (`AbstractJRubyPrepare`) for preparing local GEM + JAR installations.
== Getting Started
=== Compatibility
This plugin requires link:http://gradle.org[Gradle] 4.3 or better
=== Installing
.build.gradle
[source, groovy]
----
plugins {
id 'com.github.jruby-gradle.core' version 'VERSION-OF-PLUGIN'
}
----
=== Adding repositories
.build.gradle
[source,groovy]
----
repositories {
ruby.gems() // <1>
ruby.gems { // <2>
prerelease = true
}
ruby.gems('https://foo.bar') // <3>
ruby.gems('acme-rubygems', 'https://foo.bar') // <4>
ruby.mavengems() // <5>
ruby.mavengems('https://foo.bar') // <6>
ruby.mavengems('acme-rubygems', 'https://foo.bar') // <7>
}
----
<1> Proxy rubygems.org directly and use `rubygems` as the Maven coordinate group.
<2> Proxy rubygems.org directly and allow prerelease GEMs to be considered. Use `rubygems` as the Maven coordinate group.
<3> Proxy a custom rubygems repository.
<4> Proxy a custom rubygems repository and assign a custom Maven coordinate group.
<5> Adds a Maven repository that uses the one official supported by the JRuby group. In order to use this, GEM dependencies should all be placed in the `rubygems` group.
<6> Adds a custom Maven repository that will proxy a GEMs repository. In order to use this, GEM dependencies should all be placed in the `rubygems` group.
<7> Adds a custom Maven repository that will proxy a GEMs repository, but allocate a custom dedicated Maven group. This is useful where you would want to use both the public repository and your own, but you want to save network query traffic, by only query repositories where you know the dependencies should exist.
== Advanced
=== Customising GEM resolving
By default the `rubygems` configuration and others added via `ruby.mavengems()` and `ruby.gems()` will have additional resolving strategies applied that mimicks GEM behaviour rather then Gradle behaviour. It is possible to customise this behaviour.
.build.gradle
[source,groovy]
----
gemResolverStrategy {
excludeConfigurations 'foo', 'bar' // <1>
excludeModule 'foo.*' // <2>
excludeModule 'foo.*', /1\.2.*/ // <3>
useGemVersionResolver 'gems2'
}
----
<1> Exclude configurations `foo` and `bar` from being considered for GEM resolver strategies.
<2> Exclude module that matches regular expression from GEM resolver strategies.
<3> Exclude module and version that matches regular expression from GEM resolver strategies.
<4> Apply GEM resolver strategies to a specific configuration.

View File

@ -36,8 +36,15 @@ bintray {
vcsTag = "v${project.version}"
attributes = ['gradle-plugin': 'com.github.jruby-gradle.core:com.github.jruby-gradle:jruby-gradle-core-plugin']
desc = 'This plugin provides some core dependency resolution for JRuby/Gradle'
}
}
}
processResources {
filesMatching '**/com.jrubygradle.core-plugin.version.properties', {
expand VERSION : project.version
}
}
bintrayUpload.dependsOn assemble

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -30,6 +30,7 @@ import org.junit.rules.TemporaryFolder
import spock.lang.IgnoreIf
import spock.lang.Issue
import spock.lang.Specification
import spock.lang.Unroll
import java.util.regex.Pattern
@ -185,7 +186,7 @@ class IvyXmlProxyServerIntegrationSpec extends Specification {
build()
then:
findFiles (~/^asciidoctor-pdf.*\.gem$/).size() == 3
findFiles(~/^asciidoctor-pdf.*\.gem$/).size() == 3
}
@Issue('https://github.com/jruby-gradle/jruby-gradle-plugin/issues/380')
@ -208,6 +209,21 @@ class IvyXmlProxyServerIntegrationSpec extends Specification {
findFiles ~/^bibtex-ruby-4.4.7.gem$/
}
void 'Resolve a transitive dependency which is jruby-specific'() {
setup:
withBuildFile '''
dependencies {
something 'rubygems:rubocop:0.77.0'
}
'''
when:
build()
then:
findFiles ~/^jaro_winkler-1.5.\d+-java.gem$/
}
private List<File> findFiles(Pattern pat) {
new File(projectDir, 'build/something').listFiles(new FilenameFilter() {
@Override
@ -228,14 +244,16 @@ class IvyXmlProxyServerIntegrationSpec extends Specification {
.build()
}
private void withBuildFile(String content) {
private void withBuildFile(String content, boolean prerelease = false) {
buildFile.text = """
plugins {
id 'com.github.jruby-gradle.core'
}
repositories {
ruby.gems()
ruby.gems {
prerelease = ${prerelease}
}
}
configurations {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -29,10 +29,13 @@ import groovy.transform.CompileStatic
import org.gradle.api.DefaultTask
import org.gradle.api.artifacts.Configuration
import org.gradle.api.file.FileCollection
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.TaskAction
import org.ysb33r.grolifant.api.core.ProjectOperations
import static com.github.jrubygradle.api.gems.GemOverwriteAction.SKIP
import static com.github.jrubygradle.api.gems.GemUtils.extractGems
@ -50,13 +53,18 @@ import static com.github.jrubygradle.api.gems.GemUtils.setupJars
abstract class AbstractJRubyPrepare extends DefaultTask implements JRubyAwareTask {
protected AbstractJRubyPrepare() {
this.projectOperations = ProjectOperations.find(project)
this.outputDir = {
ProjectOperations projectOperations -> projectOperations.buildDirDescendant('.gems')
}.curry(this.projectOperations)
outputs.dir({ AbstractJRubyPrepare t -> new File(t.getOutputDir(), 'gems') }.curry(this))
}
/** Target directory for GEMs. Extracted GEMs will end up in {@code outputDir + "/gems"}
*/
@Internal
File getOutputDir() {
project.file(this.outputDir)
projectOperations.file(this.outputDir)
}
/** Sets the output directory
@ -81,7 +89,7 @@ abstract class AbstractJRubyPrepare extends DefaultTask implements JRubyAwareTas
*/
@InputFiles
FileCollection gemsAsFileCollection() {
return GemUtils.getGems(project.files(this.dependencies))
return GemUtils.getGems(projectOperations.files(this.dependencies))
}
@Internal
@ -96,16 +104,38 @@ abstract class AbstractJRubyPrepare extends DefaultTask implements JRubyAwareTas
this.dependencies.addAll(f.toList())
}
/**
*
* @return Configuration Cache safe project operations service.
*
* @since 2.1.0
*/
protected ProjectOperations getProjectOperations() {
this.projectOperations
}
/** Location of {@code jruby-complete} JAR.
*
* @return Path on local filesystem
*/
abstract protected File getJrubyJarLocation()
@Internal
abstract protected Provider<File> getJrubyJarLocation()
/** Version of JRuby to be used.
*
* This method should not resolve any files to obtain the version.
*
* @return Intended version of JRuby. Can be {@code null} if the version
* is indirectly inferred via configuration.
*/
@Input
@Optional
abstract protected String getProposedJRubyVersion()
@TaskAction
void exec() {
File out = getOutputDir()
File jrubyJar = jrubyJarLocation
File jrubyJar = jrubyJarLocation.get()
extractGems(project, jrubyJar, gemsAsFileCollection(), out, SKIP)
dependencies.findAll {
@ -115,6 +145,7 @@ abstract class AbstractJRubyPrepare extends DefaultTask implements JRubyAwareTas
}
}
private Object outputDir = { -> "${project.buildDir}/.gems" }
private Object outputDir
private final ProjectOperations projectOperations
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.github.jrubygradle.api.core
import groovy.transform.CompileStatic
/** Additional options for configuring a remote GEM repository
*
* @author Schalk W. Cronjé
*
* @since 2.0
*/
@CompileStatic
class GemRepositoryConfiguration {
/** Set whether pre-release GEMs should be considered.
*
*/
boolean prerelease = false
}

View File

@ -1,5 +1,5 @@
/**
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/**
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -30,6 +30,7 @@ import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.plugins.ExtensionAware
import org.ysb33r.grolifant.api.core.ProjectOperations
/** Provides only a repository handler extensiosn for looking up rubygem
* metadata.
@ -42,6 +43,7 @@ import org.gradle.api.plugins.ExtensionAware
class JRubyCorePlugin implements Plugin<Project> {
@Override
void apply(Project project) {
ProjectOperations.maybeCreateExtension(project)
GemResolverStrategy gemGroups = project.extensions.create(GemResolverStrategy.NAME, GemResolverStrategy)
((ExtensionAware) project.repositories).extensions.create(

View File

@ -1,5 +1,5 @@
/**
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -29,10 +29,15 @@ import groovy.transform.CompileDynamic
import groovy.transform.CompileStatic
import org.gradle.api.Action
import org.gradle.api.Project
import org.gradle.api.artifacts.dsl.RepositoryHandler
import org.gradle.api.artifacts.repositories.ArtifactRepository
import org.gradle.api.artifacts.repositories.IvyArtifactRepository
import org.gradle.api.artifacts.repositories.MavenArtifactRepository
import org.gradle.api.plugins.ExtensionContainer
import org.gradle.util.GradleVersion
import org.ysb33r.grolifant.api.v4.ClosureUtils
import static org.ysb33r.grolifant.api.v4.UriUtils.urize
/** Extension which can be added to {@code project.repositories}.
*
@ -50,17 +55,42 @@ class RepositoryHandlerExtension {
* @param project Gradle project.
*/
RepositoryHandlerExtension(final Project project) {
this.project = project
this.extensions = project.extensions
this.repositories = project.repositories
this.ivyProxies = new IvyXmlGlobalProxyRegistry(project)
}
/** Create an artifact repository which will use {@link https://rubygems.org} and
/** Create an artifact repository which will use https://rubygems.org and
* associate group {@code rubygems} with it.
*
* @return Artifact repository.
*/
ArtifactRepository gems() {
bindRepositoryToProxyServer('https://rubygems.org'.toURI(), DEFAULT_GROUP_NAME)
bindRepositoryToProxyServer(
RUBYGEMS_URI,
DEFAULT_GROUP_NAME,
new GemRepositoryConfiguration()
)
}
/** Create an artifact repository which will use https://rubygems.org and
* associate group {@code rubygems} with it.
*
* @param cfg GEM repository configuration
* @return Artifact repository.
*/
ArtifactRepository gems(@DelegatesTo(GemRepositoryConfiguration) Closure cfg) {
bindRepositoryToProxyServer(RUBYGEMS_URI, DEFAULT_GROUP_NAME, cfg)
}
/** Create an artifact repository which will use https://rubygems.org and
* associate group {@code rubygems} with it.
*
* @param cfg GEM repository configuration
* @return Artifact repository.
*/
ArtifactRepository gems(Action<GemRepositoryConfiguration> cfg) {
bindRepositoryToProxyServer(RUBYGEMS_URI, DEFAULT_GROUP_NAME, cfg)
}
/** Create an artifact repository which will use specified URI and
@ -72,7 +102,33 @@ class RepositoryHandlerExtension {
* @return Artifact repository.
*/
ArtifactRepository gems(Object uri) {
bindRepositoryToProxyServer(project.uri(uri), DEFAULT_GROUP_NAME)
bindRepositoryToProxyServer(urize(uri), DEFAULT_GROUP_NAME, new GemRepositoryConfiguration())
}
/** Create an artifact repository which will use specified URI and
* associate group {@code rubygems} with it.
*
* @param uri URI of remote repository that serves up Rubygems. Any object convertible
* with {@code project.uri} can be provided.
* @param cfg GEM repository configuration
*
* @return Artifact repository.
*/
ArtifactRepository gems(Object uri, @DelegatesTo(GemRepositoryConfiguration) Closure cfg) {
bindRepositoryToProxyServer(urize(uri), DEFAULT_GROUP_NAME, cfg)
}
/** Create an artifact repository which will use specified URI and
* associate group {@code rubygems} with it.
*
* @param uri URI of remote repository that serves up Rubygems. Any object convertible
* with {@code project.uri} can be provided.
* @param cfg GEM repository configuration
*
* @return Artifact repository.
*/
ArtifactRepository gems(Object uri, Action<GemRepositoryConfiguration> cfg) {
bindRepositoryToProxyServer(urize(uri), DEFAULT_GROUP_NAME, cfg)
}
/** Create an artifact repository which will use specified URI and
@ -84,42 +140,124 @@ class RepositoryHandlerExtension {
* @return Artifact repository.
*/
ArtifactRepository gems(String group, Object uri) {
bindRepositoryToProxyServer(project.uri(uri), group)
bindRepositoryToProxyServer(urize(uri), group, new GemRepositoryConfiguration())
}
/** Adds the legacy Torquebox Maven proxy to {@code rubygems.org}.
/** Create an artifact repository which will use specified URI and
* associate a specified group with it.
*
* Please note that this proxy is effectively unmaintained an no longer supported
* by the original creators.
*
* @return Maven artifact repository
* @param group Group to associate this server with.
* @param uri URI of remote repository that serves up Rubygems. Any object convertible
* with {@code project.uri} can be provided.
* @param cfg GEM repository configuration
* @return Artifact repository.
*/
MavenArtifactRepository torquebox() {
Action mvnConfigurator = new Action<MavenArtifactRepository>() {
ArtifactRepository gems(String group, Object uri, @DelegatesTo(GemRepositoryConfiguration) Closure cfg) {
bindRepositoryToProxyServer(urize(uri), group, cfg)
}
/** Create an artifact repository which will use specified URI and
* associate a specified group with it.
*
* @param group Group to associate this server with.
* @param uri URI of remote repository that serves up Rubygems. Any object convertible
* with {@code project.uri} can be provided.
* @param cfg GEM repository configuration
* @return Artifact repository.
*/
ArtifactRepository gems(String group, Object uri, Action<GemRepositoryConfiguration> cfg) {
bindRepositoryToProxyServer(urize(uri), group, cfg)
}
/** Adds the Maven-GEMs proxy that is supported by the JRuby group.
*
* For supporting Gradle versions, this repository will only be consulted for artifacts that are in the
* {@code rubygems} group.
*
* @return Maven repository
*/
MavenArtifactRepository mavengems() {
bindToMavenRepository(MAVENGEMS_URI, DEFAULT_GROUP_NAME)
}
/** Adds a remote Maven-GEMs proxy.
*
* For supporting Gradle versions, this repository will only be consulted for artifacts that are in the
* {@code rubygems} group.
*
* @param uri Remote Maven-GEMs proxy
* @return Maven repository
*/
MavenArtifactRepository mavengems(Object uri) {
bindToMavenRepository(urize(uri), DEFAULT_GROUP_NAME)
}
/** Adds a remote Maven-GEMs proxy anbd allocate a dedicated group for it.
*
* For supporting Gradle versions, this repository will only be consulted for artifacts that are in the
* specified group.
*
* @param group Maven group name
* @param uri Remote Maven-GEMs proxy
* @return Maven repository
*/
MavenArtifactRepository mavengems(String group, Object uri) {
bindToMavenRepository(urize(uri), group)
}
private MavenArtifactRepository bindToMavenRepository(
URI serverUri,
String group
) {
MavenArtifactRepository repo = repositories.maven(new Action<MavenArtifactRepository>() {
@Override
void execute(MavenArtifactRepository mvn) {
mvn.url = 'http://rubygems-proxy.torquebox.org/releases'.toURI()
mvn.url = serverUri
}
}
(MavenArtifactRepository)restrictToGems(
this.project.repositories.maven(mvnConfigurator),
DEFAULT_GROUP_NAME
)
})
restrictToGems(repo, group)
repo
}
private ArtifactRepository bindRepositoryToProxyServer(
URI serverUri,
String group
String group,
GemRepositoryConfiguration cfg
) {
IvyXmlProxyServer proxy = ivyProxies.registerProxy(serverUri, group)
project.extensions.getByType(GemResolverStrategy).addGemGroup(group)
IvyXmlProxyServer proxy = ivyProxies.registerProxy(serverUri, group, cfg)
extensions.getByType(GemResolverStrategy).addGemGroup(group)
restrictToGems(createIvyRepo(serverUri, proxy.bindAddress), group)
}
private ArtifactRepository bindRepositoryToProxyServer(
URI serverUri,
String group,
@DelegatesTo(GemRepositoryConfiguration) Closure cfg
) {
GemRepositoryConfiguration grc = new GemRepositoryConfiguration()
ClosureUtils.configureItem(grc, cfg)
bindRepositoryToProxyServer(serverUri, group, grc)
}
private ArtifactRepository bindRepositoryToProxyServer(
URI serverUri,
String group,
Action<GemRepositoryConfiguration> cfg
) {
GemRepositoryConfiguration grc = new GemRepositoryConfiguration()
cfg.execute(grc)
bindRepositoryToProxyServer(serverUri, group, grc)
}
@CompileDynamic
private IvyArtifactRepository createIvyRepo(URI server, URI bindAddress) {
this.project.repositories.ivy {
repositories.ivy {
artifactPattern "${server}/downloads/[artifact]-[revision](-[classifier]).gem"
ivyPattern "${bindAddress}/[organisation]/[module]/[revision]/ivy.xml"
if (HAS_SECURE_PROTOCOL_FEATURE) {
allowInsecureProtocol = true
}
}
}
@ -133,7 +271,11 @@ class RepositoryHandlerExtension {
repo
}
private final Project project
private final IvyXmlGlobalProxyRegistry ivyProxies
private final ExtensionContainer extensions
private final RepositoryHandler repositories
private static final boolean HAS_CONTENT_FEATURE = GradleVersion.current() >= GradleVersion.version('5.1')
private static final boolean HAS_SECURE_PROTOCOL_FEATURE = GradleVersion.current() >= GradleVersion.version('6.0')
private static final URI RUBYGEMS_URI = 'https://rubygems.org'.toURI()
private static final URI MAVENGEMS_URI = 'https://mavengems.jruby.org'.toURI()
}

View File

@ -1,5 +1,5 @@
/**
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -33,9 +33,10 @@ import java.util.List;
*
* @since 2.0.
*
* @see https://guides.rubygems.org/rubygems-org-api
* @see {@link https://guides.rubygems.org/rubygems-org-api}
*/
public interface RubyGemQueryRestApi {
/**
* Return all published versions for a specific GEM
*
@ -45,6 +46,16 @@ public interface RubyGemQueryRestApi {
*/
List<String> allVersions(String gemName) throws ApiException;
/**
* Return all published versions for a specific GEM
*
* @param gemName Name of GEM.
* @param includePrelease Whether pre-release versions should be included.
* @return List of versions. Can be empty if the GEM does not have any versions. Never {@code null}.
* @throws {@link ApiException} if a networking or parser error occurs.
*/
List<String> allVersions(String gemName, boolean includePrelease) throws ApiException;
/**
* Return latest published version of GEM.
*
@ -54,6 +65,16 @@ public interface RubyGemQueryRestApi {
*/
String latestVersion(String gemName) throws ApiException;
/**
* Return latest published version of GEM.
*
* @param gemName Name of GEM.
* @param allowPrerelease Whether a prereleased version can be considered a latest version.
* @return Version of GEM
* @throws {@link ApiException} if GEM does not exist.
*/
String latestVersion(String gemName, boolean allowPrerelease) throws ApiException;
/** Returns the basic metadata for a GEM.
*
* @param gemName Name of GEM.

View File

@ -1,5 +1,5 @@
/**
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/**
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -65,7 +65,7 @@ class GemResolverStrategy {
* @param configs Configurations to be excluded
*/
void excludeConfigurations(Configuration... configs) {
this.excludedConfigurations.addAll(configs*.name)
this.excludedConfigurations.addAll(configs*.name as Iterable<String>)
}
/** Exclude a configuration from being resolved using the GEM
@ -102,7 +102,7 @@ class GemResolverStrategy {
/** Whether the GEM version resolving strategy should be applied for a specific module.
*
* In most cases this will alsways be {@code true} unless a specific rule excludes it.
* In most cases this will always be {@code true} unless a specific rule excludes it.
*
* @param mvs Module version selector
* @return Whether the Bundler-like version selector atregty may be applied
@ -132,7 +132,7 @@ class GemResolverStrategy {
}
}
private final Set<Matcher> excludedModules = [].toSet()
private final Set<String> excludedConfigurations = [].toSet()
private final Set<Matcher> excludedModules = [].toSet() as Set<Matcher>
private final Set<String> excludedConfigurations = [].toSet() as Set<String>
private final Set<String> groups = [RepositoryHandlerExtension.DEFAULT_GROUP_NAME].toSet()
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -23,8 +23,8 @@
*/
package com.github.jrubygradle.api.gems
import groovy.transform.CompileDynamic
import groovy.transform.CompileStatic
import groovy.util.logging.Slf4j
import org.gradle.api.Action
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
@ -33,9 +33,9 @@ import org.gradle.api.file.CopySpec
import org.gradle.api.file.DuplicateFileCopyingException
import org.gradle.api.file.FileCollection
import org.gradle.process.JavaExecSpec
import org.ysb33r.grolifant.api.OperatingSystem
import org.ysb33r.grolifant.api.core.OperatingSystem
import org.ysb33r.grolifant.api.core.ProjectOperations
import static com.github.jrubygradle.api.gems.GemOverwriteAction.SKIP
import static com.github.jrubygradle.api.gems.GemOverwriteAction.FAIL
import static com.github.jrubygradle.api.gems.GemOverwriteAction.OVERWRITE
@ -47,6 +47,7 @@ import static com.github.jrubygradle.api.gems.GemOverwriteAction.OVERWRITE
* @since 2.0
*/
@CompileStatic
@Slf4j
class GemUtils {
public static final String JRUBY_MAINCLASS = 'org.jruby.Main'
public static final String JRUBY_ARCHIVE_NAME = 'jruby-complete'
@ -69,7 +70,10 @@ class GemUtils {
* @param gem Gem file to extract.
* @param destDir Directory to extract to.
* @param overwrite Allow overwrite of an existing gem folder.
* @deprecated Use the version that takes a {@link ProjectOperations} instead as it will be safe when
* configuration cache is active.
*/
@Deprecated
static void extractGem(
Project project,
File jRubyClasspath,
@ -77,7 +81,27 @@ class GemUtils {
File destDir,
GemOverwriteAction overwrite
) {
ProjectOperations po = ProjectOperations.find(project)
extractGems(po, jRubyClasspath, po.files(gem), destDir, overwrite)
}
/** Extracts a gem to a folder
*
* @param project {@link ProjectOperations} instance.
* @param jRubyClasspath The path to the {@code jruby-complete} jar.
* @param gem Gem file to extract.
* @param destDir Directory to extract to.
* @param overwrite Allow overwrite of an existing gem folder.
*
* @since 2.1.0
*/
static void extractGem(
ProjectOperations project,
File jRubyClasspath,
File gem,
File destDir,
GemOverwriteAction overwrite
) {
extractGems(project, jRubyClasspath, project.files(gem), destDir, overwrite)
}
@ -88,13 +112,36 @@ class GemUtils {
* @param gems GEMs to install.
* @param destDir Directory to extract to.
* @param overwrite Allow overwrite of an existing gem folder.
*
* @deprecated Use the version that takes a {@Link ProjectOperations} instead.
*/
@Deprecated
static void extractGems(
Project project,
File jRubyClasspath,
FileCollection gems,
File destDir,
GemOverwriteAction overwrite
) {
extractGems(ProjectOperations.find(project), jRubyClasspath, gems, destDir, overwrite)
}
/** Extracts and install a collection of GEMs.
*
* @param project {@link ProjectOperations} instance.
* @param jRubyClasspath The path to the {@code jruby-complete} jar.
* @param gems GEMs to install.
* @param destDir Directory to extract to.
* @param overwrite Allow overwrite of an existing gem folder.
*
* @since 2.1.0
*/
static void extractGems(
ProjectOperations project,
File jRubyClasspath,
FileCollection gems,
File destDir,
GemOverwriteAction overwrite
) {
Set<File> gemsToProcess = []
Set<File> deletes = []
@ -107,7 +154,7 @@ class GemUtils {
File extractDirForJava = new File(destDir, "gems/${gemName}-java")
switch (overwrite) {
case SKIP:
case GemOverwriteAction.SKIP:
if (extractDir.exists() || extractDirForJava.exists()) {
return
}
@ -125,10 +172,10 @@ class GemUtils {
}
if (gemsToProcess.size()) {
deletes.each { project.delete it }
deletes.each { project.delete(it) }
destDir.mkdirs()
project.logger.info("Installing ${gemsToProcess*.name.join(',')}")
log.info("Installing ${gemsToProcess*.name.join(',')}")
project.javaexec { JavaExecSpec spec ->
spec.with {
@ -189,13 +236,40 @@ class GemUtils {
* @param gemConfig Configuration containing GEMs
* @param destDir Directory to extract to
* @param action Allow overwrite of an existing gem folder
* @deprecated Use the version that takes a {@Link ProjectOperations} instead
*/
@Deprecated
static void extractGems(
Project project,
Configuration jRubyConfig,
Configuration gemConfig,
File destDir,
GemOverwriteAction action) {
extractGems(
ProjectOperations.find(project),
jRubyConfig,
gemConfig,
destDir,
action
)
}
/** Extract Gems from a given configuration.
*
* @param projectOperations Project instance
* @param jRubyClasspath Where to find the jruby-complete jar
* @param gemConfig Configuration containing GEMs
* @param destDir Directory to extract to
* @param action Allow overwrite of an existing gem folder
*
* @since 1.0
*/
static void extractGems(
ProjectOperations projectOperations,
Configuration jRubyConfig,
Configuration gemConfig,
File destDir,
GemOverwriteAction action) {
Set<File> cp = jRubyConfig.files
File jRubyClasspath = cp.find { it.name.startsWith(JRUBY_ARCHIVE_NAME) }
@ -204,7 +278,7 @@ class GemUtils {
"Cannot find ${JRUBY_ARCHIVE_NAME}. Classpath contains ${cp.join(':')}"
)
}
extractGems(project, jRubyClasspath, project.files(gemConfig.files), destDir, action)
extractGems(projectOperations, jRubyClasspath, projectOperations.files(gemConfig.files), destDir, action)
}
/** Write a JARs lock file if the content has changed.
@ -325,27 +399,47 @@ class GemUtils {
* @param Additional properties to control behaviour
* @param dir The source of the GEM files
* @return Returns a CopySpec which can be attached as a child to another object that implements a CopySpec
* @since 0.1.2
* @since 0.1.2*
* @deprecated Use the version that takes a {@link ProjectOperations}.
*/
@CompileDynamic
@Deprecated
static CopySpec gemCopySpec(Map properties = [:], Project project, Object dir) {
gemCopySpec(properties, ProjectOperations.find(project), dir)
}
/** Adds a GEM CopySpec to an archive
*
* The following are supported as properties:
* <ul>
* <li>fullGem (boolean) - Copy all of the GEM content, not just a minimal subset</li>
* <li>subfolder (Object) - Adds an additional subfolder into the GEM
* </ul>
*
* @param Additional properties to control behaviour
* @param dir The source of the GEM files
* @return Returns a CopySpec which can be attached as a child to another object that implements a CopySpec
* @since 1.0
*/
static CopySpec gemCopySpec(Map properties = [:], ProjectOperations projectOperations, Object dir) {
boolean fullGem = properties['fullGem']
String subFolder = properties['subfolder']
project.copySpec(new Action<CopySpec>() {
projectOperations.copySpec(new Action<CopySpec>() {
void execute(CopySpec spec) {
spec.with {
from(dir) {
include EVERYTHING
// TODO have some standard which is bin/*, gems/**
// specifications/*
if (!fullGem) {
exclude 'cache/**'
exclude 'gems/*/test/**'
exclude 'gems/*/tests/**'
exclude 'gems/*/spec/**'
exclude 'gems/*/specs/**'
exclude 'build_info'
from(dir) { CopySpec cs ->
cs.with {
include EVERYTHING
// TODO have some standard which is bin/*, gems/**
// specifications/*
if (!fullGem) {
exclude 'cache/**'
exclude 'gems/*/test/**'
exclude 'gems/*/tests/**'
exclude 'gems/*/spec/**'
exclude 'gems/*/specs/**'
exclude 'build_info'
}
}
}
if (subFolder) {
@ -356,6 +450,7 @@ class GemUtils {
})
}
@Deprecated
static CopySpec jarCopySpec(Project project, Object dir) {
project.copySpec { CopySpec spec ->
spec.with {
@ -364,6 +459,14 @@ class GemUtils {
}
}
static CopySpec jarCopySpec(ProjectOperations projectOperations, Object dir) {
projectOperations.copySpec { CopySpec spec ->
spec.with {
from(dir) { include EVERYTHING }
}
}
}
private static final String GEM = 'gem'
private static final String GEM_EXTENSION = '.gem'
private static final String EVERYTHING = '**'

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -62,6 +62,7 @@ import static com.github.jrubygradle.api.gems.GemVersion.Boundary.OPEN_ENDED
*
* @author Christian Meier
* @author Schalk W. Cronjé
* @author Guillaume Grossetie
*
* @since 2.0 (Moved here from base plugin where it existed since 0.4.0)
*/
@ -177,7 +178,7 @@ class GemVersion implements Comparable<GemVersion> {
gemVersions.first()
} else {
gemVersions[1..-1].inject(gemVersions.first()) { range, value ->
range.union(value)
range.intersect(value)
}
}
}
@ -300,66 +301,53 @@ class GemVersion implements Comparable<GemVersion> {
* @since 2.0
*/
GemVersion intersect(GemVersion other) {
Boundary newLowBoundary
String newLow
switch (compare(low, other.low)) {
case -1:
newLow = other.low
newLowBoundary = other.lowBoundary
break
case 0:
newLowBoundary = (lowBoundary == EXCLUSIVE || other.lowBoundary == EXCLUSIVE) ? EXCLUSIVE : INCLUSIVE
newLow = low
break
case 1:
newLow = low
newLowBoundary = lowBoundary
}
Boundary newHighBoundary
String newHigh
if (!high && other.high) {
newHigh = other.high
newHighBoundary = other.highBoundary
} else if (high && !other.high) {
newHigh = high
newHighBoundary = highBoundary
} else if (!high && !other.high) {
newHigh = null
newHighBoundary = highBoundary
} else {
switch (compare(high, other.high)) {
case 1:
newHigh = other.high
newHighBoundary = other.highBoundary
break
case 0:
newHighBoundary = (highBoundary == EXCLUSIVE || other.highBoundary == EXCLUSIVE) ? EXCLUSIVE : INCLUSIVE
newHigh = high
break
case -1:
newHigh = high
newHighBoundary = highBoundary
Tuple2<String, Boundary> newLowVersionSpec = intersect(low, lowBoundary, other.low, other.lowBoundary, true)
Tuple2<String, Boundary> newHighVersionSpec = intersect(high, highBoundary, other.high, other.highBoundary, false)
GemVersion intersection = new GemVersion(newLowVersionSpec.second, newLowVersionSpec.first, newHighVersionSpec.first, newHighVersionSpec.second)
if (intersection == this) {
// is other a subset of this?
if (compare(this.low, other.low) >= 0 && compare(other.low, this.high) < 0 && compare(this.high, other.high) <= 0) {
return intersection
}
return NO_VERSION
}
return new GemVersion(newLowBoundary, newLow, newHigh, newHighBoundary)
if (intersection == other) {
// is this a subset of other?
if (compare(other.low, this.low) >= 0 && compare(this.low, other.high) < 0 && compare(other.high, this.high) <= 0) {
return intersection
}
return NO_VERSION
}
return intersection
}
/** Creates a new GEM version requirement which that the lowest of two requirements and the highest
* of those same requirement
*
* @param other Other GEM to combine with
* @return New GEM version requirement.
*
* @since 2.0
*/
GemVersion union(GemVersion other) {
List<GemVersion> pair = [this, other]
GemVersion min = pair.min()
GemVersion max = pair.max()
Tuple2<String,Boundary> intersect(String version, Boundary boundary, String otherVersion, Boundary otherBoundary, boolean low) {
Boundary newBoundary
String newVersion
if (!version && otherVersion) {
newVersion = otherVersion
newBoundary = otherBoundary
} else if (version && !otherVersion) {
newVersion = version
newBoundary = boundary
} else if (!version && !otherVersion) {
newVersion = null
newBoundary = boundary
} else {
int compareLow = low ? compare(version, otherVersion) : compare(otherVersion, version)
if (compareLow < 0) {
newVersion = otherVersion
newBoundary = otherBoundary
} else if (compareLow > 0) {
newVersion = version
newBoundary = boundary
} else {
newBoundary = (boundary == INCLUSIVE || otherBoundary == INCLUSIVE) ? INCLUSIVE : EXCLUSIVE
newVersion = version
}
}
new GemVersion(min.lowBoundary, min.low, max.high, max.highBoundary)
return new Tuple2(newVersion, newBoundary)
}
/** Allows for versions to be compared and sorted.
@ -480,13 +468,6 @@ class GemVersion implements Comparable<GemVersion> {
matcher[0][1]
}
// private GemVersion(Boolean lowInclusive, String low, String high, Boolean highInclusive) {
// this.lowBoundary = lowInclusive ? INCLUSIVE : EXCLUSIVE
// this.low = low
// this.high = high
// this.highBoundary = highInclusive ? INCLUSIVE : EXCLUSIVE
// }
private GemVersion(Boundary pre, String low, String high, Boundary post) {
this.lowBoundary = pre
this.low = low

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/**
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -24,6 +24,7 @@
package com.github.jrubygradle.internal.core
import com.github.jrubygradle.api.core.ApiException
import com.github.jrubygradle.api.core.GemRepositoryConfiguration
import com.github.jrubygradle.api.core.IvyXmlProxyServer
import com.github.jrubygradle.api.core.RubyGemQueryRestApi
import com.github.jrubygradle.api.gems.GemInfo
@ -94,12 +95,19 @@ abstract class AbstractIvyXmlProxyServer implements IvyXmlProxyServer {
* @param cache Root directory for local Ivy XML cache.
* @param serverUri URI of remote Rubygems proxy.
* @param group Group that will be associated with the Rubygems proxy.
* @param grc Additional configuration regarding remote GEM server
*/
protected AbstractIvyXmlProxyServer(File cache, URI serverUri, String group) {
protected AbstractIvyXmlProxyServer(
File cache,
URI serverUri,
String group,
GemRepositoryConfiguration grc
) {
localCachePath = cache
gemToIvy = new GemToIvy(serverUri)
api = new DefaultRubyGemRestApi(serverUri)
this.group = group
this.configuration = grc
}
@Synchronized
@ -170,7 +178,7 @@ abstract class AbstractIvyXmlProxyServer implements IvyXmlProxyServer {
protected String getDirectoryListing(String grp, String name) throws NotFound {
if (inGroups(grp)) {
debug "Request to find all versions for ${grp}:${name}"
List<String> versions = api.allVersions(name)
List<String> versions = api.allVersions(name, configuration.prerelease)
debug "Got versions ${versions.join(', ')}"
revisionsAsHtmlDirectoryListing(versions)
} else {
@ -185,7 +193,7 @@ abstract class AbstractIvyXmlProxyServer implements IvyXmlProxyServer {
private String getGemQueryRevisionFromIvy(String gemName, String revisionPattern) {
GemVersion version = gemVersionFromGradleIvyRequirement(revisionPattern)
version.highOpenEnded ? api.latestVersion(gemName) : version.high
version.highOpenEnded ? api.latestVersion(gemName, configuration.prerelease) : version.high
}
private void debug(String text) {
@ -203,4 +211,5 @@ abstract class AbstractIvyXmlProxyServer implements IvyXmlProxyServer {
private final GemToIvy gemToIvy
private final RubyGemQueryRestApi api
private final String group
private final GemRepositoryConfiguration configuration
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -23,6 +23,7 @@
*/
package com.github.jrubygradle.internal.core
import com.github.jrubygradle.api.core.ApiException
import com.github.jrubygradle.api.gems.GemInfo
import com.github.jrubygradle.api.gems.JarDependency
import com.github.jrubygradle.internal.gems.DefaultGemDependency
@ -33,7 +34,9 @@ import groovy.transform.CompileStatic
import groovyx.net.http.HttpBuilder
import groovyx.net.http.HttpException
import okhttp3.OkHttpClient
import org.gradle.util.GradleVersion
import static com.github.jrubygradle.internal.gems.GemToIvy.JAVA_PLATFORM
import static groovyx.net.http.ContentTypes.JSON
import static groovyx.net.http.NativeHandlers.Parsers.json
import static groovyx.net.http.OkHttpBuilder.configure
@ -50,7 +53,7 @@ class DefaultRubyGemRestApi implements com.github.jrubygradle.api.core.RubyGemQu
/** Creates a client from a URI
*
* @param serverUri URI as a String. ONly the scheme plus host
* @param serverUri URI as a String. Only the scheme plus host
* parts should be provided.
*/
DefaultRubyGemRestApi(final String serverUri) {
@ -73,12 +76,25 @@ class DefaultRubyGemRestApi implements com.github.jrubygradle.api.core.RubyGemQu
* @throw {@link com.github.jrubygradle.api.core.ApiException} if a networking error occurred.
*/
@Override
@SuppressWarnings('CatchThrowable')
List<String> allVersions(String gemName) {
allVersions(gemName, false)
}
/**
* Return all published versions for a specific GEM
*
* @param gemName Name of GEM.
* @param includePrelease Whether pre-release versions should be included.
* @return List of versions. Can be empty if the GEM does not have any versions. Never {@code null}.
* @throws {@link ApiException} if a networking or parser error occurs.
*/
@Override
@SuppressWarnings('CatchThrowable')
List<String> allVersions(String gemName, boolean includePrelease) {
try {
extractVersions(getData(V1, "versions/${gemName}"))
extractVersions(getData(V1, "versions/${gemName}"), includePrelease)
} catch (Throwable e) {
throw new com.github.jrubygradle.api.core.ApiException("Count not retrieve list of versions for ${gemName}", e)
throw new ApiException("Count not retrieve list of versions for ${gemName}", e)
}
}
@ -89,16 +105,33 @@ class DefaultRubyGemRestApi implements com.github.jrubygradle.api.core.RubyGemQu
* @throw {@link com.github.jrubygradle.api.core.ApiException} if a networking error occurred or the GEM does not exist.
*/
@Override
@SuppressWarnings('CatchThrowable')
String latestVersion(String gemName) {
latestVersion(gemName, false)
}
/**
* Return latest published version of GEM.
*
* @param gemName Name of GEM.
* @param allowPrerelease Whether a prereleased version can be considered a latest version.
* @return Version of GEM
* @throws {@link ApiException} if GEM does not exist.
*/
@Override
@SuppressWarnings('CatchThrowable')
String latestVersion(String gemName, boolean allowPrerelease) {
String version
try {
version = extractVersion(getData(V1, "versions/${gemName}/latest"))
if (allowPrerelease) {
version = allVersions(gemName, allowPrerelease).collect { GradleVersion.version(it) }.max().toString()
} else {
version = extractVersion(getData(V1, "versions/${gemName}/latest"))
}
} catch (Throwable e) {
throw new com.github.jrubygradle.api.core.ApiException("Failed to retrieve latest version of ${gemName}", e)
throw new ApiException("Failed to retrieve latest version of ${gemName}", e)
}
if (version == 'unknown') {
throw new com.github.jrubygradle.api.core.ApiException("Cound not retrieve latest version of ${gemName}. Maybe it does not exist")
throw new ApiException("Cound not retrieve latest version of ${gemName}. Maybe it does not exist")
}
version
}
@ -116,9 +149,9 @@ class DefaultRubyGemRestApi implements com.github.jrubygradle.api.core.RubyGemQu
try {
extractMetadata(getData(V2, "rubygems/${gemName}/versions/${gemVersion}"))
} catch (HttpException e) {
throw new com.github.jrubygradle.api.core.ApiException(":${gemName}:${gemVersion} not found", e)
throw new ApiException(":${gemName}:${gemVersion} not found", e)
} catch (Throwable e) {
throw new com.github.jrubygradle.api.core.ApiException("Could not obtain information for :${gemName}:${gemVersion}.", e)
throw new ApiException("Could not obtain information for :${gemName}:${gemVersion}.", e)
}
}
@ -147,8 +180,12 @@ class DefaultRubyGemRestApi implements com.github.jrubygradle.api.core.RubyGemQu
}
@CompileDynamic
private List<String> extractVersions(Object jsonParser) {
jsonParser*.number
private List<String> extractVersions(Object jsonParser, boolean includePrerelease) {
if (includePrerelease) {
jsonParser*.number
} else {
jsonParser.findAll { !it.prerelease }*.number
}
}
@CompileDynamic
@ -171,8 +208,16 @@ class DefaultRubyGemRestApi implements com.github.jrubygradle.api.core.RubyGemQu
// licenses arrayList
)
if (metadata.platform != JAVA_PLATFORM) {
if (getData(V1, "versions/${metadata.name}").find {
it.number == metadata.version && it.platform == JAVA_PLATFORM
}) {
metadata.platform = JAVA_PLATFORM
}
}
if (jsonParser.dependencies?.runtime) {
metadata.dependencies.addAll( Transform.toList(jsonParser.dependencies.runtime) {
metadata.dependencies.addAll(Transform.toList(jsonParser.dependencies.runtime) {
new DefaultGemDependency(name: it.name, requirements: it.requirements)
})
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -23,6 +23,7 @@
*/
package com.github.jrubygradle.internal.core
import com.github.jrubygradle.api.core.GemRepositoryConfiguration
import groovy.transform.CompileStatic
import org.gradle.api.Project
@ -44,7 +45,7 @@ class IvyXmlGlobalProxyRegistry {
* @param project Associated project.
*/
IvyXmlGlobalProxyRegistry(Project project) {
rootCacheDir = new File(project.gradle.gradleUserHomeDir, 'rubygems-ivyxml-cache')
rootCacheDir = new File(project.gradle.gradleUserHomeDir, "rubygems-ivyxml-cache/${PluginMetadata.version()}")
refresh = project.gradle.startParameter.refreshDependencies
}
@ -54,8 +55,17 @@ class IvyXmlGlobalProxyRegistry {
* @param group Group name for GEMs that will be fected from the remote.
* @return Access to a proxy sever. If the server does not exist it will be created.
*/
com.github.jrubygradle.api.core.IvyXmlProxyServer registerProxy(URI remoteURI, String group) {
com.github.jrubygradle.api.core.IvyXmlProxyServer proxy = getOrCreateServer(remoteURI, group, new File(rootCacheDir, uriHash(remoteURI)))
com.github.jrubygradle.api.core.IvyXmlProxyServer registerProxy(
URI remoteURI,
String group,
GemRepositoryConfiguration grc
) {
com.github.jrubygradle.api.core.IvyXmlProxyServer proxy = getOrCreateServer(
remoteURI,
group,
new File(rootCacheDir, uriHash(remoteURI)),
grc
)
proxy.refreshDependencies = refresh
proxy
}
@ -68,10 +78,11 @@ class IvyXmlGlobalProxyRegistry {
static private com.github.jrubygradle.api.core.IvyXmlProxyServer getOrCreateServer(
URI uri,
String group,
File cacheDir
File cacheDir,
GemRepositoryConfiguration grc
) {
SERVER_MAP.computeIfAbsent(uri, {
com.github.jrubygradle.api.core.IvyXmlProxyServer server = createProxyServer(uri, group, cacheDir)
com.github.jrubygradle.api.core.IvyXmlProxyServer server = createProxyServer(uri, group, cacheDir, grc)
server.run()
server
})
@ -80,9 +91,10 @@ class IvyXmlGlobalProxyRegistry {
static private com.github.jrubygradle.api.core.IvyXmlProxyServer createProxyServer(
URI uri,
String group,
File cacheDir
File cacheDir,
GemRepositoryConfiguration grc
) {
new IvyXmlRatpackProxyServer(cacheDir, uri, group)
new IvyXmlRatpackProxyServer(cacheDir, uri, group, grc)
}
static private final ConcurrentMap<URI, com.github.jrubygradle.api.core.IvyXmlProxyServer> SERVER_MAP = new ConcurrentHashMap<>()

View File

@ -1,5 +1,5 @@
/**
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -23,6 +23,7 @@
*/
package com.github.jrubygradle.internal.core;
import com.github.jrubygradle.api.core.GemRepositoryConfiguration;
import ratpack.server.RatpackServer;
import java.io.File;
@ -46,9 +47,15 @@ public class IvyXmlRatpackProxyServer extends AbstractIvyXmlProxyServer {
* @param cache Root directory for local Ivy XML cache.
* @param serverUri URI of remote Rubygems proxy.
* @param group Group that will be associated with the Rubygems proxy.
* @param grc Additional configuration regarding remote GEM server
*/
public IvyXmlRatpackProxyServer(File cache, URI serverUri, String group) {
super(cache, serverUri, group);
public IvyXmlRatpackProxyServer(
File cache,
URI serverUri,
String group,
GemRepositoryConfiguration grc
) {
super(cache, serverUri, group, grc);
}
/**

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.github.jrubygradle.internal.core
import groovy.transform.CompileStatic
/** Provides some metadata about this plugin
*
* @author Schalk W. Cronjé
*
* @since 2.0.0
*
*/
@CompileStatic
class PluginMetadata {
/** Plugin version
*
* @return Version of this plugin.
*/
static String version() {
METADATA['version']
}
private static Map<String,String> loadProperties() {
final String location = 'META-INF/jruby-gradle/com.jrubygradle.core-plugin.version.properties'
final Properties props = new Properties()
PluginMetadata.classLoader.getResourceAsStream(location).withCloseable { strm ->
props.load(strm)
}
props as Map<String,String>
}
private static final Map<String,String> METADATA = loadProperties()
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -41,6 +41,8 @@ import static com.github.jrubygradle.api.gems.GemVersion.singleGemVersionFromMul
@CompileStatic
class GemToIvy {
public static final String JAVA_PLATFORM = 'java'
/** Create a converter from GEM metadata to Ivy metadata.
*
* This constructor version assumes that the group is called {@code rubygems}.
@ -145,7 +147,7 @@ class GemToIvy {
writer.toString()
}
/** Writes the SHA1 checksum of the {@code ivy.xmnl} file.
/** Writes the SHA1 checksum of the {@code ivy.xml} file.
*
* @param ivyXml Fle containing the {@code ivy.xml} content/
* @return Checksum file.
@ -156,7 +158,6 @@ class GemToIvy {
shaFile
}
private static final String JAVA_PLATFORM = 'java'
private final String serverUri
private final String org = 'rubygems'
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
# Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
# Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining

View File

@ -0,0 +1,25 @@
#
# Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
# Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
version=${VERSION}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -42,7 +42,12 @@ class IvyXmlProxyServerSpec extends Specification {
TemporaryFolder projectRoot
void setup() {
server = new IvyXmlRatpackProxyServer(projectRoot.root, 'https://rubygems.org'.toURI(), 'rubygems')
server = new IvyXmlRatpackProxyServer(
projectRoot.root,
'https://rubygems.org'.toURI(),
'rubygems',
new GemRepositoryConfiguration()
)
server.run()
httpBuilder = OkHttpBuilder.configure {
request.uri = server.bindAddress

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.github.jrubygradle.api.core
import org.gradle.api.Project
import org.gradle.testfixtures.ProjectBuilder
import spock.lang.Specification
class RepositoryHandlerExtensionSpec extends Specification {
Project project = ProjectBuilder.builder().build()
void 'Add Maven repository'() {
when:
project.allprojects {
apply plugin : JRubyCorePlugin
repositories {
ruby {
mavengems()
mavengems('https://goo1')
mavengems('goo2','https://goo2')
}
}
}
then:
project.repositories.size() == 3
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -28,6 +28,7 @@ import com.github.jrubygradle.api.gems.GemUtils
import org.gradle.api.Project
import org.gradle.api.file.DuplicateFileCopyingException
import org.gradle.testfixtures.ProjectBuilder
import org.ysb33r.grolifant.api.core.ProjectOperations
import spock.lang.Specification
import static com.github.jrubygradle.api.gems.GemOverwriteAction.FAIL
@ -46,6 +47,7 @@ class GemUtilsSpec extends Specification {
void setup() {
project = ProjectBuilder.builder().build()
ProjectOperations.maybeCreateExtension(project)
src = project.file('src')
dest = project.file('dest')
fakeGem = new File(src, 'gems/mygem-1.0')

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -23,7 +23,6 @@
*/
package com.github.jrubygradle.api.gems
import com.github.jrubygradle.api.gems.GemVersion
import spock.lang.Specification
import spock.lang.Unroll
@ -77,7 +76,7 @@ class GemVersionSpec extends Specification {
}
@Unroll
void "Intersect: #ivyLeft ∩ #ivyRight ⇒ Gem #gemVer"() {
void "intersect: #ivyLeft ∩ #ivyRight ⇒ Gem #gemVer"() {
when:
GemVersion lhs = gemVersionFromGradleIvyRequirement(ivyLeft)
GemVersion rhs = gemVersionFromGradleIvyRequirement(ivyRight)
@ -87,10 +86,10 @@ class GemVersionSpec extends Specification {
where:
ivyLeft | ivyRight | gemVer
'[1.2.1,1.2.4]' | ']1.2.1,1.2.4[' | ']1.2.1,1.2.4['
'[1.2.1,1.2.4]' | ']1.2.1,1.2.4[' | '[1.2.1,1.2.4]'
'[1.2.0,1.2.4]' | ']1.2.1,1.2.3[' | ']1.2.1,1.2.3['
'[1.2.0,1.2.4]' | '[1.2.1,1.2.3]' | '[1.2.1,1.2.3]'
']1.2.0,1.2.4[' | '[1.2.0,1.2.4]' | ']1.2.0,1.2.4['
']1.2.0,1.2.4[' | '[1.2.0,1.2.4]' | '[1.2.0,1.2.4]'
']1.2.1,1.2.3[' | '[1.2.0,1.2.4]' | ']1.2.1,1.2.3['
'[1.2.1,1.2.3]' | '[1.2.0,1.2.4]' | '[1.2.1,1.2.3]'
'[1.2.10,1.2.14]' | '[1.2.2,1.10.14]' | '[1.2.10,1.2.14]'
@ -100,9 +99,20 @@ class GemVersionSpec extends Specification {
']2.5.1.1,99999]' | ']2.5.1.1,)' | ']2.5.1.1,99999]'
}
void 'Ivy union of < 3, >= 1.2'() {
expect:
singleGemVersionFromMultipleGemRequirements('< 3,>= 1.2').toString() == '[1.2,3['
@Unroll
void '#gemRequirements (requirements) ⇒ #gemRequirement (requirement)'() {
when:
GemVersion subject = singleGemVersionFromMultipleGemRequirements(gemRequirements)
then:
subject.toString() == gemRequirement
where:
gemRequirements | gemRequirement
'< 3,>= 1.2' | '[1.2,3['
'>= 3.0, < 4.0' | '[3.0,4.0['
'< 4.0, >= 3.0' | '[3.0,4.0['
'~> 2.2, >= 2.2.1' | '[2.2.1,3.0['
}
void "intersects with conflict"() {
@ -110,7 +120,7 @@ class GemVersionSpec extends Specification {
GemVersion subject = gemVersionFromGradleIvyRequirement('[1.2.1,1.2.3]')
expect:
subject.intersect('[1.2.4, 1.2.4]').conflict() == true
subject.intersect('[1.2.4, 1.2.4]').conflict()
}
void "finds no conflicts in non-integer version ranges"() {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,6 +1,6 @@
version=2.0.0-alpha1
version=2.1.0-alpha.1
group=com.github.jruby-gradle
copyrightYear=2014-2019
copyrightYear=2014-2020
org.gradle.daemon=true
org.gradle.caching=true
@ -14,10 +14,12 @@ releaseBuild=false
targetCompatibility=1.8
sourceCompatibility=1.8
jrubyVersion=9.2.7.0
grolifantVersion=1.0.0-alpha.1
jrubyVersion=9.2.9.0
jettyVersion=9.2.12.v20150709
bcprovVersion=1.46
httpbuilderNgVersion=1.0.3
dropwizardMetricsCoreVersion=3.1.0
torqueboxProxy=http://rubygems-proxy.torquebox.org/releases
ratpackVersion=1.6.1
# unit test / integration test only

View File

@ -17,7 +17,7 @@ dependencies {
/* We want to cache jruby-complete at this alternative version which we use
* in many places
*/
integrationTestGems 'org.jruby:jruby-complete:1.7.11'
integrationTestGems "org.jruby:jruby-complete:${olderJRubyVersion}"
}
sourceSets {

View File

@ -7,7 +7,7 @@ image::https://api.bintray.com/packages/jruby-gradle/plugins/jruby-gradle-jar-pl
=== Compatibility
This plugin requires link::http://gradle.org[Gradle] 2.0 or better
This plugin requires link::http://gradle.org[Gradle] 4.9 or better
=== Installing

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -227,7 +227,7 @@ class JRubyJarTestKitSpec extends IntegrationSpecification {
private BuildResult build(String taskName, String... additionalTasks) {
writeBuildFile()
List<String> tasks = ['-i', taskName]
List<String> tasks = ['-i', '-s', taskName]
tasks.addAll(additionalTasks)
gradleRunner(tasks).build()
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
@ -71,6 +71,7 @@ class JRubyJar extends Jar {
/**
* @return Directory that the dependencies for this project will be staged into
*/
@Internal
File getGemDir() {
return prepareTask.outputDir
}
@ -83,6 +84,7 @@ class JRubyJar extends Jar {
* modifies the jrubyVersion on the project after we have instantiated, that we still
* respect this setting
* */
@Input
String getJrubyVersion() {
if (embeddedJRubyVersion == null) {
return project.jruby.defaultVersion

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
# Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
# Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,6 +1,6 @@
<!--
Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,6 +1,4 @@
description = 'This plugin encapsulates web archive building functionality for JRuby Gradle projects'
group = rootProject.group
version = "${rootProject.version}-alpha"
dependencies {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
# Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
# Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2019, R. Tyler Croy <rtyler@brokenco.de>,
* Copyright (c) 2014-2020, R. Tyler Croy <rtyler@brokenco.de>,
* Schalk Cronje <ysb33r@gmail.com>, Christian Meier, Lookout, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining