Skip to content

Commit

Permalink
Add test and setup command show and attach config command
Browse files Browse the repository at this point in the history
Test reading and writing to the output file

Signed-off-by: Luke Mallon (Nalum) <[email protected]>
  • Loading branch information
Nalum committed Jan 22, 2024
1 parent e60ad86 commit c3e8d0c
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 22 deletions.
30 changes: 30 additions & 0 deletions cmd/timoni/mod_show.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
Copyright 2023 Stefan Prodan
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
"github.com/spf13/cobra"
)

var showModCmd = &cobra.Command{
Use: "show",
Short: "Commands for showing module information",
}

func init() {
modCmd.AddCommand(showModCmd)
}
54 changes: 32 additions & 22 deletions cmd/timoni/mod_config.go → cmd/timoni/mod_show_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ import (
"bufio"
"bytes"
"context"
"errors"
"fmt"
"io"
"io/fs"
"os"
"path/filepath"
"regexp"
Expand All @@ -35,17 +37,18 @@ import (
"github.com/stefanprodan/timoni/internal/flags"
)

var configModCmd = &cobra.Command{
var configShowModCmd = &cobra.Command{
Use: "config [MODULE PATH]",
Short: "Output the #Config structure of a local module",
Long: `The config command parses the local module configuration structure and outputs the information to stdout.`,
Example: ` # print the config of a module in the current directory
timoni mod config
timoni mod show config
# print the config of a module in a specific directory
timoni mod config ./path/to/module
# output the config to a file, if the file is markdown, the table will overwrite a table in a Configuration section or
# be appended to the end of the file
timoni mod show config --output ./README.md
`,
RunE: runConfigModCmd,
RunE: runConfigShowModCmd,
}

type configModFlags struct {
Expand All @@ -55,27 +58,26 @@ type configModFlags struct {
output string
}

var configModArgs = configModFlags{
var configShowModArgs = configModFlags{
name: "module-name",
}

func init() {
configModCmd.Flags().StringVarP(&configModArgs.output, "output", "o", "", "The file to output the config Markdown to, defaults to stdout")
modCmd.AddCommand(configModCmd)
configShowModCmd.Flags().StringVarP(&configShowModArgs.output, "output", "o", "", "The file to output the config Markdown to, defaults to stdout")
showModCmd.AddCommand(configShowModCmd)
}

func runConfigModCmd(cmd *cobra.Command, args []string) error {
func runConfigShowModCmd(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
configModArgs.path = "."
configShowModArgs.path = "."
} else {
configModArgs.path = args[0]
configShowModArgs.path = args[0]
}

if fs, err := os.Stat(configModArgs.path); err != nil || !fs.IsDir() {
return fmt.Errorf("module not found at path %s", configModArgs.path)
if fs, err := os.Stat(configShowModArgs.path); err != nil || !fs.IsDir() {
return fmt.Errorf("module not found at path %s", configShowModArgs.path)
}

//log := LoggerFrom(cmd.Context())
cuectx := cuecontext.New()

tmpDir, err := os.MkdirTemp("", apiv1.FieldManager)
Expand All @@ -89,7 +91,7 @@ func runConfigModCmd(cmd *cobra.Command, args []string) error {

fetcher := engine.NewFetcher(
ctxPull,
configModArgs.path,
configShowModArgs.path,
apiv1.LatestVersion,
tmpDir,
rootArgs.cacheDir,
Expand All @@ -103,10 +105,10 @@ func runConfigModCmd(cmd *cobra.Command, args []string) error {

builder := engine.NewModuleBuilder(
cuectx,
configModArgs.name,
configShowModArgs.name,
*kubeconfigArgs.Namespace,
fetcher.GetModuleRoot(),
configModArgs.pkg.String(),
configShowModArgs.pkg.String(),
)

if err := builder.WriteSchemaFile(); err != nil {
Expand All @@ -130,15 +132,15 @@ func runConfigModCmd(cmd *cobra.Command, args []string) error {

header := []string{"Key", "Type", "Default", "Description"}

if configModArgs.output == "" {
printMarkDownTable(os.Stdout, header, rows)
if configShowModArgs.output == "" {
printMarkDownTable(rootCmd.OutOrStdout(), header, rows)
} else {
tmpFile, err := writeFile(configModArgs.output, header, rows, fetcher)
tmpFile, err := writeFile(configShowModArgs.output, header, rows, fetcher)
if err != nil {
return err
}

err = os.Rename(tmpFile, configModArgs.output)
err = os.Rename(tmpFile, configShowModArgs.output)
if err != nil {
return describeErr(fetcher.GetModuleRoot(), "Unable to rename file", err)
}
Expand All @@ -158,7 +160,15 @@ func writeFile(readFile string, header []string, rows [][]string, fetcher *engin
// open the input file
inputFile, err := os.Open(readFile)
if err != nil {
return "", describeErr(fetcher.GetModuleRoot(), "Unable to create the temporary output file", err)
if errors.Is(err, fs.ErrNotExist) {
inputFile, err = os.Create(readFile)

if err != nil {
return "", describeErr(fetcher.GetModuleRoot(), "Unable to create the temporary output file", err)
}
} else {
return "", describeErr(fetcher.GetModuleRoot(), "Unable to create the temporary output file", err)
}
}
defer inputFile.Close()

Expand Down
68 changes: 68 additions & 0 deletions cmd/timoni/mod_show_config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
Copyright 2023 Stefan Prodan
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
"fmt"
"os"
"testing"

. "github.com/onsi/gomega"
)

func Test_ShowConfig(t *testing.T) {
modPath := "testdata/module"

g := NewWithT(t)

// Push the module to registry
output, err := executeCommand(fmt.Sprintf(
"mod show config %s",
modPath,
))
g.Expect(err).ToNot(HaveOccurred())

g.Expect(output).To(ContainSubstring("`client: enabled:`"))
g.Expect(output).To(ContainSubstring("`client: image: repository:`"))
g.Expect(output).To(ContainSubstring("`server: enabled:`"))
}

func Test_ShowConfigOutput(t *testing.T) {
modPath := "testdata/module"

g := NewWithT(t)

// Push the module to registry
_, err := executeCommand(fmt.Sprintf(
"mod show config %s --output %s/README.md",
modPath,
modPath,
))
g.Expect(err).ToNot(HaveOccurred())

rmFile, err := os.ReadFile(fmt.Sprintf("%s/README.md", modPath))
g.Expect(err).ToNot(HaveOccurred())

strContent := string(rmFile)

g.Expect(strContent).To(ContainSubstring("`client: enabled:`"))
g.Expect(strContent).To(ContainSubstring("`client: image: repository:`"))
g.Expect(strContent).To(ContainSubstring("`server: enabled:`"))

err = os.Remove(fmt.Sprintf("%s/README.md", modPath))
g.Expect(err).ToNot(HaveOccurred())
}

0 comments on commit c3e8d0c

Please sign in to comment.