tmuxinator 3.3.3 → 3.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f5ef87c54d6e438767477e9e41cbe4d0b0d802c6aa980d07d1921819a7dc2b81
4
- data.tar.gz: dc974393d493a3ebfd556c87615472acc34f4dc328bb2a31b277ad40a865c8d1
3
+ metadata.gz: 0cb65a3fb5e0efb97b014caaf4bd1592508b5ee6502ed97b4088c66504750b46
4
+ data.tar.gz: 617eb45c7c9f093c2dc25ebe266ba620cc1a27d85970ceef0fa0eb4eeb4d73d0
5
5
  SHA512:
6
- metadata.gz: dec7830c2331a3fb50a36afd880168ab3ec616900b41ba87c33e610235ee5cb935f794c1738ab5054bc78e3303b3fc078a1a380aed45fd7c9a08870b6a360ca0
7
- data.tar.gz: 182bc06919fe54d090fc455c5f69c5a653115887d495acba204cc2112ffd7379e759d3ed8d40067b8c00be1b20d95468f15a72562728400bfbb806f4a7020ede
6
+ metadata.gz: 71a996aab90fa249664b58ae6c7b70bbb1f2d49fa9dbc93437b836813155ac119e5643504cfc8291f0fca2854b826c363d2466f0e294585d46d7a73c26dc23db
7
+ data.tar.gz: 596e41873c37d199fd954c0078f026996dad916f5f9dc8b394f670cbadda44e3a8e371f3c7e7e855f36c83f9b4b0055d57e1d80856365853865e60ee55c6e431
@@ -1,17 +1,19 @@
1
1
  #!<%= ENV["SHELL"] || "/bin/bash" %>
2
2
 
3
- # Clear rbenv variables before starting tmux
4
- unset RBENV_VERSION
5
- unset RBENV_DIR
3
+ <%- if !append? -%>
4
+ # Clear rbenv variables before starting tmux
5
+ unset RBENV_VERSION
6
+ unset RBENV_DIR
6
7
 
7
- <%= tmux %> start-server;
8
+ <%= tmux %> start-server;
9
+ <%- end -%>
8
10
 
9
11
  cd <%= root || "." %>
10
12
 
11
13
  # Run on_project_start command.
12
14
  <%= hook_on_project_start %>
13
15
 
14
- <%- if !tmux_has_session? name -%>
16
+ <%- if append? || !tmux_has_session?(name) -%>
15
17
 
16
18
  # Run pre command.
17
19
  <%= pre %>
@@ -98,7 +100,7 @@ cd <%= root || "." %>
98
100
  <%= hook_on_project_restart %>
99
101
  <%- end -%>
100
102
 
101
- <%- if attach? -%>
103
+ <%- if attach? && !append? -%>
102
104
  if [ -z "$TMUX" ]; then
103
105
  <%= tmux %> -u attach-session -t <%= name %>
104
106
  else
@@ -176,28 +176,22 @@ module Tmuxinator
176
176
  end
177
177
 
178
178
  def create_project(project_options = {})
179
- # Strings provided to --attach are coerced into booleans by Thor.
180
- # "f" and "false" will result in `:attach` being `false` and any other
181
- # string or the empty flag will result in `:attach` being `true`.
182
- # If the flag is not present, `:attach` will be `nil`.
183
- attach = detach = false
184
- attach = true if project_options[:attach] == true
185
- detach = true if project_options[:attach] == false
186
-
187
- options = {
179
+ Tmuxinator::Config.validate(project_create_options(project_options))
180
+ rescue StandardError => e
181
+ exit! e.message
182
+ end
183
+
184
+ def project_create_options(project_options)
185
+ {
188
186
  args: project_options[:args],
189
187
  custom_name: project_options[:custom_name],
190
- force_attach: attach,
191
- force_detach: detach,
188
+ force_attach: project_options[:attach] == true,
189
+ force_detach: project_options[:attach] == false,
192
190
  name: project_options[:name],
193
- project_config: project_options[:project_config]
191
+ project_config: project_options[:project_config],
192
+ append: project_options[:append],
193
+ no_pre_window: project_options[:no_pre_window],
194
194
  }
195
-
196
- begin
197
- Tmuxinator::Config.validate(options)
198
- rescue StandardError => e
199
- exit! e.message
200
- end
201
195
  end
202
196
 
203
197
  def render_project(project)
@@ -227,6 +221,25 @@ module Tmuxinator
227
221
  def kill_project(project)
228
222
  Kernel.exec(project.kill)
229
223
  end
224
+
225
+ def start_params(name = nil, *args)
226
+ # project-config takes precedence over a named project in the case that
227
+ # both are provided.
228
+ if options["project-config"]
229
+ args.unshift name if name
230
+ name = nil
231
+ end
232
+
233
+ {
234
+ args: args,
235
+ attach: options[:attach],
236
+ custom_name: options[:name],
237
+ name: name,
238
+ project_config: options["project-config"],
239
+ append: options["append"],
240
+ no_pre_window: options["no-pre-window"],
241
+ }
242
+ end
230
243
  end
231
244
 
232
245
  desc "start [PROJECT] [ARGS]", COMMANDS[:start]
@@ -240,22 +253,13 @@ module Tmuxinator
240
253
  desc: "Path to project config file"
241
254
  method_option "suppress-tmux-version-warning",
242
255
  desc: "Don't show a warning for unsupported tmux versions"
243
-
256
+ method_option :append, type: :boolean,
257
+ desc: "Appends the project windows and panes in " \
258
+ "the current session"
259
+ method_option "no-pre-window", type: :boolean, default: false,
260
+ desc: "Skip pre_window commands"
244
261
  def start(name = nil, *args)
245
- # project-config takes precedence over a named project in the case that
246
- # both are provided.
247
- if options["project-config"]
248
- args.unshift name if name
249
- name = nil
250
- end
251
-
252
- params = {
253
- args: args,
254
- attach: options[:attach],
255
- custom_name: options[:name],
256
- name: name,
257
- project_config: options["project-config"]
258
- }
262
+ params = start_params(name, *args)
259
263
 
260
264
  show_version_warning if version_warning?(
261
265
  options["suppress-tmux-version-warning"]
@@ -312,24 +316,16 @@ module Tmuxinator
312
316
  desc: "Give the session a different name"
313
317
  method_option "project-config", aliases: "-p",
314
318
  desc: "Path to project config file"
315
-
319
+ method_option :append, type: :boolean,
320
+ desc: "Appends the project windows and panes in " \
321
+ "the current session"
322
+ method_option "no-pre-window", type: :boolean, default: false,
323
+ desc: "Skip pre_window commands"
316
324
  def debug(name = nil, *args)
317
- # project-config takes precedence over a named project in the case that
318
- # both are provided.
319
- if options["project-config"]
320
- args.unshift name if name
321
- name = nil
322
- end
323
-
324
- params = {
325
- args: args,
326
- attach: options[:attach],
327
- custom_name: options[:name],
328
- name: name,
329
- project_config: options["project-config"]
330
- }
325
+ params = start_params(name, *args)
331
326
 
332
327
  project = create_project(params)
328
+
333
329
  say project.render
334
330
  end
335
331
 
@@ -439,7 +435,7 @@ module Tmuxinator
439
435
  Tmuxinator::Cli.new.local
440
436
  elsif name && !Tmuxinator::Cli::RESERVED_COMMANDS.include?(name) &&
441
437
  Tmuxinator::Config.exist?(name: name)
442
- Tmuxinator::Cli.new.start(name, *args.drop(1))
438
+ Tmuxinator::Cli.start([:start, *args])
443
439
  else
444
440
  Tmuxinator::Cli.start(args)
445
441
  end
@@ -40,6 +40,7 @@ module Tmuxinator
40
40
  attr_reader :force_attach
41
41
  attr_reader :force_detach
42
42
  attr_reader :custom_name
43
+ attr_reader :no_pre_window
43
44
 
44
45
  def self.load(path, options = {})
45
46
  yaml = begin
@@ -83,15 +84,29 @@ module Tmuxinator
83
84
 
84
85
  @yaml = yaml
85
86
 
86
- @custom_name = options[:custom_name]
87
+ set_instance_variables_from_options(options)
88
+
89
+ validate_options
90
+
91
+ extend Tmuxinator::WemuxSupport if wemux?
92
+ end
87
93
 
94
+ def set_instance_variables_from_options(options)
95
+ @custom_name = options[:custom_name]
88
96
  @force_attach = options[:force_attach]
89
97
  @force_detach = options[:force_detach]
98
+ @append = options[:append]
99
+ @no_pre_window = options[:no_pre_window]
100
+ end
90
101
 
91
- raise "Cannot force_attach and force_detach at the same time" \
92
- if @force_attach && @force_detach
102
+ def validate_options
103
+ if @force_attach && @force_detach
104
+ raise "Cannot force_attach and force_detach at the same time"
105
+ end
93
106
 
94
- extend Tmuxinator::WemuxSupport if wemux?
107
+ if append? && !tmux_has_session?(name)
108
+ raise "Cannot append to a session that does not exist"
109
+ end
95
110
  end
96
111
 
97
112
  def render
@@ -120,11 +135,25 @@ module Tmuxinator
120
135
  blank?(root) ? nil : File.expand_path(root).shellescape
121
136
  end
122
137
 
138
+ def current_session_name
139
+ `[[ -n "${TMUX+set}" ]] && tmux display-message -p "#S"`.strip
140
+ end
141
+
123
142
  def name
124
- name = custom_name || yaml["project_name"] || yaml["name"]
143
+ name =
144
+ if append?
145
+ current_session_name
146
+ else
147
+ custom_name || yaml["project_name"] || yaml["name"]
148
+ end
149
+
125
150
  blank?(name) ? nil : name.to_s.shellescape
126
151
  end
127
152
 
153
+ def append?
154
+ @append
155
+ end
156
+
128
157
  def pre
129
158
  pre_config = yaml["pre"]
130
159
  parsed_parameters(pre_config)
@@ -141,6 +170,8 @@ module Tmuxinator
141
170
  end
142
171
 
143
172
  def pre_window
173
+ return if no_pre_window
174
+
144
175
  params = if rbenv?
145
176
  "rbenv shell #{yaml['rbenv']}"
146
177
  elsif rvm?
@@ -167,6 +198,8 @@ module Tmuxinator
167
198
  end
168
199
 
169
200
  def tmux_has_session?(name)
201
+ return false unless name
202
+
170
203
  # Redirect stderr to /dev/null in order to prevent "failed to connect
171
204
  # to server: Connection refused" error message and non-zero exit status
172
205
  # if no tmux sessions exist.
@@ -208,7 +241,13 @@ module Tmuxinator
208
241
  end
209
242
  end
210
243
 
244
+ def last_window_index
245
+ `tmux list-windows -F '#I'`.split.last.to_i
246
+ end
247
+
211
248
  def base_index
249
+ return last_window_index + 1 if append?
250
+
212
251
  get_base_index.to_i
213
252
  end
214
253
 
@@ -241,7 +280,7 @@ module Tmuxinator
241
280
  end
242
281
 
243
282
  def window(index)
244
- "#{name}:#{index}"
283
+ append? ? ":#{index}" : "#{name}:#{index}"
245
284
  end
246
285
 
247
286
  def send_pane_command(cmd, window_index, _pane_index)
@@ -329,6 +368,8 @@ module Tmuxinator
329
368
  end
330
369
 
331
370
  def tmux_new_session_command
371
+ return if append?
372
+
332
373
  window = windows.first.tmux_window_name_option
333
374
  "#{tmux} new-session -d -s #{name} #{window}"
334
375
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tmuxinator
4
- VERSION = "3.3.3"
4
+ VERSION = "3.3.4"
5
5
  end
@@ -115,4 +115,12 @@ FactoryBot.define do
115
115
 
116
116
  initialize_with { Tmuxinator::Project.load(file) }
117
117
  end
118
+
119
+ factory :project_with_append, class: Tmuxinator::Project do
120
+ transient do
121
+ file { "spec/fixtures/sample.yml" }
122
+ end
123
+
124
+ initialize_with { Tmuxinator::Project.load(file, append: true) }
125
+ end
118
126
  end
@@ -99,11 +99,18 @@ describe Tmuxinator::Cli do
99
99
  end
100
100
 
101
101
  it "should call #start" do
102
- instance = instance_double(cli)
103
- expect(cli).to receive(:new).and_return(instance)
104
- expect(instance).to receive(:start).with(*args)
102
+ expect(cli).to receive(:start).with([:start, *args])
105
103
  subject
106
104
  end
105
+
106
+ context "and the append option is passed" do
107
+ let(:args) { ["sample", "--append"] }
108
+
109
+ it "should call #start" do
110
+ expect(cli).to receive(:start).with([:start, *args])
111
+ subject
112
+ end
113
+ end
107
114
  end
108
115
 
109
116
  context "a thor command" do
@@ -37,6 +37,10 @@ describe Tmuxinator::Project do
37
37
  FactoryBot.build(:project_with_alias)
38
38
  end
39
39
 
40
+ let(:project_with_append) do
41
+ FactoryBot.build(:project_with_append)
42
+ end
43
+
40
44
  it "should include Hooks" do
41
45
  expect(project).to be_kind_of(Tmuxinator::Hooks::Project)
42
46
  end
@@ -46,6 +50,21 @@ describe Tmuxinator::Project do
46
50
  it "creates an instance" do
47
51
  expect(project).to be_a(Tmuxinator::Project)
48
52
  end
53
+
54
+ it "validates append outside a current session" do
55
+ Tmuxinator::Project.any_instance.stub(tmux_has_session?: false)
56
+ expect { project_with_append }.to(
57
+ raise_error(
58
+ RuntimeError,
59
+ "Cannot append to a session that does not exist"
60
+ )
61
+ )
62
+ end
63
+
64
+ it "validates append within a current session" do
65
+ Tmuxinator::Project.any_instance.stub(tmux_has_session?: true)
66
+ expect { project_with_append }.to_not raise_error
67
+ end
49
68
  end
50
69
  end
51
70
 
@@ -262,6 +281,16 @@ describe Tmuxinator::Project do
262
281
  end
263
282
  end
264
283
  end
284
+
285
+ context "no_pre_window option is true" do
286
+ before do
287
+ allow(project).to receive_messages(no_pre_window: true)
288
+ end
289
+
290
+ it "returns nil" do
291
+ expect(pre_window).to be_nil
292
+ end
293
+ end
265
294
  end
266
295
 
267
296
  describe "#socket" do
@@ -368,6 +397,17 @@ describe Tmuxinator::Project do
368
397
  expect(project.base_index).to eq 0
369
398
  end
370
399
  end
400
+
401
+ context "with append set" do
402
+ before do
403
+ Tmuxinator::Project.any_instance.stub(tmux_has_session?: true)
404
+ project_with_append.stub(last_window_index: 3)
405
+ end
406
+
407
+ it "defaults to the next window index" do
408
+ expect(project_with_append.base_index).to eq 4
409
+ end
410
+ end
371
411
  end
372
412
 
373
413
  describe "#startup_window" do
@@ -410,6 +450,13 @@ describe Tmuxinator::Project do
410
450
  it "gets the window and index for tmux" do
411
451
  expect(project.window(1)).to eq "sample:1"
412
452
  end
453
+
454
+ context "with append set" do
455
+ it "excludes the session name" do
456
+ Tmuxinator::Project.any_instance.stub(tmux_has_session?: true)
457
+ expect(project_with_append.window(1)).to eq ":1"
458
+ end
459
+ end
413
460
  end
414
461
 
415
462
  describe "#name?" do
@@ -576,6 +623,13 @@ describe Tmuxinator::Project do
576
623
  expect(project.tmux_new_session_command).to eq command
577
624
  end
578
625
  end
626
+
627
+ context "with append set" do
628
+ it "returns nothing" do
629
+ Tmuxinator::Project.any_instance.stub(tmux_has_session?: true)
630
+ expect(project_with_append.tmux_new_session_command).to be_nil
631
+ end
632
+ end
579
633
  end
580
634
 
581
635
  describe "tmux_kill_session_command" do
data/spec/spec_helper.rb CHANGED
@@ -1,16 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "coveralls"
4
3
  require "pry"
5
4
  require "simplecov"
6
5
  require "xdg"
7
6
 
8
- formatters = [
9
- SimpleCov::Formatter::HTMLFormatter,
10
- Coveralls::SimpleCov::Formatter
11
- ]
12
- SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new(formatters)
13
7
  SimpleCov.start do
8
+ if ENV["CI"]
9
+ formatter SimpleCov::Formatter::SimpleFormatter
10
+ else
11
+ formatter SimpleCov::Formatter::MultiFormatter.new(
12
+ [
13
+ SimpleCov::Formatter::HTMLFormatter,
14
+ SimpleCov::Formatter::SimpleFormatter,
15
+ ]
16
+ )
17
+ end
18
+
14
19
  add_filter "vendor/cache"
15
20
  end
16
21
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tmuxinator
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.3
4
+ version: 3.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Allen Bargi
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-11-19 00:00:00.000000000 Z
12
+ date: 2025-03-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: erubi
@@ -87,20 +87,6 @@ dependencies:
87
87
  - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: '1.3'
90
- - !ruby/object:Gem::Dependency
91
- name: coveralls
92
- requirement: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: '0.8'
97
- type: :development
98
- prerelease: false
99
- version_requirements: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - "~>"
102
- - !ruby/object:Gem::Version
103
- version: '0.8'
104
90
  - !ruby/object:Gem::Dependency
105
91
  name: factory_bot
106
92
  requirement: !ruby/object:Gem::Requirement
@@ -288,7 +274,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
288
274
  - !ruby/object:Gem::Version
289
275
  version: 1.8.23
290
276
  requirements: []
291
- rubygems_version: 3.5.11
277
+ rubygems_version: 3.5.22
292
278
  signing_key:
293
279
  specification_version: 4
294
280
  summary: Create and manage complex tmux sessions easily.