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.
- checksums.yaml +4 -4
- data/README.md +251 -18
- data/bin/ascii7 +28 -0
- data/bin/blameline +17 -0
- data/bin/changes +69 -5
- data/bin/classify +128 -7
- data/bin/code_comment +102 -104
- data/bin/commit_message +26 -2
- data/bin/create_cstags +18 -0
- data/bin/create_tags +10 -0
- data/bin/discover +38 -1
- data/bin/edit +14 -1
- data/bin/edit_wait +14 -0
- data/bin/enum +139 -15
- data/bin/git-empty +50 -0
- data/bin/git-versions +20 -0
- data/bin/json_check +15 -1
- data/bin/long_lines +11 -2
- data/bin/myex +38 -0
- data/bin/on_change +22 -0
- data/bin/path +21 -0
- data/bin/print_method +29 -1
- data/bin/probe +52 -4
- data/bin/rainbow +52 -0
- data/bin/rd2md +15 -0
- data/bin/search +83 -1
- data/bin/sedit +6 -0
- data/bin/serve +18 -3
- data/bin/ssh-tunnel +14 -2
- data/bin/strip_spaces +17 -9
- data/bin/sync_dir +48 -1
- data/bin/untest +19 -1
- data/bin/utils-utilsrc +42 -6
- data/bin/vcf2alias +33 -0
- data/bin/yaml_check +24 -2
- data/lib/utils/config_dir.rb +127 -0
- data/lib/utils/config_file.rb +445 -1
- data/lib/utils/editor.rb +215 -3
- data/lib/utils/finder.rb +127 -16
- data/lib/utils/grepper.rb +90 -1
- data/lib/utils/irb.rb +387 -39
- data/lib/utils/line_blamer.rb +28 -0
- data/lib/utils/line_formatter.rb +198 -0
- data/lib/utils/md5.rb +14 -0
- data/lib/utils/patterns.rb +77 -3
- data/lib/utils/probe_server.rb +302 -23
- data/lib/utils/ssh_tunnel_specification.rb +58 -0
- data/lib/utils/version.rb +1 -1
- data/lib/utils/xt/source_location_extension.rb +18 -6
- data/lib/utils.rb +3 -1
- data/tests/utils_test.rb +7 -1
- data/utils.gemspec +5 -5
- metadata +4 -6
- data/bin/number_files +0 -26
- data/lib/utils/xdg_config.rb +0 -10
- /data/{COPYING → LICENSE} +0 -0
data/bin/code_comment
CHANGED
@@ -1,15 +1,79 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Generate YARD comments for Ruby methods using LLM assistance
|
4
|
+
#
|
5
|
+
# Usage:
|
6
|
+
# code_comment path/to/file.rb:line_number # Generate comment for method at line
|
7
|
+
#
|
8
|
+
# This script analyzes Ruby source code and generates high-quality YARD comments
|
9
|
+
# for methods using an LLM (via Ollama). It examines the surrounding context to
|
10
|
+
# identify method definitions and provides comprehensive documentation including
|
11
|
+
# descriptions, parameters, return values, and exceptions.
|
12
|
+
#
|
13
|
+
# Requires:
|
14
|
+
# - Git repository with Ruby files in lib/, spec/, or test/ directories
|
15
|
+
# - Ollama server running locally or accessible via OLLAMA_URL / OLLAMA_HOST
|
16
|
+
# - Configuration files in ~/.config/code_comment/
|
17
|
+
# - system.txt: System prompt for LLM
|
18
|
+
# - prompt.txt: Template for comment generation
|
19
|
+
# - client.json: Ollama client settings
|
20
|
+
# - options.json: Generation options (temperature, etc.)
|
21
|
+
#
|
22
|
+
# Environment variables:
|
23
|
+
# OLLAMA_URL: Base URL of Ollama server
|
24
|
+
# OLLAMA_MODEL: Model to use (default: llama3.1)
|
25
|
+
# XDG_CONFIG_HOME: Custom config directory location
|
26
|
+
# DEBUG: Set to 1 for verbose output and debug.log creation
|
27
|
+
#
|
28
|
+
# Examples:
|
29
|
+
# code_comment app/models/user.rb:42 # Document method at line 42
|
30
|
+
# code_comment lib/api/client.rb:15 # Document method at line 15
|
2
31
|
|
3
32
|
require 'ollama'
|
4
33
|
include Ollama
|
5
34
|
require 'utils'
|
6
|
-
include Utils::XDGConfig
|
7
35
|
|
36
|
+
META_METHOD = /(
|
37
|
+
(class_)? # Optional "class_" prefix
|
38
|
+
attr( # "attr" keyword
|
39
|
+
_reader| # reader variant
|
40
|
+
_writer| # writer variant
|
41
|
+
_accessor # accessor variant
|
42
|
+
)? # Optional variant
|
43
|
+
| # OR
|
44
|
+
dsl_(accessor|reader) # DSL accessor patterns
|
45
|
+
| # OR
|
46
|
+
constant # Constant definitions
|
47
|
+
| # OR
|
48
|
+
config # config settings
|
49
|
+
| # OR
|
50
|
+
(instance_)? # Optional "instance_" prefix
|
51
|
+
thread( # "thread" keyword
|
52
|
+
_local| # local variant
|
53
|
+
_global # global variant
|
54
|
+
)? # Optional variant
|
55
|
+
)\s+:/x
|
56
|
+
|
57
|
+
# Fetches the method definition from a given filename and line number.
|
58
|
+
#
|
59
|
+
# This method retrieves the source code of a method by analyzing the file
|
60
|
+
# location and line number provided. It attempts to identify the method
|
61
|
+
# definition by examining the surrounding context, including handling
|
62
|
+
# private and protected method declarations.
|
63
|
+
#
|
64
|
+
# @param filename_linenumber [ Object ] an object that responds to #source_location
|
65
|
+
# and provides filename and line number information
|
66
|
+
#
|
67
|
+
# @return [ String ] the source code of the method definition, or an empty string
|
68
|
+
# if the method cannot be determined
|
8
69
|
def fetch_method(filename_linenumber)
|
9
70
|
result = ''
|
10
71
|
source_location = filename_linenumber.source_location
|
11
72
|
lf = Tins::LinesFile.for_filename(source_location.filename, source_location.linenumber)
|
12
|
-
if
|
73
|
+
if lf.line =~ META_METHOD
|
74
|
+
return lf.line
|
75
|
+
end
|
76
|
+
if spaces = lf.match_backward(/^(\s*?)(\S.*?\s+)?def\s+/)&.first
|
13
77
|
line_number_begin = lf.line_number
|
14
78
|
lf.match_forward(/^#{spaces}end/)
|
15
79
|
line_number_end = lf.line_number
|
@@ -21,134 +85,67 @@ def fetch_method(filename_linenumber)
|
|
21
85
|
result
|
22
86
|
end
|
23
87
|
|
24
|
-
def fetch_file(filename_linenumber)
|
25
|
-
source_location = filename_linenumber.source_location
|
26
|
-
File.read(source_location.filename)
|
27
|
-
end
|
28
|
-
|
29
88
|
filename_linenumber = ARGV.shift or fail "require file_name as second argument"
|
89
|
+
config = Utils::ConfigDir.new('code_comment', env_var: 'XDG_CONFIG_HOME')
|
30
90
|
method = fetch_method(filename_linenumber)
|
31
91
|
method_indent = method[/\A( *)/, 1].size
|
32
|
-
#file = fetch_file(filename_linenumber)
|
33
92
|
files = Dir['{lib,spec,test}/**/*.rb']
|
34
93
|
base_url = ENV['OLLAMA_URL'] || 'http://%s' % ENV.fetch('OLLAMA_HOST')
|
35
94
|
model = ENV.fetch('OLLAMA_MODEL', 'llama3.1')
|
36
|
-
#file = File.read(file_name)
|
37
95
|
#call_sites = %x(cscope -L -3 "#{method_name}" $(find . -name '*.rb') | awk '{ print $1 ":" $3 }').lines.map(&:chomp).uniq
|
38
96
|
#methods = call_sites.map { fetch_method(_1) } * ?\n
|
39
97
|
|
40
|
-
|
41
|
-
Documenting Code with YARD
|
42
|
-
|
43
|
-
By default, YARD is compatible with the same RDoc syntax most Ruby developers
|
44
|
-
are already familiar with. However, one of the biggest advantages of YARD is
|
45
|
-
the extended meta-data syntax, commonly known as "tags", that you can use to
|
46
|
-
express small bits of information in a structured and formal manner. While RDoc
|
47
|
-
syntax expects you to describe your method in a completely free-form manner,
|
48
|
-
YARD recommends declaring your parameters, return types, etc. with the @tag
|
49
|
-
syntax, which makes outputting the documentation more consistent and easier to
|
50
|
-
read. Consider the RDoc documentation for a method to_format:
|
51
|
-
|
52
|
-
# Converts the object into textual markup given a specific `format`
|
53
|
-
# (defaults to `:html`)
|
54
|
-
#
|
55
|
-
# == Parameters:
|
56
|
-
# format::
|
57
|
-
# A Symbol declaring the format to convert the object to. This
|
58
|
-
# can be `:text` or `:html`.
|
59
|
-
#
|
60
|
-
# == Returns:
|
61
|
-
# A string representing the object in a specified
|
62
|
-
# format.
|
63
|
-
#
|
64
|
-
def to_format(format = :html)
|
65
|
-
# format the object
|
66
|
-
end
|
67
|
-
|
68
|
-
While this may seem easy enough to read and understand, it's hard for a machine
|
69
|
-
to properly pull this data back out of our documentation. Also we've tied our
|
70
|
-
markup to our content, and now our documentation becomes hard to maintain if we
|
71
|
-
decide later to change our markup style (maybe we don't want the ":" suffix on
|
72
|
-
our headers anymore).
|
73
|
-
|
74
|
-
In YARD, we would simply define our method as:
|
75
|
-
|
76
|
-
# Converts the object into textual markup given a specific format.
|
77
|
-
#
|
78
|
-
# @param format [Symbol] the format type, `:text` or `:html`
|
79
|
-
# @return [String] the object converted into the expected format.
|
80
|
-
# @raise [CannotFormatException] the object cannot be formatted
|
81
|
-
def to_format(format = :html)
|
82
|
-
# format the object
|
83
|
-
end
|
84
|
-
|
85
|
-
Using tags we can add semantic metadata to our code without worrying about
|
86
|
-
presentation. YARD will handle presentation for us when we decide to generate
|
87
|
-
documentation later.
|
88
|
-
EOT
|
89
|
-
|
90
|
-
system = <<EOT
|
98
|
+
default_system = <<EOT
|
91
99
|
Provide high-quality YARD comments for the given Ruby method, including a brief
|
92
100
|
description of its purpose, parameters, raised exceptions (and why), and
|
93
101
|
return values, assuming an expert-level understanding of the programming
|
94
102
|
concepts involved.
|
95
103
|
EOT
|
96
|
-
system =
|
104
|
+
system = config.read('system.txt', default: default_system)
|
97
105
|
|
98
|
-
|
106
|
+
file_contents = files.map { _1 + ":\n" + File.read(_1) } * ?\n
|
107
|
+
default_prompt = <<EOT
|
99
108
|
Look at this code to document it:
|
100
109
|
|
101
|
-
|
110
|
+
%{file_contents}
|
102
111
|
|
103
112
|
Here's an example for how you should document a method.
|
104
113
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
# bar.foo("blub", 4) { |a, b| … } #=> …
|
120
|
-
#
|
121
|
-
# @return [ ProcessResult ]
|
122
|
-
def foo(first, second, third: false, &block)
|
123
|
-
block or raise ArgumentError, 'no &block'
|
124
|
-
a = first * 2
|
125
|
-
if second < 0
|
126
|
-
raise ArgumentError, 'too small'
|
127
|
-
end
|
128
|
-
b = "foo" * second
|
129
|
-
if third
|
130
|
-
a = a * b
|
131
|
-
end
|
132
|
-
block_result = block.(a, b)
|
133
|
-
result = process block_result
|
134
|
-
return result
|
135
|
-
end
|
114
|
+
# The foo method computes the bar result by processing…
|
115
|
+
# then it returns the result.
|
116
|
+
#
|
117
|
+
# @param first [ String ] the foo string
|
118
|
+
# @param second [ Integer ] the number of bars lengthy detailed mutltiline
|
119
|
+
# detailed explanation including a newline.
|
120
|
+
# @param third [ TrueClass, FalseClass ]
|
121
|
+
#
|
122
|
+
# @yield [ a, b ]
|
123
|
+
#
|
124
|
+
# @raise [ ArgumentError ] if block argument wasn't provided
|
125
|
+
# @raise [ ArgumentError ] if second parameter was too small.
|
126
|
+
#
|
127
|
+
# @return [ ProcessResult ]
|
136
128
|
|
137
129
|
And this is the method you should document:
|
138
130
|
|
139
|
-
|
131
|
+
%{method}
|
140
132
|
|
141
133
|
Output a YARD comment for this method:
|
142
134
|
|
143
135
|
Format requirements:
|
144
136
|
|
145
|
-
1. Focus on providing a description of the method's purpose
|
146
|
-
|
147
|
-
|
148
|
-
|
137
|
+
1. Focus on providing a description of the method's purpose
|
138
|
+
without including any code snippets.
|
139
|
+
2. You should ommit the @raise if you are not sure.
|
140
|
+
3. Never use `, `ruby, ```, ```ruby in your response.
|
141
|
+
4. Never add any other remarks or explanation to your response.
|
142
|
+
5. Start each line of your comment with a single # character.
|
149
143
|
EOT
|
144
|
+
prompt = config.read('prompt.txt', default: default_prompt) % {
|
145
|
+
method:, file_contents:,
|
146
|
+
}
|
150
147
|
|
151
|
-
|
148
|
+
default_options = JSON(
|
152
149
|
#repeat_penalty: 1.8,
|
153
150
|
num_ctx: 16384,
|
154
151
|
num_predict: 512,
|
@@ -159,6 +156,11 @@ options = Ollama::Options.new(
|
|
159
156
|
min_p: 0.1,
|
160
157
|
)
|
161
158
|
|
159
|
+
client_config = Client::Config.load_from_json config + 'client.json'
|
160
|
+
client_config.base_url = base_url
|
161
|
+
ollama = Client.configure_with(client_config)
|
162
|
+
options = JSON.parse(config.read('options.json', default: default_options))
|
163
|
+
|
162
164
|
if ENV['DEBUG'].to_i == 1
|
163
165
|
File.open('debug.log', ?w) do |log|
|
164
166
|
log.puts "system:\n#{system}"
|
@@ -168,9 +170,5 @@ if ENV['DEBUG'].to_i == 1
|
|
168
170
|
end
|
169
171
|
end
|
170
172
|
|
171
|
-
config = xdg_config('code_comment')
|
172
|
-
client_config = Client::Config.load_from_json "#{config}/client.json"
|
173
|
-
client_config.base_url = base_url
|
174
|
-
ollama = Client.configure_with(client_config)
|
175
173
|
response = ollama.generate(model:, system:, prompt:, options:, stream: false, think: false).response
|
176
174
|
puts response.gsub(/^/) { ' ' * method_indent }
|
data/bin/commit_message
CHANGED
@@ -1,9 +1,33 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Git Commit Message Generator
|
4
|
+
#
|
5
|
+
# Generates AI-powered commit messages based on git changes using Ollama.
|
6
|
+
# Reads configuration from $XDG_CONFIG_HOME/commit_message/ directory.
|
7
|
+
#
|
8
|
+
# Usage:
|
9
|
+
# commit_message
|
10
|
+
#
|
11
|
+
# The script automatically:
|
12
|
+
# - Determines current git branch name
|
13
|
+
# - Loads configuration files (client.json, options.json, system.txt, prompt.txt)
|
14
|
+
# - Generates commit message using ollama_cli with the current diff as input
|
15
|
+
#
|
16
|
+
# Requirements:
|
17
|
+
# - Git repository in current directory
|
18
|
+
# - ollama_cli tool installed
|
19
|
+
# - Ollama server running
|
20
|
+
# - Configuration files in $XDG_CONFIG_HOME/commit_message/
|
21
|
+
#
|
22
|
+
# Configuration files:
|
23
|
+
# - client.json: Ollama API client configuration
|
24
|
+
# - options.json: Generation options
|
25
|
+
# - system.txt: System prompt for AI model
|
26
|
+
# - prompt.txt: Commit message template, contains %{branch} and %{stdin}
|
2
27
|
|
3
28
|
require 'utils'
|
4
|
-
include Utils::XDGConfig
|
5
29
|
|
6
|
-
config =
|
30
|
+
config = Utils::ConfigDir.new('commit_message', env_var: 'XDG_CONFIG_HOME')
|
7
31
|
|
8
32
|
branch = `git rev-parse --abbrev-ref HEAD`.chomp
|
9
33
|
exec 'ollama_cli', '-c', "#{config}/client.json",
|
data/bin/create_cstags
CHANGED
@@ -1,4 +1,22 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Create cscope database for project files
|
4
|
+
#
|
5
|
+
# Usage:
|
6
|
+
# create_cstags # Generate cscope.out database in current directory
|
7
|
+
#
|
8
|
+
# This script generates a cscope database (cscope.out) by collecting all
|
9
|
+
# project files and building an index for efficient cross-reference searching.
|
10
|
+
# It uses bundle paths and project roots to determine which files to include.
|
11
|
+
#
|
12
|
+
# Requires:
|
13
|
+
# - cscope command-line tool
|
14
|
+
#
|
15
|
+
# The script will:
|
16
|
+
# 1. Collect all files from project roots (including bundle paths)
|
17
|
+
# 2. Generate cscope.out database with cross-references
|
18
|
+
# 3. Show progress using infobar visualization
|
19
|
+
# 4. Report the size of the created database
|
2
20
|
|
3
21
|
require 'utils'
|
4
22
|
require 'infobar'
|
data/bin/create_tags
CHANGED
@@ -1,4 +1,14 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Creates ctags index for Ruby project including bundled gems
|
4
|
+
#
|
5
|
+
# This script generates a tags file that enables code navigation in editors
|
6
|
+
# like Vim. It automatically includes:
|
7
|
+
# - Current directory (.)
|
8
|
+
# - All gem paths from bundle list
|
9
|
+
# - Excludes pkg directory to avoid vendor code
|
10
|
+
#
|
11
|
+
# Usage: Run directly from project root
|
2
12
|
|
3
13
|
require 'infobar'
|
4
14
|
|
data/bin/discover
CHANGED
@@ -1,13 +1,43 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# File Discovery and Search Tool
|
4
|
+
#
|
5
|
+
# Interactive file discovery and search utility with advanced filtering and
|
6
|
+
# editing capabilities. Combines file system traversal with intelligent pattern
|
7
|
+
# matching and Vim integration.
|
8
|
+
#
|
9
|
+
# Features:
|
10
|
+
# - Interactive pattern input with live search results
|
11
|
+
# - File system discovery with directory traversal
|
12
|
+
# - Vim integration for editing discovered files
|
13
|
+
# - Configurable search filters (regexp, fuzzy, case-insensitive)
|
14
|
+
# - Search index management and caching
|
15
|
+
# - Directory listing and leaf directory identification
|
16
|
+
# - Character set filtering for patterns
|
17
|
+
# - Interactive selection when multiple matches exist
|
18
|
+
#
|
19
|
+
# The tool creates a searchable index of your file system (which is also used
|
20
|
+
# by the search tool) and provides interactive discovery of files matching your
|
21
|
+
# criteria, with seamless Vim
|
22
|
+
# integration.
|
2
23
|
|
3
24
|
require 'utils'
|
4
25
|
include Utils
|
5
|
-
require 'tins/xt'
|
6
26
|
include Tins::GO
|
7
27
|
require 'search_ui'
|
8
28
|
include SearchUI
|
9
29
|
require 'pathname'
|
10
30
|
|
31
|
+
# The edit_files method opens editor windows for specified file paths.
|
32
|
+
#
|
33
|
+
# This method allows users to edit one or more files using the configured
|
34
|
+
# editor. It provides options to pick a specific file from multiple paths or
|
35
|
+
# edit all files directly. The method supports waiting for the editor process
|
36
|
+
# to complete before returning control.
|
37
|
+
#
|
38
|
+
# @param paths [ Array<String> ] the file paths to be edited
|
39
|
+
# @param pick [ TrueClass, FalseClass ] whether to prompt for file selection
|
40
|
+
# @param wait [ TrueClass, FalseClass ] whether to wait for the editor to finish
|
11
41
|
def edit_files(*paths, pick: false, wait: true)
|
12
42
|
editor = Utils::Editor.new
|
13
43
|
if pick
|
@@ -25,6 +55,13 @@ def edit_files(*paths, pick: false, wait: true)
|
|
25
55
|
end
|
26
56
|
end
|
27
57
|
|
58
|
+
# The usage method displays the help message and version information for the
|
59
|
+
# application.
|
60
|
+
#
|
61
|
+
# This method prints a formatted usage message to standard output, including
|
62
|
+
# the application name, available options, and version number. It also shows
|
63
|
+
# detailed descriptions of each command-line option and their expected
|
64
|
+
# arguments.
|
28
65
|
def usage
|
29
66
|
puts <<-EOT
|
30
67
|
Usage: #{File.basename($0)} [OPTS] [PATTERN] [PATHS]
|
data/bin/edit
CHANGED
@@ -1,4 +1,10 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Enhanced vim editor launcher with advanced feature
|
4
|
+
#
|
5
|
+
# This script is a sophisticated wrapper around vim that provides enhanced
|
6
|
+
# editing capabilities including server management, git integration, and
|
7
|
+
# batch file handling.
|
2
8
|
|
3
9
|
require 'tins/xt'
|
4
10
|
include Tins::GO
|
@@ -6,6 +12,13 @@ require 'utils'
|
|
6
12
|
include Utils
|
7
13
|
require 'tempfile'
|
8
14
|
|
15
|
+
# The usage method displays the command-line interface help text and version
|
16
|
+
# information.
|
17
|
+
#
|
18
|
+
# This method outputs a formatted help message that describes the available
|
19
|
+
# options and usage patterns for the command-line tool, including detailed
|
20
|
+
# explanations of each flag and their purposes. It also displays the current
|
21
|
+
# version of the tool.
|
9
22
|
def usage
|
10
23
|
puts <<-EOT
|
11
24
|
Usage: #{File.basename($0)} [OPTS] [PATHS]
|
@@ -49,7 +62,7 @@ if $opt[?l]
|
|
49
62
|
elsif $opt[?s]
|
50
63
|
begin
|
51
64
|
until STDIN.eof?
|
52
|
-
line = STDIN.gets
|
65
|
+
line = STDIN.gets.chomp
|
53
66
|
line = line.sub(/.*?([^:\s]+:)/, '\1')
|
54
67
|
editor.edit(line)
|
55
68
|
end
|
data/bin/edit_wait
CHANGED
@@ -1,3 +1,17 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Wait for editor to close files before returning control
|
4
|
+
#
|
5
|
+
# Usage:
|
6
|
+
# edit_wait file1 file2 # Wait for editor to close specified files
|
7
|
+
#
|
8
|
+
# This script is a simple wrapper that calls 'edit -w' with all provided arguments.
|
9
|
+
# The '-w' flag makes the editor wait until the file(s) are closed before returning.
|
10
|
+
#
|
11
|
+
#
|
12
|
+
# Examples:
|
13
|
+
# edit_wait README.md # Edit README.md and wait for closure
|
14
|
+
# edit_wait file1.txt file2.txt # Edit multiple files and wait for all to close
|
15
|
+
|
2
16
|
|
3
17
|
exec 'edit', '-w', *$*
|