116 lines
2.9 KiB
Go
116 lines
2.9 KiB
Go
package fstree
|
|
|
|
import (
|
|
"context"
|
|
"syscall"
|
|
|
|
"github.com/hanwen/go-fuse/v2/fs"
|
|
"github.com/hanwen/go-fuse/v2/fuse"
|
|
)
|
|
|
|
const (
|
|
groupBaseInode = 1_000_000_000
|
|
)
|
|
|
|
type groupNode struct {
|
|
fs.Inode
|
|
param *FSParam
|
|
|
|
source GroupSource
|
|
staticNodes map[string]staticNode
|
|
}
|
|
|
|
type GroupSource interface {
|
|
GetGroupID() uint64
|
|
InvalidateContentCache()
|
|
}
|
|
|
|
// Ensure we are implementing the NodeReaddirer interface
|
|
var _ = (fs.NodeReaddirer)((*groupNode)(nil))
|
|
|
|
// Ensure we are implementing the NodeLookuper interface
|
|
var _ = (fs.NodeLookuper)((*groupNode)(nil))
|
|
|
|
func newGroupNodeFromSource(source GroupSource, param *FSParam) (*groupNode, error) {
|
|
node := &groupNode{
|
|
param: param,
|
|
source: source,
|
|
staticNodes: map[string]staticNode{
|
|
".refresh": newRefreshNode(source, param),
|
|
},
|
|
}
|
|
return node, nil
|
|
}
|
|
|
|
func (n *groupNode) Readdir(ctx context.Context) (fs.DirStream, syscall.Errno) {
|
|
groups, repositories, err := n.param.GitForge.FetchGroupContent(n.source.GetGroupID())
|
|
if err != nil {
|
|
n.param.logger.Error(err.Error())
|
|
}
|
|
|
|
entries := make([]fuse.DirEntry, 0, len(groups)+len(repositories)+len(n.staticNodes))
|
|
for groupName, group := range groups {
|
|
entries = append(entries, fuse.DirEntry{
|
|
Name: groupName,
|
|
Ino: group.GetGroupID() + groupBaseInode,
|
|
Mode: fuse.S_IFDIR,
|
|
})
|
|
}
|
|
for repositoryName, repository := range repositories {
|
|
entries = append(entries, fuse.DirEntry{
|
|
Name: repositoryName,
|
|
Ino: repository.GetRepositoryID() + repositoryBaseInode,
|
|
Mode: fuse.S_IFLNK,
|
|
})
|
|
}
|
|
for name, staticNode := range n.staticNodes {
|
|
entries = append(entries, fuse.DirEntry{
|
|
Name: name,
|
|
Ino: staticNode.Ino(),
|
|
Mode: staticNode.Mode(),
|
|
})
|
|
}
|
|
return fs.NewListDirStream(entries), 0
|
|
}
|
|
|
|
func (n *groupNode) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (*fs.Inode, syscall.Errno) {
|
|
groups, repositories, err := n.param.GitForge.FetchGroupContent(n.source.GetGroupID())
|
|
if err != nil {
|
|
n.param.logger.Error(err.Error())
|
|
} else {
|
|
// Check if the map of groups contains it
|
|
group, found := groups[name]
|
|
if found {
|
|
attrs := fs.StableAttr{
|
|
Ino: group.GetGroupID() + groupBaseInode,
|
|
Mode: fuse.S_IFDIR,
|
|
}
|
|
groupNode, _ := newGroupNodeFromSource(group, n.param)
|
|
return n.NewInode(ctx, groupNode, attrs), 0
|
|
}
|
|
|
|
// Check if the map of projects contains it
|
|
repository, found := repositories[name]
|
|
if found {
|
|
attrs := fs.StableAttr{
|
|
Ino: repository.GetRepositoryID() + repositoryBaseInode,
|
|
Mode: fuse.S_IFLNK,
|
|
}
|
|
repositoryNode, _ := newRepositoryNodeFromSource(repository, n.param)
|
|
return n.NewInode(ctx, repositoryNode, attrs), 0
|
|
}
|
|
|
|
// Check if the map of static nodes contains it
|
|
staticNode, ok := n.staticNodes[name]
|
|
if ok {
|
|
attrs := fs.StableAttr{
|
|
Ino: staticNode.Ino(),
|
|
Mode: staticNode.Mode(),
|
|
}
|
|
return n.NewInode(ctx, staticNode, attrs), 0
|
|
}
|
|
}
|
|
|
|
return nil, syscall.ENOENT
|
|
}
|