feat: ssh session indicator

resolves #48
This commit is contained in:
Jan De Dobbeleer 2020-11-03 20:06:11 +01:00 committed by Jan De Dobbeleer
parent ed4fd895ec
commit f86dcf23bc
3 changed files with 124 additions and 18 deletions

View file

@ -24,6 +24,8 @@ Show the current user and host name.
## Properties ## Properties
- user_info_separator: `string` - text/icon to put in between the user and host name - defaults to `@` - user_info_separator: `string` - text/icon to put in between the user and host name - defaults to `@`
- ssh_icon: `string` - text/icon to display first when in an active SSH session - defaults
to `\uF817 `
- user_color: `string` [hex color code][colors] - override the foreground color of the user name - user_color: `string` [hex color code][colors] - override the foreground color of the user name
- host_color: `string` [hex color code][colors] - override the foreground color of the host name - host_color: `string` [hex color code][colors] - override the foreground color of the host name
- display_user: `boolean` - display the user name or not - defaults to `true` - display_user: `boolean` - display the user name or not - defaults to `true`

View file

@ -21,6 +21,8 @@ const (
DisplayHost Property = "display_host" DisplayHost Property = "display_host"
//DisplayUser hides or shows the user name //DisplayUser hides or shows the user name
DisplayUser Property = "display_user" DisplayUser Property = "display_user"
//SSHIcon shows when in an SSH session
SSHIcon Property = "ssh_icon"
) )
func (s *session) enabled() bool { func (s *session) enabled() bool {
@ -43,7 +45,11 @@ func (s *session) getFormattedText() string {
if s.props.getBool(DisplayHost, true) && s.props.getBool(DisplayUser, true) { if s.props.getBool(DisplayHost, true) && s.props.getBool(DisplayUser, true) {
separator = s.props.getString(UserInfoSeparator, "@") separator = s.props.getString(UserInfoSeparator, "@")
} }
return fmt.Sprintf("<%s>%s</>%s<%s>%s</>", s.props.getColor(UserColor, s.props.foreground), username, separator, s.props.getColor(HostColor, s.props.foreground), computername) var ssh string
if s.activeSSHSession() {
ssh = s.props.getString(SSHIcon, "\uF817 ")
}
return fmt.Sprintf("%s<%s>%s</>%s<%s>%s</>", ssh, s.props.getColor(UserColor, s.props.foreground), username, separator, s.props.getColor(HostColor, s.props.foreground), computername)
} }
func (s *session) getComputerName() string { func (s *session) getComputerName() string {
@ -68,3 +74,17 @@ func (s *session) getUserName() string {
} }
return username return username
} }
func (s *session) activeSSHSession() bool {
keys := []string{
"SSH_CONNECTION",
"SSH_CLIENT",
}
for _, key := range keys {
content := s.env.getenv(key)
if content != "" {
return true
}
}
return false
}

View file

@ -6,13 +6,28 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func setupSession(userInfoSeparator string, username string, hostname string, goos string) session { type sessionArgs struct {
userInfoSeparator string
username string
hostname string
goos string
connection string
client string
sshIcon string
}
func setupSession(args *sessionArgs) session {
env := new(MockedEnvironment) env := new(MockedEnvironment)
env.On("getCurrentUser", nil).Return(username) env.On("getCurrentUser", nil).Return(args.username)
env.On("getHostName", nil).Return(hostname, nil) env.On("getHostName", nil).Return(args.hostname, nil)
env.On("getRuntimeGOOS", nil).Return(goos) env.On("getRuntimeGOOS", nil).Return(args.goos)
env.On("getenv", "SSH_CONNECTION").Return(args.connection)
env.On("getenv", "SSH_CLIENT").Return(args.client)
props := &properties{ props := &properties{
values: map[Property]interface{}{UserInfoSeparator: userInfoSeparator}, values: map[Property]interface{}{
UserInfoSeparator: args.userInfoSeparator,
SSHIcon: args.sshIcon,
},
foreground: "#fff", foreground: "#fff",
background: "#000", background: "#000",
} }
@ -23,44 +38,113 @@ func setupSession(userInfoSeparator string, username string, hostname string, go
return s return s
} }
func testUserInfoWriter(userInfoSeparator string, username string, hostname string, goos string) string { func testUserInfoWriter(args *sessionArgs) string {
s := setupSession(userInfoSeparator, username, hostname, goos) s := setupSession(args)
return s.getFormattedText() return s.getFormattedText()
} }
func TestWriteUserInfo(t *testing.T) { func TestWriteUserInfo(t *testing.T) {
want := "<#fff>bill</>@<#fff>surface</>" want := "<#fff>bill</>@<#fff>surface</>"
got := testUserInfoWriter("@", "bill", "surface", "windows") args := &sessionArgs{
userInfoSeparator: "@",
username: "bill",
hostname: "surface",
goos: "windows",
}
got := testUserInfoWriter(args)
assert.EqualValues(t, want, got) assert.EqualValues(t, want, got)
} }
func TestWriteUserInfoWindowsIncludingHostname(t *testing.T) { func TestWriteUserInfoWindowsIncludingHostname(t *testing.T) {
want := "<#fff>bill</>@<#fff>surface</>" want := "<#fff>bill</>@<#fff>surface</>"
got := testUserInfoWriter("@", "surface\\bill", "surface", "windows") args := &sessionArgs{
userInfoSeparator: "@",
username: "surface\\bill",
hostname: "surface",
goos: "windows",
}
got := testUserInfoWriter(args)
assert.EqualValues(t, want, got) assert.EqualValues(t, want, got)
} }
func TestWriteOnlyUsername(t *testing.T) { func TestWriteOnlyUsername(t *testing.T) {
s := setupSession("@", "surface\\bill", "surface", "windows") args := &sessionArgs{
userInfoSeparator: "@",
username: "surface\\bill",
hostname: "surface",
goos: "windows",
}
s := setupSession(args)
s.props.values[DisplayHost] = false s.props.values[DisplayHost] = false
want := "<#fff>bill</><#fff></>" want := "<#fff>bill</><#fff></>"
got := s.getFormattedText() got := s.getFormattedText()
assert.EqualValues(t, want, got) assert.EqualValues(t, want, got)
} }
func TestWriteOnlyHostname(t *testing.T) { func TestWriteOnlyHostname(t *testing.T) {
s := setupSession("@", "surface\\bill", "surface", "windows") args := &sessionArgs{
userInfoSeparator: "@",
username: "surface\\bill",
hostname: "surface",
goos: "windows",
}
s := setupSession(args)
s.props.values[DisplayUser] = false s.props.values[DisplayUser] = false
want := "<#fff></><#fff>surface</>" want := "<#fff></><#fff>surface</>"
got := s.getFormattedText() got := s.getFormattedText()
assert.EqualValues(t, want, got) assert.EqualValues(t, want, got)
} }
func TestSession(t *testing.T) { func TestWriteActiveSSHSession(t *testing.T) {
want := "ssh <#fff>bill</>@<#fff>surface</>"
args := &sessionArgs{
userInfoSeparator: "@",
username: "bill",
hostname: "surface",
goos: "windows",
sshIcon: "ssh ",
connection: "1.1.1.1",
}
got := testUserInfoWriter(args)
assert.EqualValues(t, want, got)
}
func TestActiveSSHSessionInactive(t *testing.T) {
env := new(MockedEnvironment)
env.On("getenv", "SSH_CONNECTION").Return("")
env.On("getenv", "SSH_CLIENT").Return("")
s := &session{ s := &session{
env: &environment{}, env: env,
} }
assert.NotEmpty(t, s.getUserName()) assert.False(t, s.activeSSHSession())
}
func TestActiveSSHSessionActiveConnection(t *testing.T) {
env := new(MockedEnvironment)
env.On("getenv", "SSH_CONNECTION").Return("1.1.1.1")
env.On("getenv", "SSH_CLIENT").Return("")
s := &session{
env: env,
}
assert.True(t, s.activeSSHSession())
}
func TestActiveSSHSessionActiveClient(t *testing.T) {
env := new(MockedEnvironment)
env.On("getenv", "SSH_CONNECTION").Return("")
env.On("getenv", "SSH_CLIENT").Return("1.1.1.1")
s := &session{
env: env,
}
assert.True(t, s.activeSSHSession())
}
func TestActiveSSHSessionActiveBoth(t *testing.T) {
env := new(MockedEnvironment)
env.On("getenv", "SSH_CONNECTION").Return("2.2.2.2")
env.On("getenv", "SSH_CLIENT").Return("1.1.1.1")
s := &session{
env: env,
}
assert.True(t, s.activeSSHSession())
} }