Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
100 changes: 73 additions & 27 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package main

import (
"fmt"
"io"
"os"
"path/filepath"

Expand All @@ -28,44 +29,89 @@ import (
)

var (
version = "develop"
gitCommit = "unknown"
)
version = "develop"
gitCommit = "unknown"
sshConfigFile string

func main() {
log, err := logger.New("LAZYSSH")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
rootCmd = &cobra.Command{
Use: ui.AppName,
Short: "Lazy SSH server picker TUI",
RunE: func(cmd *cobra.Command, args []string) error {
log, err := logger.New("LAZYSSH")
if err != nil {
fmt.Println(err)
os.Exit(1)
}

//nolint:errcheck // log.Sync may return an error which is safe to ignore here
defer log.Sync()
//nolint:errcheck // log.Sync may return an error which is safe to ignore here
defer log.Sync()

home, err := os.UserHomeDir()
if err != nil {
log.Errorw("failed to get user home directory", "error", err)
//nolint:gocritic // exitAfterDefer: ensure immediate exit on unrecoverable error
os.Exit(1)
}
sshConfigFile := filepath.Join(home, ".ssh", "config")
metaDataFile := filepath.Join(home, ".lazyssh", "metadata.json")
home, err := os.UserHomeDir()
if err != nil {
log.Errorw("failed to get user home directory", "error", err)
// nolint:gocritic // exitAfterDefer: ensure immediate exit on unrecoverable error
os.Exit(1)
}

serverRepo := ssh_config_file.NewRepository(log, sshConfigFile, metaDataFile)
serverService := services.NewServerService(log, serverRepo)
tui := ui.NewTUI(log, serverService, version, gitCommit)
if sshConfigFile == "" {
sshConfigFile = filepath.Join(home, ".ssh", "config")
} else {
stat, err := os.Stat(sshConfigFile)
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting file info: %v\n", err)
os.Exit(1)
}
if stat.Mode()&os.ModeType != 0 {
f, err := os.CreateTemp("", "tmpfile-")
if err != nil {
log.Fatal(err)
}

// close and remove the temporary file at the end of the program
defer f.Close()
defer os.Remove(f.Name())

// write data to the temporary file
fd, err := os.Open(sshConfigFile)
if err != nil {
fmt.Fprintf(os.Stderr, "Error opening file: %v\n", err)
os.Exit(1)
}
defer fd.Close()

// Read the entire contents at once
content, err := io.ReadAll(fd)
if err != nil {
fmt.Fprintf(os.Stderr, "Error reading file: %v\n", err)
os.Exit(1)
}
if _, err := f.WriteString(string(content)); err != nil {
log.Fatal(err)
}

sshConfigFile = f.Name()
}
}

metaDataFile := filepath.Join(home, ".lazyssh", "metadata.json")
serverRepo := ssh_config_file.NewRepository(log, sshConfigFile, metaDataFile)
serverService := services.NewServerService(log, serverRepo)
tui := ui.NewTUI(log, serverService, version, gitCommit)

rootCmd := &cobra.Command{
Use: ui.AppName,
Short: "Lazy SSH server picker TUI",
RunE: func(cmd *cobra.Command, args []string) error {
return tui.Run()
},
}
rootCmd.SilenceUsage = true
)

func main() {
if err := rootCmd.Execute(); err != nil {
_, _ = fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}

func init() {
rootCmd.PersistentFlags().StringVar(&sshConfigFile, "sshconfig", "", "path to ssh config file (default: ~/.ssh/config)")

rootCmd.SilenceUsage = true
}
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,8 @@ func (r *Repository) SetPinned(alias string, pinned bool) error {
func (r *Repository) RecordSSH(alias string) error {
return r.metadataManager.recordSSH(alias)
}

// GetConfigFile gets the path to the ssh config file.
func (r *Repository) GetConfigFile() string {
return r.configPath
}
1 change: 1 addition & 0 deletions internal/core/ports/repositories.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ type ServerRepository interface {
DeleteServer(server domain.Server) error
SetPinned(alias string, pinned bool) error
RecordSSH(alias string) error
GetConfigFile() string
}
3 changes: 2 additions & 1 deletion internal/core/services/server_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ func (s *serverService) SetPinned(alias string, pinned bool) error {
// SSH starts an interactive SSH session to the given alias using the system's ssh client.
func (s *serverService) SSH(alias string) error {
s.logger.Infow("ssh start", "alias", alias)
cmd := exec.Command("ssh", alias)
cmd := exec.Command("ssh", "-F", s.serverRepository.GetConfigFile(), alias)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
Expand All @@ -177,6 +177,7 @@ func (s *serverService) SSH(alias string) error {
func (s *serverService) SSHWithArgs(alias string, extraArgs []string) error {
s.logger.Infow("ssh start (with args)", "alias", alias, "args", extraArgs)
args := append([]string{}, extraArgs...)
args = append(args, "-F", s.serverRepository.GetConfigFile())
args = append(args, alias)
// #nosec G204
cmd := exec.Command("ssh", args...)
Expand Down