diff options
| author | Shulhan <ms@kilabit.info> | 2023-12-25 14:14:02 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2023-12-25 14:14:02 +0700 |
| commit | 4907d9403e71d42e70a7aa1ff76b792ed2fba2f7 (patch) | |
| tree | 5ad17ac27cc71b3234794cc110a1ad1a3c24fe33 /lib | |
| parent | 07165e72daa4d9d283ac049b06e5634f4d2f32e6 (diff) | |
| download | pakakeh.go-4907d9403e71d42e70a7aa1ff76b792ed2fba2f7.tar.xz | |
ssh/config: add parameter Config to NewSection
This changes how the Section and parser initialized.
Previously, the Config depends on the parser to set the workDir and
homeDir and Section depends on Config only on Get; now its the other
way around, from top to bottom.
Config initialized first, then parser initialized using Config instance,
and then Section initialized also using Config instance.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/ssh/client_test.go | 2 | ||||
| -rw-r--r-- | lib/ssh/config/config.go | 47 | ||||
| -rw-r--r-- | lib/ssh/config/config_test.go | 13 | ||||
| -rw-r--r-- | lib/ssh/config/parser.go | 15 | ||||
| -rw-r--r-- | lib/ssh/config/parser_test.go | 2 | ||||
| -rw-r--r-- | lib/ssh/config/section.go | 35 | ||||
| -rw-r--r-- | lib/ssh/config/section_match.go | 5 | ||||
| -rw-r--r-- | lib/ssh/config/section_match_test.go | 16 | ||||
| -rw-r--r-- | lib/ssh/config/section_test.go | 9 |
9 files changed, 88 insertions, 56 deletions
diff --git a/lib/ssh/client_test.go b/lib/ssh/client_test.go index 062a32cc..feead9cc 100644 --- a/lib/ssh/client_test.go +++ b/lib/ssh/client_test.go @@ -20,7 +20,7 @@ func TestNewClient_KeyError_notExist(t *testing.T) { t.Skip(`Require active SSH server`) var ( - section = config.NewSection(`localhost`) + section = config.NewSection(nil, `localhost`) wd string err error diff --git a/lib/ssh/config/config.go b/lib/ssh/config/config.go index 21116d44..1c156da5 100644 --- a/lib/ssh/config/config.go +++ b/lib/ssh/config/config.go @@ -30,12 +30,31 @@ var ( type Config struct { envs map[string]string + // workDir store the current working directory. workDir string + homeDir string sections []*Section } +// newConfig create new SSH Config instance from file. +func newConfig(file string) (cfg *Config, err error) { + cfg = &Config{} + + cfg.workDir, err = os.Getwd() + if err != nil { + return nil, err + } + + cfg.homeDir, err = os.UserHomeDir() + if err != nil { + return nil, err + } + + return cfg, nil +} + // Load SSH configuration from file. func Load(file string) (cfg *Config, err error) { if len(file) == 0 { @@ -47,26 +66,32 @@ func Load(file string) (cfg *Config, err error) { section *Section ) - cfg = &Config{ - sections: make([]*Section, 0), + cfg, err = newConfig(file) + if err != nil { + return nil, fmt.Errorf("%s %s: %w", logp, file, err) } cfg.loadEnvironments() - p, err := newParser() + var p *parser + + p, err = newParser(cfg) if err != nil { return nil, fmt.Errorf("%s %s: %w", logp, file, err) } - cfg.workDir = p.workDir - cfg.homeDir = p.homeDir + var lines []string - lines, err := p.load("", file) + lines, err = p.load("", file) if err != nil { return nil, fmt.Errorf("%s %s: %w", logp, file, err) } - for x, line := range lines { + var ( + line string + x int + ) + for x, line = range lines { if line[0] == '#' { continue } @@ -81,13 +106,13 @@ func Load(file string) (cfg *Config, err error) { cfg.sections = append(cfg.sections, section) section = nil } - section = newSectionHost(value) + section = newSectionHost(cfg, value) case keyMatch: if section != nil { cfg.sections = append(cfg.sections, section) section = nil } - section, err = newSectionMatch(value) + section, err = newSectionMatch(cfg, value) if err != nil { return nil, fmt.Errorf("%s %s line %d: %w", logp, file, x+1, err) } @@ -114,13 +139,13 @@ func Load(file string) (cfg *Config, err error) { // If no Host or Match found, it still return non-nil Section but with empty // fields. func (cfg *Config) Get(s string) (section *Section) { - section = NewSection(s) + section = NewSection(cfg, s) for _, hostMatch := range cfg.sections { if hostMatch.isMatch(s) { section.mergeField(hostMatch) } } - section.setDefaults(cfg.workDir, cfg.homeDir) + section.setDefaults() if s != `` && section.Field[KeyHostname] == `` { section.Set(KeyHostname, s) diff --git a/lib/ssh/config/config_test.go b/lib/ssh/config/config_test.go index f31e5050..bf9aed9b 100644 --- a/lib/ssh/config/config_test.go +++ b/lib/ssh/config/config_test.go @@ -14,19 +14,26 @@ import ( ) var ( - testDefaultSection = NewSection(``) + dummyConfig *Config + testDefaultSection *Section testParser *parser ) func TestMain(m *testing.M) { var err error - testParser, err = newParser() + dummyConfig, err = newConfig(``) if err != nil { log.Fatal(err) } - testDefaultSection.setDefaults(testParser.workDir, testParser.homeDir) + testParser, err = newParser(dummyConfig) + if err != nil { + log.Fatal(err) + } + + testDefaultSection = NewSection(dummyConfig, ``) + testDefaultSection.setDefaults() os.Exit(m.Run()) } diff --git a/lib/ssh/config/parser.go b/lib/ssh/config/parser.go index 260f0b46..3ffef0a7 100644 --- a/lib/ssh/config/parser.go +++ b/lib/ssh/config/parser.go @@ -21,18 +21,11 @@ type parser struct { homeDir string } -func newParser() (p *parser, err error) { +func newParser(cfg *Config) (p *parser, err error) { p = &parser{ - files: make(map[string]struct{}), - } - - p.workDir, err = os.Getwd() - if err != nil { - return nil, err - } - p.homeDir, err = os.UserHomeDir() - if err != nil { - return nil, err + files: make(map[string]struct{}), + workDir: cfg.workDir, + homeDir: cfg.homeDir, } return p, nil diff --git a/lib/ssh/config/parser_test.go b/lib/ssh/config/parser_test.go index dea0db82..21bef8cd 100644 --- a/lib/ssh/config/parser_test.go +++ b/lib/ssh/config/parser_test.go @@ -134,7 +134,7 @@ func TestConfigParser_load(t *testing.T) { }} for _, c := range cases { - p, err := newParser() + p, err := newParser(dummyConfig) if err != nil { t.Fatal(err) } diff --git a/lib/ssh/config/section.go b/lib/ssh/config/section.go index dc0b9654..6b359bf5 100644 --- a/lib/ssh/config/section.go +++ b/lib/ssh/config/section.go @@ -232,27 +232,39 @@ type Section struct { } // NewSection create an empty Host or Match section. -func NewSection(name string) *Section { +// +// The Config parameter is optional, if not set the section will assume that +// any path is relative to current working directory or using absolute path. +func NewSection(cfg *Config, name string) (section *Section) { name = strings.TrimSpace(name) if len(name) == 0 { name = `*` } - return &Section{ + section = &Section{ Field: map[string]string{}, env: map[string]string{}, name: name, } -} -func newSectionHost(rawPattern string) (host *Section) { - patterns := strings.Fields(rawPattern) + if cfg != nil { + section.homeDir = cfg.homeDir + section.WorkingDir = cfg.workDir + } + + return section +} - host = NewSection(rawPattern) - host.patterns = make([]*pattern, 0, len(patterns)) +func newSectionHost(cfg *Config, rawPattern string) (host *Section) { + host = NewSection(cfg, rawPattern) - for _, pattern := range patterns { - pat := newPattern(pattern) + var ( + patterns = strings.Fields(rawPattern) + s string + pat *pattern + ) + for _, s = range patterns { + pat = newPattern(s) host.patterns = append(host.patterns, pat) } return host @@ -465,10 +477,7 @@ func (section *Section) isMatch(s string) bool { } // setDefaults set and expand all of the fields values if its not set. -func (section *Section) setDefaults(workDir, homeDir string) { - section.homeDir = homeDir - section.WorkingDir = workDir - +func (section *Section) setDefaults() { if len(section.IdentityFile) == 0 { section.IdentityFile = defaultIdentityFile() } diff --git a/lib/ssh/config/section_match.go b/lib/ssh/config/section_match.go index 7c28188d..9626e20c 100644 --- a/lib/ssh/config/section_match.go +++ b/lib/ssh/config/section_match.go @@ -22,14 +22,13 @@ var ( // Other criteria may be combined arbitrarily. // All criteria but "all", "canonical", and "final" require an argument. // Criteria may be negated by prepending an exclamation mark (`!'). -func newSectionMatch(rawPattern string) (match *Section, err error) { +func newSectionMatch(cfg *Config, rawPattern string) (match *Section, err error) { var ( prevCriteria *matchCriteria criteria *matchCriteria ) - match = NewSection(rawPattern) - match.criteria = make([]*matchCriteria, 0) + match = NewSection(cfg, rawPattern) match.useCriteria = true args := parseArgs(rawPattern, ' ') diff --git a/lib/ssh/config/section_match_test.go b/lib/ssh/config/section_match_test.go index d2742698..b1df06d9 100644 --- a/lib/ssh/config/section_match_test.go +++ b/lib/ssh/config/section_match_test.go @@ -21,7 +21,7 @@ func TestNewSectionMatch(t *testing.T) { }} for _, c := range cases { - got, err := newSectionMatch(c.raw) + got, err := newSectionMatch(dummyConfig, c.raw) if err != nil { if c.expError != err.Error() { t.Fatalf("parseCriteriaWithArg: expecting error %s, got %s", @@ -29,7 +29,7 @@ func TestNewSectionMatch(t *testing.T) { } continue } - got.setDefaults(testParser.workDir, testParser.homeDir) + got.setDefaults() test.Assert(t, c.raw, *c.exp, *got) } @@ -84,7 +84,7 @@ func TestParseCriteriaAll(t *testing.T) { }} for _, c := range cases { - got, err := newSectionMatch(c.raw) + got, err := newSectionMatch(dummyConfig, c.raw) if err != nil { if c.expError != err.Error() { t.Fatalf("parseCriteriaWithArg: expecting error %s, got %s", @@ -92,7 +92,7 @@ func TestParseCriteriaAll(t *testing.T) { } continue } - got.setDefaults(testParser.workDir, testParser.homeDir) + got.setDefaults() exp := c.exp(*testDefaultSection) test.Assert(t, c.raw, *exp, *got) @@ -129,7 +129,7 @@ func TestNewSectionMatch_ParseCriteriaExec(t *testing.T) { }} for _, c := range cases { - got, err := newSectionMatch(c.raw) + got, err := newSectionMatch(dummyConfig, c.raw) if err != nil { if c.expError != err.Error() { t.Fatalf("parseCriteriaWithArg: expecting error %s, got %s", @@ -137,7 +137,7 @@ func TestNewSectionMatch_ParseCriteriaExec(t *testing.T) { } continue } - got.setDefaults(testParser.workDir, testParser.homeDir) + got.setDefaults() exp := c.exp(*testDefaultSection) test.Assert(t, c.raw, *exp, *got) @@ -198,7 +198,7 @@ func TestParseCriteriaWithArg(t *testing.T) { }} for _, c := range cases { - got, err := newSectionMatch(c.raw) + got, err := newSectionMatch(dummyConfig, c.raw) if err != nil { if c.expError != err.Error() { t.Fatalf("parseCriteriaWithArg: expecting error %s, got %s", @@ -206,7 +206,7 @@ func TestParseCriteriaWithArg(t *testing.T) { } continue } - got.setDefaults(testParser.workDir, testParser.homeDir) + got.setDefaults() exp := c.exp(*testDefaultSection) test.Assert(t, c.raw, *exp, *got) diff --git a/lib/ssh/config/section_test.go b/lib/ssh/config/section_test.go index 760d93d6..e89cc7b5 100644 --- a/lib/ssh/config/section_test.go +++ b/lib/ssh/config/section_test.go @@ -17,7 +17,6 @@ func TestNewSectionHost(t *testing.T) { }{{ rawPattern: "", exp: func(exp Section) *Section { - exp.patterns = make([]*pattern, 0) return &exp }, }, { @@ -53,8 +52,8 @@ func TestNewSectionHost(t *testing.T) { }} for _, c := range cases { - got := newSectionHost(c.rawPattern) - got.setDefaults(testParser.workDir, testParser.homeDir) + got := newSectionHost(dummyConfig, c.rawPattern) + got.setDefaults() exp := c.exp(*testDefaultSection) test.Assert(t, c.rawPattern, *exp, *got) @@ -81,7 +80,7 @@ func TestSectionSetDefaults(t *testing.T) { }} for _, c := range cases { got := c.section(*testDefaultSection) - got.setDefaults(testParser.workDir, testParser.homeDir) + got.setDefaults() exp := c.exp(*testDefaultSection) test.Assert(t, `setDefaults`, exp.IdentityFile, got.IdentityFile) @@ -167,7 +166,7 @@ func TestSection_UserKnownHostsFile(t *testing.T) { }} var ( - section = NewSection(`test`) + section = NewSection(dummyConfig, `test`) c testCase err error |
