Allow user to dump current tmux session (#45)

master
Ivan 3 years ago committed by GitHub
parent 0e3b9a465f
commit 74fe70077d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -11,19 +11,19 @@ import (
)
type Pane struct {
Root string `yaml:"root"`
Type string `yaml:"type"`
Root string `yaml:"root,omitempty"`
Type string `yaml:"type,omitempty"`
Commands []string `yaml:"commands"`
}
type Window struct {
Name string `yaml:"name"`
Root string `yaml:"root"`
Root string `yaml:"root,omitempty"`
BeforeStart []string `yaml:"before_start"`
Panes []Pane `yaml:"panes"`
Commands []string `yaml:"commands"`
Layout string `yaml:"layout"`
Manual bool `yaml:"manual"`
Manual bool `yaml:"manual,omitempty"`
}
type Config struct {

@ -6,6 +6,8 @@ import (
"os"
"path/filepath"
"strings"
"gopkg.in/yaml.v2"
)
var version = "[dev build]"
@ -125,5 +127,19 @@ func main() {
}
fmt.Println(strings.Join(configs, "\n"))
case CommandPrint:
config, err := smug.GetConfigFromSession(options, context)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
d, err := yaml.Marshal(&config)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
fmt.Println(string(d))
}
}

@ -13,9 +13,10 @@ const (
CommandNew = "new"
CommandEdit = "edit"
CommandList = "list"
CommandPrint = "print"
)
var validCommands = []string{CommandStart, CommandStop, CommandNew, CommandEdit, CommandList}
var validCommands = []string{CommandStart, CommandStop, CommandNew, CommandEdit, CommandList, CommandPrint}
type Options struct {
Command string

@ -165,3 +165,40 @@ func (smug Smug) Start(config Config, options Options, context Context) error {
return nil
}
func (smug Smug) GetConfigFromSession(options Options, context Context) (Config, error) {
config := Config{}
config.Session = options.Project
tmuxWindows, err := smug.tmux.ListWindows(options.Project)
if err != nil {
return Config{}, err
}
for _, w := range tmuxWindows {
tmuxPanes, err := smug.tmux.ListPanes(options.Project + ":" + w.Id)
if err != nil {
return Config{}, err
}
panes := []Pane{}
for _, p := range tmuxPanes {
root := p.Root
if root == w.Root {
root = ""
}
panes = append(panes, Pane{
Root: root,
})
}
config.Windows = append(config.Windows, Window{
Name: w.Name,
Layout: w.Layout,
Root: w.Root,
Panes: panes,
})
}
return config, nil
}

@ -8,12 +8,12 @@ import (
)
var testTable = []struct {
config Config
options Options
context Context
startCommands []string
stopCommands []string
commanderOutput string
config Config
options Options
context Context
startCommands []string
stopCommands []string
commanderOutputs []string
}{
{
Config{
@ -44,7 +44,7 @@ var testTable = []struct {
[]string{
"tmux kill-session -t ses",
},
"xyz",
[]string{"xyz"},
},
{
Config{
@ -89,7 +89,7 @@ var testTable = []struct {
"/bin/sh -c stop2 -d --foo=bar",
"tmux kill-session -t ses",
},
"1",
[]string{"1"},
},
{
Config{
@ -121,7 +121,7 @@ var testTable = []struct {
[]string{
"tmux kill-window -t ses:win2",
},
"xyz",
[]string{"xyz"},
},
{
Config{
@ -162,7 +162,7 @@ var testTable = []struct {
[]string{
"tmux kill-session -t ses",
},
"xyz",
[]string{"xyz"},
},
{
Config{
@ -201,7 +201,7 @@ var testTable = []struct {
[]string{
"tmux kill-session -t ses",
},
"1",
[]string{"1"},
},
{
Config{
@ -221,7 +221,7 @@ var testTable = []struct {
[]string{
"tmux kill-session -t ses",
},
"",
[]string{""},
},
{
Config{
@ -247,7 +247,7 @@ var testTable = []struct {
[]string{
"tmux kill-session -t ses",
},
"xyz",
[]string{"xyz"},
},
{
Config{
@ -265,7 +265,7 @@ var testTable = []struct {
[]string{
"tmux kill-session -t ses",
},
"xyz",
[]string{"xyz"},
},
{
Config{
@ -284,19 +284,26 @@ var testTable = []struct {
[]string{
"tmux kill-session -t ses",
},
"",
[]string{""},
},
}
type MockCommander struct {
Commands []string
DefaultOutput string
Commands []string
Outputs []string
}
func (c *MockCommander) Exec(cmd *exec.Cmd) (string, error) {
c.Commands = append(c.Commands, strings.Join(cmd.Args, " "))
return c.DefaultOutput, nil
output := ""
if len(c.Outputs) > 1 {
output, c.Outputs = c.Outputs[0], c.Outputs[1:]
} else if len(c.Outputs) == 1 {
output = c.Outputs[0]
}
return output, nil
}
func (c *MockCommander) ExecSilently(cmd *exec.Cmd) error {
@ -304,11 +311,11 @@ func (c *MockCommander) ExecSilently(cmd *exec.Cmd) error {
return nil
}
func TestStartSession(t *testing.T) {
func TestStartStopSession(t *testing.T) {
for _, params := range testTable {
t.Run("test start session", func(t *testing.T) {
commander := &MockCommander{[]string{}, params.commanderOutput}
commander := &MockCommander{[]string{}, params.commanderOutputs}
tmux := Tmux{commander}
smug := Smug{tmux, commander}
@ -323,7 +330,7 @@ func TestStartSession(t *testing.T) {
})
t.Run("test stop session", func(t *testing.T) {
commander := &MockCommander{[]string{}, params.commanderOutput}
commander := &MockCommander{[]string{}, params.commanderOutputs}
tmux := Tmux{commander}
smug := Smug{tmux, commander}
@ -339,3 +346,39 @@ func TestStartSession(t *testing.T) {
}
}
func TestPrintCurrentSession(t *testing.T) {
expectedConfig := Config{
Session: "test",
Windows: []Window{
Window{
Name: "win1",
Root: "root",
Layout: "layout",
Panes: []Pane{
Pane{},
Pane{
Root: "/tmp",
},
},
},
},
}
commander := &MockCommander{[]string{}, []string{
"id1;win1;layout;root",
"root\n/tmp",
}}
tmux := Tmux{commander}
smug := Smug{tmux, commander}
actualConfig, err := smug.GetConfigFromSession(Options{Project: "test"}, Context{})
if err != nil {
t.Fatalf("error %v", err)
}
if !reflect.DeepEqual(expectedConfig, actualConfig) {
t.Errorf("expected %v, got %v", expectedConfig, actualConfig)
}
}

@ -3,6 +3,7 @@ package main
import (
"os"
"os/exec"
"strings"
)
const (
@ -22,6 +23,17 @@ type Tmux struct {
commander Commander
}
type TmuxWindow struct {
Id string
Name string
Layout string
Root string
}
type TmuxPane struct {
Root string
}
func (tmux Tmux) NewSession(name string, root string, windowName string) (string, error) {
cmd := exec.Command("tmux", "new", "-Pd", "-s", name, "-n", windowName, "-c", root)
return tmux.commander.Exec(cmd)
@ -102,3 +114,53 @@ func (tmux Tmux) SwitchClient(target string) error {
cmd := exec.Command("tmux", "switch-client", "-t", target)
return tmux.commander.ExecSilently(cmd)
}
func (tmux Tmux) ListWindows(target string) ([]TmuxWindow, error) {
var windows []TmuxWindow
cmd := exec.Command("tmux", "list-windows", "-F", "#{window_id};#{window_name};#{window_layout};#{pane_current_path}", "-t", target)
out, err := tmux.commander.Exec(cmd)
if err != nil {
return windows, err
}
windowsList := strings.Split(out, "\n")
for _, w := range windowsList {
windowInfo := strings.Split(w, ";")
window := TmuxWindow{
Id: windowInfo[0],
Name: windowInfo[1],
Layout: windowInfo[2],
Root: windowInfo[3],
}
windows = append(windows, window)
}
return windows, nil
}
func (tmux Tmux) ListPanes(target string) ([]TmuxPane, error) {
var panes []TmuxPane
cmd := exec.Command("tmux", "list-panes", "-F", "#{pane_current_path}", "-t", target)
out, err := tmux.commander.Exec(cmd)
if err != nil {
return panes, err
}
panesList := strings.Split(out, "\n")
for _, p := range panesList {
paneInfo := strings.Split(p, ";")
pane := TmuxPane{
Root: paneInfo[0],
}
panes = append(panes, pane)
}
return panes, nil
}

Loading…
Cancel
Save