app/lib/RepoUtil.scala (43 lines of code) (raw):
/*
* Copyright 2014 The Guardian
*
* 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 lib
import com.madgag.git._
import org.eclipse.jgit.api.{Git, GitCommand, TransportCommand}
import org.eclipse.jgit.lib.Constants.DEFAULT_REMOTE_NAME
import org.eclipse.jgit.lib.Repository
import org.eclipse.jgit.storage.file.FileRepositoryBuilder
import org.eclipse.jgit.transport.{CredentialsProvider, RemoteConfig}
import play.api.Logging
import java.io.File
import java.nio.file.Files
import scala.jdk.CollectionConverters._
object RepoUtil extends Logging {
def getGitRepo(dataDirectory: File, uri: String, credentials: Option[CredentialsProvider] = None): Repository = {
def invoke[C <: GitCommand[_], R](command: TransportCommand[C, R]): R = {
command.setTimeout(15)
credentials.foreach(command.setCredentialsProvider)
command.call()
}
def getUpToDateRepo(): Repository = {
dataDirectory.mkdirs()
val gitdir = new File(dataDirectory,"repo.git")
if (gitdir.exists()) {
assert(gitdir.list().nonEmpty, s"No child files found in ${gitdir.getAbsolutePath}")
logger.info(s"Updating Git repo with fetch... $uri")
val repo = FileRepositoryBuilder.create(gitdir)
val remoteConfig = new RemoteConfig(repo.getConfig, DEFAULT_REMOTE_NAME)
val remoteUris = remoteConfig.getURIs
val remoteUri = remoteUris.asScala.headOption.getOrElse(throw new IllegalStateException(s"No remote configured for $uri")).toString
assert(remoteUri == uri, s"Wrong uri - expected $uri, got $remoteUri")
invoke(repo.git.fetch())
repo
} else {
Files.createDirectories(gitdir.toPath.getParent)
logger.info(s"Cloning new Git repo... $uri")
invoke(
Git.cloneRepository()
.setDepth(200) // the aim here is to reduce the memory load of big repos like guardian/frontend
.setBare(true).setDirectory(gitdir).setURI(uri)).getRepository
}
}
getUpToDateRepo()
}
}