gitlab获取项目所有文件名
gitlab api 没有提供获取项目下所有文件名的方法。需要通过间接的方式获取。
通过api 接口
gitlab 提供了一个 /projects/{project_id}/repository/tree?path={path}
的接口可以获取某个路径下的文件和目录。根据官方文档,该接口表现如命令 git ls-tree
类似。由于只能返回路径下的文件和目录,因此需要不断迭代。也就是先访问根目录,取出类型为src
的目录,继续遍历,直到遍历所有子目录。网上能够Google到的方案基本都是基于此原理,在此就不再赘述。
通过页面接口(重点)
gitlab页面上提供了一个find file by filename的功能。点进去后,后台会先请求获取所有文件名
,再通过前端实现实时筛选。本方就是基于此接口,最大的难点在于代码实现页面登录,保存登录信息,然后请求该接口。示例代码基于golang 和第三方库 goreqeust 完成http请求 , goquery 完成页面元素提取。
- package main
- import (
- "net/url"
-
- "github.com/PuerkitoBio/goquery"
- "github.com/parnurzeal/gorequest"
- "github.com/sirupsen/logrus"
- )
- var(
- GitlabLoginAddr="http://git.example.com/users/sign_in"
- GitProjectAddr="http://git.example.com/backend/authservice"
- GitUser = "bob"
- GitPassword = "bobpassword"
- )
- func main(){
- agent := gorequest.New()
- agent.SetDoNotClearSuperAgent(true)
- //访问登录页面,获取authenticity_token及其cookies
- resp, _, errs := agent.Get(GitlabLoginAddr).End()
- if len(errs) > 0{
- logrus.Fatal(errs)
- }
- if resp.StatusCode != 200 {
- logrus.Fatal("got statuscode: ", resp.StatusCode)
- }
- doc, err := goquery.NewDocumentFromReader(resp.Body)
- if err != nil {
- logrus.Fatal(err)
- }
- //页面提取 authenticity_token
- csrfToken, exist := doc.Find(`input[name="authenticity_token"]`).Attr("value")
- if !exist {
- logrus.Fatal("failed tp read csrf_token")
- }
- data := make(url.Values)
- data["authenticity_token"] = []string{csrfToken}
- data["user[login]"] = []string{GitUser}
- data["user[password]"] = []string{GitPassword}
- //登录
- resp, body, errs := agent.Post(GitlabLoginAddr).SendString(data.Encode()).End()
- if len(errs) > 0 {
- logrus.Fatal(errs)
- }
- if resp.StatusCode != 200 {
- logrus.Error(body)
- logrus.Fatal("got statuscode: ", resp.StatusCode)
- }
- //获取项目所有文件名
- resp, body, errs = agent.Get(GitProjectAddr+"/files/master?format=json").Set("X-CSRF-Token", csrfToken).End()
- if len(errs) > 0 {
- logrus.Fatal(errs)
- }
- if resp.StatusCode != 200 {
- logrus.Error("got statuscode: ", resp.StatusCode)
- }
- //body json解析即为所有文件名list
- logrus.Info(string(body))
- }