Plugin SVN Sonar

De EjnTricks

Lors de l'analyse d'un projet avec SonarQube, l'application est capable d'identifier l'auteur des modifications et d'affecter automatiquement les tâches. Dans le cadre de cette installation, le gestionnaire de source est SVN. Il faut donc activer le plugin SVN, qui l'est automatiquement en théorie.

Cependant, lors de la mise en place des version 5.X en tant que service, le plugin n'a pas été activé. L'assignement automatique n'était alors pas fonctionnel.


Cet article présente l'installation du plugin ainsi que sa configuration afin d'avoir un affectation automatique fonctionnelle.

Hand-icon.png Votre avis

Nobody voted on this yet

 You need to enable JavaScript to vote


System-Install-icon.png Download-icon.png Téléchargement et installation

L'installation du plugin s'effectue depuis la console d'administration de SonarQube. Avec un compte administrateur, il faut cliquer sur le lien Update Center dans le menu System de la page Settings.


Il faut alors accéder au plugin SVN dans l'onglet Available Plugins et cliquer sur le lien afin de déployer la description.


Après avoir cliquer sur le bouton Install, un message de confirmation indique la mise à disposition de celui-ci après le prochain redémarrage. En effet, le plugin est uniquement téléchargé dans le répertoire temporaire downloads, emplacement /var/opt/sonarqube/5.1.2/extensions/downloads dans le cadre de cette installation, qui est scruté lors du démarrage.


L'application étant un service Linux, il suffit de le redémarrer.

#sudo service sonarqube restart


Icon-Configuration-Settings.png Paramétrages

Icon ACL.png Accès dépôt

Cependant, la simple activation du plugin ne va pas permettre d'affecter automatiquement les tâches. En effet, le plugin nécessite d'accéder aux dépôts SVN afin d'identifier les auteurs des modifications à l'aide de la commande blame, dans le cas où le dépôt nécessite une authentification.

Un message d'erreur similaire peut être, indiquant que l'action blame a échoué.

org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.codehaus.mojo:sonar-maven-plugin:2.6:sonar (default-cli) on project verification:
Error when executing blame for file src/main/java/net/jouvinio/tutorial/Dummy.java
	at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:216)
	at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
	at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
	at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
	at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
	at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
	at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
	at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:307)
	at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:193)
	at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:106)
	at org.apache.maven.cli.MavenCli.execute(MavenCli.java:862)
	at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:286)
	at org.apache.maven.cli.MavenCli.main(MavenCli.java:197)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
	at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
	at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
	at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
Caused by: org.apache.maven.plugin.MojoExecutionException: Error when executing blame for file src/main/java/net/jouvinio/tutorial/Dummy.java
	at org.codehaus.mojo.sonar.bootstrap.ExceptionHandling.handle(ExceptionHandling.java:41)
	at org.codehaus.mojo.sonar.bootstrap.RunnerBootstraper.execute(RunnerBootstraper.java:139)
	at org.codehaus.mojo.sonar.SonarMojo.execute(SonarMojo.java:132)
	at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
	at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
	... 20 more
Caused by: java.lang.IllegalStateException: Error when executing blame for file src/main/java/net/jouvinio/tutorial/Dummy.java
	at org.sonar.plugins.scm.svn.SvnBlameCommand.blame(SvnBlameCommand.java:100)
	at org.sonar.plugins.scm.svn.SvnBlameCommand.blame(SvnBlameCommand.java:59)
	at org.sonar.batch.scm.ScmSensor.execute(ScmSensor.java:84)
	at org.sonar.batch.scan.SensorWrapper.analyse(SensorWrapper.java:59)
	at org.sonar.batch.phases.SensorsExecutor.executeSensor(SensorsExecutor.java:59)
	at org.sonar.batch.phases.SensorsExecutor.execute(SensorsExecutor.java:51)
	at org.sonar.batch.phases.DatabaseModePhaseExecutor.execute(DatabaseModePhaseExecutor.java:120)
	at org.sonar.batch.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:264)
	at org.sonar.api.platform.ComponentContainer.startComponents(ComponentContainer.java:92)
	at org.sonar.api.platform.ComponentContainer.execute(ComponentContainer.java:77)
	at org.sonar.batch.scan.ProjectScanContainer.scan(ProjectScanContainer.java:235)
	at org.sonar.batch.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:230)
	at org.sonar.batch.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:220)
	at org.sonar.api.platform.ComponentContainer.startComponents(ComponentContainer.java:92)
	at org.sonar.api.platform.ComponentContainer.execute(ComponentContainer.java:77)
	at org.sonar.batch.scan.ScanTask.scan(ScanTask.java:57)
	at org.sonar.batch.scan.ScanTask.execute(ScanTask.java:45)
	at org.sonar.batch.bootstrap.TaskContainer.doAfterStart(TaskContainer.java:135)
	at org.sonar.api.platform.ComponentContainer.startComponents(ComponentContainer.java:92)
	at org.sonar.api.platform.ComponentContainer.execute(ComponentContainer.java:77)
	at org.sonar.batch.bootstrap.GlobalContainer.executeTask(GlobalContainer.java:158)
	at org.sonar.batch.bootstrapper.Batch.executeTask(Batch.java:95)
	at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:67)
	at org.sonar.runner.batch.IsolatedLauncher.execute(IsolatedLauncher.java:48)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at org.sonar.runner.impl.BatchLauncher$1.delegateExecution(BatchLauncher.java:87)
	at org.sonar.runner.impl.BatchLauncher$1.run(BatchLauncher.java:75)
	at java.security.AccessController.doPrivileged(Native Method)
	at org.sonar.runner.impl.BatchLauncher.doExecute(BatchLauncher.java:69)
	at org.sonar.runner.impl.BatchLauncher.execute(BatchLauncher.java:50)
	at org.sonar.runner.api.EmbeddedRunner.doExecute(EmbeddedRunner.java:102)
	at org.sonar.runner.api.Runner.execute(Runner.java:100)
	at org.codehaus.mojo.sonar.bootstrap.RunnerBootstraper.execute(RunnerBootstraper.java:135)
	... 23 more
Caused by: org.tmatesoft.svn.core.SVNAuthenticationException: svn: E170001: Authentication required for '<https://www.dev.jouvinio.net:443> TUTORIAL Repository'
	at org.tmatesoft.svn.core.internal.wc.SVNErrorManager.authenticationFailed(SVNErrorManager.java:47)
	at org.tmatesoft.svn.core.internal.wc.SVNErrorManager.authenticationFailed(SVNErrorManager.java:41)
	at org.tmatesoft.svn.core.internal.wc.DefaultSVNAuthenticationManager.getFirstAuthentication(DefaultSVNAuthenticationManager.java:203)
	at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.request(HTTPConnection.java:716)
	at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.request(HTTPConnection.java:398)
	at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.request(HTTPConnection.java:386)
	at org.tmatesoft.svn.core.internal.io.dav.DAVConnection.performHttpRequest(DAVConnection.java:720)
	at org.tmatesoft.svn.core.internal.io.dav.DAVConnection.exchangeCapabilities(DAVConnection.java:634)
	at org.tmatesoft.svn.core.internal.io.dav.DAVConnection.open(DAVConnection.java:109)
	at org.tmatesoft.svn.core.internal.io.dav.DAVRepository.openConnection(DAVRepository.java:1044)
	at org.tmatesoft.svn.core.internal.io.dav.DAVRepository.hasCapability(DAVRepository.java:872)
	at org.tmatesoft.svn.core.io.SVNRepository.assertServerIsMergeInfoCapable(SVNRepository.java:787)
	at org.tmatesoft.svn.core.io.SVNRepository.getFileRevisions(SVNRepository.java:756)
	at org.tmatesoft.svn.core.internal.wc2.remote.SvnRemoteAnnotate.run(SvnRemoteAnnotate.java:111)
	at org.tmatesoft.svn.core.internal.wc2.remote.SvnRemoteAnnotate.run(SvnRemoteAnnotate.java:35)
	at org.tmatesoft.svn.core.internal.wc2.SvnOperationRunner.run(SvnOperationRunner.java:21)
	at org.tmatesoft.svn.core.wc2.SvnOperationFactory.run(SvnOperationFactory.java:1235)
	at org.tmatesoft.svn.core.wc2.SvnOperation.run(SvnOperation.java:294)
	at org.tmatesoft.svn.core.wc.SVNLogClient.doAnnotate(SVNLogClient.java:295)
	at org.sonar.plugins.scm.svn.SvnBlameCommand.blame(SvnBlameCommand.java:98) 
   ... 58 more

Il faut indiquer au plugin un compte "utilisateur" qui accède au moins en lecture seule sur le dépôt. Ceci s'effectue dans la section SCM de la page Settings.


Attention, dans le cas où une synchronisation LDAP est mise en place, il faut s'assurer que ce compte sera bien pris en compte.

Puis, il faut accéder à l'onglet SVN qui présente que deux éléments de configuration.

  • Username, qui est l'identifiant utilisé pour se connecter à SVN;
  • Password, le mot de passe du compte.


Après avoir renseigner les deux champs, il faut cliquer sur le bouton Save SVN Settings. Le plugin sera alors capable d'accéder au dépôt et d'identifier les acteurs des modifications.

Icon Folder analyze.png Configuration par projet

Le paragraphe précédent présente une configuration sur l'ensemble de l'instance SonarQube. Cependant, un compte "générique" d'accès aux dépôts n'est pas toujours disponible. Heureusement, il est possible de configurer un compte pour chacun des projets, ce qui viendra surcharger la configuration globale. Le principe est exactement le même et est disponible depuis la section SCM dans la page General Settings du projet à configurer.


User-icon.png Configuration comptes utilisateur

Dans le cadre de cette installation, les comptes utilisateurs sous SonarQube sont synchronisés depuis un annuaire LDAP, comme pour l'accès à SVN. Ainsi le plugin est capable de résoudre l'auteur de la modification dans SVN avec les comptes déclarés.

Cependant, il se peut que cette résolution ne soit pas aussi simple et nécessite de paramétrer le mapping entre les comptes des deux applications. Pour cela, il faut accéder à la liste des utilisateurs depuis la console d'administration de SonarQube. Avec un compte administrateur, il faut cliquer sur le lien Users dans le menu Security de la page Settings.


La liste des utilisateurs est alors affichée.


Ensuite, il faut éditer chacun des comptes en cliquant sur le lien Edit. Une fenêtre d'édition s'affiche.


Il est alors possible de spécifier le compte dans le gestionnaire de source avec la section SCM accounts.


A noter qu'il est possible de configurer plusieurs valeurs pour un même et unique compte utilisateur. Pour cela, il faut cliquer sur le bouton Add SCM account, qui rajoute une ligne.


La fenêtre d'édition indique que l'identifiant et l'adresse mail sont utilisés par défaut. Toutefois, si la valeur spécifiée correspond à un de ces champs, un message d'erreur est affiché lors de la sauvegarde.