Analyser le journal des validations de Subversion en Python

Cet article décrit comment utiliser python-svn en Python pour analyser les journaux de validation Subversion.

Ceci est fait dans 2.7, mais les bibliothèques Python 3.3, 3.2 et 2.7 sont fournies.

http://pysvn.tigris.org/

Installation

Installez le binaire en utilisant l'une des méthodes suivantes

__ Série Unix __

sudo apt-get install python-svn

Windows、MACOS Télécharger ci-dessous http://pysvn.tigris.org/project_downloads.html

Échantillon et description de l'acquisition de journaux

L'exemple suivant affiche l'historique du référentiel Subversion spécifié.

svnlog.py


import pysvn
import time
import sys
from collections import defaultdict


class SvnRepController:
  def __init__(self,url_or_path,user,passwd):
    self.client = pysvn.Client()
    self.url_or_path = url_or_path
    self.user = user
    self.passwd = passwd
    self.client.callback_get_login = self.get_login

  def get_login(self, realm, username, may_save):
    return True, self.user,self.passwd, False

  def log(self):
    return self.client.log(self.url_or_path, discover_changed_paths=True)

if __name__ == '__main__':
  argvs = sys.argv
  argc = len(argvs)
  if(argc != 4):
    sys.stderr.write( 'Usage:\n python %s url_or_path user pass' % argvs[0] )
    quit()
  url_or_path = argvs[1]
  user = argvs[2]
  passwd = argvs[3]
  client = SvnRepController(url_or_path,user,passwd)

  logs = client.log()
  for log in logs:
    print ("RevNo:%d" % (log.revision.number))
    print ("Author:%s date:%s" % (log.author, time.ctime(log.date)))
    print (log.message)
    for p in log.changed_paths:
      print ("  %s" % dict(p))

Il peut être exécuté comme suit.

python svnlog.py http://svn.sourceforge.jp/svnroot/simyukkuri/ "Nom d'utilisateur" "mot de passe"

La procédure sera expliquée.

(1) Générez pysvn.Client ().

(2) Spécifiez la fonction d'authentification dans client.callback_get_login. Cette fonction est rappelée lorsque l'authentification est requise. Les informations d'identification doivent être spécifiées dans la valeur de retour.

(3) Vous pouvez obtenir la séquence de PySvnLog en exécutant client.log ().

(4) PySvnLog est PysvnDictBase est PysvnDictBase est PysvnDictBase Il hérite de "PysvnDictBase"). PysvnDictBase peut être utilisé comme Directory. En d'autres termes, vous pouvez obtenir les propriétés nécessaires en procédant comme suit.

  logs = client.log()
  for log in logs:
    dict(log)

L'explication des principaux éléments obtenus ici est présentée ci-dessous.

Contenu __PySvnLog: __

Nom La description
revision.number Numéro de révision
author auteur
date Temps de validation.Il est exprimé numériquement.
message Message de validation
changed_paths Liste des PysvnLogChangedPath

Contenu de __PysvnLogChangedPath: __

Nom La description
action Représente le type d'opération
http://svnbook.red-bean.com/en/1.7/svn.ref.svn.c.update.html
path Le chemin de l'opération
copyfrom_path Copier le chemin source
copyfrom_revision Copier la révision source

(5) Après cela, effectuez l'agrégation nécessaire.

application

Un exemple d'application est présenté ci-dessous.

Il est également possible d'analyser les modèles de fichiers qui sont fréquemment mis à jour en même temps à partir de l'historique de mise à jour des fichiers. Dans l'exemple suivant, le degré d'impact qui se produit lorsqu'un fichier avec une fréquence d'apparence simple est modifié est analysé.

import pysvn
import time
import sys
from collections import defaultdict

class FilePair:
  def __init__(self,path1,path2):
    self.path1 = path1
    self.path2 = path2
    self.count = 0
    self.reliability1 =0
    self.reliability2 =0


class SvnRepController:
  def __init__(self,url_or_path,user,passwd):
    self.client = pysvn.Client()
    self.url_or_path = url_or_path
    self.user = user
    self.passwd = passwd
    self.client.callback_get_login = self.get_login

  def get_login(self, realm, username, may_save):
    return True, self.user,self.passwd, False

  def log(self):
    return self.client.log(self.url_or_path, discover_changed_paths=True)
  
  def getSimpleLogicalCoupling(self):
    files = defaultdict(int)
    ret = defaultdict(FilePair)
    logs = self.log()
    for log in logs:
      for i in range(0,len(log.changed_paths)-1):
        path1 = log.changed_paths[i]
        if path1.action != "M":
          #Ignorer sauf pour les modifications
          continue

        files[path1.path] += 1

        for j in range(i+1,len(log.changed_paths)-1):
          path2 = log.changed_paths[j]
          if path2.action != "M":
            #Ignorer sauf pour les modifications
            continue
          if path1.path == path2.path:
            continue

          key = "%s %s" % (path1.path , path2.path)
          if( ret.has_key(key) == False ):
            key = "%s %s" % (path2.path , path1.path)
            if( ret.has_key(key) == False ):
              ret[key] = FilePair(path1.path,path2.path)
          ret[key].count += 1

    for k,v in ret.items():
      v.reliability1 = float(v.count) / files[v.path1]
      v.reliability2 = float(v.count) / files[v.path2]
      
    return ret



if __name__ == '__main__':
  argvs = sys.argv
  argc = len(argvs)
  if(argc != 6):
    sys.stderr.write( 'Usage:\n python %s url_or_path user pass min_count min_reliability' % argvs[0] )
    quit()
  url_or_path = argvs[1]
  user = argvs[2]
  passwd = argvs[3]
  min_count = argvs[4]
  min_reliablility = float(argvs[5])
  client = SvnRepController(url_or_path,user,passwd)
  list = client.getSimpleLogicalCoupling()
  print '"Path A","Path B","Count","Count/count of A","Count/count of B","reliability"'
  for k,v in sorted(list.items(), key=lambda x:x[1].count, reverse=True):
    if (v.reliability1 > float(min_reliablility) or v.reliability2 > float(min_reliablility)) and v.count > int(min_count):
      print '"%s","%s","%d","%f","%f","%f"' % (v.path1,v.path2,v.count,v.reliability1,v.reliability2,v.reliability1 if v.reliability1>v.reliability2 else v.reliability2)

Connectez-vous au référentiel SampleProject avec User: admin et password admin, et si la fréquence d'occurrence est de 5 ou plus et que vous modifiez le fichier correspondant, au moins 80% du temps, vous obtiendrez la combinaison des fichiers mis à jour. Peut être fait comme suit.

python svnSimpleLogicalCoupling.py http://127.0.0.1/svn/SampleProject admin admin 5 0.8 > out.csv

De plus, il semble que les choses suivantes peuvent être faites. -Analyser le journal de validation pour voir quelles corrections sont apportées. -Extraire l'historique des modifications associé aux numéros de ticket Redmine et Trac, et trouver le taux d'occurrence de bogue pour chaque fichier. ・ Fréquence des commits pour chaque personne

Comme mentionné ci-dessus, on peut s'attendre à ce que diverses informations puissent être obtenues en analysant l'historique des modifications.

Recommended Posts

Analyser le journal des validations de Subversion en Python
Analyser le journal de validation Git en Python
Analyse CSS avec cssutils en Python
Quadtree en Python --2
Python en optimisation
CURL en Python
Géocodage en python
SendKeys en Python
Méta-analyse en Python
Unittest en Python
Époque en Python
Discord en Python
Allemand en Python
DCI en Python
tri rapide en python
nCr en python
N-Gram en Python
Programmation avec Python
Plink en Python
Constante en Python
FizzBuzz en Python
Sqlite en Python
Étape AIC en Python
LINE-Bot [0] en Python
CSV en Python
Assemblage inversé avec Python
Réflexion en Python
Constante en Python
nCr en Python.
format en python
Scons en Python 3
Puyopuyo en python
python dans virtualenv
PPAP en Python
Quad-tree en Python
Réflexion en Python
Chimie avec Python
Hashable en Python
DirectLiNGAM en Python
LiNGAM en Python
Aplatir en Python
Aplatir en python
Analysons le journal de validation git en Python!
Liste triée en Python
AtCoder # 36 quotidien avec Python
Texte de cluster en Python
AtCoder # 2 tous les jours avec Python
Daily AtCoder # 32 en Python
Daily AtCoder # 6 en Python
Daily AtCoder # 18 en Python
Modifier les polices en Python
Motif singleton en Python
Lire DXF avec python
Daily AtCoder # 53 en Python
Utilisez config.ini avec Python
Daily AtCoder # 33 en Python
Résoudre ABC168D en Python
Distribution logistique en Python
AtCoder # 7 tous les jours avec Python