lhj-tools 0.1.4 → 0.1.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/lhj/action/sh_helper.rb +138 -0
- data/lib/lhj/command/config/info.rb +47 -0
- data/lib/lhj/command/config.rb +11 -0
- data/lib/lhj/command/file_path.rb +20 -0
- data/lib/lhj/command/head_import.rb +19 -3
- data/lib/lhj/command/http.rb +14 -0
- data/lib/lhj/command/init.rb +2 -2
- data/lib/lhj/command/local/fetch.rb +1 -1
- data/lib/lhj/command/local/filter.rb +1 -1
- data/lib/lhj/command/local/local.rb +1 -1
- data/lib/lhj/command/local/local_upload.rb +1 -1
- data/lib/lhj/command/local/micro_service.rb +1 -1
- data/lib/lhj/command/oss/del.rb +18 -5
- data/lib/lhj/command/oss/list.rb +6 -2
- data/lib/lhj/command/oss/upload.rb +9 -5
- data/lib/lhj/command/refactor_rename.rb +18 -2
- data/lib/lhj/command/rename_image.rb +1 -1
- data/lib/lhj/command/sync_pod_repo.rb +151 -0
- data/lib/lhj/command/trans.rb +1 -1
- data/lib/lhj/command/yapi.rb +15 -14
- data/lib/lhj/command.rb +33 -0
- data/lib/lhj/tools/version.rb +1 -1
- data/lib/lhj/tools.rb +1 -0
- data/lib/lhj/tree/directory_renderer.rb +45 -0
- data/lib/lhj/tree/hash_walker.rb +70 -0
- data/lib/lhj/tree/node.rb +90 -0
- data/lib/lhj/tree/number_renderer.rb +30 -0
- data/lib/lhj/tree/path_walker.rb +107 -0
- data/lib/lhj/tree/tree.rb +112 -0
- data/lib/lhj/ui/errors/lhj_common_error.rb +19 -0
- data/lib/lhj/ui/errors/lhj_crash.rb +11 -0
- data/lib/lhj/ui/errors/lhj_error.rb +25 -0
- data/lib/lhj/ui/errors/lhj_exception.rb +19 -0
- data/lib/lhj/ui/errors/lhj_shell_error.rb +11 -0
- data/lib/lhj/ui/errors.rb +1 -0
- data/lib/lhj/ui/implementations/shell.rb +148 -0
- data/lib/lhj/ui/interface.rb +205 -0
- data/lib/lhj/ui/ui.rb +26 -0
- metadata +77 -2
@@ -0,0 +1,112 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'node'
|
4
|
+
require_relative 'directory_renderer'
|
5
|
+
require_relative 'number_renderer'
|
6
|
+
require_relative 'hash_walker'
|
7
|
+
require_relative '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
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative 'lhj_exception'
|
2
|
+
|
3
|
+
module Lhj
|
4
|
+
class Interface
|
5
|
+
# Super class for exception types that we do not want to record
|
6
|
+
# explicitly as crashes or user errors
|
7
|
+
class LhjCommonException < LhjException; end
|
8
|
+
|
9
|
+
# Raised when there is a build failure in xcodebuild
|
10
|
+
class LhjBuildFailure < LhjCommonException; end
|
11
|
+
|
12
|
+
# Raised when a test fails when being run by tools such as scan or snapshot
|
13
|
+
class LhjTestFailure < LhjCommonException; end
|
14
|
+
|
15
|
+
# Raise this type of exception when a failure caused by a third party
|
16
|
+
# dependency (i.e. xcodebuild, gradle, slather) happens.
|
17
|
+
class LhjDependencyCausedException < LhjCommonException; end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative 'lhj_exception'
|
2
|
+
|
3
|
+
module Lhj
|
4
|
+
class Interface
|
5
|
+
class LhjError < LhjException
|
6
|
+
attr_reader :show_github_issues
|
7
|
+
attr_reader :error_info
|
8
|
+
|
9
|
+
def initialize(show_github_issues: false, error_info: nil)
|
10
|
+
@show_github_issues = show_github_issues
|
11
|
+
@error_info = error_info
|
12
|
+
end
|
13
|
+
|
14
|
+
def prefix
|
15
|
+
'[USER_ERROR]'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Exception
|
22
|
+
# def fastlane_should_report_metrics?
|
23
|
+
# return false
|
24
|
+
# end
|
25
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Lhj
|
2
|
+
class Interface
|
3
|
+
class LhjException < StandardError
|
4
|
+
def prefix
|
5
|
+
'[LHJ_EXCEPTION]'
|
6
|
+
end
|
7
|
+
|
8
|
+
def caused_by_calling_ui_method?(method_name: nil)
|
9
|
+
return false if backtrace.nil? || backtrace[0].nil? || method_name.nil?
|
10
|
+
first_frame = backtrace[0]
|
11
|
+
if first_frame.include?(method_name) && first_frame.include?('interface.rb')
|
12
|
+
true
|
13
|
+
else
|
14
|
+
false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Dir[File.dirname(__FILE__) + "/errors/*.rb"].each { |f| require_relative f }
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require_relative '../interface'
|
2
|
+
|
3
|
+
module Lhj
|
4
|
+
# Shell is the terminal output of things
|
5
|
+
# For documentation for each of the methods open `interface.rb`
|
6
|
+
class Shell < Interface
|
7
|
+
|
8
|
+
def log
|
9
|
+
return @log if @log
|
10
|
+
|
11
|
+
$stdout.sync = true
|
12
|
+
|
13
|
+
# if !ENV.key?('DEBUG')
|
14
|
+
# $stdout.puts("Logging disabled while running tests. Force them by setting the DEBUG environment variable")
|
15
|
+
# @log ||= Logger.new(nil) # don't show any logs when running tests
|
16
|
+
# else
|
17
|
+
@log ||= Logger.new($stdout)
|
18
|
+
# end
|
19
|
+
|
20
|
+
@log.formatter = proc do |severity, datetime, progname, msg|
|
21
|
+
"#{format_string(datetime, severity)}#{msg}\n"
|
22
|
+
end
|
23
|
+
|
24
|
+
@log
|
25
|
+
end
|
26
|
+
|
27
|
+
def format_string(datetime = Time.now, severity = "")
|
28
|
+
return "[#{datetime.strftime('%H:%M:%S')}]: "
|
29
|
+
end
|
30
|
+
|
31
|
+
#####################################################
|
32
|
+
# @!group Messaging: show text to the user
|
33
|
+
#####################################################
|
34
|
+
|
35
|
+
def error(message)
|
36
|
+
log.error(message.to_s.red)
|
37
|
+
end
|
38
|
+
|
39
|
+
def important(message)
|
40
|
+
log.warn(message.to_s.yellow)
|
41
|
+
end
|
42
|
+
|
43
|
+
def success(message)
|
44
|
+
log.info(message.to_s.green)
|
45
|
+
end
|
46
|
+
|
47
|
+
def message(message)
|
48
|
+
log.info(message.to_s)
|
49
|
+
end
|
50
|
+
|
51
|
+
def deprecated(message)
|
52
|
+
log.error(message.to_s.deprecated)
|
53
|
+
end
|
54
|
+
|
55
|
+
def command(message)
|
56
|
+
log.info("$ #{message}".cyan)
|
57
|
+
end
|
58
|
+
|
59
|
+
def command_output(message)
|
60
|
+
actual = (encode_as_utf_8_if_possible(message).split("\r").last || "") # as clearing the line will remove the `>` and the time stamp
|
61
|
+
actual.split("\n").each do |msg|
|
62
|
+
prefix = msg.include?("▸") ? "" : "▸ "
|
63
|
+
log.info(prefix + "" + msg.magenta)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def verbose(message)
|
68
|
+
log.debug(message.to_s)
|
69
|
+
end
|
70
|
+
|
71
|
+
def header(message)
|
72
|
+
success(message)
|
73
|
+
end
|
74
|
+
|
75
|
+
def content_error(content, error_line)
|
76
|
+
error_line = error_line.to_i
|
77
|
+
return unless error_line > 0
|
78
|
+
|
79
|
+
contents = content.split(/\r?\n/).map(&:chomp)
|
80
|
+
|
81
|
+
start_line = error_line - 2 < 1 ? 1 : error_line - 2
|
82
|
+
end_line = error_line + 2 < contents.length ? error_line + 2 : contents.length
|
83
|
+
|
84
|
+
Range.new(start_line, end_line).each do |line|
|
85
|
+
str = line == error_line ? " => " : " "
|
86
|
+
str << line.to_s.rjust(Math.log10(end_line) + 1)
|
87
|
+
str << ":\t#{contents[line - 1]}"
|
88
|
+
error(str)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
#####################################################
|
93
|
+
# @!group Errors: Inputs
|
94
|
+
#####################################################
|
95
|
+
|
96
|
+
def interactive?
|
97
|
+
interactive = true
|
98
|
+
interactive = false if $stdout.isatty == false
|
99
|
+
interactive = false if Helper.ci?
|
100
|
+
return interactive
|
101
|
+
end
|
102
|
+
|
103
|
+
def input(message)
|
104
|
+
verify_interactive!(message)
|
105
|
+
ask("#{format_string}#{message.to_s.yellow}").to_s.strip
|
106
|
+
end
|
107
|
+
|
108
|
+
def confirm(message)
|
109
|
+
verify_interactive!(message)
|
110
|
+
agree("#{format_string}#{message.to_s.yellow} (y/n)", true)
|
111
|
+
end
|
112
|
+
|
113
|
+
def select(message, options)
|
114
|
+
verify_interactive!(message)
|
115
|
+
|
116
|
+
important(message)
|
117
|
+
choose(*options)
|
118
|
+
end
|
119
|
+
|
120
|
+
def password(message)
|
121
|
+
verify_interactive!(message)
|
122
|
+
|
123
|
+
ask("#{format_string}#{message.to_s.yellow}") do |q|
|
124
|
+
q.whitespace = :chomp
|
125
|
+
q.echo = "*"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
private
|
130
|
+
|
131
|
+
def encode_as_utf_8_if_possible(message)
|
132
|
+
return message if message.valid_encoding?
|
133
|
+
|
134
|
+
# genstrings outputs UTF-16, so we should try to use this encoding if it turns out to be valid
|
135
|
+
test_message = message.dup
|
136
|
+
return message.encode(Encoding::UTF_8, Encoding::UTF_16) if test_message.force_encoding(Encoding::UTF_16).valid_encoding?
|
137
|
+
|
138
|
+
# replace any invalid with empty string
|
139
|
+
message.encode(Encoding::UTF_8, invalid: :replace)
|
140
|
+
end
|
141
|
+
|
142
|
+
def verify_interactive!(message)
|
143
|
+
return if interactive?
|
144
|
+
important(message)
|
145
|
+
crash!("Could not retrieve response as fastlane runs in non-interactive mode")
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
require_relative 'errors'
|
2
|
+
|
3
|
+
module Lhj
|
4
|
+
# Abstract super class
|
5
|
+
class Interface
|
6
|
+
#####################################################
|
7
|
+
# @!group Messaging: show text to the user
|
8
|
+
#####################################################
|
9
|
+
|
10
|
+
# Level Error: Can be used to show additional error
|
11
|
+
# information before actually raising an exception
|
12
|
+
# or can be used to just show an error from which
|
13
|
+
# fastlane can recover (much magic)
|
14
|
+
#
|
15
|
+
# By default those messages are shown in red
|
16
|
+
def error(_message)
|
17
|
+
not_implemented(__method__)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Level Important: Can be used to show warnings to the user
|
21
|
+
# not necessarily negative, but something the user should
|
22
|
+
# be aware of.
|
23
|
+
#
|
24
|
+
# By default those messages are shown in yellow
|
25
|
+
def important(_message)
|
26
|
+
not_implemented(__method__)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Level Success: Show that something was successful
|
30
|
+
#
|
31
|
+
# By default those messages are shown in green
|
32
|
+
def success(_message)
|
33
|
+
not_implemented(__method__)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Level Message: Show a neutral message to the user
|
37
|
+
#
|
38
|
+
# By default those messages shown in white/black
|
39
|
+
def message(_message)
|
40
|
+
not_implemented(__method__)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Level Deprecated: Show that a particular function is deprecated
|
44
|
+
#
|
45
|
+
# By default those messages shown in strong blue
|
46
|
+
def deprecated(_message)
|
47
|
+
not_implemented(__method__)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Level Command: Print out a terminal command that is being
|
51
|
+
# executed.
|
52
|
+
#
|
53
|
+
# By default those messages shown in cyan
|
54
|
+
def command(_message)
|
55
|
+
not_implemented(__method__)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Level Command Output: Print the output of a command with
|
59
|
+
# this method
|
60
|
+
#
|
61
|
+
# By default those messages shown in magenta
|
62
|
+
def command_output(_message)
|
63
|
+
not_implemented(__method__)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Level Verbose: Print out additional information for the
|
67
|
+
# users that are interested. Will only be printed when
|
68
|
+
# FastlaneCore::Globals.verbose? = true
|
69
|
+
#
|
70
|
+
# By default those messages are shown in white
|
71
|
+
def verbose(_message)
|
72
|
+
not_implemented(__method__)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Print a header = a text in a box
|
76
|
+
# use this if this message is really important
|
77
|
+
def header(_message)
|
78
|
+
not_implemented(__method__)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Print lines of content around specific line where
|
82
|
+
# failed to parse.
|
83
|
+
#
|
84
|
+
# This message will be shown as error
|
85
|
+
def content_error(content, error_line)
|
86
|
+
not_implemented(__method__)
|
87
|
+
end
|
88
|
+
|
89
|
+
#####################################################
|
90
|
+
# @!group Errors: Inputs
|
91
|
+
#####################################################
|
92
|
+
|
93
|
+
# Is is possible to ask the user questions?
|
94
|
+
def interactive?
|
95
|
+
not_implemented(__method__)
|
96
|
+
end
|
97
|
+
|
98
|
+
# get a standard text input (single line)
|
99
|
+
def input(_message)
|
100
|
+
not_implemented(__method__)
|
101
|
+
end
|
102
|
+
|
103
|
+
# A simple yes or no question
|
104
|
+
def confirm(_message)
|
105
|
+
not_implemented(__method__)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Let the user select one out of x items
|
109
|
+
# return value is the value of the option the user chose
|
110
|
+
def select(_message, _options)
|
111
|
+
not_implemented(__method__)
|
112
|
+
end
|
113
|
+
|
114
|
+
# Password input for the user, text field shouldn't show
|
115
|
+
# plain text
|
116
|
+
def password(_message)
|
117
|
+
not_implemented(__method__)
|
118
|
+
end
|
119
|
+
|
120
|
+
#####################################################
|
121
|
+
# @!group Abort helper methods
|
122
|
+
#####################################################
|
123
|
+
|
124
|
+
# Pass an exception to this method to exit the program
|
125
|
+
# using the given exception
|
126
|
+
# Use this method instead of user_error! if this error is
|
127
|
+
# unexpected, e.g. an invalid server response that shouldn't happen
|
128
|
+
def crash!(exception)
|
129
|
+
raise LhjCrash.new, exception.to_s
|
130
|
+
end
|
131
|
+
|
132
|
+
# Use this method to exit the program because of an user error
|
133
|
+
# e.g. app doesn't exist on the given Developer Account
|
134
|
+
# or invalid user credentials
|
135
|
+
# or scan tests fail
|
136
|
+
# This will show the error message, but doesn't show the full
|
137
|
+
# stack trace
|
138
|
+
# Basically this should be used when you actively catch the error
|
139
|
+
# and want to show a nice error message to the user
|
140
|
+
def user_error!(error_message, options = {})
|
141
|
+
raise LhjError.new(show_github_issues: options[:show_github_issues], error_info: options[:error_info]), error_message.to_s
|
142
|
+
end
|
143
|
+
|
144
|
+
# Use this method to exit the program because of a shell command
|
145
|
+
# failure -- the command returned a non-zero response. This does
|
146
|
+
# not specify the nature of the error. The error might be from a
|
147
|
+
# programming error, a user error, or an expected error because
|
148
|
+
# the user of the Fastfile doesn't have their environment set up
|
149
|
+
# properly. Because of this, when these errors occur, it means
|
150
|
+
# that the caller of the shell command did not adequate error
|
151
|
+
# handling and the caller error handling should be improved.
|
152
|
+
def shell_error!(error_message, options = {})
|
153
|
+
raise LhjShellError.new(options), error_message.to_s
|
154
|
+
end
|
155
|
+
|
156
|
+
# Use this method to exit the program because of a build failure
|
157
|
+
# that's caused by the source code of the user. Example for this
|
158
|
+
# is that gym will fail when the code doesn't compile or because
|
159
|
+
# settings for the project are incorrect.
|
160
|
+
# By using this method we'll have more accurate results about
|
161
|
+
# fastlane failures
|
162
|
+
def build_failure!(error_message, options = {})
|
163
|
+
raise LhjBuildFailure.new(options), error_message.to_s
|
164
|
+
end
|
165
|
+
|
166
|
+
# Use this method to exit the program because of a test failure
|
167
|
+
# that's caused by the source code of the user. Example for this
|
168
|
+
# is that scan will fail when the tests fail.
|
169
|
+
# By using this method we'll have more accurate results about
|
170
|
+
# fastlane failures
|
171
|
+
def test_failure!(error_message)
|
172
|
+
raise LhjTestFailure.new, error_message
|
173
|
+
end
|
174
|
+
|
175
|
+
# Use this method to exit the program because of terminal state
|
176
|
+
# that is neither the fault of fastlane, nor a problem with the
|
177
|
+
# user's input. Using this method instead of user_error! will
|
178
|
+
# avoid tracking this outcome as a fastlane failure.
|
179
|
+
#
|
180
|
+
# e.g. tests ran successfully, but no screenshots were found
|
181
|
+
#
|
182
|
+
# This will show the message, but hide the full stack trace.
|
183
|
+
def abort_with_message!(message)
|
184
|
+
raise LhjCommonException.new, message
|
185
|
+
end
|
186
|
+
|
187
|
+
#####################################################
|
188
|
+
# @!group Helpers
|
189
|
+
#####################################################
|
190
|
+
def not_implemented(method_name)
|
191
|
+
require_relative 'ui'
|
192
|
+
UI.user_error!("Current UI '#{self}' doesn't support method '#{method_name}'")
|
193
|
+
end
|
194
|
+
|
195
|
+
def to_s
|
196
|
+
self.class.name.split('::').last
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
class String
|
202
|
+
def deprecated
|
203
|
+
self.bold.blue
|
204
|
+
end
|
205
|
+
end
|
data/lib/lhj/ui/ui.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
module Lhj
|
2
|
+
class UI
|
3
|
+
class << self
|
4
|
+
attr_accessor(:ui_object)
|
5
|
+
|
6
|
+
def ui_object
|
7
|
+
require_relative 'implementations/shell'
|
8
|
+
@ui_object ||= Shell.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def method_missing(method_sym, *args, &_block)
|
12
|
+
# not using `responds` because we don't care about methods like .to_s and so on
|
13
|
+
require_relative 'interface'
|
14
|
+
interface_methods = Lhj::Interface.instance_methods - Object.instance_methods
|
15
|
+
UI.user_error!("Unknown method '#{method_sym}', supported #{interface_methods}") unless interface_methods.include?(method_sym)
|
16
|
+
|
17
|
+
self.ui_object.send(method_sym, *args)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Import all available implementations
|
24
|
+
Dir[File.dirname(__FILE__) + '/implementations/*.rb'].each do |file|
|
25
|
+
require_relative file
|
26
|
+
end
|
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
|
+
version: 0.1.8
|
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-
|
11
|
+
date: 2022-01-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: claide
|
@@ -118,6 +118,60 @@ 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
|
141
|
+
- !ruby/object:Gem::Dependency
|
142
|
+
name: colored
|
143
|
+
requirement: !ruby/object:Gem::Requirement
|
144
|
+
requirements:
|
145
|
+
- - ">="
|
146
|
+
- !ruby/object:Gem::Version
|
147
|
+
version: '0'
|
148
|
+
type: :runtime
|
149
|
+
prerelease: false
|
150
|
+
version_requirements: !ruby/object:Gem::Requirement
|
151
|
+
requirements:
|
152
|
+
- - ">="
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
version: '0'
|
155
|
+
- !ruby/object:Gem::Dependency
|
156
|
+
name: excon
|
157
|
+
requirement: !ruby/object:Gem::Requirement
|
158
|
+
requirements:
|
159
|
+
- - ">="
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: 0.71.0
|
162
|
+
- - "<"
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: 1.0.0
|
165
|
+
type: :runtime
|
166
|
+
prerelease: false
|
167
|
+
version_requirements: !ruby/object:Gem::Requirement
|
168
|
+
requirements:
|
169
|
+
- - ">="
|
170
|
+
- !ruby/object:Gem::Version
|
171
|
+
version: 0.71.0
|
172
|
+
- - "<"
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: 1.0.0
|
121
175
|
- !ruby/object:Gem::Dependency
|
122
176
|
name: faraday-cookie_jar
|
123
177
|
requirement: !ruby/object:Gem::Requirement
|
@@ -218,8 +272,13 @@ extra_rdoc_files: []
|
|
218
272
|
files:
|
219
273
|
- README.md
|
220
274
|
- bin/lhj
|
275
|
+
- lib/lhj/action/sh_helper.rb
|
221
276
|
- lib/lhj/command.rb
|
277
|
+
- lib/lhj/command/config.rb
|
278
|
+
- lib/lhj/command/config/info.rb
|
279
|
+
- lib/lhj/command/file_path.rb
|
222
280
|
- lib/lhj/command/head_import.rb
|
281
|
+
- lib/lhj/command/http.rb
|
223
282
|
- lib/lhj/command/init.rb
|
224
283
|
- lib/lhj/command/local/fetch.rb
|
225
284
|
- lib/lhj/command/local/filter.rb
|
@@ -233,6 +292,7 @@ files:
|
|
233
292
|
- lib/lhj/command/refactor_rename.rb
|
234
293
|
- lib/lhj/command/rename_image.rb
|
235
294
|
- lib/lhj/command/reverse_import.rb
|
295
|
+
- lib/lhj/command/sync_pod_repo.rb
|
236
296
|
- lib/lhj/command/template.rb
|
237
297
|
- lib/lhj/command/trans.rb
|
238
298
|
- lib/lhj/command/view.rb
|
@@ -244,6 +304,21 @@ files:
|
|
244
304
|
- lib/lhj/helper/trans_helper.rb
|
245
305
|
- lib/lhj/tools.rb
|
246
306
|
- lib/lhj/tools/version.rb
|
307
|
+
- lib/lhj/tree/directory_renderer.rb
|
308
|
+
- lib/lhj/tree/hash_walker.rb
|
309
|
+
- lib/lhj/tree/node.rb
|
310
|
+
- lib/lhj/tree/number_renderer.rb
|
311
|
+
- lib/lhj/tree/path_walker.rb
|
312
|
+
- lib/lhj/tree/tree.rb
|
313
|
+
- lib/lhj/ui/errors.rb
|
314
|
+
- lib/lhj/ui/errors/lhj_common_error.rb
|
315
|
+
- lib/lhj/ui/errors/lhj_crash.rb
|
316
|
+
- lib/lhj/ui/errors/lhj_error.rb
|
317
|
+
- lib/lhj/ui/errors/lhj_exception.rb
|
318
|
+
- lib/lhj/ui/errors/lhj_shell_error.rb
|
319
|
+
- lib/lhj/ui/implementations/shell.rb
|
320
|
+
- lib/lhj/ui/interface.rb
|
321
|
+
- lib/lhj/ui/ui.rb
|
247
322
|
homepage:
|
248
323
|
licenses:
|
249
324
|
- MIT
|