diff --git a/src/main/resources/update/1_5.sql b/src/main/resources/update/1_5.sql index 3f85dc0..21a8337 100644 --- a/src/main/resources/update/1_5.sql +++ b/src/main/resources/update/1_5.sql @@ -1,6 +1,7 @@ ALTER TABLE REPOSITORY ADD COLUMN ORIGIN_USER_NAME VARCHAR(100); ALTER TABLE REPOSITORY ADD COLUMN ORIGIN_REPOSITORY_NAME VARCHAR(100); - +ALTER TABLE REPOSITORY ADD COLUMN PARENT_USER_NAME VARCHAR(100); +ALTER TABLE REPOSITORY ADD COLUMN PARENT_REPOSITORY_NAME VARCHAR(100); CREATE TABLE PULL_REQUEST( USER_NAME VARCHAR(100) NOT NULL, diff --git a/src/main/scala/app/CreateRepositoryController.scala b/src/main/scala/app/CreateRepositoryController.scala index 0aa12e9..403fbed 100644 --- a/src/main/scala/app/CreateRepositoryController.scala +++ b/src/main/scala/app/CreateRepositoryController.scala @@ -116,8 +116,20 @@ if(getRepository(loginUserName, repository.name, baseUrl).isEmpty){ // Insert to the database at first // TODO Is private repository cloneable? - createRepository(repository.name, loginUserName, repository.repository.description, - repository.repository.isPrivate, Some(repository.name), Some(repository.owner)) + + 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) + ) // Insert default labels insertDefaultLabels(loginUserName, repository.name) diff --git a/src/main/scala/app/RepositoryViewerController.scala b/src/main/scala/app/RepositoryViewerController.scala index e4dc1ed..6c3b1d7 100644 --- a/src/main/scala/app/RepositoryViewerController.scala +++ b/src/main/scala/app/RepositoryViewerController.scala @@ -202,6 +202,14 @@ BadRequest } }) + + get("/:owner/:repository/network/members")(referrersOnly { repository => + repo.html.forked( + getForkedRepositoryTree( + repository.repository.originUserName.getOrElse(repository.owner), + repository.repository.originRepositoryName.getOrElse(repository.name)), + repository) + }) /** * Provides HTML of the file list. diff --git a/src/main/scala/model/Repository.scala b/src/main/scala/model/Repository.scala index 1c1f2e9..215b670 100644 --- a/src/main/scala/model/Repository.scala +++ b/src/main/scala/model/Repository.scala @@ -11,7 +11,9 @@ def lastActivityDate = column[java.util.Date]("LAST_ACTIVITY_DATE") def originUserName = column[String]("ORIGIN_USER_NAME") def originRepositoryName = column[String]("ORIGIN_REPOSITORY_NAME") - def * = userName ~ repositoryName ~ isPrivate ~ description.? ~ defaultBranch ~ registeredDate ~ updatedDate ~ lastActivityDate ~ originUserName.? ~ originRepositoryName.? <> (Repository, Repository.unapply _) + def parentUserName = column[String]("PARENT_USER_NAME") + def parentRepositoryName = column[String]("PARENT_REPOSITORY_NAME") + def * = userName ~ repositoryName ~ isPrivate ~ description.? ~ defaultBranch ~ registeredDate ~ updatedDate ~ lastActivityDate ~ originUserName.? ~ originRepositoryName.? ~ parentUserName.? ~ parentRepositoryName.? <> (Repository, Repository.unapply _) def byPrimaryKey(owner: String, repository: String) = byRepository(owner, repository) } @@ -26,5 +28,7 @@ updatedDate: java.util.Date, lastActivityDate: java.util.Date, originUserName: Option[String], - originRepositoryName: Option[String] + originRepositoryName: Option[String], + parentUserName: Option[String], + parentRepositoryName: Option[String] ) diff --git a/src/main/scala/service/RepositoryService.scala b/src/main/scala/service/RepositoryService.scala index b9ce2e2..ff9d66b 100644 --- a/src/main/scala/service/RepositoryService.scala +++ b/src/main/scala/service/RepositoryService.scala @@ -19,7 +19,8 @@ * @param originUserName specify for the forked repository. (default is None) */ def createRepository(repositoryName: String, userName: String, description: Option[String], isPrivate: Boolean, - originRepositoryName: Option[String] = None, originUserName: Option[String] = None): Unit = { + originRepositoryName: Option[String] = None, originUserName: Option[String] = None, + parentRepositoryName: Option[String] = None, parentUserName: Option[String] = None): Unit = { Repositories insert Repository( userName = userName, @@ -31,8 +32,10 @@ updatedDate = currentDate, lastActivityDate = currentDate, originUserName = originUserName, - originRepositoryName = originRepositoryName) - + originRepositoryName = originRepositoryName, + parentUserName = parentUserName, + parentRepositoryName = parentRepositoryName) + IssueId insert (userName, repositoryName, 0) } @@ -87,7 +90,13 @@ } q1.union(q2).filter(visibleFor(_, loginUserName)).sortBy(_.lastActivityDate desc).list map { repository => - new RepositoryInfo(JGitUtil.getRepositoryInfo(repository.userName, repository.repositoryName, baseUrl), repository) + new RepositoryInfo( + JGitUtil.getRepositoryInfo(repository.userName, repository.repositoryName, baseUrl), + repository, + getForkedCount( + repository.originUserName.getOrElse(repository.userName), + repository.originRepositoryName.getOrElse(repository.repositoryName) + )) } } @@ -101,7 +110,13 @@ */ def getRepository(userName: String, repositoryName: String, baseUrl: String): Option[RepositoryInfo] = { (Query(Repositories) filter { t => t.byRepository(userName, repositoryName) } firstOption) map { repository => - new RepositoryInfo(JGitUtil.getRepositoryInfo(repository.userName, repository.repositoryName, baseUrl), repository) + new RepositoryInfo( + JGitUtil.getRepositoryInfo(repository.userName, repository.repositoryName, baseUrl), + repository, + getForkedCount( + repository.originUserName.getOrElse(repository.userName), + repository.originRepositoryName.getOrElse(repository.repositoryName) + )) } } @@ -115,7 +130,13 @@ def getAccessibleRepositories(account: Option[Account], baseUrl: String): List[RepositoryInfo] = { def newRepositoryInfo(repository: Repository): RepositoryInfo = { - new RepositoryInfo(JGitUtil.getRepositoryInfo(repository.userName, repository.repositoryName, baseUrl), repository) + new RepositoryInfo( + JGitUtil.getRepositoryInfo(repository.userName, repository.repositoryName, baseUrl), + repository, + getForkedCount( + repository.originUserName.getOrElse(repository.userName), + repository.originRepositoryName.getOrElse(repository.repositoryName) + )) } (account match { @@ -194,28 +215,39 @@ } } -// def getBaseRepositories(userName: String, repositoryName: String, repositories: List[String] = Nil): List[String] = { -// Query(Repositories).filter { t => -// (t.originUserName is userName.bind) && (t.originRepositoryName is repositoryName.bind) -// }.map(_.userName).list match { -// case Nil => repositories.sorted -// case list => list.map { x => -// getBaseRepositories(x, repositoryName, x :: repositories) -// }.flatten -// } -// } + // TODO It must be _.length instead of map (_.issueId) list).length. + // But it does not work on Slick 1.0.1 (worked on Slick 1.0.0). + // https://github.com/slick/slick/issues/170 + private def getForkedCount(userName: String, repositoryName: String): Int = + Query(Repositories).filter { t => + (t.originUserName is userName.bind) && (t.originRepositoryName is repositoryName.bind) + }.list.length + + + def getForkedRepositoryTree(userName: String, repositoryName: String): RepositoryTreeNode = { + RepositoryTreeNode(userName, repositoryName, + Query(Repositories).filter { t => + (t.parentUserName is userName.bind) && (t.parentRepositoryName is repositoryName.bind) + }.map { t => + t.userName ~ t.repositoryName + }.list.map { case (userName, repositoryName) => + getForkedRepositoryTree(userName, repositoryName) + } + ) + } } object RepositoryService { case class RepositoryInfo(owner: String, name: String, url: String, repository: Repository, - commitCount: Int, branchList: List[String], tags: List[util.JGitUtil.TagInfo]){ + commitCount: Int, forkedCount: Int, branchList: List[String], tags: List[util.JGitUtil.TagInfo]){ - def this(repo: JGitUtil.RepositoryInfo, model: Repository) = { - this(repo.owner, repo.name, repo.url, model, repo.commitCount, repo.branchList, repo.tags) + def this(repo: JGitUtil.RepositoryInfo, model: Repository, forkedCount: Int) = { + this(repo.owner, repo.name, repo.url, model, repo.commitCount, forkedCount, repo.branchList, repo.tags) } - } + case class RepositoryTreeNode(owner: String, name: String, children: List[RepositoryTreeNode]) + } \ No newline at end of file diff --git a/src/main/twirl/account/repositories.scala.html b/src/main/twirl/account/repositories.scala.html index 03f2c6e..97045d9 100644 --- a/src/main/twirl/account/repositories.scala.html +++ b/src/main/twirl/account/repositories.scala.html @@ -16,7 +16,7 @@ } @if(repository.repository.originUserName.isDefined){ -
+ } @if(repository.repository.description.isDefined){