package source import ( "context" "fmt" "strconv" "strings" dvpb "code.hackerspace.pl/hscloud/devtools/depotview/proto" ) type DepotViewSourceProvider struct { stub dvpb.DepotViewClient } func NewDepotView(stub dvpb.DepotViewClient) SourceProvider { return &DepotViewSourceProvider{ stub: stub, } } func changeRef(ref string) int64 { ref = strings.ToLower(ref) if !strings.HasPrefix(ref, "change/") && !strings.HasPrefix(ref, "cr/") { return 0 } n, err := strconv.ParseInt(strings.SplitN(ref, "/", 2)[1], 10, 64) if err != nil { return 0 } return n } func (s *DepotViewSourceProvider) Source(ctx context.Context, ref string) (Source, error) { var hash string n := changeRef(ref) if n != 0 { res, err := s.stub.ResolveGerritChange(ctx, &dvpb.ResolveGerritChangeRequest{Change: n}) if err != nil { return nil, err } hash = res.Hash } else { res, err := s.stub.Resolve(ctx, &dvpb.ResolveRequest{Ref: ref}) if err != nil { return nil, err } hash = res.Hash } if hash == "" { return nil, nil } return &depotViewSource{ stub: s.stub, hash: hash, change: n, }, nil } type depotViewSource struct { stub dvpb.DepotViewClient hash string change int64 } func (s *depotViewSource) IsFile(ctx context.Context, path string) (bool, error) { res, err := s.stub.Stat(ctx, &dvpb.StatRequest{ Hash: s.hash, Path: path, }) if err != nil { return false, err } return res.Type == dvpb.StatResponse_TYPE_FILE, nil } func (s *depotViewSource) IsDirectory(ctx context.Context, path string) (bool, error) { res, err := s.stub.Stat(ctx, &dvpb.StatRequest{ Hash: s.hash, Path: path, }) if err != nil { return false, err } return res.Type == dvpb.StatResponse_TYPE_DIRECTORY, nil } func (s *depotViewSource) ReadFile(ctx context.Context, path string) ([]byte, error) { var data []byte srv, err := s.stub.Read(ctx, &dvpb.ReadRequest{ Hash: s.hash, Path: path, }) if err != nil { return nil, err } for { res, err := srv.Recv() if err != nil { return nil, err } if len(res.Data) == 0 { break } data = append(data, res.Data...) } return data, nil } func (s *depotViewSource) WebLinks(fpath string) []WebLink { gitURL := fmt.Sprintf(FlagGitwebURLPattern, s.hash, fpath) links := []WebLink{ WebLink{Kind: "source", LinkLabel: s.hash[:16], LinkURL: gitURL}, } if s.change != 0 { gerritLabel := fmt.Sprintf("change %d", s.change) gerritLink := fmt.Sprintf("https://gerrit.hackerspace.pl/%d", s.change) links = append(links, WebLink{Kind: "gerrit", LinkLabel: gerritLabel, LinkURL: gerritLink}) } return links }