mirror of
https://github.com/harness/drone.git
synced 2025-05-05 20:11:36 +08:00
161 lines
4.2 KiB
Go
161 lines
4.2 KiB
Go
// Copyright 2023 Harness, Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package adapter
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"path"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/harness/gitness/git/types"
|
|
|
|
gitea "code.gitea.io/gitea/modules/git"
|
|
)
|
|
|
|
func cleanTreePath(treePath string) string {
|
|
return strings.Trim(path.Clean("/"+treePath), "/")
|
|
}
|
|
|
|
// GetTreeNode returns the tree node at the given path as found for the provided reference.
|
|
// Note: ref can be Branch / Tag / CommitSHA.
|
|
func (a Adapter) GetTreeNode(
|
|
ctx context.Context,
|
|
repoPath string,
|
|
ref string,
|
|
treePath string,
|
|
) (*types.TreeNode, error) {
|
|
treePath = cleanTreePath(treePath)
|
|
|
|
giteaRepo, err := gitea.OpenRepository(ctx, repoPath)
|
|
if err != nil {
|
|
return nil, processGiteaErrorf(err, "failed to open repository")
|
|
}
|
|
defer giteaRepo.Close()
|
|
|
|
// Get the giteaCommit object for the ref
|
|
giteaCommit, err := giteaRepo.GetCommit(ref)
|
|
if err != nil {
|
|
return nil, processGiteaErrorf(err, "error getting commit for ref '%s'", ref)
|
|
}
|
|
|
|
// TODO: handle ErrNotExist :)
|
|
giteaTreeEntry, err := giteaCommit.GetTreeEntryByPath(treePath)
|
|
if err != nil {
|
|
return nil, processGiteaErrorf(err, "failed to get tree entry for commit '%s' at path '%s'",
|
|
giteaCommit.ID.String(), treePath)
|
|
}
|
|
|
|
nodeType, mode, err := mapGiteaNodeToTreeNodeModeAndType(giteaTreeEntry.Mode())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &types.TreeNode{
|
|
Mode: mode,
|
|
NodeType: nodeType,
|
|
Sha: giteaTreeEntry.ID.String(),
|
|
Name: giteaTreeEntry.Name(),
|
|
Path: treePath,
|
|
}, nil
|
|
}
|
|
|
|
// ListTreeNodes lists the child nodes of a tree reachable from ref via the specified path
|
|
// and includes the latest commit for all nodes if requested.
|
|
// Note: ref can be Branch / Tag / CommitSHA.
|
|
func (a Adapter) ListTreeNodes(
|
|
ctx context.Context,
|
|
repoPath string,
|
|
ref string,
|
|
treePath string,
|
|
) ([]types.TreeNode, error) {
|
|
treePath = cleanTreePath(treePath)
|
|
|
|
giteaRepo, err := gitea.OpenRepository(ctx, repoPath)
|
|
if err != nil {
|
|
return nil, processGiteaErrorf(err, "failed to open repository")
|
|
}
|
|
defer giteaRepo.Close()
|
|
|
|
// Get the giteaCommit object for the ref
|
|
giteaCommit, err := giteaRepo.GetCommit(ref)
|
|
if err != nil {
|
|
return nil, processGiteaErrorf(err, "error getting commit for ref '%s'", ref)
|
|
}
|
|
|
|
// Get the giteaTree object for the ref
|
|
giteaTree, err := giteaCommit.SubTree(treePath)
|
|
if err != nil {
|
|
return nil, processGiteaErrorf(err, "error getting tree for '%s'", treePath)
|
|
}
|
|
|
|
giteaEntries, err := giteaTree.ListEntries()
|
|
if err != nil {
|
|
return nil, processGiteaErrorf(err, "failed to list entries for tree '%s'", treePath)
|
|
}
|
|
|
|
nodes := make([]types.TreeNode, len(giteaEntries))
|
|
for i := range giteaEntries {
|
|
giteaEntry := giteaEntries[i]
|
|
|
|
var nodeType types.TreeNodeType
|
|
var mode types.TreeNodeMode
|
|
nodeType, mode, err = mapGiteaNodeToTreeNodeModeAndType(giteaEntry.Mode())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// giteaNode.Name() returns the path of the node relative to the tree.
|
|
relPath := giteaEntry.Name()
|
|
name := filepath.Base(relPath)
|
|
|
|
nodes[i] = types.TreeNode{
|
|
NodeType: nodeType,
|
|
Mode: mode,
|
|
Sha: giteaEntry.ID.String(),
|
|
Name: name,
|
|
Path: filepath.Join(treePath, relPath),
|
|
}
|
|
}
|
|
|
|
return nodes, nil
|
|
}
|
|
|
|
func (a Adapter) ReadTree(
|
|
ctx context.Context,
|
|
repoPath string,
|
|
ref string,
|
|
w io.Writer,
|
|
args ...string,
|
|
) error {
|
|
if repoPath == "" {
|
|
return ErrRepositoryPathEmpty
|
|
}
|
|
errbuf := bytes.Buffer{}
|
|
if err := gitea.NewCommand(ctx, append([]string{"read-tree", ref}, args...)...).
|
|
Run(&gitea.RunOpts{
|
|
Dir: repoPath,
|
|
Stdout: w,
|
|
Stderr: &errbuf,
|
|
}); err != nil {
|
|
return fmt.Errorf("unable to read %s in to the index: %w\n%s",
|
|
ref, err, errbuf.String())
|
|
}
|
|
return nil
|
|
}
|