Created
March 4, 2016 06:32
-
-
Save big-guy/3e0cc0a19771613e9367 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.gradle.api.Transformer; | |
import org.gradle.api.internal.resolve.ProjectModelResolver; | |
import org.gradle.model.ModelMap; | |
import org.gradle.model.internal.registry.ModelRegistry; | |
import org.gradle.nativeplatform.NativeBinarySpec; | |
import org.gradle.nativeplatform.NativeDependencySet; | |
import org.gradle.nativeplatform.NativeLibraryRequirement; | |
import org.gradle.nativeplatform.NativeLibrarySpec; | |
import org.gradle.nativeplatform.internal.NativeBinarySpecInternal; | |
import org.gradle.nativeplatform.internal.resolve.NativeBinaryRequirementResolveResult; | |
import org.gradle.nativeplatform.internal.resolve.NativeBinaryResolveResult; | |
import org.gradle.nativeplatform.internal.resolve.NativeDependencyResolver; | |
import org.gradle.platform.base.ComponentSpecContainer; | |
import org.gradle.util.CollectionUtils; | |
import java.util.ArrayList; | |
import java.util.Collections; | |
import java.util.List; | |
/** | |
* Transitively resolves dependencies between native binaries. | |
* Does not attempt to cache any steps | |
* Does not attempt to prevent cycles | |
*/ | |
public class TransitiveNativeDependencyResolver implements NativeDependencyResolver { | |
private final NativeDependencyResolver delegate; | |
private final ProjectModelResolver projectModelResolver; | |
public TransitiveNativeDependencyResolver(NativeDependencyResolver delegate, ProjectModelResolver projectModelResolver) { | |
this.delegate = delegate; | |
this.projectModelResolver = projectModelResolver; | |
} | |
@Override | |
public void resolve(NativeBinaryResolveResult nativeBinaryResolveResult) { | |
delegate.resolve(nativeBinaryResolveResult); | |
// do not try to transitively resolve dependencies if there are unresolved dependencies | |
if (nativeBinaryResolveResult.getPendingResolutions().isEmpty()) { | |
// only attempt to find transitive dependencies if there are dependencies | |
if (!nativeBinaryResolveResult.getAllResolutions().isEmpty()) { | |
List<NativeBinaryRequirementResolveResult> transitiveResults = new ArrayList<NativeBinaryRequirementResolveResult>(); | |
for (NativeBinaryRequirementResolveResult resolution : nativeBinaryResolveResult.getAllResolutions()) { | |
transitiveResults.add(resolution); | |
transitiveResults.addAll(getTransitiveLibs(nativeBinaryResolveResult.getTarget(), resolution.getRequirement())); | |
} | |
// Replace the non-transitive resolution result with our transitive one | |
nativeBinaryResolveResult.getAllResolutions().clear(); | |
nativeBinaryResolveResult.getAllResolutions().addAll(transitiveResults); | |
} | |
} | |
} | |
private List getTransitiveLibs(NativeBinarySpec target, final NativeLibraryRequirement requirement) { | |
NativeLibrarySpec librarySpec = findComponent(requirement); | |
if (librarySpec == null) { | |
// prebuilt library, no transitive dependencies for these | |
return Collections.emptyList(); | |
} | |
ModelMap<NativeBinarySpecInternal> binaries = librarySpec.getBinaries().withType(NativeBinarySpecInternal.class); | |
NativeBinarySpecInternal matchingBinary = findBinary(binaries, target); | |
return CollectionUtils.collect(matchingBinary.getLibs(), new Transformer<NativeBinaryRequirementResolveResult, NativeDependencySet>() { | |
@Override | |
public NativeBinaryRequirementResolveResult transform(NativeDependencySet nativeDependencySet) { | |
NativeBinaryRequirementResolveResult transitiveResult = new NativeBinaryRequirementResolveResult("transitive from " + requirement); | |
transitiveResult.setNativeDependencySet(nativeDependencySet); | |
return transitiveResult; | |
} | |
}); | |
} | |
private NativeLibrarySpec findComponent(NativeLibraryRequirement requirement) { | |
ModelRegistry projectModel = projectModelResolver.resolveProjectModel(requirement.getProjectPath()); | |
ComponentSpecContainer components = projectModel.find("components", ComponentSpecContainer.class); | |
String libraryName = requirement.getLibraryName(); | |
return components.withType(NativeLibrarySpec.class).get(libraryName); | |
} | |
private NativeBinarySpecInternal findBinary(ModelMap<NativeBinarySpecInternal> projectBinaries, NativeBinarySpec target) { | |
for (NativeBinarySpecInternal binary : projectBinaries) { | |
if (target.getFlavor() != null && !target.getFlavor().getName().equals(binary.getFlavor().getName())) { | |
continue; | |
} | |
if (target.getTargetPlatform() != null && !target.getTargetPlatform().getName().equals(binary.getTargetPlatform().getName())) { | |
continue; | |
} | |
if (target.getBuildType() != null && !target.getBuildType().getName().equals(binary.getBuildType().getName())) { | |
continue; | |
} | |
return binary; | |
} | |
return null; // something went wrong | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment