استخراج داده های مخزن git با PyDriller

در اوایل سال 2022، من یک سخنرانی به نام «تجسم کد» را آغاز کردم که از تجسم داده ها برای کشف الگوها در پروژه های منبع باز استفاده می کرد. این مقاله اولین مقاله از یک سری جدید است که شما را در مورد چگونگی کشف و تجزیه و تحلیل الگوهای موجود در مخازن خود راهنمایی می کند.
به طور خاص، این مقاله نحوه برداشتن هر مخزن عمومی در GitHub و استخراج یک فایل CSV پر از اطلاعات تاریخچه commit را پوشش می دهد. هنگامی که یک فایل داده در دسترس دارید، فرآیند تجزیه و تحلیل این مجموعه داده نسبتاً انعطاف پذیر است و می تواند به روش های مختلفی از جمله کد پایتون، تابلو، Power BI یا حتی اکسل انجام شود.
کد ارائه شده در این مقاله فرض می کند که شما دارید pydriller
و pandas
نصب شده است. PyDriller برای محتوای این مقاله مورد نیاز است در حالی که Pandas به سادگی به تجسم داده های بارگذاری شده و صادرات آن به یک فایل CSV کمک می کند. برای اطلاعات بیشتر در مورد شروع کار، اما معمولاً به نصب PyDriller مراجعه کنید pip install pydriller
این همه چیزی است که تو نیاز داری.
PyDriller چیست؟
PyDriller یک کتابخانه Python منبع باز است که به شما امکان می دهد تا در مخازن git “دریل” کنید.
با توجه به مخزن GitHub آن، PyDriller یک چارچوب پایتون است که به توسعه دهندگان در تجزیه و تحلیل مخازن Git کمک می کند. با PyDriller می توانید به راحتی اطلاعات مربوط به commit ها، توسعه دهندگان، فایل های اصلاح شده، تفاوت ها و کد منبع را استخراج کنید..
با استفاده از PyDriller میتوانیم اطلاعات را از هر مخزن عمومی GitHub استخراج کنیم، از جمله:
- انفرادی متعهد می شود
- نویسندگان را متعهد کنید
- تاریخ ها، زمان ها و مناطق زمانی را متعهد کنید
- فایل های اصلاح شده توسط هر commit
- تعداد خطوط اضافه و حذف شده
- تعهدات مرتبط
- معیارهای پیچیدگی کد
بیایید نگاهی به نحوه عملکرد آن بیندازیم
اتصال به مخزن
برای گرفتن اطلاعات از یک مخزن، ابتدا باید a ایجاد کنیم Repository
شی از یک URL GitHub داده شده.
کد این کار نسبتاً ساده است:
# We need PyDriller to pull git repository information
from pydriller import Repository
# Replace this path with your own repository of interest
path = 'https://github.com/dotnet/machinelearning'
repo = Repository(path)
این کد در واقع نیست تجزیه و تحلیل مخزن، اما ما را به حالتی می رساند که می توانیم از commit هایی که بخشی از مخزن git هستند عبور کنیم.
ما در واقع با تماس این تعهدات را بررسی می کنیم traverse_commits()
بر روی … ما Repository
شی و حلقه زدن بر روی نتایج.
یادداشت مهم: حلقه زدن به تعهدات مخزن برای مخازن بزرگ زمان زیادی می برد. تجزیه و تحلیل مخزن ML.NET که این نمونه کد به آن اشاره می کند، 52 دقیقه طول کشید، که در زمان تجزیه و تحلیل در 25 فوریه 2023، 2681 commit داشت.
کد زیر روی تمام commit ها و برای هر commit حلقه می شود:
- لیستی از فایل هایی که توسط آن commit اصلاح شده اند بسازید
- استخراج اطلاعات commit اولیه
- محاسبه معیارهای کد با استفاده از مدل قابلیت نگهداری دلتا منبع باز PyDriller (OS-DMM)
همانطور که هر commit خوانده می شود، به لیستی از commit ها اضافه می شود که به عنوان محصول فرعی نهایی فرآیند بارگذاری عمل می کند.
لیست کد به شرح زیر است:
# Loop over each PyDriller commit to transform it to a commit usable for analysis later
# NOTE: This can take a LONG time if there are many commits
commits = []
for commit in repo.traverse_commits():
hash = commit.hash
# Gather a list of files modified in the commit
files = []
try:
for f in commit.modified_files:
if f.new_path is not None:
files.append(f.new_path)
except Exception:
print('Could not read files for commit ' + hash)
continue
# Capture information about the commit in object format so I can reference it later
record = {
'hash': hash,
'message': commit.msg,
'author_name': commit.author.name,
'author_email': commit.author.email,
'author_date': commit.author_date,
'author_tz': commit.author_timezone,
'committer_name': commit.committer.name,
'committer_email': commit.committer.email,
'committer_date': commit.committer_date,
'committer_tz': commit.committer_timezone,
'in_main': commit.in_main_branch,
'is_merge': commit.merge,
'num_deletes': commit.deletions,
'num_inserts': commit.insertions,
'net_lines': commit.insertions - commit.deletions,
'num_files': commit.files,
'branches': ', '.join(commit.branches), # Comma separated list of branches the commit is found in
'files': ', '.join(files), # Comma separated list of files the commit modifies
'parents': ', '.join(commit.parents), # Comma separated list of parents
# PyDriller Open Source Delta Maintainability Model (OS-DMM) stat. See https://pydriller.readthedocs.io/en/latest/deltamaintainability.html for metric definitions
'dmm_unit_size': commit.dmm_unit_size,
'dmm_unit_complexity': commit.dmm_unit_complexity,
'dmm_unit_interfacing': commit.dmm_unit_interfacing,
}
# Omitted: modified_files (list), project_path, project_name
commits.append(record)
توجه داشته باشید که کد بالا در a است try / except
. این به این دلیل است که GitHub به طور غیرمنتظره ای به برخی از درخواست های PyDriller برای جزئیات commit پاسخ داد. با دانستن اینکه این یک مخزن معتبر است، احساس کردم بهترین استراتژی این است که خطای رخ داده در هش commit را ثبت کنم و آن تعهدات را از مجموعه نتایج نهایی حذف کنم.
اعتبار سنجی فرآیند بارگذاری
پس از بارگیری داده ها (که ممکن است مدتی طول بکشد)، زمان آن است که مطمئن شوید که معتبر به نظر می رسد.
من این کار را با استفاده از کتابخانه محبوب پانداها برای کارهای تجزیه و تحلیل داده های جدولی انتخاب کردم.
در حالی که پانداها معمولاً برای تجزیه و تحلیل، غربال کردن، تمیز کردن و دستکاری منابع داده جدولی استفاده میشوند، استفاده ما در این مرحله از پروژه کاملاً اساسی است: دادهها را در یک DataFrame جدولی بارگذاری میکنیم، یک پیشنمایش کوچک از آن را نمایش میدهیم و سپس آن را در آن ذخیره میکنیم. دیسک
کد بارگیری و پیش نمایش مجموعه داده به شرح زیر است:
import pandas as pd
# Translate this list of commits to a Pandas data frame
df_commits = pd.DataFrame(commits)
# Display the first 5 rows of the DataFrame
df_commits.head()
خط پایانی df_commits.head()
اگر در یک نوت بوک Jupyter اجرا شود، تماس چیزی شبیه به نتیجه زیر را نشان می دهد:
یادداشت مهم: نمایش 5 ردیف اول DataFrame از طریق .head()
تماس تنها در صورتی کار می کند که این کد به عنوان بخشی از نوت بوک Jupyter اجرا شود و آن خط آخرین خط در سلول کد باشد. با این حال، این مرحله اختیاری است، زیرا تنها هدف آن این است که به شما اجازه نگاه کردن به خروجی را بدهد.
صادر کردن داده ها به یک فایل CSV
در نهایت می توانید محتویات قاب داده را در یک فایل CSV با کد زیر ذخیره کنید:
df_commits.to_csv('Commits.csv')
با این کار فایل روی دیسک در فهرست فعلی تحت نام ذخیره می شود Commits.csv
.
هنگامی که فایل روی دیسک نوشته شد، می توانید آن را به Excel، Tableau، Power BI یا ابزار تجزیه و تحلیل داده دیگری وارد کنید.
از طرف دیگر، میتوانید آن را دوباره با پانداها بارگذاری کنید و آن را با کد پایتون تجسم کنید که در مقالهای آینده بررسی خواهیم کرد.
محدودیت ها و مراحل بعدی
کدی که من در اینجا ارائه کرده ام برای تولید یک فایل CSV از commit ها از یک مخزن عمومی در GitHub مفید است.
اگر میخواهید با انجام تجزیه و تحلیل دستی بیشتر دادهها یا وصل کردن دادهها به ابزار تجسم داده، روندها را در تاریخچه تعهد خود تجسم کنید، مفید خواهد بود.
با این حال، این فرآیند دارای چند محدودیت است:
اول اینکه روی مخازن غیر عمومی در GitHub یا در مخازن git که در GitHub نیستند کار نمی کند.
ثانیاً، مشاهده کردم که 10 مورد از 2681 تعهدی که سعی کردم تفسیر کنم، نوعی خطای مداوم در بازیابی اطلاعات خود از GitHub از طریق PyDriller داشتند. من این مشکل را فقط در یک مخزن دیده ام، اما ممکن است در مخازن خود با آن مواجه شوید.
سوم، این فرآیند زمان قابل توجهی برای پردازش تاریخچه مخزن می گیرد. در آزمایشهایم عملکرد پردازش حدود 1 commit را در هر 800 میلیثانیه دیدم، که به این معنی است که پردازش بیشتر مخازن زمان غیر ضروری را میگیرد.
در نهایت، این فرآیند فقط اطلاعات سطح بالا در مورد تغییرات git را ردیابی می کند و جزئیات مربوط به خطوط منفرد یا تغییرات کدی را که شامل می شوند شامل نمی شود، اگرچه فایل های اصلاح شده باید گنجانده شوند.
در همه موارد، PyDriller یک ابزار عالی برای دریافت آسان داده های مخزن git آماده و آماده برای تجزیه و تحلیل بیشتر است.
منتظر مقالات بعدی باشید که نحوه کار با داده هایی را که از مخزن git شما می گیرد را نشان می دهد.