diff --git a/src/main/scala/app/CreateRepositoryController.scala b/src/main/scala/app/CreateRepositoryController.scala index 67083aa..16cd05c 100644 --- a/src/main/scala/app/CreateRepositoryController.scala +++ b/src/main/scala/app/CreateRepositoryController.scala @@ -113,54 +113,62 @@ val loginUserName = loginAccount.userName LockUtil.lock(s"${loginUserName}/${repository.name}/create"){ - if(getRepository(loginUserName, repository.name, baseUrl).isEmpty){ - // Insert to the database at first - val originUserName = repository.repository.originUserName.getOrElse(repository.owner) - val originRepositoryName = repository.repository.originRepositoryName.getOrElse(repository.name) + if(repository.owner == loginUserName){ + // redirect to the repository + redirect(s"/${repository.owner}/${repository.name}") + } else { + getForkedRepositories(repository.owner, repository.name).find(_._1 == loginUserName).map { case (owner, name) => + // redirect to the repository + redirect(s"/${owner}/${name}") + } getOrElse { + // Insert to the database at first + val originUserName = repository.repository.originUserName.getOrElse(repository.owner) + val originRepositoryName = repository.repository.originRepositoryName.getOrElse(repository.name) - createRepository( - repositoryName = repository.name, - userName = loginUserName, - description = repository.repository.description, - isPrivate = repository.repository.isPrivate, - originRepositoryName = Some(originRepositoryName), - originUserName = Some(originUserName), - parentRepositoryName = Some(repository.name), - parentUserName = Some(repository.owner) - ) + createRepository( + repositoryName = repository.name, + userName = loginUserName, + description = repository.repository.description, + isPrivate = repository.repository.isPrivate, + originRepositoryName = Some(originRepositoryName), + originUserName = Some(originUserName), + parentRepositoryName = Some(repository.name), + parentUserName = Some(repository.owner) + ) - // Insert default labels - insertDefaultLabels(loginUserName, repository.name) + // Insert default labels + insertDefaultLabels(loginUserName, repository.name) - // clone repository actually - JGitUtil.cloneRepository( - getRepositoryDir(repository.owner, repository.name), - getRepositoryDir(loginUserName, repository.name)) + // clone repository actually + JGitUtil.cloneRepository( + getRepositoryDir(repository.owner, repository.name), + getRepositoryDir(loginUserName, repository.name)) - // Create Wiki repository - JGitUtil.cloneRepository( - getWikiRepositoryDir(repository.owner, repository.name), - getWikiRepositoryDir(loginUserName, repository.name)) + // Create Wiki repository + JGitUtil.cloneRepository( + getWikiRepositoryDir(repository.owner, repository.name), + getWikiRepositoryDir(loginUserName, repository.name)) - // insert commit id - using(Git.open(getRepositoryDir(loginUserName, repository.name))){ git => - JGitUtil.getRepositoryInfo(loginUserName, repository.name, baseUrl).branchList.foreach { branch => - JGitUtil.getCommitLog(git, branch) match { - case Right((commits, _)) => commits.foreach { commit => - if(!existsCommitId(loginUserName, repository.name, commit.id)){ - insertCommitId(loginUserName, repository.name, commit.id) + // insert commit id + using(Git.open(getRepositoryDir(loginUserName, repository.name))){ git => + JGitUtil.getRepositoryInfo(loginUserName, repository.name, baseUrl).branchList.foreach { branch => + JGitUtil.getCommitLog(git, branch) match { + case Right((commits, _)) => commits.foreach { commit => + if(!existsCommitId(loginUserName, repository.name, commit.id)){ + insertCommitId(loginUserName, repository.name, commit.id) + } } + case Left(_) => ??? } - case Left(_) => ??? } } - } - // Record activity - recordForkActivity(repository.owner, repository.name, loginUserName) + // Record activity + recordForkActivity(repository.owner, repository.name, loginUserName) + // redirect to the repository + redirect(s"/${loginUserName}/${repository.name}") + } } - // redirect to the repository - redirect("/%s/%s".format(loginUserName, repository.name)) } }) diff --git a/src/main/scala/app/PullRequestsController.scala b/src/main/scala/app/PullRequestsController.scala index 2bbe3ba..a85d990 100644 --- a/src/main/scala/app/PullRequestsController.scala +++ b/src/main/scala/app/PullRequestsController.scala @@ -31,14 +31,15 @@ private val logger = LoggerFactory.getLogger(classOf[PullRequestsControllerBase]) val pullRequestForm = mapping( - "title" -> trim(label("Title" , text(required, maxlength(100)))), - "content" -> trim(label("Content", optional(text()))), - "targetUserName" -> trim(text(required, maxlength(100))), - "targetBranch" -> trim(text(required, maxlength(100))), - "requestUserName" -> trim(text(required, maxlength(100))), - "requestBranch" -> trim(text(required, maxlength(100))), - "commitIdFrom" -> trim(text(required, maxlength(40))), - "commitIdTo" -> trim(text(required, maxlength(40))) + "title" -> trim(label("Title" , text(required, maxlength(100)))), + "content" -> trim(label("Content", optional(text()))), + "targetUserName" -> trim(text(required, maxlength(100))), + "targetBranch" -> trim(text(required, maxlength(100))), + "requestUserName" -> trim(text(required, maxlength(100))), + "requestRepositoryName" -> trim(text(required, maxlength(100))), + "requestBranch" -> trim(text(required, maxlength(100))), + "commitIdFrom" -> trim(text(required, maxlength(40))), + "commitIdTo" -> trim(text(required, maxlength(40))) )(PullRequestForm.apply) val mergeForm = mapping( @@ -51,6 +52,7 @@ targetUserName: String, targetBranch: String, requestUserName: String, + requestRepositoryName: String, requestBranch: String, commitIdFrom: String, commitIdTo: String) @@ -213,73 +215,85 @@ } }) - get("/:owner/:repository/compare/*...*")(referrersOnly { repository => + get("/:owner/:repository/compare/*...*")(referrersOnly { forkedRepository => val Seq(origin, forked) = multiParams("splat") - val (originOwner, tmpOriginBranch) = parseCompareIdentifie(origin, repository.owner) - val (forkedOwner, tmpForkedBranch) = parseCompareIdentifie(forked, repository.owner) + val (originOwner, tmpOriginBranch) = parseCompareIdentifie(origin, forkedRepository.owner) + val (forkedOwner, tmpForkedBranch) = parseCompareIdentifie(forked, forkedRepository.owner) - (getRepository(originOwner, repository.name, baseUrl), - getRepository(forkedOwner, repository.name, baseUrl)) match { - case (Some(originRepository), Some(forkedRepository)) => { - using( - Git.open(getRepositoryDir(originOwner, repository.name)), - Git.open(getRepositoryDir(forkedOwner, repository.name)) - ){ case (oldGit, newGit) => - val originBranch = JGitUtil.getDefaultBranch(oldGit, originRepository, tmpOriginBranch).get._2 - val forkedBranch = JGitUtil.getDefaultBranch(newGit, forkedRepository, tmpForkedBranch).get._2 - - val forkedId = getForkedCommitId(oldGit, newGit, - originOwner, repository.name, originBranch, - forkedOwner, repository.name, forkedBranch) - - val oldId = oldGit.getRepository.resolve(forkedId) - val newId = newGit.getRepository.resolve(forkedBranch) - - val (commits, diffs) = getRequestCompareInfo( - originOwner, repository.name, oldId.getName, - forkedOwner, repository.name, newId.getName) - - pulls.html.compare( - commits, - diffs, - repository.repository.originUserName.map { userName => - userName :: getForkedRepositories(userName, repository.name) - } getOrElse List(repository.owner), - originBranch, - forkedBranch, - oldId.getName, - newId.getName, - repository, - originRepository, - forkedRepository, - hasWritePermission(repository.owner, repository.name, context.loginAccount)) + (for( + originRepositoryName <- if(originOwner == forkedOwner){ + Some(forkedRepository.name) + } else { + forkedRepository.repository.originRepositoryName.orElse { + getForkedRepositories(forkedRepository.owner, forkedRepository.name).find(_._1 == originOwner).map(_._2) } + }; + originRepository <- getRepository(originOwner, originRepositoryName, baseUrl) + ) yield { + using( + Git.open(getRepositoryDir(originRepository.owner, originRepository.name)), + Git.open(getRepositoryDir(forkedRepository.owner, forkedRepository.name)) + ){ case (oldGit, newGit) => + val originBranch = JGitUtil.getDefaultBranch(oldGit, originRepository, tmpOriginBranch).get._2 + val forkedBranch = JGitUtil.getDefaultBranch(newGit, forkedRepository, tmpForkedBranch).get._2 + + val forkedId = getForkedCommitId(oldGit, newGit, + originRepository.owner, originRepository.name, originBranch, + forkedRepository.owner, forkedRepository.name, forkedBranch) + + val oldId = oldGit.getRepository.resolve(forkedId) + val newId = newGit.getRepository.resolve(forkedBranch) + + val (commits, diffs) = getRequestCompareInfo( + originRepository.owner, originRepository.name, oldId.getName, + forkedRepository.owner, forkedRepository.name, newId.getName) + + pulls.html.compare( + commits, + diffs, + (forkedRepository.repository.originUserName, forkedRepository.repository.originRepositoryName) match { + case (Some(userName), Some(repositoryName)) => (userName, repositoryName) :: getForkedRepositories(userName, repositoryName) + case _ => (forkedRepository.owner, forkedRepository.name) :: getForkedRepositories(forkedRepository.owner, forkedRepository.name) + }, + originBranch, + forkedBranch, + oldId.getName, + newId.getName, + forkedRepository, + originRepository, + forkedRepository, + hasWritePermission(forkedRepository.owner, forkedRepository.name, context.loginAccount)) } - case _ => NotFound - } + }) getOrElse NotFound }) - ajaxGet("/:owner/:repository/compare/*...*/mergecheck")(collaboratorsOnly { repository => + ajaxGet("/:owner/:repository/compare/*...*/mergecheck")(collaboratorsOnly { forkedRepository => val Seq(origin, forked) = multiParams("splat") - val (originOwner, tmpOriginBranch) = parseCompareIdentifie(origin, repository.owner) - val (forkedOwner, tmpForkedBranch) = parseCompareIdentifie(forked, repository.owner) + val (originOwner, tmpOriginBranch) = parseCompareIdentifie(origin, forkedRepository.owner) + val (forkedOwner, tmpForkedBranch) = parseCompareIdentifie(forked, forkedRepository.owner) - (getRepository(originOwner, repository.name, baseUrl), - getRepository(forkedOwner, repository.name, baseUrl)) match { - case (Some(originRepository), Some(forkedRepository)) => { - using( - Git.open(getRepositoryDir(originOwner, repository.name)), - Git.open(getRepositoryDir(forkedOwner, repository.name)) - ){ case (oldGit, newGit) => - val originBranch = JGitUtil.getDefaultBranch(oldGit, originRepository, tmpOriginBranch).get._2 - val forkedBranch = JGitUtil.getDefaultBranch(newGit, forkedRepository, tmpForkedBranch).get._2 - - pulls.html.mergecheck( - checkConflict(originOwner, repository.name, originBranch, forkedOwner, repository.name, forkedBranch)) + (for( + originRepositoryName <- if(originOwner == forkedOwner){ + Some(forkedRepository.name) + } else { + forkedRepository.repository.originRepositoryName.orElse { + getForkedRepositories(forkedRepository.owner, forkedRepository.name).find(_._1 == originOwner).map(_._2) } + }; + originRepository <- getRepository(originOwner, originRepositoryName, baseUrl) + ) yield { + using( + Git.open(getRepositoryDir(originRepository.owner, originRepository.name)), + Git.open(getRepositoryDir(forkedRepository.owner, forkedRepository.name)) + ){ case (oldGit, newGit) => + val originBranch = JGitUtil.getDefaultBranch(oldGit, originRepository, tmpOriginBranch).get._2 + val forkedBranch = JGitUtil.getDefaultBranch(newGit, forkedRepository, tmpForkedBranch).get._2 + + pulls.html.mergecheck( + checkConflict(originRepository.owner, originRepository.name, originBranch, + forkedRepository.owner, forkedRepository.name, forkedBranch)) } - case _ => NotFound() - } + }) getOrElse NotFound }) post("/:owner/:repository/pulls/new", pullRequestForm)(referrersOnly { (form, repository) => @@ -301,7 +315,7 @@ issueId = issueId, originBranch = form.targetBranch, requestUserName = form.requestUserName, - requestRepositoryName = repository.name, + requestRepositoryName = form.requestRepositoryName, requestBranch = form.requestBranch, commitIdFrom = form.commitIdFrom, commitIdTo = form.commitIdTo) @@ -309,7 +323,7 @@ // fetch requested branch using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git => git.fetch - .setRemote(getRepositoryDir(form.requestUserName, repository.name).toURI.toString) + .setRemote(getRepositoryDir(form.requestUserName, form.requestRepositoryName).toURI.toString) .setRefSpecs(new RefSpec(s"refs/heads/${form.requestBranch}:refs/pull/${issueId}/head")) .call } @@ -407,8 +421,7 @@ private def getForkedCommitId(oldGit: Git, newGit: Git, userName: String, repositoryName: String, branch: String, requestUserName: String, requestRepositoryName: String, requestBranch: String): String = JGitUtil.getCommitLogs(newGit, requestBranch, true){ commit => - existsCommitId(userName, repositoryName, commit.getName) && - JGitUtil.getBranchesOfCommit(oldGit, commit.getName).contains(branch) + existsCommitId(userName, repositoryName, commit.getName) && JGitUtil.getBranchesOfCommit(oldGit, commit.getName).contains(branch) }.head.id private def getRequestCompareInfo(userName: String, repositoryName: String, branch: String, diff --git a/src/main/scala/app/RepositorySettingsController.scala b/src/main/scala/app/RepositorySettingsController.scala index 4c85311..e6b995c 100644 --- a/src/main/scala/app/RepositorySettingsController.scala +++ b/src/main/scala/app/RepositorySettingsController.scala @@ -21,12 +21,13 @@ with OwnerAuthenticator with UsersAuthenticator => // for repository options - case class OptionsForm(description: Option[String], defaultBranch: String, isPrivate: Boolean) + case class OptionsForm(repositoryName: String, description: Option[String], defaultBranch: String, isPrivate: Boolean) val optionsForm = mapping( - "description" -> trim(label("Description" , optional(text()))), - "defaultBranch" -> trim(label("Default Branch" , text(required, maxlength(100)))), - "isPrivate" -> trim(label("Repository Type", boolean())) + "repositoryName" -> trim(label("Description" , text(required, maxlength(40), identifier))), // TODO unique checking + "description" -> trim(label("Description" , optional(text()))), + "defaultBranch" -> trim(label("Default Branch" , text(required, maxlength(100)))), + "isPrivate" -> trim(label("Repository Type", boolean())) )(OptionsForm.apply) // for collaborator addition @@ -70,8 +71,21 @@ repository.repository.isPrivate } getOrElse form.isPrivate ) + // Change repository name + if(repository.name != form.repositoryName){ + // Update database + renameRepository(repository.owner, repository.name, form.repositoryName) + // Move git repository + defining(getRepositoryDir(repository.owner, repository.name)){ dir => + FileUtils.moveDirectory(dir, getRepositoryDir(repository.owner, form.repositoryName)) + } + // Move wiki repository + defining(getWikiRepositoryDir(repository.owner, repository.name)){ dir => + FileUtils.moveDirectory(dir, getWikiRepositoryDir(repository.owner, form.repositoryName)) + } + } flash += "info" -> "Repository settings has been updated." - redirect(s"/${repository.owner}/${repository.name}/settings/options") + redirect(s"/${repository.owner}/${form.repositoryName}/settings/options") }) /** diff --git a/src/main/scala/service/RepositoryService.scala b/src/main/scala/service/RepositoryService.scala index 14172c1..7bef539 100644 --- a/src/main/scala/service/RepositoryService.scala +++ b/src/main/scala/service/RepositoryService.scala @@ -39,6 +39,51 @@ IssueId insert (userName, repositoryName, 0) } + def renameRepository(userName: String, oldRepositoryName: String, newRepositoryName: String): Unit = { + (Query(Repositories) filter { t => t.byRepository(userName, oldRepositoryName) } firstOption).map { repository => + Repositories insert repository.copy(repositoryName = newRepositoryName) + + val webHooks = Query(WebHooks ).filter(_.byRepository(userName, oldRepositoryName)).list + val milestones = Query(Milestones ).filter(_.byRepository(userName, oldRepositoryName)).list + val issueId = Query(IssueId ).filter(_.byRepository(userName, oldRepositoryName)).list + val issues = Query(Issues ).filter(_.byRepository(userName, oldRepositoryName)).list + val pullRequests = Query(PullRequests ).filter(_.byRepository(userName, oldRepositoryName)).list + val labels = Query(Labels ).filter(_.byRepository(userName, oldRepositoryName)).list + val issueComments = Query(IssueComments).filter(_.byRepository(userName, oldRepositoryName)).list + val issueLabels = Query(IssueLabels ).filter(_.byRepository(userName, oldRepositoryName)).list + val collaborators = Query(Collaborators).filter(_.byRepository(userName, oldRepositoryName)).list + val commitLog = Query(CommitLog ).filter(_.byRepository(userName, oldRepositoryName)).list + val activities = Query(Activities ).filter(_.byRepository(userName, oldRepositoryName)).list + + Repositories.filter { t => + (t.originUserName is userName.bind) && (t.originRepositoryName is oldRepositoryName.bind) + }.map(_.originRepositoryName).update(newRepositoryName) + + Repositories.filter { t => + (t.parentUserName is userName.bind) && (t.parentRepositoryName is oldRepositoryName.bind) + }.map(_.parentRepositoryName).update(newRepositoryName) + + PullRequests.filter { t => + t.requestRepositoryName is oldRepositoryName.bind + }.map(_.requestRepositoryName).update(newRepositoryName) + + deleteRepository(userName, oldRepositoryName) + + WebHooks .insertAll(webHooks .map(_.copy(repositoryName = newRepositoryName)) :_*) + Milestones .insertAll(milestones .map(_.copy(repositoryName = newRepositoryName)) :_*) + IssueId .insertAll(issueId .map(_.copy(_2 = newRepositoryName)) :_*) + Issues .insertAll(issues .map(_.copy(repositoryName = newRepositoryName)) :_*) + PullRequests .insertAll(pullRequests .map(_.copy(repositoryName = newRepositoryName)) :_*) + IssueComments .insertAll(issueComments .map(_.copy(repositoryName = newRepositoryName)) :_*) + Labels .insertAll(labels .map(_.copy(repositoryName = newRepositoryName)) :_*) + IssueLabels .insertAll(issueLabels .map(_.copy(repositoryName = newRepositoryName)) :_*) + Collaborators .insertAll(collaborators .map(_.copy(repositoryName = newRepositoryName)) :_*) + CommitLog .insertAll(commitLog .map(_.copy(_2 = newRepositoryName)) :_*) + Activities .insertAll(activities .map(_.copy(repositoryName = newRepositoryName)) :_*) + + } + } + def deleteRepository(userName: String, repositoryName: String): Unit = { Activities .filter(_.byRepository(userName, repositoryName)).delete CommitLog .filter(_.byRepository(userName, repositoryName)).delete @@ -207,11 +252,11 @@ }.length).first - def getForkedRepositories(userName: String, repositoryName: String): List[String] = + def getForkedRepositories(userName: String, repositoryName: String): List[(String, String)] = Query(Repositories).filter { t => (t.originUserName is userName.bind) && (t.originRepositoryName is repositoryName.bind) } - .sortBy(_.userName asc).map(_.userName).list + .sortBy(_.userName asc).map(t => t.userName ~ t.repositoryName).list } diff --git a/src/main/twirl/pulls/compare.scala.html b/src/main/twirl/pulls/compare.scala.html index 2ac9135..92fc8f8 100644 --- a/src/main/twirl/pulls/compare.scala.html +++ b/src/main/twirl/pulls/compare.scala.html @@ -1,6 +1,6 @@ @(commits: Seq[Seq[util.JGitUtil.CommitInfo]], diffs: Seq[util.JGitUtil.DiffInfo], - members: List[String], + members: List[(String, String)], originId: String, forkedId: String, sourceId: String, @@ -20,25 +20,25 @@
@@ -49,7 +49,7 @@