diff --git a/src/main/resources/update/1_3.sql b/src/main/resources/update/1_3.sql index 8001b9e..00c020e 100644 --- a/src/main/resources/update/1_3.sql +++ b/src/main/resources/update/1_3.sql @@ -1 +1,15 @@ ALTER TABLE ACCOUNT ADD COLUMN IMAGE VARCHAR(100); + +ALTER TABLE REPOSITORY ADD COLUMN ORIGIN_USER_NAME VARCHAR(100); +ALTER TABLE REPOSITORY ADD COLUMN ORIGIN_REPOSITORY_NAME VARCHAR(100); + +CREATE TABLE PULL_REQUEST( + PULL_REQUEST_ID INT AUTO_INCREMENT, + USER_NAME VARCHAR(100) NOT NULL, + REPOSITORY_NAME VARCHAR(100) NOT NULL, + ISSUE_ID INT NOT NULL, + COMMIT_ID VARCHAR(40) NOT NULL +); + +ALTER TABLE PULL_REQUEST ADD CONSTRAINT IDX_PULL_REQUEST_PK PRIMARY KEY (PULL_REQUEST_ID); +ALTER TABLE PULL_REQUEST ADD CONSTRAINT IDX_PULL_REQUEST_1 UNIQUE ISSUE (USER_NAME, REPOSITORY_NAME, ISSUE_ID); diff --git a/src/main/scala/app/CreateRepositoryController.scala b/src/main/scala/app/CreateRepositoryController.scala index 1e51caa..4edddb2 100644 --- a/src/main/scala/app/CreateRepositoryController.scala +++ b/src/main/scala/app/CreateRepositoryController.scala @@ -1,7 +1,7 @@ package app import util.Directory._ -import util.UsersAuthenticator +import util.{JGitUtil, UsersAuthenticator, ReferrerAuthenticator} import service._ import java.io.File import org.eclipse.jgit.api.Git @@ -11,24 +11,31 @@ class CreateRepositoryController extends CreateRepositoryControllerBase with RepositoryService with AccountService with WikiService with LabelsService with ActivityService - with UsersAuthenticator + with UsersAuthenticator with ReferrerAuthenticator /** * Creates new repository. */ trait CreateRepositoryControllerBase extends ControllerBase { self: RepositoryService with WikiService with LabelsService with ActivityService - with UsersAuthenticator => + with UsersAuthenticator with ReferrerAuthenticator => case class RepositoryCreationForm(name: String, description: Option[String], isPrivate: Boolean, createReadme: Boolean) - val form = mapping( + case class ForkRepositoryForm(owner: String, name: String) + + val newForm = mapping( "name" -> trim(label("Repository name", text(required, maxlength(40), identifier, unique))), "description" -> trim(label("Description" , optional(text()))), "isPrivate" -> trim(label("Repository Type", boolean())), "createReadme" -> trim(label("Create README" , boolean())) )(RepositoryCreationForm.apply) + val forkForm = mapping( + "owner" -> trim(label("Repository owner", text(required))), + "name" -> trim(label("Repository name", text(required))) + )(ForkRepositoryForm.apply) + /** * Show the new repository form. */ @@ -39,7 +46,7 @@ /** * Create new repository. */ - post("/new", form)(usersOnly { form => + post("/new", newForm)(usersOnly { form => val loginAccount = context.loginAccount.get val loginUserName = loginAccount.userName @@ -47,12 +54,7 @@ createRepository(form.name, loginUserName, form.description, form.isPrivate) // Insert default labels - createLabel(loginUserName, form.name, "bug", "fc2929") - createLabel(loginUserName, form.name, "duplicate", "cccccc") - createLabel(loginUserName, form.name, "enhancement", "84b6eb") - createLabel(loginUserName, form.name, "invalid", "e6e6e6") - createLabel(loginUserName, form.name, "question", "cc317c") - createLabel(loginUserName, form.name, "wontfix", "ffffff") + insertDefaultLabels(loginUserName, form.name) // Create the actual repository val gitdir = getRepositoryDir(loginUserName, form.name) @@ -97,7 +99,50 @@ // redirect to the repository redirect("/%s/%s".format(loginUserName, form.name)) }) - + + post("/:owner/:repository/_fork")(referrersOnly { repository => + val loginAccount = context.loginAccount.get + val loginUserName = loginAccount.userName + + 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)) + + // Insert default labels + insertDefaultLabels(loginUserName, repository.name) + + // clone repository actually + val git = Git.cloneRepository + .setURI(getRepositoryDir(repository.owner, repository.name).toURI.toString) + .setDirectory(getRepositoryDir(loginUserName, repository.name)) + .setBare(true).call + + val config = git.getRepository.getConfig + config.setBoolean("http", null, "receivepack", true) + config.save + + // Create Wiki repository + // TODO Wiki repository should be cloned also!! + createWikiRepository(loginAccount, repository.name) + + // TODO Record activity!! + //recordCreateRepositoryActivity(loginUserName, repositoryName, loginUserName) + } + // redirect to the repository + redirect("/%s/%s".format(loginUserName, repository.name)) + }) + + private def insertDefaultLabels(userName: String, repositoryName: String): Unit = { + createLabel(userName, repositoryName, "bug", "fc2929") + createLabel(userName, repositoryName, "duplicate", "cccccc") + createLabel(userName, repositoryName, "enhancement", "84b6eb") + createLabel(userName, repositoryName, "invalid", "e6e6e6") + createLabel(userName, repositoryName, "question", "cc317c") + createLabel(userName, repositoryName, "wontfix", "ffffff") + } + /** * Duplicate check for the repository name. */ diff --git a/src/main/scala/model/Repository.scala b/src/main/scala/model/Repository.scala index fcfb336..1c1f2e9 100644 --- a/src/main/scala/model/Repository.scala +++ b/src/main/scala/model/Repository.scala @@ -9,7 +9,9 @@ def registeredDate = column[java.util.Date]("REGISTERED_DATE") def updatedDate = column[java.util.Date]("UPDATED_DATE") def lastActivityDate = column[java.util.Date]("LAST_ACTIVITY_DATE") - def * = userName ~ repositoryName ~ isPrivate ~ description.? ~ defaultBranch ~ registeredDate ~ updatedDate ~ lastActivityDate <> (Repository, Repository.unapply _) + 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 byPrimaryKey(owner: String, repository: String) = byRepository(owner, repository) } @@ -22,5 +24,7 @@ defaultBranch: String, registeredDate: java.util.Date, updatedDate: java.util.Date, - lastActivityDate: java.util.Date + lastActivityDate: java.util.Date, + originUserName: Option[String], + originRepositoryName: Option[String] ) diff --git a/src/main/scala/service/RepositoryService.scala b/src/main/scala/service/RepositoryService.scala index 153aa95..d207f6d 100644 --- a/src/main/scala/service/RepositoryService.scala +++ b/src/main/scala/service/RepositoryService.scala @@ -15,18 +15,23 @@ * @param userName the user name of the repository owner * @param description the repository description * @param isPrivate the repository type (private is true, otherwise false) + * @param originRepositoryName specify for the forked repository. (default is None) + * @param originUserName specify for the forked repository. (default is None) */ - def createRepository(repositoryName: String, userName: String, description: Option[String], isPrivate: Boolean): Unit = { + def createRepository(repositoryName: String, userName: String, description: Option[String], isPrivate: Boolean, + originRepositoryName: Option[String] = None, originUserName: Option[String] = None): Unit = { Repositories insert Repository( - userName = userName, - repositoryName = repositoryName, - isPrivate = isPrivate, - description = description, - defaultBranch = "master", - registeredDate = currentDate, - updatedDate = currentDate, - lastActivityDate = currentDate) + userName = userName, + repositoryName = repositoryName, + isPrivate = isPrivate, + description = description, + defaultBranch = "master", + registeredDate = currentDate, + updatedDate = currentDate, + lastActivityDate = currentDate, + originUserName = originUserName, + originRepositoryName = originRepositoryName) IssueId insert (userName, repositoryName, 0) } diff --git a/src/main/twirl/header.scala.html b/src/main/twirl/header.scala.html index 45b939d..a46eecd 100644 --- a/src/main/twirl/header.scala.html +++ b/src/main/twirl/header.scala.html @@ -6,6 +6,7 @@ @if(repository.repository.isPrivate){ } +