mk_semi_lattice 0.1.1 → 0.3.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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.DS_Store +0 -0
  3. data/.stack/docs/knowledge_fixer.key +0 -0
  4. data/.stack/docs/mk_semi_lattice_distilled.key +0 -0
  5. data/{.hyper_card → .stack}/history/20251022_0725_add_color_index.md +1 -1
  6. data/.stack/history/add_icon_shape_251208.md +197 -0
  7. data/.stack/history/ignore_opt.md +395 -0
  8. data/.stack/history/ignore_opt_251215.md +417 -0
  9. data/.stack/history/test_viz_options_251216.md +398 -0
  10. data/.stack/history/viz_options_251215.md +412 -0
  11. data/README.org +69 -0
  12. data/app/assets/icons/document.png +0 -0
  13. data/app/assets/icons/folder.png +0 -0
  14. data/app/assets/icons/icon.jpg +0 -0
  15. data/exe/{sl → mk_sl} +0 -2
  16. data/lib/mk_semi_lattice/.semi_lattice/dir_node_edge.yaml +63 -0
  17. data/lib/mk_semi_lattice/.semi_lattice/dir_tree.yaml +10 -0
  18. data/lib/mk_semi_lattice/.semi_lattice/semi_lattice.yaml +99 -0
  19. data/lib/mk_semi_lattice/init_env.rb +121 -0
  20. data/lib/mk_semi_lattice/{mk_node_edge.rb → manage_yaml/mk_node_edge_yaml.rb} +1 -8
  21. data/lib/mk_semi_lattice/manage_yaml/mk_semi_lattice_yaml.rb +188 -0
  22. data/lib/mk_semi_lattice/option_manager.rb +54 -3
  23. data/lib/mk_semi_lattice/ruby2d_action.rb +9 -2
  24. data/lib/mk_semi_lattice/sl_components.rb +364 -0
  25. data/lib/mk_semi_lattice/version.rb +1 -1
  26. data/lib/mk_semi_lattice.rb +81 -9
  27. metadata +48 -25
  28. data/.hyper_card/history/file_path_modifier.md +0 -481
  29. data/README.md +0 -43
  30. data/lib/mk_semi_lattice/config.rb +0 -53
  31. data/lib/mk_semi_lattice/log.rb +0 -26
  32. data/lib/mk_semi_lattice/manage_yaml.rb +0 -89
  33. data/lib/mk_semi_lattice/mk_dir_yaml.rb +0 -40
  34. data/lib/mk_semi_lattice/mk_semi_lattice_graph.rb +0 -254
  35. data/lib/mk_semi_lattice/mk_semi_lattice_viewer.rb +0 -77
  36. /data/{.hyper_card → .stack}/history/20251020_1517_readme_formatted.md +0 -0
  37. /data/{.hyper_card → .stack}/history/20251020_1828_minor_rev_formatted.md +0 -0
  38. /data/{.hyper_card → .stack}/history/20251021_1110_wsl_ubuntu_japanese.md +0 -0
  39. /data/{.hyper_card → .stack}/history/20251021_1142_double_click_action.md +0 -0
  40. /data/{.hyper_card → .stack}/history/20251021_1151_select_semi_data_action.md +0 -0
  41. /data/{.hyper_card → .stack}/history/20251021_2322_add_comment_edges.md +0 -0
  42. /data/{.hyper_card → .stack}/history/classify_251103.md +0 -0
  43. /data/{.hyper_card → .stack}/history/file_path_modifier_251103.md +0 -0
  44. /data/{.hyper_card → .stack}/history/knowledge_fixer.pdf +0 -0
  45. /data/{.hyper_card → .stack}/history/log_with_symbol_251102.md +0 -0
  46. /data/{.hyper_card → .stack}/history/memory_leak_251028.md +0 -0
  47. /data/{.hyper_card → .stack}/history/set_log_conf_251027.md +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fd367913e384f82dbbb7b8db40d35646855a82d5006715a51fc4eaa6601bc0ca
4
- data.tar.gz: fed2c0e74140c8dd15933c13ec8eb4e6466f72ac8f7f5a899c063046e62a6ce8
3
+ metadata.gz: 0d344bc5e5985d443acbd280d0c567b0e01be8635971e5155339d5b3b21e1b76
4
+ data.tar.gz: 3782664243e07f23a4e800505d08daf299963afb0df5923a489602ead09d84ad
5
5
  SHA512:
6
- metadata.gz: b44216e9db854f9a28d5f9b27463f0bfd119aaa0dece1e70cdd4e35c0628ee1c5720d5f780985c35e548c32dd63f71c46af9781e7f35960d3d8ec98b680b6a3f
7
- data.tar.gz: 8984c903dc85dcdf6e32bf80405d0ef6aae28718c8e776e5496554f385604a30d73bacecda8af54b7b0b6eadaaaae9ce6ef48e48844898de1adc7407f54e4bda
6
+ metadata.gz: 9c9d8bd624f964fe520ba5b55dbad67cdac44a0791b1693f6d3d177e5c9555675cc88a853e764cbd99eea209c7c120a0d2b1e420911a128f34c68aa8148d7105
7
+ data.tar.gz: f3990badd3f2fbd9d7a0c1b4a99322c8203a018d9d0e80e30018da3d8736980599a37b9bfca0a77480b71f8a01bde7edbce8097584d5d26a5480295327f02134
data/.DS_Store CHANGED
Binary file
Binary file
@@ -1,4 +1,4 @@
1
- daddygongon: 描かれたnodeにidも表示するoptionとして-i, -indexを追加.
1
+ **daddygongon**: 描かれたnodeにidも表示するoptionとして-i, -indexを追加.
2
2
 
3
3
  GitHub Copilot: ### [mk_semi_lattice.rb](file:///Users/bob/git_hub/mk_semi_lattice/lib/mk_semi_lattice.rb)
4
4
 
@@ -0,0 +1,197 @@
1
+ # head
2
+ date: 2025-12-08
3
+ author: bob
4
+
5
+ ## User
6
+ 重複してますね.refactorしましょう.
7
+
8
+ ## Copilot
9
+ 重複している`@text`生成部分をまとめて、`dir`/それ以外で分岐する部分を簡潔にリファクタリングできます。
10
+ 以下のように書き換えるとスッキリします。
11
+
12
+ ```ruby
13
+ # ...existing code...
14
+ def create_graphics
15
+ return if @created
16
+ font_path = japanese_font
17
+
18
+ # テキスト生成(共通化)
19
+ if font_path && File.exist?(font_path)
20
+ @text = Text.new(label, x: x-28, y: y-10, size: 18, color: 'black', font: font_path, z: 11)
21
+ else
22
+ @text = Text.new(label, x: x-28, y: y-10, size: 18, color: 'black', z: 11)
23
+ end
24
+
25
+ # アイコン生成
26
+ @circle = if @type == 'dir'
27
+ Folder.new(x: x, y: y, color: NODE_COLOR, z: 10)
28
+ else
29
+ Circle.new(x: x, y: y, radius: 30, color: NODE_COLOR, z: 10)
30
+ end
31
+ @created = true
32
+ end
33
+ # ...existing code...
34
+ ```
35
+
36
+ - `@text`の生成を一度だけにまとめました。
37
+ - `@circle`の分岐のみを残しています。
38
+
39
+ このようにすることで、重複がなくなり、保守性も向上します。
40
+
41
+ ## User
42
+ pngファイルを表示するように変更.
43
+
44
+ ## Copilot
45
+ `Folder`クラスでフォルダアイコンを図形からPNG画像表示に変更するには、`Rectangle`の代わりに`Image`を使います。
46
+ 下記のように修正してください。
47
+
48
+ ```ruby
49
+ # ...existing code...
50
+ class Folder
51
+ # フォルダアイコンをRuby2Dの画像で描画するクラス
52
+ attr_accessor :x, :y, :name, :label, :fixed, :linked, :dx, :dy, :type, :file_path
53
+ def initialize(attrs = {})
54
+ @x = attrs[:x]
55
+ @y = attrs[:y]
56
+ @z = attrs[:z]
57
+ @color = attrs[:color]
58
+ @image = Image.new(
59
+ './icons/folder.png', # PNGファイルのパス
60
+ x: @x-28, y: @y-20, width: 56, height: 32, z: @z
61
+ )
62
+ end
63
+
64
+ def color=(c)
65
+ # 画像には直接色をつけられません。必要なら画像を加工してください。
66
+ end
67
+
68
+ def x=(x)
69
+ @image.x = x - 28
70
+ end
71
+
72
+ def y=(y)
73
+ @image.y = y - 20
74
+ end
75
+ end
76
+ # ...existing code...
77
+ ```
78
+
79
+ - `./icons/folder.png` をプロジェクト内に配置してください。
80
+ - `color=` メソッドは画像には使えません(必要なら画像自体を加工してください)。
81
+
82
+ この修正で、フォルダアイコンがPNG画像で表示されるようになります。
83
+
84
+ ## User
85
+ codeが重複しています.親クラスとしてNodeShapeを作り,派生クラスとしてFolder2, Document, Folderを作成してください.
86
+
87
+ ## Copilot
88
+ 以下のように、共通部分を`NodeShape`親クラスにまとめ、`Folder2`, `Document`, `Folder`を継承する形でリファクタリングできます。
89
+
90
+ ```ruby
91
+ # ...existing code...
92
+ class NodeShape
93
+ attr_accessor :x, :y, :name, :label, :fixed, :linked, :dx, :dy, :type, :file_path
94
+
95
+ def initialize(attrs = {})
96
+ @x = attrs[:x]
97
+ @y = attrs[:y]
98
+ @z = attrs[:z]
99
+ @color = attrs[:color]
100
+ @name = attrs[:name]
101
+ @label = attrs[:label]
102
+ @fixed = attrs[:fixed]
103
+ @linked = attrs[:linked]
104
+ @dx = attrs[:dx]
105
+ @dy = attrs[:dy]
106
+ @type = attrs[:type]
107
+ @file_path = attrs[:file_path]
108
+ setup_shape
109
+ end
110
+
111
+ def color=(c)
112
+ # 派生クラスでオーバーライド
113
+ end
114
+
115
+ def x=(x)
116
+ # 派生クラスでオーバーライド
117
+ end
118
+
119
+ def y=(y)
120
+ # 派生クラスでオーバーライド
121
+ end
122
+
123
+ def setup_shape
124
+ # 派生クラスでオーバーライド
125
+ end
126
+ end
127
+
128
+ class Folder2 < NodeShape
129
+ def setup_shape
130
+ @image = Image.new(
131
+ './icons/folder.png',
132
+ x: @x-28, y: @y-20, width: 56, height: 36, z: @z
133
+ )
134
+ end
135
+
136
+ def color=(c)
137
+ # 画像には直接色をつけられません
138
+ end
139
+
140
+ def x=(x)
141
+ @image.x = x - 28
142
+ end
143
+
144
+ def y=(y)
145
+ @image.y = y - 20
146
+ end
147
+ end
148
+
149
+ class Document < NodeShape
150
+ def setup_shape
151
+ @image = Image.new(
152
+ './icons/document.png',
153
+ x: @x-28, y: @y-20, width: 38, height: 56, z: @z
154
+ )
155
+ end
156
+
157
+ def color=(c)
158
+ # 画像には直接色をつけられません
159
+ end
160
+
161
+ def x=(x)
162
+ @image.x = x - 28
163
+ end
164
+
165
+ def y=(y)
166
+ @image.y = y - 20
167
+ end
168
+ end
169
+
170
+ class Folder < NodeShape
171
+ def setup_shape
172
+ @folder1 = Rectangle.new(x: @x-28, y: @y-10, width: 56, height: 32, color: @color, z: @z)
173
+ @folder2 = Rectangle.new(x: @x-28, y: @y-20, width: 26, height: 12, color: @color, z: @z)
174
+ end
175
+
176
+ def color=(c)
177
+ @folder1.color = c
178
+ @folder2.color = c
179
+ end
180
+
181
+ def x=(x)
182
+ @folder1.x = x - 28
183
+ @folder2.x = x - 28
184
+ end
185
+
186
+ def y=(y)
187
+ @folder1.y = y - 10
188
+ @folder2.y = y - 20
189
+ end
190
+ end
191
+ # ...existing code...
192
+ ```
193
+
194
+ - `NodeShape`で共通属性・初期化をまとめ、`setup_shape`を各派生クラスで実装します。
195
+ - `color=`, `x=`, `y=`も必要に応じてオーバーライドします。
196
+
197
+ この構造で重複が大幅に減り、拡張・保守が容易になります。
@@ -0,0 +1,395 @@
1
+ User: optionで-I '_stack_*|*.yaml'としてこれらのdir, file名をIgnoreする@option[:ignore]を設定するように修正.
2
+
3
+ GitHub Copilot: ````ruby
4
+ # ...existing code...
5
+
6
+ opts.on("-I", "--ignore=PATTERN", "Ignore files/dirs matching PATTERN (e.g. '_stack_*|*.yaml')") do |pattern|
7
+ @options[:ignore] = pattern
8
+ end
9
+
10
+ # ...existing code...
11
+ ````
12
+
13
+ この修正により、`-I` または `--ignore=PATTERN` オプションで `@options[:ignore]` にパターンが設定されます。
14
+
15
+ User: @option[:ignore]のpatternが含まれるdir, file名をIgnoreするように修正.
16
+
17
+ GitHub Copilot: ````ruby
18
+ # ...existing code...
19
+ def dir_tree(path, depth)
20
+ return nil if depth < 0
21
+ tree = {}
22
+ entries =
23
+ if @options && (@options[:visibility] == 'all' || @options[:visibility] == 'dir_and_hidden_dir')
24
+ Dir.entries(path) - ['.', '..']
25
+ else
26
+ Dir.children(path)
27
+ end
28
+
29
+ ignore_pattern = @options && @options[:ignore] ? @options[:ignore] : nil
30
+ ignore_regex = ignore_pattern ? Regexp.new(ignore_pattern) : nil
31
+
32
+ entries.each do |entry|
33
+ next if entry.end_with?('~')
34
+ next if ignore_regex && entry.match(ignore_regex)
35
+ full = File.join(path, entry)
36
+ case @options && @options[:visibility]
37
+ when 'dir_only'
38
+ next if entry.start_with?('.') # 隠しディレクトリ除外
39
+ next unless File.directory?(full)
40
+ when 'dir_and_hidden_dir'
41
+ next unless File.directory?(full) # 隠しも含めてディレクトリのみ
42
+ when 'all'
43
+ # すべて含める(除外なし)
44
+ when 'yaml_exclude'
45
+ next if File.extname(entry) == '.yaml'
46
+ else # 'normal'
47
+ next if entry.start_with?('.')
48
+ next if File.file?(full) && File.extname(entry) == '.yaml' && entry != 'semi_lattice.yaml'
49
+ end
50
+ if File.symlink?(full)
51
+ target = File.readlink(full)
52
+ tree[entry] = "-> #{target}"
53
+ elsif File.directory?(full)
54
+ subtree = dir_tree(full, depth - 1)
55
+ if subtree
56
+ tree["#{entry}/"] = subtree
57
+ else
58
+ tree["#{entry}/"] = nil
59
+ end
60
+ else
61
+ tree[entry] = nil unless @options && (@options[:visibility] == 'dir_only' || @options[:visibility] == 'dir_and_hidden_dir')
62
+ end
63
+ end
64
+ tree
65
+ end
66
+ # ...existing code...
67
+ ````
68
+
69
+ この修正で、`@options[:ignore]` のパターンにマッチするファイル・ディレクトリ名を無視します。パターンは正規表現として扱われます。
70
+
71
+ User: treeの-I optionと同様に,mk_sl -I '_stack_*|*.yaml'de
72
+
73
+ GitHub Copilot: `-I '_stack_*|*.yaml'` のようなパターンで、`tree` コマンドの `-I` オプションと同様に「ワイルドカード(*)」や「|」区切りの複数パターン」をサポートするには、globパターンを正規表現に変換する必要があります。
74
+ 以下のように修正してください。
75
+
76
+ ````ruby
77
+ # ...existing code...
78
+ def dir_tree(path, depth)
79
+ return nil if depth < 0
80
+ tree = {}
81
+ entries =
82
+ if @options && (@options[:visibility] == 'all' || @options[:visibility] == 'dir_and_hidden_dir')
83
+ Dir.entries(path) - ['.', '..']
84
+ else
85
+ Dir.children(path)
86
+ end
87
+
88
+ # tree -I のようなワイルドカード・複数パターン対応
89
+ ignore_pattern = @options && @options[:ignore] ? @options[:ignore] : nil
90
+ ignore_regex = nil
91
+ if ignore_pattern
92
+ # '_stack_*|*.yaml' → /(?:\A_stack_.*\z|\A.*\.yaml\z)/
93
+ regex_str = ignore_pattern.split('|').map do |pat|
94
+ pat = pat.strip
95
+ pat = Regexp.escape(pat).gsub('\*', '.*').gsub('\?', '.')
96
+ "\\A#{pat}\\z"
97
+ end.join('|')
98
+ ignore_regex = Regexp.new("(?:#{regex_str})")
99
+ end
100
+
101
+ entries.each do |entry|
102
+ next if entry.end_with?('~')
103
+ next if ignore_regex && entry.match(ignore_regex)
104
+ full = File.join(path, entry)
105
+ case @options && @options[:visibility]
106
+ when 'dir_only'
107
+ next if entry.start_with?('.') # 隠しディレクトリ除外
108
+ next unless File.directory?(full)
109
+ when 'dir_and_hidden_dir'
110
+ next unless File.directory?(full) # 隠しも含めてディレクトリのみ
111
+ when 'all'
112
+ # すべて含める(除外なし)
113
+ when 'yaml_exclude'
114
+ next if File.extname(entry) == '.yaml'
115
+ else # 'normal'
116
+ next if entry.start_with?('.')
117
+ next if File.file?(full) && File.extname(entry) == '.yaml' && entry != 'semi_lattice.yaml'
118
+ end
119
+ if File.symlink?(full)
120
+ target = File.readlink(full)
121
+ tree[entry] = "-> #{target}"
122
+ elsif File.directory?(full)
123
+ subtree = dir_tree(full, depth - 1)
124
+ if subtree
125
+ tree["#{entry}/"] = subtree
126
+ else
127
+ tree["#{entry}/"] = nil
128
+ end
129
+ else
130
+ tree[entry] = nil unless @options && (@options[:visibility] == 'dir_only' || @options[:visibility] == 'dir_and_hidden_dir')
131
+ end
132
+ end
133
+ tree
134
+ end
135
+ # ...existing code...
136
+ ````
137
+
138
+ この修正で、`-I '_stack_*|*.yaml'` のような複数・ワイルドカードパターンが `tree` コマンド同様に動作します。
139
+
140
+ User: #file:mk_semi_lattice_yaml.rb:117-175 がだいぶ長い関数になっています.まずは,l127-138を別関数に切り出しましょう.
141
+
142
+ GitHub Copilot: ````ruby
143
+ # ...existing code...
144
+ def build_ignore_regex(ignore_pattern)
145
+ return nil unless ignore_pattern
146
+ # '_stack_*|*.yaml' → /(?:\A_stack_.*\z|\A.*\.yaml\z)/
147
+ regex_str = ignore_pattern.split('|').map do |pat|
148
+ pat = pat.strip
149
+ pat = Regexp.escape(pat).gsub('\*', '.*').gsub('\?', '.')
150
+ "\\A#{pat}\\z"
151
+ end.join('|')
152
+ Regexp.new("(?:#{regex_str})")
153
+ end
154
+
155
+ def dir_tree(path, depth)
156
+ return nil if depth < 0
157
+ tree = {}
158
+ entries =
159
+ if @options && (@options[:visibility] == 'all' || @options[:visibility] == 'dir_and_hidden_dir')
160
+ Dir.entries(path) - ['.', '..']
161
+ else
162
+ Dir.children(path)
163
+ end
164
+
165
+ ignore_pattern = @options && @options[:ignore] ? @options[:ignore] : nil
166
+ ignore_regex = build_ignore_regex(ignore_pattern)
167
+
168
+ entries.each do |entry|
169
+ next if entry.end_with?('~')
170
+ next if ignore_regex && entry.match(ignore_regex)
171
+ full = File.join(path, entry)
172
+ case @options && @options[:visibility]
173
+ when 'dir_only'
174
+ next if entry.start_with?('.') # 隠しディレクトリ除外
175
+ next unless File.directory?(full)
176
+ when 'dir_and_hidden_dir'
177
+ next unless File.directory?(full) # 隠しも含めてディレクトリのみ
178
+ when 'all'
179
+ # すべて含める(除外なし)
180
+ when 'yaml_exclude'
181
+ next if File.extname(entry) == '.yaml'
182
+ else # 'normal'
183
+ next if entry.start_with?('.')
184
+ next if File.file?(full) && File.extname(entry) == '.yaml' && entry != 'semi_lattice.yaml'
185
+ end
186
+ if File.symlink?(full)
187
+ target = File.readlink(full)
188
+ tree[entry] = "-> #{target}"
189
+ elsif File.directory?(full)
190
+ subtree = dir_tree(full, depth - 1)
191
+ if subtree
192
+ tree["#{entry}/"] = subtree
193
+ else
194
+ tree["#{entry}/"] = nil
195
+ end
196
+ else
197
+ tree[entry] = nil unless @options && (@options[:visibility] == 'dir_only' || @options[:visibility] == 'dir_and_hidden_dir')
198
+ end
199
+ end
200
+ tree
201
+ end
202
+ # ...existing code...
203
+ ````
204
+
205
+ `l127-138` の ignore パターン処理を `build_ignore_regex` メソッドとして切り出しました。
206
+
207
+ User: このあたりをskip_nameとして切り出しましょう.
208
+
209
+ GitHub Copilot: ````ruby
210
+ # ...existing code...
211
+ def skip_name?(entry, full, ignore_regex)
212
+ return true if entry.end_with?('~')
213
+ return true if ignore_regex && entry.match(ignore_regex)
214
+ case @options && @options[:visibility]
215
+ when 'dir_only'
216
+ return true if entry.start_with?('.') # 隠しディレクトリ除外
217
+ return true unless File.directory?(full)
218
+ when 'dir_and_hidden_dir'
219
+ return true unless File.directory?(full) # 隠しも含めてディレクトリのみ
220
+ when 'all'
221
+ # すべて含める(除外なし)
222
+ when 'yaml_exclude'
223
+ return true if File.extname(entry) == '.yaml'
224
+ else # 'normal'
225
+ return true if entry.start_with?('.')
226
+ return true if File.file?(full) && File.extname(entry) == '.yaml' && entry != 'semi_lattice.yaml'
227
+ end
228
+ false
229
+ end
230
+
231
+ def dir_tree(path, depth)
232
+ return nil if depth < 0
233
+ tree = {}
234
+ entries =
235
+ if @options && (@options[:visibility] == 'all' || @options[:visibility] == 'dir_and_hidden_dir')
236
+ Dir.entries(path) - ['.', '..']
237
+ else
238
+ Dir.children(path)
239
+ end
240
+
241
+ ignore_pattern = @options && @options[:ignore] ? @options[:ignore] : nil
242
+ ignore_regex = build_ignore_regex(ignore_pattern)
243
+
244
+ entries.each do |entry|
245
+ full = File.join(path, entry)
246
+ next if skip_name?(entry, full, ignore_regex)
247
+ if File.symlink?(full)
248
+ target = File.readlink(full)
249
+ tree[entry] = "-> #{target}"
250
+ elsif File.directory?(full)
251
+ subtree = dir_tree(full, depth - 1)
252
+ if subtree
253
+ tree["#{entry}/"] = subtree
254
+ else
255
+ tree["#{entry}/"] = nil
256
+ end
257
+ else
258
+ tree[entry] = nil unless @options && (@options[:visibility] == 'dir_only' || @options[:visibility] == 'dir_and_hidden_dir')
259
+ end
260
+ end
261
+ tree
262
+ end
263
+ # ...existing code...
264
+ ````
265
+
266
+ `skip_name?` メソッドとして切り出しました。
267
+
268
+ User: mk_sl -I '_stack_*|*.yaml' -a
269
+ mk_semi_lattice is running...
270
+ /Users/bob/.rbenv/gems/3.4.0/gems/mk_semi_lattice-0.3.1/lib/mk_semi_lattice/option_manager.rb:84:in 'OptionManager#parse!': missing argument: -a (OptionParser::MissingArgument)
271
+ とのエラーが出ます.
272
+
273
+ GitHub Copilot: このエラーは、`OptionParser` で `-a` や `-d` などの短いフラグ(引数なし)と、`-I` のような引数付きオプションを同時に使った場合、`-I` の値が `'a'` などの次のフラグとして誤認識されるために発生します。
274
+
275
+ **原因**
276
+ `OptionParser` は `-I` のような引数付きオプションの直後にスペースを空けて値を渡す場合、次の `-a` も値として解釈しようとします。
277
+ 例:
278
+ `mk_sl -I _stack_*|*.yaml -a`
279
+ → `-I` の値が `_stack_*|*.yaml` ではなく `_stack_*|*.yaml -a` になり、`-a` が値として消費されてしまう。
280
+
281
+ **解決策**
282
+ - `-I` の値は必ず`=`で渡す(`-I='_stack_*|*.yaml'` または `--ignore='_stack_*|*.yaml'` のようにする)
283
+ - もしくは、`-I '_stack_*|*.yaml'` のようにクォートで囲む(シェルによっては必要)
284
+
285
+ **例:**
286
+ ```
287
+ mk_sl -I='_stack_*|*.yaml' -a
288
+ mk_sl --ignore='_stack_*|*.yaml' -a
289
+ ```
290
+ または
291
+ ```
292
+ mk_sl -a -I '_stack_*|*.yaml'
293
+ ```
294
+
295
+ **補足**
296
+ この挙動は `OptionParser` の仕様であり、コード側での修正は不要です。
297
+ READMEやヘルプに「`-I` の値は `=` で渡すか、クォートで囲むこと」と明記すると親切です。
298
+
299
+ ---
300
+
301
+ **まとめ:**
302
+ `-I` の値は `=` で渡すか、クォートで囲んでください。
303
+ 例:
304
+ `mk_sl -I='_stack_*|*.yaml' -a`
305
+
306
+ User: mk_sl -I='_stack_*|*.yaml' -a
307
+ mk_semi_lattice is running...
308
+ /Users/bob/.rbenv/gems/3.4.0/gems/mk_semi_lattice-0.3.1/lib/mk_semi_lattice/option_manager.rb:84:in 'OptionManager#parse!': missing argument: -a (OptionParser::MissingArgument)
309
+ とのエラーがまだ出ています.
310
+
311
+ GitHub Copilot: この問題は、`OptionParser` の `-ad` オプションが `"Show all directories including hidden ones"` という説明で定義されていますが、`-a` と `-d` の組み合わせ(`-a -d`や`-ad`)を正しく処理できていないことが原因です。
312
+
313
+ **主な原因:**
314
+ - `-ad` のような複数フラグを1つにまとめた短縮形(POSIXスタイル)を `OptionParser` で使う場合、`-a -d` ではなく `-ad` と書く必要があります。
315
+ - しかし、`-ad` を `opts.on("-ad", ...)` で定義しているため、`-a -d` のように個別に指定した場合は `-a` だけが認識され、`-d` は未定義のフラグとして扱われてしまいます。
316
+
317
+ **解決策:**
318
+ 1. `-ad` の定義を削除し、`-a` と `-d` のみを定義する。
319
+ 2. `-a` と `-d` の両方が指定された場合の処理は、既存の
320
+ ```ruby
321
+ if a_flag && d_flag
322
+ @options[:visibility] = 'dir_and_hidden_dir'
323
+ ```
324
+ で十分です。
325
+
326
+ **修正例:**
327
+
328
+ ````ruby
329
+ # ...existing code...
330
+ # opts.on("-ad", "Show all directories including hidden ones") do
331
+ # a_flag = true
332
+ # d_flag = true
333
+ # end
334
+ # ...existing code...
335
+ ````
336
+
337
+ **READMEやUsage例にも「-a -d のように個別に指定してください」と記載すると親切です。**
338
+
339
+ ---
340
+
341
+ ### まとめ
342
+
343
+ - `-ad` の定義を削除し、`-a -d` のように個別指定で使ってください。
344
+ - これで `-I='_stack_*|*.yaml' -a` も正しく動作します。
345
+
346
+ もし `-ad` の短縮形もサポートしたい場合は、`OptionParser` ではなく手動でフラグをパースする必要がありますが、一般的には `-a -d` で十分です。
347
+
348
+ User: 上記の仕様を英語のhelpにして出力するように修正.
349
+
350
+ GitHub Copilot: ````ruby
351
+ # ...existing code...
352
+ OptionParser.new do |opts|
353
+ opts.banner = <<~BANNER
354
+ Usage: mk_semi_lattice PATH [options]
355
+ Default PATH = '.'
356
+
357
+ Options:
358
+ -L N Layer depth (default: 2)
359
+ -t, --tree=FILE Use FILE from tree
360
+ -n, --node=FILE Use FILE from node-edge
361
+ -i, --index Display node ids
362
+ -l, --log [BOOL] Enable/disable logging (true/false), and save to config
363
+ -v, --version Show version
364
+ -d Show directories only
365
+ -a Show all (files and directories)
366
+ -Y YAML exclude mode
367
+ -I, --ignore=PATTERN Ignore files/dirs matching PATTERN (e.g. '_stack_*|*.yaml')
368
+ Multiple patterns can be separated by '|'.
369
+ Wildcards '*' and '?' are supported (like the 'tree' command).
370
+ When using -I, always use '=' or quote the pattern, e.g.:
371
+ -I='_stack_*|*.yaml' -a
372
+ --ignore='_stack_*|*.yaml' -a
373
+ Do not use -ad; use -a -d for combined flags.
374
+ BANNER
375
+ # ...existing code...
376
+ ````
377
+
378
+ この修正で、helpメッセージに英語で仕様が明記されます。
379
+
380
+ User: mk_sl -I='_stack_*|*.yaml'
381
+ mk_semi_lattice is running...
382
+ {layer: 2, init_step: :from_semi_lattice, show_index: false, merge: false, visibility: "normal", ignore: "=_stack_*|*.yaml"となっています.
383
+ これを修正
384
+
385
+ GitHub Copilot: ````ruby
386
+ # ...existing code...
387
+ opts.on("-I PATTERN", "--ignore=PATTERN", "Ignore files/dirs matching PATTERN (e.g. '_stack_*|*.yaml')") do |pattern|
388
+ # Remove leading '=' if present (e.g. when user writes -I='_stack_*|*.yaml')
389
+ pattern = pattern.sub(/\A=/, '') if pattern
390
+ @options[:ignore] = pattern
391
+ end
392
+ # ...existing code...
393
+ ````
394
+
395
+ この修正で、`-I='_stack_*|*.yaml'` のような場合に `ignore: "_stack_*|*.yaml"` となり、先頭の `=` が格納されなくなります。