chore(errors): Better error management

We must remove all "Fatal" calls and use errors instead, to be returned
and managed globally.
This is the first step, but it is, at this time, a real problem. Tests
are complicated without this.
This commit is contained in:
2024-12-03 14:37:13 +01:00
parent eb760d4299
commit e574a2e2a8
5 changed files with 41 additions and 18 deletions

View File

@@ -141,11 +141,11 @@ func generateConvertCommand() *cobra.Command {
convertCmd := &cobra.Command{ convertCmd := &cobra.Command{
Use: "convert", Use: "convert",
Short: "Converts a docker-compose file to a Helm Chart", Short: "Converts a docker-compose file to a Helm Chart",
Run: func(cmd *cobra.Command, args []string) { RunE: func(cmd *cobra.Command, args []string) error {
if givenAppVersion != "" { if givenAppVersion != "" {
appVersion = &givenAppVersion appVersion = &givenAppVersion
} }
generator.Convert(generator.ConvertOptions{ return generator.Convert(generator.ConvertOptions{
Force: force, Force: force,
OutputDir: outputDir, OutputDir: outputDir,
Profiles: profiles, Profiles: profiles,

View File

@@ -1,6 +1,7 @@
package generator package generator
import ( import (
"fmt"
"katenary/generator/labels" "katenary/generator/labels"
"katenary/generator/labels/labelStructs" "katenary/generator/labels/labelStructs"
"katenary/utils" "katenary/utils"
@@ -141,7 +142,7 @@ func NewConfigMapFromDirectory(service types.ServiceConfig, appName, path string
// cumulate the path to the WorkingDir // cumulate the path to the WorkingDir
path = filepath.Join(service.WorkingDir, path) path = filepath.Join(service.WorkingDir, path)
path = filepath.Clean(path) path = filepath.Clean(path)
cm.AppenddDir(path) cm.AppendDir(path)
return cm return cm
} }
@@ -160,17 +161,17 @@ func (c *ConfigMap) AddBinaryData(key string, value []byte) {
// AddFile adds files from given path to the configmap. It is not recursive, to add all files in a directory, // AddFile adds files from given path to the configmap. It is not recursive, to add all files in a directory,
// you need to call this function for each subdirectory. // you need to call this function for each subdirectory.
func (c *ConfigMap) AppenddDir(path string) { func (c *ConfigMap) AppendDir(path string) error {
// read all files in the path and add them to the configmap // read all files in the path and add them to the configmap
stat, err := os.Stat(path) stat, err := os.Stat(path)
if err != nil { if err != nil {
log.Fatalf("Path %s does not exist\n", path) return fmt.Errorf("Path %s does not exist, %w\n", path, err)
} }
// recursively read all files in the path and add them to the configmap // recursively read all files in the path and add them to the configmap
if stat.IsDir() { if stat.IsDir() {
files, err := os.ReadDir(path) files, err := os.ReadDir(path)
if err != nil { if err != nil {
log.Fatal(err) return err
} }
for _, file := range files { for _, file := range files {
if file.IsDir() { if file.IsDir() {
@@ -180,7 +181,7 @@ func (c *ConfigMap) AppenddDir(path string) {
path := filepath.Join(path, file.Name()) path := filepath.Join(path, file.Name())
content, err := os.ReadFile(path) content, err := os.ReadFile(path)
if err != nil { if err != nil {
log.Fatal(err) return err
} }
// remove the path from the file // remove the path from the file
filename := filepath.Base(path) filename := filepath.Base(path)
@@ -195,7 +196,7 @@ func (c *ConfigMap) AppenddDir(path string) {
// add the file to the configmap // add the file to the configmap
content, err := os.ReadFile(path) content, err := os.ReadFile(path)
if err != nil { if err != nil {
log.Fatal(err) return err
} }
filename := filepath.Base(path) filename := filepath.Base(path)
if utf8.Valid(content) { if utf8.Valid(content) {
@@ -204,20 +205,21 @@ func (c *ConfigMap) AppenddDir(path string) {
c.AddBinaryData(filename, content) c.AddBinaryData(filename, content)
} }
} }
return nil
} }
func (c *ConfigMap) AppendFile(path string) { func (c *ConfigMap) AppendFile(path string) error {
// read all files in the path and add them to the configmap // read all files in the path and add them to the configmap
stat, err := os.Stat(path) stat, err := os.Stat(path)
if err != nil { if err != nil {
log.Fatalf("Path %s does not exist\n", path) return fmt.Errorf("Path %s doesn not exists, %w", path, err)
} }
// recursively read all files in the path and add them to the configmap // recursively read all files in the path and add them to the configmap
if !stat.IsDir() { if !stat.IsDir() {
// add the file to the configmap // add the file to the configmap
content, err := os.ReadFile(path) content, err := os.ReadFile(path)
if err != nil { if err != nil {
log.Fatal(err) return err
} }
if utf8.Valid(content) { if utf8.Valid(content) {
c.AddData(filepath.Base(path), string(content)) c.AddData(filepath.Base(path), string(content))
@@ -226,6 +228,7 @@ func (c *ConfigMap) AppendFile(path string) {
} }
} }
return nil
} }
// Filename returns the filename of the configmap. If the configmap is used for files, the filename contains the path. // Filename returns the filename of the configmap. If the configmap is used for files, the filename contains the path.

View File

@@ -6,6 +6,7 @@ import (
"os" "os"
"testing" "testing"
"github.com/compose-spec/compose-go/types"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
) )
@@ -73,3 +74,19 @@ services:
t.Errorf("Expected FOO to be baz, got %s", v) t.Errorf("Expected FOO to be baz, got %s", v)
} }
} }
func TestAppendBadFile(t *testing.T) {
cm := NewConfigMap(types.ServiceConfig{}, "app", true)
err := cm.AppendFile("foo")
if err == nil {
t.Errorf("Expected error, got nil")
}
}
func TestAppendBadDir(t *testing.T) {
cm := NewConfigMap(types.ServiceConfig{}, "app", true)
err := cm.AppendDir("foo")
if err == nil {
t.Errorf("Expected error, got nil")
}
}

View File

@@ -90,7 +90,7 @@ var keyRegExp = regexp.MustCompile(`^\s*[^#]+:.*`)
// Convert a compose (docker, podman...) project to a helm chart. // Convert a compose (docker, podman...) project to a helm chart.
// It calls Generate() to generate the chart and then write it to the disk. // It calls Generate() to generate the chart and then write it to the disk.
func Convert(config ConvertOptions, dockerComposeFile ...string) { func Convert(config ConvertOptions, dockerComposeFile ...string) error {
var ( var (
templateDir = filepath.Join(config.OutputDir, "templates") templateDir = filepath.Join(config.OutputDir, "templates")
helpersPath = filepath.Join(config.OutputDir, "templates", "_helpers.tpl") helpersPath = filepath.Join(config.OutputDir, "templates", "_helpers.tpl")
@@ -105,7 +105,7 @@ func Convert(config ConvertOptions, dockerComposeFile ...string) {
// go to the root of the project // go to the root of the project
if err := os.Chdir(filepath.Dir(dockerComposeFile[0])); err != nil { if err := os.Chdir(filepath.Dir(dockerComposeFile[0])); err != nil {
fmt.Println(utils.IconFailure, err) fmt.Println(utils.IconFailure, err)
os.Exit(1) return err
} }
defer os.Chdir(currentDir) // after the generation, go back to the original directory defer os.Chdir(currentDir) // after the generation, go back to the original directory
@@ -118,13 +118,13 @@ func Convert(config ConvertOptions, dockerComposeFile ...string) {
project, err := parser.Parse(config.Profiles, config.EnvFiles, dockerComposeFile...) project, err := parser.Parse(config.Profiles, config.EnvFiles, dockerComposeFile...)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
os.Exit(1) return err
} }
// check older version of labels // check older version of labels
if err := checkOldLabels(project); err != nil { if err := checkOldLabels(project); err != nil {
fmt.Println(utils.IconFailure, err) fmt.Println(utils.IconFailure, err)
os.Exit(1) return err
} }
// TODO: use katenary.yaml file here to set the labels // TODO: use katenary.yaml file here to set the labels
@@ -140,7 +140,7 @@ func Convert(config ConvertOptions, dockerComposeFile ...string) {
) )
if !overwrite { if !overwrite {
fmt.Println("Aborting") fmt.Println("Aborting")
os.Exit(126) // 126 is the exit code for "Command invoked cannot execute" return nil
} }
} }
fmt.Println() // clean line fmt.Println() // clean line
@@ -150,7 +150,7 @@ func Convert(config ConvertOptions, dockerComposeFile ...string) {
chart, err := Generate(project) chart, err := Generate(project)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
os.Exit(1) return err
} }
// if the app version is set from the command line, use it // if the app version is set from the command line, use it
@@ -194,6 +194,7 @@ func Convert(config ConvertOptions, dockerComposeFile ...string) {
// call helm update if needed // call helm update if needed
callHelmUpdate(config) callHelmUpdate(config)
return nil
} }
func addChartDoc(values []byte, project *types.Project) []byte { func addChartDoc(values []byte, project *types.Project) []byte {

View File

@@ -48,7 +48,9 @@ func internalCompileTest(t *testing.T, options ...string) string {
AppVersion: appVersion, AppVersion: appVersion,
ChartVersion: chartVersion, ChartVersion: chartVersion,
} }
Convert(convertOptions, "compose.yml") if err := Convert(convertOptions, "compose.yml"); err != nil {
return err.Error()
}
// launch helm lint to check the generated chart // launch helm lint to check the generated chart
if helmLint(convertOptions) != nil { if helmLint(convertOptions) != nil {