Адаптер Gitlab собирает данные по проектам из кабинета в Gitlab и загружает их в базу данных Mongo. Также адаптер генерирует срезовут таблицу с данными по проектам и количеству коммитов в них. Ниже приведена документация разработчика. Ссылка на гит: https://git.miem.hse.ru/394/gathering-statistics-from-gitlab.
import "command-line-arguments"
Пакет domain содержит все модели для работы с адаптером Gitlab. Тут лежат все структуры и общие методы для них.
BasicProject - упрощенная версия проекта в Gitlab
type BasicProject struct {
ID int `json:"id" bson:"id"`
Description string `json:"description" bson:"description"`
Name string `json:"name" bson:"name"`
NameWithNamespace string `json:"name_with_namespace" bson:"name_with_namespace"`
Path string `json:"path" bson:"path"`
PathWithNamespace string `json:"path_with_namespace" bson:"path_with_namespace"`
CreatedAt time.Time `json:"created_at" bson:"created_at"`
DefaultBranch string `json:"default_branch" bson:"default_branch"`
TagList []string `json:"tag_list" bson:"tag_list"`
SSHURLToRepo string `json:"ssh_url_to_repo" bson:"ssh_url_to_repo"`
HTTPURLToRepo string `json:"http_url_to_repo" bson:"http_url_to_repo"`
WebURL string `json:"web_url" bson:"web_url"`
ReadmeURL string `json:"readme_url" bson:"readme_url"`
LicenseURL string `json:"license_url" bson:"license_url"`
License *license `json:"license" bson:"license"`
AvatarURL *string `json:"avatar_url" bson:"avatar_url"`
StarCount int `json:"star_count" bson:"star_count"`
ForksCount int `json:"forks_count" bson:"forks_count"`
LastActivityAt time.Time `json:"last_activity_at" bson:"last_activity_at"`
Namespace *Namespace `json:"Namespace" bson:"Namespace"`
Links *links `json:"_links" bson:"_links"`
EmptyRepo bool `json:"empty_repo" bson:"empty_repo"`
Archived bool `json:"archived" bson:"archived"`
Visibility string `json:"visibility" bson:"visibility"`
Owner *owner `json:"owner" bson:"owner"`
ResolveOutdatedDiffDiscussions bool `json:"resolve_outdated_diff_discussions" bson:"resolve_outdated_diff_discussions"`
ContainerRegistryEnabled bool `json:"container_registry_enabled" bson:"container_registry_enabled"`
ContainerExpirationPolicy *containerExpirationPolicy `json:"container_expiration_policy" bson:"container_expiration_policy"`
IssuesEnabled bool `json:"issues_enabled" bson:"issues_enabled"`
MergeRequestsEnabled bool `json:"merge_requests_enabled" bson:"merge_requests_enabled"`
WikiEnabled bool `json:"wiki_enabled" bson:"wiki_enabled"`
JobsEnabled bool `json:"jobs_enabled" bson:"jobs_enabled"`
SnippetsEnabled bool `json:"snippets_enabled" bson:"snippets_enabled"`
CanCreateMergeRequestIn bool `json:"can_create_merge_request_in" bson:"can_create_merge_request_in"`
IssuesAccessLevel string `json:"issues_access_level" bson:"issues_access_level"`
RepositoryAccessLevel string `json:"repository_access_level" bson:"repository_access_level"`
MergeRequestsAccessLevel string `json:"merge_requests_access_level" bson:"merge_requests_access_level"`
WikiAccessLevel string `json:"wiki_access_level" bson:"wiki_access_level"`
BuildsAccessLevel string `json:"builds_access_level" bson:"builds_access_level"`
SnippetsAccessLevel string `json:"snippets_access_level" bson:"snippets_access_level"`
PagesAccessLevel string `json:"pages_access_level" bson:"pages_access_level"`
EmailsDisabled *bool `json:"emails_disabled" bson:"emails_disabled"`
SharedRunnersEnabled bool `json:"shared_runners_enabled" bson:"shared_runners_enabled"`
LfsEnabled bool `json:"lfs_enabled" bson:"lfs_enabled"`
CreatorID int `json:"creator_id" bson:"creator_id"`
ImportStatus string `json:"import_status" bson:"import_status"`
ImportError *string `json:"import_error" bson:"import_error"`
OpenIssuesCount int `json:"open_issues_count" bson:"open_issues_count"`
RunnersToken string `json:"runners_token" bson:"runners_token"`
CiDefaultGitDepth int `json:"ci_default_git_depth" bson:"ci_default_git_depth"`
PublicJobs bool `json:"public_jobs" bson:"public_jobs"`
BuildGitStrategy string `json:"build_git_strategy" bson:"build_git_strategy"`
BuildTimeout int `json:"build_timeout" bson:"build_timeout"`
AutoCancelPendingPipelines string `json:"auto_cancel_pending_pipelines" bson:"auto_cancel_pending_pipelines"`
BuildCoverageRegex *string `json:"build_coverage_regex" bson:"build_coverage_regex"`
CiConfigPath string `json:"ci_config_path" bson:"ci_config_path"`
SharedWithGroups []struct {
GroupID int `json:"group_id" bson:"group_id"`
GroupName string `json:"group_name" bson:"group_name"`
GroupAccessLevel int `json:"group_access_level" bson:"group_access_level"`
} `json:"shared_with_groups" bson:"shared_with_groups"`
MergeMethod string `json:"merge_method" bson:"merge_method"`
SuggestionCommitMessage *string `json:"suggestion_commit_message" bson:"suggestion_commit_message"`
AutoDevopsEnabled bool `json:"auto_devops_enabled" bson:"auto_devops_enabled"`
AutoDevopsDeployStrategy string `json:"auto_devops_deploy_strategy" bson:"auto_devops_deploy_strategy"`
AutocloseReferencedIssues bool `json:"autoclose_referenced_issues" bson:"autoclose_referenced_issues"`
Permissions *Permissions `json:"permissions" bson:"permissions"`
OnlyAllowMergeIfPipelineSucceeds bool `json:"only_allow_merge_if_pipeline_succeeds" bson:"only_allow_merge_if_pipeline_succeeds"`
RequestAccessEnabled bool `json:"request_access_enabled" bson:"request_access_enabled"`
OnlyAllowMergeIfAllDiscussionsAreResolved bool `json:"only_allow_merge_if_all_discussions_are_resolved" bson:"only_allow_merge_if_all_discussions_are_resolved"`
RemoveSourceBranchAfterMerge bool `json:"remove_source_branch_after_merge" bson:"remove_source_branch_after_merge"`
PrintingMergeRequestLinkEnabled bool `json:"printing_merge_request_link_enabled" bson:"printing_merge_request_link_enabled"`
Statistics *statistics `json:"statistics" bson:"statistics"`
Languages language `json:"languages" bson:"languages"`
}
Commit - коммит в проекте Gitlab
type Commit struct {
ID string `json:"id" bson:"id"`
ShortID string `json:"short_id" bson:"short_id"`
CreatedAt time.Time `json:"created_at" bson:"created_at"`
ParentIds []string `json:"parent_ids" bson:"parent_ids"`
Title string `json:"title" bson:"title"`
Message string `json:"message" bson:"message"`
AuthorName string `json:"author_name" bson:"author_name"`
AuthorEmail string `json:"author_email" bson:"author_email"`
AuthoredDate time.Time `json:"authored_date" bson:"authored_date"`
CommitterName string `json:"committer_name" bson:"committer_name"`
CommitterEmail string `json:"committer_email" bson:"committer_email"`
CommittedDate time.Time `json:"committed_date" bson:"committed_date"`
Stats *stats `json:"stats" bson:"stats"`
}
Group - группа в Gitlab
type Group struct {
ID int `json:"id" bson:"id"`
Name string `json:"name" bson:"name"`
Path string `json:"path" bson:"path"`
Description string `json:"description" bson:"description"`
Visibility string `json:"visibility" bson:"visibility"`
ShareWithGroupLock bool `json:"share_with_group_lock" bson:"share_with_group_lock"`
RequireTwoFactorAuthentication bool `json:"require_two_factor_authentication" bson:"require_two_factor_authentication"`
TwoFactorGracePeriod int `json:"two_factor_grace_period" bson:"two_factor_grace_period"`
ProjectCreationLevel string `json:"project_creation_level" bson:"project_creation_level"`
AutoDevopsEnabled interface{} `json:"auto_devops_enabled" bson:"auto_devops_enabled"`
SubgroupCreationLevel string `json:"subgroup_creation_level" bson:"subgroup_creation_level"`
EmailsDisabled interface{} `json:"emails_disabled" bson:"emails_disabled"`
MentionsDisabled interface{} `json:"mentions_disabled" bson:"mentions_disabled"`
LfsEnabled bool `json:"lfs_enabled" bson:"lfs_enabled"`
DefaultBranchProtection int `json:"default_branch_protection" bson:"default_branch_protection"`
AvatarURL string `json:"avatar_url" bson:"avatar_url"`
WebURL string `json:"web_url" bson:"web_url"`
RequestAccessEnabled bool `json:"request_access_enabled" bson:"request_access_enabled"`
FullName string `json:"full_name" bson:"full_name"`
FullPath string `json:"full_path" bson:"full_path"`
FileTemplateProjectID int `json:"file_template_project_id" bson:"file_template_project_id"`
ParentID interface{} `json:"parent_id" bson:"parent_id"`
CreatedAt time.Time `json:"created_at" bson:"created_at"`
Statistics Statistics `json:"statistics" bson:"statistics"`
Projects []*BasicProject `json:"projects" bson:"projects"`
Members []Member `json:"members" bson:"members"`
}
GroupAccess описывает доступ к группе Gitlab
type GroupAccess struct {
AccessLevel int `json:"access_level" bson:"access_level"`
NotificationLevel int `json:"notification_level" bson:"notification_level"`
}
type Identities struct {
Provider string `json:"provider" bson:"provider"`
ExternUID string `json:"extern_uid" bson:"extern_uid"`
}
Member - участник проекта Gitlab
type Member struct {
ID int `json:"id" bson:"id"`
Username string `json:"username" bson:"username"`
Name string `json:"name" bson:"name"`
State string `json:"state" bson:"state"`
AvatarURL string `json:"avatar_url" bson:"avatar_url"`
WebURL string `json:"web_url" bson:"web_url"`
AccessLevel int `json:"access_level" bson:"access_level"`
ExpiresAt string `json:"expires_at" bson:"expires_at"`
CreatedAt string `json:"created_at""`
}
Membership - описание пользователя в проекте Gitlab
type Membership struct {
SourceID int `json:"source_id" bson:"source_id"`
SourceName string `json:"source_name" bson:"source_name"`
SourceType string `json:"source_type" bson:"source_type"`
AccessLevel int `json:"access_level" bson:"access_level"`
}
Namespace - описание окружения проекта или группы. Name - название окружения. Для проектов из кабинета всегда начинается с номера проекта. Path - номер проекта. Для проектов из кабинета - всегда числовое значение, которое совпадает с номером проекта из Gitlab.
type Namespace struct {
ID int `json:"id" bson:"id"`
Name string `json:"name" bson:"name"`
Path string `json:"path" bson:"path"`
Kind string `json:"kind" bson:"kind"`
FullPath string `json:"full_path" bson:"full_path"`
ParentID int `json:"parent_id" bson:"parent_id"`
AvatarURL string `json:"avatar_url" bson:"avatar_url"`
WebURL string `json:"web_url" bson:"web_url"`
}
Permissions описывает права доступа к группе Gitlab
type Permissions struct {
ProjectAccess *ProjectAccess `json:"project_access" bson:"project_access"`
GroupAccess *GroupAccess `json:"group_access" bson:"group_access"`
}
ProjUsers - участник проекта Gitlab
type ProjUsers struct {
ID int `json:"id" bson:"id"`
Name string `json:"name" bson:"name"`
Username string `json:"username" bson:"username"`
State string `json:"state" bson:"state"`
AvatarURL string `json:"avatar_url" bson:"avatar_url"`
WebURL string `json:"web_url" bson:"web_url"`
}
Project - полное описание проекта в Gitlab
type Project struct {
ID int `json:"id" bson:"id"`
Description string `json:"description" bson:"description"`
Name string `json:"name" bson:"name"`
NameWithNamespace string `json:"name_with_namespace" bson:"name_with_namespace"`
Path string `json:"path" bson:"path"`
PathWithNamespace string `json:"path_with_namespace" bson:"path_with_namespace"`
CreatedAt time.Time `json:"created_at" bson:"created_at"`
DefaultBranch string `json:"default_branch" bson:"default_branch"`
TagList []string `json:"tag_list" bson:"tag_list"`
SSHURLToRepo string `json:"ssh_url_to_repo" bson:"ssh_url_to_repo"`
HTTPURLToRepo string `json:"http_url_to_repo" bson:"http_url_to_repo"`
WebURL string `json:"web_url" bson:"web_url"`
ReadmeURL string `json:"readme_url" bson:"readme_url"`
LicenseURL string `json:"license_url" bson:"license_url"`
License *license `json:"license" bson:"license"`
AvatarURL *string `json:"avatar_url" bson:"avatar_url"`
StarCount int `json:"star_count" bson:"star_count"`
ForksCount int `json:"forks_count" bson:"forks_count"`
LastActivityAt time.Time `json:"last_activity_at" bson:"last_activity_at"`
Namespace *Namespace `json:"Namespace" bson:"Namespace"`
Links *links `json:"_links" bson:"_links"`
EmptyRepo bool `json:"empty_repo" bson:"empty_repo"`
Archived bool `json:"archived" bson:"archived"`
Visibility string `json:"visibility" bson:"visibility"`
Owner *owner `json:"owner" bson:"owner"`
ResolveOutdatedDiffDiscussions bool `json:"resolve_outdated_diff_discussions" bson:"resolve_outdated_diff_discussions"`
ContainerRegistryEnabled bool `json:"container_registry_enabled" bson:"container_registry_enabled"`
ContainerExpirationPolicy *containerExpirationPolicy `json:"container_expiration_policy" bson:"container_expiration_policy"`
IssuesEnabled bool `json:"issues_enabled" bson:"issues_enabled"`
MergeRequestsEnabled bool `json:"merge_requests_enabled" bson:"merge_requests_enabled"`
WikiEnabled bool `json:"wiki_enabled" bson:"wiki_enabled"`
JobsEnabled bool `json:"jobs_enabled" bson:"jobs_enabled"`
SnippetsEnabled bool `json:"snippets_enabled" bson:"snippets_enabled"`
CanCreateMergeRequestIn bool `json:"can_create_merge_request_in" bson:"can_create_merge_request_in"`
IssuesAccessLevel string `json:"issues_access_level" bson:"issues_access_level"`
RepositoryAccessLevel string `json:"repository_access_level" bson:"repository_access_level"`
MergeRequestsAccessLevel string `json:"merge_requests_access_level" bson:"merge_requests_access_level"`
WikiAccessLevel string `json:"wiki_access_level" bson:"wiki_access_level"`
BuildsAccessLevel string `json:"builds_access_level" bson:"builds_access_level"`
SnippetsAccessLevel string `json:"snippets_access_level" bson:"snippets_access_level"`
PagesAccessLevel string `json:"pages_access_level" bson:"pages_access_level"`
EmailsDisabled *bool `json:"emails_disabled" bson:"emails_disabled"`
SharedRunnersEnabled bool `json:"shared_runners_enabled" bson:"shared_runners_enabled"`
LfsEnabled bool `json:"lfs_enabled" bson:"lfs_enabled"`
CreatorID int `json:"creator_id" bson:"creator_id"`
ImportStatus string `json:"import_status" bson:"import_status"`
ImportError *string `json:"import_error" bson:"import_error"`
OpenIssuesCount int `json:"open_issues_count" bson:"open_issues_count"`
RunnersToken string `json:"runners_token" bson:"runners_token"`
CiDefaultGitDepth int `json:"ci_default_git_depth" bson:"ci_default_git_depth"`
PublicJobs bool `json:"public_jobs" bson:"public_jobs"`
BuildGitStrategy string `json:"build_git_strategy" bson:"build_git_strategy"`
BuildTimeout int `json:"build_timeout" bson:"build_timeout"`
AutoCancelPendingPipelines string `json:"auto_cancel_pending_pipelines" bson:"auto_cancel_pending_pipelines"`
BuildCoverageRegex *string `json:"build_coverage_regex" bson:"build_coverage_regex"`
CiConfigPath string `json:"ci_config_path" bson:"ci_config_path"`
SharedWithGroups []struct {
GroupID int `json:"group_id" bson:"group_id"`
GroupName string `json:"group_name" bson:"group_name"`
GroupAccessLevel int `json:"group_access_level" bson:"group_access_level"`
} `json:"shared_with_groups" bson:"shared_with_groups"`
MergeMethod string `json:"merge_method" bson:"merge_method"`
SuggestionCommitMessage *string `json:"suggestion_commit_message" bson:"suggestion_commit_message"`
AutoDevopsEnabled bool `json:"auto_devops_enabled" bson:"auto_devops_enabled"`
AutoDevopsDeployStrategy string `json:"auto_devops_deploy_strategy" bson:"auto_devops_deploy_strategy"`
AutocloseReferencedIssues bool `json:"autoclose_referenced_issues" bson:"autoclose_referenced_issues"`
Permissions *Permissions `json:"permissions" bson:"permissions"`
OnlyAllowMergeIfPipelineSucceeds bool `json:"only_allow_merge_if_pipeline_succeeds" bson:"only_allow_merge_if_pipeline_succeeds"`
RequestAccessEnabled bool `json:"request_access_enabled" bson:"request_access_enabled"`
OnlyAllowMergeIfAllDiscussionsAreResolved bool `json:"only_allow_merge_if_all_discussions_are_resolved" bson:"only_allow_merge_if_all_discussions_are_resolved"`
RemoveSourceBranchAfterMerge bool `json:"remove_source_branch_after_merge" bson:"remove_source_branch_after_merge"`
PrintingMergeRequestLinkEnabled bool `json:"printing_merge_request_link_enabled" bson:"printing_merge_request_link_enabled"`
Statistics *statistics `json:"statistics" bson:"statistics"`
Languages language `json:"languages" bson:"languages"`
Users []*ProjUsers `json:"users" bson:"users"`
Commits []Commit `json:"commits" bson:"commits"`
CommitsCount int `json:"commit_count" bson:"commit_count"`
}
ProjectAccess описывает доступ к проекту Gitlab
type ProjectAccess struct {
AccessLevel int `json:"access_level" bson:"access_level"`
NotificationLevel int `json:"notification_level" bson:"notification_level"`
}
Statistics - статистика проекта Gitlab
type Statistics struct {
StorageSize int `json:"storage_size" bson:"storage_size"`
RepositorySize int `json:"repository_size" bson:"repository_size"`
WikiSize int `json:"wiki_size" bson:"wiki_size"`
LfsObjectsSize int `json:"lfs_objects_size" bson:"lfs_objects_size"`
JobArtifactsSize int `json:"job_artifacts_size" bson:"job_artifacts_size"`
PackagesSize int `json:"packages_size" bson:"packages_size"`
SnippetsSize int `json:"snippets_size" bson:"snippets_size"`
}
User - пользователь Gitlab
type User struct {
ID int `json:"id" bson:"id"`
Name string `json:"name" bson:"name"`
Username string `json:"username" bson:"username"`
State string `json:"state" bson:"state"`
AvatarURL string `json:"avatar_url" bson:"avatar_url"`
WebURL string `json:"web_url" bson:"web_url"`
CreatedAt time.Time `json:"created_at" bson:"created_at"`
Bio string `json:"bio" bson:"bio"`
Location string `json:"location" bson:"location"`
PublicEmail string `json:"public_email" bson:"public_email"`
Skype string `json:"skype" bson:"skype"`
Linkedin string `json:"linkedin" bson:"linkedin"`
Twitter string `json:"twitter" bson:"twitter"`
WebsiteURL string `json:"website_url" bson:"website_url"`
Organization string `json:"organization" bson:"organization"`
LastSignInAt time.Time `json:"last_sign_in_at" bson:"last_sign_in_at"`
ConfirmedAt time.Time `json:"confirmed_at" bson:"confirmed_at"`
LastActivityOn string `json:"last_activity_on" bson:"last_activity_on"`
Email string `json:"email" bson:"email"`
ThemeID int `json:"theme_id" bson:"theme_id"`
ColorSchemeID int `json:"color_scheme_id" bson:"color_scheme_id"`
ProjectsLimit int `json:"projects_limit" bson:"projects_limit"`
CurrentSignInAt time.Time `json:"current_sign_in_at" bson:"current_sign_in_at"`
Identities []Identities `json:"identities" bson:"identities"`
CanCreateGroup bool `json:"can_create_group" bson:"can_create_group"`
CanCreateProject bool `json:"can_create_project" bson:"can_create_project"`
TwoFactorEnabled bool `json:"two_factor_enabled" bson:"two_factor_enabled"`
External bool `json:"external" bson:"external"`
PrivateProfile bool `json:"private_profile" bson:"private_profile"`
IsAdmin bool `json:"is_admin" bson:"is_admin"`
Memberships []Membership `json:"projects" bson:"projects"`
}
import "command-line-arguments"
Package config содержит обработчик и генератор конфига. С его помощью содержимое config.json можно отобразить в Go структуре. Общий вид конфига: { "mongo": { "url": "", "db": "", "user_collection": "", "group_collection": "" }, "git": { "scheme": "https", "host": "git.miem.hse.ru", "base_api_uri": "/api/v4", "token": "" }, "common": { "conn_timeout": 40, "max_retries": 20, "max_conns_per_host": 5, "request_pause": 0, "log_folder": "./logs", "log_in_std_in": false } }
func SetupConfig() error
SetupConfig регистрирует конфиг в исполняемом файле
Common - общий конфиг
type Common struct {
ConnTimeout int `json:"conn_timeout"`
MaxRetries int `json:"max_retries"`
RequestPause int `json:"request_pause"`
LogFolder string `json:"log_folder"`
LogInStdIn bool `json:"log_in_std_in"`
}
func GetCommonConfig() Common
GetCommonConfig позволяет получить общий конфиг в виде структуры Common
Config - весь конфиг
type Config struct {
Mongo Mongo `json:"mongo"`
Git Git `json:"git"`
Common Common `json:"common"`
}
func GetConfig() (Config, error)
GetConfig позволяет получить весь конфиг в виде структуры Config
Git - конфиг гита
type Git struct {
Scheme string `json:"scheme"`
Host string `json:"host"`
BaseApiUri string `json:"base_api_uri"`
Token string `json:"token"`
}
func GetGitConfig() Git
GetGitConfig позволяет получить конфиг для гита в виде структуры Git
Mongo - конфиг базы данных
type Mongo struct {
Url string `json:"url"`
DB string `json:"db"`
UserCollection string `json:"user_collection"`
GroupCollection string `json:"group_collection"`
}
func GetMongoConfig() Mongo
GetMongoConfig позволяет получить конфиг для базы данных в виде структуры Mongo
import "command-line-arguments"
Package git содержит имплементацию клиента Gitlab со всеми функциями, нужными для сбора данных.
type Client struct {
// contains filtered or unexported fields
}
func NewGitClient(iterator PageIterator, config config.Git, logger *log.Logger) *Client
func (c *Client) GetMemberships(id int) ([]domain.Membership, error)
GetMemberships достает всей участников проекта по id
func (c *Client) GetProjects() (<-chan domain.Project, error)
GetProjects достает из гита все проекты
func (c *Client) GetUsers() (<-chan domain.User, error)
GetUsers достает из гита всех пользователей
func (c *Client) SendFastRequest(resource, query string) ([]byte, error)
func (c *Client) SendRequest(resource, query string) (<-chan []byte, error)
PageIterator собирает информацию ответа по страничкам. Поддерживает запросы с задержкой для снижения нагрузки.
type PageIterator interface {
Scan(url string, pages chan<- []byte)
BackoffRequest(url string) (resp *http.Response, err error)
}
type Client struct {
// contains filtered or unexported fields
}
func NewGitClient(iterator PageIterator, config config.Git, logger *log.Logger) *Client
func (c *Client) GetMemberships(id int) ([]domain.Membership, error)
GetMemberships достает всей участников проекта по id
func (c *Client) GetProjects() (<-chan domain.Project, error)
GetProjects достает из гита все проекты
func (c *Client) GetUsers() (<-chan domain.User, error)
GetUsers достает из гита всех пользователей
func (c *Client) SendFastRequest(resource, query string) ([]byte, error)
func (c *Client) SendRequest(resource, query string) (<-chan []byte, error)
PageIterator собирает информацию ответа по страничкам. Поддерживает запросы с задержкой для снижения нагрузки.
type PageIterator interface {
Scan(url string, pages chan<- []byte)
BackoffRequest(url string) (resp *http.Response, err error)
}
func CreateProjectsTable(projects <-chan domain.Project) map[string]ProjectInfo
CreateProjectsTable создает таблицу с проектами
type ProjectInfo struct {
ID int `json:"id"`
Path string `json:"path"`
Name string `json:"name"`
CommitsCount int `json:"commits_count"`
LastCommitDate time.Time `json:"last_commit_date"`
}
Projects имплементирует функционал для работы с проектами из гита.
type Projects struct {
// contains filtered or unexported fields
}
func NewProjects(logger *log.Logger, client *git.Client) *Projects
NewProjects - конструктор Projects
func (p *Projects) GetCommits(id int, query string) ([]domain.Commit, error)
GetCommits достает все коммиты из проекта по id
func (p *Projects) GetProjects() <-chan domain.Project
GetProjects достает все проекты из гита
type Client struct {
// contains filtered or unexported fields
}
func NewGitClient(iterator PageIterator, config config.Git, logger *log.Logger) *Client
func (c *Client) GetMemberships(id int) ([]domain.Membership, error)
GetMemberships достает всей участников проекта по id
func (c *Client) GetProjects() (<-chan domain.Project, error)
GetProjects достает из гита все проекты
func (c *Client) GetUsers() (<-chan domain.User, error)
GetUsers достает из гита всех пользователей
func (c *Client) SendFastRequest(resource, query string) ([]byte, error)
func (c *Client) SendRequest(resource, query string) (<-chan []byte, error)
PageIterator собирает информацию ответа по страничкам. Поддерживает запросы с задержкой для снижения нагрузки.
type PageIterator interface {
Scan(url string, pages chan<- []byte)
BackoffRequest(url string) (resp *http.Response, err error)
}
import httplib2
import apiclient
import csv
import datetime
from oauth2client.service_account import ServiceAccountCredentials
Скрипт sheets.py экспортирует полученную таблицу в Google Docs.
batchUpdate - экспорт данных из таблицы csv в Google Docs.
service.spreadsheets().values().batchUpdate(
spreadsheetId=Sheet_id,
body={
"valueInputOption": "USER_ENTERED",
"data": [
{"range": f'A1:D{len(a)}',
"majorDimension": "ROWS",
"values": a
}
]
}
).execute()
csv_dict_reader - функция импорта данных из полученной csv таблицы.
def csv_dict_reader(file_obj):
reader = csv.DictReader(file_obj, delimiter=',')
a = [['Номер проекта', 'Название проекта', 'Число коммитов', 'Дата последнего коммита']]
for line in reader:
a.append([line['Номер проекта'], line['Название проекта'], line['Число коммитов'], line['Дата последнего коммита']])