chocomint 1.0.1 → 1.0.2
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/lib/chocomint/edit_handlers.rb +47 -47
- data/lib/chocomint.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c1e486a61190ec1d3548de09e65d74ea64d42a664c3d536c0e8013f61e6e2c1c
|
|
4
|
+
data.tar.gz: b7e23eedd909b6d2dffaeaa341721e7ccbd3bc91a2556a87d2654991c9475443
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5234597d4d58068f04609037aaf53d058b48a0ddfea9a12240cc64c84ace0371b5277aee1442dcea8e1b8239449a7da0e32f976aca1672f4da3b5dfa90ee6645
|
|
7
|
+
data.tar.gz: e42a3f878d613ce09722db0929d745d3aaf3fdda93698eeb691203834063a9bf3090d10bf5aca20f7797391b76305885fcf89c63e6c03c67ae58580520a46704
|
|
@@ -28,8 +28,8 @@ module Chocomint
|
|
|
28
28
|
def handle_edit_files(req, res)
|
|
29
29
|
return edit_method_guard(res) unless req.request_method == "GET"
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
edit_json(res, 200, "files" =>
|
|
31
|
+
files, empty_dirs = walk_workspace_tree
|
|
32
|
+
edit_json(res, 200, "files" => files, "dirs" => empty_dirs,
|
|
33
33
|
"root" => relative_root, "abs_root" => edit_root.tr("\\", "/"))
|
|
34
34
|
rescue Chocomint::Error => e
|
|
35
35
|
edit_json(res, 500, "error" => e.message)
|
|
@@ -39,60 +39,60 @@ module Chocomint
|
|
|
39
39
|
MAX_LISTED_FILES = 2000
|
|
40
40
|
|
|
41
41
|
# 中身を展開しない VCS メタデータ・依存パッケージ等 (数千件で一覧を埋め尽くすため除外する)。
|
|
42
|
-
|
|
42
|
+
# ディレクトリ名 (basename) で判定するため、"vendor/bundle" のようなパス階層は含めない。
|
|
43
|
+
EXCLUDED_TREE_DIRS = %w[.git .hg .svn .venv venv node_modules .bundle].freeze
|
|
43
44
|
|
|
44
|
-
|
|
45
|
+
# workspace ツリーを1度だけ手動再帰し、[ファイル相対パス, 空ディレクトリ相対パス] を返す。
|
|
46
|
+
#
|
|
47
|
+
# Dir.glob("**/*") はツリー全体を舐めてから除外判定するため、node_modules を大量に
|
|
48
|
+
# 含むホームディレクトリ (例: C:\Users\<name>) を起点にすると応答が返らず WORKING
|
|
49
|
+
# DIRECTORY が空のままになる。除外ディレクトリはその配下へ降りる前に枝刈りし、
|
|
50
|
+
# MAX_LISTED_FILES 到達で打ち切ることで巨大ツリーでも実用的な時間で応答する。
|
|
51
|
+
def walk_workspace_tree
|
|
45
52
|
root = edit_root
|
|
46
|
-
return [] unless File.directory?(root)
|
|
53
|
+
return [[], []] unless File.directory?(root)
|
|
47
54
|
|
|
48
55
|
files = []
|
|
49
|
-
#
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
# "." / ".." など自己・親参照は除外する (FNM_DOTMATCH で拾われるため)。
|
|
53
|
-
next if [".", ".."].include?(File.basename(rel))
|
|
54
|
-
# .git などの配下は展開しない (メタデータで一覧が埋まるのを防ぐ)。
|
|
55
|
-
next if EXCLUDED_TREE_DIRS.any? { |d| rel == d || rel.start_with?("#{d}/") }
|
|
56
|
-
|
|
57
|
-
abs = File.join(root, rel)
|
|
58
|
-
next unless File.file?(abs)
|
|
59
|
-
|
|
60
|
-
files << rel
|
|
61
|
-
break if files.size >= MAX_LISTED_FILES
|
|
62
|
-
end
|
|
63
|
-
files.sort
|
|
64
|
-
end
|
|
56
|
+
# 中身を1件も持たないディレクトリ (files からツリー復元できない) を別途フロントに伝える。
|
|
57
|
+
empty_dirs = []
|
|
58
|
+
stack = [""] # root からの相対ディレクトリ (root 自身は "")
|
|
65
59
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
def list_workspace_empty_dirs(files)
|
|
69
|
-
root = edit_root
|
|
70
|
-
return [] unless File.directory?(root)
|
|
71
|
-
|
|
72
|
-
covered = files.each_with_object(Set.new) do |rel, set|
|
|
73
|
-
parts = rel.split("/")
|
|
74
|
-
parts.pop
|
|
75
|
-
prefix = +""
|
|
76
|
-
parts.each do |part|
|
|
77
|
-
prefix = prefix.empty? ? part : "#{prefix}/#{part}"
|
|
78
|
-
set << prefix
|
|
79
|
-
end
|
|
80
|
-
end
|
|
60
|
+
until stack.empty?
|
|
61
|
+
break if files.size >= MAX_LISTED_FILES
|
|
81
62
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
rel = rel.tr("\\", "/")
|
|
85
|
-
next if [".", ".."].include?(File.basename(rel))
|
|
86
|
-
next if EXCLUDED_TREE_DIRS.any? { |d| rel == d || rel.start_with?("#{d}/") }
|
|
87
|
-
next if covered.include?(rel)
|
|
63
|
+
rel_dir = stack.pop
|
|
64
|
+
abs_dir = rel_dir.empty? ? root : File.join(root, rel_dir)
|
|
88
65
|
|
|
89
|
-
|
|
90
|
-
|
|
66
|
+
child_count = 0
|
|
67
|
+
begin
|
|
68
|
+
Dir.each_child(abs_dir) do |name|
|
|
69
|
+
next if name == "." || name == ".."
|
|
70
|
+
|
|
71
|
+
rel = rel_dir.empty? ? name : "#{rel_dir}/#{name}"
|
|
72
|
+
abs = File.join(abs_dir, name)
|
|
73
|
+
|
|
74
|
+
if File.directory?(abs)
|
|
75
|
+
child_count += 1
|
|
76
|
+
# 除外ディレクトリは配下へ降りない (中身も一覧に出さない)。
|
|
77
|
+
next if EXCLUDED_TREE_DIRS.include?(name)
|
|
78
|
+
|
|
79
|
+
stack.push(rel)
|
|
80
|
+
elsif File.file?(abs)
|
|
81
|
+
child_count += 1
|
|
82
|
+
files << rel
|
|
83
|
+
break if files.size >= MAX_LISTED_FILES
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
rescue SystemCallError
|
|
87
|
+
# 権限不足などで開けないディレクトリはスキップする (ホーム配下で発生しうる)。
|
|
88
|
+
next
|
|
89
|
+
end
|
|
91
90
|
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
# 子を1件も持たないディレクトリはツリーに現れないため、明示的に伝える (root は除く)。
|
|
92
|
+
empty_dirs << rel_dir if child_count.zero? && !rel_dir.empty?
|
|
94
93
|
end
|
|
95
|
-
|
|
94
|
+
|
|
95
|
+
[files.sort, empty_dirs.sort]
|
|
96
96
|
end
|
|
97
97
|
|
|
98
98
|
# ---- ファイル取得 -------------------------------------------------------
|
data/lib/chocomint.rb
CHANGED