|
import com.google.auto.service.AutoService |
|
import org.robolectric.internal.dependency.DependencyResolver |
|
import org.robolectric.pluginapi.SdkProvider |
|
import org.apache.maven.artifact.ant.DependenciesTask |
|
import org.robolectric.internal.dependency.DependencyJar |
|
import java.io.IOException |
|
import java.nio.channels.FileLock |
|
import java.nio.channels.FileChannel |
|
import java.io.RandomAccessFile |
|
import java.io.File |
|
import java.net.MalformedURLException |
|
import java.nio.file.Paths |
|
import java.lang.System.getProperties |
|
import java.util.Hashtable |
|
import org.apache.maven.model.Dependency |
|
import org.apache.tools.ant.Project |
|
import org.apache.maven.artifact.ant.Authentication |
|
import org.apache.maven.artifact.ant.RemoteRepository |
|
import java.net.URL |
|
|
|
@AutoService(DependencyResolver::class) |
|
class MyDependencyResolver private constructor( |
|
private val repositoryUrl: String, |
|
private val repositoryId: String, |
|
private val repositoryUserName: String? = null, |
|
private val repositoryPassword: String? = null |
|
) : DependencyResolver { |
|
|
|
constructor() : this(REPO_URL, REPO_NAME /* put credentials here, if needed */) |
|
|
|
companion object { |
|
const val REPO_NAME = "my-repo-name" |
|
const val REPO_URL = "https://host/path/to/internal/maven/repository/" |
|
} |
|
|
|
override fun getLocalArtifactUrl(dependencyJar: DependencyJar): URL? { |
|
val dependenciesTask = DependenciesTask() |
|
val remoteRepository = RemoteRepository() |
|
remoteRepository.url = repositoryUrl |
|
remoteRepository.id = repositoryId |
|
if (repositoryUserName != null || repositoryPassword != null) { |
|
val authentication = Authentication() |
|
authentication.userName = repositoryUserName |
|
authentication.password = repositoryPassword |
|
remoteRepository.addAuthentication(authentication) |
|
} |
|
dependenciesTask.addConfiguredRemoteRepository(remoteRepository) |
|
val project = Project() |
|
dependenciesTask.project = project |
|
val dependency = Dependency() |
|
dependency.artifactId = dependencyJar.artifactId |
|
dependency.groupId = dependencyJar.groupId |
|
dependency.type = dependencyJar.type |
|
dependency.version = dependencyJar.version |
|
if (dependencyJar.classifier != null) { |
|
dependency.classifier = dependencyJar.classifier |
|
} |
|
dependenciesTask.addDependency(dependency) |
|
|
|
whileLocked(Runnable { dependenciesTask.execute() }) |
|
|
|
val artifacts = project.properties |
|
|
|
try { |
|
return Paths.get(artifacts[key(dependencyJar)] as String).toUri().toURL() |
|
} catch (e: MalformedURLException) { |
|
throw RuntimeException(e) |
|
} |
|
} |
|
|
|
private fun whileLocked(runnable: Runnable) { |
|
val lockFile = File(System.getProperty("user.home"), ".robolectric-download-lock") |
|
try { |
|
RandomAccessFile(lockFile, "rw").use { raf -> |
|
raf.channel.use { channel -> |
|
val fileLock = channel.lock() |
|
try { |
|
println("Downloading from maven ") |
|
runnable.run() |
|
} finally { |
|
fileLock.release() |
|
} |
|
} |
|
} |
|
} catch (e: IOException) { |
|
throw IllegalStateException("Couldn't create lock file $lockFile", e) |
|
} finally { |
|
lockFile.delete() |
|
} |
|
} |
|
|
|
private fun key(dependency: DependencyJar): String { |
|
var key = dependency.groupId + ":" + dependency.artifactId + ":" + dependency.type |
|
if (dependency.classifier != null) { |
|
key += ":" + dependency.classifier |
|
} |
|
return key |
|
} |
|
} |