Skip to content

Commit

Permalink
feat(cli): add pkg edit command
Browse files Browse the repository at this point in the history
  • Loading branch information
nikoksr committed Dec 26, 2022
1 parent 917444f commit adc020a
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 9 deletions.
113 changes: 113 additions & 0 deletions internal/cli/proji/package/edit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package pkg

import (
"bufio"
"context"
"os"
"os/exec"
"runtime"

"github.com/nikoksr/simplog"

"github.com/cockroachdb/errors"
"github.com/spf13/cobra"

"github.com/nikoksr/proji/internal/cli"
)

func newEditCommand() *cobra.Command {
var fileType string

cmd := &cobra.Command{
Use: "edit [OPTIONS] LABEL",
Short: "Edit details about an installed package",
Args: cobra.ExactArgs(1),
DisableFlagsInUseLine: true,

RunE: func(cmd *cobra.Command, args []string) error {
return editPackage(cmd.Context(), args[0], fileType)
},
}

cmd.Flags().StringVarP(&fileType, "type", "t", "toml", "File type in which to apply the editing (toml, json)")

return cmd
}

func newCommand(ctx context.Context, name string, args ...string) *exec.Cmd {
cmd := exec.CommandContext(ctx, name, args...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr

return cmd
}

func openFile(ctx context.Context, system, path string) error {
logger := simplog.FromContext(ctx)

if path == "" {
return errors.New("path is empty")
}

// TODO: More options for opening files; potentially use config file to set default editor/switch between $EDITOR;
// $VISUAL, commands like xdg-open or other application names
// Set command depending on system
switch system {
case "darwin", "freebsd", "linux", "netbsd", "openbsd":
editor := os.Getenv("EDITOR")
logger.Debugf("opening file %q with editor %q", path, editor)

return newCommand(ctx, editor, path).Run()
case "windows":
logger.Debugf("opening file %q with start command", path)

// return exec.Command("rundll32", "url.dll,FileProtocolHandler", path).Start()
return newCommand(ctx, "start", path).Run()
default:
return errors.Newf("unsupported OS %q", system)
}
}

func editPackage(ctx context.Context, label, fileType string) error {
logger := simplog.FromContext(ctx)

// Get package manager from session
logger.Debug("getting package manager from cli session")
pama := cli.SessionFromContext(ctx).PackageManager
if pama == nil {
return errors.New("no package manager available")
}

// Load package that should be edited
logger.Debugf("load package %q", label)
pkg, err := pama.GetByLabel(ctx, label)
if err != nil {
return errors.Wrapf(err, "get package %q", label)
}

// Export package to temp dir. Note: an empty destination path will cause the package to be exported to a temp dir
logger.Debug("exporting package to temp dir")
path, err := exportPackage(ctx, "", fileType, pkg.ToConfig())
if err != nil {
return errors.Wrap(err, "export package")
}

// Edit package; open file is OS dependent and will open the file in the default editor.
logger.Infof("Opening config file of package %q in default editor", label)
if err := openFile(ctx, runtime.GOOS, path); err != nil {
return errors.Wrap(err, "open file")
}

// Wait for user to finish editing
logger.Info("Press ENTER to confirm your changes")
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()

// When we are done editing, we can import the edited package
if err := replacePackage(ctx, label, path); err != nil {
return errors.Wrap(err, "replace package")
}

return nil
}
1 change: 1 addition & 0 deletions internal/cli/proji/package/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ func NewCommand() *cobra.Command {

cmd.AddCommand(
newImportCommand(),
newEditCommand(),
newExportCommand(),
newListCommand(),
newMimicCommand(),
Expand Down
16 changes: 7 additions & 9 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@ func newProvider(path string) *viper.Viper {

// Allow for cross-platform paths
path = filepath.Clean(path)
path = filepath.FromSlash(path)
dir := filepath.Dir(path)

// Set default configuration
Expand Down Expand Up @@ -237,14 +236,6 @@ func (conf *Config) readFlags(cmdFlags *pflag.FlagSet) error {
func load(ctx context.Context, path string, flags *pflag.FlagSet) (conf *Config, err error) {
logger := simplog.FromContext(ctx)

// Clean up path
path = filepath.Clean(path)

path, err = filepath.Abs(path)
if err != nil {
return nil, errors.Wrap(err, "get absolute config path")
}

// If no explicit path is given, use default path
if path == "" {
path, err = defaultConfigPath()
Expand All @@ -255,6 +246,13 @@ func load(ctx context.Context, path string, flags *pflag.FlagSet) (conf *Config,
logger.Debugf("no explicit config path given, using default path: %q", path)
}

// Clean up path
path = filepath.Clean(path)
path, err = filepath.Abs(path)
if err != nil {
return nil, errors.Wrap(err, "get absolute config path")
}

// Create default config
logger.Debugf("creating config provider with path: %q", path)
conf = &Config{
Expand Down

0 comments on commit adc020a

Please sign in to comment.