-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Automatic dependency resolution. #420
Merged
+359
−37
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
114 changes: 114 additions & 0 deletions
114
src/main/groovy/com/github/j2objccontrib/j2objcgradle/DependencyConverter.groovy
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
/* | ||
* Copyright (c) 2015 the authors of j2objc-gradle (see AUTHORS file) | ||
* | ||
* 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 com.github.j2objccontrib.j2objcgradle | ||
|
||
import groovy.transform.CompileStatic | ||
import groovy.transform.PackageScope | ||
import org.gradle.api.Project | ||
import org.gradle.api.artifacts.Dependency | ||
import org.gradle.api.artifacts.ExternalModuleDependency | ||
import org.gradle.api.artifacts.ProjectDependency | ||
import org.gradle.api.artifacts.SelfResolvingDependency | ||
|
||
/** | ||
* Converts `[test]compile` dependencies to their | ||
* `j2objcTranslation` and/or `j2objcLinkage` equivalents, depending on the type | ||
* of dependency and whether or not they are already provided in native code. | ||
* <p/> | ||
* They will be resolved to appropriate `j2objc` constructs using DependencyResolver. | ||
*/ | ||
@PackageScope | ||
@CompileStatic | ||
class DependencyConverter { | ||
|
||
final Project project | ||
final J2objcConfig j2objcConfig | ||
|
||
// List of `group:name` | ||
// TODO: Handle versioning. | ||
static final List<String> J2OBJC_DEFAULT_LIBS = [ | ||
'com.google.guava:guava', | ||
'junit:junit', | ||
'org.mockito:mockito-core', | ||
'com.google.j2objc:j2objc-annotations'] | ||
|
||
DependencyConverter(Project project, J2objcConfig j2objcConfig) { | ||
this.project = project | ||
this.j2objcConfig = j2objcConfig | ||
} | ||
|
||
void configureAll() { | ||
project.configurations.getByName('compile').dependencies.each { | ||
visit(it) | ||
} | ||
project.configurations.getByName('testCompile').dependencies.each { | ||
visit(it) | ||
} | ||
} | ||
|
||
protected void visit(Dependency dep) { | ||
if (dep instanceof ProjectDependency) { | ||
// ex. `compile project(':peer1')` | ||
visitProjectDependency(dep as ProjectDependency) | ||
} else if (dep instanceof SelfResolvingDependency) { | ||
// ex. `compile fileTree(dir: 'libs', include: ['*.jar'])` | ||
visitSelfResolvingDependency(dep as SelfResolvingDependency) | ||
} else if (dep instanceof ExternalModuleDependency) { | ||
// ex. `compile "com.google.code.gson:gson:2.3.1"` | ||
visitExternalModuleDependency(dep as ExternalModuleDependency) | ||
} else { | ||
// Everything else | ||
visitGenericDependency(dep) | ||
} | ||
} | ||
|
||
protected void visitSelfResolvingDependency( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add example, repeat for the other visitor methods below:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
SelfResolvingDependency dep) { | ||
project.logger.debug("j2objc dependency converter: Translating file dep: $dep") | ||
project.configurations.getByName('j2objcTranslation').dependencies.add( | ||
dep.copy()) | ||
} | ||
|
||
protected void visitProjectDependency(ProjectDependency dep) { | ||
project.logger.debug("j2objc dependency converter: Linking Project: $dep") | ||
project.configurations.getByName('j2objcLinkage').dependencies.add( | ||
dep.copy()) | ||
} | ||
|
||
protected void visitExternalModuleDependency(ExternalModuleDependency dep) { | ||
project.logger.debug("j2objc dependency converter: External module dep: $dep") | ||
// If the dep is already in the j2objc dist, ignore it. | ||
if (J2OBJC_DEFAULT_LIBS.contains("${dep.group}:${dep.name}".toString())) { | ||
// TODO: A more correct method might be converting these into our own | ||
// form of SelfResolvingDependency that specifies which j2objc dist lib | ||
// to use. | ||
project.logger.debug("-- Skipped J2OBJC_DEFAULT_LIB: $dep") | ||
return | ||
} | ||
project.logger.debug("-- Copied as source: $dep") | ||
String group = dep.group == null ? '' : dep.group | ||
String version = dep.version == null ? '' : dep.version | ||
// TODO: Make this less fragile. What if sources don't exist for this artifact? | ||
project.dependencies.add('j2objcTranslation', "${group}:${dep.name}:${version}:sources") | ||
} | ||
|
||
protected void visitGenericDependency(Dependency dep) { | ||
project.logger.warn("j2objc dependency converter: Unknown dependency type: $dep; copying naively") | ||
project.configurations.getByName('j2objcTranslation').dependencies.add( | ||
dep.copy()) | ||
} | ||
} |
113 changes: 113 additions & 0 deletions
113
src/main/groovy/com/github/j2objccontrib/j2objcgradle/DependencyResolver.groovy
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
/* | ||
* Copyright (c) 2015 the authors of j2objc-gradle (see AUTHORS file) | ||
* | ||
* 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 com.github.j2objccontrib.j2objcgradle | ||
|
||
import groovy.transform.CompileStatic | ||
import groovy.transform.PackageScope | ||
import org.gradle.api.InvalidUserDataException | ||
import org.gradle.api.Project | ||
import org.gradle.api.artifacts.Dependency | ||
import org.gradle.api.artifacts.ProjectDependency | ||
import org.gradle.api.artifacts.SelfResolvingDependency | ||
import org.gradle.api.plugins.JavaPlugin | ||
import org.gradle.api.tasks.bundling.AbstractArchiveTask | ||
|
||
/** | ||
* Resolves `j2objcTranslation` and 'j2objcLinkage' dependencies into their `j2objc` constructs. | ||
*/ | ||
@PackageScope | ||
@CompileStatic | ||
class DependencyResolver { | ||
|
||
final Project project | ||
final J2objcConfig j2objcConfig | ||
|
||
DependencyResolver(Project project, J2objcConfig j2objcConfig) { | ||
this.project = project | ||
this.j2objcConfig = j2objcConfig | ||
} | ||
|
||
void configureAll() { | ||
project.configurations.getByName('j2objcTranslation').each { File it -> | ||
// These are the resolved files, NOT the dependencies themselves. | ||
visitTranslateFile(it) | ||
} | ||
project.configurations.getByName('j2objcLinkage').dependencies.each { | ||
visitLink(it) | ||
} | ||
} | ||
|
||
protected void visitTranslateFile(File depFile) { | ||
j2objcConfig.translateSourcepaths(depFile.absolutePath) | ||
j2objcConfig.enableBuildClosure() | ||
} | ||
|
||
protected void visitLink(Dependency dep) { | ||
if (dep instanceof ProjectDependency) { | ||
visitLinkProjectDependency((ProjectDependency) dep) | ||
} else if (dep instanceof SelfResolvingDependency) { | ||
visitLinkSelfResolvingDependency((SelfResolvingDependency) dep) | ||
} else { | ||
visitLinkGenericDependency(dep) | ||
} | ||
} | ||
|
||
protected void visitLinkSelfResolvingDependency( | ||
SelfResolvingDependency dep) { | ||
// TODO: handle native prebuilt libraries as files. | ||
throw new UnsupportedOperationException("Cannot automatically link J2ObjC dependency: $dep") | ||
} | ||
|
||
protected void visitLinkProjectDependency(ProjectDependency dep) { | ||
Project beforeProject = dep.dependencyProject | ||
// We need to have j2objcConfig on the beforeProject configured first. | ||
project.evaluationDependsOn beforeProject.path | ||
|
||
if (!beforeProject.plugins.hasPlugin(JavaPlugin)) { | ||
String message = "$beforeProject is not a Java project.\n" + | ||
"dependsOnJ2ObjcLib can only automatically resolve a\n" + | ||
"dependency on a Java project also converted using the\n" + | ||
"J2ObjC Gradle Plugin." | ||
throw new InvalidUserDataException(message) | ||
} | ||
|
||
if (!beforeProject.plugins.hasPlugin(J2objcPlugin)) { | ||
String message = "$beforeProject does not use the J2ObjC Gradle Plugin.\n" + | ||
"dependsOnJ2objcLib can be used only with another project that\n" + | ||
"itself uses the J2ObjC Gradle Plugin." | ||
throw new InvalidUserDataException(message) | ||
} | ||
|
||
// Build and test the java/objc libraries and the objc headers of | ||
// the other project first. | ||
// Since we assert the presence of the J2objcPlugin above, | ||
// we are guaranteed that the java plugin, which creates the jar task, | ||
// is also present. | ||
project.tasks.getByName('j2objcPreBuild').dependsOn { | ||
return [beforeProject.tasks.getByName('j2objcBuild'), | ||
beforeProject.tasks.getByName('jar')] | ||
} | ||
AbstractArchiveTask jarTask = beforeProject.tasks.getByName('jar') as AbstractArchiveTask | ||
project.logger.debug("$project:j2objcTranslate must use ${jarTask.archivePath}") | ||
j2objcConfig.translateClasspaths += jarTask.archivePath.absolutePath | ||
j2objcConfig.nativeCompilation.dependsOnJ2objcLib(beforeProject) | ||
} | ||
|
||
protected void visitLinkGenericDependency(Dependency dep) { | ||
throw new UnsupportedOperationException("Cannot automatically link J2ObjC dependency: $dep") | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should dependencies be split out to their own doc? It feels like that's becoming a substantial section unto itself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in my next PR, i hope to make dependencies a much shorter doc :)
it should be much simpler once this goes in.