From f86dcf23bc4ddd12778dfad5d189d9ab34ae74bc Mon Sep 17 00:00:00 2001 From: Jan De Dobbeleer Date: Tue, 3 Nov 2020 20:06:11 +0100 Subject: [PATCH] feat: ssh session indicator resolves #48 --- docs/docs/segment-session.md | 2 + segment_session.go | 22 ++++++- segment_session_test.go | 118 ++++++++++++++++++++++++++++++----- 3 files changed, 124 insertions(+), 18 deletions(-) diff --git a/docs/docs/segment-session.md b/docs/docs/segment-session.md index ef9bdc5e..0397eb64 100644 --- a/docs/docs/segment-session.md +++ b/docs/docs/segment-session.md @@ -24,6 +24,8 @@ Show the current user and host name. ## Properties - 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 - 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` diff --git a/segment_session.go b/segment_session.go index 8f459c0d..95454339 100755 --- a/segment_session.go +++ b/segment_session.go @@ -21,6 +21,8 @@ const ( DisplayHost Property = "display_host" //DisplayUser hides or shows the user name DisplayUser Property = "display_user" + //SSHIcon shows when in an SSH session + SSHIcon Property = "ssh_icon" ) 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) { 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 { @@ -68,3 +74,17 @@ func (s *session) getUserName() string { } 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 +} diff --git a/segment_session_test.go b/segment_session_test.go index 32d55ab4..2512ab53 100755 --- a/segment_session_test.go +++ b/segment_session_test.go @@ -6,13 +6,28 @@ import ( "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.On("getCurrentUser", nil).Return(username) - env.On("getHostName", nil).Return(hostname, nil) - env.On("getRuntimeGOOS", nil).Return(goos) + env.On("getCurrentUser", nil).Return(args.username) + env.On("getHostName", nil).Return(args.hostname, nil) + 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{ - values: map[Property]interface{}{UserInfoSeparator: userInfoSeparator}, + values: map[Property]interface{}{ + UserInfoSeparator: args.userInfoSeparator, + SSHIcon: args.sshIcon, + }, foreground: "#fff", background: "#000", } @@ -23,44 +38,113 @@ func setupSession(userInfoSeparator string, username string, hostname string, go return s } -func testUserInfoWriter(userInfoSeparator string, username string, hostname string, goos string) string { - s := setupSession(userInfoSeparator, username, hostname, goos) +func testUserInfoWriter(args *sessionArgs) string { + s := setupSession(args) return s.getFormattedText() } func TestWriteUserInfo(t *testing.T) { 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) } func TestWriteUserInfoWindowsIncludingHostname(t *testing.T) { 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) } 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 - want := "<#fff>bill<#fff>" got := s.getFormattedText() assert.EqualValues(t, want, got) } 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 - want := "<#fff><#fff>surface" got := s.getFormattedText() assert.EqualValues(t, want, got) } -func TestSession(t *testing.T) { - s := &session{ - env: &environment{}, +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", } - assert.NotEmpty(t, s.getUserName()) + 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{ + env: env, + } + 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()) }