worktree_manager 0.2.1
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 +7 -0
- data/.github/workflows/test.yml +52 -0
- data/.gitignore +37 -0
- data/.mise.toml +9 -0
- data/.rspec +3 -0
- data/.version +1 -0
- data/.worktree.yml.example +45 -0
- data/CHANGELOG.md +50 -0
- data/CLAUDE.md +17 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +53 -0
- data/LICENSE +9 -0
- data/README.md +391 -0
- data/Rakefile +6 -0
- data/bin/wm +6 -0
- data/bin/worktree_manager +6 -0
- data/lib/worktree_manager/cli.rb +794 -0
- data/lib/worktree_manager/config_manager.rb +64 -0
- data/lib/worktree_manager/hook_manager.rb +269 -0
- data/lib/worktree_manager/manager.rb +126 -0
- data/lib/worktree_manager/version.rb +3 -0
- data/lib/worktree_manager/worktree.rb +56 -0
- data/lib/worktree_manager.rb +11 -0
- data/mise/release.sh +120 -0
- data/pkg/worktree_manager-0.1.0.gem +0 -0
- data/spec/integration/worktree_integration_spec.rb +288 -0
- data/spec/spec_helper.rb +34 -0
- data/spec/worktree_manager/cli_help_spec.rb +154 -0
- data/spec/worktree_manager/cli_spec.rb +976 -0
- data/spec/worktree_manager/config_manager_spec.rb +172 -0
- data/spec/worktree_manager/hook_manager_spec.rb +581 -0
- data/spec/worktree_manager/manager_spec.rb +95 -0
- data/spec/worktree_manager/worktree_spec.rb +83 -0
- data/spec/worktree_manager_spec.rb +14 -0
- data/worktree_manager.gemspec +33 -0
- metadata +136 -0
@@ -0,0 +1,172 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'worktree_manager/config_manager'
|
3
|
+
require 'tmpdir'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
RSpec.describe WorktreeManager::ConfigManager do
|
7
|
+
let(:test_dir) { Dir.mktmpdir }
|
8
|
+
let(:config_manager) { described_class.new(test_dir) }
|
9
|
+
|
10
|
+
after do
|
11
|
+
FileUtils.rm_rf(test_dir)
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#worktrees_dir' do
|
15
|
+
context 'when no config file exists' do
|
16
|
+
it 'returns the default value' do
|
17
|
+
expect(config_manager.worktrees_dir).to eq('../')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'when config file exists with worktrees_dir' do
|
22
|
+
before do
|
23
|
+
config_content = { 'worktrees_dir' => '../../custom-worktrees' }
|
24
|
+
File.write(File.join(test_dir, '.worktree.yml'), config_content.to_yaml)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'returns the configured value' do
|
28
|
+
expect(config_manager.worktrees_dir).to eq('../../custom-worktrees')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'when config file exists in .git directory' do
|
33
|
+
before do
|
34
|
+
FileUtils.mkdir_p(File.join(test_dir, '.git'))
|
35
|
+
config_content = { 'worktrees_dir' => '../worktrees' }
|
36
|
+
File.write(File.join(test_dir, '.git/.worktree.yml'), config_content.to_yaml)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'returns the configured value' do
|
40
|
+
expect(config_manager.worktrees_dir).to eq('../worktrees')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'when both config files exist' do
|
45
|
+
before do
|
46
|
+
FileUtils.mkdir_p(File.join(test_dir, '.git'))
|
47
|
+
config_content1 = { 'worktrees_dir' => '../priority' }
|
48
|
+
config_content2 = { 'worktrees_dir' => '../secondary' }
|
49
|
+
File.write(File.join(test_dir, '.worktree.yml'), config_content1.to_yaml)
|
50
|
+
File.write(File.join(test_dir, '.git/.worktree.yml'), config_content2.to_yaml)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'prioritizes .worktree.yml over .git/.worktree.yml' do
|
54
|
+
expect(config_manager.worktrees_dir).to eq('../priority')
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '#hooks' do
|
60
|
+
context 'when config file has hooks' do
|
61
|
+
before do
|
62
|
+
config_content = {
|
63
|
+
'worktrees_dir' => '../',
|
64
|
+
'hooks' => {
|
65
|
+
'pre_add' => "echo 'pre add hook'",
|
66
|
+
'post_add' => "echo 'post add hook'"
|
67
|
+
}
|
68
|
+
}
|
69
|
+
File.write(File.join(test_dir, '.worktree.yml'), config_content.to_yaml)
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'returns the hooks configuration' do
|
73
|
+
hooks = config_manager.hooks
|
74
|
+
expect(hooks).to be_a(Hash)
|
75
|
+
expect(hooks['pre_add']).to eq("echo 'pre add hook'")
|
76
|
+
expect(hooks['post_add']).to eq("echo 'post add hook'")
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'when no hooks are configured' do
|
81
|
+
it 'returns an empty hash' do
|
82
|
+
expect(config_manager.hooks).to eq({})
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe '#main_branch_name' do
|
88
|
+
context 'when no config file exists' do
|
89
|
+
it 'returns the default value' do
|
90
|
+
expect(config_manager.main_branch_name).to eq('main')
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'when config file exists with main_branch_name' do
|
95
|
+
before do
|
96
|
+
config_content = { 'main_branch_name' => 'master' }
|
97
|
+
File.write(File.join(test_dir, '.worktree.yml'), config_content.to_yaml)
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'returns the configured value' do
|
101
|
+
expect(config_manager.main_branch_name).to eq('master')
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context 'when config file exists with custom main_branch_name' do
|
106
|
+
before do
|
107
|
+
config_content = { 'main_branch_name' => 'development' }
|
108
|
+
File.write(File.join(test_dir, '.worktree.yml'), config_content.to_yaml)
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'returns the configured custom value' do
|
112
|
+
expect(config_manager.main_branch_name).to eq('development')
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe '#resolve_worktree_path' do
|
118
|
+
before do
|
119
|
+
config_content = { 'worktrees_dir' => '../worktrees' }
|
120
|
+
File.write(File.join(test_dir, '.worktree.yml'), config_content.to_yaml)
|
121
|
+
end
|
122
|
+
|
123
|
+
context 'with an absolute path' do
|
124
|
+
it 'returns the path as is' do
|
125
|
+
absolute_path = '/absolute/path/to/worktree'
|
126
|
+
expect(config_manager.resolve_worktree_path(absolute_path)).to eq(absolute_path)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context 'with a relative path containing /' do
|
131
|
+
it 'resolves relative to repository path' do
|
132
|
+
relative_path = '../custom/worktree'
|
133
|
+
expected = File.expand_path(relative_path, test_dir)
|
134
|
+
expect(config_manager.resolve_worktree_path(relative_path)).to eq(expected)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context 'with a simple name' do
|
139
|
+
it 'resolves relative to worktrees_dir' do
|
140
|
+
name = 'feature-branch'
|
141
|
+
expected = File.expand_path('../worktrees/feature-branch', test_dir)
|
142
|
+
expect(config_manager.resolve_worktree_path(name)).to eq(expected)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
context 'when worktrees_dir is not configured' do
|
147
|
+
before do
|
148
|
+
FileUtils.rm(File.join(test_dir, '.worktree.yml'))
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'uses default worktrees_dir' do
|
152
|
+
name = 'my-worktree'
|
153
|
+
expected = File.expand_path('../my-worktree', test_dir)
|
154
|
+
expect(config_manager.resolve_worktree_path(name)).to eq(expected)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
describe 'error handling' do
|
160
|
+
context 'when config file has invalid YAML' do
|
161
|
+
before do
|
162
|
+
File.write(File.join(test_dir, '.worktree.yml'), 'invalid: yaml: content:')
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'returns default values and prints warning' do
|
166
|
+
expect { config_manager }.to output(/Warning: Failed to load config file/).to_stdout
|
167
|
+
expect(config_manager.worktrees_dir).to eq('../')
|
168
|
+
expect(config_manager.hooks).to eq({})
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|