Expose SHA1s as extended attributes. Change-Id: I71b1fbd6dd3ae475ac4f67e4a570445d2b5ddc3a
diff --git a/fs/gitilesfs.go b/fs/gitilesfs.go index 91d1a93..616b9f7 100644 --- a/fs/gitilesfs.go +++ b/fs/gitilesfs.go
@@ -120,7 +120,18 @@ return fuse.OK } -// TODO(hanwen): implement extended attributes to read the SHA1. +const xattrName = "user.gitsha1" + +func (n *gitilesNode) GetXAttr(attribute string, context *fuse.Context) (data []byte, code fuse.Status) { + if attribute != xattrName { + return nil, fuse.ENODATA + } + return []byte(n.id.String()), fuse.OK +} + +func (n *gitilesNode) ListXAttr(context *fuse.Context) (attrs []string, code fuse.Status) { + return []string{xattrName}, fuse.OK +} func (n *gitilesNode) Open(flags uint32, context *fuse.Context) (file nodefs.File, code fuse.Status) { if n.root.handleLessIO { @@ -216,6 +227,10 @@ return nodefs.NewDataFile(d.data), fuse.OK } +func (d *dataNode) GetXAttr(attribute string, context *fuse.Context) (data []byte, code fuse.Status) { + return nil, fuse.ENODATA +} + func (n *dataNode) Deletable() bool { return false } func newDataNode(c []byte) nodefs.Node { @@ -239,6 +254,10 @@ func (r *gitilesRoot) Deletable() bool { return false } +func (n *gitilesRoot) GetXAttr(attribute string, context *fuse.Context) (data []byte, code fuse.Status) { + return nil, fuse.ENODATA +} + func (r *gitilesRoot) OnMount(fsConn *nodefs.FileSystemConnector) { if err := r.onMount(fsConn); err != nil { log.Printf("onMount: %v", err)
diff --git a/fs/gitilesfs_test.go b/fs/gitilesfs_test.go index b19789c..49dc122 100644 --- a/fs/gitilesfs_test.go +++ b/fs/gitilesfs_test.go
@@ -190,6 +190,23 @@ } else if string(got) != want { t.Errorf("got %q, want %q", got, want) } + + data := make([]byte, 1024) + sz, err := syscall.Listxattr(filepath.Join(fix.mntDir, "AUTHORS"), data) + if err != nil { + t.Fatalf("Listxattr: %v", err) + } + if got, want := string(data[:sz]), xattrName+"\000"; got != want { + t.Errorf("got xattrs %q, want %q", got, want) + } + + sz, err = syscall.Getxattr(filepath.Join(fix.mntDir, "AUTHORS"), xattrName, data) + if err != nil { + t.Fatalf("Getxattr: %v", err) + } + if got, want := "787d767f94fd634ed29cd69ec9f93bab2b25f5d4", string(data[:sz]); got != want { + t.Errorf("got %q, want %q", got, want) + } } func TestGitilesFS(t *testing.T) {
diff --git a/fs/manifestfs.go b/fs/manifestfs.go index 3d5bce5..a6c8898 100644 --- a/fs/manifestfs.go +++ b/fs/manifestfs.go
@@ -23,6 +23,7 @@ "github.com/google/gitfs/cache" "github.com/google/gitfs/gitiles" "github.com/google/gitfs/manifest" + "github.com/hanwen/go-fuse/fuse" "github.com/hanwen/go-fuse/fuse/nodefs" git "github.com/libgit2/git2go" ) @@ -45,6 +46,10 @@ func (r *manifestFSRoot) Deletable() bool { return false } +func (r *manifestFSRoot) GetXAttr(attribute string, context *fuse.Context) (data []byte, code fuse.Status) { + return nil, fuse.ENODATA +} + // NewManifestFS creates a Manifest FS root node. func NewManifestFS(service *gitiles.Service, cache *cache.Cache, opts ManifestOptions) (nodefs.Node, error) { xml, err := opts.Manifest.MarshalXML()
diff --git a/fs/multifs.go b/fs/multifs.go index 57e9f98..97babe9 100644 --- a/fs/multifs.go +++ b/fs/multifs.go
@@ -56,6 +56,10 @@ func (r *multiManifestFSRoot) Deletable() bool { return false } +func (r *multiManifestFSRoot) GetXAttr(attribute string, context *fuse.Context) (data []byte, code fuse.Status) { + return nil, fuse.ENODATA +} + type configNode struct { nodefs.Node root *multiManifestFSRoot