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.
- checksums.yaml +4 -4
- data/.DS_Store +0 -0
- data/.stack/docs/knowledge_fixer.key +0 -0
- data/.stack/docs/mk_semi_lattice_distilled.key +0 -0
- data/{.hyper_card → .stack}/history/20251022_0725_add_color_index.md +1 -1
- data/.stack/history/add_icon_shape_251208.md +197 -0
- data/.stack/history/ignore_opt.md +395 -0
- data/.stack/history/ignore_opt_251215.md +417 -0
- data/.stack/history/test_viz_options_251216.md +398 -0
- data/.stack/history/viz_options_251215.md +412 -0
- data/README.org +69 -0
- data/app/assets/icons/document.png +0 -0
- data/app/assets/icons/folder.png +0 -0
- data/app/assets/icons/icon.jpg +0 -0
- data/exe/{sl → mk_sl} +0 -2
- data/lib/mk_semi_lattice/.semi_lattice/dir_node_edge.yaml +63 -0
- data/lib/mk_semi_lattice/.semi_lattice/dir_tree.yaml +10 -0
- data/lib/mk_semi_lattice/.semi_lattice/semi_lattice.yaml +99 -0
- data/lib/mk_semi_lattice/init_env.rb +121 -0
- data/lib/mk_semi_lattice/{mk_node_edge.rb → manage_yaml/mk_node_edge_yaml.rb} +1 -8
- data/lib/mk_semi_lattice/manage_yaml/mk_semi_lattice_yaml.rb +188 -0
- data/lib/mk_semi_lattice/option_manager.rb +54 -3
- data/lib/mk_semi_lattice/ruby2d_action.rb +9 -2
- data/lib/mk_semi_lattice/sl_components.rb +364 -0
- data/lib/mk_semi_lattice/version.rb +1 -1
- data/lib/mk_semi_lattice.rb +81 -9
- metadata +48 -25
- data/.hyper_card/history/file_path_modifier.md +0 -481
- data/README.md +0 -43
- data/lib/mk_semi_lattice/config.rb +0 -53
- data/lib/mk_semi_lattice/log.rb +0 -26
- data/lib/mk_semi_lattice/manage_yaml.rb +0 -89
- data/lib/mk_semi_lattice/mk_dir_yaml.rb +0 -40
- data/lib/mk_semi_lattice/mk_semi_lattice_graph.rb +0 -254
- data/lib/mk_semi_lattice/mk_semi_lattice_viewer.rb +0 -77
- /data/{.hyper_card → .stack}/history/20251020_1517_readme_formatted.md +0 -0
- /data/{.hyper_card → .stack}/history/20251020_1828_minor_rev_formatted.md +0 -0
- /data/{.hyper_card → .stack}/history/20251021_1110_wsl_ubuntu_japanese.md +0 -0
- /data/{.hyper_card → .stack}/history/20251021_1142_double_click_action.md +0 -0
- /data/{.hyper_card → .stack}/history/20251021_1151_select_semi_data_action.md +0 -0
- /data/{.hyper_card → .stack}/history/20251021_2322_add_comment_edges.md +0 -0
- /data/{.hyper_card → .stack}/history/classify_251103.md +0 -0
- /data/{.hyper_card → .stack}/history/file_path_modifier_251103.md +0 -0
- /data/{.hyper_card → .stack}/history/knowledge_fixer.pdf +0 -0
- /data/{.hyper_card → .stack}/history/log_with_symbol_251102.md +0 -0
- /data/{.hyper_card → .stack}/history/memory_leak_251028.md +0 -0
- /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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0d344bc5e5985d443acbd280d0c567b0e01be8635971e5155339d5b3b21e1b76
|
|
4
|
+
data.tar.gz: 3782664243e07f23a4e800505d08daf299963afb0df5923a489602ead09d84ad
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9c9d8bd624f964fe520ba5b55dbad67cdac44a0791b1693f6d3d177e5c9555675cc88a853e764cbd99eea209c7c120a0d2b1e420911a128f34c68aa8148d7105
|
|
7
|
+
data.tar.gz: f3990badd3f2fbd9d7a0c1b4a99322c8203a018d9d0e80e30018da3d8736980599a37b9bfca0a77480b71f8a01bde7edbce8097584d5d26a5480295327f02134
|
data/.DS_Store
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -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"` となり、先頭の `=` が格納されなくなります。
|