mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-05 04:56:02 +01:00
Fix Repository Contents API issues (#2802)
This commit is contained in:
@@ -28,7 +28,7 @@ object ApiContents {
|
|||||||
"file",
|
"file",
|
||||||
fileInfo.name,
|
fileInfo.name,
|
||||||
fileInfo.path,
|
fileInfo.path,
|
||||||
fileInfo.commitId,
|
fileInfo.id.getName,
|
||||||
Some(Base64.getEncoder.encodeToString(arr)),
|
Some(Base64.getEncoder.encodeToString(arr)),
|
||||||
Some("base64")
|
Some("base64")
|
||||||
)(repositoryName)
|
)(repositoryName)
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import gitbucket.core.util.Directory._
|
|||||||
import gitbucket.core.model.{Account, WebHook}
|
import gitbucket.core.model.{Account, WebHook}
|
||||||
import gitbucket.core.service.RepositoryService.RepositoryInfo
|
import gitbucket.core.service.RepositoryService.RepositoryInfo
|
||||||
import gitbucket.core.service.WebHookService.{WebHookCreatePayload, WebHookPushPayload}
|
import gitbucket.core.service.WebHookService.{WebHookCreatePayload, WebHookPushPayload}
|
||||||
import gitbucket.core.util.JGitUtil.CommitInfo
|
|
||||||
import gitbucket.core.view
|
import gitbucket.core.view
|
||||||
import gitbucket.core.view.helpers
|
import gitbucket.core.view.helpers
|
||||||
import org.apache.commons.compress.archivers.{ArchiveEntry, ArchiveOutputStream}
|
import org.apache.commons.compress.archivers.{ArchiveEntry, ArchiveOutputStream}
|
||||||
@@ -267,23 +266,9 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
branchName,
|
branchName,
|
||||||
repository,
|
repository,
|
||||||
logs
|
logs
|
||||||
.map {
|
.map { commit =>
|
||||||
commit =>
|
|
||||||
(
|
(
|
||||||
CommitInfo(
|
commit.copy(verified = commit.commitSign.flatMap(GpgUtil.verifySign)),
|
||||||
id = commit.id,
|
|
||||||
shortMessage = commit.shortMessage,
|
|
||||||
fullMessage = commit.fullMessage,
|
|
||||||
parents = commit.parents,
|
|
||||||
authorTime = commit.authorTime,
|
|
||||||
authorName = commit.authorName,
|
|
||||||
authorEmailAddress = commit.authorEmailAddress,
|
|
||||||
commitTime = commit.commitTime,
|
|
||||||
committerName = commit.committerName,
|
|
||||||
committerEmailAddress = commit.committerEmailAddress,
|
|
||||||
commitSign = commit.commitSign,
|
|
||||||
verified = commit.commitSign.flatMap(GpgUtil.verifySign)
|
|
||||||
),
|
|
||||||
JGitUtil.getTagsOnCommit(git, commit.id),
|
JGitUtil.getTagsOnCommit(git, commit.id),
|
||||||
getCommitStatusWithSummary(repository.owner, repository.name, commit.id)
|
getCommitStatusWithSummary(repository.owner, repository.name, commit.id)
|
||||||
)
|
)
|
||||||
@@ -356,11 +341,11 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
|
|
||||||
val newFiles = files.map { file =>
|
val newFiles = files.map { file =>
|
||||||
file.copy(name = if (form.path.length == 0) file.name else s"${form.path}/${file.name}")
|
file.copy(name = if (form.path.length == 0) file.name else s"${form.path}/${file.name}")
|
||||||
}.toSeq
|
}
|
||||||
|
|
||||||
if (form.newBranch) {
|
if (form.newBranch) {
|
||||||
val newBranchName = createNewBranchForPullRequest(repository, form.branch, loginAccount)
|
val newBranchName = createNewBranchForPullRequest(repository, form.branch, loginAccount)
|
||||||
val objectId = _commit(newBranchName, files, newFiles, loginAccount)
|
val objectId = _commit(newBranchName, newFiles, loginAccount)
|
||||||
val issueId =
|
val issueId =
|
||||||
createIssueAndPullRequest(
|
createIssueAndPullRequest(
|
||||||
repository,
|
repository,
|
||||||
@@ -373,7 +358,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
)
|
)
|
||||||
redirect(s"/${repository.owner}/${repository.name}/pull/${issueId}")
|
redirect(s"/${repository.owner}/${repository.name}/pull/${issueId}")
|
||||||
} else {
|
} else {
|
||||||
_commit(form.branch, files, newFiles, loginAccount)
|
_commit(form.branch, newFiles, loginAccount)
|
||||||
if (form.path.length == 0) {
|
if (form.path.length == 0) {
|
||||||
redirect(s"/${repository.owner}/${repository.name}/tree/${form.branch}")
|
redirect(s"/${repository.owner}/${repository.name}/tree/${form.branch}")
|
||||||
} else {
|
} else {
|
||||||
@@ -384,15 +369,15 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
|
|
||||||
def _commit(
|
def _commit(
|
||||||
branchName: String,
|
branchName: String,
|
||||||
files: Seq[CommitFile],
|
//files: Seq[CommitFile],
|
||||||
newFiles: Seq[CommitFile],
|
newFiles: Seq[CommitFile],
|
||||||
loginAccount: Account
|
loginAccount: Account
|
||||||
): ObjectId = {
|
): ObjectId = {
|
||||||
commitFiles(
|
commitFiles(
|
||||||
repository = repository,
|
repository = repository,
|
||||||
branch = branchName,
|
branch = branchName,
|
||||||
path = form.path,
|
//path = form.path,
|
||||||
files = files.toIndexedSeq,
|
//files = files.toIndexedSeq,
|
||||||
message = form.message.getOrElse("Add files via upload"),
|
message = form.message.getOrElse("Add files via upload"),
|
||||||
loginAccount = loginAccount,
|
loginAccount = loginAccount,
|
||||||
settings = context.settings
|
settings = context.settings
|
||||||
@@ -509,7 +494,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
commit = form.commit,
|
commit = form.commit,
|
||||||
loginAccount = loginAccount,
|
loginAccount = loginAccount,
|
||||||
settings = context.settings
|
settings = context.settings
|
||||||
)
|
)._1
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -556,7 +541,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
commit = form.commit,
|
commit = form.commit,
|
||||||
loginAccount = loginAccount,
|
loginAccount = loginAccount,
|
||||||
settings = context.settings
|
settings = context.settings
|
||||||
)
|
)._1
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -599,7 +584,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
commit = form.commit,
|
commit = form.commit,
|
||||||
loginAccount = loginAccount,
|
loginAccount = loginAccount,
|
||||||
settings = context.settings
|
settings = context.settings
|
||||||
)
|
)._1
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package gitbucket.core.controller.api
|
package gitbucket.core.controller.api
|
||||||
import gitbucket.core.api.{ApiContents, ApiError, CreateAFile, JsonFormat}
|
import gitbucket.core.api.{ApiCommit, ApiContents, ApiError, CreateAFile, JsonFormat}
|
||||||
import gitbucket.core.controller.ControllerBase
|
import gitbucket.core.controller.ControllerBase
|
||||||
import gitbucket.core.service.{RepositoryCommitFileService, RepositoryService}
|
import gitbucket.core.service.{RepositoryCommitFileService, RepositoryService}
|
||||||
import gitbucket.core.util.Directory.getRepositoryDir
|
import gitbucket.core.util.Directory.getRepositoryDir
|
||||||
import gitbucket.core.util.JGitUtil.{FileInfo, getContentFromId, getFileList}
|
import gitbucket.core.util.JGitUtil.{CommitInfo, FileInfo, getContentFromId, getFileList}
|
||||||
import gitbucket.core.util._
|
import gitbucket.core.util._
|
||||||
import gitbucket.core.view.helpers.{isRenderable, renderMarkup}
|
import gitbucket.core.view.helpers.{isRenderable, renderMarkup}
|
||||||
import gitbucket.core.util.Implicits._
|
import gitbucket.core.util.Implicits._
|
||||||
@@ -35,7 +35,7 @@ trait ApiRepositoryContentsControllerBase extends ControllerBase {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* ii. Get contents
|
* ii. Get contents
|
||||||
* https://developer.github.com/v3/repos/contents/#get-contents
|
* https://docs.github.com/en/rest/reference/repos#get-repository-content
|
||||||
*/
|
*/
|
||||||
get("/api/v3/repos/:owner/:repository/contents")(referrersOnly { repository =>
|
get("/api/v3/repos/:owner/:repository/contents")(referrersOnly { repository =>
|
||||||
getContents(repository, ".", params.getOrElse("ref", repository.repository.defaultBranch))
|
getContents(repository, ".", params.getOrElse("ref", repository.repository.defaultBranch))
|
||||||
@@ -43,19 +43,13 @@ trait ApiRepositoryContentsControllerBase extends ControllerBase {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* ii. Get contents
|
* ii. Get contents
|
||||||
* https://developer.github.com/v3/repos/contents/#get-contents
|
* https://docs.github.com/en/rest/reference/repos#get-repository-content
|
||||||
*/
|
*/
|
||||||
get("/api/v3/repos/:owner/:repository/contents/*")(referrersOnly { repository =>
|
get("/api/v3/repos/:owner/:repository/contents/*")(referrersOnly { repository =>
|
||||||
getContents(repository, multiParams("splat").head, params.getOrElse("ref", repository.repository.defaultBranch))
|
getContents(repository, multiParams("splat").head, params.getOrElse("ref", repository.repository.defaultBranch))
|
||||||
})
|
})
|
||||||
|
|
||||||
private def getContents(
|
private def getFileInfo(git: Git, revision: String, pathStr: String, ignoreCase: Boolean): Option[FileInfo] = {
|
||||||
repository: RepositoryService.RepositoryInfo,
|
|
||||||
path: String,
|
|
||||||
refStr: String,
|
|
||||||
ignoreCase: Boolean = false
|
|
||||||
) = {
|
|
||||||
def getFileInfo(git: Git, revision: String, pathStr: String, ignoreCase: Boolean): Option[FileInfo] = {
|
|
||||||
val (dirName, fileName) = pathStr.lastIndexOf('/') match {
|
val (dirName, fileName) = pathStr.lastIndexOf('/') match {
|
||||||
case -1 =>
|
case -1 =>
|
||||||
(".", pathStr)
|
(".", pathStr)
|
||||||
@@ -71,6 +65,12 @@ trait ApiRepositoryContentsControllerBase extends ControllerBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private def getContents(
|
||||||
|
repository: RepositoryService.RepositoryInfo,
|
||||||
|
path: String,
|
||||||
|
refStr: String,
|
||||||
|
ignoreCase: Boolean = false
|
||||||
|
) = {
|
||||||
Using.resource(Git.open(getRepositoryDir(params("owner"), params("repository")))) { git =>
|
Using.resource(Git.open(getRepositoryDir(params("owner"), params("repository")))) { git =>
|
||||||
val fileList = getFileList(git, refStr, path, maxFiles = context.settings.repositoryViewer.maxFiles)
|
val fileList = getFileList(git, refStr, path, maxFiles = context.settings.repositoryViewer.maxFiles)
|
||||||
if (fileList.isEmpty) { // file or NotFound
|
if (fileList.isEmpty) { // file or NotFound
|
||||||
@@ -126,14 +126,13 @@ trait ApiRepositoryContentsControllerBase extends ControllerBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
|
/**
|
||||||
* iii. Create a file or iv. Update a file
|
* iii. Create a file or iv. Update a file
|
||||||
* https://developer.github.com/v3/repos/contents/#create-a-file
|
* https://docs.github.com/en/rest/reference/repos#create-or-update-file-contents
|
||||||
* https://developer.github.com/v3/repos/contents/#update-a-file
|
|
||||||
* if sha is presented, update a file else create a file.
|
* if sha is presented, update a file else create a file.
|
||||||
* requested #2112
|
* requested #2112
|
||||||
*/
|
*/
|
||||||
|
|
||||||
put("/api/v3/repos/:owner/:repository/contents/*")(writableUsersOnly { repository =>
|
put("/api/v3/repos/:owner/:repository/contents/*")(writableUsersOnly { repository =>
|
||||||
context.withLoginAccount {
|
context.withLoginAccount {
|
||||||
loginAccount =>
|
loginAccount =>
|
||||||
@@ -147,13 +146,18 @@ trait ApiRepositoryContentsControllerBase extends ControllerBase {
|
|||||||
}
|
}
|
||||||
val paths = multiParams("splat").head.split("/")
|
val paths = multiParams("splat").head.split("/")
|
||||||
val path = paths.take(paths.size - 1).toList.mkString("/")
|
val path = paths.take(paths.size - 1).toList.mkString("/")
|
||||||
if (data.sha.isDefined && data.sha.get != commit) {
|
Using.resource(Git.open(getRepositoryDir(params("owner"), params("repository")))) {
|
||||||
|
git =>
|
||||||
|
val fileInfo = getFileInfo(git, commit, path, false)
|
||||||
|
|
||||||
|
fileInfo match {
|
||||||
|
case Some(f) if !data.sha.contains(f.id.getName) =>
|
||||||
ApiError(
|
ApiError(
|
||||||
"The blob SHA is not matched.",
|
"The blob SHA is not matched.",
|
||||||
Some("https://developer.github.com/v3/repos/contents/#update-a-file")
|
Some("https://docs.github.com/en/rest/reference/repos#create-or-update-file-contents")
|
||||||
)
|
)
|
||||||
} else {
|
case _ =>
|
||||||
val objectId = commitFile(
|
val (commitId, blobId) = commitFile(
|
||||||
repository,
|
repository,
|
||||||
branch,
|
branch,
|
||||||
path,
|
path,
|
||||||
@@ -167,7 +171,28 @@ trait ApiRepositoryContentsControllerBase extends ControllerBase {
|
|||||||
data.committer.map(_.email).getOrElse(loginAccount.mailAddress),
|
data.committer.map(_.email).getOrElse(loginAccount.mailAddress),
|
||||||
context.settings
|
context.settings
|
||||||
)
|
)
|
||||||
ApiContents("file", paths.last, path, objectId.name, None, None)(RepositoryName(repository))
|
|
||||||
|
blobId match {
|
||||||
|
case None =>
|
||||||
|
ApiError("Failed to commit a file.", None)
|
||||||
|
case Some(blobId) =>
|
||||||
|
Map(
|
||||||
|
"content" -> ApiContents(
|
||||||
|
"file",
|
||||||
|
paths.last,
|
||||||
|
path,
|
||||||
|
blobId.name,
|
||||||
|
Some(data.content),
|
||||||
|
Some("base64")
|
||||||
|
)(RepositoryName(repository)),
|
||||||
|
"commit" -> ApiCommit(
|
||||||
|
git,
|
||||||
|
RepositoryName(repository),
|
||||||
|
new CommitInfo(JGitUtil.getRevCommitFromId(git, commitId))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -175,13 +200,14 @@ trait ApiRepositoryContentsControllerBase extends ControllerBase {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* v. Delete a file
|
* v. Delete a file
|
||||||
* https://developer.github.com/v3/repos/contents/#delete-a-file
|
* https://docs.github.com/en/rest/reference/repos#delete-a-file
|
||||||
* should be implemented
|
* should be implemented
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vi. Get archive link
|
* vi. Download a repository archive (tar/zip)
|
||||||
* https://developer.github.com/v3/repos/contents/#get-archive-link
|
* https://docs.github.com/en/rest/reference/repos#download-a-repository-archive-tar
|
||||||
|
* https://docs.github.com/en/rest/reference/repos#download-a-repository-archive-zip
|
||||||
*/
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,23 +23,29 @@ trait RepositoryCommitFileService {
|
|||||||
with PullRequestService
|
with PullRequestService
|
||||||
with WebHookPullRequestService
|
with WebHookPullRequestService
|
||||||
with RepositoryService =>
|
with RepositoryService =>
|
||||||
import RepositoryCommitFileService._
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create multiple files by callback function.
|
||||||
|
* Returns commitId.
|
||||||
|
*/
|
||||||
def commitFiles(
|
def commitFiles(
|
||||||
repository: RepositoryService.RepositoryInfo,
|
repository: RepositoryService.RepositoryInfo,
|
||||||
files: Seq[CommitFile],
|
|
||||||
branch: String,
|
branch: String,
|
||||||
path: String,
|
|
||||||
message: String,
|
message: String,
|
||||||
loginAccount: Account,
|
loginAccount: Account,
|
||||||
settings: SystemSettings
|
settings: SystemSettings
|
||||||
)(
|
)(
|
||||||
f: (Git, ObjectId, DirCacheBuilder, ObjectInserter) => Unit
|
f: (Git, ObjectId, DirCacheBuilder, ObjectInserter) => Unit
|
||||||
)(implicit s: Session, c: JsonFormat.Context) = {
|
)(implicit s: Session, c: JsonFormat.Context): ObjectId = {
|
||||||
// prepend path to the filename
|
_createFiles(repository, branch, message, loginAccount, loginAccount.fullName, loginAccount.mailAddress, settings)(
|
||||||
_commitFile(repository, branch, message, loginAccount, loginAccount.fullName, loginAccount.mailAddress, settings)(f)
|
f
|
||||||
|
)._1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a file from string content.
|
||||||
|
* Returns commitId + blobId.
|
||||||
|
*/
|
||||||
def commitFile(
|
def commitFile(
|
||||||
repository: RepositoryService.RepositoryInfo,
|
repository: RepositoryService.RepositoryInfo,
|
||||||
branch: String,
|
branch: String,
|
||||||
@@ -52,7 +58,7 @@ trait RepositoryCommitFileService {
|
|||||||
commit: String,
|
commit: String,
|
||||||
loginAccount: Account,
|
loginAccount: Account,
|
||||||
settings: SystemSettings
|
settings: SystemSettings
|
||||||
)(implicit s: Session, c: JsonFormat.Context): ObjectId = {
|
)(implicit s: Session, c: JsonFormat.Context): (ObjectId, Option[ObjectId]) = {
|
||||||
commitFile(
|
commitFile(
|
||||||
repository,
|
repository,
|
||||||
branch,
|
branch,
|
||||||
@@ -69,6 +75,10 @@ trait RepositoryCommitFileService {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a file from byte array content.
|
||||||
|
* Returns commitId + blobId.
|
||||||
|
*/
|
||||||
def commitFile(
|
def commitFile(
|
||||||
repository: RepositoryService.RepositoryInfo,
|
repository: RepositoryService.RepositoryInfo,
|
||||||
branch: String,
|
branch: String,
|
||||||
@@ -82,7 +92,7 @@ trait RepositoryCommitFileService {
|
|||||||
committerName: String,
|
committerName: String,
|
||||||
committerMailAddress: String,
|
committerMailAddress: String,
|
||||||
settings: SystemSettings
|
settings: SystemSettings
|
||||||
)(implicit s: Session, c: JsonFormat.Context): ObjectId = {
|
)(implicit s: Session, c: JsonFormat.Context): (ObjectId, Option[ObjectId]) = {
|
||||||
|
|
||||||
val newPath = newFileName.map { newFileName =>
|
val newPath = newFileName.map { newFileName =>
|
||||||
if (path.length == 0) newFileName else s"${path}/${newFileName}"
|
if (path.length == 0) newFileName else s"${path}/${newFileName}"
|
||||||
@@ -91,7 +101,7 @@ trait RepositoryCommitFileService {
|
|||||||
if (path.length == 0) oldFileName else s"${path}/${oldFileName}"
|
if (path.length == 0) oldFileName else s"${path}/${oldFileName}"
|
||||||
}
|
}
|
||||||
|
|
||||||
_commitFile(repository, branch, message, pusherAccount, committerName, committerMailAddress, settings) {
|
_createFiles(repository, branch, message, pusherAccount, committerName, committerMailAddress, settings) {
|
||||||
case (git, headTip, builder, inserter) =>
|
case (git, headTip, builder, inserter) =>
|
||||||
if (headTip.getName == commit) {
|
if (headTip.getName == commit) {
|
||||||
val permission = JGitUtil
|
val permission = JGitUtil
|
||||||
@@ -105,18 +115,23 @@ trait RepositoryCommitFileService {
|
|||||||
}
|
}
|
||||||
.flatten
|
.flatten
|
||||||
.headOption
|
.headOption
|
||||||
|
.map { bits =>
|
||||||
newPath.foreach { newPath =>
|
|
||||||
builder.add(JGitUtil.createDirCacheEntry(newPath, permission.map { bits =>
|
|
||||||
FileMode.fromBits(bits)
|
FileMode.fromBits(bits)
|
||||||
} getOrElse FileMode.REGULAR_FILE, inserter.insert(Constants.OBJ_BLOB, content)))
|
}
|
||||||
|
.getOrElse(FileMode.REGULAR_FILE)
|
||||||
|
|
||||||
|
val objectId = newPath.map { newPath =>
|
||||||
|
val objectId = inserter.insert(Constants.OBJ_BLOB, content)
|
||||||
|
builder.add(JGitUtil.createDirCacheEntry(newPath, permission, objectId))
|
||||||
|
objectId
|
||||||
}
|
}
|
||||||
builder.finish()
|
builder.finish()
|
||||||
}
|
objectId
|
||||||
|
} else None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private def _commitFile(
|
private def _createFiles[R](
|
||||||
repository: RepositoryService.RepositoryInfo,
|
repository: RepositoryService.RepositoryInfo,
|
||||||
branch: String,
|
branch: String,
|
||||||
message: String,
|
message: String,
|
||||||
@@ -125,8 +140,8 @@ trait RepositoryCommitFileService {
|
|||||||
committerMailAddress: String,
|
committerMailAddress: String,
|
||||||
settings: SystemSettings
|
settings: SystemSettings
|
||||||
)(
|
)(
|
||||||
f: (Git, ObjectId, DirCacheBuilder, ObjectInserter) => Unit
|
f: (Git, ObjectId, DirCacheBuilder, ObjectInserter) => R
|
||||||
)(implicit s: Session, c: JsonFormat.Context): ObjectId = {
|
)(implicit s: Session, c: JsonFormat.Context): (ObjectId, R) = {
|
||||||
|
|
||||||
LockUtil.lock(s"${repository.owner}/${repository.name}") {
|
LockUtil.lock(s"${repository.owner}/${repository.name}") {
|
||||||
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
||||||
@@ -135,7 +150,7 @@ trait RepositoryCommitFileService {
|
|||||||
val headName = s"refs/heads/${branch}"
|
val headName = s"refs/heads/${branch}"
|
||||||
val headTip = git.getRepository.resolve(headName)
|
val headTip = git.getRepository.resolve(headName)
|
||||||
|
|
||||||
f(git, headTip, builder, inserter)
|
val result = f(git, headTip, builder, inserter)
|
||||||
|
|
||||||
val commitId = JGitUtil.createNewCommit(
|
val commitId = JGitUtil.createNewCommit(
|
||||||
git,
|
git,
|
||||||
@@ -228,7 +243,7 @@ trait RepositoryCommitFileService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
commitId
|
(commitId, result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import gitbucket.core.model.Profile._
|
|||||||
import gitbucket.core.model.Profile.profile.blockingApi._
|
import gitbucket.core.model.Profile.profile.blockingApi._
|
||||||
import org.apache.http.client.utils.URLEncodedUtils
|
import org.apache.http.client.utils.URLEncodedUtils
|
||||||
import gitbucket.core.util.JGitUtil.CommitInfo
|
import gitbucket.core.util.JGitUtil.CommitInfo
|
||||||
import gitbucket.core.util.Implicits._
|
|
||||||
import gitbucket.core.util.{HttpClientUtil, RepositoryName, StringUtil}
|
import gitbucket.core.util.{HttpClientUtil, RepositoryName, StringUtil}
|
||||||
import gitbucket.core.service.RepositoryService.RepositoryInfo
|
import gitbucket.core.service.RepositoryService.RepositoryInfo
|
||||||
import org.apache.http.NameValuePair
|
import org.apache.http.NameValuePair
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
package gitbucket.core.api
|
package gitbucket.core.api
|
||||||
|
|
||||||
import gitbucket.core.TestingGitBucketServer
|
import gitbucket.core.TestingGitBucketServer
|
||||||
|
import org.apache.commons.io.IOUtils
|
||||||
import org.scalatest.funsuite.AnyFunSuite
|
import org.scalatest.funsuite.AnyFunSuite
|
||||||
|
|
||||||
import scala.util.Using
|
import scala.util.Using
|
||||||
import org.kohsuke.github.{GHCommitState, GitHub}
|
import org.kohsuke.github.{GHCommitState, GitHub}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Need to run `sbt package` before running this test.
|
||||||
|
*/
|
||||||
class ApiIntegrationTest extends AnyFunSuite {
|
class ApiIntegrationTest extends AnyFunSuite {
|
||||||
|
|
||||||
test("create repository") {
|
test("create repository") {
|
||||||
@@ -133,4 +137,48 @@ class ApiIntegrationTest extends AnyFunSuite {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("create and update contents") {
|
||||||
|
Using.resource(new TestingGitBucketServer(19999)) { server =>
|
||||||
|
val github = server.client("root", "root")
|
||||||
|
|
||||||
|
val repo = github.createRepository("create_contents_test").autoInit(true).create()
|
||||||
|
|
||||||
|
val createResult =
|
||||||
|
repo
|
||||||
|
.createContent()
|
||||||
|
.branch("master")
|
||||||
|
.content("create")
|
||||||
|
.message("Create content")
|
||||||
|
.path("README.md")
|
||||||
|
.commit();
|
||||||
|
|
||||||
|
assert(createResult.getContent.isFile == true)
|
||||||
|
assert(IOUtils.toString(createResult.getContent.read(), "UTF-8") == "create")
|
||||||
|
|
||||||
|
val content1 = repo.getFileContent("README.md")
|
||||||
|
assert(content1.isFile == true)
|
||||||
|
assert(IOUtils.toString(content1.read(), "UTF-8") == "create")
|
||||||
|
assert(content1.getSha == createResult.getContent.getSha)
|
||||||
|
|
||||||
|
val updateResult =
|
||||||
|
repo
|
||||||
|
.createContent()
|
||||||
|
.branch("master")
|
||||||
|
.content("update")
|
||||||
|
.message("Update content")
|
||||||
|
.path("README.md")
|
||||||
|
.sha(content1.getSha)
|
||||||
|
.commit();
|
||||||
|
|
||||||
|
assert(updateResult.getContent.isFile == true)
|
||||||
|
assert(IOUtils.toString(updateResult.getContent.read(), "UTF-8") == "update")
|
||||||
|
|
||||||
|
val content2 = repo.getFileContent("README.md")
|
||||||
|
assert(content2.isFile == true)
|
||||||
|
assert(IOUtils.toString(content2.read(), "UTF-8") == "update")
|
||||||
|
assert(content2.getSha == updateResult.getContent.getSha)
|
||||||
|
assert(content1.getSha != content2.getSha)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user