feat: print warning on some unsupported compose features (#288)

* feat: error on unsupported compose features

This implements a check for the unimplemented features of the uncloud
support matrix and points to the matrix in the error.

Fixes: #237

This redos #277, as I messed up my branch, (basically rebase gone
wrong).

Signed-off-by: Miek Gieben <miek@miek.nl>

* Fix tests by capturing stderr

The error should be nil, but we _do_ want to know if the user saw an
warning. Redirect stderr to capture this as the error is emited by
printing to stderr.

Signed-off-by: Miek Gieben <miek@miek.nl>

---------

Signed-off-by: Miek Gieben <miek@miek.nl>
This commit is contained in:
Miek Gieben
2026-03-31 16:37:35 +10:00
committed by GitHub
parent 636307d3ea
commit d38312fec6
3 changed files with 143 additions and 0 deletions
+89
View File
@@ -2,6 +2,7 @@ package compose
import (
"context"
"io"
"os"
"path/filepath"
"testing"
@@ -186,3 +187,91 @@ REDIS_URL=redis://localhost:6379
})
}
}
// TestLoadProject_Unsupported checks that unsupported features lead to an error.
func TestLoadProject_Unsupported(t *testing.T) {
requireWarning := func(t *testing.T, r io.Reader) {
p := make([]byte, 15) // also room for the (color) escapes
io.ReadFull(r, p)
require.Contains(t, string(p), "WARNING:")
}
tests := []struct {
name string
composeYAML string
verify func(t *testing.T, projectDir string)
}{
{
name: "unsupported dns",
composeYAML: `services:
app:
image: myapp:latest
dns: 8.8.8.8
`,
verify: func(t *testing.T, projectDir string) {
old := os.Stderr
var r io.ReadCloser
defer func() { os.Stderr = old }()
r, os.Stderr, _ = os.Pipe()
defer r.Close()
defer os.Stderr.Close()
_, err := LoadProject(context.Background(), []string{filepath.Join(projectDir, "compose.yaml")})
require.NoError(t, err)
requireWarning(t, r)
},
},
{
name: "unsupported networks",
composeYAML: `services:
app:
image: myapp:latest
networks:
- frontend
networks:
frontend:
`,
verify: func(t *testing.T, projectDir string) {
old := os.Stderr
var r io.ReadCloser
defer func() { os.Stderr = old }()
r, os.Stderr, _ = os.Pipe()
defer r.Close()
defer os.Stderr.Close()
_, err := LoadProject(context.Background(), []string{filepath.Join(projectDir, "compose.yaml")})
require.NoError(t, err)
requireWarning(t, r)
},
},
{
name: "supported networks",
composeYAML: `services:
app:
image: myapp:latest
networks:
- default
networks:
default: {}
`,
verify: func(t *testing.T, projectDir string) {
_, err := LoadProject(context.Background(), []string{filepath.Join(projectDir, "compose.yaml")})
require.NoError(t, err)
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tempDir := t.TempDir()
composeFile := filepath.Join(tempDir, "compose.yaml")
err := os.WriteFile(composeFile, []byte(tt.composeYAML), 0o644)
require.NoError(t, err)
tt.verify(t, tempDir)
})
}
}