diff --git a/generated.go b/generated.go index b57790c..6178282 100644 --- a/generated.go +++ b/generated.go @@ -243,9 +243,9 @@ func (s *Storage) parsePairStorageCopy(opts []Pair) (pairStorageCopy, error) { // pairStorageCreate is the parsed struct type pairStorageCreate struct { - pairs []Pair - HasMultipartID bool - MultipartID string + pairs []Pair + HasObjectMode bool + ObjectMode ObjectMode } // parsePairStorageCreate will parse Pair slice into *pairStorageCreate @@ -259,12 +259,12 @@ func (s *Storage) parsePairStorageCreate(opts []Pair) (pairStorageCreate, error) isUnsupportedPair := false switch v.Key { - case "multipart_id": - if result.HasMultipartID { + case "object_mode": + if result.HasObjectMode { continue } - result.HasMultipartID = true - result.MultipartID = v.Value.(string) + result.HasObjectMode = true + result.ObjectMode = v.Value.(ObjectMode) continue default: isUnsupportedPair = true @@ -360,7 +360,9 @@ func (s *Storage) parsePairStorageCreateDir(opts []Pair) (pairStorageCreateDir, // pairStorageDelete is the parsed struct type pairStorageDelete struct { - pairs []Pair + pairs []Pair + HasObjectMode bool + ObjectMode ObjectMode } // parsePairStorageDelete will parse Pair slice into *pairStorageDelete @@ -374,6 +376,13 @@ func (s *Storage) parsePairStorageDelete(opts []Pair) (pairStorageDelete, error) isUnsupportedPair := false switch v.Key { + case "object_mode": + if result.HasObjectMode { + continue + } + result.HasObjectMode = true + result.ObjectMode = v.Value.(ObjectMode) + continue default: isUnsupportedPair = true } @@ -621,7 +630,9 @@ func (s *Storage) parsePairStorageRead(opts []Pair) (pairStorageRead, error) { // pairStorageStat is the parsed struct type pairStorageStat struct { - pairs []Pair + pairs []Pair + HasObjectMode bool + ObjectMode ObjectMode } // parsePairStorageStat will parse Pair slice into *pairStorageStat @@ -635,6 +646,13 @@ func (s *Storage) parsePairStorageStat(opts []Pair) (pairStorageStat, error) { isUnsupportedPair := false switch v.Key { + case "object_mode": + if result.HasObjectMode { + continue + } + result.HasObjectMode = true + result.ObjectMode = v.Value.(ObjectMode) + continue default: isUnsupportedPair = true } @@ -819,6 +837,11 @@ func (s *Storage) CopyWithContext(ctx context.Context, src string, dst string, p // Create will create a new object without any api call. // +// ## Behavior +// +// - Create SHOULD NOT send any API call. +// - Create SHOULD accept ObjectMode pair as object mode. +// // This function will create a context by default. func (s *Storage) Create(path string, pairs ...Pair) (o *Object) { pairs = append(pairs, s.defaultPairs.Create...) @@ -880,7 +903,17 @@ func (s *Storage) CreateDirWithContext(ctx context.Context, path string, pairs . return s.createDir(ctx, path, opt) } -// Delete will delete an Object from service. +// Delete will delete an object from service. +// +// ## Behavior +// +// - Delete only delete one and only one object. +// - Service DON'T NEED to support remove all. +// - User NEED to implement remove_all by themself. +// - Delete is idempotent. +// - Successful delete always return nil error. +// - Delete SHOULD never return `ObjectNotExist` +// - Delete DON'T NEED to check the object exist or not. // // This function will create a context by default. func (s *Storage) Delete(path string, pairs ...Pair) (err error) { @@ -888,7 +921,17 @@ func (s *Storage) Delete(path string, pairs ...Pair) (err error) { return s.DeleteWithContext(ctx, path, pairs...) } -// DeleteWithContext will delete an Object from service. +// DeleteWithContext will delete an object from service. +// +// ## Behavior +// +// - Delete only delete one and only one object. +// - Service DON'T NEED to support remove all. +// - User NEED to implement remove_all by themself. +// - Delete is idempotent. +// - Successful delete always return nil error. +// - Delete SHOULD never return `ObjectNotExist` +// - Delete DON'T NEED to check the object exist or not. func (s *Storage) DeleteWithContext(ctx context.Context, path string, pairs ...Pair) (err error) { defer func() { err = s.formatError("delete", err, path) @@ -1020,6 +1063,12 @@ func (s *Storage) ReadWithContext(ctx context.Context, path string, w io.Writer, // Stat will stat a path to get info of an object. // +// ## Behavior +// +// - Stat SHOULD accept ObjectMode pair as hints. +// - Service COULD have different implementations for different object mode. +// - Service SHOULD check if returning ObjectMode is match +// // This function will create a context by default. func (s *Storage) Stat(path string, pairs ...Pair) (o *Object, err error) { ctx := context.Background() @@ -1027,6 +1076,12 @@ func (s *Storage) Stat(path string, pairs ...Pair) (o *Object, err error) { } // StatWithContext will stat a path to get info of an object. +// +// ## Behavior +// +// - Stat SHOULD accept ObjectMode pair as hints. +// - Service COULD have different implementations for different object mode. +// - Service SHOULD check if returning ObjectMode is match func (s *Storage) StatWithContext(ctx context.Context, path string, pairs ...Pair) (o *Object, err error) { defer func() { err = s.formatError("stat", err, path) diff --git a/go.mod b/go.mod index 3589c9c..23bc50b 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module github.com/beyondstorage/go-service-fs/v3 go 1.15 require ( - github.com/beyondstorage/go-integration-test/v4 v4.0.0 - github.com/beyondstorage/go-storage/v4 v4.0.1-0.20210530044854-1c928ddbe52d + github.com/beyondstorage/go-integration-test/v4 v4.1.0 + github.com/beyondstorage/go-storage/v4 v4.1.0 github.com/qingstor/go-mime v0.1.0 github.com/stretchr/testify v1.7.0 golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 diff --git a/go.sum b/go.sum index bdd7b6b..38ca4e3 100644 --- a/go.sum +++ b/go.sum @@ -1,13 +1,11 @@ github.com/Xuanwo/templateutils v0.1.0 h1:WpkWOqQtIQ2vAIpJLa727DdN8WtxhUkkbDGa6UhntJY= github.com/Xuanwo/templateutils v0.1.0/go.mod h1:OdE0DJ+CJxDBq6psX5DPV+gOZi8bhuHuVUpPCG++Wb8= -github.com/beyondstorage/go-integration-test/v4 v4.0.0 h1:tdXQV9yxQ3Q6p9xfyQKzK3MEo9r9j9g3uT5+3sbVtnQ= -github.com/beyondstorage/go-integration-test/v4 v4.0.0/go.mod h1:26/JF4b0XxRN0pL4kihpnVNhbbw+QWvmmvgxfnFJDfA= -github.com/beyondstorage/go-storage/v4 v4.0.0/go.mod h1:oa2dYco+xplPj99WSBnYVw/xXvRkIKWSSVDQKNZ5Kz8= -github.com/beyondstorage/go-storage/v4 v4.0.1-0.20210530044854-1c928ddbe52d h1:s9t6VNNRDqmg+PXyXtVEsxIM7xZQIJOYlma28IpkbNQ= -github.com/beyondstorage/go-storage/v4 v4.0.1-0.20210530044854-1c928ddbe52d/go.mod h1:kXMu07IDZaKtxbqI1ufuhqo0FjYe0nH7zPCbBanln/Y= -github.com/beyondstorage/specs/go v0.0.0-20210521044836-3d41c1d9c97f/go.mod h1:f5VvmLHc/dNJwl+/yAv/TOHdev3phvuEswx8DIXiSQQ= -github.com/beyondstorage/specs/go v0.0.0-20210530044123-3ff75e192bc9 h1:YSiF27cAHlDZk9q+oaEHQbA8dH8XTvYxeTOoPzNCwOQ= -github.com/beyondstorage/specs/go v0.0.0-20210530044123-3ff75e192bc9/go.mod h1:f5VvmLHc/dNJwl+/yAv/TOHdev3phvuEswx8DIXiSQQ= +github.com/beyondstorage/go-integration-test/v4 v4.1.0 h1:/cKM5uC+tW1mYAM/FTQlMq3EZMAb8hBm8gL4ZHk9InQ= +github.com/beyondstorage/go-integration-test/v4 v4.1.0/go.mod h1:W6Dhve1tbEpWAR1WSRuJl4UYpMNpM2QTAcb1dCpuEUI= +github.com/beyondstorage/go-storage/v4 v4.1.0 h1:O5SuSoTvs0KeXaZ/dYhpURlki6PjTNPyIzsJMY9sJWw= +github.com/beyondstorage/go-storage/v4 v4.1.0/go.mod h1:dK5DFnvKQI70bfpM1MLU9QqDYB12Z/dFV5sUnbJ/AoU= +github.com/beyondstorage/specs/go v0.0.0-20210608070420-9185b588aa58 h1:AvxsyR0bSSBi90WtYEMdAkM4Sm+Xxr7JVGXAQVVfeOo= +github.com/beyondstorage/specs/go v0.0.0-20210608070420-9185b588aa58/go.mod h1:1Az5o44awI/Ljop+ppO2djyezVfdKKb1RjJ6+M+a5XQ= github.com/dave/dst v0.26.2 h1:lnxLAKI3tx7MgLNVDirFCsDTlTG9nKTk7GcptKcWSwY= github.com/dave/dst v0.26.2/go.mod h1:UMDJuIRPfyUCC78eFuB+SV/WI8oDeyFDvM/JR6NI3IU= github.com/dave/gopackages v0.0.0-20170318123100-46e7023ec56e/go.mod h1:i00+b/gKdIDIxuLDFob7ustLAVqhsZRk2qVZrArELGQ= @@ -33,8 +31,8 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/pelletier/go-toml v1.9.1 h1:a6qW1EVNZWH9WGI6CsYdD8WAylkoXBS5yv0XHlh17Tc= -github.com/pelletier/go-toml v1.9.1/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml v1.9.2 h1:7NiByeVF4jKSG1lDF3X8LTIkq2/bu+1uYbIm1eS5tzk= +github.com/pelletier/go-toml v1.9.2/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/qingstor/go-mime v0.1.0 h1:FhTJtM7TRm9pfgCXpjGUxqwbumGojrgE9ecRz5PXvfc= diff --git a/service.toml b/service.toml index 3ca9e8c..a19059b 100644 --- a/service.toml +++ b/service.toml @@ -7,7 +7,10 @@ implement = ["copier", "mover", "fetcher", "appender", "direr"] optional = ["storage_features", "default_storage_pairs", "work_dir"] [namespace.storage.op.create] -optional = ["multipart_id"] +optional = ["object_mode"] + +[namespace.storage.op.delete] +optional = ["object_mode"] [namespace.storage.op.list] optional = ["continuation_token", "list_mode"] @@ -15,6 +18,9 @@ optional = ["continuation_token", "list_mode"] [namespace.storage.op.read] optional = ["offset", "io_callback", "size"] +[namespace.storage.op.stat] +optional = ["object_mode"] + [namespace.storage.op.write] optional = ["content_md5", "content_type", "offset", "io_callback"] diff --git a/storage.go b/storage.go index 25eb4a8..7b28fbe 100644 --- a/storage.go +++ b/storage.go @@ -78,10 +78,16 @@ func (s *Storage) copy(ctx context.Context, src string, dst string, opt pairStor } func (s *Storage) create(path string, opt pairStorageCreate) (o *Object) { - o = s.newObject(false) + if opt.HasObjectMode && opt.ObjectMode.IsDir() { + o = s.newObject(false) + o.Mode = ModeDir + } else { + o = s.newObject(false) + o.Mode = ModeRead + } + o.ID = filepath.Join(s.workDir, path) o.Path = path - o.Mode = ModeRead return o } diff --git a/tests/storage_test.go b/tests/storage_test.go index b5b4bd3..d497854 100644 --- a/tests/storage_test.go +++ b/tests/storage_test.go @@ -20,3 +20,10 @@ func TestAppend(t *testing.T) { } tests.TestAppender(t, setupTest(t)) } + +func TestDir(t *testing.T) { + if os.Getenv("STORAGE_FS_INTEGRATION_TEST") != "on" { + t.Skipf("STORAGE_FS_INTEGRATION_TEST is not 'on', skipped") + } + tests.TestDirer(t, setupTest(t)) +}