Added an option to pass git@ based URLs
This commit is contained in:
@@ -38,6 +38,7 @@ import org.eclipse.jgit.transport.JschConfigSessionFactory;
|
||||
import org.eclipse.jgit.transport.OpenSshConfig;
|
||||
import org.eclipse.jgit.transport.RefSpec;
|
||||
import org.eclipse.jgit.transport.SshTransport;
|
||||
import org.eclipse.jgit.transport.URIish;
|
||||
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
|
||||
import org.eclipse.jgit.util.FS;
|
||||
import org.eclipse.jgit.util.FileUtils;
|
||||
@@ -94,7 +95,7 @@ class GitRepo {
|
||||
* @param projectUri - URI of the project
|
||||
* @return file where the project was cloned
|
||||
*/
|
||||
File cloneProject(URI projectUri) {
|
||||
File cloneProject(URIish projectUri) {
|
||||
try {
|
||||
log.info("Cloning repo from [{}] to [{}]", projectUri, this.basedir);
|
||||
Git git = cloneToBasedir(projectUri, this.basedir);
|
||||
@@ -243,7 +244,7 @@ class GitRepo {
|
||||
return ResourceUtils.getFile(project.toURI()).getAbsoluteFile();
|
||||
}
|
||||
|
||||
private Git cloneToBasedir(URI projectUrl, File destinationFolder)
|
||||
private Git cloneToBasedir(URIish projectUrl, File destinationFolder)
|
||||
throws GitAPIException {
|
||||
CloneCommand command = this.gitFactory.getCloneCommandByCloneRepository()
|
||||
.setURI(projectUrl.toString() + ".git").setDirectory(destinationFolder);
|
||||
|
||||
@@ -3,8 +3,10 @@ package org.springframework.cloud.release.internal.git;
|
||||
import java.io.File;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
|
||||
import org.eclipse.jgit.transport.URIish;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.cloud.release.internal.ReleaserProperties;
|
||||
@@ -82,9 +84,15 @@ public class ProjectGitHandler implements ReleaserPropertiesAware {
|
||||
*/
|
||||
public File cloneProjectFromOrg(String projectName) {
|
||||
String orgUrl = this.properties.getMetaRelease().getGitOrgUrl();
|
||||
String fullUrl = orgUrl.endsWith("/") ? orgUrl + projectName : orgUrl + "/" +
|
||||
projectName + suffixNonHttpRepo(orgUrl);
|
||||
String fullUrl = orgUrl.endsWith("/") ? (orgUrl + projectName) : (orgUrl + "/" +
|
||||
projectName + suffixNonHttpRepo(orgUrl));
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Full url of the project is [{}]", fullUrl);
|
||||
}
|
||||
File clonedProject = cloneProject(fullUrl);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Successfully cloned the project to [{}]", clonedProject);
|
||||
}
|
||||
String version = this.properties.getFixedVersions().get(projectName);
|
||||
if (StringUtils.isEmpty(version)) {
|
||||
throw new IllegalStateException("You haven't provided a version for project [" + projectName + "]");
|
||||
@@ -109,7 +117,7 @@ public class ProjectGitHandler implements ReleaserPropertiesAware {
|
||||
File destinationDir = properties.getGit().getCloneDestinationDir() != null ?
|
||||
new File(properties.getGit().getCloneDestinationDir()) :
|
||||
Files.createTempDirectory("releaser").toFile();
|
||||
return gitRepo(destinationDir).cloneProject(URI.create(url));
|
||||
return gitRepo(destinationDir).cloneProject(new URIish(url));
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ public class PomUpdateAcceptanceTests {
|
||||
|
||||
private ReleaserProperties releaserProperties() throws URISyntaxException {
|
||||
ReleaserProperties releaserProperties = new ReleaserProperties();
|
||||
releaserProperties.getGit().setSpringCloudReleaseGitUrl(file("/projects/spring-cloud-release/").toURI().getPath());
|
||||
releaserProperties.getGit().setSpringCloudReleaseGitUrl(file("/projects/spring-cloud-release/").toURI().toString());
|
||||
return releaserProperties;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ public class DocumentationUpdaterTests {
|
||||
TestUtils.prepareLocalRepo();
|
||||
FileSystemUtils.copyRecursively(file("/projects"), this.tmpFolder);
|
||||
ReleaserProperties properties = new ReleaserProperties();
|
||||
properties.getGit().setDocumentationUrl(file("/projects/spring-cloud-static/").toURI().getPath());
|
||||
properties.getGit().setDocumentationUrl(file("/projects/spring-cloud-static/").toURI().toString());
|
||||
this.handler = new ProjectGitHandler(properties);
|
||||
this.clonedDocProject = this.handler.cloneDocumentationProject();
|
||||
}
|
||||
@@ -51,7 +51,7 @@ public class DocumentationUpdaterTests {
|
||||
ProjectVersion releaseTrainVersion = new ProjectVersion("spring-cloud-sleuth", "1.3.4.SR10");
|
||||
ReleaserProperties properties = new ReleaserProperties();
|
||||
properties.getGit().setDocumentationBranch("master");
|
||||
properties.getGit().setDocumentationUrl(file("/projects/spring-cloud-release/").toURI().getPath());
|
||||
properties.getGit().setDocumentationUrl(file("/projects/spring-cloud-release/").toURI().toString());
|
||||
|
||||
BDDAssertions.thenThrownBy(() ->
|
||||
new DocumentationUpdater(new ProjectGitHandler(properties))
|
||||
@@ -65,7 +65,7 @@ public class DocumentationUpdaterTests {
|
||||
throws URISyntaxException {
|
||||
ProjectVersion releaseTrainVersion = new ProjectVersion("spring-cloud-sleuth", "1.3.4.SR10");
|
||||
ReleaserProperties properties = new ReleaserProperties();
|
||||
properties.getGit().setDocumentationUrl(file("/projects/spring-cloud-static/").toURI().getPath());
|
||||
properties.getGit().setDocumentationUrl(file("/projects/spring-cloud-static/").toURI().toString());
|
||||
|
||||
BDDAssertions.thenThrownBy(() ->
|
||||
new DocumentationUpdater(new ProjectGitHandler(properties)) {
|
||||
@@ -94,7 +94,7 @@ public class DocumentationUpdaterTests {
|
||||
throws URISyntaxException, IOException {
|
||||
ProjectVersion releaseTrainVersion = new ProjectVersion("spring-cloud-sleuth", "1.3.4.SR10");
|
||||
ReleaserProperties properties = new ReleaserProperties();
|
||||
properties.getGit().setDocumentationUrl(file("/projects/spring-cloud-static/").toURI().getPath());
|
||||
properties.getGit().setDocumentationUrl(file("/projects/spring-cloud-static/").toURI().toString());
|
||||
|
||||
File updatedDocs = new DocumentationUpdater(new ProjectGitHandler(properties))
|
||||
.updateDocsRepo(releaseTrainVersion, "vAngel.SR33");
|
||||
@@ -110,7 +110,7 @@ public class DocumentationUpdaterTests {
|
||||
throws URISyntaxException {
|
||||
ProjectVersion releaseTrainVersion = new ProjectVersion("spring-cloud-sleuth", "1.3.4.SR10");
|
||||
ReleaserProperties properties = new ReleaserProperties();
|
||||
properties.getGit().setDocumentationUrl(this.clonedDocProject.toURI().getPath());
|
||||
properties.getGit().setDocumentationUrl(this.clonedDocProject.toURI().toString());
|
||||
ProjectGitHandler handler = BDDMockito.spy(new ProjectGitHandler(properties));
|
||||
|
||||
new DocumentationUpdater(handler)
|
||||
@@ -125,7 +125,7 @@ public class DocumentationUpdaterTests {
|
||||
throws URISyntaxException, IOException {
|
||||
ProjectVersion releaseTrainVersion = new ProjectVersion("spring-cloud-sleuth", "1.3.4.SR10");
|
||||
ReleaserProperties properties = new ReleaserProperties();
|
||||
properties.getGit().setDocumentationUrl(this.clonedDocProject.toURI().getPath());
|
||||
properties.getGit().setDocumentationUrl(this.clonedDocProject.toURI().toString());
|
||||
|
||||
File updatedDocs = new DocumentationUpdater(new ProjectGitHandler(properties))
|
||||
.updateDocsRepo(releaseTrainVersion, "Angel.SR33");
|
||||
@@ -141,7 +141,7 @@ public class DocumentationUpdaterTests {
|
||||
throws URISyntaxException, IOException {
|
||||
ProjectVersion releaseTrainVersion = new ProjectVersion("spring-cloud-sleuth", "2.0.0.SR33");
|
||||
ReleaserProperties properties = new ReleaserProperties();
|
||||
properties.getGit().setDocumentationUrl(this.clonedDocProject.toURI().getPath());
|
||||
properties.getGit().setDocumentationUrl(this.clonedDocProject.toURI().toString());
|
||||
|
||||
File updatedDocs = new DocumentationUpdater(new ProjectGitHandler(properties))
|
||||
.updateDocsRepo(releaseTrainVersion, "vFinchley.SR33");
|
||||
@@ -157,7 +157,7 @@ public class DocumentationUpdaterTests {
|
||||
throws URISyntaxException, IOException {
|
||||
ProjectVersion releaseTrainVersion = new ProjectVersion("spring-cloud-sleuth", "2.0.0.SR33");
|
||||
ReleaserProperties properties = new ReleaserProperties();
|
||||
properties.getGit().setDocumentationUrl(this.clonedDocProject.toURI().getPath());
|
||||
properties.getGit().setDocumentationUrl(this.clonedDocProject.toURI().toString());
|
||||
|
||||
File updatedDocs = new DocumentationUpdater(new ProjectGitHandler(properties))
|
||||
.updateDocsRepo(releaseTrainVersion, "Finchley.SR33");
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.lib.Ref;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.eclipse.jgit.transport.URIish;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
@@ -46,7 +47,7 @@ public class GitRepoTests {
|
||||
|
||||
@Test
|
||||
public void should_clone_the_project_from_a_given_location() throws IOException {
|
||||
this.gitRepo.cloneProject(this.springCloudReleaseProject.toURI());
|
||||
this.gitRepo.cloneProject(new URIish(this.springCloudReleaseProject.toURI().toURL()));
|
||||
|
||||
then(new File(this.tmpFolder, ".git")).exists();
|
||||
}
|
||||
@@ -54,14 +55,15 @@ public class GitRepoTests {
|
||||
@Test
|
||||
public void should_throw_exception_when_there_is_no_repo() throws IOException, URISyntaxException {
|
||||
thenThrownBy(() -> this.gitRepo
|
||||
.cloneProject(GitRepoTests.class.getResource("/projects/").toURI()))
|
||||
.cloneProject(new URIish(GitRepoTests.class.getResource("/projects/").toURI().toURL())))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessageContaining("Exception occurred while cloning repo");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_throw_an_exception_when_failed_to_initialize_the_repo() throws IOException {
|
||||
thenThrownBy(() -> new GitRepo(this.tmpFolder, new ExceptionThrowingJGitFactory()).cloneProject(this.springCloudReleaseProject.toURI()))
|
||||
thenThrownBy(() -> new GitRepo(this.tmpFolder,
|
||||
new ExceptionThrowingJGitFactory()).cloneProject(new URIish(this.springCloudReleaseProject.toURI().toURL())))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessageContaining("Exception occurred while cloning repo")
|
||||
.hasCauseInstanceOf(CustomException.class);
|
||||
@@ -69,7 +71,8 @@ public class GitRepoTests {
|
||||
|
||||
@Test
|
||||
public void should_check_out_a_branch_on_cloned_repo() throws IOException {
|
||||
File project = this.gitRepo.cloneProject(this.springCloudReleaseProject.toURI());
|
||||
File project = this.gitRepo
|
||||
.cloneProject(new URIish(this.springCloudReleaseProject.toURI().toURL()));
|
||||
new GitRepo(project).checkout("vCamden.SR3");
|
||||
|
||||
File pom = new File(this.tmpFolder, "pom.xml");
|
||||
@@ -79,7 +82,8 @@ public class GitRepoTests {
|
||||
|
||||
@Test
|
||||
public void should_check_out_a_branch_on_cloned_repo2() throws IOException {
|
||||
File project = this.gitRepo.cloneProject(this.springCloudReleaseProject.toURI());
|
||||
File project = this.gitRepo
|
||||
.cloneProject(new URIish(this.springCloudReleaseProject.toURI().toURL()));
|
||||
new GitRepo(project).checkout("Camden.x");
|
||||
|
||||
File pom = new File(this.tmpFolder, "pom.xml");
|
||||
@@ -89,21 +93,24 @@ public class GitRepoTests {
|
||||
|
||||
@Test
|
||||
public void should_return_true_if_branch_exists() throws IOException {
|
||||
File project = new GitRepo(this.tmpFolder).cloneProject(this.springCloudReleaseProject.toURI());
|
||||
File project = new GitRepo(this.tmpFolder)
|
||||
.cloneProject(new URIish(this.springCloudReleaseProject.toURI().toURL()));
|
||||
|
||||
then(new GitRepo(project).hasBranch("Camden.x")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_return_false_if_branch_does_not_exist() throws IOException {
|
||||
File project = new GitRepo(this.tmpFolder).cloneProject(this.springCloudReleaseProject.toURI());
|
||||
File project = new GitRepo(this.tmpFolder)
|
||||
.cloneProject(new URIish(this.springCloudReleaseProject.toURI().toURL()));
|
||||
|
||||
then(new GitRepo(project).hasBranch("aksjdhkasjkajshd")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_throw_an_exception_when_checking_out_nonexisting_branch() throws IOException {
|
||||
File project = new GitRepo(this.tmpFolder).cloneProject(this.springCloudReleaseProject.toURI());
|
||||
File project = new GitRepo(this.tmpFolder)
|
||||
.cloneProject(new URIish(this.springCloudReleaseProject.toURI().toURL()));
|
||||
try {
|
||||
new GitRepo(project).checkout("nonExistingBranch");
|
||||
fail("should throw an exception");
|
||||
@@ -114,7 +121,8 @@ public class GitRepoTests {
|
||||
|
||||
@Test
|
||||
public void should_commit_changes() throws Exception {
|
||||
File project = new GitRepo(this.tmpFolder).cloneProject(this.springCloudReleaseProject.toURI());
|
||||
File project = new GitRepo(this.tmpFolder)
|
||||
.cloneProject(new URIish(this.springCloudReleaseProject.toURI().toURL()));
|
||||
createNewFile(project);
|
||||
|
||||
new GitRepo(project).commit("some message");
|
||||
@@ -127,7 +135,8 @@ public class GitRepoTests {
|
||||
|
||||
@Test
|
||||
public void should_not_commit_empty_changes() throws Exception {
|
||||
File project = new GitRepo(this.tmpFolder).cloneProject(this.springCloudReleaseProject.toURI());
|
||||
File project = new GitRepo(this.tmpFolder)
|
||||
.cloneProject(new URIish(this.springCloudReleaseProject.toURI().toURL()));
|
||||
createNewFile(project);
|
||||
new GitRepo(project).commit("some message");
|
||||
|
||||
@@ -141,7 +150,8 @@ public class GitRepoTests {
|
||||
|
||||
@Test
|
||||
public void should_create_a_tag() throws Exception {
|
||||
File project = new GitRepo(this.tmpFolder).cloneProject(this.springCloudReleaseProject.toURI());
|
||||
File project = new GitRepo(this.tmpFolder)
|
||||
.cloneProject(new URIish(this.springCloudReleaseProject.toURI().toURL()));
|
||||
createNewFile(project);
|
||||
new GitRepo(project).commit("some message");
|
||||
|
||||
@@ -161,7 +171,8 @@ public class GitRepoTests {
|
||||
@Test
|
||||
public void should_push_changes_to_master_branch() throws Exception {
|
||||
File origin = clonedProject(this.tmp.newFolder(), this.springCloudReleaseProject);
|
||||
File project = new GitRepo(this.tmpFolder).cloneProject(this.springCloudReleaseProject.toURI());
|
||||
File project = new GitRepo(this.tmpFolder)
|
||||
.cloneProject(new URIish(this.springCloudReleaseProject.toURI().toURL()));
|
||||
setOriginOnProjectToTmp(origin, project);
|
||||
createNewFile(project);
|
||||
new GitRepo(project).commit("some message");
|
||||
@@ -177,7 +188,8 @@ public class GitRepoTests {
|
||||
@Test
|
||||
public void should_push_changes_to_current_branch() throws Exception {
|
||||
File origin = clonedProject(this.tmp.newFolder(), this.springCloudReleaseProject);
|
||||
File project = new GitRepo(this.tmpFolder).cloneProject(this.springCloudReleaseProject.toURI());
|
||||
File project = new GitRepo(this.tmpFolder)
|
||||
.cloneProject(new URIish(this.springCloudReleaseProject.toURI().toURL()));
|
||||
setOriginOnProjectToTmp(origin, project);
|
||||
createNewFile(project);
|
||||
new GitRepo(project).commit("some message");
|
||||
@@ -193,7 +205,8 @@ public class GitRepoTests {
|
||||
@Test
|
||||
public void should_return_the_branch_name() throws Exception {
|
||||
File origin = clonedProject(this.tmp.newFolder(), this.springCloudReleaseProject);
|
||||
File project = new GitRepo(this.tmpFolder).cloneProject(this.springCloudReleaseProject.toURI());
|
||||
File project = new GitRepo(this.tmpFolder)
|
||||
.cloneProject(new URIish(this.springCloudReleaseProject.toURI().toURL()));
|
||||
setOriginOnProjectToTmp(origin, project);
|
||||
createNewFile(project);
|
||||
|
||||
@@ -205,7 +218,8 @@ public class GitRepoTests {
|
||||
@Test
|
||||
public void should_push_a_tag_to_new_branch_in_origin() throws Exception {
|
||||
File origin = clonedProject(this.tmp.newFolder(), this.springCloudReleaseProject);
|
||||
File project = new GitRepo(this.tmpFolder).cloneProject(this.springCloudReleaseProject.toURI());
|
||||
File project = new GitRepo(this.tmpFolder)
|
||||
.cloneProject(new URIish(this.springCloudReleaseProject.toURI().toURL()));
|
||||
setOriginOnProjectToTmp(origin, project);
|
||||
createNewFile(project);
|
||||
new GitRepo(project).commit("some message");
|
||||
@@ -239,7 +253,8 @@ public class GitRepoTests {
|
||||
|
||||
@Test
|
||||
public void should_revert_changes() throws Exception {
|
||||
File project = new GitRepo(this.tmpFolder).cloneProject(this.springCloudReleaseProject.toURI());
|
||||
File project = new GitRepo(this.tmpFolder)
|
||||
.cloneProject(new URIish(this.springCloudReleaseProject.toURI().toURL()));
|
||||
File foo = new File(project, "foo");
|
||||
foo.createNewFile();
|
||||
new GitRepo(project).commit("Update SNAPSHOT to 1.0.0.RC1");
|
||||
@@ -254,7 +269,8 @@ public class GitRepoTests {
|
||||
|
||||
@Test
|
||||
public void should_not_revert_changes_when_commit_message_is_not_related_to_updating_snapshots() throws Exception {
|
||||
File project = new GitRepo(tmpFolder).cloneProject(this.springCloudReleaseProject.toURI());
|
||||
File project = new GitRepo(tmpFolder)
|
||||
.cloneProject(new URIish(this.springCloudReleaseProject.toURI().toURL()));
|
||||
|
||||
BDDAssertions.thenThrownBy(
|
||||
() -> new GitRepo(project).revert("some message"))
|
||||
|
||||
@@ -35,7 +35,7 @@ public class GitTestUtils {
|
||||
|
||||
public static File clonedProject(File baseDir, File projectToClone) throws IOException {
|
||||
GitRepo projectRepo = new GitRepo(baseDir);
|
||||
projectRepo.cloneProject(projectToClone.toURI());
|
||||
projectRepo.cloneProject(new URIish(projectToClone.toURI().toURL()));
|
||||
return baseDir;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class GitTestUtils {
|
||||
|
||||
public static File clonedProject(File baseDir, File projectToClone) throws IOException {
|
||||
GitRepo projectRepo = new GitRepo(baseDir);
|
||||
projectRepo.cloneProject(projectToClone.toURI());
|
||||
projectRepo.cloneProject(new URIish(projectToClone.toURI().toURL()));
|
||||
return baseDir;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -576,8 +576,8 @@ public class AcceptanceTests {
|
||||
|
||||
private ReleaserProperties releaserProperties(File project, String branch) throws URISyntaxException {
|
||||
ReleaserProperties releaserProperties = new ReleaserProperties();
|
||||
releaserProperties.getGit().setSpringCloudReleaseGitUrl(file("/projects/spring-cloud-release/").toURI().getPath());
|
||||
releaserProperties.getGit().setDocumentationUrl(file("/projects/spring-cloud-static-angel/").toURI().getPath());
|
||||
releaserProperties.getGit().setSpringCloudReleaseGitUrl(file("/projects/spring-cloud-release/").toURI().toString());
|
||||
releaserProperties.getGit().setDocumentationUrl(file("/projects/spring-cloud-static-angel/").toURI().toString());
|
||||
releaserProperties.getMaven().setBuildCommand("echo build");
|
||||
releaserProperties.getMaven().setDeployCommand("echo deploy");
|
||||
releaserProperties.getMaven().setPublishDocsCommands(new String[] { "echo docs"} );
|
||||
@@ -589,7 +589,7 @@ public class AcceptanceTests {
|
||||
|
||||
private ReleaserProperties metaReleaserProperties(Map<String, String> versions) throws URISyntaxException {
|
||||
ReleaserProperties releaserProperties = new ReleaserProperties();
|
||||
releaserProperties.getGit().setDocumentationUrl(file("/projects/spring-cloud-static-angel/").toURI().getPath());
|
||||
releaserProperties.getGit().setDocumentationUrl(file("/projects/spring-cloud-static-angel/").toURI().toString());
|
||||
releaserProperties.getMaven().setBuildCommand("echo executed_build");
|
||||
releaserProperties.getMaven().setDeployCommand("echo executed_deploy");
|
||||
releaserProperties.getMaven().setPublishDocsCommands(new String[] { "echo executed_docs"} );
|
||||
@@ -602,8 +602,8 @@ public class AcceptanceTests {
|
||||
|
||||
private ReleaserProperties snapshotScReleaseReleaserProperties(File project, String branch) throws URISyntaxException {
|
||||
ReleaserProperties releaserProperties = releaserProperties(project, branch);
|
||||
releaserProperties.getGit().setSpringCloudReleaseGitUrl(file("/projects/spring-cloud-release-with-snapshot/").toURI().getPath());
|
||||
releaserProperties.getGit().setDocumentationUrl(file("/projects/spring-cloud-static/").toURI().getPath());
|
||||
releaserProperties.getGit().setSpringCloudReleaseGitUrl(file("/projects/spring-cloud-release-with-snapshot/").toURI().toString());
|
||||
releaserProperties.getGit().setDocumentationUrl(file("/projects/spring-cloud-static/").toURI().toString());
|
||||
this.releaserProperties = releaserProperties;
|
||||
return releaserProperties;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user