Develop #118

Merged
metal3d merged 4 commits from develop into master 2025-06-04 13:22:09 +00:00
27 changed files with 346 additions and 200 deletions

26
.golangci.yml Normal file
View 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"

View File

@@ -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])
}, },
} }

View File

@@ -0,0 +1,5 @@
MD012: false
MD013: false
MD022: false
MD033: false
MD046: false

View File

@@ -61,7 +61,6 @@ labels:
- ./conf.d - ./conf.d
``` ```
### katenary.v3/cronjob ### katenary.v3/cronjob
Create a cronjob from the service. Create a cronjob from the service.
@@ -71,6 +70,7 @@ Create a cronjob from the service.
This adds a cronjob to the chart. This adds a cronjob to the chart.
The label value is a YAML object with the following attributes: The label value is a YAML object with the following attributes:
- command: the command to be executed - command: the command to be executed
- schedule: the cron schedule (cron format or @every where "every" is a - schedule: the cron schedule (cron format or @every where "every" is a
duration like 1h30m, daily, hourly...) duration like 1h30m, daily, hourly...)
@@ -86,7 +86,6 @@ labels:
schedule: "* */1 * * *" # or @hourly for example schedule: "* */1 * * *" # or @hourly for example
``` ```
### katenary.v3/dependencies ### katenary.v3/dependencies
Add Helm dependencies to the service. Add Helm dependencies to the service.
@@ -133,7 +132,6 @@ labels:
password: the secret password password: the secret password
``` ```
### katenary.v3/description ### katenary.v3/description
Description of the service Description of the service
@@ -154,7 +152,6 @@ labels:
It can be multiline. It can be multiline.
``` ```
### katenary.v3/env-from ### katenary.v3/env-from
Add environment variables from antoher service. Add environment variables from antoher service.
@@ -180,7 +177,6 @@ service2:
- myservice1 - myservice1
``` ```
### katenary.v3/exchange-volumes ### katenary.v3/exchange-volumes
Add exchange volumes (empty directory on the node) to share data Add exchange volumes (empty directory on the node) to share data
@@ -198,9 +194,10 @@ This will create:
- a `initContainer` for each definition - a `initContainer` for each definition
Fields: Fields:
- name: the name of the volume (manadatory)
- mountPath: the path where the volume is mounted in the pod (optional, default is `/opt`) - name: the name of the volume (manadatory)
- init: a command to run to initialize the volume with data (optional) - mountPath: the path where the volume is mounted in the pod (optional, default is `/opt`)
- init: a command to run to initialize the volume with data (optional)
!!! Warning !!! Warning
This is highly experimental. This is mainly useful when using the "same-pod" label. This is highly experimental. This is mainly useful when using the "same-pod" label.
@@ -223,7 +220,6 @@ php:
init: cp -ra /var/www/html/* /opt init: cp -ra /var/www/html/* /opt
``` ```
### katenary.v3/health-check ### katenary.v3/health-check
Health check to be added to the deployment. Health check to be added to the deployment.
@@ -243,7 +239,6 @@ labels:
port: 8080 port: 8080
``` ```
### katenary.v3/ignore ### katenary.v3/ignore
Ignore the service Ignore the service
@@ -259,7 +254,6 @@ labels:
katenary.v3/ignore: "true" katenary.v3/ignore: "true"
``` ```
### katenary.v3/ingress ### katenary.v3/ingress
Ingress rules to be added to the service. Ingress rules to be added to the service.
@@ -278,7 +272,6 @@ labels:
hostname: mywebsite.com (optional) hostname: mywebsite.com (optional)
``` ```
### katenary.v3/main-app ### katenary.v3/main-app
Mark the service as the main app. Mark the service as the main app.
@@ -305,7 +298,6 @@ ghost:
katenary.v3/main-app: true katenary.v3/main-app: true
``` ```
### katenary.v3/map-env ### katenary.v3/map-env
Map env vars from the service to the deployment. Map env vars from the service to the deployment.
@@ -333,7 +325,6 @@ labels:
DB_HOST: '{{ include "__APP__.fullname" . }}-database' DB_HOST: '{{ include "__APP__.fullname" . }}-database'
``` ```
### katenary.v3/ports ### katenary.v3/ports
Ports to be added to the service. Ports to be added to the service.
@@ -352,7 +343,6 @@ labels:
- 8081 - 8081
``` ```
### katenary.v3/same-pod ### katenary.v3/same-pod
Move the same-pod deployment to the target deployment. Move the same-pod deployment to the target deployment.
@@ -377,7 +367,6 @@ php:
katenary.v3/same-pod: web katenary.v3/same-pod: web
``` ```
### katenary.v3/secrets ### katenary.v3/secrets
Env vars to be set as secrets. Env vars to be set as secrets.
@@ -401,7 +390,6 @@ labels:
- PASSWORD - PASSWORD
``` ```
### katenary.v3/values ### katenary.v3/values
Environment variables to be added to the values.yaml Environment variables to be added to the values.yaml
@@ -438,7 +426,6 @@ labels:
It can be, of course, a multiline text. It can be, of course, a multiline text.
``` ```
### katenary.v3/values-from ### katenary.v3/values-from
Add values from another service. Add values from another service.
@@ -460,9 +447,9 @@ database:
MARIADB_USER: myuser MARIADB_USER: myuser
MARIADB_PASSWORD: mypassword MARIADB_PASSWORD: mypassword
labels: labels:
# it can be a secret # we can declare secrets
katenary.v3/secrets: |- katenary.v3/secrets: |-
- DB_PASSWORD - MARIADB_PASSWORD
php: php:
image: php:7.4-fpm image: php:7.4-fpm
environment: environment:
@@ -476,5 +463,4 @@ php:
DB_PASSWORD: database.MARIADB_PASSWORD DB_PASSWORD: database.MARIADB_PASSWORD
``` ```
<!-- STOP_DETAILED_DOC : do not remove this tag !--> <!-- STOP_DETAILED_DOC : do not remove this tag !-->

View File

@@ -35,7 +35,7 @@ var Version = "master" // changed at compile time
``` ```
<a name="Convert"></a> <a name="Convert"></a>
## func [Convert](<https://github.com/metal3d/katenary/blob/develop/generator/converter.go#L93>) ## func [Convert](<https://github.com/metal3d/katenary/blob/develop/generator/converter.go#L99>)
```go ```go
func Convert(config ConvertOptions, dockerComposeFile ...string) error func Convert(config ConvertOptions, dockerComposeFile ...string) error
@@ -92,7 +92,7 @@ NewCronJob creates a new CronJob from a compose service. The appName is the name
## func [ToK8SYaml](<https://github.com/metal3d/katenary/blob/develop/generator/utils.go#L90>) ## func [ToK8SYaml](<https://github.com/metal3d/katenary/blob/develop/generator/utils.go#L90>)
```go ```go
func ToK8SYaml(obj interface{}) ([]byte, error) func ToK8SYaml(obj any) ([]byte, error)
``` ```
@@ -149,7 +149,7 @@ func NewConfigMapFromDirectory(service types.ServiceConfig, appName, path string
NewConfigMapFromDirectory creates a new ConfigMap from a compose service. This path is the path to the file or directory. If the path is a directory, all files in the directory are added to the ConfigMap. Each subdirectory are ignored. Note that the Generate\(\) function will create the subdirectories ConfigMaps. NewConfigMapFromDirectory creates a new ConfigMap from a compose service. This path is the path to the file or directory. If the path is a directory, all files in the directory are added to the ConfigMap. Each subdirectory are ignored. Note that the Generate\(\) function will create the subdirectories ConfigMaps.
<a name="ConfigMap.AddBinaryData"></a> <a name="ConfigMap.AddBinaryData"></a>
### func \(\*ConfigMap\) [AddBinaryData](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L155>) ### func \(\*ConfigMap\) [AddBinaryData](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L157>)
```go ```go
func (c *ConfigMap) AddBinaryData(key string, value []byte) func (c *ConfigMap) AddBinaryData(key string, value []byte)
@@ -158,7 +158,7 @@ func (c *ConfigMap) AddBinaryData(key string, value []byte)
AddBinaryData adds binary data to the configmap. Append or overwrite the value if the key already exists. AddBinaryData adds binary data to the configmap. Append or overwrite the value if the key already exists.
<a name="ConfigMap.AddData"></a> <a name="ConfigMap.AddData"></a>
### func \(\*ConfigMap\) [AddData](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L150>) ### func \(\*ConfigMap\) [AddData](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L152>)
```go ```go
func (c *ConfigMap) AddData(key, value string) func (c *ConfigMap) AddData(key, value string)
@@ -167,7 +167,7 @@ func (c *ConfigMap) AddData(key, value string)
AddData adds a key value pair to the configmap. Append or overwrite the value if the key already exists. AddData adds a key value pair to the configmap. Append or overwrite the value if the key already exists.
<a name="ConfigMap.AppendDir"></a> <a name="ConfigMap.AppendDir"></a>
### func \(\*ConfigMap\) [AppendDir](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L164>) ### func \(\*ConfigMap\) [AppendDir](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L166>)
```go ```go
func (c *ConfigMap) AppendDir(path string) error func (c *ConfigMap) AppendDir(path string) error
@@ -176,7 +176,7 @@ func (c *ConfigMap) AppendDir(path string) error
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. 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.
<a name="ConfigMap.AppendFile"></a> <a name="ConfigMap.AppendFile"></a>
### func \(\*ConfigMap\) [AppendFile](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L211>) ### func \(\*ConfigMap\) [AppendFile](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L213>)
```go ```go
func (c *ConfigMap) AppendFile(path string) error func (c *ConfigMap) AppendFile(path string) error
@@ -185,7 +185,7 @@ func (c *ConfigMap) AppendFile(path string) error
<a name="ConfigMap.Filename"></a> <a name="ConfigMap.Filename"></a>
### func \(\*ConfigMap\) [Filename](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L235>) ### func \(\*ConfigMap\) [Filename](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L237>)
```go ```go
func (c *ConfigMap) Filename() string func (c *ConfigMap) Filename() string
@@ -194,7 +194,7 @@ func (c *ConfigMap) Filename() string
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.
<a name="ConfigMap.SetData"></a> <a name="ConfigMap.SetData"></a>
### func \(\*ConfigMap\) [SetData](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L245>) ### func \(\*ConfigMap\) [SetData](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L247>)
```go ```go
func (c *ConfigMap) SetData(data map[string]string) func (c *ConfigMap) SetData(data map[string]string)
@@ -203,7 +203,7 @@ func (c *ConfigMap) SetData(data map[string]string)
SetData sets the data of the configmap. It replaces the entire data. SetData sets the data of the configmap. It replaces the entire data.
<a name="ConfigMap.Yaml"></a> <a name="ConfigMap.Yaml"></a>
### func \(\*ConfigMap\) [Yaml](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L250>) ### func \(\*ConfigMap\) [Yaml](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L252>)
```go ```go
func (c *ConfigMap) Yaml() ([]byte, error) func (c *ConfigMap) Yaml() ([]byte, error)
@@ -275,7 +275,7 @@ Yaml returns the yaml representation of the cronjob.
Implements the Yaml interface. Implements the Yaml interface.
<a name="CronJobValue"></a> <a name="CronJobValue"></a>
## type [CronJobValue](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L113-L118>) ## type [CronJobValue](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L118-L123>)
CronJobValue is a cronjob configuration that will be saved in values.yaml. CronJobValue is a cronjob configuration that will be saved in values.yaml.
@@ -376,7 +376,7 @@ func (d *Deployment) BindFrom(service types.ServiceConfig, binded *Deployment)
<a name="Deployment.BindMapFilesToContainer"></a> <a name="Deployment.BindMapFilesToContainer"></a>
### func \(\*Deployment\) [BindMapFilesToContainer](<https://github.com/metal3d/katenary/blob/develop/generator/deployment.go#L377>) ### func \(\*Deployment\) [BindMapFilesToContainer](<https://github.com/metal3d/katenary/blob/develop/generator/deployment.go#L374>)
```go ```go
func (d *Deployment) BindMapFilesToContainer(service types.ServiceConfig, secrets []string, appName string) (*corev1.Container, int) func (d *Deployment) BindMapFilesToContainer(service types.ServiceConfig, secrets []string, appName string) (*corev1.Container, int)
@@ -403,7 +403,7 @@ func (d *Deployment) Filename() string
Filename returns the filename of the deployment. Filename returns the filename of the deployment.
<a name="Deployment.MountExchangeVolumes"></a> <a name="Deployment.MountExchangeVolumes"></a>
### func \(\*Deployment\) [MountExchangeVolumes](<https://github.com/metal3d/katenary/blob/develop/generator/deployment.go#L428>) ### func \(\*Deployment\) [MountExchangeVolumes](<https://github.com/metal3d/katenary/blob/develop/generator/deployment.go#L425>)
```go ```go
func (d *Deployment) MountExchangeVolumes() func (d *Deployment) MountExchangeVolumes()
@@ -421,7 +421,7 @@ func (d *Deployment) SetEnvFrom(service types.ServiceConfig, appName string, sam
SetEnvFrom sets the environment variables to a configmap. The configmap is created. SetEnvFrom sets the environment variables to a configmap. The configmap is created.
<a name="Deployment.Yaml"></a> <a name="Deployment.Yaml"></a>
### func \(\*Deployment\) [Yaml](<https://github.com/metal3d/katenary/blob/develop/generator/deployment.go#L452>) ### func \(\*Deployment\) [Yaml](<https://github.com/metal3d/katenary/blob/develop/generator/deployment.go#L449>)
```go ```go
func (d *Deployment) Yaml() ([]byte, error) func (d *Deployment) Yaml() ([]byte, error)
@@ -471,7 +471,7 @@ type HelmChart struct {
``` ```
<a name="Generate"></a> <a name="Generate"></a>
### func [Generate](<https://github.com/metal3d/katenary/blob/develop/generator/generator.go#L29>) ### func [Generate](<https://github.com/metal3d/katenary/blob/develop/generator/generator.go#L31>)
```go ```go
func Generate(project *types.Project) (*HelmChart, error) func Generate(project *types.Project) (*HelmChart, error)
@@ -509,7 +509,7 @@ func (chart *HelmChart) SaveTemplates(templateDir string)
SaveTemplates the templates of the chart to the given directory. SaveTemplates the templates of the chart to the given directory.
<a name="Ingress"></a> <a name="Ingress"></a>
## type [Ingress](<https://github.com/metal3d/katenary/blob/develop/generator/ingress.go#L17-L20>) ## type [Ingress](<https://github.com/metal3d/katenary/blob/develop/generator/ingress.go#L17-L21>)
@@ -521,7 +521,7 @@ type Ingress struct {
``` ```
<a name="NewIngress"></a> <a name="NewIngress"></a>
### func [NewIngress](<https://github.com/metal3d/katenary/blob/develop/generator/ingress.go#L23>) ### func [NewIngress](<https://github.com/metal3d/katenary/blob/develop/generator/ingress.go#L24>)
```go ```go
func NewIngress(service types.ServiceConfig, Chart *HelmChart) *Ingress func NewIngress(service types.ServiceConfig, Chart *HelmChart) *Ingress
@@ -530,7 +530,7 @@ func NewIngress(service types.ServiceConfig, Chart *HelmChart) *Ingress
NewIngress creates a new Ingress from a compose service. NewIngress creates a new Ingress from a compose service.
<a name="Ingress.Filename"></a> <a name="Ingress.Filename"></a>
### func \(\*Ingress\) [Filename](<https://github.com/metal3d/katenary/blob/develop/generator/ingress.go#L122>) ### func \(\*Ingress\) [Filename](<https://github.com/metal3d/katenary/blob/develop/generator/ingress.go#L128>)
```go ```go
func (ingress *Ingress) Filename() string func (ingress *Ingress) Filename() string
@@ -539,7 +539,7 @@ func (ingress *Ingress) Filename() string
<a name="Ingress.Yaml"></a> <a name="Ingress.Yaml"></a>
### func \(\*Ingress\) [Yaml](<https://github.com/metal3d/katenary/blob/develop/generator/ingress.go#L126>) ### func \(\*Ingress\) [Yaml](<https://github.com/metal3d/katenary/blob/develop/generator/ingress.go#L132>)
```go ```go
func (ingress *Ingress) Yaml() ([]byte, error) func (ingress *Ingress) Yaml() ([]byte, error)
@@ -548,7 +548,7 @@ func (ingress *Ingress) Yaml() ([]byte, error)
<a name="IngressValue"></a> <a name="IngressValue"></a>
## type [IngressValue](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L28-L35>) ## type [IngressValue](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L29-L36>)
IngressValue is a ingress configuration that will be saved in values.yaml. IngressValue is a ingress configuration that will be saved in values.yaml.
@@ -809,18 +809,19 @@ func (r *ServiceAccount) Yaml() ([]byte, error)
<a name="TLS"></a> <a name="TLS"></a>
## type [TLS](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L23-L25>) ## type [TLS](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L23-L26>)
```go ```go
type TLS struct { type TLS struct {
Enabled bool `yaml:"enabled"` Enabled bool `yaml:"enabled"`
SecretName string `yaml:"secretName"`
} }
``` ```
<a name="Value"></a> <a name="Value"></a>
## type [Value](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L38-L49>) ## type [Value](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L39-L50>)
Value will be saved in values.yaml. It contains configuration for all deployment and services. Value will be saved in values.yaml. It contains configuration for all deployment and services.
@@ -840,7 +841,7 @@ type Value struct {
``` ```
<a name="NewValue"></a> <a name="NewValue"></a>
### func [NewValue](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L56>) ### func [NewValue](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L57>)
```go ```go
func NewValue(service types.ServiceConfig, main ...bool) *Value func NewValue(service types.ServiceConfig, main ...bool) *Value
@@ -851,7 +852,7 @@ NewValue creates a new Value from a compose service. The value contains the nece
If \`main\` is true, the tag will be empty because it will be set in the helm chart appVersion. If \`main\` is true, the tag will be empty because it will be set in the helm chart appVersion.
<a name="Value.AddIngress"></a> <a name="Value.AddIngress"></a>
### func \(\*Value\) [AddIngress](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L89>) ### func \(\*Value\) [AddIngress](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L90>)
```go ```go
func (v *Value) AddIngress(host, path string) func (v *Value) AddIngress(host, path string)
@@ -860,7 +861,7 @@ func (v *Value) AddIngress(host, path string)
<a name="Value.AddPersistence"></a> <a name="Value.AddPersistence"></a>
### func \(\*Value\) [AddPersistence](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L99>) ### func \(\*Value\) [AddPersistence](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L104>)
```go ```go
func (v *Value) AddPersistence(volumeName string) func (v *Value) AddPersistence(volumeName string)

View File

@@ -17,7 +17,7 @@ func NotesFile(services []string) string
NotesFile returns the content of the note.txt file. NotesFile returns the content of the note.txt file.
<a name="ReadMeFile"></a> <a name="ReadMeFile"></a>
## func [ReadMeFile](<https://github.com/metal3d/katenary/blob/develop/generator/extrafiles/readme.go#L45>) ## func [ReadMeFile](<https://github.com/metal3d/katenary/blob/develop/generator/extrafiles/readme.go#L46>)
```go ```go
func ReadMeFile(charname, description string, values map[string]any) string func ReadMeFile(charname, description string, values map[string]any) string

View File

@@ -12,7 +12,7 @@ A katenary file, named "katenary.yml" or "katenary.yaml", is a file where you ca
Formely, the file describe the same structure as in labels, and so that can be validated and completed by LSP. It also ease the use of katenary. Formely, the file describe the same structure as in labels, and so that can be validated and completed by LSP. It also ease the use of katenary.
## func [GenerateSchema](<https://github.com/metal3d/katenary/blob/develop/generator/katenaryfile/main.go#L131>) ## func [GenerateSchema](<https://github.com/metal3d/katenary/blob/develop/generator/katenaryfile/main.go#L137>)
```go ```go
func GenerateSchema() string func GenerateSchema() string

View File

@@ -15,7 +15,7 @@ const KatenaryLabelPrefix = "katenary.v3"
``` ```
<a name="GetLabelHelp"></a> <a name="GetLabelHelp"></a>
## func [GetLabelHelp](<https://github.com/metal3d/katenary/blob/develop/generator/labels/katenaryLabels.go#L87>) ## func [GetLabelHelp](<https://github.com/metal3d/katenary/blob/develop/generator/labels/katenaryLabels.go#L88>)
```go ```go
func GetLabelHelp(asMarkdown bool) string func GetLabelHelp(asMarkdown bool) string
@@ -24,7 +24,7 @@ func GetLabelHelp(asMarkdown bool) string
Generate the help for the labels. Generate the help for the labels.
<a name="GetLabelHelpFor"></a> <a name="GetLabelHelpFor"></a>
## func [GetLabelHelpFor](<https://github.com/metal3d/katenary/blob/develop/generator/labels/katenaryLabels.go#L96>) ## func [GetLabelHelpFor](<https://github.com/metal3d/katenary/blob/develop/generator/labels/katenaryLabels.go#L97>)
```go ```go
func GetLabelHelpFor(labelname string, asMarkdown bool) string func GetLabelHelpFor(labelname string, asMarkdown bool) string
@@ -33,7 +33,7 @@ func GetLabelHelpFor(labelname string, asMarkdown bool) string
GetLabelHelpFor returns the help for a specific label. GetLabelHelpFor returns the help for a specific label.
<a name="GetLabelNames"></a> <a name="GetLabelNames"></a>
## func [GetLabelNames](<https://github.com/metal3d/katenary/blob/develop/generator/labels/katenaryLabels.go#L71>) ## func [GetLabelNames](<https://github.com/metal3d/katenary/blob/develop/generator/labels/katenaryLabels.go#L72>)
```go ```go
func GetLabelNames() []string func GetLabelNames() []string
@@ -42,7 +42,7 @@ func GetLabelNames() []string
GetLabelNames returns a sorted list of all katenary label names. GetLabelNames returns a sorted list of all katenary label names.
<a name="Prefix"></a> <a name="Prefix"></a>
## func [Prefix](<https://github.com/metal3d/katenary/blob/develop/generator/labels/katenaryLabels.go#L224>) ## func [Prefix](<https://github.com/metal3d/katenary/blob/develop/generator/labels/katenaryLabels.go#L235>)
```go ```go
func Prefix() string func Prefix() string
@@ -51,7 +51,7 @@ func Prefix() string
<a name="Help"></a> <a name="Help"></a>
## type [Help](<https://github.com/metal3d/katenary/blob/develop/generator/labels/katenaryLabels.go#L63-L68>) ## type [Help](<https://github.com/metal3d/katenary/blob/develop/generator/labels/katenaryLabels.go#L64-L69>)
Help is the documentation of a label. Help is the documentation of a label.
@@ -65,7 +65,7 @@ type Help struct {
``` ```
<a name="Label"></a> <a name="Label"></a>
## type [Label](<https://github.com/metal3d/katenary/blob/develop/generator/labels/katenaryLabels.go#L56>) ## type [Label](<https://github.com/metal3d/katenary/blob/develop/generator/labels/katenaryLabels.go#L57>)
Label is a katenary label to find in compose files. Label is a katenary label to find in compose files.
@@ -97,7 +97,7 @@ const (
``` ```
<a name="LabelName"></a> <a name="LabelName"></a>
### func [LabelName](<https://github.com/metal3d/katenary/blob/develop/generator/labels/katenaryLabels.go#L58>) ### func [LabelName](<https://github.com/metal3d/katenary/blob/develop/generator/labels/katenaryLabels.go#L59>)
```go ```go
func LabelName(name string) Label func LabelName(name string) Label

View File

@@ -1,60 +0,0 @@
<!-- Code generated by gomarkdoc. DO NOT EDIT -->
# update
```go
import "katenary/update"
```
Update package is used to check if a new version of katenary is available.
## Variables
<a name="Version"></a>
```go
var (
Version = "master" // reset by cmd/main.go
)
```
<a name="DownloadFile"></a>
## func [DownloadFile](<https://github.com/metal3d/katenary/blob/develop/update/main.go#L134>)
```go
func DownloadFile(url, exe string) error
```
DownloadFile will download a url to a local file. It also ensure that the file is executable.
<a name="DownloadLatestVersion"></a>
## func [DownloadLatestVersion](<https://github.com/metal3d/katenary/blob/develop/update/main.go#L80>)
```go
func DownloadLatestVersion(assets []Asset) error
```
DownloadLatestVersion will download the latest version of katenary.
<a name="Asset"></a>
## type [Asset](<https://github.com/metal3d/katenary/blob/develop/update/main.go#L23-L26>)
Asset is a github asset from release url.
```go
type Asset struct {
Name string `json:"name"`
URL string `json:"browser_download_url"`
}
```
<a name="CheckLatestVersion"></a>
### func [CheckLatestVersion](<https://github.com/metal3d/katenary/blob/develop/update/main.go#L29>)
```go
func CheckLatestVersion() (string, []Asset, error)
```
CheckLatestVersion check katenary latest version from release and propose to download it
Generated by [gomarkdoc](<https://github.com/princjef/gomarkdoc>)

View File

@@ -8,7 +8,7 @@ import "katenary/utils"
Utils package provides some utility functions used in katenary. It defines some constants and functions used in the whole project. Utils package provides some utility functions used in katenary. It defines some constants and functions used in the whole project.
## func [AsResourceName](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L191>) ## func [AsResourceName](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L193>)
```go ```go
func AsResourceName(name string) string func AsResourceName(name string) string
@@ -35,7 +35,7 @@ func CountStartingSpaces(line string) int
CountStartingSpaces counts the number of spaces at the beginning of a string. CountStartingSpaces counts the number of spaces at the beginning of a string.
<a name="EncodeBasicYaml"></a> <a name="EncodeBasicYaml"></a>
## func [EncodeBasicYaml](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L173>) ## func [EncodeBasicYaml](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L175>)
```go ```go
func EncodeBasicYaml(data any) ([]byte, error) func EncodeBasicYaml(data any) ([]byte, error)
@@ -44,7 +44,7 @@ func EncodeBasicYaml(data any) ([]byte, error)
EncodeBasicYaml encodes a basic yaml from an interface. EncodeBasicYaml encodes a basic yaml from an interface.
<a name="FixedResourceName"></a> <a name="FixedResourceName"></a>
## func [FixedResourceName](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L185>) ## func [FixedResourceName](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L187>)
```go ```go
func FixedResourceName(name string) string func FixedResourceName(name string) string
@@ -146,7 +146,7 @@ GetContainerByName returns a container by name and its index in the array.
## func [Warn](<https://github.com/metal3d/katenary/blob/develop/utils/icons.go#L25>) ## func [Warn](<https://github.com/metal3d/katenary/blob/develop/utils/icons.go#L25>)
```go ```go
func Warn(msg ...interface{}) func Warn(msg ...any)
``` ```
Warn prints a warning message Warn prints a warning message

View File

@@ -54,7 +54,6 @@ nav:
- Go Packages: - Go Packages:
- packages/cmd/katenary.md - packages/cmd/katenary.md
- packages/parser.md - packages/parser.md
- packages/update.md
- packages/utils.md - packages/utils.md
- Generator: - Generator:
- Index: packages/generator.md - Index: packages/generator.md

View File

@@ -116,9 +116,11 @@ func (chart *HelmChart) SaveTemplates(templateDir string) {
fmt.Println(utils.IconFailure, err) fmt.Println(utils.IconFailure, err)
os.Exit(1) os.Exit(1)
} }
defer f.Close()
if _, err := f.Write(t); err != nil {
log.Fatal("error writing template file:", err)
}
f.Write(t)
f.Close()
} }
} }
@@ -126,7 +128,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
} }

View File

@@ -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() {

View File

@@ -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 {
@@ -627,7 +631,11 @@ func writeContent(path string, content []byte) {
os.Exit(1) os.Exit(1)
} }
defer f.Close() defer f.Close()
f.Write(content) defer func() {
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.

View File

@@ -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) {

View File

@@ -0,0 +1,40 @@
package extrafiles
import (
"strings"
"testing"
)
// override the embedded template for testing
var testTemplate = `
Some header
{{ ingress_list }}
Some footer
`
func init() {
notesTemplate = testTemplate
}
func TestNotesFile_NoServices(t *testing.T) {
result := NotesFile([]string{})
if !strings.Contains(result, "Some header") || !strings.Contains(result, "Some footer") {
t.Errorf("Expected template header/footer in output, got: %s", result)
}
}
func TestNotesFile_WithServices(t *testing.T) {
services := []string{"svc1", "svc2"}
result := NotesFile(services)
for _, svc := range services {
cond := "{{- if and .Values." + svc + ".ingress .Values." + svc + ".ingress.enabled }}"
line := "{{- $count = add1 $count -}}{{- $listOfURL = printf \"%s\\n- http://%s\" $listOfURL (tpl .Values." + svc + ".ingress.host .) -}}"
if !strings.Contains(result, cond) {
t.Errorf("Expected condition for service %s in output", svc)
}
if !strings.Contains(result, line) {
t.Errorf("Expected line for service %s in output", svc)
}
}
}

View File

@@ -4,6 +4,7 @@ import (
"bytes" "bytes"
_ "embed" _ "embed"
"fmt" "fmt"
"log"
"sort" "sort"
"strings" "strings"
"text/template" "text/template"
@@ -20,7 +21,7 @@ type chart struct {
Values []string Values []string
} }
func parseValues(prefix string, values map[string]interface{}, result map[string]string) { func parseValues(prefix string, values map[string]any, result map[string]string) {
for key, value := range values { for key, value := range values {
path := key path := key
if prefix != "" { if prefix != "" {
@@ -28,11 +29,11 @@ func parseValues(prefix string, values map[string]interface{}, result map[string
} }
switch v := value.(type) { switch v := value.(type) {
case []interface{}: case []any:
for i, u := range v { for i, u := range v {
parseValues(fmt.Sprintf("%s[%d]", path, i), map[string]interface{}{"value": u}, result) parseValues(fmt.Sprintf("%s[%d]", path, i), map[string]any{"value": u}, result)
} }
case map[string]interface{}: case map[string]any:
parseValues(path, v, result) parseValues(path, v, result)
default: default:
strValue := fmt.Sprintf("`%v`", value) strValue := fmt.Sprintf("`%v`", value)
@@ -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)

View File

@@ -0,0 +1,33 @@
package extrafiles
import (
"regexp"
"testing"
)
func TestReadMeFile_Basic(t *testing.T) {
values := map[string]any{
"replicas": 2,
"image": map[string]any{
"repository": "nginx",
"tag": "latest",
},
}
result := ReadMeFile("testchart", "A test chart", values)
t.Logf("Generated README content:\n%s", result)
paramerRegExp := regexp.MustCompile(`\|\s+` + "`" + `(.*?)` + "`" + `\s+\|\s+` + "`" + `(.*?)` + "`" + `\s+\|`)
matches := paramerRegExp.FindAllStringSubmatch(result, -1)
if len(matches) != 3 {
t.Errorf("Expected 5 lines in the table for headers and parameters, got %d", len(matches))
}
if matches[0][1] != "image.repository" || matches[0][2] != "nginx" {
t.Errorf("Expected third line to be image.repository, got %s", matches[1])
}
if matches[1][1] != "image.tag" || matches[1][2] != "latest" {
t.Errorf("Expected fourth line to be image.tag, got %s", matches[2])
}
if matches[2][1] != "replicas" || matches[2][2] != "2" {
t.Errorf("Expected second line to be replicas, got %s", matches[0])
}
}

View File

@@ -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
} }

View File

@@ -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()
} }

View File

@@ -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()
} }

View File

@@ -49,6 +49,7 @@ func internalCompileTest(t *testing.T, options ...string) string {
ChartVersion: chartVersion, ChartVersion: chartVersion,
} }
if err := Convert(convertOptions, "compose.yml"); err != nil { if err := Convert(convertOptions, "compose.yml"); err != nil {
log.Printf("Failed to convert: %s", err)
return err.Error() return err.Error()
} }

View File

@@ -87,7 +87,7 @@ func UnWrapTPL(in []byte) []byte {
return regexpLineWrap.ReplaceAll(in, []byte(" }}")) return regexpLineWrap.ReplaceAll(in, []byte(" }}"))
} }
func ToK8SYaml(obj interface{}) ([]byte, error) { func ToK8SYaml(obj any) ([]byte, error) {
if o, err := yaml.Marshal(obj); err != nil { if o, err := yaml.Marshal(obj); err != nil {
return nil, nil return nil, nil
} else { } else {

60
parser/main_test.go Normal file
View 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
View 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")
}
}

View File

@@ -22,7 +22,7 @@ const (
) )
// Warn prints a warning message // Warn prints a warning message
func Warn(msg ...interface{}) { func Warn(msg ...any) {
orange := "\033[38;5;214m" orange := "\033[38;5;214m"
reset := "\033[0m" reset := "\033[0m"
fmt.Print(IconWarning, orange, " ") fmt.Print(IconWarning, orange, " ")

View File

@@ -136,12 +136,12 @@ func GetValuesFromLabel(service types.ServiceConfig, LabelValues string) map[str
switch val := value.(type) { switch val := value.(type) {
case string: case string:
descriptions[val] = nil descriptions[val] = nil
case map[string]interface{}: case map[string]any:
for k, v := range value.(map[string]interface{}) { for k, v := range value.(map[string]any) {
descriptions[k] = &EnvConfig{Service: service, Description: v.(string)} descriptions[k] = &EnvConfig{Service: service, Description: v.(string)}
} }
case map[interface{}]interface{}: case map[any]any:
for k, v := range value.(map[interface{}]interface{}) { for k, v := range value.(map[any]any) {
descriptions[k.(string)] = &EnvConfig{Service: service, Description: v.(string)} descriptions[k.(string)] = &EnvConfig{Service: service, Description: v.(string)}
} }
default: default:
@@ -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"
} }