Skip to content

Commit

Permalink
🚂 v2.2.1
Browse files Browse the repository at this point in the history
  • Loading branch information
yodamad authored Jun 5, 2021
2 parents 1275e71 + 474e8f2 commit 66fadf1
Show file tree
Hide file tree
Showing 12 changed files with 90 additions and 24 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<groupId>fr.yodamad.svn2git</groupId>
<artifactId>svn-2-git</artifactId>
<version>2.2.0</version>
<version>2.2.1</version>
<packaging>jar</packaging>
<name>Svn 2 GitLab</name>

Expand Down
7 changes: 4 additions & 3 deletions src/main/kotlin/fr/yodamad/svn2git/io/Shell.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import fr.yodamad.svn2git.domain.Migration
import fr.yodamad.svn2git.service.util.CommandManager
import org.apache.commons.io.IOUtils
import org.slf4j.LoggerFactory
import org.springframework.util.StringUtils.isEmpty
import java.io.*
import java.nio.charset.Charset
import java.time.LocalDateTime
Expand Down Expand Up @@ -65,7 +66,7 @@ object Shell {
*/
@JvmOverloads
@Throws(InterruptedException::class, IOException::class)
fun execCommand(commandManager: CommandManager, directory: String, command: String?, securedCommandToPrint: String? = command, usePowershell: Boolean = false): Int {
fun execCommand(commandManager: CommandManager, directory: String, command: String?, securedCommandToPrint: String? = command, usePowershell: Boolean = false, alwaysPrintOutput: Boolean = false): Int {
val builder = ProcessBuilder()
val execDir = formatDirectory(directory)
if (isWindows) {
Expand All @@ -78,9 +79,9 @@ object Shell {
LOG.debug(String.format("Exec command : %s", securedCommandToPrint))
LOG.debug(String.format("in %s", execDir))
val process = builder.start()
val streamGobbler = StreamGobbler(process.inputStream) { s: String? -> LOG.debug(s) }
val streamGobbler = StreamGobbler(process.inputStream) { s: String? -> if (alwaysPrintOutput && !isEmpty(s) && !s!!.contains("password", true)) LOG.info(s) else LOG.debug(s) }
Executors.newSingleThreadExecutor().submit(streamGobbler)
val errorStreamGobbler = StreamGobbler(process.errorStream) { s: String? -> LOG.debug(s) }
val errorStreamGobbler = StreamGobbler(process.errorStream) { s: String? -> LOG.error(s) }
Executors.newSingleThreadExecutor().submit(errorStreamGobbler)
val stderr = IOUtils.toString(process.errorStream, Charset.defaultCharset())
val exitCode = process.waitFor()
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/fr/yodamad/svn2git/service/GitManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ open class GitManager(val historyMgr: HistoryManager,
var cloneOK = true
if (workUnit.commandManager.isFirstAttemptMigration) {
try {
execCommand(workUnit.commandManager, workUnit.root, cloneCommand, safeCommand, true)
execCommand(workUnit.commandManager, workUnit.root, cloneCommand, safeCommand, true, true)
} catch (thr: Throwable) {
cloneOK = false
LOG.warn("Cannot git svn clone", thr.message)
Expand Down
15 changes: 15 additions & 0 deletions src/main/kotlin/fr/yodamad/svn2git/web/rest/GitlabResource.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,21 @@ open class GitlabResource(val gitlabAdmin: GitlabAdmin,

val logger: Logger = LoggerFactory.getLogger(GitlabResource::class.java)

/**
* @return current user for token
*/
@Timed
@PostMapping("/user")
open fun getUserFromToken(@RequestBody gitlabInfo: GitlabInfo) : ResponseEntity<String> {
val api: UserApi = overrideGitlab(gitlabInfo).userApi
val user = api.getCurrentUser()
return if (user != null) {
ResponseEntity.ok().body(user.username)
} else {
ResponseEntity.notFound().build()
}
}

/**
* Check if a user exists on Gitlab
*
Expand Down
1 change: 1 addition & 0 deletions src/main/kotlin/fr/yodamad/svn2git/web/rest/SvnResource.kt
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ open class SvnResource(val applicationProperties: ApplicationProperties) {
} catch (ex: SVNException) {
if (ex is SVNAuthenticationException) {
log.error("Cannot access SVN", ex)
throw ex
} else {
log.warn("Flat repo", ex)
}
Expand Down
20 changes: 16 additions & 4 deletions src/main/webapp/app/migration/migration-process.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import { Injectable } from '@angular/core';
import { SERVER_API_URL } from 'app/app.constants';
import { HttpClient, HttpParams, HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { catchError, map } from 'rxjs/operators';
import { IMigration } from 'app/shared/model/migration.model';
import { MigrationFilter } from 'app/shared/model/migration-filter.model';

type EntityResponseType = HttpResponse<boolean>;
type StringResponseType = HttpResponse<string>;
type EntityStructureResponseType = HttpResponse<SvnStructure>;
type MigrationArrayResponseType = HttpResponse<IMigration[]>;

Expand All @@ -27,6 +28,13 @@ export class MigrationProcessService {

constructor(private http: HttpClient) {}

currentUserFromToken(url: string, token?: string): Observable<StringResponseType> {
const gitlabInfo = new GitlabInfo(url, token);
return this.http
.post<string>(`${this.userUrl}`, gitlabInfo, { observe: 'response', responseType: 'text' as 'json' })
.pipe(map((res: StringResponseType) => res));
}

checkUser(name: string, url: string, token?: string): Observable<EntityResponseType> {
const gitlabInfo = new GitlabInfo(url, token);
return this.http
Expand Down Expand Up @@ -56,9 +64,13 @@ export class MigrationProcessService {

checkSvn(name: string, url: string, user: string, password: string, depth: number): Observable<EntityStructureResponseType> {
const svnInfo = new SvnInfo(url, user, password);
return this.http
.post<SvnStructure>(`${this.repositoryUrl}/${name}?depth=${depth}`, svnInfo, { observe: 'response' })
.pipe(map((res: EntityStructureResponseType) => res));
return this.http.post<SvnStructure>(`${this.repositoryUrl}/${name}?depth=${depth}`, svnInfo, { observe: 'response' }).pipe(
map((res: EntityStructureResponseType) => res),
catchError(err => {
console.log(err);
throw err;
})
);
}

findActiveMigrations(): Observable<MigrationArrayResponseType> {
Expand Down
10 changes: 4 additions & 6 deletions src/main/webapp/app/migration/migration-stepper.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,18 @@
<div class="col-md-12 col-xs-12 p-4">
<div class="row">
<div class="col-md-2 pl-4 pt-3 pr-2 text-center">
<span jhiTranslate="migration-process.gitlab.credentials">
<span jhiTranslate="migration-process.gitlab.username">
Credentials
</span>
</div>
<div class="col-md-10">
<mat-form-field *ngIf="svnCredsOption === 'required'" style="width:350px">
<input matInput placeholder="{{'migration-process.gitlab.user' | translate}}" formControlName="gitlabUser" required>
</mat-form-field>
<button type="button" mat-raised-button (click)="checkGitlabUser()" class="btn btn-primary"
<button type="button" mat-raised-button (click)="getGitlabUser()" class="btn btn-primary"
[ngClass]="{'btn-danger': gitlabUserKO, 'btn-success': !gitlabUserKO && gitlabUserKO !== null}"
[disabled]="checkingGitlabUser">
<span jhiTranslate="migration-process.check" *ngIf="!checkingGitlabUser">Check</span>
<span jhiTranslate="migration-process.check-token" *ngIf="!checkingGitlabUser">Check</span>
<span jhiTranslate="migration-process.checking" *ngIf="checkingGitlabUser">Checking</span>
</button>
<span *ngIf="gitlabUser !== ''" jhiTranslate="migration-process.gitlab.account-info" [translateValues]="{username: gitlabUser}" style="margin-left: 20px"></span>
<mat-error *ngIf="!gitlabUserKO && gitlabUserKO !== null">
<fa-icon icon="check"></fa-icon>
<span class="pl-2" jhiTranslate="migration-process.gitlab.account-found">Account found in Gitlab</span>
Expand Down
33 changes: 29 additions & 4 deletions src/main/webapp/app/migration/migration-stepper.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export class MigrationStepperComponent implements OnInit {
svnCredsOption: string;
svnDepth: number;
gitlabUrl: string;
gitlabUser = '';
gitlabCredsOption: string;
renamings: MigrationRenaming[] = [];
artifactoryUrl: string;
Expand Down Expand Up @@ -169,7 +170,6 @@ export class MigrationStepperComponent implements OnInit {
this.nexusUrl = localStorage.getItem(NEXUS_URL);

this.gitlabFormGroup = this._formBuilder.group({
gitlabUser: ['', Validators.required],
gitlabGroup: ['', Validators.required],
gitlabURL: [{ value: this.gitlabUrl, disabled: true }, Validators.required],
gitlabToken: ['']
Expand Down Expand Up @@ -223,6 +223,31 @@ export class MigrationStepperComponent implements OnInit {
.subscribe(res => (this.isGitlabGroupCreation = res), () => (this.isGitlabGroupCreation = false));
}

/**
* Get Gitlab user
*/
getGitlabUser() {
// initialise to true for each check
this.gitlabUserKO = null;
this.checkingGitlabUser = true;

this._migrationProcessService
.currentUserFromToken(this.gitlabFormGroup.controls['gitlabURL'].value, this.gitlabFormGroup.controls['gitlabToken'].value)
.subscribe(
res => {
console.log(res);
this.gitlabUser = res.body;
this.gitlabUserKO = false;
this.checkingGitlabUser = false;
},
err => {
console.log(err);
this.gitlabUserKO = true;
this.checkingGitlabUser = false;
}
);
}

/**
* Check if user exists
*/
Expand Down Expand Up @@ -260,7 +285,7 @@ export class MigrationStepperComponent implements OnInit {
this._migrationProcessService
.checkGroup(
this.gitlabFormGroup.controls['gitlabGroup'].value,
this.gitlabFormGroup.controls['gitlabUser'].value,
this.gitlabUser,
this.gitlabFormGroup.controls['gitlabURL'].value,
this.gitlabFormGroup.controls['gitlabToken'].value
)
Expand Down Expand Up @@ -451,7 +476,7 @@ export class MigrationStepperComponent implements OnInit {
if (this.gitlabFormGroup.controls['gitlabToken'] !== undefined && this.gitlabFormGroup.controls['gitlabToken'].value !== '') {
this.mig.gitlabToken = this.gitlabFormGroup.controls['gitlabToken'].value;
}
this.mig.user = this.gitlabFormGroup.controls['gitlabUser'].value;
this.mig.user = this.gitlabUser;
this.mig.gitlabGroup = this.gitlabFormGroup.controls['gitlabGroup'].value;
const renaming = this.renamings.find(
r =>
Expand Down Expand Up @@ -930,6 +955,6 @@ export class MigrationStepperComponent implements OnInit {
}

warningUploadExtension() {
return this.staticExtensions.length == 0;
return this.staticExtensions.length === 0;
}
}
4 changes: 3 additions & 1 deletion src/main/webapp/i18n/en/migrationProcess.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"back" : " Back",
"blocked": "Some namespaces aren't available. Fix before starting migration",
"check" : "Check",
"check-token" : "Check Token",
"checking" : "Checking",
"cleaning" : {
"options" : "🧹 Cleaning options",
Expand Down Expand Up @@ -54,14 +55,15 @@
"url-help": "The base URL, e.g. https://gitlab.com/",
"url-default": "Default",
"url-custom": "Custom",
"credentials": "Credentials",
"username": "Username",
"rename": "New name for project in Gitlab",
"upload": "🦊 Upload artefacts",
"use" : {
"default" : "Use default URL and user"
},
"user" : "User",
"account-found": "Account found in Gitlab",
"account-info": "<b>{{ username }}</b> will be use for Gitlab connection",
"account-unknown": "Account not found in Gitlab you need to log in first"
},
"history" : {
Expand Down
4 changes: 3 additions & 1 deletion src/main/webapp/i18n/fr/migrationProcess.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"back" : " Retour",
"blocked": "Certains namespaces ne sont pas disponibles. Corriger pour continuer",
"check" : "Vérifier",
"check-token" : "Vérifier le token",
"checking" : "En cours",
"cleaning" : {
"options" : "🧹 Nettoyage",
Expand Down Expand Up @@ -54,14 +55,15 @@
"url-help": "L'url de base comme https://gitlab.com/",
"url-default": "Par défault",
"url-custom": "Personnalisé",
"credentials": "Identifiants",
"username": "Username",
"rename": "Nouveau nom du projet dans Gitlab",
"upload": "🦊 Upload fichiers",
"use" : {
"default" : "URL par défaut et utilisateur"
},
"user" : "Utilisateur",
"account-found": "Compte trouvé sur Gitlab",
"account-info": "<b>{{ username }}</b> sera utilisé pour la connexion à Gitlab",
"account-unknown": "Compte non trouvé sur Gitlab, vous devez vous connecter dessus au préalable"
},
"history" : {
Expand Down
10 changes: 10 additions & 0 deletions src/test/java/fr/yodamad/svn2git/e2e/FlatRepoTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.gitlab4j.api.GitLabApiException;
import org.gitlab4j.api.models.Branch;
import org.gitlab4j.api.models.Project;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
Expand Down Expand Up @@ -56,6 +57,15 @@ public void cleanGitlab() throws GitLabApiException {
if (project.isPresent()) api.getProjectApi().deleteProject(project.get().getId());
}

@After
public void forceCleanGitlab() throws GitLabApiException, InterruptedException {
Optional<Project> project = api.getProjectApi().getOptionalProject(flat().namespace, flat().name);
if (project.isPresent()) api.getProjectApi().deleteProject(project.get().getId());
while(api.getProjectApi().getOptionalProject(flat().namespace, flat().name).isPresent()) {
Thread.sleep(500);
}
}

@Test
public void test_migration_on_flat_repository() throws ExecutionException, InterruptedException, GitLabApiException {
Migration migration = initFlatMigration(applicationProperties);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.tmatesoft.svn.core.SVNAuthenticationException;

import java.util.List;

Expand Down Expand Up @@ -127,11 +128,10 @@ public void test_svn_listing_with_depth_1() {
});
}

@Test
@Test(expected = SVNAuthenticationException.class)
public void test_invalid_credentials() {
svnInfo.user = "hacker";
svnInfo.password = "hacker";
SvnStructure svnStructure = svnResource.listSVN(svnInfo, Repository.simple().name, DEPTH);
assertThat(svnStructure.modules).isEmpty();
svnResource.listSVN(svnInfo, Repository.simple().name, DEPTH);
}
}

0 comments on commit 66fadf1

Please sign in to comment.