lhj-tools 0.1.3 → 0.1.7

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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/lib/lhj/action/sh_helper.rb +138 -0
  3. data/lib/lhj/command/config/info.rb +47 -0
  4. data/lib/lhj/command/config.rb +11 -0
  5. data/lib/lhj/command/file_path.rb +20 -0
  6. data/lib/lhj/command/head_import.rb +19 -3
  7. data/lib/lhj/command/http.rb +14 -0
  8. data/lib/lhj/command/init.rb +2 -2
  9. data/lib/lhj/command/local/fetch.rb +1 -1
  10. data/lib/lhj/command/local/filter.rb +1 -1
  11. data/lib/lhj/command/local/local.rb +1 -1
  12. data/lib/lhj/command/local/local_upload.rb +1 -1
  13. data/lib/lhj/command/local/micro_service.rb +1 -1
  14. data/lib/lhj/command/oss/del.rb +18 -5
  15. data/lib/lhj/command/oss/list.rb +6 -2
  16. data/lib/lhj/command/oss/upload.rb +9 -5
  17. data/lib/lhj/command/refactor_rename.rb +18 -2
  18. data/lib/lhj/command/rename_image.rb +48 -8
  19. data/lib/lhj/command/sync_pod_repo.rb +138 -0
  20. data/lib/lhj/command/trans.rb +1 -1
  21. data/lib/lhj/command/yapi.rb +15 -14
  22. data/lib/lhj/command.rb +33 -0
  23. data/lib/lhj/tools/version.rb +1 -1
  24. data/lib/lhj/tools.rb +1 -0
  25. data/lib/lhj/tree/directory_renderer.rb +45 -0
  26. data/lib/lhj/tree/hash_walker.rb +70 -0
  27. data/lib/lhj/tree/node.rb +90 -0
  28. data/lib/lhj/tree/number_renderer.rb +30 -0
  29. data/lib/lhj/tree/path_walker.rb +107 -0
  30. data/lib/lhj/tree/tree.rb +112 -0
  31. data/lib/lhj/ui/errors/lhj_common_error.rb +19 -0
  32. data/lib/lhj/ui/errors/lhj_crash.rb +11 -0
  33. data/lib/lhj/ui/errors/lhj_error.rb +25 -0
  34. data/lib/lhj/ui/errors/lhj_exception.rb +19 -0
  35. data/lib/lhj/ui/errors/lhj_shell_error.rb +11 -0
  36. data/lib/lhj/ui/errors.rb +1 -0
  37. data/lib/lhj/ui/implementations/shell.rb +148 -0
  38. data/lib/lhj/ui/interface.rb +205 -0
  39. data/lib/lhj/ui/ui.rb +26 -0
  40. metadata +77 -2
@@ -0,0 +1,138 @@
1
+ require 'lhj/config'
2
+ require 'highline'
3
+
4
+ module Lhj
5
+ class Command
6
+ # sync code to pod
7
+ class SyncPod < Command
8
+ self.summary = '同步代码到私用仓库'
9
+
10
+ def initialize(argv)
11
+ @cli = HighLine.new
12
+ super
13
+ end
14
+
15
+ def handle
16
+ sync
17
+ end
18
+
19
+ def sync
20
+ config_file = File.join(Lhj::Config.instance.home_dir, 'pod_config.yml')
21
+ arr = YAML.load_file(config_file)
22
+ arr.each_index { |i| puts "#{i}.#{arr[i]['pod']}".yellow }
23
+ idx = @cli.ask('请选择哪一个库同步: '.green).strip.to_i
24
+ pod_name = arr[idx]['pod']
25
+ src = arr[idx]['main_path']
26
+ dest = arr[idx]['pod_path']
27
+ FileUtils.cp_r(src, dest, remove_destination: true)
28
+ puts '1.从主工程复制代码到pod库成功'.green
29
+
30
+ ma = nil
31
+ Dir.chdir(dest) do
32
+ Dir.glob("*.podspec").each do |p|
33
+ update_podspec_version(p)
34
+ version_line = IO.readlines(p).find{ |line| (/\.version/ =~ line) && (version_regex =~ line) }
35
+ ma = version_line.match(version_regex)
36
+ end
37
+ puts '2.更新版本号成功'.green
38
+
39
+ Actions.sh("git add .")
40
+ puts '3.git add成功'.green
41
+
42
+ Actions.sh("git commit -m '同步主工程代码by fastlane'")
43
+ puts '4.git 提交成功'.green
44
+
45
+ Actions.sh("git push")
46
+ puts '5.git 推送成功'.green
47
+
48
+ add_tag(ma[0]) if ma
49
+ puts "6.设置tag成功! tag号:#{ma[0]}".green
50
+
51
+ push_tag
52
+ puts '7.推送tag成功'.green
53
+
54
+ update_pod_repo
55
+ puts "8.#{pod_name}推送pod repo成功".green
56
+
57
+ end
58
+
59
+ if ma
60
+ pod_version = ma[0]
61
+ update_all_pod_dependency(pod_name, pod_version)
62
+ puts '9.更新主工程引用pod版本号成功'.green
63
+ end
64
+
65
+ puts '10.手动执行`pod update --verbose --no-repo-update`更新pod'.green
66
+ end
67
+
68
+ def version_regex
69
+ /\d+\.\d+\.(\d+)/
70
+ end
71
+
72
+ def update_podspec_version(path)
73
+ str = ''
74
+ File.readlines(path).each do |l|
75
+ if (/\.version/ =~ l) && (version_regex =~ l)
76
+ last_version = l.scan(version_regex).flatten.first
77
+ next_version = last_version.to_i + 1
78
+ next_version_str = next_version.to_s
79
+ str += l.gsub(/(\d+\.\d+\.)(\d+)/, '\1' + next_version_str)
80
+ else
81
+ str += l.dup
82
+ end
83
+ end
84
+ File.write(path, str)
85
+ end
86
+
87
+ def add_tag(tag)
88
+ cmd = ['git tag']
89
+ cmd << '--force'
90
+ cmd << tag
91
+ UI.message("Adding git tag '#{tag}' 🎯.")
92
+ Actions.sh(cmd.join(' '))
93
+ end
94
+
95
+ def push_tag
96
+ cmd = ['git push --tags']
97
+ UI.message("git push --tags 🎯.")
98
+ Actions.sh(cmd.join(' '))
99
+ end
100
+
101
+ def update_pod_repo
102
+ # pod repo push miguatech-aomi_ios-mlspecs *.podspec --sources=miguatech-aomi_ios-mlspecs,aliyun,trunk --allow-warnings --use-libraries --verbose
103
+ cmd = ['pod repo push']
104
+ pod_repo_name = 'miguatech-aomi_ios-mlspecs'
105
+ cmd << pod_repo_name
106
+ cmd << "*.podspec"
107
+ cmd << "--sources=#{pod_repo_name},aliyun,trunk"
108
+ cmd << "--allow-warnings"
109
+ cmd << "--use-libraries"
110
+ cmd << "--verbose"
111
+ Actions.sh(cmd.join(' '), log: true, error_callback: nil)
112
+ end
113
+
114
+ def update_all_pod_dependency(pod_name, pod_version)
115
+ Dir.glob(["./**/*.podspec", "./**/Podfile"]).each do |p|
116
+ unless /Example/ =~ p
117
+ puts "更新文件:#{p}".magenta
118
+ update_main_proj_podspec_version(p, pod_name, pod_version)
119
+ end
120
+ end
121
+ end
122
+
123
+ def update_main_proj_podspec_version(path, pod_name, pod_version)
124
+ cont = ''
125
+ File.readlines(path).each do |l|
126
+ if (/#{pod_name}/ =~ l) && (/\d+\.\d+\.\d+/ =~ l)
127
+ l.scan(/\d+\.\d+\.\d+/).each do |key|
128
+ cont += l.gsub(key, pod_version)
129
+ end
130
+ else
131
+ cont += l.dup
132
+ end
133
+ end
134
+ File.write(path, cont)
135
+ end
136
+ end
137
+ end
138
+ end
@@ -21,7 +21,7 @@ module Lhj
21
21
  super
22
22
  end
23
23
 
24
- def run
24
+ def handle
25
25
  handler_files
26
26
  end
27
27
 
@@ -5,6 +5,7 @@ require 'yaml'
5
5
 
6
6
  module Lhj
7
7
  class Command
8
+ # generate model from yapi
8
9
  class Yapi < Command
9
10
  self.summary = '通过yapi接口生成请求'
10
11
  self.description = '更新 ~/.lhj/yapi.yml 文件配置后执行`lhj api`生成接口模型'
@@ -34,7 +35,7 @@ module Lhj
34
35
  super
35
36
  end
36
37
 
37
- def run
38
+ def handle
38
39
  load_config
39
40
  fetch_model
40
41
  print_methods
@@ -49,13 +50,13 @@ module Lhj
49
50
  end
50
51
 
51
52
  def puts_h(str)
52
- puts str
53
+ puts str.magenta
53
54
  @h_file_array ||= []
54
55
  @h_file_array << str
55
56
  end
56
57
 
57
58
  def puts_m(str)
58
- puts str
59
+ puts str.blue
59
60
  @m_file_array ||= []
60
61
  @m_file_array << str
61
62
  end
@@ -65,9 +66,9 @@ module Lhj
65
66
  file_name = gen_model_name('')
66
67
  h_file = File.join('.', "#{file_name}.h")
67
68
  m_file = File.join('.', "#{file_name}.m")
68
- File.write(h_file, @h_file_array.join("\n")) if @h_file_array.count > 0
69
- File.write(m_file, @m_file_array.join("\n")) if @m_file_array.count > 0
70
- puts "\n\n生成文件成功!所在路径:\n#{File.expand_path(h_file)} \n#{File.expand_path(m_file)}"
69
+ File.write(h_file, @h_file_array.join("\n")) if @h_file_array.count.positive?
70
+ File.write(m_file, @m_file_array.join("\n")) if @m_file_array.count.positive?
71
+ puts "\n\n生成文件成功!所在路径:\n#{File.expand_path(h_file)} \n#{File.expand_path(m_file)}".green
71
72
  end
72
73
 
73
74
  def url_str
@@ -78,7 +79,7 @@ module Lhj
78
79
  yml = File.join(Lhj::Config.instance.home_dir, 'yapi.yml')
79
80
  config = YAML.load_file(yml)
80
81
  config.each do |k, v|
81
- @http_headers << "#{k}=#{v}" if (k.eql?('__wpkreporterwid_') || k.eql?('_yapi_token') || k.eql?('_yapi_uid'))
82
+ @http_headers << "#{k}=#{v}" if k.eql?('__wpkreporterwid_') || k.eql?('_yapi_token') || k.eql?('_yapi_uid')
82
83
  end
83
84
  @http_url = config['url']
84
85
  @config_id = config['id']
@@ -107,27 +108,27 @@ module Lhj
107
108
  res = Net::HTTP.start(uri.hostname, uri.port) do |http|
108
109
  http.request(req)
109
110
  end
110
- puts res.body
111
+ puts res.body unless res.body['errcode'].to_i.zero?
111
112
  JSON.parse(res.body)
112
113
  end
113
114
 
114
115
  def fetch_model
115
116
  res_json = req_model
116
117
  begin
117
- puts "\n<===============打印返回数据模型-Begin=====================>\n"
118
+ puts "\n<===============打印返回数据模型-Begin=====================>\n".green
118
119
  fetch_res_boy(res_json)
119
120
  print_models
120
121
  print_models_implementation
121
- puts "\n<===============打印返回数据模型-End=====================>\n"
122
+ puts "\n<===============打印返回数据模型-End=====================>\n".green
122
123
  end
123
124
  begin
124
- puts "\n<===============打印请求模型-Begin=====================>\n"
125
+ puts "\n<===============打印请求模型-Begin=====================>\n".green
125
126
  @models = []
126
127
  @model_names = []
127
128
  fetch_req_body(res_json)
128
129
  print_models
129
130
  print_models_implementation
130
- puts "\n<===============打印请求模型-End=====================>\n"
131
+ puts "\n<===============打印请求模型-End=====================>\n".green
131
132
  end
132
133
  end
133
134
 
@@ -221,7 +222,7 @@ module Lhj
221
222
  @models.each do |model|
222
223
  puts_m "@implementation #{model[:name]}"
223
224
  str = model[:properties].filter { |p| p[:type].eql?('array') && !p[:type_name].eql?('NSString') }.map { |p| "@\"#{p[:key]}\": #{p[:type_name]}.class" }.join(', ')
224
- if str && str.length > 0
225
+ if str && str.length.positive?
225
226
  puts_m '+(NSDictionary *)modelContainerPropertyGenericClass {'
226
227
  puts_m " return @{#{str}};"
227
228
  puts_m '}'
@@ -268,7 +269,7 @@ module Lhj
268
269
  end
269
270
 
270
271
  def print_methods
271
- puts "\n<===============方法调用=====================>\n"
272
+ puts "\n<===============方法调用=====================>\n".green
272
273
  puts_m '/**'
273
274
  puts_m " * #{@data_json['title']} -- #{@data_json['username']}"
274
275
  puts_m ' */'
data/lib/lhj/command.rb CHANGED
@@ -1,9 +1,13 @@
1
1
  require 'claide'
2
+ require "tty-spinner"
3
+ require 'lhj/action/sh_helper'
4
+ require 'lhj/ui/ui'
2
5
 
3
6
  module Lhj
4
7
  # command plugin
5
8
  class Command < CLAide::Command
6
9
  require 'lhj/command/init'
10
+ require 'lhj/command/config'
7
11
  require 'lhj/command/head_import'
8
12
  require 'lhj/command/refactor_rename'
9
13
  require 'lhj/command/local/fetch'
@@ -19,8 +23,37 @@ module Lhj
19
23
  require 'lhj/command/rename_image'
20
24
  require 'lhj/command/trans'
21
25
  require 'lhj/command/yapi'
26
+ require 'lhj/command/file_path'
27
+ require 'lhj/command/http'
28
+ require 'lhj/command/sync_pod_repo'
22
29
 
23
30
  self.abstract_command = true
24
31
  self.command = 'lhj'
32
+
33
+ def auto_spin
34
+ print "正在处理...\n".green
35
+ # @spinner.auto_spin
36
+ end
37
+
38
+ def stop
39
+ print '处理完成'.green
40
+ # @spinner.success('Done!')
41
+ end
42
+
43
+ def initialize(argv)
44
+ super(argv)
45
+ @spinner = TTY::Spinner.new('...', output: $stdout, format: :dots, clear: true)
46
+ end
47
+
48
+ def run
49
+ auto_spin
50
+ handle
51
+ stop
52
+ end
53
+
54
+ def handle
55
+ raise 'A subclass should override the `Lhj::Command#run` method'
56
+ end
57
+
25
58
  end
26
59
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lhj
4
4
  module Tools
5
- VERSION = "0.1.3"
5
+ VERSION = "0.1.7"
6
6
  end
7
7
  end
data/lib/lhj/tools.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  require_relative "tools/version"
3
+ require 'colored'
3
4
 
4
5
  module Lhj
5
6
  require 'lhj/config'
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lhj
4
+ class Tree
5
+ # Render nodes as files paths explorer
6
+ class DirectoryRenderer
7
+ MARKERS = {
8
+ unicode: {
9
+ branch: '├──',
10
+ leaf: '└──',
11
+ pipe: '│'
12
+ },
13
+ ansi: {
14
+ branch: '|--',
15
+ leaf: '`--',
16
+ pipe: '|'
17
+ }
18
+ }.freeze
19
+
20
+ def initialize(nodes, options = {})
21
+ @nodes = nodes
22
+ @indent = options.fetch(:indent, 4)
23
+ @pipe_mark = MARKERS[:unicode][:pipe] + ' ' * [@indent - 1, 0].max
24
+ @space_mark = ' ' * @indent
25
+ end
26
+
27
+ def render
28
+ @nodes.reduce([]) do |acc, node|
29
+ render_node(acc, node, @pipe_mark, @space_mark)
30
+ end.join('')
31
+ end
32
+
33
+ private
34
+
35
+ def render_node(acc, node, pipe_mark, space_mark)
36
+ acc << node.prefix.gsub(/:pipe/, pipe_mark).gsub(/:space/, space_mark)
37
+ unless node.root?
38
+ acc << MARKERS[:unicode][node.leaf? ? :leaf : :branch]
39
+ acc << ' '
40
+ end
41
+ acc << node.name.to_s + "\n"
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pathname'
4
+
5
+ require_relative 'node'
6
+
7
+ module Lhj
8
+ class Tree
9
+ # Walk and collect nodes from hash data strcture.
10
+ #
11
+ # @api public
12
+ class HashWalker
13
+ attr_reader :nodes
14
+
15
+ attr_reader :files_count
16
+
17
+ attr_reader :dirs_count
18
+
19
+ def initialize(options = {})
20
+ @nodes = []
21
+ @files_count = 0
22
+ @dirs_count = 0
23
+ @level = options.fetch(:level) { -1 }
24
+ @file_limit = options.fetch(:file_limit) { - 1 }
25
+ end
26
+
27
+ def traverse(data)
28
+ walk(data, Pathname.new(''), '', 0, false)
29
+ end
30
+
31
+ def walk(data, parent_path, prefix, level, is_last)
32
+ node = is_last ? LeafNode : Node
33
+
34
+ case data
35
+ when Hash
36
+ return if @level != -1 && level + 1 > @level
37
+
38
+ data.each do |dir, item|
39
+ dir_node = node.new(dir.to_s, parent_path, prefix, level)
40
+ @nodes << dir_node
41
+ @dirs_count += 1 unless dir_node.root?
42
+
43
+ if level > 0
44
+ postfix = ':pipe'
45
+ postfix = ':space' if is_last
46
+ else
47
+ postfix = ''
48
+ end
49
+
50
+ walk(item, parent_path + dir.to_s,
51
+ prefix + postfix, level + 1, false)
52
+ end
53
+ when Array
54
+ return if @file_limit != -1 && data.size > @file_limit
55
+
56
+ last_data_index = data.size - 1
57
+
58
+ data.each_with_index do |item, i|
59
+ last = (last_data_index == i)
60
+
61
+ walk(item, parent_path, prefix, level, last)
62
+ end
63
+ else
64
+ @nodes << node.new(data.to_s, parent_path, prefix, level)
65
+ @files_count += 1
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+ require 'pathname'
5
+
6
+ module Lhj
7
+ class Tree
8
+ # A representation of tree node
9
+ #
10
+ # @api private
11
+ class Node
12
+ extend Forwardable
13
+
14
+ # The base name for the directory or file
15
+ attr_reader :name
16
+
17
+ # The parent directory path
18
+ attr_reader :parent
19
+
20
+ # The require path prefix
21
+ attr_reader :prefix
22
+
23
+ # The directory depth
24
+ attr_reader :level
25
+
26
+ # The file stat
27
+ attr_reader :stat
28
+
29
+ # The current path
30
+ attr_reader :path
31
+
32
+ def_delegators :@path, :directory?, :executable?, :file?,
33
+ :symlink?, :socket?, :pipe?
34
+
35
+ def initialize(path, parent, prefix, level)
36
+ if path.is_a? String
37
+ # strip null bytes from the string to avoid throwing errors
38
+ path = path.delete("\0")
39
+ end
40
+
41
+ @path = Pathname.new(path)
42
+ @name = @path.basename
43
+ @parent = Pathname.new(parent)
44
+ @prefix = prefix
45
+ @level = level
46
+ end
47
+
48
+ def full_path
49
+ return parent if name.to_s.empty?
50
+
51
+ parent.join(name)
52
+ end
53
+
54
+ def root?
55
+ parent.to_s.empty?
56
+ end
57
+
58
+ def hidden?
59
+ name.to_s.start_with?('.')
60
+ end
61
+
62
+ def leaf?
63
+ false
64
+ end
65
+
66
+ def to_s
67
+ @name
68
+ end
69
+
70
+ def ==(other)
71
+ other.is_a?(self.class) && other.state_attrs == state_attrs
72
+ end
73
+ alias eql? ==
74
+
75
+ protected
76
+
77
+ def state_attrs
78
+ [@name, @path, @parent, @prefix, @level]
79
+ end
80
+
81
+ ROOT = Node.new('', Pathname.new(''), '', 0).freeze
82
+ end # Node
83
+
84
+ class LeafNode < Node
85
+ def leaf?
86
+ true
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lhj
4
+ class Tree
5
+ # Render nodes as numbered list
6
+ class NumberRenderer
7
+ def initialize(nodes, options = {})
8
+ @indent = options.fetch(:indent, 4)
9
+ @nodes = nodes
10
+ @mark = ' ' * @indent
11
+ end
12
+
13
+ def render
14
+ @nodes.each_with_index.reduce([]) do |acc, (node, i)|
15
+ render_node(acc, node, i, @mark)
16
+ end.join
17
+ end
18
+
19
+ private
20
+
21
+ def render_node(acc, node, i, mark)
22
+ acc << node.prefix.gsub(/:pipe|:space/, mark)
23
+ unless node.root?
24
+ acc << "#{node.level}.#{i} "
25
+ end
26
+ acc << node.name.to_s + "\n"
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pathname'
4
+ require_relative 'node'
5
+
6
+ module Lhj
7
+ class Tree
8
+ # Walk and collect nodes from directory.
9
+ #
10
+ # @api public
11
+ class PathWalker
12
+ attr_reader :nodes
13
+
14
+ attr_reader :files_count
15
+
16
+ attr_reader :dirs_count
17
+
18
+ # Create a PathWalker
19
+ #
20
+ # @api public
21
+ def initialize(options = {})
22
+ @files_count = 0
23
+ @dirs_count = 0
24
+ @nodes = []
25
+ @filters = []
26
+ @level = options.fetch(:level) { -1 }
27
+ @file_limit = options.fetch(:file_limit) { - 1 }
28
+
29
+ unless options[:show_hidden]
30
+ add_filter(-> (p) { !p.basename.to_s.start_with?('.') })
31
+ end
32
+
33
+ if options[:only_dirs]
34
+ add_filter(-> (p) { p.directory? })
35
+ end
36
+ end
37
+
38
+ def add_filter(filter)
39
+ @filters << filter
40
+ end
41
+
42
+ # Traverse given path recursively
43
+ #
44
+ # @param [String] path
45
+ # the path to traverse
46
+ #
47
+ # @api public
48
+ def traverse(path)
49
+ root_path = Pathname.new(path)
50
+ empty_path = Pathname.new('')
51
+
52
+ unless root_path.directory?
53
+ raise ArgumentError, "#{root_path} is not a directory path"
54
+ end
55
+
56
+ @nodes << Node.new(root_path, empty_path, '', 0)
57
+
58
+ walk(root_path, root_path.children, '', 1)
59
+ end
60
+
61
+ private
62
+
63
+ # Filter entries
64
+ #
65
+ # @api private
66
+ def filter_entries(entries, filters)
67
+ return entries if filters.nil? || filters.empty?
68
+ filter = filters[0]
69
+ filter_entries(entries.select(&filter), filters[1..-1])
70
+ end
71
+
72
+ # Walk paths recursively
73
+ #
74
+ # @api private
75
+ def walk(parent_path, entries, prefix, level)
76
+ if entries.empty? || (@level != -1 && @level < level)
77
+ return
78
+ else
79
+ return if @file_limit != -1 && entries.size > @file_limit
80
+ processed_paths = filter_entries(entries, @filters).sort
81
+ last_path_index = processed_paths.size - 1
82
+
83
+ processed_paths.each_with_index do |path, i|
84
+ sub_path = path.relative_path_from(parent_path)
85
+
86
+ node = last_path_index == i ? LeafNode : Node
87
+
88
+ if path.directory?
89
+ next if @level != -1 && level + 1 > @level
90
+
91
+ @nodes << node.new(sub_path, parent_path, prefix, level)
92
+ @dirs_count += 1
93
+
94
+ postfix = ':pipe'
95
+ postfix = ':space' if i == last_path_index
96
+
97
+ walk(path, path.children, prefix + postfix, level + 1)
98
+ elsif path.file?
99
+ @nodes << node.new(path, parent_path, prefix, level)
100
+ @files_count += 1
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end