lhj-tools 0.1.4 → 0.1.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 74f8ff17bf0bbd3cbb38c92aa203ecb3983da440b5bb158fa1af980adc9fc452
4
- data.tar.gz: c43f7f0ad99e94fd7602e64aaf1246ca1244c588b53794960b937a02ce4e6783
3
+ metadata.gz: ae59197a9dbd9ce3ed7de0da5c26ce2cc91c8b97f7049b08981134c293e67b1a
4
+ data.tar.gz: 9b553856214eab3372e2c528707eae16dbbf59068109ac1042256cb32ffedaa0
5
5
  SHA512:
6
- metadata.gz: b200a275276a8b419427203042365a4641920df44420637d4be89d5f588a173d9a6a944fe65f00d2d956262aae0ebe3bf379dc2ce63afec749401923294f6f3f
7
- data.tar.gz: c3bb0f9d4cce6b7f789a00856efe2398274cadb9cbee4b8b5d1b7af6a7c6398f02c33422dff1527f1edeefe3353d65f341d5e637a6a87ead4e283a7e410c4e8c
6
+ metadata.gz: 197f2cdaa7e7f8eacbbe3fd28b9f2a6cf4a871d4045134f359cd6ec01f6b79995a8416c5ef4cec2b6b5a21cee238f1a34f2ddb3559fb96e8400c3c878e73f75b
7
+ data.tar.gz: 990499bcc61e51695cad04f2e5b248056fa236a640cf704e40d2774ddace77df537b4a99429f8c36d168e9344daa2db2763a7bd82eb5086ede790fe7b974912f
@@ -12,8 +12,10 @@ module Lhj
12
12
  self.description = '使用工具前先执行`lhj init`'
13
13
 
14
14
  def run
15
+ auto_spin
15
16
  FileUtils.mkdir_p(target_folder) unless File.exist?(target_folder)
16
17
  download_file
18
+ stop
17
19
  end
18
20
 
19
21
  def down_load_urls
@@ -36,7 +38,7 @@ module Lhj
36
38
  end
37
39
 
38
40
  def file_name_with_url(url)
39
- url.scan(%r{(/.[^/]*)}).flatten.last
41
+ url.scan(%r{/([^/]+)}).flatten.last
40
42
  end
41
43
 
42
44
  def download_file
@@ -1,4 +1,5 @@
1
1
  require 'lhj/helper/oss_helper'
2
+ require 'terminal-table'
2
3
 
3
4
  module Lhj
4
5
  class Command
@@ -8,10 +9,13 @@ module Lhj
8
9
 
9
10
  def run
10
11
  objects = Lhj::OSS::Helper.instance.list
12
+ rows = []
11
13
  objects.each do |o|
12
14
  path = "#{Lhj::OSS::Helper.instance.url_path}/#{o.key}"
13
- puts path
15
+ rows << [path]
14
16
  end
17
+ table = Terminal::Table.new title: 'OSS List', headings: ['URL'], rows: rows
18
+ puts table
15
19
  end
16
20
  end
17
21
  end
@@ -23,7 +23,7 @@ module Lhj
23
23
 
24
24
  def validate!
25
25
  super
26
- help! '类型或名字必须输入' unless @name && @type
26
+ help! '类型或名字必须输入' unless @name || @type
27
27
  end
28
28
 
29
29
  def initialize(argv)
@@ -34,7 +34,7 @@ module Lhj
34
34
  end
35
35
 
36
36
  def run
37
- Dir.glob(@current_path).each do |f|
37
+ Dir.glob("#{@current_path}/*").each do |f|
38
38
  file_name = File.basename(f)
39
39
  if @name && /#{@name}/ =~ file_name
40
40
  upload(f, file_name)
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'find'
4
4
  require 'fileutils'
5
+ require 'terminal-table'
5
6
 
6
7
  module Lhj
7
8
  class Command
@@ -31,11 +32,13 @@ module Lhj
31
32
  @current_path = argv.shift_argument || Dir.pwd
32
33
  @key = argv.option('key')
33
34
  @other = argv.option('other')
35
+ @modify_files = []
34
36
  super
35
37
  end
36
38
 
37
39
  def run
38
40
  update_source_file
41
+ print_info
39
42
  end
40
43
 
41
44
  def update_source_file
@@ -69,9 +72,22 @@ module Lhj
69
72
 
70
73
  def format_string(file, line)
71
74
  result = line
72
- result = result.gsub(/(\W)(#{@key})(\W)/, "\\1#{@other}\\3") if /(\W)(#{@key})(\W)/ =~ line
75
+ if /(\W)(#{@key})(\W)/ =~ line
76
+ result = result.gsub(/(\W)(#{@key})(\W)/, "\\1#{@other}\\3")
77
+ @modify_files << file unless @modify_files.include?(file)
78
+ end
73
79
  result
74
80
  end
81
+
82
+ def print_info
83
+ rows = []
84
+ @modify_files.each do |file|
85
+ rows << [File.basename(file), File.absolute_path(file)]
86
+ end
87
+ title = "修改了#{rows.count}个文件"
88
+ table = Terminal::Table.new title: title, headings: %w[文件 路径], rows: rows
89
+ puts table
90
+ end
75
91
  end
76
92
  end
77
93
  end
data/lib/lhj/command.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'claide'
2
+ require "tty-spinner"
2
3
 
3
4
  module Lhj
4
5
  # command plugin
@@ -22,5 +23,18 @@ module Lhj
22
23
 
23
24
  self.abstract_command = true
24
25
  self.command = 'lhj'
26
+
27
+ def spinner
28
+ @spinner ||= TTY::Spinner.new('[:spinner]正在处理...', format: :dots)
29
+ end
30
+
31
+ def auto_spin
32
+ spinner.auto_spin
33
+ end
34
+
35
+ def stop
36
+ spinner.stop('Done!')
37
+ end
38
+
25
39
  end
26
40
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lhj
4
4
  module Tools
5
- VERSION = "0.1.4"
5
+ VERSION = "0.1.5"
6
6
  end
7
7
  end
@@ -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 'lhj/tree/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,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pathname'
4
+
5
+ require 'lhj/tree/node'
6
+
7
+ module Lhj
8
+ class Tree
9
+ # Walk and collect nodes from directory.
10
+ #
11
+ # @api public
12
+ class PathWalker
13
+ attr_reader :nodes
14
+
15
+ attr_reader :files_count
16
+
17
+ attr_reader :dirs_count
18
+
19
+ # Create a PathWalker
20
+ #
21
+ # @api public
22
+ def initialize(options = {})
23
+ @files_count = 0
24
+ @dirs_count = 0
25
+ @nodes = []
26
+ @filters = []
27
+ @level = options.fetch(:level) { -1 }
28
+ @file_limit = options.fetch(:file_limit) { - 1 }
29
+
30
+ unless options[:show_hidden]
31
+ add_filter(-> (p) { !p.basename.to_s.start_with?('.') })
32
+ end
33
+
34
+ if options[:only_dirs]
35
+ add_filter(-> (p) { p.directory? })
36
+ end
37
+ end
38
+
39
+ def add_filter(filter)
40
+ @filters << filter
41
+ end
42
+
43
+ # Traverse given path recursively
44
+ #
45
+ # @param [String] path
46
+ # the path to traverse
47
+ #
48
+ # @api public
49
+ def traverse(path)
50
+ root_path = Pathname.new(path)
51
+ empty_path = Pathname.new('')
52
+
53
+ unless root_path.directory?
54
+ raise ArgumentError, "#{root_path} is not a directory path"
55
+ end
56
+
57
+ @nodes << Node.new(root_path, empty_path, '', 0)
58
+
59
+ walk(root_path, root_path.children, '', 1)
60
+ end
61
+
62
+ private
63
+
64
+ # Filter entries
65
+ #
66
+ # @api private
67
+ def filter_entries(entries, filters)
68
+ return entries if filters.nil? || filters.empty?
69
+ filter = filters[0]
70
+ filter_entries(entries.select(&filter), filters[1..-1])
71
+ end
72
+
73
+ # Walk paths recursively
74
+ #
75
+ # @api private
76
+ def walk(parent_path, entries, prefix, level)
77
+ if entries.empty? || (@level != -1 && @level < level)
78
+ return
79
+ else
80
+ return if @file_limit != -1 && entries.size > @file_limit
81
+ processed_paths = filter_entries(entries, @filters).sort
82
+ last_path_index = processed_paths.size - 1
83
+
84
+ processed_paths.each_with_index do |path, i|
85
+ sub_path = path.relative_path_from(parent_path)
86
+
87
+ node = last_path_index == i ? LeafNode : Node
88
+
89
+ if path.directory?
90
+ next if @level != -1 && level + 1 > @level
91
+
92
+ @nodes << node.new(sub_path, parent_path, prefix, level)
93
+ @dirs_count += 1
94
+
95
+ postfix = ':pipe'
96
+ postfix = ':space' if i == last_path_index
97
+
98
+ walk(path, path.children, prefix + postfix, level + 1)
99
+ elsif path.file?
100
+ @nodes << node.new(path, parent_path, prefix, level)
101
+ @files_count += 1
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'lhj/tree/node'
4
+ require 'lhj/tree/directory_renderer'
5
+ require 'lhj/tree/number_renderer'
6
+ require 'lhj/tree/hash_walker'
7
+ require 'lhj/tree/path_walker'
8
+
9
+ module Lhj
10
+ class Tree
11
+ # @api public
12
+ def self.[](data)
13
+ new(data)
14
+ end
15
+
16
+ # The list of nodes in this tree.
17
+ attr_reader :nodes
18
+
19
+ # Create a Tree
20
+ #
21
+ # @param [String,Dir,Hash] data
22
+ #
23
+ # @api public
24
+ def initialize(data = nil, options = {}, &block)
25
+ @data = data ? data.dup.freeze : nil
26
+ @walker = select_walker.new(options)
27
+ @nodes = []
28
+
29
+ if @data
30
+ @walker.traverse(data)
31
+ @nodes = @walker.nodes
32
+ end
33
+
34
+ @nodes_stack = []
35
+
36
+ instance_eval(&block) if block_given?
37
+
38
+ freeze
39
+ end
40
+
41
+ # Add node to this tree.
42
+ #
43
+ # @param [Symbol,String] name
44
+ # the name for the node
45
+ #
46
+ # @param [Node, LeafNode] type
47
+ # the type of node to add
48
+ #
49
+ # @example
50
+ # TTY::Tree.new do
51
+ # node '...' do
52
+ # node '...'
53
+ # end
54
+ # end
55
+ #
56
+ # @api public
57
+ def node(name, type = Node, &block)
58
+ parent = @nodes_stack.empty? ? Node::ROOT : @nodes_stack.last
59
+ level = [0, @nodes_stack.size - 1].max
60
+ prefix = ':pipe' * level
61
+ if parent.class == LeafNode
62
+ prefix = ':space' * level
63
+ end
64
+ node = type.new(name, parent.full_path, prefix, @nodes_stack.size)
65
+ @nodes << node
66
+
67
+ return unless block_given?
68
+
69
+ @nodes_stack << node
70
+ if block.arity.zero?
71
+ instance_eval(&block)
72
+ else
73
+ instance_eval(&(->(*_args) { block[node] }))
74
+ end
75
+ @nodes_stack.pop
76
+ end
77
+
78
+ # Add leaf node
79
+ #
80
+ # @api public
81
+ def leaf(name, &block)
82
+ node(name, LeafNode, &block)
83
+ end
84
+
85
+ # @api public
86
+ def render(options = {})
87
+ as = options.delete(:as) || :dir
88
+ renderer = select_renderer(as).new(nodes, options)
89
+ renderer.render
90
+ end
91
+
92
+ private
93
+
94
+ # @api private
95
+ def select_walker
96
+ if @data.is_a?(Hash) || @data.nil?
97
+ HashWalker
98
+ else
99
+ @data ||= Dir.pwd
100
+ PathWalker
101
+ end
102
+ end
103
+
104
+ def select_renderer(as)
105
+ case as
106
+ when :dir, :directory then DirectoryRenderer
107
+ when :num, :number then NumberRenderer
108
+ end
109
+ end
110
+ end
111
+ end
112
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lhj-tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - lihaijian
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-20 00:00:00.000000000 Z
11
+ date: 2022-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: claide
@@ -118,6 +118,26 @@ dependencies:
118
118
  - - "~>"
119
119
  - !ruby/object:Gem::Version
120
120
  version: '2.8'
121
+ - !ruby/object:Gem::Dependency
122
+ name: tty-spinner
123
+ requirement: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ version: 0.8.0
128
+ - - "<"
129
+ - !ruby/object:Gem::Version
130
+ version: 1.0.0
131
+ type: :runtime
132
+ prerelease: false
133
+ version_requirements: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: 0.8.0
138
+ - - "<"
139
+ - !ruby/object:Gem::Version
140
+ version: 1.0.0
121
141
  - !ruby/object:Gem::Dependency
122
142
  name: faraday-cookie_jar
123
143
  requirement: !ruby/object:Gem::Requirement
@@ -244,6 +264,12 @@ files:
244
264
  - lib/lhj/helper/trans_helper.rb
245
265
  - lib/lhj/tools.rb
246
266
  - lib/lhj/tools/version.rb
267
+ - lib/lhj/tree/directory_renderer.rb
268
+ - lib/lhj/tree/hash_walker.rb
269
+ - lib/lhj/tree/node.rb
270
+ - lib/lhj/tree/number_renderer.rb
271
+ - lib/lhj/tree/path_walker.rb
272
+ - lib/lhj/tree/tree.rb
247
273
  homepage:
248
274
  licenses:
249
275
  - MIT