Skip to content

Commit dd9692f

Browse files
authored
Refactor/coding standards (#8)
* remove redundant comments to align with guidelines * remove code duplication * remove redundant code
1 parent 938cd9a commit dd9692f

14 files changed

Lines changed: 58 additions & 132 deletions

File tree

internal/config/backup.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func (m *Manager) EnsureFirstRunBackup() error {
3030
metaPath := filepath.Join(backupDir, "metadata.json")
3131

3232
if _, err := os.Stat(metaPath); err == nil {
33-
return nil // backup already exists
33+
return nil
3434
}
3535

3636
var existingFiles []string
@@ -43,7 +43,7 @@ func (m *Manager) EnsureFirstRunBackup() error {
4343
}
4444
}
4545

46-
// enforce secure, user-only read/write access to the backup folder
46+
// why: openssh configuration backups must remain user-accessible only for security
4747
if err := os.MkdirAll(backupDir, 0700); err != nil {
4848
return fmt.Errorf("failed to create backup directory: %w", err)
4949
}
@@ -73,7 +73,7 @@ func (m *Manager) EnsureFirstRunBackup() error {
7373
return fmt.Errorf("failed to marshal backup metadata: %w", err)
7474
}
7575

76-
// enforce secure user-only access on the metadata file
76+
// why: metadata file stores sensitive backup paths and must be restricted
7777
if err := os.WriteFile(metaPath, metaBytes, 0600); err != nil {
7878
return fmt.Errorf("failed to write backup metadata: %w", err)
7979
}

internal/config/backup_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ func TestEnsureFirstRunBackup(t *testing.T) {
3131
backupDir := filepath.Join(tmpDir, "pre-tusshi")
3232
assert.DirExists(t, backupDir)
3333

34-
// check folder permissions (must be 0700 on Unix)
34+
// check folder permissions (must be 0700 on unix)
3535
info, err := os.Stat(backupDir)
3636
assert.NoError(t, err)
3737
assert.Equal(t, os.ModeDir|0700, info.Mode().Perm()|os.ModeDir)

internal/config/config_file.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ func (m *Manager) AddConfigFile(targetPath string) error {
2828
return err
2929
}
3030

31-
// write a simple marker comment to represent a blank config file
3231
if err := os.WriteFile(absTarget, []byte("# SSH config file created by tusshi\n"), 0600); err != nil {
3332
return err
3433
}

internal/config/editor.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,7 @@ func (m *Manager) UpdateHost(originalAlias string, h *Host) error {
113113
}
114114

115115
if newASTHost != nil {
116-
// Keep any existing comment nodes from the original host block
117-
// This makes sure we don't remove user generated comments from the file
116+
// why: user comments must be preserved inside the edited host block to prevent data loss
118117
for _, node := range targetCfg.Hosts[targetIdx].Nodes {
119118
if _, isComment := node.(*ssh_config.Empty); isComment {
120119
newASTHost.Nodes = append(newASTHost.Nodes, node)
@@ -223,13 +222,11 @@ func (m *Manager) registerInclude(includePath string) error {
223222
}
224223
}
225224

226-
// Decode the include line using parser to create the correct node type cleanly
227225
decoded, err := ssh_config.Decode(strings.NewReader("Include " + relPath + "\n"))
228226
if err != nil || len(decoded.Hosts) == 0 {
229227
return fmt.Errorf("failed to generate include AST node: %w", err)
230228
}
231229

232-
// Insert Include block at the very top of the primary config's Host list
233230
primaryCfg.Hosts = append([]*ssh_config.Host{decoded.Hosts[0]}, primaryCfg.Hosts...)
234231
return m.SaveFile(m.PrimaryPath)
235232
}

internal/config/manager.go

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package config
22

33
import (
44
"fmt"
5+
"maps"
56
"os"
67
"path/filepath"
78
"reflect"
@@ -50,7 +51,6 @@ func (m *Manager) Load() error {
5051
// It automatically resolves wildcard settings for each specific host.
5152
func (m *Manager) GetHosts() []*Host {
5253
var hosts []*Host
53-
// We gather global wildcard configs to perform inheritance resolution later.
5454
globalConfig := m.buildGlobalConfig()
5555

5656
for _, filePath := range m.FileOrder {
@@ -60,7 +60,7 @@ func (m *Manager) GetHosts() []*Host {
6060
}
6161

6262
for _, astHost := range cfg.Hosts {
63-
// Skip the implicit default "Host *" block added by the parser
63+
// why: the parser injects a default implicit host block that we do not want to display
6464
val := reflect.ValueOf(astHost)
6565
if val.Kind() == reflect.Pointer && !val.IsNil() {
6666
elem := val.Elem()
@@ -70,7 +70,6 @@ func (m *Manager) GetHosts() []*Host {
7070
}
7171
}
7272

73-
// Extract all aliases defined in this Host block.
7473
for _, pat := range astHost.Patterns {
7574
alias := pat.String()
7675
if alias == "" {
@@ -85,26 +84,20 @@ func (m *Manager) GetHosts() []*Host {
8584
Properties: make(map[string]string),
8685
}
8786

88-
// Extract explicit key-value properties from the host block's nodes.
8987
for _, node := range astHost.Nodes {
9088
if kv, ok := node.(*ssh_config.KV); ok {
9189
h.Properties[kv.Key] = kv.Value
9290
}
9391
}
9492

95-
// Map critical properties to top-level fields for convenience.
9693
h.Name = h.Properties["HostName"]
9794
h.User = h.Properties["User"]
9895
h.Port = h.Properties["Port"]
9996
h.IdentityFile = h.Properties["IdentityFile"]
10097

101-
// Resolve final values using global OpenSSH inheritance.
10298
h.ResolvedProperties = make(map[string]string)
103-
for k, v := range h.Properties {
104-
h.ResolvedProperties[k] = v
105-
}
99+
maps.Copy(h.ResolvedProperties, h.Properties)
106100

107-
// Inject inherited properties from matching wildcard blocks.
108101
if !isWildcard && globalConfig != nil {
109102
for _, key := range []string{keyHostName, keyUser, keyPort, keyIdentityFile, keyForwardAgent, keyProxyJump} {
110103
if _, explicit := h.Properties[key]; !explicit {
@@ -115,7 +108,6 @@ func (m *Manager) GetHosts() []*Host {
115108
}
116109
}
117110

118-
// Update resolved shortcuts.
119111
if h.Name == "" && h.ResolvedProperties[keyHostName] != "" {
120112
h.Name = h.ResolvedProperties[keyHostName]
121113
}
@@ -150,7 +142,7 @@ func (m *Manager) loadPath(path string, depth int) error {
150142
f, err := os.Open(filepath.Clean(path))
151143
if err != nil {
152144
if os.IsNotExist(err) && path == m.PrimaryPath {
153-
// If primary file doesn't exist, we start with a clean empty config
145+
// why: if primary file doesn't exist, we start with a clean empty config
154146
m.Configs[path] = &ssh_config.Config{Hosts: []*ssh_config.Host{}}
155147
return nil
156148
}
@@ -167,7 +159,6 @@ func (m *Manager) loadPath(path string, depth int) error {
167159

168160
m.Configs[path] = cfg
169161

170-
// Scan AST nodes to discover and parse any Include directives.
171162
for _, astHost := range cfg.Hosts {
172163
for _, node := range astHost.Nodes {
173164
if incl, ok := node.(*ssh_config.Include); ok {
@@ -208,7 +199,6 @@ func (m *Manager) resolveAndLoadIncludes(pattern string, depth int) {
208199
}
209200

210201
if err := m.loadPath(absMatch, depth); err == nil {
211-
// Track order of newly discovered files.
212202
found := slices.Contains(m.FileOrder, absMatch)
213203
if !found {
214204
m.FileOrder = append(m.FileOrder, absMatch)
@@ -238,3 +228,14 @@ func expandTilde(path string) string {
238228
}
239229
return path
240230
}
231+
232+
// FindConfigFile searches FileOrder for a path matching the given name,
233+
// base name, or extensionless nickname.
234+
func (m *Manager) FindConfigFile(name string) (string, bool) {
235+
for _, file := range m.FileOrder {
236+
if file == name || filepath.Base(file) == name || strings.TrimSuffix(filepath.Base(file), filepath.Ext(file)) == name {
237+
return file, true
238+
}
239+
}
240+
return "", false
241+
}

internal/config/manager_test.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Host 10.200.1.46
3737
assert.NoError(t, err)
3838

3939
hosts := mgr.GetHosts()
40-
// Total hosts: Host *, prod-web-01, 10.200.1.46
40+
// total hosts: Host *, prod-web-01, 10.200.1.46
4141
assert.Len(t, hosts, 3)
4242

4343
var wildcardHost, prodHost, dbHost *Host
@@ -56,17 +56,17 @@ Host 10.200.1.46
5656
assert.True(t, wildcardHost.IsWildcard)
5757
assert.Equal(t, "default_user", wildcardHost.User)
5858

59-
// Verify prodHost details and explicit key mapping
59+
// verify prodHost details and explicit key mapping
6060
assert.NotNil(t, prodHost)
6161
assert.False(t, prodHost.IsWildcard)
6262
assert.Equal(t, "10.200.1.45", prodHost.Name)
6363
assert.Equal(t, "deploy", prodHost.User)
6464
assert.Equal(t, "~/.ssh/keys/work_rsa", prodHost.IdentityFile)
65-
// Verify prodHost inherited port 2222 from wildcard Host *
65+
// verify prodHost inherited port 2222 from wildcard Host *
6666
assert.Equal(t, "2222", prodHost.ResolvedProperties["Port"])
6767
assert.Equal(t, "yes", prodHost.ResolvedProperties[keyForwardAgent])
6868

69-
// Verify dbHost does not have alias (its alias is the IP itself)
69+
// verify dbHost does not have alias (its alias is the IP itself)
7070
assert.NotNil(t, dbHost)
7171
assert.Equal(t, "10.200.1.46", dbHost.Alias)
7272
// dbHost should inherit User, Port, and ForwardAgent from wildcard
@@ -136,7 +136,7 @@ Host my-host
136136
err = mgr.AddHost(primaryPath, newHost)
137137
assert.NoError(t, err)
138138

139-
// Reload to verify write
139+
// reload to verify write
140140
mgr2 := NewManager(primaryPath)
141141
err = mgr2.Load()
142142
assert.NoError(t, err)
@@ -169,7 +169,7 @@ Host my-host
169169
err = mgr2.UpdateHost("added-host", updatedHost)
170170
assert.NoError(t, err)
171171

172-
// Reload to verify update
172+
// reload to verify update
173173
mgr3 := NewManager(primaryPath)
174174
err = mgr3.Load()
175175
assert.NoError(t, err)
@@ -193,7 +193,7 @@ Host my-host
193193
err = mgr3.DeleteHost("added-host-new")
194194
assert.NoError(t, err)
195195

196-
// Reload to verify delete
196+
// reload to verify delete
197197
mgr4 := NewManager(primaryPath)
198198
err = mgr4.Load()
199199
assert.NoError(t, err)
@@ -213,21 +213,21 @@ func TestManagerConfigFileCRUD(t *testing.T) {
213213

214214
subPath := filepath.Join(tmpDir, "sub-config")
215215

216-
// 1. Add Config File
216+
// 1. add config file
217217
err = mgr.AddConfigFile(subPath)
218218
assert.NoError(t, err)
219219
assert.FileExists(t, subPath)
220220
assert.Contains(t, mgr.FileOrder, subPath)
221221

222-
// Check if Include directive is added in primary
222+
// check if Include directive is added in primary
223223
// #nosec G304
224224
primaryContent, err := os.ReadFile(primaryPath)
225225
assert.NoError(t, err)
226226
relSub, err := filepath.Rel(filepath.Dir(primaryPath), subPath)
227227
assert.NoError(t, err)
228228
assert.Contains(t, string(primaryContent), "Include "+relSub)
229229

230-
// 2. Rename Config File
230+
// 2. rename config file
231231
renamedPath := filepath.Join(tmpDir, "renamed-config")
232232
err = mgr.RenameConfigFile(subPath, renamedPath)
233233
assert.NoError(t, err)
@@ -236,7 +236,7 @@ func TestManagerConfigFileCRUD(t *testing.T) {
236236
assert.Contains(t, mgr.FileOrder, renamedPath)
237237
assert.NotContains(t, mgr.FileOrder, subPath)
238238

239-
// Check if Include is updated in primary
239+
// check if Include is updated in primary
240240
// #nosec G304
241241
primaryContent2, err := os.ReadFile(primaryPath)
242242
assert.NoError(t, err)
@@ -245,7 +245,7 @@ func TestManagerConfigFileCRUD(t *testing.T) {
245245
assert.Contains(t, string(primaryContent2), "Include "+relRenamed)
246246
assert.NotContains(t, string(primaryContent2), "Include "+relSub)
247247

248-
// 3. Prevent deleting if connections are present
248+
// 3. prevent deleting if connections are present
249249
h := &Host{
250250
Alias: "test-host",
251251
Name: "127.0.0.1",
@@ -257,17 +257,17 @@ func TestManagerConfigFileCRUD(t *testing.T) {
257257
assert.Error(t, err)
258258
assert.Contains(t, err.Error(), "connections are still present")
259259

260-
// Delete host first
260+
// delete host first
261261
err = mgr.DeleteHost("test-host")
262262
assert.NoError(t, err)
263263

264-
// 4. Delete Config File successfully when no connections are present
264+
// 4. delete config file successfully when no connections are present
265265
err = mgr.DeleteConfigFile(renamedPath)
266266
assert.NoError(t, err)
267267
assert.NoFileExists(t, renamedPath)
268268
assert.NotContains(t, mgr.FileOrder, renamedPath)
269269

270-
// Check if Include is removed from primary
270+
// check if Include is removed from primary
271271
// #nosec G304
272272
primaryContent3, err := os.ReadFile(primaryPath)
273273
assert.NoError(t, err)

internal/tui/commands/config.go

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,8 @@ func RenameConfig(mgr *config.Manager, parts []string) func(Context) {
6969
return
7070
}
7171

72-
var oldPath string
73-
for _, file := range mgr.FileOrder {
74-
if file == oldName || filepath.Base(file) == oldName || strings.TrimSuffix(filepath.Base(file), filepath.Ext(file)) == oldName {
75-
oldPath = file
76-
break
77-
}
78-
}
79-
80-
if oldPath == "" {
72+
oldPath, found := mgr.FindConfigFile(oldName)
73+
if !found {
8174
ctx.SetError(fmt.Sprintf("Config file %q not found", oldName))
8275
return
8376
}
@@ -122,15 +115,8 @@ func DeleteConfig(mgr *config.Manager, parts []string) func(Context) {
122115
targetName = activeTab
123116
}
124117

125-
var targetPath string
126-
for _, file := range mgr.FileOrder {
127-
if file == targetName || filepath.Base(file) == targetName || strings.TrimSuffix(filepath.Base(file), filepath.Ext(file)) == targetName {
128-
targetPath = file
129-
break
130-
}
131-
}
132-
133-
if targetPath == "" {
118+
targetPath, found := mgr.FindConfigFile(targetName)
119+
if !found {
134120
ctx.SetError(fmt.Sprintf("Config file %q not found", targetName))
135121
return
136122
}

internal/tui/commands/move.go

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package commands
33
import (
44
"fmt"
55
"path/filepath"
6-
"strings"
76

87
"tusshi/internal/config"
98
)
@@ -17,15 +16,8 @@ func Move(mgr *config.Manager, selectedHost *config.Host, parts []string) func(C
1716
}
1817

1918
targetNickname := parts[1]
20-
var matchedFile string
21-
for _, file := range mgr.FileOrder {
22-
if filepath.Base(file) == targetNickname || strings.TrimSuffix(filepath.Base(file), filepath.Ext(file)) == targetNickname {
23-
matchedFile = file
24-
break
25-
}
26-
}
27-
28-
if matchedFile == "" {
19+
matchedFile, found := mgr.FindConfigFile(targetNickname)
20+
if !found {
2921
matchedFile = filepath.Join(filepath.Dir(mgr.PrimaryPath), targetNickname)
3022
}
3123

0 commit comments

Comments
 (0)