Skip to content

Commit 98be8b8

Browse files
committed
feat: provide cli flag to specify ssh config path
- add -F flag to ssh command in exec.Command to use provided ssh config file - tested. works fixes #83 Signed-off-by: omani <3346207+omani@users.noreply.github.com> fix last
1 parent 07cb2ab commit 98be8b8

File tree

4 files changed

+81
-28
lines changed

4 files changed

+81
-28
lines changed

cmd/main.go

Lines changed: 73 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package main
1616

1717
import (
1818
"fmt"
19+
"io"
1920
"os"
2021
"path/filepath"
2122

@@ -28,44 +29,89 @@ import (
2829
)
2930

3031
var (
31-
version = "develop"
32-
gitCommit = "unknown"
33-
)
32+
version = "develop"
33+
gitCommit = "unknown"
34+
sshConfigFile string
3435

35-
func main() {
36-
log, err := logger.New("LAZYSSH")
37-
if err != nil {
38-
fmt.Println(err)
39-
os.Exit(1)
40-
}
36+
rootCmd = &cobra.Command{
37+
Use: ui.AppName,
38+
Short: "Lazy SSH server picker TUI",
39+
RunE: func(cmd *cobra.Command, args []string) error {
40+
log, err := logger.New("LAZYSSH")
41+
if err != nil {
42+
fmt.Println(err)
43+
os.Exit(1)
44+
}
4145

42-
//nolint:errcheck // log.Sync may return an error which is safe to ignore here
43-
defer log.Sync()
46+
//nolint:errcheck // log.Sync may return an error which is safe to ignore here
47+
defer log.Sync()
4448

45-
home, err := os.UserHomeDir()
46-
if err != nil {
47-
log.Errorw("failed to get user home directory", "error", err)
48-
//nolint:gocritic // exitAfterDefer: ensure immediate exit on unrecoverable error
49-
os.Exit(1)
50-
}
51-
sshConfigFile := filepath.Join(home, ".ssh", "config")
52-
metaDataFile := filepath.Join(home, ".lazyssh", "metadata.json")
49+
home, err := os.UserHomeDir()
50+
if err != nil {
51+
log.Errorw("failed to get user home directory", "error", err)
52+
// nolint:gocritic // exitAfterDefer: ensure immediate exit on unrecoverable error
53+
os.Exit(1)
54+
}
5355

54-
serverRepo := ssh_config_file.NewRepository(log, sshConfigFile, metaDataFile)
55-
serverService := services.NewServerService(log, serverRepo)
56-
tui := ui.NewTUI(log, serverService, version, gitCommit)
56+
if sshConfigFile == "" {
57+
sshConfigFile = filepath.Join(home, ".ssh", "config")
58+
} else {
59+
stat, err := os.Stat(sshConfigFile)
60+
if err != nil {
61+
fmt.Fprintf(os.Stderr, "Error getting file info: %v\n", err)
62+
os.Exit(1)
63+
}
64+
if stat.Mode()&os.ModeType != 0 {
65+
f, err := os.CreateTemp("", "tmpfile-")
66+
if err != nil {
67+
log.Fatal(err)
68+
}
69+
70+
// close and remove the temporary file at the end of the program
71+
defer f.Close()
72+
defer os.Remove(f.Name())
73+
74+
// write data to the temporary file
75+
fd, err := os.Open(sshConfigFile)
76+
if err != nil {
77+
fmt.Fprintf(os.Stderr, "Error opening file: %v\n", err)
78+
os.Exit(1)
79+
}
80+
defer fd.Close()
81+
82+
// Read the entire contents at once
83+
content, err := io.ReadAll(fd)
84+
if err != nil {
85+
fmt.Fprintf(os.Stderr, "Error reading file: %v\n", err)
86+
os.Exit(1)
87+
}
88+
if _, err := f.WriteString(string(content)); err != nil {
89+
log.Fatal(err)
90+
}
91+
92+
sshConfigFile = f.Name()
93+
}
94+
}
95+
96+
metaDataFile := filepath.Join(home, ".lazyssh", "metadata.json")
97+
serverRepo := ssh_config_file.NewRepository(log, sshConfigFile, metaDataFile)
98+
serverService := services.NewServerService(log, serverRepo)
99+
tui := ui.NewTUI(log, serverService, version, gitCommit)
57100

58-
rootCmd := &cobra.Command{
59-
Use: ui.AppName,
60-
Short: "Lazy SSH server picker TUI",
61-
RunE: func(cmd *cobra.Command, args []string) error {
62101
return tui.Run()
63102
},
64103
}
65-
rootCmd.SilenceUsage = true
104+
)
66105

106+
func main() {
67107
if err := rootCmd.Execute(); err != nil {
68108
_, _ = fmt.Fprintln(os.Stderr, err)
69109
os.Exit(1)
70110
}
71111
}
112+
113+
func init() {
114+
rootCmd.PersistentFlags().StringVar(&sshConfigFile, "sshconfig", "", "path to ssh config file (default: ~/.ssh/config)")
115+
116+
rootCmd.SilenceUsage = true
117+
}

internal/adapters/data/ssh_config_file/ssh_config_file_repo.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,3 +164,8 @@ func (r *Repository) SetPinned(alias string, pinned bool) error {
164164
func (r *Repository) RecordSSH(alias string) error {
165165
return r.metadataManager.recordSSH(alias)
166166
}
167+
168+
// GetConfigFile gets the path to the ssh config file.
169+
func (r *Repository) GetConfigFile() string {
170+
return r.configPath
171+
}

internal/core/ports/repositories.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ type ServerRepository interface {
2323
DeleteServer(server domain.Server) error
2424
SetPinned(alias string, pinned bool) error
2525
RecordSSH(alias string) error
26+
GetConfigFile() string
2627
}

internal/core/services/server_service.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ func (s *serverService) SetPinned(alias string, pinned bool) error {
156156
// SSH starts an interactive SSH session to the given alias using the system's ssh client.
157157
func (s *serverService) SSH(alias string) error {
158158
s.logger.Infow("ssh start", "alias", alias)
159-
cmd := exec.Command("ssh", alias)
159+
cmd := exec.Command("ssh", "-F", s.serverRepository.GetConfigFile(), alias)
160160
cmd.Stdin = os.Stdin
161161
cmd.Stdout = os.Stdout
162162
cmd.Stderr = os.Stderr
@@ -177,6 +177,7 @@ func (s *serverService) SSH(alias string) error {
177177
func (s *serverService) SSHWithArgs(alias string, extraArgs []string) error {
178178
s.logger.Infow("ssh start (with args)", "alias", alias, "args", extraArgs)
179179
args := append([]string{}, extraArgs...)
180+
args = append(args, "-F", s.serverRepository.GetConfigFile())
180181
args = append(args, alias)
181182
// #nosec G204
182183
cmd := exec.Command("ssh", args...)

0 commit comments

Comments
 (0)