gitlab获取项目所有文件名

gitlab api 没有提供获取项目下所有文件名的方法。需要通过间接的方式获取。

通过api 接口

gitlab 提供了一个 /projects/{project_id}/repository/tree?path={path} 的接口可以获取某个路径下的文件和目录。根据官方文档,该接口表现如命令 git ls-tree 类似。由于只能返回最多100条,因此需要根据header返回的分页信息进行遍历。网上能够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))
}
03-31 01:12