pysvnについて
- Subversionのpython用のAPIで、svnをインストールする必要はありません。
- svnをラップしているそうなので、機能は一緒だと思います。
- https://github.com/dsoprea/PySvn
- https://pysvn.sourceforge.io/Docs/pysvn_prog_ref.html
pysvnのインストールについて
Windows環境
- インストーラーでインストールできます
- https://pysvn.sourceforge.io/downloads.html
Mac環境
- インストーラーはありますが、py39-python_org-pysvn-svn1142-1.9.18-2091-x86_64.dmgをインストールしようとしたところエラーになりました。Pythonのパスが「/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages」で固定されており、pyenvを使っている筆者の環境ではインストールできませんでした。次章に記載のDockerでUbuntuを導入してインストールしました。
- https://pysvn.sourceforge.io/downloads.html
pipインストール
- pipインストールはできますがバージョンが古い(2022/11/25時点 pysvn 0.1.0)ので注意して下さい。(筆者はこの古いバージョンを使って謎のエラーに悩みました。)
- https://pypi.org/project/pysvn/
- リファレンスには1.6以降を使えと記載されてます。
- https://pysvn.sourceforge.io/Docs/pysvn_prog_ref.html
- ちなみにエラーはこんな感じです、とにかく1.6以降を使って下さい
python
$ python3 svnlog.py http://svn.sourceforge.jp/svnroot/simyukkuri/ "admin" "admin"
Traceback (most recent call last):
File "/Users/mba/Downloads/pysvn-main/svnlog.py", line 32, in <module>
logs = client.log()
File "/Users/mba/Downloads/pysvn-main/svnlog.py", line 19, in log
return self.client.log(self.url_or_path, discover_changed_paths=True)
TypeError: log() got an unexpected keyword argument 'discover_changed_paths'
discover_changed_pathsのパラメーターがない
discover_changed_pathsを消してみると
$ python3 svnlog.py http://svn.sourceforge.jp/svnroot/simyukkuri/ "admin" "admin"
Traceback (most recent call last):
File "/Users/mba/Downloads/pysvn-main/svnlog.py", line 33, in <module>
logs = client.log()
File "/Users/mba/Downloads/pysvn-main/svnlog.py", line 20, in log
return self.client.log(self.url_or_path)
File "/Users/mba/.pyenv/versions/3.9.1/lib/python3.9/site-packages/pysvn/client.py", line 21, in log
root = xml.etree.ElementTree.fromstring(data)
File "/Users/mba/.pyenv/versions/3.9.1/lib/python3.9/xml/etree/ElementTree.py", line 1348, in XML
return parser.close()
xml.etree.ElementTree.ParseError: no element found: line 3, column 0
pysvn.Client.logができない、詰んだ…
Dockerのubutuにpysvnをインストールする
Ubuntuのイメージを起動する
- 20.04以降のUbutuを導入する(Python2系と3系が混在すると紛らわしいためです)
- 20.04 LTSで完全にPython2を含まないシステムになりました。
- https://forums.ubuntulinux.jp/viewtopic.php?id=21046
- https://qiita.com/yasuoka_dev/items/073f7e8c7dba75993323
bash
$ docker pull ubuntu:20.04
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 20.04 680e5dfb52c7 3 weeks ago 72.8MB
$ docker run -it -d --name ubuntu ubuntu:20.04
$ docker exec -it ubuntu /bin/bash
Ubuntu環境の構築
bash
$ apt update
$ apt upgrade
$ apt install build-essential libbz2-dev libdb-dev \
libreadline-dev libffi-dev libgdbm-dev liblzma-dev \
libncursesw5-dev libsqlite3-dev libssl-dev \
zlib1g-dev uuid-dev tk-dev
$ apt-get install vim
$ dpkg -l vim
$ apt install python3
$ python3 -V
Python 3.8.10
$ which python3
/usr/local/bin/python3
$ pip3 install pandas
Ubuntuにpysvnをインストール
- python-svnはpython2系に対応していることに気をつけて下さい
bash
$ apt-get install python3-svn
pysvnでファイル情報を取得する
構築した環境をテストする
- こちらの記事「PythonでSubversionのコミットログを解析する」のコードをコピペして、構築した環境のテストと公開されているサンプルのSubversionでログインなどをテストしてみて下さい。
- 筆者のgithubにもバックアップがあります、cloneして下記のコマンドを実行して下さい。svnlog.txtの内容がコンソールに出力されたらOKです。
bash
$ python3 svnlog.py http://svn.sourceforge.jp/svnroot/simyukkuri/ "admin" "admin"
ファイル情報を取得する
-
pysvn - Programmer's referenceによるとpysvn.Client.lsでリポジトリのファイルやフォルダ情報が取得できます。パラメータは下記です。
- created_rev - pysvn.Revision - the revision of the last change
- has_props - bool - True if the node has properties
- kind - node_kind - one of the pysvn.node_kind values←ファイルまたはフォルダ
- last_author - the author of the last change
- name - string - name of the file←URL
- size - long - size of file←バイト
- time - float - the time of the last change←タイムスタンプ
- file_list.pyを実行するとSubversionリポジトリのファイル一覧をfile_list.csvへ出力します。
- kindでファイルのみに絞っています、フォルダを取得したい場合にはここを変更して下さい。
python
import os,sys
import csv
import pandas as pd
from collections import defaultdict
from datetime import datetime
import pysvn
###env
RESULT_FILE='file_list.csv'
class SvnClient:
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 ls(self):
return self.client.ls(self.url_or_path, recurse=True)
if __name__ == '__main__':
## command sample
## python3 svnlog.py http://svn.sourceforge.jp/svnroot/simyukkuri/ "admin" "admin"
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 = SvnClient(url_or_path,user,passwd)
## pysvn.Client.ls
## https://pysvn.sourceforge.io/Docs/pysvn_prog_ref.html#pysvn_client_ls
## created_rev - pysvn.Revision - the revision of the last change
## has_props - bool - True if the node has properties
## kind - node_kind - one of the pysvn.node_kind values
## last_author - the author of the last change
## name - string - name of the file
## size - long - size of file
## time - float - the time of the last change
df = pd.DataFrame(columns = ['dir_path','file_name','file_ext','size','created_rev','has_props','kind','last_author','time'])
repo_infos = client.ls()
for info in repo_infos:
if str(info.kind) == "file":
time = datetime.fromtimestamp(info.time).strftime('%Y-%m-%d %H:%M:%S')
info_array = info.name.split('/')
file_name = info_array[-1]
path, file_ext = os.path.splitext(file_name)
row = pd.DataFrame([[info.name, file_name, file_ext, info.size, info.created_rev, info.has_props, info.kind, info.last_author, time]], columns=df.columns)
df = pd.concat([df,row],ignore_index=True)
df.to_csv(RESULT_FILE, encoding='utf-8', index=True)
- 筆者のgithub、cloneして下記のコマンドを実行して下さい。
bash
$ python3 file_list.py http://svn.sourceforge.jp/svnroot/simyukkuri/ "admin" "admin"