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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b709fe8b17a110ea17968fb9d7d4ff45e2ceac57bed76c3dcda67438880dcdc4
4
- data.tar.gz: 1ff6831f0c5bfbc9d54d8dac31e18fdad3003ec0d527bfb3999e11a472b1591b
3
+ metadata.gz: 46f243576af73a6b5e4b56a097e4876377f2f4b0b2871ea013955d6eb75addd0
4
+ data.tar.gz: c44bcb2a54d9f1c3e9d5c19543805ba16f0bd224f5ece98acb02da3be071bf31
5
5
  SHA512:
6
- metadata.gz: f408128eb985f8ad45949c452be46aa55edc028f1dc060c2870afdbea358016258071e0cc8aadf155e867c0f8e7be4295e8045c699eb0f82c501feaeb9b7502b
7
- data.tar.gz: 75d8bbfd502b9a331be9c57e25b7f824b2bf1d24c94f6fe477f64f2078dde1a76911b4964b0bdcf531098f895a753556778571f0a4354e1d2b733b1fedc56212
6
+ metadata.gz: 2d04141ca190c6a98bd4481156708c9fbff7f9550324bee3612c283959ad94b90efaf33484fd77b6425f3320ecf6e2e8996422e307506f837f07785267cf5686
7
+ data.tar.gz: 761917986fb8e915fc189e2d4cee710bd39ac44c968b421cca4ee65affd0d07ec7de9455a3e46e15beb1ee09110e966c72bc2be01e9746254256e50067308d88
data/CHANGELOG CHANGED
@@ -1,7 +1,21 @@
1
1
  ------------------
2
- 0.3.0 (2026-06-02)
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
- # Common utility class providing logging, configuration, and shell execution methods
5
- class Common
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
- # Raise error if system command failed
54
- # @param check_err [Boolean] Whether to check for errors
55
- # @param sysret [Process::Status] System return status
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 abort_if_err(check_err, sysret, ret = nil)
59
- if sysret.exitstatus != 0 && check_err == true
60
- unless parent_module.const_defined?(:RunError)
61
- raise "CLIClassTool parent module #{parent_module} must extend CLIClassTool::Utils to define RunError"
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
- raise(parent_module::RunError.new(sysret.exitstatus, ret))
38
+ return Object.const_get(parts[0...-1].join('::'))
64
39
  end
65
40
  end
66
41
 
67
- # Debug command execution
68
- # @param cmd_type [String] Type of command (e.g., 'git')
69
- # @param cmd [String] The command string
70
- def cmd_debug(cmd_type, cmd)
71
- log(:DEBUG, "Called from #{caller[1]}")
72
- log(:DEBUG, "Running #{cmd_type} command '#{cmd}'")
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
- protected
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
@@ -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
- possible_name = base.name ? "#{base.name}Error" : nil
7
+ return if base == nil
8
8
 
9
- superclass = if possible_name && Object.const_defined?(possible_name)
10
- Object.const_get(possible_name)
11
- elsif base.const_defined?(:Error)
12
- base.const_get(:Error)
13
- else
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, superclass)
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
- # Some class have their own execAction, because object creation might be tricky.
121
- if kClass.respond_to?(:execAction)
122
- ret = kClass.execAction(opts, action)
123
- else
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}")
@@ -1,31 +1,19 @@
1
1
  module CLIClassTool
2
- class RunError < StandardError
3
- attr_reader :err_code, :output
2
+ def self.define_run_error(parent_module, superclass)
3
+ klass = Class.new(superclass)
4
4
 
5
- def initialize(err_code, output = nil)
6
- @err_code = err_code
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
- def initialize(err_code, output = nil)
20
- @err_code = err_code
21
- @output = output
22
- super("Command failed with exit status #{err_code}#{output ? "\n#{output}" : ''}")
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
- end
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.3.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-02 00:00:00.000000000 Z
10
+ date: 2026-06-05 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rake