Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions cmd/wsh/cmd/wshcmd-export-config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package cmd

import (
"archive/zip"
"fmt"
"io"
"os"
"path/filepath"
"strings"

"github.com/spf13/cobra"
)

func init() {
var exportConfigCmd = &cobra.Command{
Use: "export-config [output-path]",
Short: "export Wave Terminal configuration",
Long: "Export Wave Terminal configuration files into a zip archive",
RunE: runExportConfig,
}
rootCmd.AddCommand(exportConfigCmd)
}

func runExportConfig(cmd *cobra.Command, args []string) error {
if len(args) != 1 {
return fmt.Errorf("export-config requires an output path")
}

outputPath := args[0]
if !strings.HasSuffix(outputPath, ".zip") {
outputPath += ".zip"
}

configDir := getWaveConfigDir()
if err := zipDir(configDir, outputPath); err != nil {
return fmt.Errorf("export-config failed: %v", err)
}

fmt.Printf("Configuration exported to %s\n", outputPath)
return nil
}

func zipDir(sourceDir, zipPath string) error {
zipFile, err := os.Create(zipPath)
if err != nil {
return err
}
defer zipFile.Close()

archive := zip.NewWriter(zipFile)
defer archive.Close()

return filepath.Walk(sourceDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}

relPath, err := filepath.Rel(sourceDir, path)
if err != nil {
return err
}

file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()

writer, err := archive.Create(relPath)
if err != nil {
return err
}

_, err = io.Copy(writer, file)
return err
})
}

func getWaveConfigDir() string {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not reliable as the user may have a different config directory defined, such as on dev where it's ~/.config/waveterm-dev. You should use wavebase.GetWaveConfigDir instead.

Copy link
Member

@esimkowitz esimkowitz Jan 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, because this is called from the wsh side, which doesn't have the environment variables defined, you should instead call the wshclient.PathCommand function, since that will get you whatever the value is in wavesrv

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, this won't work at all if you're on a remote machine. The logic for zipping the config should be moved to wavesrv and called through the wshserver mechanism, you can look at the other commands to see how we do this. Then, if the user is invoking this command from a remote machine, we should copy the zipped archive to the output path on the remote machine

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To copy the zipped archive to the output path on the remote machine, should I use the filestore.WFS.WriteFile or something else? I am using filestore.WFS.WriteFile but ls doesn't show anything on the remote machine. thanks!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm working on a more flexible filesystem traversal mechanism right now, targeting end of this week. Once this is implemented, I'll let you know so you can integrate it here. For now, let's hold on this PR

homeDir, err := os.UserHomeDir()
if err != nil {
return ""
}
return filepath.Join(homeDir, ".config", "waveterm")
}