lhj-tools 0.1.6 → 0.1.10
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/lhj/action/sh_helper.rb +138 -0
- data/lib/lhj/command/config/info.rb +67 -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 +38 -16
- 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 +1 -1
- data/lib/lhj/command/oss/list.rb +1 -1
- data/lib/lhj/command/oss/upload.rb +1 -1
- data/lib/lhj/command/refactor_rename.rb +1 -1
- data/lib/lhj/command/rename_image.rb +1 -1
- data/lib/lhj/command/sync_pod_repo.rb +153 -0
- data/lib/lhj/command/trans.rb +1 -1
- data/lib/lhj/command/yapi/formatters/base.rb +15 -0
- data/lib/lhj/command/yapi/formatters/command_context.rb +23 -0
- data/lib/lhj/command/yapi/formatters/service.rb +23 -0
- data/lib/lhj/command/yapi.rb +136 -98
- data/lib/lhj/command.rb +27 -5
- data/lib/lhj/tools/version.rb +1 -1
- data/lib/lhj/tools.rb +1 -0
- data/lib/lhj/tree/hash_walker.rb +1 -1
- data/lib/lhj/tree/path_walker.rb +1 -2
- data/lib/lhj/tree/tree.rb +5 -5
- 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 +54 -2
@@ -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.10
|
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-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: claide
|
@@ -138,6 +138,40 @@ dependencies:
|
|
138
138
|
- - "<"
|
139
139
|
- !ruby/object:Gem::Version
|
140
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: '1.2'
|
148
|
+
type: :runtime
|
149
|
+
prerelease: false
|
150
|
+
version_requirements: !ruby/object:Gem::Requirement
|
151
|
+
requirements:
|
152
|
+
- - '='
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
version: '1.2'
|
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
|
141
175
|
- !ruby/object:Gem::Dependency
|
142
176
|
name: faraday-cookie_jar
|
143
177
|
requirement: !ruby/object:Gem::Requirement
|
@@ -238,8 +272,13 @@ extra_rdoc_files: []
|
|
238
272
|
files:
|
239
273
|
- README.md
|
240
274
|
- bin/lhj
|
275
|
+
- lib/lhj/action/sh_helper.rb
|
241
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
|
242
280
|
- lib/lhj/command/head_import.rb
|
281
|
+
- lib/lhj/command/http.rb
|
243
282
|
- lib/lhj/command/init.rb
|
244
283
|
- lib/lhj/command/local/fetch.rb
|
245
284
|
- lib/lhj/command/local/filter.rb
|
@@ -253,10 +292,14 @@ files:
|
|
253
292
|
- lib/lhj/command/refactor_rename.rb
|
254
293
|
- lib/lhj/command/rename_image.rb
|
255
294
|
- lib/lhj/command/reverse_import.rb
|
295
|
+
- lib/lhj/command/sync_pod_repo.rb
|
256
296
|
- lib/lhj/command/template.rb
|
257
297
|
- lib/lhj/command/trans.rb
|
258
298
|
- lib/lhj/command/view.rb
|
259
299
|
- lib/lhj/command/yapi.rb
|
300
|
+
- lib/lhj/command/yapi/formatters/base.rb
|
301
|
+
- lib/lhj/command/yapi/formatters/command_context.rb
|
302
|
+
- lib/lhj/command/yapi/formatters/service.rb
|
260
303
|
- lib/lhj/config.rb
|
261
304
|
- lib/lhj/helper/local_config.rb
|
262
305
|
- lib/lhj/helper/oss_config.rb
|
@@ -270,6 +313,15 @@ files:
|
|
270
313
|
- lib/lhj/tree/number_renderer.rb
|
271
314
|
- lib/lhj/tree/path_walker.rb
|
272
315
|
- lib/lhj/tree/tree.rb
|
316
|
+
- lib/lhj/ui/errors.rb
|
317
|
+
- lib/lhj/ui/errors/lhj_common_error.rb
|
318
|
+
- lib/lhj/ui/errors/lhj_crash.rb
|
319
|
+
- lib/lhj/ui/errors/lhj_error.rb
|
320
|
+
- lib/lhj/ui/errors/lhj_exception.rb
|
321
|
+
- lib/lhj/ui/errors/lhj_shell_error.rb
|
322
|
+
- lib/lhj/ui/implementations/shell.rb
|
323
|
+
- lib/lhj/ui/interface.rb
|
324
|
+
- lib/lhj/ui/ui.rb
|
273
325
|
homepage:
|
274
326
|
licenses:
|
275
327
|
- MIT
|