feat(tests): Fixing linter problems
Using golangci-lint
This commit is contained in:
26
.golangci.yml
Normal file
26
.golangci.yml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
version: "2"
|
||||||
|
run:
|
||||||
|
issues-exit-code: 1
|
||||||
|
linters:
|
||||||
|
enabled:
|
||||||
|
- unused
|
||||||
|
exclusions:
|
||||||
|
generated: lax
|
||||||
|
presets:
|
||||||
|
- comments
|
||||||
|
- common-false-positives
|
||||||
|
- legacy
|
||||||
|
- std-error-handling
|
||||||
|
paths:
|
||||||
|
- third_party$
|
||||||
|
- builtin$
|
||||||
|
- examples$
|
||||||
|
- "(.+)_test.go"
|
||||||
|
formatters:
|
||||||
|
exclusions:
|
||||||
|
generated: lax
|
||||||
|
paths:
|
||||||
|
- third_party$
|
||||||
|
- builtin$
|
||||||
|
- examples$
|
||||||
|
- "(.+)_test.go"
|
@@ -10,6 +10,7 @@ import (
|
|||||||
"katenary/generator/katenaryfile"
|
"katenary/generator/katenaryfile"
|
||||||
"katenary/generator/labels"
|
"katenary/generator/labels"
|
||||||
"katenary/utils"
|
"katenary/utils"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -24,7 +25,10 @@ Each [command] and subcommand has got an "help" and "--help" flag to show more i
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rootCmd := buildRootCmd()
|
rootCmd := buildRootCmd()
|
||||||
rootCmd.Execute()
|
|
||||||
|
if err := rootCmd.Execute(); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildRootCmd() *cobra.Command {
|
func buildRootCmd() *cobra.Command {
|
||||||
@@ -97,26 +101,26 @@ func generateCompletionCommand(name string) *cobra.Command {
|
|||||||
Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs),
|
Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs),
|
||||||
Short: "Generates completion scripts",
|
Short: "Generates completion scripts",
|
||||||
Long: fmt.Sprintf(completionHelp, name),
|
Long: fmt.Sprintf(completionHelp, name),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
cmd.Help()
|
return cmd.Help()
|
||||||
return
|
|
||||||
}
|
}
|
||||||
switch args[0] {
|
switch args[0] {
|
||||||
case "bash":
|
case "bash":
|
||||||
// get the bash version
|
// get the bash version
|
||||||
if cmd.Flags().Changed("bash-v1") {
|
if cmd.Flags().Changed("bash-v1") {
|
||||||
cmd.Root().GenBashCompletion(os.Stdout)
|
return cmd.Root().GenBashCompletion(os.Stdout)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
cmd.Root().GenBashCompletionV2(os.Stdout, true)
|
return cmd.Root().GenBashCompletionV2(os.Stdout, true)
|
||||||
case "zsh":
|
case "zsh":
|
||||||
cmd.Root().GenZshCompletion(os.Stdout)
|
return cmd.Root().GenZshCompletion(os.Stdout)
|
||||||
case "fish":
|
case "fish":
|
||||||
cmd.Root().GenFishCompletion(os.Stdout, true)
|
return cmd.Root().GenFishCompletion(os.Stdout, true)
|
||||||
case "powershell":
|
case "powershell":
|
||||||
cmd.Root().GenPowerShellCompletion(os.Stdout)
|
return cmd.Root().GenPowerShellCompletion(os.Stdout)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("unknown completion type: %s", args[0])
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -117,8 +117,13 @@ func (chart *HelmChart) SaveTemplates(templateDir string) {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
f.Write(t)
|
if _, err := f.Write(t); err != nil {
|
||||||
f.Close()
|
log.Fatal("error writing template file:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := f.Close(); err != nil {
|
||||||
|
log.Fatal("error closing template file:", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,7 +131,7 @@ func (chart *HelmChart) SaveTemplates(templateDir string) {
|
|||||||
func (chart *HelmChart) generateConfigMapsAndSecrets(project *types.Project) error {
|
func (chart *HelmChart) generateConfigMapsAndSecrets(project *types.Project) error {
|
||||||
appName := chart.Name
|
appName := chart.Name
|
||||||
for _, s := range project.Services {
|
for _, s := range project.Services {
|
||||||
if s.Environment == nil || len(s.Environment) == 0 {
|
if len(s.Environment) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -142,7 +142,9 @@ 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.AppendDir(path)
|
if err := cm.AppendDir(path); err != nil {
|
||||||
|
log.Fatal("Error adding files to configmap:", err)
|
||||||
|
}
|
||||||
return cm
|
return cm
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,7 +167,7 @@ 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 {
|
||||||
return fmt.Errorf("Path %s does not exist, %w\n", path, err)
|
return fmt.Errorf("path %s does not exist, %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() {
|
||||||
@@ -212,7 +214,7 @@ 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 {
|
||||||
return fmt.Errorf("Path %s doesn not exists, %w", path, err)
|
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() {
|
||||||
|
@@ -113,7 +113,11 @@ func Convert(config ConvertOptions, dockerComposeFile ...string) error {
|
|||||||
fmt.Println(utils.IconFailure, err)
|
fmt.Println(utils.IconFailure, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer os.Chdir(currentDir) // after the generation, go back to the original directory
|
defer func() {
|
||||||
|
if err := os.Chdir(currentDir); err != nil { // after the generation, go back to the original directory
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
// repove the directory part of the docker-compose files
|
// repove the directory part of the docker-compose files
|
||||||
for i, f := range dockerComposeFile {
|
for i, f := range dockerComposeFile {
|
||||||
@@ -626,8 +630,14 @@ func writeContent(path string, content []byte) {
|
|||||||
fmt.Println(utils.IconFailure, err)
|
fmt.Println(utils.IconFailure, err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer func() {
|
||||||
f.Write(content)
|
if err := f.Close(); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err := f.Write(content); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
// helmLint runs "helm lint" on the output directory.
|
// helmLint runs "helm lint" on the output directory.
|
||||||
|
@@ -305,10 +305,7 @@ func (d *Deployment) SetEnvFrom(service types.ServiceConfig, appName string, sam
|
|||||||
if len(service.Environment) == 0 {
|
if len(service.Environment) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
inSamePod := false
|
inSamePod := len(samePod) > 0 && samePod[0]
|
||||||
if len(samePod) > 0 && samePod[0] {
|
|
||||||
inSamePod = true
|
|
||||||
}
|
|
||||||
|
|
||||||
drop := []string{}
|
drop := []string{}
|
||||||
secrets := []string{}
|
secrets := []string{}
|
||||||
@@ -660,7 +657,9 @@ func (d *Deployment) appendFileToConfigMap(service types.ServiceConfig, appName
|
|||||||
d.configMaps[pathname].mountPath = mp
|
d.configMaps[pathname].mountPath = mp
|
||||||
|
|
||||||
}
|
}
|
||||||
cm.AppendFile(volume.Source)
|
if err := cm.AppendFile(volume.Source); err != nil {
|
||||||
|
log.Fatal("Error adding file to configmap:", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Deployment) bindVolumes(volume types.ServiceVolumeConfig, isSamePod bool, tobind map[string]bool, service types.ServiceConfig, appName string) {
|
func (d *Deployment) bindVolumes(volume types.ServiceVolumeConfig, isSamePod bool, tobind map[string]bool, service types.ServiceConfig, appName string) {
|
||||||
|
@@ -4,6 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
_ "embed"
|
_ "embed"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
@@ -48,7 +49,9 @@ func ReadMeFile(charname, description string, values map[string]any) string {
|
|||||||
|
|
||||||
vv := map[string]any{}
|
vv := map[string]any{}
|
||||||
out, _ := yaml.Marshal(values)
|
out, _ := yaml.Marshal(values)
|
||||||
yaml.Unmarshal(out, &vv)
|
if err := yaml.Unmarshal(out, &vv); err != nil {
|
||||||
|
log.Printf("Error parsing values: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
result := make(map[string]string)
|
result := make(map[string]string)
|
||||||
parseValues("", vv, result)
|
parseValues("", vv, result)
|
||||||
|
@@ -117,7 +117,10 @@ func Generate(project *types.Project) (*HelmChart, error) {
|
|||||||
for _, s := range project.Services {
|
for _, s := range project.Services {
|
||||||
for _, d := range s.GetDependencies() {
|
for _, d := range s.GetDependencies() {
|
||||||
if dep, ok := deployments[d]; ok {
|
if dep, ok := deployments[d]; ok {
|
||||||
deployments[s.Name].DependsOn(dep, d)
|
err := deployments[s.Name].DependsOn(dep, d)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("error creating init container for service %[1]s: %[2]s", s.Name, err)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Printf("service %[1]s depends on %[2]s, but %[2]s is not defined", s.Name, d)
|
log.Printf("service %[1]s depends on %[2]s, but %[2]s is not defined", s.Name, d)
|
||||||
}
|
}
|
||||||
@@ -129,7 +132,9 @@ func Generate(project *types.Project) (*HelmChart, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// generate configmaps with environment variables
|
// generate configmaps with environment variables
|
||||||
chart.generateConfigMapsAndSecrets(project)
|
if err := chart.generateConfigMapsAndSecrets(project); err != nil {
|
||||||
|
log.Fatalf("error generating configmaps and secrets: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
// if the env-from label is set, we need to add the env vars from the configmap
|
// if the env-from label is set, we need to add the env vars from the configmap
|
||||||
// to the environment of the service
|
// to the environment of the service
|
||||||
@@ -385,7 +390,7 @@ func samePodVolume(service types.ServiceConfig, v types.ServiceVolumeConfig, dep
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if service.Volumes == nil || len(service.Volumes) == 0 {
|
if len(service.Volumes) == 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -75,24 +75,30 @@ func OverrideWithConfig(project *types.Project) {
|
|||||||
if project.Services[i].Labels == nil {
|
if project.Services[i].Labels == nil {
|
||||||
project.Services[i].Labels = make(map[string]string)
|
project.Services[i].Labels = make(map[string]string)
|
||||||
}
|
}
|
||||||
|
mustGetLabelContent := func(o any, s *types.ServiceConfig, labelName string) {
|
||||||
|
err := getLabelContent(o, s, labelName)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if s, ok := services[name]; ok {
|
if s, ok := services[name]; ok {
|
||||||
getLabelContent(s.MainApp, &project.Services[i], labels.LabelMainApp)
|
mustGetLabelContent(s.MainApp, &project.Services[i], labels.LabelMainApp)
|
||||||
getLabelContent(s.Values, &project.Services[i], labels.LabelValues)
|
mustGetLabelContent(s.Values, &project.Services[i], labels.LabelValues)
|
||||||
getLabelContent(s.Secrets, &project.Services[i], labels.LabelSecrets)
|
mustGetLabelContent(s.Secrets, &project.Services[i], labels.LabelSecrets)
|
||||||
getLabelContent(s.Ports, &project.Services[i], labels.LabelPorts)
|
mustGetLabelContent(s.Ports, &project.Services[i], labels.LabelPorts)
|
||||||
getLabelContent(s.Ingress, &project.Services[i], labels.LabelIngress)
|
mustGetLabelContent(s.Ingress, &project.Services[i], labels.LabelIngress)
|
||||||
getLabelContent(s.HealthCheck, &project.Services[i], labels.LabelHealthCheck)
|
mustGetLabelContent(s.HealthCheck, &project.Services[i], labels.LabelHealthCheck)
|
||||||
getLabelContent(s.SamePod, &project.Services[i], labels.LabelSamePod)
|
mustGetLabelContent(s.SamePod, &project.Services[i], labels.LabelSamePod)
|
||||||
getLabelContent(s.Description, &project.Services[i], labels.LabelDescription)
|
mustGetLabelContent(s.Description, &project.Services[i], labels.LabelDescription)
|
||||||
getLabelContent(s.Ignore, &project.Services[i], labels.LabelIgnore)
|
mustGetLabelContent(s.Ignore, &project.Services[i], labels.LabelIgnore)
|
||||||
getLabelContent(s.Dependencies, &project.Services[i], labels.LabelDependencies)
|
mustGetLabelContent(s.Dependencies, &project.Services[i], labels.LabelDependencies)
|
||||||
getLabelContent(s.ConfigMapFile, &project.Services[i], labels.LabelConfigMapFiles)
|
mustGetLabelContent(s.ConfigMapFile, &project.Services[i], labels.LabelConfigMapFiles)
|
||||||
getLabelContent(s.MapEnv, &project.Services[i], labels.LabelMapEnv)
|
mustGetLabelContent(s.MapEnv, &project.Services[i], labels.LabelMapEnv)
|
||||||
getLabelContent(s.CronJob, &project.Services[i], labels.LabelCronJob)
|
mustGetLabelContent(s.CronJob, &project.Services[i], labels.LabelCronJob)
|
||||||
getLabelContent(s.EnvFrom, &project.Services[i], labels.LabelEnvFrom)
|
mustGetLabelContent(s.EnvFrom, &project.Services[i], labels.LabelEnvFrom)
|
||||||
getLabelContent(s.ExchangeVolumes, &project.Services[i], labels.LabelExchangeVolume)
|
mustGetLabelContent(s.ExchangeVolumes, &project.Services[i], labels.LabelExchangeVolume)
|
||||||
getLabelContent(s.ValuesFrom, &project.Services[i], labels.LabelValueFrom)
|
mustGetLabelContent(s.ValuesFrom, &project.Services[i], labels.LabelValueFrom)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Println(utils.IconInfo, "Katenary file loaded successfully, the services are now configured.")
|
fmt.Println(utils.IconInfo, "Katenary file loaded successfully, the services are now configured.")
|
||||||
@@ -155,5 +161,5 @@ func GenerateSchema() string {
|
|||||||
return err.Error()
|
return err.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
return string(out.Bytes())
|
return out.String()
|
||||||
}
|
}
|
||||||
|
@@ -5,6 +5,7 @@ import (
|
|||||||
_ "embed"
|
_ "embed"
|
||||||
"fmt"
|
"fmt"
|
||||||
"katenary/utils"
|
"katenary/utils"
|
||||||
|
"log"
|
||||||
"regexp"
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -125,23 +126,30 @@ func GetLabelHelpFor(labelname string, asMarkdown bool) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
template.Must(template.New("shorthelp").Parse(help.Long)).Execute(&buf, struct {
|
var err error
|
||||||
|
err = template.Must(template.New("shorthelp").Parse(help.Long)).Execute(&buf, struct {
|
||||||
KatenaryPrefix string
|
KatenaryPrefix string
|
||||||
}{
|
}{
|
||||||
KatenaryPrefix: KatenaryLabelPrefix,
|
KatenaryPrefix: KatenaryLabelPrefix,
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error executing template: %v", err)
|
||||||
|
}
|
||||||
help.Long = buf.String()
|
help.Long = buf.String()
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
|
|
||||||
template.Must(template.New("example").Parse(help.Example)).Execute(&buf, struct {
|
err = template.Must(template.New("example").Parse(help.Example)).Execute(&buf, struct {
|
||||||
KatenaryPrefix string
|
KatenaryPrefix string
|
||||||
}{
|
}{
|
||||||
KatenaryPrefix: KatenaryLabelPrefix,
|
KatenaryPrefix: KatenaryLabelPrefix,
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error executing template: %v", err)
|
||||||
|
}
|
||||||
help.Example = buf.String()
|
help.Example = buf.String()
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
|
|
||||||
template.Must(template.New("complete").Parse(helpTemplate)).Execute(&buf, struct {
|
err = template.Must(template.New("complete").Parse(helpTemplate)).Execute(&buf, struct {
|
||||||
Name string
|
Name string
|
||||||
Help Help
|
Help Help
|
||||||
KatenaryPrefix string
|
KatenaryPrefix string
|
||||||
@@ -150,6 +158,9 @@ func GetLabelHelpFor(labelname string, asMarkdown bool) string {
|
|||||||
Help: help,
|
Help: help,
|
||||||
KatenaryPrefix: KatenaryLabelPrefix,
|
KatenaryPrefix: KatenaryLabelPrefix,
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error executing template: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
return buf.String()
|
return buf.String()
|
||||||
}
|
}
|
||||||
|
60
parser/main_test.go
Normal file
60
parser/main_test.go
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package parser
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
const composeFile = `
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
image: nginx:latest
|
||||||
|
`
|
||||||
|
|
||||||
|
func setupTest() (string, error) {
|
||||||
|
// write the composeFile to a temporary file
|
||||||
|
tmpDir, err := os.MkdirTemp("", "katenary-test-parse")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
writeFile := filepath.Join(tmpDir, "compose.yaml")
|
||||||
|
writeErr := os.WriteFile(writeFile, []byte(composeFile), 0644)
|
||||||
|
return writeFile, writeErr
|
||||||
|
}
|
||||||
|
|
||||||
|
func tearDownTest(tmpDir string) {
|
||||||
|
if tmpDir != "" {
|
||||||
|
if err := os.RemoveAll(tmpDir); err != nil {
|
||||||
|
log.Fatalf("Failed to remove temporary directory %s: %s", tmpDir, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParse(t *testing.T) {
|
||||||
|
file, err := setupTest()
|
||||||
|
dirname := filepath.Dir(file)
|
||||||
|
currentDir, _ := os.Getwd()
|
||||||
|
if err := os.Chdir(dirname); err != nil {
|
||||||
|
t.Fatalf("Failed to change directory to %s: %s", dirname, err.Error())
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
tearDownTest(dirname)
|
||||||
|
if err := os.Chdir(currentDir); err != nil {
|
||||||
|
t.Fatalf("Failed to change back to original directory %s: %s", currentDir, err.Error())
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to setup test: %s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
Project, err := Parse(nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to parse compose file: %s", err.Error())
|
||||||
|
}
|
||||||
|
if Project == nil {
|
||||||
|
t.Fatal("Expected project to be not nil")
|
||||||
|
}
|
||||||
|
}
|
13
utils/hash_test.go
Normal file
13
utils/hash_test.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestHash(t *testing.T) {
|
||||||
|
h, err := HashComposefiles([]string{"./hash.go"})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to hash compose files: %v", err)
|
||||||
|
}
|
||||||
|
if len(h) == 0 {
|
||||||
|
t.Fatal("hash should not be empty")
|
||||||
|
}
|
||||||
|
}
|
@@ -165,7 +165,9 @@ func Confirm(question string, icon ...Icon) bool {
|
|||||||
fmt.Print(question + " [y/N] ")
|
fmt.Print(question + " [y/N] ")
|
||||||
}
|
}
|
||||||
var response string
|
var response string
|
||||||
fmt.Scanln(&response)
|
if _, err := fmt.Scanln(&response); err != nil {
|
||||||
|
log.Fatalf("Error parsing response: %s", err.Error())
|
||||||
|
}
|
||||||
return strings.ToLower(response) == "y"
|
return strings.ToLower(response) == "y"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user