diff --git a/datanode/medium_test.go b/datanode/medium_test.go index 70ffa19..730ddb4 100644 --- a/datanode/medium_test.go +++ b/datanode/medium_test.go @@ -227,8 +227,8 @@ func TestDataNode_List_Good(t *testing.T) { require.NoError(t, err) names := make([]string, len(entries)) - for i, e := range entries { - names[i] = e.Name() + for index, entry := range entries { + names[index] = entry.Name() } assert.Contains(t, names, "root.txt") assert.Contains(t, names, "pkg") @@ -236,8 +236,8 @@ func TestDataNode_List_Good(t *testing.T) { entries, err = dataNodeMedium.List("pkg") require.NoError(t, err) names = make([]string, len(entries)) - for i, e := range entries { - names[i] = e.Name() + for index, entry := range entries { + names[index] = entry.Name() } assert.Contains(t, names, "a.go") assert.Contains(t, names, "b.go") @@ -264,11 +264,11 @@ func TestDataNode_Open_Good(t *testing.T) { require.NoError(t, dataNodeMedium.Write("open.txt", "opened")) - f, err := dataNodeMedium.Open("open.txt") + file, err := dataNodeMedium.Open("open.txt") require.NoError(t, err) - defer f.Close() + defer file.Close() - data, err := io.ReadAll(f) + data, err := io.ReadAll(file) require.NoError(t, err) assert.Equal(t, "opened", string(data)) } @@ -276,19 +276,19 @@ func TestDataNode_Open_Good(t *testing.T) { func TestDataNode_CreateAppend_Good(t *testing.T) { dataNodeMedium := New() - w, err := dataNodeMedium.Create("new.txt") + writer, err := dataNodeMedium.Create("new.txt") require.NoError(t, err) - w.Write([]byte("hello")) - w.Close() + _, _ = writer.Write([]byte("hello")) + require.NoError(t, writer.Close()) got, err := dataNodeMedium.Read("new.txt") require.NoError(t, err) assert.Equal(t, "hello", got) - w, err = dataNodeMedium.Append("new.txt") + writer, err = dataNodeMedium.Append("new.txt") require.NoError(t, err) - w.Write([]byte(" world")) - w.Close() + _, _ = writer.Write([]byte(" world")) + require.NoError(t, writer.Close()) got, err = dataNodeMedium.Read("new.txt") require.NoError(t, err) @@ -315,17 +315,17 @@ func TestDataNode_Append_ReadFailure_Bad(t *testing.T) { func TestDataNode_Streams_Good(t *testing.T) { dataNodeMedium := New() - ws, err := dataNodeMedium.WriteStream("stream.txt") + writeStream, err := dataNodeMedium.WriteStream("stream.txt") require.NoError(t, err) - ws.Write([]byte("streamed")) - ws.Close() + _, _ = writeStream.Write([]byte("streamed")) + require.NoError(t, writeStream.Close()) - rs, err := dataNodeMedium.ReadStream("stream.txt") + readStream, err := dataNodeMedium.ReadStream("stream.txt") require.NoError(t, err) - data, err := io.ReadAll(rs) + data, err := io.ReadAll(readStream) require.NoError(t, err) assert.Equal(t, "streamed", string(data)) - rs.Close() + require.NoError(t, readStream.Close()) } func TestDataNode_SnapshotRestore_Good(t *testing.T) { @@ -334,11 +334,11 @@ func TestDataNode_SnapshotRestore_Good(t *testing.T) { require.NoError(t, dataNodeMedium.Write("a.txt", "alpha")) require.NoError(t, dataNodeMedium.Write("b/c.txt", "charlie")) - snap, err := dataNodeMedium.Snapshot() + snapshotData, err := dataNodeMedium.Snapshot() require.NoError(t, err) - assert.NotEmpty(t, snap) + assert.NotEmpty(t, snapshotData) - restoredNode, err := FromTar(snap) + restoredNode, err := FromTar(snapshotData) require.NoError(t, err) got, err := restoredNode.Read("a.txt") @@ -355,13 +355,13 @@ func TestDataNode_Restore_Good(t *testing.T) { require.NoError(t, dataNodeMedium.Write("original.txt", "before")) - snap, err := dataNodeMedium.Snapshot() + snapshotData, err := dataNodeMedium.Snapshot() require.NoError(t, err) require.NoError(t, dataNodeMedium.Write("original.txt", "after")) require.NoError(t, dataNodeMedium.Write("extra.txt", "extra")) - require.NoError(t, dataNodeMedium.Restore(snap)) + require.NoError(t, dataNodeMedium.Restore(snapshotData)) got, err := dataNodeMedium.Read("original.txt") require.NoError(t, err) @@ -375,14 +375,14 @@ func TestDataNode_DataNode_Good(t *testing.T) { require.NoError(t, dataNodeMedium.Write("test.txt", "borg")) - dn := dataNodeMedium.DataNode() - assert.NotNil(t, dn) + dataNode := dataNodeMedium.DataNode() + assert.NotNil(t, dataNode) - f, err := dn.Open("test.txt") + file, err := dataNode.Open("test.txt") require.NoError(t, err) - defer f.Close() + defer file.Close() - data, err := io.ReadAll(f) + data, err := io.ReadAll(file) require.NoError(t, err) assert.Equal(t, "borg", string(data)) } diff --git a/docs/architecture.md b/docs/architecture.md index d557610..0d11aa6 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -139,7 +139,7 @@ keyValueStore, _ := store.New(store.Options{Path: ":memory:"}) keyValueStore.Set("user", "pool", "pool.lthn.io:3333") keyValueStore.Set("user", "wallet", "iz...") renderedText, _ := keyValueStore.Render(`{"pool":"{{ .pool }}"}`, "user") -// renderedText: {"pool":"pool.lthn.io:3333"} +assert.Equal(t, `{"pool":"pool.lthn.io:3333"}`, renderedText) ``` ### store.Medium (Medium adapter) @@ -164,8 +164,8 @@ The sigil package implements composable, reversible data transformations. ```go type Sigil interface { - In(data []byte) ([]byte, error) // forward transform - Out(data []byte) ([]byte, error) // reverse transform + In(data []byte) ([]byte, error) + Out(data []byte) ([]byte, error) } ``` @@ -199,10 +199,8 @@ Created via `NewSigil(name)`: ### Pipeline Functions ```go -// Apply sigils left-to-right. encoded, _ := sigil.Transmute(data, []sigil.Sigil{gzipSigil, hexSigil}) -// Reverse sigils right-to-left. original, _ := sigil.Untransmute(encoded, []sigil.Sigil{gzipSigil, hexSigil}) ``` @@ -231,12 +229,11 @@ The pre-obfuscation layer ensures that raw plaintext patterns are never sent dir key := make([]byte, 32) rand.Read(key) -s, _ := sigil.NewChaChaPolySigil(key, nil) -ciphertext, _ := s.In([]byte("secret")) -plaintext, _ := s.Out(ciphertext) +cipherSigil, _ := sigil.NewChaChaPolySigil(key, nil) +ciphertext, _ := cipherSigil.In([]byte("secret")) +plaintext, _ := cipherSigil.Out(ciphertext) -// With stronger obfuscation: -s2, _ := sigil.NewChaChaPolySigil(key, &sigil.ShuffleMaskObfuscator{}) +shuffleCipherSigil, _ := sigil.NewChaChaPolySigil(key, &sigil.ShuffleMaskObfuscator{}) ``` Each call to `In` generates a fresh random nonce, so encrypting the same plaintext twice produces different ciphertexts. diff --git a/docs/development.md b/docs/development.md index d23b72d..a1a6b28 100644 --- a/docs/development.md +++ b/docs/development.md @@ -96,7 +96,6 @@ func TestMyFeature(t *testing.T) { _ = memoryMedium.Write("config.yaml", "key: value") _ = memoryMedium.EnsureDir("data") - // Your code under test receives memoryMedium as an io.Medium result, err := myFunction(memoryMedium) assert.NoError(t, err) output, err := memoryMedium.Read("output.txt") diff --git a/docs/index.md b/docs/index.md index 9ce4c25..05762f9 100644 --- a/docs/index.md +++ b/docs/index.md @@ -19,21 +19,17 @@ import ( "forge.lthn.ai/core/go-io/node" ) -// Use the pre-initialised local filesystem (unsandboxed, rooted at "/"). content, _ := io.Local.Read("/etc/hostname") -// Create a sandboxed medium restricted to a single directory. -sandbox, _ := io.NewSandboxed("/var/data/myapp") -_ = sandbox.Write("config.yaml", "key: value") +sandboxMedium, _ := io.NewSandboxed("/var/data/myapp") +_ = sandboxMedium.Write("config.yaml", "key: value") -// In-memory filesystem with tar serialisation. -mem := node.New() -mem.AddData("hello.txt", []byte("world")) -tarball, _ := mem.ToTar() +nodeTree := node.New() +nodeTree.AddData("hello.txt", []byte("world")) +tarball, _ := nodeTree.ToTar() -// S3 backend (requires an *awss3.Client from the AWS SDK). -bucket, _ := s3.New(s3.Options{Bucket: "my-bucket", Client: awsClient, Prefix: "uploads/"}) -_ = bucket.Write("photo.jpg", rawData) +s3Medium, _ := s3.New(s3.Options{Bucket: "my-bucket", Client: awsClient, Prefix: "uploads/"}) +_ = s3Medium.Write("photo.jpg", rawData) ``` @@ -58,29 +54,24 @@ Every storage backend implements the same 17-method interface: ```go type Medium interface { - // Content operations Read(path string) (string, error) Write(path, content string) error WriteMode(path, content string, mode fs.FileMode) error - // Streaming (for large files) ReadStream(path string) (io.ReadCloser, error) WriteStream(path string) (io.WriteCloser, error) Open(path string) (fs.File, error) Create(path string) (io.WriteCloser, error) Append(path string) (io.WriteCloser, error) - // Directory operations EnsureDir(path string) error List(path string) ([]fs.DirEntry, error) - // Metadata Stat(path string) (fs.FileInfo, error) Exists(path string) bool IsFile(path string) bool IsDir(path string) bool - // Mutation Delete(path string) error DeleteAll(path string) error Rename(oldPath, newPath string) error @@ -95,12 +86,12 @@ All backends implement this interface fully. Backends where a method has no natu The root package provides helper functions that accept any `Medium`: ```go -// Copy a file between any two backends. -err := io.Copy(localMedium, "source.txt", s3Medium, "dest.txt") +sourceMedium := io.Local +destinationMedium := io.NewMemoryMedium() +err := io.Copy(sourceMedium, "source.txt", destinationMedium, "dest.txt") -// Read/Write wrappers that take an explicit medium. -content, err := io.Read(medium, "path") -err := io.Write(medium, "path", "content") +content, err := io.Read(destinationMedium, "path") +err = io.Write(destinationMedium, "path", "content") ``` diff --git a/local/medium.go b/local/medium.go index 1cce3cb..100dd74 100644 --- a/local/medium.go +++ b/local/medium.go @@ -30,23 +30,29 @@ func New(root string) (*Medium, error) { } func dirSeparator() string { - if sep := core.Env("DS"); sep != "" { - return sep + if separator := core.Env("CORE_PATH_SEPARATOR"); separator != "" { + return separator + } + if separator := core.Env("DS"); separator != "" { + return separator } return "/" } func normalisePath(path string) string { - sep := dirSeparator() - if sep == "/" { - return core.Replace(path, "\\", sep) + separator := dirSeparator() + if separator == "/" { + return core.Replace(path, "\\", separator) } - return core.Replace(path, "/", sep) + return core.Replace(path, "/", separator) } func currentWorkingDir() string { - if cwd := core.Env("DIR_CWD"); cwd != "" { - return cwd + if workingDirectory := core.Env("CORE_WORKING_DIRECTORY"); workingDirectory != "" { + return workingDirectory + } + if workingDirectory := core.Env("DIR_CWD"); workingDirectory != "" { + return workingDirectory } return "." } diff --git a/local/medium_test.go b/local/medium_test.go index 6c4e42c..de84c45 100644 --- a/local/medium_test.go +++ b/local/medium_test.go @@ -40,8 +40,8 @@ func TestLocal_Path_RootFilesystem_Good(t *testing.T) { assert.Equal(t, "/etc/passwd", localMedium.sandboxedPath("/etc/passwd")) assert.Equal(t, "/home/user/file.txt", localMedium.sandboxedPath("/home/user/file.txt")) - cwd := currentWorkingDir() - assert.Equal(t, core.Path(cwd, "file.txt"), localMedium.sandboxedPath("file.txt")) + workingDirectory := currentWorkingDir() + assert.Equal(t, core.Path(workingDirectory, "file.txt"), localMedium.sandboxedPath("file.txt")) } func TestLocal_ReadWrite_Basic_Good(t *testing.T) { @@ -303,8 +303,8 @@ func TestLocal_List_Good(t *testing.T) { assert.Len(t, entries, 3) names := make(map[string]bool) - for _, e := range entries { - names[e.Name()] = true + for _, entry := range entries { + names[entry.Name()] = true } assert.True(t, names["file1.txt"]) assert.True(t, names["file2.txt"]) diff --git a/medium_test.go b/medium_test.go index 9417d49..69eb94e 100644 --- a/medium_test.go +++ b/medium_test.go @@ -167,8 +167,8 @@ func TestMemoryMedium_List_Good(t *testing.T) { assert.Len(t, entries, 3) names := make(map[string]bool) - for _, e := range entries { - names[e.Name()] = true + for _, entry := range entries { + names[entry.Name()] = true } assert.True(t, names["file1.txt"]) assert.True(t, names["file2.txt"]) diff --git a/node/node_test.go b/node/node_test.go index b9354d1..5d2a21b 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -556,8 +556,8 @@ func TestNode_FSInterface_Good(t *testing.T) { func sortedNames(entries []fs.DirEntry) []string { var names []string - for _, e := range entries { - names = append(names, e.Name()) + for _, entry := range entries { + names = append(names, entry.Name()) } sort.Strings(names) return names diff --git a/s3/s3_test.go b/s3/s3_test.go index 10460df..c72e771 100644 --- a/s3/s3_test.go +++ b/s3/s3_test.go @@ -409,8 +409,8 @@ func TestS3_List_Good(t *testing.T) { require.NoError(t, err) names := make(map[string]bool) - for _, e := range entries { - names[e.Name()] = true + for _, entry := range entries { + names[entry.Name()] = true } assert.True(t, names["file1.txt"], "should list file1.txt") @@ -418,10 +418,10 @@ func TestS3_List_Good(t *testing.T) { assert.True(t, names["sub"], "should list sub directory") assert.Len(t, entries, 3) - for _, e := range entries { - if e.Name() == "sub" { - assert.True(t, e.IsDir()) - info, err := e.Info() + for _, entry := range entries { + if entry.Name() == "sub" { + assert.True(t, entry.IsDir()) + info, err := entry.Info() require.NoError(t, err) assert.True(t, info.IsDir()) } @@ -438,8 +438,8 @@ func TestS3_List_Root_Good(t *testing.T) { require.NoError(t, err) names := make(map[string]bool) - for _, e := range entries { - names[e.Name()] = true + for _, entry := range entries { + names[entry.Name()] = true } assert.True(t, names["root.txt"]) @@ -476,15 +476,15 @@ func TestS3_Open_Good(t *testing.T) { require.NoError(t, s3Medium.Write("file.txt", "open me")) - f, err := s3Medium.Open("file.txt") + file, err := s3Medium.Open("file.txt") require.NoError(t, err) - defer f.Close() + defer file.Close() - data, err := goio.ReadAll(f.(goio.Reader)) + data, err := goio.ReadAll(file.(goio.Reader)) require.NoError(t, err) assert.Equal(t, "open me", string(data)) - stat, err := f.Stat() + stat, err := file.Stat() require.NoError(t, err) assert.Equal(t, "file.txt", stat.Name()) } @@ -499,14 +499,14 @@ func TestS3_Open_NotFound_Bad(t *testing.T) { func TestS3_Create_Good(t *testing.T) { s3Medium, _ := newS3Medium(t) - w, err := s3Medium.Create("new.txt") + writer, err := s3Medium.Create("new.txt") require.NoError(t, err) - n, err := w.Write([]byte("created")) + bytesWritten, err := writer.Write([]byte("created")) require.NoError(t, err) - assert.Equal(t, 7, n) + assert.Equal(t, 7, bytesWritten) - err = w.Close() + err = writer.Close() require.NoError(t, err) content, err := s3Medium.Read("new.txt") @@ -519,12 +519,12 @@ func TestS3_Append_Good(t *testing.T) { require.NoError(t, s3Medium.Write("append.txt", "hello")) - w, err := s3Medium.Append("append.txt") + writer, err := s3Medium.Append("append.txt") require.NoError(t, err) - _, err = w.Write([]byte(" world")) + _, err = writer.Write([]byte(" world")) require.NoError(t, err) - err = w.Close() + err = writer.Close() require.NoError(t, err) content, err := s3Medium.Read("append.txt") @@ -535,12 +535,12 @@ func TestS3_Append_Good(t *testing.T) { func TestS3_Append_NewFile_Good(t *testing.T) { s3Medium, _ := newS3Medium(t) - w, err := s3Medium.Append("new.txt") + writer, err := s3Medium.Append("new.txt") require.NoError(t, err) - _, err = w.Write([]byte("fresh")) + _, err = writer.Write([]byte("fresh")) require.NoError(t, err) - err = w.Close() + err = writer.Close() require.NoError(t, err) content, err := s3Medium.Read("new.txt") diff --git a/sigil/crypto_sigil_test.go b/sigil/crypto_sigil_test.go index d7a2e29..41a20d2 100644 --- a/sigil/crypto_sigil_test.go +++ b/sigil/crypto_sigil_test.go @@ -331,7 +331,7 @@ func TestCryptoSigil_ChaChaPolySigil_TamperedCiphertext_Bad(t *testing.T) { type failReader struct{} -func (f *failReader) Read([]byte) (int, error) { +func (reader *failReader) Read([]byte) (int, error) { return 0, core.NewError("entropy source failed") } @@ -432,8 +432,8 @@ func isHex(data []byte) bool { type failSigil struct{} -func (f *failSigil) In([]byte) ([]byte, error) { return nil, core.NewError("fail in") } -func (f *failSigil) Out([]byte) ([]byte, error) { return nil, core.NewError("fail out") } +func (sigil *failSigil) In([]byte) ([]byte, error) { return nil, core.NewError("fail in") } +func (sigil *failSigil) Out([]byte) ([]byte, error) { return nil, core.NewError("fail out") } func TestCryptoSigil_Transmute_ErrorPropagation_Bad(t *testing.T) { _, err := Transmute([]byte("data"), []Sigil{&failSigil{}}) diff --git a/sqlite/sqlite_test.go b/sqlite/sqlite_test.go index e0f1bc8..2e14452 100644 --- a/sqlite/sqlite_test.go +++ b/sqlite/sqlite_test.go @@ -282,8 +282,8 @@ func TestSqlite_List_Good(t *testing.T) { require.NoError(t, err) names := make(map[string]bool) - for _, e := range entries { - names[e.Name()] = true + for _, entry := range entries { + names[entry.Name()] = true } assert.True(t, names["file1.txt"]) @@ -302,8 +302,8 @@ func TestSqlite_List_Root_Good(t *testing.T) { require.NoError(t, err) names := make(map[string]bool) - for _, e := range entries { - names[e.Name()] = true + for _, entry := range entries { + names[entry.Name()] = true } assert.True(t, names["root.txt"]) @@ -369,15 +369,15 @@ func TestSqlite_Open_Good(t *testing.T) { require.NoError(t, sqliteMedium.Write("file.txt", "open me")) - f, err := sqliteMedium.Open("file.txt") + file, err := sqliteMedium.Open("file.txt") require.NoError(t, err) - defer f.Close() + defer file.Close() - data, err := goio.ReadAll(f.(goio.Reader)) + data, err := goio.ReadAll(file.(goio.Reader)) require.NoError(t, err) assert.Equal(t, "open me", string(data)) - stat, err := f.Stat() + stat, err := file.Stat() require.NoError(t, err) assert.Equal(t, "file.txt", stat.Name()) } @@ -400,14 +400,14 @@ func TestSqlite_Open_IsDirectory_Bad(t *testing.T) { func TestSqlite_Create_Good(t *testing.T) { sqliteMedium := newSqliteMedium(t) - w, err := sqliteMedium.Create("new.txt") + writer, err := sqliteMedium.Create("new.txt") require.NoError(t, err) - n, err := w.Write([]byte("created")) + bytesWritten, err := writer.Write([]byte("created")) require.NoError(t, err) - assert.Equal(t, 7, n) + assert.Equal(t, 7, bytesWritten) - err = w.Close() + err = writer.Close() require.NoError(t, err) content, err := sqliteMedium.Read("new.txt") @@ -420,11 +420,11 @@ func TestSqlite_Create_Overwrite_Good(t *testing.T) { require.NoError(t, sqliteMedium.Write("file.txt", "old content")) - w, err := sqliteMedium.Create("file.txt") + writer, err := sqliteMedium.Create("file.txt") require.NoError(t, err) - _, err = w.Write([]byte("new")) + _, err = writer.Write([]byte("new")) require.NoError(t, err) - require.NoError(t, w.Close()) + require.NoError(t, writer.Close()) content, err := sqliteMedium.Read("file.txt") require.NoError(t, err) @@ -443,12 +443,12 @@ func TestSqlite_Append_Good(t *testing.T) { require.NoError(t, sqliteMedium.Write("append.txt", "hello")) - w, err := sqliteMedium.Append("append.txt") + writer, err := sqliteMedium.Append("append.txt") require.NoError(t, err) - _, err = w.Write([]byte(" world")) + _, err = writer.Write([]byte(" world")) require.NoError(t, err) - require.NoError(t, w.Close()) + require.NoError(t, writer.Close()) content, err := sqliteMedium.Read("append.txt") require.NoError(t, err) @@ -458,12 +458,12 @@ func TestSqlite_Append_Good(t *testing.T) { func TestSqlite_Append_NewFile_Good(t *testing.T) { sqliteMedium := newSqliteMedium(t) - w, err := sqliteMedium.Append("new.txt") + writer, err := sqliteMedium.Append("new.txt") require.NoError(t, err) - _, err = w.Write([]byte("fresh")) + _, err = writer.Write([]byte("fresh")) require.NoError(t, err) - require.NoError(t, w.Close()) + require.NoError(t, writer.Close()) content, err := sqliteMedium.Read("new.txt") require.NoError(t, err) diff --git a/store/medium_test.go b/store/medium_test.go index 2e433f3..4c24269 100644 --- a/store/medium_test.go +++ b/store/medium_test.go @@ -99,9 +99,9 @@ func TestKeyValueMedium_List_Groups_Good(t *testing.T) { assert.Len(t, entries, 2) names := make(map[string]bool) - for _, e := range entries { - names[e.Name()] = true - assert.True(t, e.IsDir()) + for _, entry := range entries { + names[entry.Name()] = true + assert.True(t, entry.IsDir()) } assert.True(t, names["alpha"]) assert.True(t, names["beta"]) @@ -146,11 +146,11 @@ func TestKeyValueMedium_Open_Read_Good(t *testing.T) { keyValueMedium := newKeyValueMedium(t) _ = keyValueMedium.Write("group/key", "hello world") - f, err := keyValueMedium.Open("group/key") + file, err := keyValueMedium.Open("group/key") require.NoError(t, err) - defer f.Close() + defer file.Close() - data, err := io.ReadAll(f) + data, err := io.ReadAll(file) require.NoError(t, err) assert.Equal(t, "hello world", string(data)) } @@ -158,10 +158,10 @@ func TestKeyValueMedium_Open_Read_Good(t *testing.T) { func TestKeyValueMedium_CreateClose_Good(t *testing.T) { keyValueMedium := newKeyValueMedium(t) - w, err := keyValueMedium.Create("group/key") + writer, err := keyValueMedium.Create("group/key") require.NoError(t, err) - _, _ = w.Write([]byte("streamed")) - require.NoError(t, w.Close()) + _, _ = writer.Write([]byte("streamed")) + require.NoError(t, writer.Close()) value, err := keyValueMedium.Read("group/key") require.NoError(t, err) @@ -172,10 +172,10 @@ func TestKeyValueMedium_Append_Good(t *testing.T) { keyValueMedium := newKeyValueMedium(t) _ = keyValueMedium.Write("group/key", "hello") - w, err := keyValueMedium.Append("group/key") + writer, err := keyValueMedium.Append("group/key") require.NoError(t, err) - _, _ = w.Write([]byte(" world")) - require.NoError(t, w.Close()) + _, _ = writer.Write([]byte(" world")) + require.NoError(t, writer.Close()) value, err := keyValueMedium.Read("group/key") require.NoError(t, err) diff --git a/workspace/service.go b/workspace/service.go index ebe78e3..c1bb624 100644 --- a/workspace/service.go +++ b/workspace/service.go @@ -222,7 +222,7 @@ func (service *Service) HandleWorkspaceCommand(command WorkspaceCommand) core.Re } // Example: result := service.HandleWorkspaceMessage(core.New(), WorkspaceCommand{Action: WorkspaceSwitchAction, WorkspaceID: "f3f0d7"}) -func (service *Service) HandleWorkspaceMessage(coreInstance *core.Core, message core.Message) core.Result { +func (service *Service) HandleWorkspaceMessage(_ *core.Core, message core.Message) core.Result { switch command := message.(type) { case WorkspaceCommand: return service.HandleWorkspaceCommand(command) @@ -242,11 +242,14 @@ func resolveWorkspaceHomeDirectory() string { func joinPathWithinRoot(root string, parts ...string) (string, error) { candidate := core.Path(append([]string{root}, parts...)...) - sep := core.Env("DS") - if sep == "" { - sep = "/" + separator := core.Env("CORE_PATH_SEPARATOR") + if separator == "" { + separator = core.Env("DS") } - if candidate == root || core.HasPrefix(candidate, root+sep) { + if separator == "" { + separator = "/" + } + if candidate == root || core.HasPrefix(candidate, root+separator) { return candidate, nil } return "", fs.ErrPermission diff --git a/workspace/service_test.go b/workspace/service_test.go index aab95ed..578ec2c 100644 --- a/workspace/service_test.go +++ b/workspace/service_test.go @@ -119,7 +119,7 @@ func TestService_WriteWorkspaceFile_TraversalBlocked_Bad(t *testing.T) { } func TestService_JoinPathWithinRoot_DefaultSeparator_Good(t *testing.T) { - t.Setenv("DS", "") + t.Setenv("CORE_PATH_SEPARATOR", "") path, err := joinPathWithinRoot("/tmp/workspaces", "../workspaces2") require.Error(t, err)