rollup from next branch (#4)
All checks were successful
continuous-integration/drone/push Build is passing

Co-authored-by: sneak <sneak@sneak.berlin>
Reviewed-on: #4
This commit was merged in pull request #4.
This commit is contained in:
2022-12-04 07:59:36 +00:00
parent eb3b685aa3
commit 7a8a1b4a4a
665 changed files with 832 additions and 248432 deletions

3
mfer/gen.go Normal file
View File

@@ -0,0 +1,3 @@
package mfer
//go:generate protoc --go_out=. --go_opt=paths=source_relative mf.proto

114
mfer/manifest.go Normal file
View File

@@ -0,0 +1,114 @@
package mfer
import (
"fmt"
"io"
"io/fs"
"os"
"path/filepath"
"strings"
"github.com/spf13/afero"
)
type ManifestFile struct {
Path string
FileInfo fs.FileInfo
}
func (m *ManifestFile) String() string {
return fmt.Sprintf("<File \"%s\">", m.Path)
}
type Manifest struct {
SourceFS afero.Fs
SourceFSRoot string
Files []*ManifestFile
ScanOptions *ManifestScanOptions
TotalFileSize int64
}
func (m *Manifest) String() string {
return fmt.Sprintf("<Manifest count=%d totalSize=%d>", len(m.Files), m.TotalFileSize)
}
type ManifestScanOptions struct {
IgnoreDotfiles bool
FollowSymLinks bool
}
func NewFromPath(inputPath string, options *ManifestScanOptions) (*Manifest, error) {
abs, err := filepath.Abs(inputPath)
if err != nil {
return nil, err
}
afs := afero.NewBasePathFs(afero.NewOsFs(), abs)
m, err := NewFromFS(afs, options)
if err != nil {
return nil, err
}
m.SourceFSRoot = abs
return m, nil
}
func NewFromFS(fs afero.Fs, options *ManifestScanOptions) (*Manifest, error) {
m := &Manifest{
SourceFS: fs,
ScanOptions: options,
}
err := m.Scan()
if err != nil {
return nil, err
}
return m, nil
}
func (m *Manifest) Scan() error {
// FIXME scan and whatever function does the hashing should take ctx
oe := afero.Walk(m.SourceFS, "./", func(path string, info fs.FileInfo, err error) error {
if m.ScanOptions.IgnoreDotfiles && strings.HasPrefix(path, ".") {
// FIXME make this check all path components BUG
return nil
}
if info != nil && info.IsDir() {
// manifests contain only files, directories are implied.
return nil
}
fileinfo, staterr := m.SourceFS.Stat(path)
if staterr != nil {
panic(staterr)
}
nf := &ManifestFile{
Path: path,
FileInfo: fileinfo,
}
m.Files = append(m.Files, nf)
m.TotalFileSize = m.TotalFileSize + info.Size()
return nil
})
if oe != nil {
return oe
}
return nil
}
func (m *Manifest) WriteToFile(path string) error {
// FIXME refuse to overwrite without -f if file exists
f, err := os.Create(path)
if err != nil {
return err
}
defer f.Close()
return m.Write(f)
}
func (m *Manifest) Write(output io.Writer) error {
// FIXME implement
panic("nope")
return nil // nolint:all
}

70
mfer/mf.proto Normal file
View File

@@ -0,0 +1,70 @@
syntax = "proto3";
option go_package = "git.eeqj.de/sneak/mfer";
message Timestamp {
int64 seconds = 1;
int32 nanos = 2;
}
message MFFile {
enum Version {
NONE = 0;
ONE = 1; // only one for now
}
// required mffile root attributes 1xx
Version version = 101;
bytes innerMessage = 102;
// these are used solely to detect corruption/truncation
// and not for cryptographic integrity.
int64 size = 103;
bytes sha256 = 104;
// 2xx for optional manifest root attributes
// think we might use gosignify instead of gpg:
// github.com/frankbraun/gosignify
//detached signature, ascii or binary
optional bytes signature = 201;
//full GPG key id
optional bytes signer = 202;
//full GPG signing public key, ascii or binary
optional bytes signingPubKey = 203;
}
message MFFilePath {
// required attributes:
string path = 1;
int64 size = 2;
// gotta have at least one:
repeated MFFileChecksum hashes = 3;
// optional per-file metadata
optional string mimeType = 301;
optional Timestamp mtime = 302;
optional Timestamp ctime = 303;
optional Timestamp atime = 304;
}
message MFFileChecksum {
// 1.0 golang implementation must write a multihash here
// it's ok to only ever use/verify sha256 multihash
bytes multiHash = 1;
}
message MFFileInner {
enum Version {
NONE = 0;
ONE = 1; // only one for now
}
Version version = 100;
// required manifest attributes:
repeated MFFilePath files = 101;
// optional manifest attributes 2xx:
optional Timestamp createdAt = 201;
}

12
mfer/mfer_test.go Normal file
View File

@@ -0,0 +1,12 @@
package mfer
import "testing"
// Add those variables as well
var (
existingFolder = "./testdata/a-folder-that-exists"
nonExistingFolder = "./testdata/a-folder-that-does-not-exists"
)
func TestManifestGeneration(t *testing.T) {
}