automux 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +20 -0
- data/LICENSE.txt +22 -0
- data/VERSION +1 -0
- data/automux.gemspec +18 -0
- data/bin/automux +22 -0
- data/data/automux/blueprints/default.yml +26 -0
- data/data/automux/recipes/default.sh.erb +46 -0
- data/features/custom_recipes.feature +63 -0
- data/features/error_messages.feature +8 -0
- data/features/general_usage.feature +180 -0
- data/features/managing_blueprints.feature +66 -0
- data/features/runtime_options.feature +84 -0
- data/features/session_and_window_options.feature +67 -0
- data/features/session_hooks.feature +68 -0
- data/features/setup_windows.feature +22 -0
- data/features/step_definitions/custom_recipes_steps.rb +9 -0
- data/features/step_definitions/managing_blueprints_steps.rb +9 -0
- data/features/step_definitions/setup_windows_steps.rb +18 -0
- data/features/step_definitions/shared_steps.rb +43 -0
- data/features/support/env.rb +8 -0
- data/features/support/hooks.rb +4 -0
- data/features/support/transformations.rb +6 -0
- data/lib/automux.rb +9 -0
- data/lib/automux/cache.rb +10 -0
- data/lib/automux/cache/blueprint.rb +20 -0
- data/lib/automux/cache/recipe.rb +27 -0
- data/lib/automux/controller.rb +14 -0
- data/lib/automux/controller/base.rb +18 -0
- data/lib/automux/controller/blueprints.rb +45 -0
- data/lib/automux/controller/messages.rb +11 -0
- data/lib/automux/controller/recipes.rb +39 -0
- data/lib/automux/controller/setup.rb +11 -0
- data/lib/automux/controller/support.rb +5 -0
- data/lib/automux/controller/support/filters.rb +55 -0
- data/lib/automux/controller/support/rendering.rb +54 -0
- data/lib/automux/core.rb +11 -0
- data/lib/automux/core/base.rb +7 -0
- data/lib/automux/core/blueprint.rb +31 -0
- data/lib/automux/core/error.rb +15 -0
- data/lib/automux/core/hook.rb +26 -0
- data/lib/automux/core/option.rb +20 -0
- data/lib/automux/core/recipe.rb +12 -0
- data/lib/automux/core/support.rb +6 -0
- data/lib/automux/core/support/custom_accessors.rb +15 -0
- data/lib/automux/core/support/hooks_helper.rb +28 -0
- data/lib/automux/core/support/options_helper.rb +18 -0
- data/lib/automux/core/tmux.rb +6 -0
- data/lib/automux/core/tmux/pane.rb +19 -0
- data/lib/automux/core/tmux/session.rb +137 -0
- data/lib/automux/core/tmux/window.rb +76 -0
- data/lib/automux/initializers.rb +2 -0
- data/lib/automux/initializers/custom_hooks.rb +4 -0
- data/lib/automux/initializers/setup_caches.rb +3 -0
- data/lib/automux/library.rb +5 -0
- data/lib/automux/library/mini_erb.rb +22 -0
- data/lib/automux/library/yaml_parser.rb +41 -0
- data/lib/automux/paths.rb +41 -0
- data/lib/automux/setup.rb +0 -0
- data/lib/automux/views/blueprints/copy.sh.erb +2 -0
- data/lib/automux/views/blueprints/create.sh.erb +2 -0
- data/lib/automux/views/blueprints/edit.sh.erb +1 -0
- data/lib/automux/views/messages/error.sh.erb +3 -0
- data/lib/automux/views/setup/clone_defaults.sh.erb +21 -0
- data/test/session_test.rb +16 -0
- data/test/support/common_methods.rb +0 -0
- data/test/support/factories.rb +13 -0
- data/test/support/hash_factory.rb +19 -0
- data/test/support/test_helper.rb +7 -0
- metadata +136 -0
@@ -0,0 +1,84 @@
|
|
1
|
+
Feature: Providing runtime options for blueprints
|
2
|
+
|
3
|
+
Scenario: Providing commands and disabling windows at runtime
|
4
|
+
Given I have the following blueprint named "test_sample"
|
5
|
+
"""
|
6
|
+
name: test
|
7
|
+
root: '-r:'
|
8
|
+
windows:
|
9
|
+
- name: top
|
10
|
+
opt: '-t'
|
11
|
+
panes: top
|
12
|
+
"""
|
13
|
+
When Automux processes the blueprint "test_sample" with the following options
|
14
|
+
| option | value |
|
15
|
+
| -r | test |
|
16
|
+
Then the rendered sequence of shell commands should be
|
17
|
+
"""
|
18
|
+
cd test
|
19
|
+
|
20
|
+
tmux start-server
|
21
|
+
tmux new-session -d -s test
|
22
|
+
|
23
|
+
tmux attach-session -t test
|
24
|
+
"""
|
25
|
+
|
26
|
+
Scenario: Completing partial commands at runtime
|
27
|
+
Given I have the following blueprint named "test_sample"
|
28
|
+
"""
|
29
|
+
name: test
|
30
|
+
windows:
|
31
|
+
- name: git
|
32
|
+
panes: git pull "-r:" master
|
33
|
+
"""
|
34
|
+
When Automux processes the blueprint "test_sample" with the following options
|
35
|
+
| option | value |
|
36
|
+
| -r | origin |
|
37
|
+
Then the rendered sequence of shell commands should be
|
38
|
+
"""
|
39
|
+
cd .
|
40
|
+
|
41
|
+
tmux start-server
|
42
|
+
tmux new-session -d -s test
|
43
|
+
|
44
|
+
tmux new-window -t test:0 2> /dev/null
|
45
|
+
tmux rename-window -t test:0 git
|
46
|
+
tmux send-keys -t test:0 "git pull origin master" C-m
|
47
|
+
|
48
|
+
tmux attach-session -t test
|
49
|
+
"""
|
50
|
+
|
51
|
+
Scenario: Providing combined runtime options
|
52
|
+
Given I have the following blueprint named "test_sample"
|
53
|
+
"""
|
54
|
+
name: test
|
55
|
+
root: '-r:'
|
56
|
+
windows:
|
57
|
+
- name: vim
|
58
|
+
opt: "-v"
|
59
|
+
panes: vim
|
60
|
+
- name: top
|
61
|
+
opt: '-t'
|
62
|
+
panes: top
|
63
|
+
"""
|
64
|
+
When Automux processes the blueprint "test_sample" with the following options
|
65
|
+
| option | value |
|
66
|
+
| -vtr | projects |
|
67
|
+
Then the rendered sequence of shell commands should be
|
68
|
+
"""
|
69
|
+
cd projects
|
70
|
+
|
71
|
+
tmux start-server
|
72
|
+
tmux new-session -d -s test
|
73
|
+
|
74
|
+
tmux new-window -t test:0 2> /dev/null
|
75
|
+
tmux rename-window -t test:0 vim
|
76
|
+
tmux send-keys -t test:0 "vim" C-m
|
77
|
+
|
78
|
+
tmux new-window -t test:1 2> /dev/null
|
79
|
+
tmux rename-window -t test:1 top
|
80
|
+
tmux send-keys -t test:1 "top" C-m
|
81
|
+
|
82
|
+
tmux attach-session -t test
|
83
|
+
"""
|
84
|
+
|
@@ -0,0 +1,67 @@
|
|
1
|
+
Feature: Handling session/window specific options
|
2
|
+
|
3
|
+
Scenario: setting options for session and window together
|
4
|
+
Given I have the following blueprint named "test_sample"
|
5
|
+
"""
|
6
|
+
name: test
|
7
|
+
options:
|
8
|
+
status-left: '#S>'
|
9
|
+
status: off
|
10
|
+
windows:
|
11
|
+
- panes: pwd
|
12
|
+
hooks:
|
13
|
+
post: ls
|
14
|
+
options:
|
15
|
+
automatic-rename: off
|
16
|
+
window-status-bg: black
|
17
|
+
"""
|
18
|
+
When I invoke Automux with the blueprint "test_sample"
|
19
|
+
Then the rendered sequence of shell commands should be
|
20
|
+
"""
|
21
|
+
cd .
|
22
|
+
|
23
|
+
tmux start-server
|
24
|
+
tmux new-session -d -s test
|
25
|
+
|
26
|
+
tmux set-option status-left '#S>'
|
27
|
+
tmux set-option status 'off'
|
28
|
+
|
29
|
+
tmux new-window -t test:0 2> /dev/null
|
30
|
+
tmux send-keys -t test:0 "pwd" C-m
|
31
|
+
|
32
|
+
tmux set-window-option -t test:0 automatic-rename 'off'
|
33
|
+
tmux set-window-option -t test:0 window-status-bg 'black'
|
34
|
+
|
35
|
+
tmux send-keys -t test:0 "ls" C-m
|
36
|
+
|
37
|
+
tmux attach-session -t test
|
38
|
+
"""
|
39
|
+
|
40
|
+
Scenario: Setting the base index
|
41
|
+
Given I have the following blueprint named "test_sample"
|
42
|
+
"""
|
43
|
+
name: test
|
44
|
+
options:
|
45
|
+
base-index: 2
|
46
|
+
windows:
|
47
|
+
- panes: pwd
|
48
|
+
- panes: ls
|
49
|
+
"""
|
50
|
+
When I invoke Automux with the blueprint "test_sample"
|
51
|
+
Then the rendered sequence of shell commands should be
|
52
|
+
"""
|
53
|
+
cd .
|
54
|
+
|
55
|
+
tmux start-server
|
56
|
+
tmux new-session -d -s test
|
57
|
+
|
58
|
+
tmux set-option base-index '2'
|
59
|
+
|
60
|
+
tmux new-window -t test:2 2> /dev/null
|
61
|
+
tmux send-keys -t test:2 "pwd" C-m
|
62
|
+
|
63
|
+
tmux new-window -t test:3 2> /dev/null
|
64
|
+
tmux send-keys -t test:3 "ls" C-m
|
65
|
+
|
66
|
+
tmux attach-session -t test
|
67
|
+
"""
|
@@ -0,0 +1,68 @@
|
|
1
|
+
Feature: Using pre and post hooks for session
|
2
|
+
|
3
|
+
Scenario: Using session hooks
|
4
|
+
Given I have the following blueprint named "test_sample"
|
5
|
+
"""
|
6
|
+
name: hooked
|
7
|
+
hooks:
|
8
|
+
pre:
|
9
|
+
- "echo Hello"
|
10
|
+
- "rvm use automux"
|
11
|
+
post: "echo 'I will be back'"
|
12
|
+
"""
|
13
|
+
When I invoke Automux with the blueprint "test_sample"
|
14
|
+
Then the rendered sequence of shell commands should be
|
15
|
+
"""
|
16
|
+
cd .
|
17
|
+
|
18
|
+
echo Hello
|
19
|
+
rvm use automux
|
20
|
+
|
21
|
+
tmux start-server
|
22
|
+
tmux new-session -d -s hooked
|
23
|
+
|
24
|
+
tmux attach-session -t hooked
|
25
|
+
|
26
|
+
echo 'I will be back'
|
27
|
+
"""
|
28
|
+
|
29
|
+
Scenario: Using window hooks
|
30
|
+
Given I have the following blueprint named "test_sample"
|
31
|
+
"""
|
32
|
+
name: hooked
|
33
|
+
hooks:
|
34
|
+
pre: "echo <%= name %>"
|
35
|
+
windows:
|
36
|
+
- panes: pwd
|
37
|
+
- name: echoed-window
|
38
|
+
hooks:
|
39
|
+
pre:
|
40
|
+
- echo <%= name %> start
|
41
|
+
- rvm use custom
|
42
|
+
post: echo <%= name %> complete
|
43
|
+
panes:
|
44
|
+
- ls
|
45
|
+
"""
|
46
|
+
When I invoke Automux with the blueprint "test_sample"
|
47
|
+
Then the rendered sequence of shell commands should be
|
48
|
+
"""
|
49
|
+
cd .
|
50
|
+
|
51
|
+
echo hooked
|
52
|
+
|
53
|
+
tmux start-server
|
54
|
+
tmux new-session -d -s hooked
|
55
|
+
|
56
|
+
tmux new-window -t hooked:0 2> /dev/null
|
57
|
+
tmux send-keys -t hooked:0 "pwd" C-m
|
58
|
+
|
59
|
+
tmux new-window -t hooked:1 2> /dev/null
|
60
|
+
tmux rename-window -t hooked:1 echoed-window
|
61
|
+
|
62
|
+
tmux send-keys -t hooked:1 "echo echoed-window start" C-m
|
63
|
+
tmux send-keys -t hooked:1 "rvm use custom" C-m
|
64
|
+
tmux send-keys -t hooked:1 "ls" C-m
|
65
|
+
tmux send-keys -t hooked:1 "echo echoed-window complete" C-m
|
66
|
+
|
67
|
+
tmux attach-session -t hooked
|
68
|
+
"""
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Feature: Creating Window objects from user provided data
|
2
|
+
|
3
|
+
Scenario: Window with conflicting indexes
|
4
|
+
Given I have provided a blueprint with the following window information
|
5
|
+
| name | index | panes |
|
6
|
+
| first | 1 | top |
|
7
|
+
| second | | pwd |
|
8
|
+
| third | 1 | ls |
|
9
|
+
| fourth | 0 | echo |
|
10
|
+
When the windows are setup
|
11
|
+
Then the window with the name "first" should have the following
|
12
|
+
| index |
|
13
|
+
| 1 |
|
14
|
+
And the window with the name "second" should have the following
|
15
|
+
| index |
|
16
|
+
| 2 |
|
17
|
+
And the window with the name "third" should have the following
|
18
|
+
| index |
|
19
|
+
| 3 |
|
20
|
+
And the window with the name "fourth" should have the following
|
21
|
+
| index |
|
22
|
+
| 0 |
|
@@ -0,0 +1,9 @@
|
|
1
|
+
Given(/^I have the following recipe named "(.+)"$/) do |name, string|
|
2
|
+
path = File.join(Automux::Paths.recipes_container, "#{ name }.sh.erb")
|
3
|
+
File.open(path, 'w') { |f| f.write(string) }
|
4
|
+
end
|
5
|
+
|
6
|
+
When(/^I invoke Automux with the recipe "(.+)" and the blueprint "(.+)"$/) do |recipe_name, blueprint_name|
|
7
|
+
system %[bin/automux #{ blueprint_name } #{ recipe_name }]
|
8
|
+
@results = File.read('/tmp/results')
|
9
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
When(/^I invoke Automux to "(.+)" the blueprint "(.+)"$/) do |action, name|
|
2
|
+
system %[bin/automux blueprint #{ action } #{ name }]
|
3
|
+
@results = File.read('/tmp/results')
|
4
|
+
end
|
5
|
+
|
6
|
+
When(/^I call Automux to "(.+)" the blueprint "(.+)" as "(.+)"$/) do |action, target_name, destination_name|
|
7
|
+
system %[bin/automux blueprint #{ action } #{ target_name } #{ destination_name }]
|
8
|
+
@results = File.read('/tmp/results')
|
9
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
Given(/^I have provided a blueprint with the following window information$/) do |table|
|
2
|
+
windows_data = common_transformations(table.hashes)
|
3
|
+
@data = {"project_name"=>"test", "project_root"=>"~/"}
|
4
|
+
@data['windows'] = windows_data
|
5
|
+
end
|
6
|
+
|
7
|
+
When(/^the windows are setup$/) do
|
8
|
+
@session = Automux::Core::Tmux::Session.new(@data)
|
9
|
+
@session.setup
|
10
|
+
end
|
11
|
+
|
12
|
+
Then(/^the window with the name "(.+)" should have the following$/) do |name, table|
|
13
|
+
window = @session.windows.find { |window| window.name == name }
|
14
|
+
params = common_transformations(table.hashes).first
|
15
|
+
params.each do |field, value|
|
16
|
+
window.send(field).must_equal value
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
Given(/^I have the following blueprint named "(.+)"$/) do |name, string|
|
2
|
+
path = File.join(Automux::Paths.blueprints_container, "#{ name }.yml")
|
3
|
+
File.open(path, 'w') { |f| f.write(string) }
|
4
|
+
end
|
5
|
+
|
6
|
+
When(/^Automux processes the blueprint "(.+)" with the following options$/) do |name, table|
|
7
|
+
opts = table.hashes.map { |h| h.values }.flatten.join(' ')
|
8
|
+
system %[bin/automux #{ name } #{ opts }]
|
9
|
+
@results = File.read('/tmp/results')
|
10
|
+
end
|
11
|
+
|
12
|
+
Then(/^the rendered sequence of shell commands should be$/) do |string|
|
13
|
+
expected_array, results_array = expected_and_results_array(string)
|
14
|
+
|
15
|
+
expected_array.length.times do |i|
|
16
|
+
assert_equal(expected_array[i], results_array[i])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
Then(/^the rendered sequence of shell commands should contain$/) do |string|
|
21
|
+
expected_array, results_array = expected_and_results_array(string)
|
22
|
+
|
23
|
+
expected_array.each do |command|
|
24
|
+
assert_includes(results_array, command)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def expected_and_results_array(string)
|
29
|
+
results_array = @results.split("\n").map { |text| text.strip }
|
30
|
+
expected_array = expected_array_for(string)
|
31
|
+
[expected_array, results_array]
|
32
|
+
end
|
33
|
+
|
34
|
+
def expected_array_for(string)
|
35
|
+
expected_string = string.gsub(/\$HOME/, ENV['HOME'])
|
36
|
+
expected_array = expected_string.split("\n").reject { |text| text.split.empty? }
|
37
|
+
expected_array.map { |text| text.strip }
|
38
|
+
end
|
39
|
+
|
40
|
+
When(/^I invoke Automux with the blueprint "(.*?)"$/) do |name|
|
41
|
+
system %[bin/automux #{ name }]
|
42
|
+
@results = File.read('/tmp/results')
|
43
|
+
end
|
data/lib/automux.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
module Automux
|
2
|
+
module Cache
|
3
|
+
module Blueprint
|
4
|
+
extend self
|
5
|
+
|
6
|
+
Instances = {}
|
7
|
+
|
8
|
+
def setup
|
9
|
+
Automux::Paths.blueprints.each do |path|
|
10
|
+
blueprint = Automux::Core::Blueprint.new(path)
|
11
|
+
Instances[blueprint.name] = blueprint
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def find_by_name(name)
|
16
|
+
Instances[name]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Automux
|
2
|
+
module Cache
|
3
|
+
module Recipe
|
4
|
+
extend self
|
5
|
+
|
6
|
+
Instances = {}
|
7
|
+
|
8
|
+
def setup
|
9
|
+
user_and_default_recipe_paths.each do |path|
|
10
|
+
recipe = Automux::Core::Recipe.new(path)
|
11
|
+
Instances[recipe.name] = recipe
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def find_by_name(name)
|
16
|
+
Instances[name]
|
17
|
+
end
|
18
|
+
|
19
|
+
private ###
|
20
|
+
|
21
|
+
# Default recipe overwrites any user defined recipe having the same name.
|
22
|
+
def user_and_default_recipe_paths
|
23
|
+
Automux::Paths.recipes.push(Automux::Paths.default_recipe)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'automux/controller/support'
|
2
|
+
require 'automux/controller/base'
|
3
|
+
require 'automux/controller/setup'
|
4
|
+
require 'automux/controller/recipes'
|
5
|
+
require 'automux/controller/blueprints'
|
6
|
+
require 'automux/controller/messages'
|
7
|
+
|
8
|
+
module Automux::Controller
|
9
|
+
class << self
|
10
|
+
def base_inheriting_classes
|
11
|
+
constants.select { |constant_name| const_get(constant_name) < Base }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Automux
|
2
|
+
module Controller
|
3
|
+
class Base
|
4
|
+
include Support::Rendering
|
5
|
+
extend Support::Filters
|
6
|
+
|
7
|
+
attr_reader :params
|
8
|
+
|
9
|
+
def initialize(params = {})
|
10
|
+
@params = params
|
11
|
+
end
|
12
|
+
|
13
|
+
def notify_error(message)
|
14
|
+
Automux::Controller::Messages.new(message: message).error
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|