From 456bb8c26c1c444e40d988897e932dc75881c222 Mon Sep 17 00:00:00 2001 From: oppiliappan Date: Tue, 11 Nov 2025 11:23:41 +0000 Subject: [PATCH] types: rework NiceTree to use go-git filemodes Change-Id: yyyrkvukqtwutvqwwqwprqunnztolxsn we can now differentiate between regular directories and submodules in filetree walkers. this fixes things like broken commit info and language detection in submodules. Signed-off-by: oppiliappan --- appview/repo/index.go | 9 ++++----- appview/repo/repo_util.go | 4 ++-- appview/repo/tree.go | 9 ++++----- knotserver/git/tree.go | 17 ++++------------- knotserver/ingester.go | 2 +- knotserver/internal.go | 2 +- knotserver/xrpc/repo_tree.go | 8 +++----- types/tree.go | 33 ++++++++++++++++++++++++++++----- 8 files changed, 47 insertions(+), 37 deletions(-) diff --git a/appview/repo/index.go b/appview/repo/index.go index 218b9777..6815e5c7 100644 --- a/appview/repo/index.go +++ b/appview/repo/index.go @@ -351,12 +351,11 @@ func (rp *Repo) buildIndexResponse(ctx context.Context, xrpcc *indigoxrpc.Client if treeResp != nil && treeResp.Files != nil { for _, file := range treeResp.Files { niceFile := types.NiceTree{ - IsFile: file.Is_file, - IsSubtree: file.Is_subtree, - Name: file.Name, - Mode: file.Mode, - Size: file.Size, + Name: file.Name, + Mode: file.Mode, + Size: file.Size, } + if file.Last_commit != nil { when, _ := time.Parse(time.RFC3339, file.Last_commit.When) niceFile.LastCommit = &types.LastCommitInfo{ diff --git a/appview/repo/repo_util.go b/appview/repo/repo_util.go index 816f51f9..34bc20c6 100644 --- a/appview/repo/repo_util.go +++ b/appview/repo/repo_util.go @@ -17,8 +17,8 @@ import ( func sortFiles(files []types.NiceTree) { sort.Slice(files, func(i, j int) bool { - iIsFile := files[i].IsFile - jIsFile := files[j].IsFile + iIsFile := files[i].IsFile() + jIsFile := files[j].IsFile() if iIsFile != jIsFile { return !iIsFile } diff --git a/appview/repo/tree.go b/appview/repo/tree.go index 6ad6b98d..82f68352 100644 --- a/appview/repo/tree.go +++ b/appview/repo/tree.go @@ -50,11 +50,9 @@ func (rp *Repo) Tree(w http.ResponseWriter, r *http.Request) { files := make([]types.NiceTree, len(xrpcResp.Files)) for i, xrpcFile := range xrpcResp.Files { file := types.NiceTree{ - Name: xrpcFile.Name, - Mode: xrpcFile.Mode, - Size: int64(xrpcFile.Size), - IsFile: xrpcFile.Is_file, - IsSubtree: xrpcFile.Is_subtree, + Name: xrpcFile.Name, + Mode: xrpcFile.Mode, + Size: int64(xrpcFile.Size), } // Convert last commit info if present if xrpcFile.Last_commit != nil { @@ -97,6 +95,7 @@ func (rp *Repo) Tree(w http.ResponseWriter, r *http.Request) { } } sortFiles(result.Files) + rp.pages.RepoTree(w, pages.RepoTreeParams{ LoggedInUser: user, BreadCrumbs: breadcrumbs, diff --git a/knotserver/git/tree.go b/knotserver/git/tree.go index 6ba0bf8a..a01742f7 100644 --- a/knotserver/git/tree.go +++ b/knotserver/git/tree.go @@ -7,6 +7,7 @@ import ( "path" "time" + "github.com/go-git/go-git/v5/plumbing/filemode" "github.com/go-git/go-git/v5/plumbing/object" "tangled.org/core/types" ) @@ -53,9 +54,7 @@ func (g *GitRepo) makeNiceTree(ctx context.Context, subtree *object.Tree, parent } for _, e := range subtree.Entries { - mode, _ := e.Mode.ToOSFileMode() sz, _ := subtree.Size(e.Name) - fpath := path.Join(parent, e.Name) var lastCommit *types.LastCommitInfo @@ -69,8 +68,7 @@ func (g *GitRepo) makeNiceTree(ctx context.Context, subtree *object.Tree, parent nts = append(nts, types.NiceTree{ Name: e.Name, - Mode: mode.String(), - IsFile: e.Mode.IsFile(), + Mode: e.Mode.String(), Size: sz, LastCommit: lastCommit, }) @@ -126,21 +124,14 @@ func (g *GitRepo) walkHelper( default: } - mode, err := e.Mode.ToOSFileMode() - if err != nil { - // TODO: log this - continue - } - if e.Mode.IsFile() { - err = cb(e, currentTree, root) - if errors.Is(err, TerminateWalk) { + if err := cb(e, currentTree, root); errors.Is(err, TerminateWalk) { return err } } // e is a directory - if mode.IsDir() { + if e.Mode == filemode.Dir { subtree, err := currentTree.Tree(e.Name) if err != nil { return fmt.Errorf("sub tree %s: %w", e.Name, err) diff --git a/knotserver/ingester.go b/knotserver/ingester.go index fefcef6d..5d2cc6e7 100644 --- a/knotserver/ingester.go +++ b/knotserver/ingester.go @@ -161,7 +161,7 @@ func (h *Knot) processPull(ctx context.Context, event *models.Event) error { var pipeline workflow.RawPipeline for _, e := range workflowDir { - if !e.IsFile { + if !e.IsFile() { continue } diff --git a/knotserver/internal.go b/knotserver/internal.go index 4829848e..b9bcaffa 100644 --- a/knotserver/internal.go +++ b/knotserver/internal.go @@ -277,7 +277,7 @@ func (h *InternalHandle) triggerPipeline( var pipeline workflow.RawPipeline for _, e := range workflowDir { - if !e.IsFile { + if !e.IsFile() { continue } diff --git a/knotserver/xrpc/repo_tree.go b/knotserver/xrpc/repo_tree.go index ba9ad711..7e2ad01d 100644 --- a/knotserver/xrpc/repo_tree.go +++ b/knotserver/xrpc/repo_tree.go @@ -67,11 +67,9 @@ func (x *Xrpc) RepoTree(w http.ResponseWriter, r *http.Request) { treeEntries := make([]*tangled.RepoTree_TreeEntry, len(files)) for i, file := range files { entry := &tangled.RepoTree_TreeEntry{ - Name: file.Name, - Mode: file.Mode, - Size: file.Size, - Is_file: file.IsFile, - Is_subtree: file.IsSubtree, + Name: file.Name, + Mode: file.Mode, + Size: file.Size, } if file.LastCommit != nil { diff --git a/types/tree.go b/types/tree.go index 3e721e0e..f78a9f07 100644 --- a/types/tree.go +++ b/types/tree.go @@ -4,20 +4,43 @@ import ( "time" "github.com/go-git/go-git/v5/plumbing" + "github.com/go-git/go-git/v5/plumbing/filemode" ) // A nicer git tree representation. type NiceTree struct { // Relative path - Name string `json:"name"` - Mode string `json:"mode"` - Size int64 `json:"size"` - IsFile bool `json:"is_file"` - IsSubtree bool `json:"is_subtree"` + Name string `json:"name"` + Mode string `json:"mode"` + Size int64 `json:"size"` LastCommit *LastCommitInfo `json:"last_commit,omitempty"` } +func (t *NiceTree) FileMode() (filemode.FileMode, error) { + return filemode.New(t.Mode) +} + +func (t *NiceTree) IsFile() bool { + m, err := t.FileMode() + + if err != nil { + return false + } + + return m.IsFile() +} + +func (t *NiceTree) IsSubmodule() bool { + m, err := t.FileMode() + + if err != nil { + return false + } + + return m == filemode.Submodule +} + type LastCommitInfo struct { Hash plumbing.Hash Message string -- 2.43.0