cli_class_tool 0.3.0 → 0.4.1
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/CHANGELOG +15 -1
- data/lib/cli_class_tool/common.rb +88 -48
- data/lib/cli_class_tool/utils.rb +11 -16
- data/lib/cli_class_tool.rb +10 -22
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 46f243576af73a6b5e4b56a097e4876377f2f4b0b2871ea013955d6eb75addd0
|
|
4
|
+
data.tar.gz: c44bcb2a54d9f1c3e9d5c19543805ba16f0bd224f5ece98acb02da3be071bf31
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2d04141ca190c6a98bd4481156708c9fbff7f9550324bee3612c283959ad94b90efaf33484fd77b6425f3320ecf6e2e8996422e307506f837f07785267cf5686
|
|
7
|
+
data.tar.gz: 761917986fb8e915fc189e2d4cee710bd39ac44c968b421cca4ee65affd0d07ec7de9455a3e46e15beb1ee09110e966c72bc2be01e9746254256e50067308d88
|
data/CHANGELOG
CHANGED
|
@@ -1,7 +1,21 @@
|
|
|
1
1
|
------------------
|
|
2
|
-
0.
|
|
2
|
+
0.4.1 (2026-06-05)
|
|
3
|
+
------------------
|
|
4
|
+
|
|
5
|
+
* Fix definition on RunError
|
|
6
|
+
* In DEBUG=1 mode, run() call stack depth can be tuned with DEBUG_CALL_STACK=<n>
|
|
7
|
+
|
|
8
|
+
------------------
|
|
9
|
+
0.4.0 (2026-06-05)
|
|
3
10
|
------------------
|
|
4
11
|
|
|
12
|
+
* Add basic initializer for Common
|
|
13
|
+
* Add Common::run() that will auto spawn a Common object and run the command with it.
|
|
14
|
+
* log function can now be used in alternate object or class by including/extending CLIClassTool::Logger
|
|
15
|
+
|
|
16
|
+
------------------
|
|
17
|
+
0.3.0 (2026-06-02)
|
|
18
|
+
------------------
|
|
5
19
|
|
|
6
20
|
* Enforce module/class namespaces for all action classes (potentially breaking change)
|
|
7
21
|
* Support automatic project-specific `RunError` generation with customized base error inheritance
|
|
@@ -1,39 +1,9 @@
|
|
|
1
1
|
# Main module for generic CLI class-based tools and utilities
|
|
2
2
|
module CLIClassTool
|
|
3
3
|
|
|
4
|
-
#
|
|
5
|
-
|
|
6
|
-
# Hook to enforce namespace loading at load time
|
|
7
|
-
def self.inherited(subclass)
|
|
8
|
-
if subclass.name
|
|
9
|
-
parts = subclass.name.to_s.split('::')
|
|
10
|
-
if parts.size <= 1
|
|
11
|
-
raise "CLIClassTool action classes must be defined within a named module/class namespace"
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
# List of available actions for this class
|
|
17
|
-
ACTION_LIST = [ :list_actions ]
|
|
18
|
-
# Help text for actions
|
|
19
|
-
ACTION_HELP = {}
|
|
20
|
-
|
|
4
|
+
# Logger for CLIClassTool::Common
|
|
5
|
+
module Logger
|
|
21
6
|
private
|
|
22
|
-
# Get the parent module of this class (e.g. KernelWork or XXX)
|
|
23
|
-
def parent_module
|
|
24
|
-
@parent_module ||= begin
|
|
25
|
-
if self.class.name.nil?
|
|
26
|
-
Object
|
|
27
|
-
else
|
|
28
|
-
parts = self.class.name.split('::')
|
|
29
|
-
if parts.size <= 1
|
|
30
|
-
raise "CLIClassTool action classes must be defined within a named module/class namespace"
|
|
31
|
-
end
|
|
32
|
-
Object.const_get(parts[0...-1].join('::'))
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
7
|
# Internal log method
|
|
38
8
|
# @param lvl [String] Log level string (colored)
|
|
39
9
|
# @param str [String] Message
|
|
@@ -50,28 +20,34 @@ module CLIClassTool
|
|
|
50
20
|
out.print("# " + lvl.to_s() + ": " + str + "\r")
|
|
51
21
|
end
|
|
52
22
|
|
|
53
|
-
#
|
|
54
|
-
#
|
|
55
|
-
# @param
|
|
56
|
-
# @param ret [String, nil] Optional return message
|
|
23
|
+
# Compute the parent module of an object or a class
|
|
24
|
+
#
|
|
25
|
+
# @param obj [Object,Class] Object or class to get the Module from
|
|
57
26
|
# @raise [StandardError] If command failed
|
|
58
|
-
def
|
|
59
|
-
if
|
|
60
|
-
|
|
61
|
-
|
|
27
|
+
def obj_to_parent_mod(obj)
|
|
28
|
+
return obj if obj.class == Module
|
|
29
|
+
|
|
30
|
+
theClass = obj.is_a?(Class) ? obj : obj.class
|
|
31
|
+
if theClass.name.nil?
|
|
32
|
+
return Object
|
|
33
|
+
else
|
|
34
|
+
parts = theClass.name.split('::')
|
|
35
|
+
if parts.size <= 1
|
|
36
|
+
raise "CLIClassTool action classes must be defined within a named module/class namespace"
|
|
62
37
|
end
|
|
63
|
-
|
|
38
|
+
return Object.const_get(parts[0...-1].join('::'))
|
|
64
39
|
end
|
|
65
40
|
end
|
|
66
41
|
|
|
67
|
-
#
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
42
|
+
# Get the parent module of this class (e.g. KernelWork or XXX)
|
|
43
|
+
def parent_module
|
|
44
|
+
return @parent_module if @parent_module != nil
|
|
45
|
+
|
|
46
|
+
@parent_module = obj_to_parent_mod(self)
|
|
47
|
+
return @parent_module
|
|
73
48
|
end
|
|
74
|
-
|
|
49
|
+
|
|
50
|
+
public
|
|
75
51
|
# Log a message with a specific level
|
|
76
52
|
#
|
|
77
53
|
# @param lvl [Symbol] Log level (:DEBUG, :INFO, :WARNING, :ERROR, etc.)
|
|
@@ -121,8 +97,68 @@ module CLIClassTool
|
|
|
121
97
|
end
|
|
122
98
|
return rep
|
|
123
99
|
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Common utility class providing logging, configuration, and shell execution methods
|
|
103
|
+
class Common
|
|
104
|
+
# Hook to enforce namespace loading at load time
|
|
105
|
+
def self.inherited(subclass)
|
|
106
|
+
if subclass.name
|
|
107
|
+
parts = subclass.name.to_s.split('::')
|
|
108
|
+
if parts.size <= 1
|
|
109
|
+
raise "CLIClassTool action classes must be defined within a named module/class namespace"
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# List of available actions for this class
|
|
115
|
+
ACTION_LIST = [ :list_actions ]
|
|
116
|
+
# Help text for actions
|
|
117
|
+
ACTION_HELP = {}
|
|
118
|
+
|
|
119
|
+
# Give the Logger mathods to Common
|
|
120
|
+
include CLIClassTool::Logger
|
|
121
|
+
|
|
122
|
+
private
|
|
123
|
+
# Raise error if system command failed
|
|
124
|
+
# @param check_err [Boolean] Whether to check for errors
|
|
125
|
+
# @param sysret [Process::Status] System return status
|
|
126
|
+
# @param ret [String, nil] Optional return message
|
|
127
|
+
# @raise [StandardError] If command failed
|
|
128
|
+
def abort_if_err(check_err, sysret, ret = nil)
|
|
129
|
+
if sysret.exitstatus != 0 && check_err == true
|
|
130
|
+
unless parent_module.const_defined?(:RunError)
|
|
131
|
+
raise "CLIClassTool parent module #{parent_module} must extend CLIClassTool::Utils to define RunError"
|
|
132
|
+
end
|
|
133
|
+
raise(parent_module::RunError.new(sysret.exitstatus, ret))
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Debug command execution
|
|
138
|
+
# @param cmd_type [String] Type of command (e.g., 'git')
|
|
139
|
+
# @param cmd [String] The command string
|
|
140
|
+
def cmd_debug(cmd_type, cmd)
|
|
141
|
+
log(:DEBUG, "Called from:")
|
|
142
|
+
depth=1
|
|
143
|
+
if ENV["DEBUG_CALL_DEPTH"].to_s() != ""
|
|
144
|
+
depth = ENV["DEBUG_CALL_DEPTH"].to_i()
|
|
145
|
+
end
|
|
146
|
+
[ depth, caller.length].min.downto(1){|x|
|
|
147
|
+
log(:DEBUG, " #{caller[x]}")
|
|
148
|
+
}
|
|
149
|
+
log(:DEBUG, "Running #{cmd_type} command '#{cmd}'")
|
|
150
|
+
end
|
|
151
|
+
|
|
124
152
|
|
|
125
153
|
public
|
|
154
|
+
# Simple initializer for a Common object
|
|
155
|
+
#
|
|
156
|
+
# @param path [String] Path to run commands from
|
|
157
|
+
def initialize(path=".", caller_obj=self)
|
|
158
|
+
@path = path
|
|
159
|
+
@parent_module = obj_to_parent_mod(caller_obj)
|
|
160
|
+
end
|
|
161
|
+
|
|
126
162
|
# Run a shell command
|
|
127
163
|
#
|
|
128
164
|
# @param cmd [String] Command to run
|
|
@@ -136,6 +172,10 @@ module CLIClassTool
|
|
|
136
172
|
return ret
|
|
137
173
|
end
|
|
138
174
|
|
|
175
|
+
def self.run(path, cmd, check_err = true)
|
|
176
|
+
obj = Common.new(path, self)
|
|
177
|
+
return obj.run(cmd, check_err)
|
|
178
|
+
end
|
|
139
179
|
# Run a shell command using system() (interactive)
|
|
140
180
|
#
|
|
141
181
|
# @param cmd [String] Command to run
|
data/lib/cli_class_tool/utils.rb
CHANGED
|
@@ -4,17 +4,16 @@ module CLIClassTool
|
|
|
4
4
|
|
|
5
5
|
# Hook called when a module extends CLIClassTool::Utils
|
|
6
6
|
def self.extended(base)
|
|
7
|
-
|
|
7
|
+
return if base == nil
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
CLIClassTool::RunError
|
|
9
|
+
lower_mod = base.name.split('::')[-1]
|
|
10
|
+
superclass_name = "#{base.name}::#{lower_mod}Error"
|
|
11
|
+
|
|
12
|
+
if ! Object.const_defined?(superclass_name)
|
|
13
|
+
raise("Could not find a base error class named #{superclass_name}")
|
|
15
14
|
end
|
|
16
15
|
|
|
17
|
-
CLIClassTool.define_run_error(base,
|
|
16
|
+
CLIClassTool.define_run_error(base, Object.const_get(superclass_name))
|
|
18
17
|
end
|
|
19
18
|
|
|
20
19
|
# Convert a string to an action symbol, validating it against available actions
|
|
@@ -117,14 +116,10 @@ module CLIClassTool
|
|
|
117
116
|
|
|
118
117
|
self._runOnClass(action, nil) {|kClass|
|
|
119
118
|
begin
|
|
120
|
-
#
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
# Use load factory method if defined, else fall back to .new
|
|
125
|
-
obj = kClass.respond_to?(:load) ? kClass.load() : kClass.new()
|
|
126
|
-
ret = obj.public_send(action, opts)
|
|
127
|
-
end
|
|
119
|
+
# Use load factory method if defined, else fall back to .new
|
|
120
|
+
obj = kClass.respond_to?(:load) ? kClass.load() : kClass.new()
|
|
121
|
+
ret = obj.public_send(action, opts)
|
|
122
|
+
|
|
128
123
|
return ret.is_a?(Integer) ? ret : 0
|
|
129
124
|
rescue caught_error_class => e
|
|
130
125
|
puts("# " + "ERROR".red().to_s() + ": Action '#{action}' failed: #{e.message}")
|
data/lib/cli_class_tool.rb
CHANGED
|
@@ -1,31 +1,19 @@
|
|
|
1
1
|
module CLIClassTool
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
def self.define_run_error(parent_module, superclass)
|
|
3
|
+
klass = Class.new(superclass)
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
@output = output
|
|
8
|
-
super("Command failed with exit status #{err_code}#{output ? "\n#{output}" : ''}")
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def self.define_run_error(parent_module, superclass = CLIClassTool::RunError)
|
|
13
|
-
klass = Class.new(superclass)
|
|
14
|
-
|
|
15
|
-
if !(superclass <= CLIClassTool::RunError)
|
|
16
|
-
klass.class_eval do
|
|
17
|
-
attr_reader :err_code, :output
|
|
5
|
+
klass.class_eval do
|
|
6
|
+
attr_reader :err_code, :msg
|
|
18
7
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
8
|
+
def initialize(err_code, output = nil)
|
|
9
|
+
@err_code = err_code
|
|
10
|
+
@msg = output
|
|
11
|
+
super("Command failed with exit status #{err_code}")
|
|
12
|
+
end
|
|
23
13
|
end
|
|
24
|
-
|
|
14
|
+
parent_module.const_set(:RunError, klass)
|
|
25
15
|
end
|
|
26
16
|
|
|
27
|
-
parent_module.const_set(:RunError, klass)
|
|
28
|
-
end
|
|
29
17
|
end
|
|
30
18
|
|
|
31
19
|
require_relative 'cli_class_tool/string'
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cli_class_tool
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nicolas Morey
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-06-
|
|
10
|
+
date: 2026-06-05 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: rake
|