refactor(snix/castore): rename proto node to entry
In the castore Rust types, nodes don't have names, they only get names my the mapping happening in a Directory struct. However, in proto land, they do, as Directories are not maps, but three (individually sorted) lists. This has caused some confusion in the past. Let's fix this, by renaming what used to be proto nodes to "Entry". We also use this "entry" in a very similar fashion in the NAR reader, describing something with a name, so this should be more consistent and understandable. There's no change in the wire representation. Change-Id: Ie6184d9a6e00c8114fc2a46bfd2bc90208a1d623 Reviewed-on: https://cl.snix.dev/c/snix/+/30296 Tested-by: besadii Reviewed-by: Vova Kryachko <v.kryachko@gmail.com> Autosubmit: Florian Klink <flokli@flokli.de>
This commit is contained in:
parent
7b20d0dac1
commit
06ffeec464
21 changed files with 365 additions and 355 deletions
|
|
@ -51,7 +51,7 @@ message BuildRequest {
|
|||
// As all references are content-addressed, no additional signatures are
|
||||
// needed to substitute / make these available in the build environment.
|
||||
// Inputs MUST be sorted by their names.
|
||||
repeated snix.castore.v1.Node inputs = 1;
|
||||
repeated snix.castore.v1.Entry inputs = 1;
|
||||
|
||||
// The command (and its args) executed as the build script.
|
||||
// In the case of a Nix derivation, this is usually
|
||||
|
|
@ -161,7 +161,7 @@ message Build {
|
|||
|
||||
// The outputs that were produced after successfully building.
|
||||
// They are sorted by their names.
|
||||
repeated snix.castore.v1.Node outputs = 2;
|
||||
repeated snix.castore.v1.Entry outputs = 2;
|
||||
|
||||
message OutputNeedles {
|
||||
// The numbers are indexing into `refscan_needles` originally specified in the BuildRequest.
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ where
|
|||
};
|
||||
|
||||
Ok::<_, std::io::Error>((
|
||||
snix_castore::proto::Node::from_name_and_node(
|
||||
snix_castore::proto::Entry::from_name_and_node(
|
||||
output_path
|
||||
.file_name()
|
||||
.and_then(|s| s.to_str())
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ impl From<crate::buildservice::BuildRequest> for BuildRequest {
|
|||
.inputs
|
||||
.into_iter()
|
||||
.map(|(name, node)| {
|
||||
snix_castore::proto::Node::from_name_and_node(name.into(), node)
|
||||
snix_castore::proto::Entry::from_name_and_node(name.into(), node)
|
||||
})
|
||||
.collect(),
|
||||
command_args: value.command_args,
|
||||
|
|
|
|||
|
|
@ -51,8 +51,8 @@ func isValidName(n []byte) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// Validate ensures a DirectoryNode has a valid name and correct digest len.
|
||||
func (n *DirectoryNode) Validate() error {
|
||||
// Validate ensures a DirectoryEntry has a valid name and correct digest len.
|
||||
func (n *DirectoryEntry) Validate() error {
|
||||
if len(n.Digest) != 32 {
|
||||
return fmt.Errorf("invalid digest length for %s, expected %d, got %d", n.Name, 32, len(n.Digest))
|
||||
}
|
||||
|
|
@ -64,8 +64,8 @@ func (n *DirectoryNode) Validate() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Validate ensures a FileNode has a valid name and correct digest len.
|
||||
func (n *FileNode) Validate() error {
|
||||
// Validate ensures a FileEntry has a valid name and correct digest len.
|
||||
func (n *FileEntry) Validate() error {
|
||||
if len(n.Digest) != 32 {
|
||||
return fmt.Errorf("invalid digest length for %s, expected %d, got %d", n.Name, 32, len(n.Digest))
|
||||
}
|
||||
|
|
@ -77,8 +77,8 @@ func (n *FileNode) Validate() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Validate ensures a SymlinkNode has a valid name and target.
|
||||
func (n *SymlinkNode) Validate() error {
|
||||
// Validate ensures a SymlinkEntry has a valid name and target.
|
||||
func (n *SymlinkEntry) Validate() error {
|
||||
if len(n.Target) == 0 || bytes.Contains(n.Target, []byte{0}) {
|
||||
return fmt.Errorf("invalid symlink target: %s", n.Target)
|
||||
}
|
||||
|
|
@ -91,7 +91,7 @@ func (n *SymlinkNode) Validate() error {
|
|||
}
|
||||
|
||||
// Validate ensures a node is valid, by dispatching to the per-type validation functions.
|
||||
func (n *Node) Validate() error {
|
||||
func (n *Entry) Validate() error {
|
||||
if node := n.GetDirectory(); node != nil {
|
||||
if err := node.Validate(); err != nil {
|
||||
return fmt.Errorf("SymlinkNode failed validation: %w", err)
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const (
|
|||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// A Directory can contain Directory, File or Symlink nodes.
|
||||
// A Directory can contain Directory, File or Symlink entries.
|
||||
// Each of these nodes have a name attribute, which is the basename in that
|
||||
// directory and node type specific attributes.
|
||||
// The name attribute:
|
||||
|
|
@ -37,9 +37,9 @@ const (
|
|||
// attribute.
|
||||
type Directory struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Directories []*DirectoryNode `protobuf:"bytes,1,rep,name=directories,proto3" json:"directories,omitempty"`
|
||||
Files []*FileNode `protobuf:"bytes,2,rep,name=files,proto3" json:"files,omitempty"`
|
||||
Symlinks []*SymlinkNode `protobuf:"bytes,3,rep,name=symlinks,proto3" json:"symlinks,omitempty"`
|
||||
Directories []*DirectoryEntry `protobuf:"bytes,1,rep,name=directories,proto3" json:"directories,omitempty"`
|
||||
Files []*FileEntry `protobuf:"bytes,2,rep,name=files,proto3" json:"files,omitempty"`
|
||||
Symlinks []*SymlinkEntry `protobuf:"bytes,3,rep,name=symlinks,proto3" json:"symlinks,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
|
@ -74,33 +74,33 @@ func (*Directory) Descriptor() ([]byte, []int) {
|
|||
return file_snix_castore_protos_castore_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Directory) GetDirectories() []*DirectoryNode {
|
||||
func (x *Directory) GetDirectories() []*DirectoryEntry {
|
||||
if x != nil {
|
||||
return x.Directories
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Directory) GetFiles() []*FileNode {
|
||||
func (x *Directory) GetFiles() []*FileEntry {
|
||||
if x != nil {
|
||||
return x.Files
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Directory) GetSymlinks() []*SymlinkNode {
|
||||
func (x *Directory) GetSymlinks() []*SymlinkEntry {
|
||||
if x != nil {
|
||||
return x.Symlinks
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// A DirectoryNode represents a directory in a Directory.
|
||||
type DirectoryNode struct {
|
||||
// A DirectoryEntry represents a directory.
|
||||
type DirectoryEntry struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// The (base)name of the directory
|
||||
Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
// The blake3 hash of a Directory message, serialized in protobuf canonical form.
|
||||
// The blake3 digest of a Directory message.
|
||||
Digest []byte `protobuf:"bytes,2,opt,name=digest,proto3" json:"digest,omitempty"`
|
||||
// Number of child elements in the Directory referred to by `digest`.
|
||||
// Calculated by summing up the numbers of `directories`, `files` and
|
||||
|
|
@ -117,20 +117,20 @@ type DirectoryNode struct {
|
|||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *DirectoryNode) Reset() {
|
||||
*x = DirectoryNode{}
|
||||
func (x *DirectoryEntry) Reset() {
|
||||
*x = DirectoryEntry{}
|
||||
mi := &file_snix_castore_protos_castore_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *DirectoryNode) String() string {
|
||||
func (x *DirectoryEntry) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*DirectoryNode) ProtoMessage() {}
|
||||
func (*DirectoryEntry) ProtoMessage() {}
|
||||
|
||||
func (x *DirectoryNode) ProtoReflect() protoreflect.Message {
|
||||
func (x *DirectoryEntry) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_snix_castore_protos_castore_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
|
|
@ -142,34 +142,34 @@ func (x *DirectoryNode) ProtoReflect() protoreflect.Message {
|
|||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use DirectoryNode.ProtoReflect.Descriptor instead.
|
||||
func (*DirectoryNode) Descriptor() ([]byte, []int) {
|
||||
// Deprecated: Use DirectoryEntry.ProtoReflect.Descriptor instead.
|
||||
func (*DirectoryEntry) Descriptor() ([]byte, []int) {
|
||||
return file_snix_castore_protos_castore_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *DirectoryNode) GetName() []byte {
|
||||
func (x *DirectoryEntry) GetName() []byte {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *DirectoryNode) GetDigest() []byte {
|
||||
func (x *DirectoryEntry) GetDigest() []byte {
|
||||
if x != nil {
|
||||
return x.Digest
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *DirectoryNode) GetSize() uint64 {
|
||||
func (x *DirectoryEntry) GetSize() uint64 {
|
||||
if x != nil {
|
||||
return x.Size
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// A FileNode represents a regular or executable file in a Directory.
|
||||
type FileNode struct {
|
||||
// A FileEntry represents a regular or executable file.
|
||||
type FileEntry struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// The (base)name of the file
|
||||
Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
|
|
@ -183,20 +183,20 @@ type FileNode struct {
|
|||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *FileNode) Reset() {
|
||||
*x = FileNode{}
|
||||
func (x *FileEntry) Reset() {
|
||||
*x = FileEntry{}
|
||||
mi := &file_snix_castore_protos_castore_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *FileNode) String() string {
|
||||
func (x *FileEntry) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*FileNode) ProtoMessage() {}
|
||||
func (*FileEntry) ProtoMessage() {}
|
||||
|
||||
func (x *FileNode) ProtoReflect() protoreflect.Message {
|
||||
func (x *FileEntry) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_snix_castore_protos_castore_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
|
|
@ -208,41 +208,41 @@ func (x *FileNode) ProtoReflect() protoreflect.Message {
|
|||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use FileNode.ProtoReflect.Descriptor instead.
|
||||
func (*FileNode) Descriptor() ([]byte, []int) {
|
||||
// Deprecated: Use FileEntry.ProtoReflect.Descriptor instead.
|
||||
func (*FileEntry) Descriptor() ([]byte, []int) {
|
||||
return file_snix_castore_protos_castore_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *FileNode) GetName() []byte {
|
||||
func (x *FileEntry) GetName() []byte {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *FileNode) GetDigest() []byte {
|
||||
func (x *FileEntry) GetDigest() []byte {
|
||||
if x != nil {
|
||||
return x.Digest
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *FileNode) GetSize() uint64 {
|
||||
func (x *FileEntry) GetSize() uint64 {
|
||||
if x != nil {
|
||||
return x.Size
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *FileNode) GetExecutable() bool {
|
||||
func (x *FileEntry) GetExecutable() bool {
|
||||
if x != nil {
|
||||
return x.Executable
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// A SymlinkNode represents a symbolic link in a Directory.
|
||||
type SymlinkNode struct {
|
||||
// A SymlinkEntry represents a symbolic link.
|
||||
type SymlinkEntry struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// The (base)name of the symlink
|
||||
Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
|
|
@ -252,20 +252,20 @@ type SymlinkNode struct {
|
|||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *SymlinkNode) Reset() {
|
||||
*x = SymlinkNode{}
|
||||
func (x *SymlinkEntry) Reset() {
|
||||
*x = SymlinkEntry{}
|
||||
mi := &file_snix_castore_protos_castore_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *SymlinkNode) String() string {
|
||||
func (x *SymlinkEntry) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*SymlinkNode) ProtoMessage() {}
|
||||
func (*SymlinkEntry) ProtoMessage() {}
|
||||
|
||||
func (x *SymlinkNode) ProtoReflect() protoreflect.Message {
|
||||
func (x *SymlinkEntry) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_snix_castore_protos_castore_proto_msgTypes[3]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
|
|
@ -277,52 +277,52 @@ func (x *SymlinkNode) ProtoReflect() protoreflect.Message {
|
|||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use SymlinkNode.ProtoReflect.Descriptor instead.
|
||||
func (*SymlinkNode) Descriptor() ([]byte, []int) {
|
||||
// Deprecated: Use SymlinkEntry.ProtoReflect.Descriptor instead.
|
||||
func (*SymlinkEntry) Descriptor() ([]byte, []int) {
|
||||
return file_snix_castore_protos_castore_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *SymlinkNode) GetName() []byte {
|
||||
func (x *SymlinkEntry) GetName() []byte {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *SymlinkNode) GetTarget() []byte {
|
||||
func (x *SymlinkEntry) GetTarget() []byte {
|
||||
if x != nil {
|
||||
return x.Target
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// A Node is either a DirectoryNode, FileNode or SymlinkNode.
|
||||
type Node struct {
|
||||
// A Entry is either a DirectoryEntry, FileEntry or SymlinkEntry.
|
||||
type Entry struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// Types that are valid to be assigned to Node:
|
||||
// Types that are valid to be assigned to Entry:
|
||||
//
|
||||
// *Node_Directory
|
||||
// *Node_File
|
||||
// *Node_Symlink
|
||||
Node isNode_Node `protobuf_oneof:"node"`
|
||||
// *Entry_Directory
|
||||
// *Entry_File
|
||||
// *Entry_Symlink
|
||||
Entry isEntry_Entry `protobuf_oneof:"entry"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Node) Reset() {
|
||||
*x = Node{}
|
||||
func (x *Entry) Reset() {
|
||||
*x = Entry{}
|
||||
mi := &file_snix_castore_protos_castore_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *Node) String() string {
|
||||
func (x *Entry) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Node) ProtoMessage() {}
|
||||
func (*Entry) ProtoMessage() {}
|
||||
|
||||
func (x *Node) ProtoReflect() protoreflect.Message {
|
||||
func (x *Entry) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_snix_castore_protos_castore_proto_msgTypes[4]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
|
|
@ -334,66 +334,66 @@ func (x *Node) ProtoReflect() protoreflect.Message {
|
|||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Node.ProtoReflect.Descriptor instead.
|
||||
func (*Node) Descriptor() ([]byte, []int) {
|
||||
// Deprecated: Use Entry.ProtoReflect.Descriptor instead.
|
||||
func (*Entry) Descriptor() ([]byte, []int) {
|
||||
return file_snix_castore_protos_castore_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *Node) GetNode() isNode_Node {
|
||||
func (x *Entry) GetEntry() isEntry_Entry {
|
||||
if x != nil {
|
||||
return x.Node
|
||||
return x.Entry
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Node) GetDirectory() *DirectoryNode {
|
||||
func (x *Entry) GetDirectory() *DirectoryEntry {
|
||||
if x != nil {
|
||||
if x, ok := x.Node.(*Node_Directory); ok {
|
||||
if x, ok := x.Entry.(*Entry_Directory); ok {
|
||||
return x.Directory
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Node) GetFile() *FileNode {
|
||||
func (x *Entry) GetFile() *FileEntry {
|
||||
if x != nil {
|
||||
if x, ok := x.Node.(*Node_File); ok {
|
||||
if x, ok := x.Entry.(*Entry_File); ok {
|
||||
return x.File
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Node) GetSymlink() *SymlinkNode {
|
||||
func (x *Entry) GetSymlink() *SymlinkEntry {
|
||||
if x != nil {
|
||||
if x, ok := x.Node.(*Node_Symlink); ok {
|
||||
if x, ok := x.Entry.(*Entry_Symlink); ok {
|
||||
return x.Symlink
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type isNode_Node interface {
|
||||
isNode_Node()
|
||||
type isEntry_Entry interface {
|
||||
isEntry_Entry()
|
||||
}
|
||||
|
||||
type Node_Directory struct {
|
||||
Directory *DirectoryNode `protobuf:"bytes,1,opt,name=directory,proto3,oneof"`
|
||||
type Entry_Directory struct {
|
||||
Directory *DirectoryEntry `protobuf:"bytes,1,opt,name=directory,proto3,oneof"`
|
||||
}
|
||||
|
||||
type Node_File struct {
|
||||
File *FileNode `protobuf:"bytes,2,opt,name=file,proto3,oneof"`
|
||||
type Entry_File struct {
|
||||
File *FileEntry `protobuf:"bytes,2,opt,name=file,proto3,oneof"`
|
||||
}
|
||||
|
||||
type Node_Symlink struct {
|
||||
Symlink *SymlinkNode `protobuf:"bytes,3,opt,name=symlink,proto3,oneof"`
|
||||
type Entry_Symlink struct {
|
||||
Symlink *SymlinkEntry `protobuf:"bytes,3,opt,name=symlink,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*Node_Directory) isNode_Node() {}
|
||||
func (*Entry_Directory) isEntry_Entry() {}
|
||||
|
||||
func (*Node_File) isNode_Node() {}
|
||||
func (*Entry_File) isEntry_Entry() {}
|
||||
|
||||
func (*Node_Symlink) isNode_Node() {}
|
||||
func (*Entry_Symlink) isEntry_Entry() {}
|
||||
|
||||
var File_snix_castore_protos_castore_proto protoreflect.FileDescriptor
|
||||
|
||||
|
|
@ -401,48 +401,49 @@ var file_snix_castore_protos_castore_proto_rawDesc = string([]byte{
|
|||
0x0a, 0x21, 0x73, 0x6e, 0x69, 0x78, 0x2f, 0x63, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x63, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x73, 0x6e, 0x69, 0x78, 0x2e, 0x63, 0x61, 0x73, 0x74, 0x6f, 0x72,
|
||||
0x65, 0x2e, 0x76, 0x31, 0x22, 0xb8, 0x01, 0x0a, 0x09, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f,
|
||||
0x72, 0x79, 0x12, 0x40, 0x0a, 0x0b, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x69, 0x65,
|
||||
0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x6e, 0x69, 0x78, 0x2e, 0x63,
|
||||
0x65, 0x2e, 0x76, 0x31, 0x22, 0xbb, 0x01, 0x0a, 0x09, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f,
|
||||
0x72, 0x79, 0x12, 0x41, 0x0a, 0x0b, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x69, 0x65,
|
||||
0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x73, 0x6e, 0x69, 0x78, 0x2e, 0x63,
|
||||
0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74,
|
||||
0x6f, 0x72, 0x79, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x0b, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f,
|
||||
0x72, 0x69, 0x65, 0x73, 0x12, 0x2f, 0x0a, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x6e, 0x69, 0x78, 0x2e, 0x63, 0x61, 0x73, 0x74, 0x6f,
|
||||
0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05,
|
||||
0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x08, 0x73, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b,
|
||||
0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x73, 0x6e, 0x69, 0x78, 0x2e, 0x63,
|
||||
0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6d, 0x6c, 0x69, 0x6e,
|
||||
0x6b, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x08, 0x73, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x22,
|
||||
0x4f, 0x0a, 0x0d, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x4e, 0x6f, 0x64, 0x65,
|
||||
0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04,
|
||||
0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65,
|
||||
0x22, 0x6a, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
|
||||
0x12, 0x16, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c,
|
||||
0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x1e, 0x0a, 0x0a,
|
||||
0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08,
|
||||
0x52, 0x0a, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x39, 0x0a, 0x0b,
|
||||
0x53, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e,
|
||||
0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
|
||||
0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52,
|
||||
0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0xb9, 0x01, 0x0a, 0x04, 0x4e, 0x6f, 0x64, 0x65,
|
||||
0x12, 0x3e, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x6e, 0x69, 0x78, 0x2e, 0x63, 0x61, 0x73, 0x74, 0x6f,
|
||||
0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x4e,
|
||||
0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79,
|
||||
0x12, 0x2f, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19,
|
||||
0x2e, 0x73, 0x6e, 0x69, 0x78, 0x2e, 0x63, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x04, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x12, 0x38, 0x0a, 0x07, 0x73, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x73, 0x6e, 0x69, 0x78, 0x2e, 0x63, 0x61, 0x73, 0x74, 0x6f, 0x72,
|
||||
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x4e, 0x6f, 0x64, 0x65,
|
||||
0x48, 0x00, 0x52, 0x07, 0x73, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x42, 0x06, 0x0a, 0x04, 0x6e,
|
||||
0x6f, 0x64, 0x65, 0x42, 0x22, 0x5a, 0x20, 0x73, 0x6e, 0x69, 0x78, 0x2e, 0x64, 0x65, 0x76, 0x2f,
|
||||
0x63, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x63, 0x61,
|
||||
0x73, 0x74, 0x6f, 0x72, 0x65, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x6f, 0x72, 0x79, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74,
|
||||
0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x02,
|
||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x6e, 0x69, 0x78, 0x2e, 0x63, 0x61, 0x73, 0x74,
|
||||
0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79,
|
||||
0x52, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x39, 0x0a, 0x08, 0x73, 0x79, 0x6d, 0x6c, 0x69,
|
||||
0x6e, 0x6b, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x6e, 0x69, 0x78,
|
||||
0x2e, 0x63, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6d, 0x6c,
|
||||
0x69, 0x6e, 0x6b, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x73, 0x79, 0x6d, 0x6c, 0x69, 0x6e,
|
||||
0x6b, 0x73, 0x22, 0x50, 0x0a, 0x0e, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x45,
|
||||
0x6e, 0x74, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0c, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65,
|
||||
0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74,
|
||||
0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04,
|
||||
0x73, 0x69, 0x7a, 0x65, 0x22, 0x6b, 0x0a, 0x09, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x6e, 0x74, 0x72,
|
||||
0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
|
||||
0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x7a,
|
||||
0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18,
|
||||
0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c,
|
||||
0x65, 0x22, 0x3a, 0x0a, 0x0c, 0x53, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x45, 0x6e, 0x74, 0x72,
|
||||
0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
|
||||
0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0xbe, 0x01,
|
||||
0x0a, 0x05, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x3f, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63,
|
||||
0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x73, 0x6e, 0x69,
|
||||
0x78, 0x2e, 0x63, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x72,
|
||||
0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x48, 0x00, 0x52, 0x09, 0x64,
|
||||
0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x30, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x6e, 0x69, 0x78, 0x2e, 0x63, 0x61,
|
||||
0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x6e, 0x74,
|
||||
0x72, 0x79, 0x48, 0x00, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x39, 0x0a, 0x07, 0x73, 0x79,
|
||||
0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x6e,
|
||||
0x69, 0x78, 0x2e, 0x63, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79,
|
||||
0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x48, 0x00, 0x52, 0x07, 0x73, 0x79,
|
||||
0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x22,
|
||||
0x5a, 0x20, 0x73, 0x6e, 0x69, 0x78, 0x2e, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x61, 0x73, 0x74, 0x6f,
|
||||
0x72, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x63, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65,
|
||||
0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
})
|
||||
|
||||
var (
|
||||
|
|
@ -460,18 +461,18 @@ func file_snix_castore_protos_castore_proto_rawDescGZIP() []byte {
|
|||
var file_snix_castore_protos_castore_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
|
||||
var file_snix_castore_protos_castore_proto_goTypes = []any{
|
||||
(*Directory)(nil), // 0: snix.castore.v1.Directory
|
||||
(*DirectoryNode)(nil), // 1: snix.castore.v1.DirectoryNode
|
||||
(*FileNode)(nil), // 2: snix.castore.v1.FileNode
|
||||
(*SymlinkNode)(nil), // 3: snix.castore.v1.SymlinkNode
|
||||
(*Node)(nil), // 4: snix.castore.v1.Node
|
||||
(*DirectoryEntry)(nil), // 1: snix.castore.v1.DirectoryEntry
|
||||
(*FileEntry)(nil), // 2: snix.castore.v1.FileEntry
|
||||
(*SymlinkEntry)(nil), // 3: snix.castore.v1.SymlinkEntry
|
||||
(*Entry)(nil), // 4: snix.castore.v1.Entry
|
||||
}
|
||||
var file_snix_castore_protos_castore_proto_depIdxs = []int32{
|
||||
1, // 0: snix.castore.v1.Directory.directories:type_name -> snix.castore.v1.DirectoryNode
|
||||
2, // 1: snix.castore.v1.Directory.files:type_name -> snix.castore.v1.FileNode
|
||||
3, // 2: snix.castore.v1.Directory.symlinks:type_name -> snix.castore.v1.SymlinkNode
|
||||
1, // 3: snix.castore.v1.Node.directory:type_name -> snix.castore.v1.DirectoryNode
|
||||
2, // 4: snix.castore.v1.Node.file:type_name -> snix.castore.v1.FileNode
|
||||
3, // 5: snix.castore.v1.Node.symlink:type_name -> snix.castore.v1.SymlinkNode
|
||||
1, // 0: snix.castore.v1.Directory.directories:type_name -> snix.castore.v1.DirectoryEntry
|
||||
2, // 1: snix.castore.v1.Directory.files:type_name -> snix.castore.v1.FileEntry
|
||||
3, // 2: snix.castore.v1.Directory.symlinks:type_name -> snix.castore.v1.SymlinkEntry
|
||||
1, // 3: snix.castore.v1.Entry.directory:type_name -> snix.castore.v1.DirectoryEntry
|
||||
2, // 4: snix.castore.v1.Entry.file:type_name -> snix.castore.v1.FileEntry
|
||||
3, // 5: snix.castore.v1.Entry.symlink:type_name -> snix.castore.v1.SymlinkEntry
|
||||
6, // [6:6] is the sub-list for method output_type
|
||||
6, // [6:6] is the sub-list for method input_type
|
||||
6, // [6:6] is the sub-list for extension type_name
|
||||
|
|
@ -485,9 +486,9 @@ func file_snix_castore_protos_castore_proto_init() {
|
|||
return
|
||||
}
|
||||
file_snix_castore_protos_castore_proto_msgTypes[4].OneofWrappers = []any{
|
||||
(*Node_Directory)(nil),
|
||||
(*Node_File)(nil),
|
||||
(*Node_Symlink)(nil),
|
||||
(*Entry_Directory)(nil),
|
||||
(*Entry_File)(nil),
|
||||
(*Entry_Symlink)(nil),
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ var (
|
|||
func TestDirectorySize(t *testing.T) {
|
||||
t.Run("empty", func(t *testing.T) {
|
||||
d := castorev1pb.Directory{
|
||||
Directories: []*castorev1pb.DirectoryNode{},
|
||||
Files: []*castorev1pb.FileNode{},
|
||||
Symlinks: []*castorev1pb.SymlinkNode{},
|
||||
Directories: []*castorev1pb.DirectoryEntry{},
|
||||
Files: []*castorev1pb.FileEntry{},
|
||||
Symlinks: []*castorev1pb.SymlinkEntry{},
|
||||
}
|
||||
|
||||
assert.Equal(t, uint64(0), d.Size())
|
||||
|
|
@ -28,13 +28,13 @@ func TestDirectorySize(t *testing.T) {
|
|||
|
||||
t.Run("containing single empty directory", func(t *testing.T) {
|
||||
d := castorev1pb.Directory{
|
||||
Directories: []*castorev1pb.DirectoryNode{{
|
||||
Directories: []*castorev1pb.DirectoryEntry{{
|
||||
Name: []byte([]byte("foo")),
|
||||
Digest: dummyDigest,
|
||||
Size: 0,
|
||||
}},
|
||||
Files: []*castorev1pb.FileNode{},
|
||||
Symlinks: []*castorev1pb.SymlinkNode{},
|
||||
Files: []*castorev1pb.FileEntry{},
|
||||
Symlinks: []*castorev1pb.SymlinkEntry{},
|
||||
}
|
||||
|
||||
assert.Equal(t, uint64(1), d.Size())
|
||||
|
|
@ -42,13 +42,13 @@ func TestDirectorySize(t *testing.T) {
|
|||
|
||||
t.Run("containing single non-empty directory", func(t *testing.T) {
|
||||
d := castorev1pb.Directory{
|
||||
Directories: []*castorev1pb.DirectoryNode{{
|
||||
Directories: []*castorev1pb.DirectoryEntry{{
|
||||
Name: []byte("foo"),
|
||||
Digest: dummyDigest,
|
||||
Size: 4,
|
||||
}},
|
||||
Files: []*castorev1pb.FileNode{},
|
||||
Symlinks: []*castorev1pb.SymlinkNode{},
|
||||
Files: []*castorev1pb.FileEntry{},
|
||||
Symlinks: []*castorev1pb.SymlinkEntry{},
|
||||
}
|
||||
|
||||
assert.Equal(t, uint64(5), d.Size())
|
||||
|
|
@ -56,14 +56,14 @@ func TestDirectorySize(t *testing.T) {
|
|||
|
||||
t.Run("containing single file", func(t *testing.T) {
|
||||
d := castorev1pb.Directory{
|
||||
Directories: []*castorev1pb.DirectoryNode{},
|
||||
Files: []*castorev1pb.FileNode{{
|
||||
Directories: []*castorev1pb.DirectoryEntry{},
|
||||
Files: []*castorev1pb.FileEntry{{
|
||||
Name: []byte("foo"),
|
||||
Digest: dummyDigest,
|
||||
Size: 42,
|
||||
Executable: false,
|
||||
}},
|
||||
Symlinks: []*castorev1pb.SymlinkNode{},
|
||||
Symlinks: []*castorev1pb.SymlinkEntry{},
|
||||
}
|
||||
|
||||
assert.Equal(t, uint64(1), d.Size())
|
||||
|
|
@ -71,9 +71,9 @@ func TestDirectorySize(t *testing.T) {
|
|||
|
||||
t.Run("containing single symlink", func(t *testing.T) {
|
||||
d := castorev1pb.Directory{
|
||||
Directories: []*castorev1pb.DirectoryNode{},
|
||||
Files: []*castorev1pb.FileNode{},
|
||||
Symlinks: []*castorev1pb.SymlinkNode{{
|
||||
Directories: []*castorev1pb.DirectoryEntry{},
|
||||
Files: []*castorev1pb.FileEntry{},
|
||||
Symlinks: []*castorev1pb.SymlinkEntry{{
|
||||
Name: []byte("foo"),
|
||||
Target: []byte("bar"),
|
||||
}},
|
||||
|
|
@ -85,9 +85,9 @@ func TestDirectorySize(t *testing.T) {
|
|||
}
|
||||
func TestDirectoryDigest(t *testing.T) {
|
||||
d := castorev1pb.Directory{
|
||||
Directories: []*castorev1pb.DirectoryNode{},
|
||||
Files: []*castorev1pb.FileNode{},
|
||||
Symlinks: []*castorev1pb.SymlinkNode{},
|
||||
Directories: []*castorev1pb.DirectoryEntry{},
|
||||
Files: []*castorev1pb.FileEntry{},
|
||||
Symlinks: []*castorev1pb.SymlinkEntry{},
|
||||
}
|
||||
|
||||
dgst, err := d.Digest()
|
||||
|
|
@ -102,9 +102,9 @@ func TestDirectoryDigest(t *testing.T) {
|
|||
func TestDirectoryValidate(t *testing.T) {
|
||||
t.Run("empty", func(t *testing.T) {
|
||||
d := castorev1pb.Directory{
|
||||
Directories: []*castorev1pb.DirectoryNode{},
|
||||
Files: []*castorev1pb.FileNode{},
|
||||
Symlinks: []*castorev1pb.SymlinkNode{},
|
||||
Directories: []*castorev1pb.DirectoryEntry{},
|
||||
Files: []*castorev1pb.FileEntry{},
|
||||
Symlinks: []*castorev1pb.SymlinkEntry{},
|
||||
}
|
||||
|
||||
assert.NoError(t, d.Validate())
|
||||
|
|
@ -113,49 +113,49 @@ func TestDirectoryValidate(t *testing.T) {
|
|||
t.Run("invalid names", func(t *testing.T) {
|
||||
{
|
||||
d := castorev1pb.Directory{
|
||||
Directories: []*castorev1pb.DirectoryNode{{
|
||||
Directories: []*castorev1pb.DirectoryEntry{{
|
||||
Name: []byte{},
|
||||
Digest: dummyDigest,
|
||||
Size: 42,
|
||||
}},
|
||||
Files: []*castorev1pb.FileNode{},
|
||||
Symlinks: []*castorev1pb.SymlinkNode{},
|
||||
Files: []*castorev1pb.FileEntry{},
|
||||
Symlinks: []*castorev1pb.SymlinkEntry{},
|
||||
}
|
||||
|
||||
assert.ErrorContains(t, d.Validate(), "invalid node name")
|
||||
}
|
||||
{
|
||||
d := castorev1pb.Directory{
|
||||
Directories: []*castorev1pb.DirectoryNode{{
|
||||
Directories: []*castorev1pb.DirectoryEntry{{
|
||||
Name: []byte("."),
|
||||
Digest: dummyDigest,
|
||||
Size: 42,
|
||||
}},
|
||||
Files: []*castorev1pb.FileNode{},
|
||||
Symlinks: []*castorev1pb.SymlinkNode{},
|
||||
Files: []*castorev1pb.FileEntry{},
|
||||
Symlinks: []*castorev1pb.SymlinkEntry{},
|
||||
}
|
||||
|
||||
assert.ErrorContains(t, d.Validate(), "invalid node name")
|
||||
}
|
||||
{
|
||||
d := castorev1pb.Directory{
|
||||
Directories: []*castorev1pb.DirectoryNode{},
|
||||
Files: []*castorev1pb.FileNode{{
|
||||
Directories: []*castorev1pb.DirectoryEntry{},
|
||||
Files: []*castorev1pb.FileEntry{{
|
||||
Name: []byte(".."),
|
||||
Digest: dummyDigest,
|
||||
Size: 42,
|
||||
Executable: false,
|
||||
}},
|
||||
Symlinks: []*castorev1pb.SymlinkNode{},
|
||||
Symlinks: []*castorev1pb.SymlinkEntry{},
|
||||
}
|
||||
|
||||
assert.ErrorContains(t, d.Validate(), "invalid node name")
|
||||
}
|
||||
{
|
||||
d := castorev1pb.Directory{
|
||||
Directories: []*castorev1pb.DirectoryNode{},
|
||||
Files: []*castorev1pb.FileNode{},
|
||||
Symlinks: []*castorev1pb.SymlinkNode{{
|
||||
Directories: []*castorev1pb.DirectoryEntry{},
|
||||
Files: []*castorev1pb.FileEntry{},
|
||||
Symlinks: []*castorev1pb.SymlinkEntry{{
|
||||
Name: []byte("\x00"),
|
||||
Target: []byte("foo"),
|
||||
}},
|
||||
|
|
@ -165,9 +165,9 @@ func TestDirectoryValidate(t *testing.T) {
|
|||
}
|
||||
{
|
||||
d := castorev1pb.Directory{
|
||||
Directories: []*castorev1pb.DirectoryNode{},
|
||||
Files: []*castorev1pb.FileNode{},
|
||||
Symlinks: []*castorev1pb.SymlinkNode{{
|
||||
Directories: []*castorev1pb.DirectoryEntry{},
|
||||
Files: []*castorev1pb.FileEntry{},
|
||||
Symlinks: []*castorev1pb.SymlinkEntry{{
|
||||
Name: []byte("foo/bar"),
|
||||
Target: []byte("foo"),
|
||||
}},
|
||||
|
|
@ -179,13 +179,13 @@ func TestDirectoryValidate(t *testing.T) {
|
|||
|
||||
t.Run("invalid digest", func(t *testing.T) {
|
||||
d := castorev1pb.Directory{
|
||||
Directories: []*castorev1pb.DirectoryNode{{
|
||||
Directories: []*castorev1pb.DirectoryEntry{{
|
||||
Name: []byte("foo"),
|
||||
Digest: nil,
|
||||
Size: 42,
|
||||
}},
|
||||
Files: []*castorev1pb.FileNode{},
|
||||
Symlinks: []*castorev1pb.SymlinkNode{},
|
||||
Files: []*castorev1pb.FileEntry{},
|
||||
Symlinks: []*castorev1pb.SymlinkEntry{},
|
||||
}
|
||||
|
||||
assert.ErrorContains(t, d.Validate(), "invalid digest length")
|
||||
|
|
@ -194,9 +194,9 @@ func TestDirectoryValidate(t *testing.T) {
|
|||
t.Run("invalid symlink targets", func(t *testing.T) {
|
||||
{
|
||||
d := castorev1pb.Directory{
|
||||
Directories: []*castorev1pb.DirectoryNode{},
|
||||
Files: []*castorev1pb.FileNode{},
|
||||
Symlinks: []*castorev1pb.SymlinkNode{{
|
||||
Directories: []*castorev1pb.DirectoryEntry{},
|
||||
Files: []*castorev1pb.FileEntry{},
|
||||
Symlinks: []*castorev1pb.SymlinkEntry{{
|
||||
Name: []byte("foo"),
|
||||
Target: []byte{},
|
||||
}},
|
||||
|
|
@ -206,9 +206,9 @@ func TestDirectoryValidate(t *testing.T) {
|
|||
}
|
||||
{
|
||||
d := castorev1pb.Directory{
|
||||
Directories: []*castorev1pb.DirectoryNode{},
|
||||
Files: []*castorev1pb.FileNode{},
|
||||
Symlinks: []*castorev1pb.SymlinkNode{{
|
||||
Directories: []*castorev1pb.DirectoryEntry{},
|
||||
Files: []*castorev1pb.FileEntry{},
|
||||
Symlinks: []*castorev1pb.SymlinkEntry{{
|
||||
Name: []byte("foo"),
|
||||
Target: []byte{0x66, 0x6f, 0x6f, 0},
|
||||
}},
|
||||
|
|
@ -222,7 +222,7 @@ func TestDirectoryValidate(t *testing.T) {
|
|||
// "b" comes before "a", bad.
|
||||
{
|
||||
d := castorev1pb.Directory{
|
||||
Directories: []*castorev1pb.DirectoryNode{{
|
||||
Directories: []*castorev1pb.DirectoryEntry{{
|
||||
Name: []byte("b"),
|
||||
Digest: dummyDigest,
|
||||
Size: 42,
|
||||
|
|
@ -231,8 +231,8 @@ func TestDirectoryValidate(t *testing.T) {
|
|||
Digest: dummyDigest,
|
||||
Size: 42,
|
||||
}},
|
||||
Files: []*castorev1pb.FileNode{},
|
||||
Symlinks: []*castorev1pb.SymlinkNode{},
|
||||
Files: []*castorev1pb.FileEntry{},
|
||||
Symlinks: []*castorev1pb.SymlinkEntry{},
|
||||
}
|
||||
assert.ErrorContains(t, d.Validate(), "is not in sorted order")
|
||||
}
|
||||
|
|
@ -240,18 +240,18 @@ func TestDirectoryValidate(t *testing.T) {
|
|||
// "a" exists twice, bad.
|
||||
{
|
||||
d := castorev1pb.Directory{
|
||||
Directories: []*castorev1pb.DirectoryNode{{
|
||||
Directories: []*castorev1pb.DirectoryEntry{{
|
||||
Name: []byte("a"),
|
||||
Digest: dummyDigest,
|
||||
Size: 42,
|
||||
}},
|
||||
Files: []*castorev1pb.FileNode{{
|
||||
Files: []*castorev1pb.FileEntry{{
|
||||
Name: []byte("a"),
|
||||
Digest: dummyDigest,
|
||||
Size: 42,
|
||||
Executable: false,
|
||||
}},
|
||||
Symlinks: []*castorev1pb.SymlinkNode{},
|
||||
Symlinks: []*castorev1pb.SymlinkEntry{},
|
||||
}
|
||||
assert.ErrorContains(t, d.Validate(), "duplicate name")
|
||||
}
|
||||
|
|
@ -259,7 +259,7 @@ func TestDirectoryValidate(t *testing.T) {
|
|||
// "a" comes before "b", all good.
|
||||
{
|
||||
d := castorev1pb.Directory{
|
||||
Directories: []*castorev1pb.DirectoryNode{{
|
||||
Directories: []*castorev1pb.DirectoryEntry{{
|
||||
Name: []byte("a"),
|
||||
Digest: dummyDigest,
|
||||
Size: 42,
|
||||
|
|
@ -268,8 +268,8 @@ func TestDirectoryValidate(t *testing.T) {
|
|||
Digest: dummyDigest,
|
||||
Size: 42,
|
||||
}},
|
||||
Files: []*castorev1pb.FileNode{},
|
||||
Symlinks: []*castorev1pb.SymlinkNode{},
|
||||
Files: []*castorev1pb.FileEntry{},
|
||||
Symlinks: []*castorev1pb.SymlinkEntry{},
|
||||
}
|
||||
assert.NoError(t, d.Validate(), "shouldn't error")
|
||||
}
|
||||
|
|
@ -277,7 +277,7 @@ func TestDirectoryValidate(t *testing.T) {
|
|||
// [b, c] and [a] are both properly sorted.
|
||||
{
|
||||
d := castorev1pb.Directory{
|
||||
Directories: []*castorev1pb.DirectoryNode{{
|
||||
Directories: []*castorev1pb.DirectoryEntry{{
|
||||
Name: []byte("b"),
|
||||
Digest: dummyDigest,
|
||||
Size: 42,
|
||||
|
|
@ -286,8 +286,8 @@ func TestDirectoryValidate(t *testing.T) {
|
|||
Digest: dummyDigest,
|
||||
Size: 42,
|
||||
}},
|
||||
Files: []*castorev1pb.FileNode{},
|
||||
Symlinks: []*castorev1pb.SymlinkNode{{
|
||||
Files: []*castorev1pb.FileEntry{},
|
||||
Symlinks: []*castorev1pb.SymlinkEntry{{
|
||||
Name: []byte("a"),
|
||||
Target: []byte("foo"),
|
||||
}},
|
||||
|
|
|
|||
38
snix/castore-go/rename_entry.go
Normal file
38
snix/castore-go/rename_entry.go
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
package castorev1
|
||||
|
||||
// RenamedEntry returns an entry with a new name.
|
||||
func RenamedEntry(entry *Entry, name string) *Entry {
|
||||
if directoryEntry := entry.GetDirectory(); directoryEntry != nil {
|
||||
return &Entry{
|
||||
Entry: &Entry_Directory{
|
||||
Directory: &DirectoryEntry{
|
||||
Name: []byte(name),
|
||||
Digest: directoryEntry.GetDigest(),
|
||||
Size: directoryEntry.GetSize(),
|
||||
},
|
||||
},
|
||||
}
|
||||
} else if fileEntry := entry.GetFile(); fileEntry != nil {
|
||||
return &Entry{
|
||||
Entry: &Entry_File{
|
||||
File: &FileEntry{
|
||||
Name: []byte(name),
|
||||
Digest: fileEntry.GetDigest(),
|
||||
Size: fileEntry.GetSize(),
|
||||
Executable: fileEntry.GetExecutable(),
|
||||
},
|
||||
},
|
||||
}
|
||||
} else if symlinkEntry := entry.GetSymlink(); symlinkEntry != nil {
|
||||
return &Entry{
|
||||
Entry: &Entry_Symlink{
|
||||
Symlink: &SymlinkEntry{
|
||||
Name: []byte(name),
|
||||
Target: symlinkEntry.GetTarget(),
|
||||
},
|
||||
},
|
||||
}
|
||||
} else {
|
||||
panic("unreachable")
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
package castorev1
|
||||
|
||||
// RenamedNode returns a node with a new name.
|
||||
func RenamedNode(node *Node, name string) *Node {
|
||||
if directoryNode := node.GetDirectory(); directoryNode != nil {
|
||||
return &Node{
|
||||
Node: &Node_Directory{
|
||||
Directory: &DirectoryNode{
|
||||
Name: []byte(name),
|
||||
Digest: directoryNode.GetDigest(),
|
||||
Size: directoryNode.GetSize(),
|
||||
},
|
||||
},
|
||||
}
|
||||
} else if fileNode := node.GetFile(); fileNode != nil {
|
||||
return &Node{
|
||||
Node: &Node_File{
|
||||
File: &FileNode{
|
||||
Name: []byte(name),
|
||||
Digest: fileNode.GetDigest(),
|
||||
Size: fileNode.GetSize(),
|
||||
Executable: fileNode.GetExecutable(),
|
||||
},
|
||||
},
|
||||
}
|
||||
} else if symlinkNode := node.GetSymlink(); symlinkNode != nil {
|
||||
return &Node{
|
||||
Node: &Node_Symlink{
|
||||
Symlink: &SymlinkNode{
|
||||
Name: []byte(name),
|
||||
Target: symlinkNode.GetTarget(),
|
||||
},
|
||||
},
|
||||
}
|
||||
} else {
|
||||
panic("unreachable")
|
||||
}
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@ package snix.castore.v1;
|
|||
|
||||
option go_package = "snix.dev/castore/proto;castorev1";
|
||||
|
||||
// A Directory can contain Directory, File or Symlink nodes.
|
||||
// A Directory can contain Directory, File or Symlink entries.
|
||||
// Each of these nodes have a name attribute, which is the basename in that
|
||||
// directory and node type specific attributes.
|
||||
// The name attribute:
|
||||
|
|
@ -18,16 +18,16 @@ option go_package = "snix.dev/castore/proto;castorev1";
|
|||
// Elements in each list need to be lexicographically ordered by the name
|
||||
// attribute.
|
||||
message Directory {
|
||||
repeated DirectoryNode directories = 1;
|
||||
repeated FileNode files = 2;
|
||||
repeated SymlinkNode symlinks = 3;
|
||||
repeated DirectoryEntry directories = 1;
|
||||
repeated FileEntry files = 2;
|
||||
repeated SymlinkEntry symlinks = 3;
|
||||
}
|
||||
|
||||
// A DirectoryNode represents a directory in a Directory.
|
||||
message DirectoryNode {
|
||||
// A DirectoryEntry represents a directory.
|
||||
message DirectoryEntry {
|
||||
// The (base)name of the directory
|
||||
bytes name = 1;
|
||||
// The blake3 hash of a Directory message, serialized in protobuf canonical form.
|
||||
// The blake3 digest of a Directory message.
|
||||
bytes digest = 2;
|
||||
// Number of child elements in the Directory referred to by `digest`.
|
||||
// Calculated by summing up the numbers of `directories`, `files` and
|
||||
|
|
@ -42,8 +42,8 @@ message DirectoryNode {
|
|||
uint64 size = 3;
|
||||
}
|
||||
|
||||
// A FileNode represents a regular or executable file in a Directory.
|
||||
message FileNode {
|
||||
// A FileEntry represents a regular or executable file.
|
||||
message FileEntry {
|
||||
// The (base)name of the file
|
||||
bytes name = 1;
|
||||
// The blake3 digest of the file contents
|
||||
|
|
@ -54,19 +54,19 @@ message FileNode {
|
|||
bool executable = 4;
|
||||
}
|
||||
|
||||
// A SymlinkNode represents a symbolic link in a Directory.
|
||||
message SymlinkNode {
|
||||
// A SymlinkEntry represents a symbolic link.
|
||||
message SymlinkEntry {
|
||||
// The (base)name of the symlink
|
||||
bytes name = 1;
|
||||
// The target of the symlink.
|
||||
bytes target = 2;
|
||||
}
|
||||
|
||||
// A Node is either a DirectoryNode, FileNode or SymlinkNode.
|
||||
message Node {
|
||||
oneof node {
|
||||
DirectoryNode directory = 1;
|
||||
FileNode file = 2;
|
||||
SymlinkNode symlink = 3;
|
||||
// A Entry is either a DirectoryEntry, FileEntry or SymlinkEntry.
|
||||
message Entry {
|
||||
oneof entry {
|
||||
DirectoryEntry directory = 1;
|
||||
FileEntry file = 2;
|
||||
SymlinkEntry symlink = 3;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,9 +59,9 @@ pub enum DirectoryError {
|
|||
/// Elements are not in sorted order. Can only happen on protos
|
||||
#[error("{:?} is not sorted", .0.as_bstr())]
|
||||
WrongSorting(bytes::Bytes),
|
||||
/// This can only happen if there's an unknown node type (on protos)
|
||||
#[error("No node set")]
|
||||
NoNodeSet,
|
||||
/// This can only happen if there's an unknown entry type (on protos)
|
||||
#[error("No entry set")]
|
||||
NoEntrySet,
|
||||
}
|
||||
|
||||
impl From<JoinError> for Error {
|
||||
|
|
|
|||
|
|
@ -121,8 +121,8 @@ impl TryFrom<Directory> for crate::Directory {
|
|||
|
||||
for e in value.directories {
|
||||
elems.push(
|
||||
Node {
|
||||
node: Some(node::Node::Directory(e)),
|
||||
Entry {
|
||||
entry: Some(entry::Entry::Directory(e)),
|
||||
}
|
||||
.try_into_name_and_node()?,
|
||||
);
|
||||
|
|
@ -130,8 +130,8 @@ impl TryFrom<Directory> for crate::Directory {
|
|||
|
||||
for e in value.files {
|
||||
elems.push(
|
||||
Node {
|
||||
node: Some(node::Node::File(e)),
|
||||
Entry {
|
||||
entry: Some(entry::Entry::File(e)),
|
||||
}
|
||||
.try_into_name_and_node()?,
|
||||
)
|
||||
|
|
@ -139,8 +139,8 @@ impl TryFrom<Directory> for crate::Directory {
|
|||
|
||||
for e in value.symlinks {
|
||||
elems.push(
|
||||
Node {
|
||||
node: Some(node::Node::Symlink(e)),
|
||||
Entry {
|
||||
entry: Some(entry::Entry::Symlink(e)),
|
||||
}
|
||||
.try_into_name_and_node()?,
|
||||
)
|
||||
|
|
@ -162,19 +162,19 @@ impl From<crate::Directory> for Directory {
|
|||
digest,
|
||||
size,
|
||||
executable,
|
||||
} => files.push(FileNode {
|
||||
} => files.push(FileEntry {
|
||||
name: name.into(),
|
||||
digest: digest.into(),
|
||||
size,
|
||||
executable,
|
||||
}),
|
||||
crate::Node::Directory { digest, size } => directories.push(DirectoryNode {
|
||||
crate::Node::Directory { digest, size } => directories.push(DirectoryEntry {
|
||||
name: name.into(),
|
||||
digest: digest.into(),
|
||||
size,
|
||||
}),
|
||||
crate::Node::Symlink { target } => {
|
||||
symlinks.push(SymlinkNode {
|
||||
symlinks.push(SymlinkEntry {
|
||||
name: name.into(),
|
||||
target: target.into(),
|
||||
});
|
||||
|
|
@ -190,7 +190,7 @@ impl From<crate::Directory> for Directory {
|
|||
}
|
||||
}
|
||||
|
||||
impl Node {
|
||||
impl Entry {
|
||||
/// Converts a proto [Node] to a [crate::Node], and splits off the name as a [PathComponent].
|
||||
pub fn try_into_name_and_node(self) -> Result<(PathComponent, crate::Node), DirectoryError> {
|
||||
let (name_bytes, node) = self.try_into_unchecked_name_and_checked_node()?;
|
||||
|
|
@ -205,8 +205,8 @@ impl Node {
|
|||
fn try_into_unchecked_name_and_checked_node(
|
||||
self,
|
||||
) -> Result<(bytes::Bytes, crate::Node), DirectoryError> {
|
||||
match self.node.ok_or_else(|| DirectoryError::NoNodeSet)? {
|
||||
node::Node::Directory(n) => {
|
||||
match self.entry.ok_or_else(|| DirectoryError::NoEntrySet)? {
|
||||
entry::Entry::Directory(n) => {
|
||||
let digest = B3Digest::try_from(n.digest)
|
||||
.map_err(|e| DirectoryError::InvalidNode(n.name.clone(), e.into()))?;
|
||||
|
||||
|
|
@ -217,7 +217,7 @@ impl Node {
|
|||
|
||||
Ok((n.name, node))
|
||||
}
|
||||
node::Node::File(n) => {
|
||||
entry::Entry::File(n) => {
|
||||
let digest = B3Digest::try_from(n.digest)
|
||||
.map_err(|e| DirectoryError::InvalidNode(n.name.clone(), e.into()))?;
|
||||
|
||||
|
|
@ -230,7 +230,7 @@ impl Node {
|
|||
Ok((n.name, node))
|
||||
}
|
||||
|
||||
node::Node::Symlink(n) => {
|
||||
entry::Entry::Symlink(n) => {
|
||||
let node = crate::Node::Symlink {
|
||||
target: n.target.try_into().map_err(|e| {
|
||||
DirectoryError::InvalidNode(
|
||||
|
|
@ -259,13 +259,13 @@ impl Node {
|
|||
Ok(node)
|
||||
}
|
||||
|
||||
/// Constructs a [Node] from a name and [crate::Node].
|
||||
/// Constructs an [Entry] from a name and [crate::Node].
|
||||
/// The name is a [bytes::Bytes], not a [PathComponent], as we have use an
|
||||
/// empty name in some places.
|
||||
pub fn from_name_and_node(name: bytes::Bytes, n: crate::Node) -> Self {
|
||||
match n {
|
||||
crate::Node::Directory { digest, size } => Self {
|
||||
node: Some(node::Node::Directory(DirectoryNode {
|
||||
entry: Some(entry::Entry::Directory(DirectoryEntry {
|
||||
name,
|
||||
digest: digest.into(),
|
||||
size,
|
||||
|
|
@ -276,7 +276,7 @@ impl Node {
|
|||
size,
|
||||
executable,
|
||||
} => Self {
|
||||
node: Some(node::Node::File(FileNode {
|
||||
entry: Some(entry::Entry::File(FileEntry {
|
||||
name,
|
||||
digest: digest.into(),
|
||||
size,
|
||||
|
|
@ -284,7 +284,7 @@ impl Node {
|
|||
})),
|
||||
},
|
||||
crate::Node::Symlink { target } => Self {
|
||||
node: Some(node::Node::Symlink(SymlinkNode {
|
||||
entry: Some(entry::Entry::Symlink(SymlinkEntry {
|
||||
name,
|
||||
target: target.into(),
|
||||
})),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::proto::{Directory, DirectoryError, DirectoryNode, FileNode, SymlinkNode};
|
||||
use crate::proto::{Directory, DirectoryEntry, DirectoryError, FileEntry, SymlinkEntry};
|
||||
use crate::ValidateNodeError;
|
||||
|
||||
use hex_literal::hex;
|
||||
|
|
@ -13,7 +13,7 @@ fn size() {
|
|||
}
|
||||
{
|
||||
let d = Directory {
|
||||
directories: vec![DirectoryNode {
|
||||
directories: vec![DirectoryEntry {
|
||||
name: "foo".into(),
|
||||
digest: DUMMY_DIGEST.to_vec().into(),
|
||||
size: 0,
|
||||
|
|
@ -24,7 +24,7 @@ fn size() {
|
|||
}
|
||||
{
|
||||
let d = Directory {
|
||||
directories: vec![DirectoryNode {
|
||||
directories: vec![DirectoryEntry {
|
||||
name: "foo".into(),
|
||||
digest: DUMMY_DIGEST.to_vec().into(),
|
||||
size: 4,
|
||||
|
|
@ -35,7 +35,7 @@ fn size() {
|
|||
}
|
||||
{
|
||||
let d = Directory {
|
||||
files: vec![FileNode {
|
||||
files: vec![FileEntry {
|
||||
name: "foo".into(),
|
||||
digest: DUMMY_DIGEST.to_vec().into(),
|
||||
size: 42,
|
||||
|
|
@ -47,7 +47,7 @@ fn size() {
|
|||
}
|
||||
{
|
||||
let d = Directory {
|
||||
symlinks: vec![SymlinkNode {
|
||||
symlinks: vec![SymlinkEntry {
|
||||
name: "foo".into(),
|
||||
target: "bar".into(),
|
||||
}],
|
||||
|
|
@ -62,7 +62,7 @@ fn size() {
|
|||
#[should_panic = "Directory::size exceeds u64::MAX"]
|
||||
fn size_unchecked_panic() {
|
||||
let d = Directory {
|
||||
directories: vec![DirectoryNode {
|
||||
directories: vec![DirectoryEntry {
|
||||
name: "foo".into(),
|
||||
digest: DUMMY_DIGEST.to_vec().into(),
|
||||
size: u64::MAX,
|
||||
|
|
@ -77,7 +77,7 @@ fn size_unchecked_panic() {
|
|||
#[cfg_attr(debug_assertions, ignore)]
|
||||
fn size_unchecked_saturate() {
|
||||
let d = Directory {
|
||||
directories: vec![DirectoryNode {
|
||||
directories: vec![DirectoryEntry {
|
||||
name: "foo".into(),
|
||||
digest: DUMMY_DIGEST.to_vec().into(),
|
||||
size: u64::MAX,
|
||||
|
|
@ -94,7 +94,7 @@ fn size_checked() {
|
|||
// child count, since that would take an absurd amount of memory.
|
||||
{
|
||||
let d = Directory {
|
||||
directories: vec![DirectoryNode {
|
||||
directories: vec![DirectoryEntry {
|
||||
name: "foo".into(),
|
||||
digest: DUMMY_DIGEST.to_vec().into(),
|
||||
size: u64::MAX - 1,
|
||||
|
|
@ -105,7 +105,7 @@ fn size_checked() {
|
|||
}
|
||||
{
|
||||
let d = Directory {
|
||||
directories: vec![DirectoryNode {
|
||||
directories: vec![DirectoryEntry {
|
||||
name: "foo".into(),
|
||||
digest: DUMMY_DIGEST.to_vec().into(),
|
||||
size: u64::MAX,
|
||||
|
|
@ -117,12 +117,12 @@ fn size_checked() {
|
|||
{
|
||||
let d = Directory {
|
||||
directories: vec![
|
||||
DirectoryNode {
|
||||
DirectoryEntry {
|
||||
name: "foo".into(),
|
||||
digest: DUMMY_DIGEST.to_vec().into(),
|
||||
size: u64::MAX / 2,
|
||||
},
|
||||
DirectoryNode {
|
||||
DirectoryEntry {
|
||||
name: "foo".into(),
|
||||
digest: DUMMY_DIGEST.to_vec().into(),
|
||||
size: u64::MAX / 2,
|
||||
|
|
@ -154,7 +154,7 @@ fn validate_empty() {
|
|||
fn validate_invalid_names() {
|
||||
{
|
||||
let d = Directory {
|
||||
directories: vec![DirectoryNode {
|
||||
directories: vec![DirectoryEntry {
|
||||
name: b"\0"[..].into(),
|
||||
digest: DUMMY_DIGEST.to_vec().into(),
|
||||
size: 42,
|
||||
|
|
@ -168,7 +168,7 @@ fn validate_invalid_names() {
|
|||
|
||||
{
|
||||
let d = Directory {
|
||||
directories: vec![DirectoryNode {
|
||||
directories: vec![DirectoryEntry {
|
||||
name: ".".into(),
|
||||
digest: DUMMY_DIGEST.to_vec().into(),
|
||||
size: 42,
|
||||
|
|
@ -181,7 +181,7 @@ fn validate_invalid_names() {
|
|||
|
||||
{
|
||||
let d = Directory {
|
||||
files: vec![FileNode {
|
||||
files: vec![FileEntry {
|
||||
name: "..".into(),
|
||||
digest: DUMMY_DIGEST.to_vec().into(),
|
||||
size: 42,
|
||||
|
|
@ -195,7 +195,7 @@ fn validate_invalid_names() {
|
|||
|
||||
{
|
||||
let d = Directory {
|
||||
symlinks: vec![SymlinkNode {
|
||||
symlinks: vec![SymlinkEntry {
|
||||
name: "\x00".into(),
|
||||
target: "foo".into(),
|
||||
}],
|
||||
|
|
@ -207,7 +207,7 @@ fn validate_invalid_names() {
|
|||
|
||||
{
|
||||
let d = Directory {
|
||||
symlinks: vec![SymlinkNode {
|
||||
symlinks: vec![SymlinkEntry {
|
||||
name: "foo/bar".into(),
|
||||
target: "foo".into(),
|
||||
}],
|
||||
|
|
@ -219,7 +219,7 @@ fn validate_invalid_names() {
|
|||
|
||||
{
|
||||
let d = Directory {
|
||||
symlinks: vec![SymlinkNode {
|
||||
symlinks: vec![SymlinkEntry {
|
||||
name: bytes::Bytes::copy_from_slice("X".repeat(500).into_bytes().as_slice()),
|
||||
target: "foo".into(),
|
||||
}],
|
||||
|
|
@ -233,7 +233,7 @@ fn validate_invalid_names() {
|
|||
#[test]
|
||||
fn validate_invalid_digest() {
|
||||
let d = Directory {
|
||||
directories: vec![DirectoryNode {
|
||||
directories: vec![DirectoryEntry {
|
||||
name: "foo".into(),
|
||||
digest: vec![0x00, 0x42].into(), // invalid length
|
||||
size: 42,
|
||||
|
|
@ -254,12 +254,12 @@ fn validate_sorting() {
|
|||
{
|
||||
let d = Directory {
|
||||
directories: vec![
|
||||
DirectoryNode {
|
||||
DirectoryEntry {
|
||||
name: "b".into(),
|
||||
digest: DUMMY_DIGEST.to_vec().into(),
|
||||
size: 42,
|
||||
},
|
||||
DirectoryNode {
|
||||
DirectoryEntry {
|
||||
name: "a".into(),
|
||||
digest: DUMMY_DIGEST.to_vec().into(),
|
||||
size: 42,
|
||||
|
|
@ -279,12 +279,12 @@ fn validate_sorting() {
|
|||
{
|
||||
let d = Directory {
|
||||
directories: vec![
|
||||
DirectoryNode {
|
||||
DirectoryEntry {
|
||||
name: "a".into(),
|
||||
digest: DUMMY_DIGEST.to_vec().into(),
|
||||
size: 42,
|
||||
},
|
||||
DirectoryNode {
|
||||
DirectoryEntry {
|
||||
name: "a".into(),
|
||||
digest: DUMMY_DIGEST.to_vec().into(),
|
||||
size: 42,
|
||||
|
|
@ -303,12 +303,12 @@ fn validate_sorting() {
|
|||
// "a" exists twice (different types), bad.
|
||||
{
|
||||
let d = Directory {
|
||||
directories: vec![DirectoryNode {
|
||||
directories: vec![DirectoryEntry {
|
||||
name: "a".into(),
|
||||
digest: DUMMY_DIGEST.to_vec().into(),
|
||||
size: 42,
|
||||
}],
|
||||
symlinks: vec![SymlinkNode {
|
||||
symlinks: vec![SymlinkEntry {
|
||||
name: "a".into(),
|
||||
target: "b".into(),
|
||||
}],
|
||||
|
|
@ -326,12 +326,12 @@ fn validate_sorting() {
|
|||
{
|
||||
let d = Directory {
|
||||
directories: vec![
|
||||
DirectoryNode {
|
||||
DirectoryEntry {
|
||||
name: "a".into(),
|
||||
digest: DUMMY_DIGEST.to_vec().into(),
|
||||
size: 42,
|
||||
},
|
||||
DirectoryNode {
|
||||
DirectoryEntry {
|
||||
name: "b".into(),
|
||||
digest: DUMMY_DIGEST.to_vec().into(),
|
||||
size: 42,
|
||||
|
|
@ -347,18 +347,18 @@ fn validate_sorting() {
|
|||
{
|
||||
let d = Directory {
|
||||
directories: vec![
|
||||
DirectoryNode {
|
||||
DirectoryEntry {
|
||||
name: "b".into(),
|
||||
digest: DUMMY_DIGEST.to_vec().into(),
|
||||
size: 42,
|
||||
},
|
||||
DirectoryNode {
|
||||
DirectoryEntry {
|
||||
name: "c".into(),
|
||||
digest: DUMMY_DIGEST.to_vec().into(),
|
||||
size: 42,
|
||||
},
|
||||
],
|
||||
symlinks: vec![SymlinkNode {
|
||||
symlinks: vec![SymlinkEntry {
|
||||
name: "a".into(),
|
||||
target: "foo".into(),
|
||||
}],
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
use super::{node, Node, SymlinkNode};
|
||||
use super::{entry, Entry, SymlinkEntry};
|
||||
use crate::DirectoryError;
|
||||
|
||||
mod directory;
|
||||
|
||||
/// Create a node with an empty symlink target, and ensure it fails validation.
|
||||
/// Create an entry with an empty symlink target, and ensure it fails validation.
|
||||
#[test]
|
||||
fn convert_symlink_empty_target_invalid() {
|
||||
Node {
|
||||
node: Some(node::Node::Symlink(SymlinkNode {
|
||||
Entry {
|
||||
entry: Some(entry::Entry::Symlink(SymlinkEntry {
|
||||
name: "foo".into(),
|
||||
target: "".into(),
|
||||
})),
|
||||
|
|
@ -20,8 +20,8 @@ fn convert_symlink_empty_target_invalid() {
|
|||
/// fails validation.
|
||||
#[test]
|
||||
fn convert_symlink_target_null_byte_invalid() {
|
||||
Node {
|
||||
node: Some(node::Node::Symlink(SymlinkNode {
|
||||
Entry {
|
||||
entry: Some(entry::Entry::Symlink(SymlinkEntry {
|
||||
name: "foo".into(),
|
||||
target: "foo\0".into(),
|
||||
})),
|
||||
|
|
@ -35,8 +35,8 @@ fn convert_symlink_target_null_byte_invalid() {
|
|||
fn convert_anonymous_with_name_fail() {
|
||||
assert_eq!(
|
||||
DirectoryError::NameInAnonymousNode,
|
||||
Node {
|
||||
node: Some(node::Node::Symlink(SymlinkNode {
|
||||
Entry {
|
||||
entry: Some(entry::Entry::Symlink(SymlinkEntry {
|
||||
name: "foo".into(),
|
||||
target: "somewhereelse".into(),
|
||||
})),
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ pub async fn get_head(
|
|||
}
|
||||
|
||||
// parse the proto
|
||||
let root_node: snix_castore::proto::Node = Message::decode(Bytes::from(root_node_proto))
|
||||
let root_node: snix_castore::proto::Entry = Message::decode(Bytes::from(root_node_proto))
|
||||
.map_err(|e| {
|
||||
warn!(err=%e, "unable to decode root node proto");
|
||||
StatusCode::NOT_FOUND
|
||||
|
|
@ -244,7 +244,10 @@ mod tests {
|
|||
pub static NAR_STR_SYMLINK: LazyLock<String> = LazyLock::new(|| {
|
||||
use prost::Message;
|
||||
BASE64URL_NOPAD.encode(
|
||||
&snix_castore::proto::Node::from_name_and_node("".into(), CASTORE_NODE_SYMLINK.clone())
|
||||
&snix_castore::proto::Entry::from_name_and_node(
|
||||
"".into(),
|
||||
CASTORE_NODE_SYMLINK.clone(),
|
||||
)
|
||||
.encode_to_vec(),
|
||||
)
|
||||
});
|
||||
|
|
@ -305,9 +308,9 @@ mod tests {
|
|||
|
||||
let invalid_url = {
|
||||
use prost::Message;
|
||||
let n = snix_castore::proto::Node {
|
||||
node: Some(snix_castore::proto::node::Node::Directory(
|
||||
snix_castore::proto::DirectoryNode {
|
||||
let n = snix_castore::proto::Entry {
|
||||
entry: Some(snix_castore::proto::entry::Entry::Directory(
|
||||
snix_castore::proto::DirectoryEntry {
|
||||
name: "".into(),
|
||||
digest: "invalid b64".into(),
|
||||
size: 1,
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ fn gen_narinfo_str(path_info: &PathInfo) -> String {
|
|||
let url = format!(
|
||||
"nar/snix-castore/{}?narsize={}",
|
||||
data_encoding::BASE64URL_NOPAD.encode(
|
||||
&snix_castore::proto::Node::from_name_and_node("".into(), path_info.node.to_owned())
|
||||
&snix_castore::proto::Entry::from_name_and_node("".into(), path_info.node.to_owned())
|
||||
.encode_to_vec()
|
||||
),
|
||||
path_info.nar_size,
|
||||
|
|
|
|||
|
|
@ -12,8 +12,9 @@ option go_package = "snix.dev/store/proto;storev1";
|
|||
// PathInfo shows information about a Nix Store Path.
|
||||
// That's a single element inside /nix/store.
|
||||
message PathInfo {
|
||||
// The path can be a directory, file or symlink.
|
||||
snix.castore.v1.Node node = 1;
|
||||
// The entry both describes the store path and the contents, which can be a
|
||||
// directory, file or symlink.
|
||||
snix.castore.v1.Entry entry = 1;
|
||||
|
||||
// List of references (output path hashes)
|
||||
// This really is the raw *bytes*, after decoding nixbase32, and not a
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ service PathInfoService {
|
|||
//
|
||||
// It can also be used to calculate arbitrary NAR hashes of output paths, in
|
||||
// case a legacy Nix Binary Cache frontend is provided.
|
||||
rpc CalculateNAR(snix.castore.v1.Node) returns (CalculateNARResponse);
|
||||
rpc CalculateNAR(snix.castore.v1.Entry) returns (CalculateNARResponse);
|
||||
|
||||
// Return a stream of PathInfo messages matching the criteria specified in
|
||||
// ListPathInfoRequest.
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ where
|
|||
let path_info = self
|
||||
.grpc_client
|
||||
.clone()
|
||||
.calculate_nar(snix_castore::proto::Node::from_name_and_node(
|
||||
.calculate_nar(snix_castore::proto::Entry::from_name_and_node(
|
||||
"".into(),
|
||||
root_node.to_owned(),
|
||||
))
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ where
|
|||
#[instrument(skip_all)]
|
||||
async fn calculate_nar(
|
||||
&self,
|
||||
request: Request<castorepb::Node>,
|
||||
request: Request<castorepb::Entry>,
|
||||
) -> Result<Response<proto::CalculateNarResponse>> {
|
||||
let root_node = request
|
||||
.into_inner()
|
||||
|
|
|
|||
|
|
@ -35,9 +35,9 @@ pub enum ValidatePathInfoError {
|
|||
#[error("Invalid length of digest at position {}, expected {}, got {}", .0, store_path::DIGEST_SIZE, .1)]
|
||||
InvalidReferenceDigestLen(usize, usize),
|
||||
|
||||
/// No node present
|
||||
#[error("No node present")]
|
||||
NoNodePresent,
|
||||
/// No entry present
|
||||
#[error("No entry present")]
|
||||
NoEntryPresent,
|
||||
|
||||
/// Node fails validation
|
||||
#[error("Invalid root node: {:?}", .0.to_string())]
|
||||
|
|
@ -181,7 +181,7 @@ impl From<&nix_compat::nixhash::CAHash> for nar_info::Ca {
|
|||
impl From<crate::pathinfoservice::PathInfo> for PathInfo {
|
||||
fn from(value: crate::pathinfoservice::PathInfo) -> Self {
|
||||
Self {
|
||||
node: Some(castorepb::Node::from_name_and_node(
|
||||
entry: Some(castorepb::Entry::from_name_and_node(
|
||||
value.store_path.to_string().into_bytes().into(),
|
||||
value.node,
|
||||
)),
|
||||
|
|
@ -270,10 +270,10 @@ impl TryFrom<PathInfo> for crate::pathinfoservice::PathInfo {
|
|||
|
||||
let nar_sha256_length = narinfo.nar_sha256.len();
|
||||
|
||||
// split value.node into the name and node components
|
||||
// split value.entry into the name and node components
|
||||
let (name, node) = value
|
||||
.node
|
||||
.ok_or_else(|| ValidatePathInfoError::NoNodePresent)?
|
||||
.entry
|
||||
.ok_or_else(|| ValidatePathInfoError::NoEntryPresent)?
|
||||
.try_into_name_and_node()
|
||||
.map_err(ValidatePathInfoError::InvalidRootNode)?;
|
||||
|
||||
|
|
|
|||
|
|
@ -14,12 +14,14 @@ use snix_castore::{DirectoryError, ValidateNodeError};
|
|||
/// The references in `narinfo.reference_names` aligns with what's in
|
||||
/// `references`.
|
||||
static PROTO_PATH_INFO: LazyLock<proto::PathInfo> = LazyLock::new(|| proto::PathInfo {
|
||||
node: Some(castorepb::Node {
|
||||
node: Some(castorepb::node::Node::Directory(castorepb::DirectoryNode {
|
||||
entry: Some(castorepb::Entry {
|
||||
entry: Some(castorepb::entry::Entry::Directory(
|
||||
castorepb::DirectoryEntry {
|
||||
name: DUMMY_PATH_STR.into(),
|
||||
digest: DUMMY_DIGEST.clone().into(),
|
||||
size: 0,
|
||||
})),
|
||||
},
|
||||
)),
|
||||
}),
|
||||
references: vec![DUMMY_PATH_DIGEST.as_slice().into()],
|
||||
narinfo: Some(proto::NarInfo {
|
||||
|
|
@ -58,15 +60,15 @@ fn convert_valid_deriver() {
|
|||
}
|
||||
|
||||
#[rstest]
|
||||
#[case::no_node(None, ValidatePathInfoError::NoNodePresent)]
|
||||
#[case::no_node_2(Some(castorepb::Node { node: None}), ValidatePathInfoError::InvalidRootNode(DirectoryError::NoNodeSet))]
|
||||
fn convert_pathinfo_wrong_nodes(
|
||||
#[case] node: Option<castorepb::Node>,
|
||||
#[case::no_entry(None, ValidatePathInfoError::NoEntryPresent)]
|
||||
#[case::no_entry_2(Some(castorepb::Entry { entry: None}), ValidatePathInfoError::InvalidRootNode(DirectoryError::NoEntrySet))]
|
||||
fn convert_pathinfo_wrong_entries(
|
||||
#[case] entry: Option<castorepb::Entry>,
|
||||
#[case] exp_err: ValidatePathInfoError,
|
||||
) {
|
||||
// construct the PathInfo object
|
||||
let mut path_info = PROTO_PATH_INFO.clone();
|
||||
path_info.node = node;
|
||||
path_info.entry = entry;
|
||||
|
||||
assert_eq!(
|
||||
exp_err,
|
||||
|
|
@ -74,19 +76,19 @@ fn convert_pathinfo_wrong_nodes(
|
|||
);
|
||||
}
|
||||
|
||||
/// Constructs a [proto::PathInfo] with root nodes that have wrong data in
|
||||
/// various places, causing the conversion to [PathInfo] to fail.
|
||||
/// Constructs a [proto::PathInfo] with an entry that has wrong data in various
|
||||
/// places, causing the conversion to [PathInfo] to fail.
|
||||
#[rstest]
|
||||
#[case::directory_invalid_digest_length(
|
||||
castorepb::node::Node::Directory(castorepb::DirectoryNode {
|
||||
castorepb::entry::Entry::Directory(castorepb::DirectoryEntry {
|
||||
name: DUMMY_PATH_STR.into(),
|
||||
digest: Bytes::new(),
|
||||
size: 0,
|
||||
}),
|
||||
ValidatePathInfoError::InvalidRootNode(DirectoryError::InvalidNode(DUMMY_PATH_STR.into(), ValidateNodeError::InvalidDigestLen(0)))
|
||||
)]
|
||||
#[case::directory_invalid_node_name_no_storepath(
|
||||
castorepb::node::Node::Directory(castorepb::DirectoryNode {
|
||||
#[case::directory_invalid_entry_name_no_storepath(
|
||||
castorepb::entry::Entry::Directory(castorepb::DirectoryEntry {
|
||||
name: "invalid".into(),
|
||||
digest: DUMMY_DIGEST.clone().into(),
|
||||
size: 0,
|
||||
|
|
@ -94,15 +96,15 @@ fn convert_pathinfo_wrong_nodes(
|
|||
ValidatePathInfoError::InvalidNodeName("invalid".into(), store_path::Error::InvalidLength)
|
||||
)]
|
||||
#[case::file_invalid_digest_len(
|
||||
castorepb::node::Node::File(castorepb::FileNode {
|
||||
castorepb::entry::Entry::File(castorepb::FileEntry {
|
||||
name: DUMMY_PATH_STR.into(),
|
||||
digest: Bytes::new(),
|
||||
..Default::default()
|
||||
}),
|
||||
ValidatePathInfoError::InvalidRootNode(DirectoryError::InvalidNode(DUMMY_PATH_STR.into(), ValidateNodeError::InvalidDigestLen(0)))
|
||||
)]
|
||||
#[case::file_invalid_node_name(
|
||||
castorepb::node::Node::File(castorepb::FileNode {
|
||||
#[case::file_invalid_entry_name(
|
||||
castorepb::entry::Entry::File(castorepb::FileEntry {
|
||||
name: "invalid".into(),
|
||||
digest: DUMMY_DIGEST.clone().into(),
|
||||
..Default::default()
|
||||
|
|
@ -112,8 +114,8 @@ fn convert_pathinfo_wrong_nodes(
|
|||
store_path::Error::InvalidLength
|
||||
)
|
||||
)]
|
||||
#[case::symlink_invalid_node_name(
|
||||
castorepb::node::Node::Symlink(castorepb::SymlinkNode {
|
||||
#[case::symlink_invalid_entry_name(
|
||||
castorepb::entry::Entry::Symlink(castorepb::SymlinkEntry {
|
||||
name: "invalid".into(),
|
||||
target: "foo".into(),
|
||||
}),
|
||||
|
|
@ -122,10 +124,13 @@ fn convert_pathinfo_wrong_nodes(
|
|||
store_path::Error::InvalidLength
|
||||
)
|
||||
)]
|
||||
fn convert_fail_node(#[case] node: castorepb::node::Node, #[case] exp_err: ValidatePathInfoError) {
|
||||
fn convert_fail_entry(
|
||||
#[case] entry: castorepb::entry::Entry,
|
||||
#[case] exp_err: ValidatePathInfoError,
|
||||
) {
|
||||
// construct the proto::PathInfo object
|
||||
let mut p = PROTO_PATH_INFO.clone();
|
||||
p.node = Some(castorepb::Node { node: Some(node) });
|
||||
p.entry = Some(castorepb::Entry { entry: Some(entry) });
|
||||
|
||||
assert_eq!(exp_err, PathInfo::try_from(p).expect_err("must fail"));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue