utils 0.68.0 → 0.69.0

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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +251 -18
  3. data/bin/ascii7 +28 -0
  4. data/bin/blameline +17 -0
  5. data/bin/changes +69 -5
  6. data/bin/classify +128 -7
  7. data/bin/code_comment +102 -104
  8. data/bin/commit_message +26 -2
  9. data/bin/create_cstags +18 -0
  10. data/bin/create_tags +10 -0
  11. data/bin/discover +38 -1
  12. data/bin/edit +14 -1
  13. data/bin/edit_wait +14 -0
  14. data/bin/enum +139 -15
  15. data/bin/git-empty +50 -0
  16. data/bin/git-versions +20 -0
  17. data/bin/json_check +15 -1
  18. data/bin/long_lines +11 -2
  19. data/bin/myex +38 -0
  20. data/bin/on_change +22 -0
  21. data/bin/path +21 -0
  22. data/bin/print_method +29 -1
  23. data/bin/probe +52 -4
  24. data/bin/rainbow +52 -0
  25. data/bin/rd2md +15 -0
  26. data/bin/search +83 -1
  27. data/bin/sedit +6 -0
  28. data/bin/serve +18 -3
  29. data/bin/ssh-tunnel +14 -2
  30. data/bin/strip_spaces +17 -9
  31. data/bin/sync_dir +48 -1
  32. data/bin/untest +19 -1
  33. data/bin/utils-utilsrc +42 -6
  34. data/bin/vcf2alias +33 -0
  35. data/bin/yaml_check +24 -2
  36. data/lib/utils/config_dir.rb +127 -0
  37. data/lib/utils/config_file.rb +445 -1
  38. data/lib/utils/editor.rb +215 -3
  39. data/lib/utils/finder.rb +127 -16
  40. data/lib/utils/grepper.rb +90 -1
  41. data/lib/utils/irb.rb +387 -39
  42. data/lib/utils/line_blamer.rb +28 -0
  43. data/lib/utils/line_formatter.rb +198 -0
  44. data/lib/utils/md5.rb +14 -0
  45. data/lib/utils/patterns.rb +77 -3
  46. data/lib/utils/probe_server.rb +302 -23
  47. data/lib/utils/ssh_tunnel_specification.rb +58 -0
  48. data/lib/utils/version.rb +1 -1
  49. data/lib/utils/xt/source_location_extension.rb +18 -6
  50. data/lib/utils.rb +3 -1
  51. data/tests/utils_test.rb +7 -1
  52. data/utils.gemspec +5 -5
  53. metadata +4 -6
  54. data/bin/number_files +0 -26
  55. data/lib/utils/xdg_config.rb +0 -10
  56. /data/{COPYING → LICENSE} +0 -0
@@ -1,27 +1,65 @@
1
1
  require 'unix_socks'
2
- require 'tins/xt'
3
2
  require 'term/ansicolor'
4
- class String
5
- include Term::ANSIColor
6
- end
7
3
 
8
4
  module Utils
9
5
  class ProcessJob
6
+ include Term::ANSIColor
7
+
8
+ # Initializes a new ProcessJob instance with the specified arguments and
9
+ # optional probe server.
10
+ #
11
+ # This method creates a process job object that can be enqueued for
12
+ # execution by a probe server. It assigns a unique job ID from the probe
13
+ # server if provided and stores the command arguments as an array.
14
+ #
15
+ # @param args [ Array ] the command arguments to be executed by the job
16
+ # @param probe_server [ Utils::ProbeServer, nil ] the probe server instance
17
+ # to use for generating job IDs
18
+ #
19
+ # @return [ Utils::ProcessJob ] a new ProcessJob instance configured with
20
+ # the provided arguments and server reference
10
21
  def initialize(args:, probe_server: nil)
11
- @id = probe_server&.next_job_id
12
- @args = Array(args)
22
+ @id = probe_server&.next_job_id
23
+ @args = Array(args)
13
24
  end
14
25
 
26
+ # Returns the unique identifier of the process job.
27
+ #
28
+ # @return [ Integer ] the job ID
15
29
  attr_reader :id
16
30
 
31
+ # The args reader method provides access to the arguments stored in the
32
+ # instance.
33
+ #
34
+ # @return [ Array ] the array of arguments
17
35
  attr_reader :args
18
36
 
37
+ # The ok method sets the success status of the process job.
38
+ #
39
+ # @param value [ TrueClass, FalseClass, nil ] the success status to set
19
40
  attr_writer :ok
20
41
 
42
+ # Returns the type identifier for the process job.
43
+ #
44
+ # This method provides a constant string value that identifies the object
45
+ # as a process job within the probe server system, facilitating type-based
46
+ # dispatch and handling.
47
+ #
48
+ # @return [ String ] the string 'process_job' indicating the object's type
21
49
  def type
22
50
  'process_job'
23
51
  end
24
52
 
53
+ # The ok method returns a character representation of the job's success
54
+ # status.
55
+ #
56
+ # This method provides a visual indicator of whether a process job has
57
+ # succeeded, failed, or is still in progress. It returns 'y' for successful
58
+ # jobs, 'n' for failed jobs, and '…' for jobs that are currently running or
59
+ # pending.
60
+ #
61
+ # @return [ String ] 'y' if the job succeeded, 'n' if it failed, or '…' if
62
+ # the status is unknown
25
63
  def ok
26
64
  case @ok
27
65
  when false then 'n'
@@ -30,24 +68,58 @@ module Utils
30
68
  end
31
69
  end
32
70
 
71
+ # The ok_colorize method applies color formatting to a string based on the
72
+ # success status.
73
+ #
74
+ # This method returns the input string wrapped with color codes to indicate
75
+ # whether the associated process job succeeded, failed, or is in progress.
76
+ # Successful jobs are highlighted in green, failed jobs in red, and pending
77
+ # jobs are returned without any color formatting.
78
+ #
79
+ # @param string [ String ] the string to be colorized
80
+ #
81
+ # @return [ String ] the colorized string or the original string if status is unknown
33
82
  def ok_colorize(string)
34
83
  case @ok
35
- when false then string.white.on_red
36
- when true then string.black.on_green
84
+ when false then white { on_red { string } }
85
+ when true then black { on_green { string } }
37
86
  else string
38
87
  end
39
88
  end
40
89
 
90
+ # The inspect method generates a colorized string representation of the
91
+ # process job.
92
+ #
93
+ # This method creates a formatted string that includes the job's unique
94
+ # identifier and its command arguments, with the status indicator
95
+ # color-coded based on whether the job succeeded, failed, or is pending.
96
+ #
97
+ # @return [ String ] a formatted string representation of the process job
98
+ # including its ID, arguments, and color-coded status indicator
41
99
  def inspect
42
100
  ok_colorize("#{id} #{args.map { |a| a.include?(' ') ? a.inspect : a } * ' '}")
43
101
  end
44
102
 
45
103
  alias to_s inspect
46
104
 
105
+ # The as_json method converts the process job object into a
106
+ # JSON-serializable hash.
107
+ #
108
+ # This method creates and returns a hash representation of the process job,
109
+ # containing its type, unique identifier, and command arguments.
110
+ #
111
+ # @return [ Hash ] a hash containing the type, id, and args of the process job
47
112
  def as_json(*)
48
113
  { type:, id:, args:, }
49
114
  end
50
115
 
116
+ # The to_json method converts the object to a JSON string representation.
117
+ #
118
+ # This method delegates to the as_json method to generate a hash representation
119
+ # of the object, then converts that hash to a JSON string using the
120
+ # standard JSON library's to_json method.
121
+ #
122
+ # @return [ String ] a JSON string representation of the object
51
123
  def to_json(*)
52
124
  as_json.to_json(*)
53
125
  end
@@ -55,15 +127,38 @@ module Utils
55
127
 
56
128
  class ProbeClient
57
129
  class EnvProxy
130
+ # The initialize method sets up a new instance with the provided server
131
+ # object.
132
+ #
133
+ # @param server [ UnixSocks::Server ] the server object to be assigned
134
+ # to the instance variable
58
135
  def initialize(server)
59
136
  @server = server
60
137
  end
61
138
 
139
+ # The []= method sets an environment variable value through the probe server.
140
+ #
141
+ # This method transmits a request to the probe server to set the specified
142
+ # environment variable key to the given value, then returns the updated
143
+ # environment value from the server's response.
144
+ #
145
+ # @param key [ String ] the environment variable key to set
146
+ # @param value [ String ] the value to assign to the environment variable
147
+ #
148
+ # @return [ String ] the updated environment variable value returned by the server
62
149
  def []=(key, value)
63
150
  response = @server.transmit_with_response(type: 'set_env', key:, value:)
64
151
  response.env
65
152
  end
66
153
 
154
+ # The [] method retrieves the value of an environment variable from the probe server.
155
+ #
156
+ # This method sends a request to the probe server to fetch the current value of the specified
157
+ # environment variable key and returns the corresponding value.
158
+ #
159
+ # @param key [ String ] the environment variable key to retrieve
160
+ #
161
+ # @return [ String ] the value of the specified environment variable
67
162
  def [](key)
68
163
  response = @server.transmit_with_response(type: 'get_env', key:)
69
164
  response.env
@@ -72,20 +167,59 @@ module Utils
72
167
  attr_reader :env
73
168
  end
74
169
 
170
+ # The initialize method sets up a new probe server instance.
171
+ #
172
+ # This method creates and configures a Unix domain socket server for
173
+ # handling probe jobs and communication. It initializes the server with a
174
+ # specific socket name and runtime directory, preparing it to listen for
175
+ # incoming connections and process jobs.
176
+ #
177
+ # @return [ Utils::ProbeServer ] a new probe server instance configured with
178
+ # the specified socket name and runtime directory
75
179
  def initialize
76
180
  @server = UnixSocks::Server.new(socket_name: 'probe.sock', runtime_dir: Dir.pwd)
77
181
  end
78
182
 
183
+ # The env method provides access to environment variable management through
184
+ # a proxy object.
185
+ #
186
+ # This method returns an EnvProxy instance that allows for setting and
187
+ # retrieving environment variables via the probe server communication
188
+ # channel.
189
+ #
190
+ # @return [ Utils::ProbeServer::EnvProxy ] a proxy object for environment
191
+ # variable operations
79
192
  def env
80
193
  EnvProxy.new(@server)
81
194
  end
82
195
 
196
+ # The enqueue method submits a new process job to the probe server for
197
+ # execution.
198
+ #
199
+ # This method transmits a process job request to the underlying Unix domain
200
+ # socket server, which then adds the job to the processing queue. The job
201
+ # includes the specified command arguments that will be executed by the
202
+ # probe server.
203
+ #
204
+ # @param args [ Array ] the command arguments to be executed by the process
205
+ # job
83
206
  def enqueue(args)
84
207
  @server.transmit({ type: 'process_job', args: })
85
208
  end
86
209
  end
87
210
 
88
211
  class ProbeServer
212
+ include Term::ANSIColor
213
+
214
+ # The initialize method sets up a new probe server instance.
215
+ #
216
+ # This method creates and configures the core components of the probe
217
+ # server, including initializing the Unix domain socket server for
218
+ # communication, setting up the job queue for processing tasks, and
219
+ # preparing the history tracking for completed jobs.
220
+ #
221
+ # @return [ Utils::ProbeServer ] a new probe server instance configured
222
+ # with the specified socket name and runtime directory
89
223
  def initialize
90
224
  @server = UnixSocks::Server.new(socket_name: 'probe.sock', runtime_dir: Dir.pwd)
91
225
  @history = [].freeze
@@ -93,15 +227,14 @@ module Utils
93
227
  @current_job_id = 0
94
228
  end
95
229
 
96
- def print(*msg)
97
- if msg.first !~ /^irb: warn: can't alias / # shut your god d*mn wh*re mouth
98
- super
99
- end
100
- end
101
-
230
+ # The start method initializes and begins operation of the probe server.
231
+ #
232
+ # This method sets up the probe server by starting a thread to process jobs
233
+ # from the queue and entering a receive loop to handle incoming requests.
234
+ # It also manages interrupt signals to enter interactive mode when needed.
102
235
  def start
103
236
  output_message "Starting probe server listening to #{@server.server_socket_path}.", type: :info
104
- work_loop = Thread.new do
237
+ Thread.new do
105
238
  loop do
106
239
  job = @jobs_queue.pop
107
240
  run_job job
@@ -125,6 +258,15 @@ module Utils
125
258
  end
126
259
  end
127
260
 
261
+ # The inspect method returns a string representation of the probe server
262
+ # instance.
263
+ #
264
+ # This method provides a concise overview of the probe server's state by
265
+ # displaying its type and the current size of the job queue, making it
266
+ # useful for debugging and monitoring purposes.
267
+ #
268
+ # @return [ String ] a formatted string containing the probe server identifier
269
+ # and the number of jobs currently in the queue
128
270
  def inspect
129
271
  "#<Probe #queue=#{@jobs_queue.size}>"
130
272
  end
@@ -134,6 +276,11 @@ module Utils
134
276
 
135
277
  annotate :shortcut
136
278
 
279
+ # The help method displays a formatted list of available commands and their
280
+ # descriptions.
281
+ #
282
+ # This method organizes and presents the documented commands along with their
283
+ # shortcuts and descriptions in a formatted table layout for easy reference.
137
284
  doc 'Display this help.'
138
285
  shortcut :h
139
286
  def help
@@ -141,13 +288,20 @@ module Utils
141
288
  docs_size = docs.map { |a| a.first.size }.max
142
289
  format = "%-#{docs_size}s %-3s %s"
143
290
  output_message [
144
- (format % %w[ command sho description ]).on_color(20).white
291
+ on_color(20) { white { format % %w[ command sho description ] } }
145
292
  ] << docs.map { |cmd, doc|
146
293
  shortcut = shortcut_of(cmd) and shortcut = "(#{shortcut})"
147
294
  format % [ cmd, shortcut, doc ]
148
295
  }
149
296
  end
150
297
 
298
+ # The job_enqueue method adds a new process job to the execution queue.
299
+ #
300
+ # This method creates a process job instance with the provided arguments
301
+ # and enqueues it for execution by the probe server. It provides feedback
302
+ # about the enqueued job through output messaging.
303
+ #
304
+ # @param args [ Array ] the command arguments to be executed by the process job
151
305
  doc 'Enqueue a new job with the argument array <args>.'
152
306
  shortcut :e
153
307
  def job_enqueue(args)
@@ -157,14 +311,29 @@ module Utils
157
311
  end
158
312
  alias enqueue job_enqueue
159
313
 
160
- doc 'Send the <signal> to the process that is working on the current job, if any.'
314
+ # The shutdown method terminates the probe server process immediately.
315
+ #
316
+ # This method outputs a warning message indicating that the server is being
317
+ # shut down forcefully and then exits the program with status code 23.
161
318
  doc 'Quit the server.'
162
319
  shortcut :q
163
320
  def shutdown
164
- output_message "Server was shutdown down – HARD!", type: :warn
321
+ output_message "Server was shutdown down manually!", type: :info
165
322
  exit 23
166
323
  end
167
324
 
325
+ # The job_repeat method re-executes a previously run job from the history.
326
+ #
327
+ # This method takes a job identifier and attempts to find the corresponding
328
+ # job in the server's execution history. If found, it enqueues a new
329
+ # instance of that job for execution with the same arguments as the
330
+ # original.
331
+ #
332
+ # @param job_id [ Integer, Utils::ProcessJob ] the identifier of the job to repeat
333
+ # or the job object itself
334
+ #
335
+ # @return [ TrueClass, FalseClass ] true if the job was found and re-enqueued,
336
+ # false otherwise
168
337
  doc 'Repeat the job with <job_id> or the last, it will be assigned a new id, though.'
169
338
  shortcut :r
170
339
  def job_repeat(job_id = @history.last)
@@ -177,12 +346,25 @@ module Utils
177
346
  end
178
347
  end
179
348
 
349
+ # The history_list method displays the list of previously executed jobs
350
+ # from the server's history.
351
+ #
352
+ # This method outputs all completed jobs that have been processed by the probe server,
353
+ # showing their identifiers and command arguments for review.
180
354
  doc 'List the history of run jobs.'
181
355
  shortcut :l
182
356
  def history_list
183
357
  output_message @history
184
358
  end
185
359
 
360
+ # The history_clear method clears all entries from the server's execution
361
+ # history.
362
+ #
363
+ # This method resets the internal history array to an empty state,
364
+ # effectively removing all records of previously executed jobs from the
365
+ # probe server.
366
+ #
367
+ # @return [ TrueClass ] always returns true after clearing the history
186
368
  doc 'Clear the history of run jobs.'
187
369
  def history_clear
188
370
  @history = []
@@ -190,28 +372,77 @@ module Utils
190
372
  end
191
373
 
192
374
  class LogWrapper < BasicObject
375
+ # The initialize method sets up a new instance with the provided server
376
+ # object and object.
377
+ #
378
+ # This method creates and configures a LogWrapper instance by storing
379
+ # references to the specified server and object parameters. It prepares
380
+ # the wrapper for use in logging environment variable operations while
381
+ # maintaining access to both the server for messaging and the underlying
382
+ # object for attribute access.
383
+ #
384
+ # @param server [ Utils::ProbeServer ] the probe server instance to be assigned
385
+ # @param object [ ENV ] the environment object to be wrapped
193
386
  def initialize(server, object)
194
387
  @server, @object = server, object
195
388
  end
196
389
 
390
+ # The []= method sets an environment variable value through the probe
391
+ # server.
392
+ #
393
+ # This method transmits a request to the probe server to set the
394
+ # specified environment variable key to the given value, then returns the
395
+ # updated environment value from the server's response.
396
+ #
397
+ # @param name [ String ] the environment variable key to set
398
+ # @param value [ String ] the value to assign to the environment variable
399
+ #
400
+ # @return [ String ] the updated environment variable value returned by
401
+ # the server
197
402
  def []=(name, value)
198
403
  name, value = name.to_s, value.to_s
199
404
  @server.output_message("Setting #{name}=#{value.inspect}.", type: :info)
200
405
  @object[name] = value
201
406
  end
202
407
 
408
+ # The method_missing method delegates calls to the wrapped object's
409
+ # methods.
410
+ #
411
+ # This method acts as a fallback handler that forwards undefined method
412
+ # calls to the internal object instance, enabling dynamic method dispatch
413
+ # while maintaining access to all available methods through the wrapper
414
+ # interface.
415
+ #
416
+ # @param a [ Array ] the arguments passed to the missing method
417
+ # @param b [ Proc ] the block passed to the missing method
418
+ #
419
+ # @return [ Object ] the result of the delegated method call on the
420
+ # wrapped object
203
421
  def method_missing(*a, &b)
204
422
  @object.__send__(*a, &b)
205
423
  end
206
424
  end
207
425
 
208
426
  doc "The environment of the server process, use env['a'] = 'b' and env['a']."
209
- memoize_method def env
427
+ # The env method provides access to the server's environment variables
428
+ # through a wrapped interface.
429
+ #
430
+ # This method returns a LogWrapper instance that allows for setting and
431
+ # retrieving environment variables while logging the operations. The
432
+ # wrapper maintains access to both the probe server for messaging and the
433
+ # underlying ENV object for attribute access.
434
+ #
435
+ # @return [ Utils::ProbeServer::LogWrapper ] a wrapped environment object
436
+ # for variable management
437
+ memoize method:
438
+ def env
210
439
  LogWrapper.new(self, ENV)
211
440
  end
212
441
 
213
442
  doc "Clear the terminal screen"
214
443
  shortcut :c
444
+ # The clear method clears the terminal screen by executing the clear
445
+ # command.
215
446
  def clear
216
447
  system "clear"
217
448
  end
@@ -220,22 +451,41 @@ module Utils
220
451
  alias_method shortcut, method_name
221
452
  end
222
453
 
454
+ # The next_job_id method increments and returns the current job identifier.
455
+ #
456
+ # This method maintains a sequential counter for job identification within
457
+ # the probe server, providing unique IDs for newly enqueued process jobs.
458
+ #
459
+ # @return [ Integer ] the next available job identifier in the sequence
223
460
  def next_job_id
224
461
  @current_job_id += 1
225
462
  end
226
463
 
464
+ # The output_message method displays a formatted message to standard output
465
+ # with optional styling based on the message type.
466
+ #
467
+ # This method takes a message and an optional type parameter to determine
468
+ # the formatting style for the output. It handles both string and array
469
+ # messages, converting arrays into multi-line strings. Different message
470
+ # types are styled using color codes and formatting attributes to provide
471
+ # visual distinction.
472
+ #
473
+ # @param msg [ String, Array ] the message to be displayed
474
+ # @param type [ Symbol ] the type of message for styling (success, info, warn, failure)
475
+ #
476
+ # @return [ Utils::ProbeServer ] returns self to allow for method chaining
227
477
  def output_message(msg, type: nil)
228
478
  msg.respond_to?(:to_a) and msg = msg.to_a * "\n"
229
479
  msg =
230
480
  case type
231
481
  when :success
232
- msg.on_color(22).white
482
+ on_color(22) { white { msg } }
233
483
  when :info
234
- msg.on_color(20).white
484
+ on_color(20) { white { msg } }
235
485
  when :warn
236
- msg.on_color(94).white
486
+ on_color(94) { white { msg } }
237
487
  when :failure
238
- msg.on_color(124).blink.white
488
+ on_color(124) { blink { white { msg } } }
239
489
  else
240
490
  msg
241
491
  end
@@ -246,6 +496,15 @@ module Utils
246
496
 
247
497
  private
248
498
 
499
+ # The run_job method executes a process job and updates the server's
500
+ # history with the result.
501
+ #
502
+ # This method takes a process job, outputs a message indicating it is
503
+ # running, executes the job using the system command, and then updates the
504
+ # job's success status. It also logs the outcome of the job execution and
505
+ # adds the completed job to the server's history for future reference.
506
+ #
507
+ # @param job [ Utils::ProcessJob ] the process job to be executed
249
508
  def run_job(job)
250
509
  output_message " → #{job.inspect} now running.", type: :info
251
510
  system(*cmd(job.args))
@@ -261,8 +520,16 @@ module Utils
261
520
  end
262
521
  @history += [ job.freeze ]
263
522
  @history.freeze
523
+ nil
264
524
  end
265
525
 
526
+ # The receive_loop method sets up and starts processing incoming jobs from
527
+ # the server.
528
+ #
529
+ # This method configures a background receiver on the probe server to handle
530
+ # incoming job requests. It processes different job types by delegating to
531
+ # appropriate handler methods, including enqueuing process jobs and managing
532
+ # environment variable operations through response handling.
266
533
  def receive_loop
267
534
  @server.receive_in_background do |job|
268
535
  case job.type
@@ -277,6 +544,18 @@ module Utils
277
544
  end
278
545
  end
279
546
 
547
+ # The cmd method constructs and returns a command array for execution.
548
+ #
549
+ # This method builds a command array by first checking for the presence of
550
+ # a BUNDLE_GEMFILE environment variable. If found, it appends the bundle
551
+ # exec command to the call array.
552
+ # It then adds the current script name ($0) followed by the provided job
553
+ # arguments to complete the command. The method also outputs an
554
+ # informational message about the command being executed.
555
+ #
556
+ # @param job [ Array ] the job arguments to be included in the command
557
+ #
558
+ # @return [ Array<String> ] the constructed command array ready for execution
280
559
  def cmd(job)
281
560
  call = []
282
561
  if ENV.key?('BUNDLE_GEMFILE') and bundle = `which bundle`.full?(:chomp)
@@ -1,33 +1,91 @@
1
1
  module Utils
2
2
  class SshTunnelSpecification
3
+ # Initializes a new SshTunnelSpecification instance by parsing the provided
4
+ # specification string.
5
+ #
6
+ # This method takes a specification string and extracts local and remote
7
+ # address/port combinations to configure the SSH tunnel parameters. The
8
+ # specification can take various formats including port-only
9
+ # specifications, localhost mappings, and full address:port combinations.
10
+ #
11
+ # @param spec_string [ String ] the specification string defining the SSH
12
+ # tunnel configuration
3
13
  def initialize(spec_string)
4
14
  interpret_spec(spec_string)
5
15
  end
6
16
 
17
+ # Returns the local address component of the SSH tunnel specification.
18
+ #
19
+ # @return [ String, nil ] the local address used for the SSH tunnel connection
7
20
  attr_reader :local_addr
8
21
 
22
+ # Returns the local port component of the SSH tunnel specification.
23
+ #
24
+ # @return [ Integer, nil ] the local port number used for the SSH tunnel connection
9
25
  attr_reader :local_port
10
26
 
27
+ # Returns the remote address component of the SSH tunnel specification.
28
+ #
29
+ # @return [ String, nil ] the remote address used for the SSH tunnel connection
11
30
  attr_reader :remote_addr
12
31
 
32
+ # Returns the remote port component of the SSH tunnel specification.
33
+ #
34
+ # @return [ Integer, nil ] the remote port number used for the SSH tunnel connection
13
35
  attr_reader :remote_port
14
36
 
37
+ # Returns an array representation of the SSH tunnel specification.
38
+ #
39
+ # This method combines the local and remote address/port components into a
40
+ # four-element array in the order: [local_addr, local_port, remote_addr, remote_port].
41
+ #
42
+ # @return [ Array<String, Integer, String, Integer> ] an array containing the
43
+ # local address, local port, remote address, and remote port values
15
44
  def to_a
16
45
  [ local_addr, local_port, remote_addr, remote_port ]
17
46
  end
18
47
 
48
+ # Checks if all components of the SSH tunnel specification are present and
49
+ # valid.
50
+ #
51
+ # This method verifies that all address and port components of the tunnel
52
+ # configuration have been set. If all components are present, it returns
53
+ # the string representation of the specification; otherwise, it returns
54
+ # nil.
55
+ #
56
+ # @return [ String, nil ] the string representation of the specification if all
57
+ # components are present, otherwise nil
19
58
  def valid?
20
59
  if to_a.all?
21
60
  to_s
22
61
  end
23
62
  end
24
63
 
64
+ # Returns a string representation of the SSH tunnel specification.
65
+ #
66
+ # This method combines the local address, local port, remote address, and
67
+ # remote port components into a single colon-separated string format.
68
+ #
69
+ # @return [ String ] a colon-separated string containing the tunnel specification
70
+ # in the format "local_addr:local_port:remote_addr:remote_port"
25
71
  def to_s
26
72
  to_a * ':'
27
73
  end
28
74
 
29
75
  private
30
76
 
77
+ # Parses a specification string to extract local and remote address/port
78
+ # components for SSH tunnel configuration.
79
+ #
80
+ # This method processes a given specification string and extracts the
81
+ # necessary components to configure an SSH tunnel, handling various format
82
+ # patterns including port-only specifications, localhost mappings, and full
83
+ # address:port combinations.
84
+ #
85
+ # @param spec_string [ String ] the specification string defining the SSH tunnel configuration
86
+ #
87
+ # @return [ Array<String, Integer, String, Integer> ] an array containing the local address,
88
+ # local port, remote address, and remote port values extracted from the specification
31
89
  def interpret_spec(spec_string)
32
90
  @local_addr, @local_port, @remote_addr, @remote_port =
33
91
  case spec_string
data/lib/utils/version.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Utils
2
2
  # Utils version
3
- VERSION = '0.68.0'
3
+ VERSION = '0.69.0'
4
4
  VERSION_ARRAY = VERSION.split('.').map(&:to_i) # :nodoc:
5
5
  VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
6
6
  VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
@@ -1,14 +1,26 @@
1
- require 'tins/deep_const_get'
2
-
3
1
  module Utils
4
2
  module Xt
5
3
  module SourceLocationExtension
6
- include Tins::DeepConstGet
7
-
4
+ # Regular expression to match Ruby class method signatures
5
+ # Matches patterns like "ClassName#method" or "ClassName.method"
8
6
  CLASS_METHOD_REGEXP = /\A([A-Z][\w:]+)([#.])([\w!?]+)/
9
7
 
8
+ # Regular expression to parse file path and line number information
9
+ # Matches patterns like "file.rb:123" or "file.rb:123-125"
10
10
  FILE_LINENUMBER_REGEXP = /\A\s*([^:]+):(\d+)-?(\d+)?/
11
11
 
12
+ # The source_location method determines the file path and line number
13
+ # information for an object.
14
+ #
15
+ # This method analyzes the object to extract source location details,
16
+ # handling different cases including string representations that contain
17
+ # file paths with line numbers, class method references, or simple file
18
+ # names. It returns an array containing the filename and line number,
19
+ # along with additional methods attached to the array for convenient
20
+ # access to location information.
21
+ #
22
+ # @return [ Array<String, Integer> ] an array containing the filename and line number,
23
+ # with additional methods attached for accessing filename, linenumber, and range properties
12
24
  def source_location
13
25
  filename = nil
14
26
  linenumber = nil
@@ -24,8 +36,8 @@ module Utils
24
36
  klassname = $1
25
37
  method_kind = $2 == '#' ? :instance_method : :method
26
38
  methodname = $3
27
- filename, linenumber =
28
- deep_const_get(klassname).__send__(method_kind, methodname).source_location
39
+ filename, linenumber = ::Object.const_get(klassname).
40
+ __send__(method_kind, methodname).source_location
29
41
  else
30
42
  filename = string
31
43
  end
data/lib/utils.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require 'tins/xt'
2
+
1
3
  module Utils
2
4
  require 'utils/version'
3
5
  require 'utils/md5'
@@ -9,7 +11,7 @@ module Utils
9
11
  require 'utils/probe_server'
10
12
  require 'utils/ssh_tunnel_specification'
11
13
  require 'utils/line_blamer'
12
- require 'utils/xdg_config'
14
+ require 'utils/config_dir'
13
15
 
14
16
  require 'utils/xt/source_location_extension'
15
17
  class ::Object