[gradle] Add gradle-local subpackage
Mikolaj Izdebski
mizdebsk at fedoraproject.org
Tue Nov 18 20:13:40 UTC 2014
commit 16ee7bb26dc776dd473612363a4dcc2c3ec92639
Author: Mikolaj Izdebski <mizdebsk at redhat.com>
Date: Thu Nov 13 14:23:00 2014 +0100
Add gradle-local subpackage
GradleResolver.java | 374 +++++++++++++++++++++++++++++++++++++++++++++++++++
gradle.spec | 34 +++++-
2 files changed, 407 insertions(+), 1 deletions(-)
---
diff --git a/GradleResolver.java b/GradleResolver.java
new file mode 100644
index 0000000..0b6e00b
--- /dev/null
+++ b/GradleResolver.java
@@ -0,0 +1,374 @@
+/*-
+ * Copyright (c) 2014 Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.fedoraproject.xmvn.connector.gradle;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.fedoraproject.xmvn.artifact.Artifact;
+import org.fedoraproject.xmvn.artifact.DefaultArtifact;
+import org.fedoraproject.xmvn.locator.IsolatedXMvnServiceLocator;
+import org.fedoraproject.xmvn.locator.XMvnHomeClassLoader;
+import org.fedoraproject.xmvn.resolver.ResolutionRequest;
+import org.fedoraproject.xmvn.resolver.ResolutionResult;
+import org.fedoraproject.xmvn.resolver.Resolver;
+import org.gradle.api.artifacts.ModuleVersionIdentifier;
+import org.gradle.api.artifacts.component.ModuleComponentIdentifier;
+import org.gradle.api.artifacts.repositories.ArtifactRepository;
+import org.gradle.api.internal.artifacts.ivyservice.ivyresolve.ConfiguredModuleComponentRepository;
+import org.gradle.api.internal.artifacts.ivyservice.ivyresolve.ModuleComponentRepositoryAccess;
+import org.gradle.api.internal.artifacts.ivyservice.ivyresolve.parser.DescriptorParseContext;
+import org.gradle.api.internal.artifacts.ivyservice.ivyresolve.parser.GradlePomModuleDescriptorParser;
+import org.gradle.api.internal.artifacts.ivyservice.ivyresolve.parser.MetaDataParser;
+import org.gradle.api.internal.artifacts.repositories.ResolutionAwareRepository;
+import org.gradle.api.internal.component.ArtifactType;
+import org.gradle.internal.component.external.model.DefaultMavenModuleResolveMetaData;
+import org.gradle.internal.component.external.model.DefaultModuleComponentArtifactMetaData;
+import org.gradle.internal.component.external.model.ModuleComponentResolveMetaData;
+import org.gradle.internal.component.external.model.MutableModuleComponentResolveMetaData;
+import org.gradle.internal.component.model.ComponentArtifactMetaData;
+import org.gradle.internal.component.model.ComponentResolveMetaData;
+import org.gradle.internal.component.model.ComponentUsage;
+import org.gradle.internal.component.model.DefaultIvyArtifactName;
+import org.gradle.internal.component.model.DependencyMetaData;
+import org.gradle.internal.component.model.IvyArtifactName;
+import org.gradle.internal.component.model.ModuleSource;
+import org.gradle.internal.resolve.ArtifactResolveException;
+import org.gradle.internal.resolve.ModuleVersionResolveException;
+import org.gradle.internal.resolve.result.BuildableArtifactResolveResult;
+import org.gradle.internal.resolve.result.BuildableArtifactSetResolveResult;
+import org.gradle.internal.resolve.result.BuildableModuleComponentMetaDataResolveResult;
+import org.gradle.internal.resolve.result.BuildableModuleComponentVersionSelectionResolveResult;
+import org.gradle.internal.resource.DefaultLocallyAvailableExternalResource;
+import org.gradle.internal.resource.LocallyAvailableExternalResource;
+import org.gradle.internal.resource.local.DefaultLocallyAvailableResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * @author Mikolaj Izdebski
+ */
+public class GradleResolver
+ implements ArtifactRepository, ResolutionAwareRepository, ConfiguredModuleComponentRepository,
+ ModuleComponentRepositoryAccess, DescriptorParseContext
+{
+ private final Logger logger = LoggerFactory.getLogger( GradleResolver.class );
+
+ static class LazyLocatorProvider
+ {
+ static final IsolatedXMvnServiceLocator locator;
+
+ static
+ {
+ XMvnHomeClassLoader realm = new XMvnHomeClassLoader( LazyLocatorProvider.class.getClassLoader() );
+ realm.importAllPackages( "org.slf4j" );
+ realm.importAllPackages( "org.gradle.api.logging" );
+ locator = new IsolatedXMvnServiceLocator( realm );
+ }
+ }
+
+ static class LazyResolverProvider
+ {
+ static final Resolver resolver = LazyLocatorProvider.locator.getService( Resolver.class );
+ }
+
+ private Path resolve( Artifact artifact )
+ {
+ logger.debug( "Trying to resolve artifact {}", artifact );
+ ResolutionRequest request = new ResolutionRequest( artifact );
+ Resolver resolver = LazyResolverProvider.resolver;
+ ResolutionResult result = resolver.resolve( request );
+ return result.getArtifactPath();
+ }
+
+ private String name;
+
+ @Override
+ public String getName()
+ {
+ return name;
+ }
+
+ @Override
+ public void setName( String name )
+ {
+ this.name = name;
+ }
+
+ @Override
+ public ConfiguredModuleComponentRepository createResolver()
+ {
+ return this;
+ }
+
+ @Override
+ public String getId()
+ {
+ return "XMvn";
+ }
+
+ @Override
+ public ModuleComponentRepositoryAccess getLocalAccess()
+ {
+ return this;
+ }
+
+ @Override
+ public ModuleComponentRepositoryAccess getRemoteAccess()
+ {
+ return this;
+ }
+
+ @Override
+ public boolean isDynamicResolveMode()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean isLocal()
+ {
+ return true;
+ }
+
+ @Override
+ public void listModuleVersions( DependencyMetaData arg0, BuildableModuleComponentVersionSelectionResolveResult arg1 )
+ {
+ logger.debug( "listModuleVersions() called, but it is NOT IMPLEMENTED" );
+ }
+
+ @Override
+ public void resolveArtifact( ComponentArtifactMetaData artifact, ModuleSource module,
+ BuildableArtifactResolveResult result )
+ {
+
+ ModuleVersionIdentifier moduleId =
+ ( (DefaultModuleComponentArtifactMetaData) artifact ).toArtifactIdentifier().getModuleVersionIdentifier();
+ String groupId = moduleId.getGroup();
+ String artifactId = artifact.getName().getName();
+ String extension = artifact.getName().getExtension();
+ String classifier = artifact.getName().getClassifier();
+ String version = moduleId.getVersion();
+
+ Artifact artifact2 = new DefaultArtifact( groupId, artifactId, extension, classifier, version );
+ Path path = resolve( artifact2 );
+
+ if ( path == null )
+ {
+ logger.debug( "Unable to resolve artifact {}", artifact2 );
+ result.failed( new ArtifactResolveException( artifact.getId(), "XMvn was unable to resolve artifact "
+ + artifact2 ) );
+ return;
+ }
+
+ // Gradle expects resolved file to be named like in Maven/Ivy repo...
+ try
+ {
+ Path dir = Files.createTempDirectory( "xmvn-gradle-" );
+ String baseName =
+ artifact2.getArtifactId() + "-" + artifact2.getVersion()
+ + ( artifact2.getClassifier().isEmpty() ? "" : "-" + artifact2.getClassifier() ) + "."
+ + artifact2.getExtension();
+ Path origpPath = path;
+ path = dir.resolve( baseName );
+ Files.createSymbolicLink( path, origpPath );
+ }
+ catch ( IOException e )
+ {
+ throw new RuntimeException( e );
+ }
+
+ logger.debug( "Artifact {} was resolved to {}", artifact2, path );
+ result.resolved( path.toFile() );
+ }
+
+ @Override
+ public void resolveComponentMetaData( DependencyMetaData dependency, ModuleComponentIdentifier id,
+ BuildableModuleComponentMetaDataResolveResult result )
+ {
+ logger.debug( "Trying to resolve model for {}:{}:{}", id.getGroup(), id.getModule(), id.getVersion() );
+
+ Artifact artifact2 = new DefaultArtifact( id.getGroup(), id.getModule(), "pom", id.getVersion() );
+ Path pomPath = resolve( artifact2 );
+
+ if ( pomPath != null )
+ {
+ logger.debug( "Found Maven POM: {}", pomPath );
+ Path fakePom = fakePom( pomPath, id );
+ logger.debug( "Created fake POM: {}", fakePom );
+
+ MetaDataParser parser = new GradlePomModuleDescriptorParser();
+ MutableModuleComponentResolveMetaData metaData = parser.parseMetaData( this, fakePom.toFile() );
+
+ result.resolved( metaData );
+ return;
+ }
+ else
+ {
+ logger.debug( "POM not found, trying non-POM artifacts" );
+ for ( IvyArtifactName artifact : getDependencyArtifactNames( dependency ) )
+ {
+ String groupId = id.getGroup();
+ String artifactId = artifact.getName();
+ String extension = artifact.getExtension();
+ String classifier = artifact.getClassifier();
+ String version = id.getVersion();
+
+ Artifact artifact3 = new DefaultArtifact( groupId, artifactId, extension, classifier, version );
+ Path path = resolve( artifact3 );
+
+ if ( path != null )
+ {
+ logger.debug( "Artifact {} found, returning minimal model", artifact3 );
+ MutableModuleComponentResolveMetaData metaData = new DefaultMavenModuleResolveMetaData( dependency );
+ result.resolved( metaData );
+ return;
+ }
+ }
+ }
+
+ logger.debug( "No POM and no artifact found, failing" );
+ result.failed( new ModuleVersionResolveException( id, "XMvn was unable to resolve artifact " + artifact2 ) );
+ }
+
+ private Set<IvyArtifactName> getDependencyArtifactNames( DependencyMetaData dependency )
+ {
+ String moduleName = dependency.getRequested().getName();
+ Set<IvyArtifactName> artifactSet = new LinkedHashSet<>();
+ artifactSet.addAll( dependency.getArtifacts() );
+
+ if ( artifactSet.isEmpty() )
+ {
+ artifactSet.add( new DefaultIvyArtifactName( moduleName, "jar", "jar",
+ Collections.<String, String> emptyMap() ) );
+ }
+
+ return artifactSet;
+ }
+
+ private static void setElement( Document doc, String name, String value )
+ {
+ NodeList childreen = doc.getDocumentElement().getChildNodes();
+ for ( int i = 0; i < childreen.getLength(); i++ )
+ {
+ Node child = childreen.item( i );
+ if ( child.getNodeName().equals( name ) )
+ {
+ child.setTextContent( value );
+ return;
+ }
+ }
+
+ Node child = doc.createElement( name );
+ child.setTextContent( value );
+ doc.getDocumentElement().appendChild( child );
+ }
+
+ private static Path fakePom( Path pom, ModuleComponentIdentifier moduleVersionIdentifier )
+ {
+ try
+ {
+ DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
+ Document doc = domFactory.newDocumentBuilder().parse( pom.toFile() );
+ setElement( doc, "groupId", moduleVersionIdentifier.getGroup() );
+ setElement( doc, "artifactId", moduleVersionIdentifier.getModule() );
+ setElement( doc, "version", moduleVersionIdentifier.getVersion() );
+
+ NodeList dependencies = doc.getElementsByTagName( "dependency" );
+ outer: for ( int i = 0; i < dependencies.getLength(); i++ )
+ {
+ Node dependency = dependencies.item( i );
+ NodeList childreen = dependency.getChildNodes();
+ for ( int j = 0; j < childreen.getLength(); j++ )
+ {
+ Node child = childreen.item( j );
+ if ( child.getNodeName().equals( "version" ) )
+ continue outer;
+ }
+
+ Node child = doc.createElement( "version" );
+ child.setTextContent( "SYSTEM" );
+ dependency.appendChild( child );
+ }
+
+ TransformerFactory transformerFactory = TransformerFactory.newInstance();
+ Transformer transformer = transformerFactory.newTransformer();
+ transformer.setOutputProperty( OutputKeys.INDENT, "yes" );
+ DOMSource source = new DOMSource( doc );
+
+ Path fakePom = Files.createTempFile( "xmvn-", ".gradle.pom" );
+ StreamResult file = new StreamResult( fakePom.toFile() );
+ transformer.transform( source, file );
+ return fakePom;
+ }
+ catch ( Exception e )
+ {
+ throw new RuntimeException( e );
+ }
+ }
+
+ @Override
+ public void resolveModuleArtifacts( ComponentResolveMetaData component, ComponentUsage usage,
+ BuildableArtifactSetResolveResult result )
+ {
+ result.resolved( Collections.singleton( ( (ModuleComponentResolveMetaData) component ).artifact( "jar", "jar",
+ null ) ) );
+ }
+
+ @Override
+ public void resolveModuleArtifacts( ComponentResolveMetaData component, ArtifactType type,
+ BuildableArtifactSetResolveResult result )
+ {
+ if ( type != ArtifactType.MAVEN_POM )
+ {
+ logger.debug( "resolveModuleArtifacts() called for artifact type {}", type );
+ result.failed( new ArtifactResolveException( "resolveModuleArtifacts() is implemended only for Maven POMs" ) );
+ return;
+ }
+
+ ModuleComponentResolveMetaData metaData = (ModuleComponentResolveMetaData) component;
+ ModuleComponentIdentifier id = metaData.getComponentId();
+ DefaultIvyArtifactName name = new DefaultIvyArtifactName( id.getModule(), "pom", "pom" );
+ DefaultModuleComponentArtifactMetaData resolvedMetaData = new DefaultModuleComponentArtifactMetaData( id, name );
+ result.resolved( Collections.singleton( resolvedMetaData ) );
+ }
+
+ @Override
+ public LocallyAvailableExternalResource getMetaDataArtifact( ModuleVersionIdentifier id, ArtifactType type )
+ {
+ Path pomPath = resolve( new DefaultArtifact( id.getGroup(), id.getName(), "pom", id.getVersion() ) );
+
+ if ( pomPath == null )
+ return null;
+
+ return new DefaultLocallyAvailableExternalResource( pomPath.toUri(),
+ new DefaultLocallyAvailableResource( pomPath.toFile() ) );
+ }
+}
diff --git a/gradle.spec b/gradle.spec
index 35a38ba..bf7e47b 100644
--- a/gradle.spec
+++ b/gradle.spec
@@ -1,6 +1,6 @@
Name: gradle
Version: 2.2
-Release: 0.39%{?dist}
+Release: 0.40%{?dist}
Summary: Build automation tool
# Some examples and integration tests are under GNU LGPL and Boost
# Software License, but are not used to create binary package.
@@ -14,6 +14,7 @@ Source2: gradle-font-metadata.xml
Source3: gradle-jquery-metadata.xml
Source4: gradle-launcher.sh
Source5: gradle.desktop
+Source6: GradleResolver.java
Patch0: 0001-Gradle-local-mode.patch
Patch1: 0002-Use-Maven-Wagon-2.8.patch
@@ -152,6 +153,10 @@ BuildRequires: lato-fonts
BuildRequires: liberation-mono-fonts
BuildRequires: js-jquery
+# for gradle-local
+BuildRequires: xmvn-api
+BuildRequires: xmvn-launcher
+
Requires: javapackages-tools
Requires: java-devel
Requires: bash
@@ -298,6 +303,17 @@ sensible defaults. Gradle is quickly becoming the build system of
choice for many open source projects, leading edge enterprises and
legacy automation challenges.
+%package local
+Summary: XMvn connector for Gradle
+Requires: %{name} = %{version}-%{release}
+Requires: apache-ivy
+Requires: slf4j
+Requires: xmvn-api
+Requires: xmvn-launcher
+
+%description local
+This package provides XMvn connector for Gradle, which allows Gradle
+to resolve artifacts from system artifact repository.
%prep
%setup -q
@@ -322,6 +338,13 @@ cp %{SOURCE1} build/all-released-versions.json
%build
gradle -x docs:distDocs --offline -s install -Pgradle_installPath=$PWD/inst
+# Build and assemble local connector
+mkdir -p local/org/fedoraproject/xmvn/connector/gradle
+cd ./local
+cp %{SOURCE6} org/fedoraproject/xmvn/connector/gradle/
+javac -cp $(echo ../subprojects/core/build/libs/gradle-core-%{version}*.jar):$(echo ../subprojects/dependency-management/build/libs/gradle-dependency-management-%{version}*.jar):$(echo ../subprojects/resources/build/libs/gradle-resources-%{version}*.jar):$(echo ../subprojects/base-services/build/libs/gradle-base-services-%{version}*.jar):$(build-classpath xmvn/xmvn-api xmvn/xmvn-launcher slf4j/api ivy) $(find -name *.java)
+jar cf xmvn-connector-gradle.jar org
+
%install
repo=$HOME/.m2/repository
@@ -363,6 +386,10 @@ do
ln -sf %{_javadir}/%{name}/$mod.jar %{buildroot}%{_datadir}/%{name}/lib/$f-%{version}*.jar
done
+%mvn_artifact org.fedoraproject.xmvn:xmvn-connector-gradle:2.1.0-SNAPSHOT local/xmvn-connector-gradle.jar
+%mvn_package ":xmvn*" local
+%mvn_file ":{xmvn*}" xmvn/@1
+
%mvn_install
install -d -m 755 %{buildroot}%{_bindir}/
@@ -399,7 +426,12 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
%doc changelog.txt
%doc LICENSE NOTICE
+%files local -f .mfiles-local
+
%changelog
+* Thu Nov 13 2014 Mikolaj Izdebski <mizdebsk at redhat.com> - 2.2-0.40
+- Add gradle-local subpackage
+
* Wed Nov 12 2014 Mikolaj Izdebski <mizdebsk at redhat.com> - 2.2-0.39
- Rebuild with gradle 2.2
More information about the scm-commits
mailing list