mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-03 12:05:59 +01:00
(refs #421)Add tar.gz archive download
* Update jgit version * Add new lib org.eclipse.jgit.archive * TODO: Add link in views
This commit is contained in:
@@ -26,7 +26,8 @@ object MyBuild extends Build {
|
|||||||
),
|
),
|
||||||
scalacOptions := Seq("-deprecation", "-language:postfixOps"),
|
scalacOptions := Seq("-deprecation", "-language:postfixOps"),
|
||||||
libraryDependencies ++= Seq(
|
libraryDependencies ++= Seq(
|
||||||
"org.eclipse.jgit" % "org.eclipse.jgit.http.server" % "3.0.0.201306101825-r",
|
"org.eclipse.jgit" % "org.eclipse.jgit.http.server" % "3.4.1.201406201815-r",
|
||||||
|
"org.eclipse.jgit" % "org.eclipse.jgit.archive" % "3.4.1.201406201815-r",
|
||||||
"org.scalatra" %% "scalatra" % ScalatraVersion,
|
"org.scalatra" %% "scalatra" % ScalatraVersion,
|
||||||
"org.scalatra" %% "scalatra-specs2" % ScalatraVersion % "test",
|
"org.scalatra" %% "scalatra-specs2" % ScalatraVersion % "test",
|
||||||
"org.scalatra" %% "scalatra-json" % ScalatraVersion,
|
"org.scalatra" %% "scalatra-json" % ScalatraVersion,
|
||||||
|
|||||||
@@ -8,11 +8,12 @@ import _root_.util._
|
|||||||
import service._
|
import service._
|
||||||
import org.scalatra._
|
import org.scalatra._
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import org.eclipse.jgit.api.Git
|
|
||||||
|
import org.eclipse.jgit.api.{ArchiveCommand, Git}
|
||||||
|
import org.eclipse.jgit.archive.{TgzFormat, ZipFormat}
|
||||||
import org.eclipse.jgit.lib._
|
import org.eclipse.jgit.lib._
|
||||||
import org.apache.commons.io.FileUtils
|
import org.apache.commons.io.FileUtils
|
||||||
import org.eclipse.jgit.treewalk._
|
import org.eclipse.jgit.treewalk._
|
||||||
import java.util.zip.{ZipEntry, ZipOutputStream}
|
|
||||||
import jp.sf.amateras.scalatra.forms._
|
import jp.sf.amateras.scalatra.forms._
|
||||||
import org.eclipse.jgit.dircache.DirCache
|
import org.eclipse.jgit.dircache.DirCache
|
||||||
import org.eclipse.jgit.revwalk.RevCommit
|
import org.eclipse.jgit.revwalk.RevCommit
|
||||||
@@ -22,6 +23,7 @@ class RepositoryViewerController extends RepositoryViewerControllerBase
|
|||||||
with RepositoryService with AccountService with ActivityService with IssuesService with WebHookService
|
with RepositoryService with AccountService with ActivityService with IssuesService with WebHookService
|
||||||
with ReferrerAuthenticator with CollaboratorsAuthenticator
|
with ReferrerAuthenticator with CollaboratorsAuthenticator
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The repository viewer.
|
* The repository viewer.
|
||||||
*/
|
*/
|
||||||
@@ -29,6 +31,9 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
self: RepositoryService with AccountService with ActivityService with IssuesService with WebHookService
|
self: RepositoryService with AccountService with ActivityService with IssuesService with WebHookService
|
||||||
with ReferrerAuthenticator with CollaboratorsAuthenticator =>
|
with ReferrerAuthenticator with CollaboratorsAuthenticator =>
|
||||||
|
|
||||||
|
ArchiveCommand.registerFormat("zip", new ZipFormat)
|
||||||
|
ArchiveCommand.registerFormat("tar.gz", new TgzFormat)
|
||||||
|
|
||||||
case class EditorForm(
|
case class EditorForm(
|
||||||
branch: String,
|
branch: String,
|
||||||
path: String,
|
path: String,
|
||||||
@@ -259,50 +264,12 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
* Download repository contents as an archive.
|
* Download repository contents as an archive.
|
||||||
*/
|
*/
|
||||||
get("/:owner/:repository/archive/*")(referrersOnly { repository =>
|
get("/:owner/:repository/archive/*")(referrersOnly { repository =>
|
||||||
val name = multiParams("splat").head
|
multiParams("splat").head match {
|
||||||
|
case name if name.endsWith(".zip") =>
|
||||||
if(name.endsWith(".zip")){
|
archiveRepository(name, ".zip", repository)
|
||||||
val revision = name.stripSuffix(".zip")
|
case name if name.endsWith(".tar.gz") =>
|
||||||
val workDir = getDownloadWorkDir(repository.owner, repository.name, session.getId)
|
archiveRepository(name, ".tar.gz", repository)
|
||||||
if(workDir.exists){
|
case _ => BadRequest
|
||||||
FileUtils.deleteDirectory(workDir)
|
|
||||||
}
|
|
||||||
workDir.mkdirs
|
|
||||||
|
|
||||||
val zipFile = new File(workDir, repository.name + "-" +
|
|
||||||
(if(revision.length == 40) revision.substring(0, 10) else revision).replace('/', '_') + ".zip")
|
|
||||||
|
|
||||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git =>
|
|
||||||
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(revision))
|
|
||||||
using(new TreeWalk(git.getRepository)){ walk =>
|
|
||||||
val reader = walk.getObjectReader
|
|
||||||
val objectId = new MutableObjectId
|
|
||||||
|
|
||||||
using(new ZipOutputStream(new java.io.FileOutputStream(zipFile))){ out =>
|
|
||||||
walk.addTree(revCommit.getTree)
|
|
||||||
walk.setRecursive(true)
|
|
||||||
|
|
||||||
while(walk.next){
|
|
||||||
val name = walk.getPathString
|
|
||||||
val mode = walk.getFileMode(0)
|
|
||||||
if(mode == FileMode.REGULAR_FILE || mode == FileMode.EXECUTABLE_FILE){
|
|
||||||
walk.getObjectId(objectId, 0)
|
|
||||||
val entry = new ZipEntry(name)
|
|
||||||
val loader = reader.open(objectId)
|
|
||||||
entry.setSize(loader.getSize)
|
|
||||||
out.putNextEntry(entry)
|
|
||||||
loader.copyTo(out)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
contentType = "application/octet-stream"
|
|
||||||
response.setHeader("Content-Disposition", s"attachment; filename=${zipFile.getName}")
|
|
||||||
zipFile
|
|
||||||
} else {
|
|
||||||
BadRequest
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -447,4 +414,29 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private def archiveRepository(name: String, suffix: String, repository: RepositoryService.RepositoryInfo): File = {
|
||||||
|
val revision = name.stripSuffix(suffix)
|
||||||
|
val workDir = getDownloadWorkDir(repository.owner, repository.name, session.getId)
|
||||||
|
if(workDir.exists) {
|
||||||
|
FileUtils.deleteDirectory(workDir)
|
||||||
|
}
|
||||||
|
workDir.mkdirs
|
||||||
|
|
||||||
|
val file = new File(workDir, repository.name + "-" +
|
||||||
|
(if(revision.length == 40) revision.substring(0, 10) else revision).replace('/', '_') + suffix)
|
||||||
|
|
||||||
|
using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git =>
|
||||||
|
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(revision))
|
||||||
|
using(new java.io.FileOutputStream(file)) { out =>
|
||||||
|
git.archive
|
||||||
|
.setFormat(suffix.tail)
|
||||||
|
.setTree(revCommit.getTree)
|
||||||
|
.setOutputStream(out)
|
||||||
|
.call()
|
||||||
|
}
|
||||||
|
contentType = "application/octet-stream"
|
||||||
|
response.setHeader("Content-Disposition", s"attachment; filename=${file.getName}")
|
||||||
|
file
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user