Files
ssh-netbox-wrapper/internal/shortcuts/shortcuts.go
Sebastian UnterschützandClaude Opus 5.5 878701aba7 feat(shortcuts): regex rewrite rules for host shortcuts
shortcuts.rewrites applies regex replacements after the domain suffix
is stripped, e.g. ^([a-z]+)[0-9]+- -> $1 turns fsn1-bx1.hoster.de into
fsnbx1. The shortcut works for connecting (cached hosts), shell
aliases, and Tab completion, where it is offered when the full name
does not match the typed text. Rules are editable in netssh configure,
and netssh alias --test HOSTNAME shows a name's shortcut and the cached
hosts it matches.

The shortcut lookup only ran when domains or strip_hyphens were set;
it now also runs for rewrite-only configurations.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-13 22:42:13 +01:00

65 lines
1.8 KiB
Go

package shortcuts
import (
"regexp"
"strings"
"sync"
"git.zb-server.de/Sebi/ssh-netbox-wrapper/internal/config"
)
// compiled caches rewrite patterns: Normalize runs for every cache entry on each lookup.
var compiled sync.Map // pattern → *regexp.Regexp
func rewritePattern(pattern string) *regexp.Regexp {
if re, ok := compiled.Load(pattern); ok {
return re.(*regexp.Regexp)
}
re, err := regexp.Compile(pattern)
if err != nil {
return nil // rejected by config.Load already
}
compiled.Store(pattern, re)
return re
}
// Normalize strips configured domain suffixes, applies rewrite rules in order, and
// optionally strips hyphens. The result is lowercased for case-insensitive comparison.
func Normalize(name string, cfg config.ShortcutsConfig) string {
s := strings.ToLower(name)
for _, domain := range cfg.Domains {
suffix := strings.ToLower(domain)
if !strings.HasPrefix(suffix, ".") {
suffix = "." + suffix
}
if strings.HasSuffix(s, suffix) {
s = s[:len(s)-len(suffix)]
break
}
}
for _, rewrite := range cfg.Rewrites {
if re := rewritePattern(rewrite.Pattern); re != nil {
s = re.ReplaceAllString(s, rewrite.Replace)
}
}
if cfg.StripHyphens {
s = strings.ReplaceAll(s, "-", "")
}
return s
}
// MakeNormalizer returns a closure bound to cfg, suitable for Cache.GetByShortcut.
func MakeNormalizer(cfg config.ShortcutsConfig) func(string) string {
return func(name string) string {
return Normalize(name, cfg)
}
}
// AliasName returns a shell-safe alias name for the given host.
// It normalizes the name (strips configured domains, applies rewrites, optionally strips hyphens) then
// replaces any remaining dots with underscores so the result is a valid identifier.
func AliasName(name string, cfg config.ShortcutsConfig) string {
s := Normalize(name, cfg)
return strings.NewReplacer(".", "_", "/", "_").Replace(s)
}