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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 85f412311ef245615fb822299605146a2b1fe3c6a678b7c4826bfda8c7f80e78
|
4
|
+
data.tar.gz: 0af45f306f2115ccb6b2a508d7d206a19d8433305d88e9d4b36da3d362edbae3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5b72e6f84ed6945c7dcc29ce430385c29fe5f91ff27a5ddeff394e09a0c43324845677a775311cd67059507918a3080699b78d9c1828c132d439a4055103881e
|
7
|
+
data.tar.gz: 26f68d486605ae78883a3dd6589517e80351f186efb17e4be12946b18d2fbdbd870276f89ee68e08f8eb1f21ff0958cc7ff7b100ab709ae7a128ac475ca0208a
|
data/README.md
CHANGED
@@ -1,27 +1,260 @@
|
|
1
|
-
# Utils -
|
1
|
+
# 📦 Utils - Developer Productivity Command-Line Utilities
|
2
2
|
|
3
|
-
## Description
|
3
|
+
## 📝 Description
|
4
4
|
|
5
|
-
This
|
5
|
+
This Ruby gem delivers a curated collection of command-line utilities designed
|
6
|
+
to streamline software development workflows and automate repetitive tasks. The
|
7
|
+
toolkit spans multiple domains including code analysis, testing automation,
|
8
|
+
file manipulation, and system administration.
|
6
9
|
|
7
|
-
|
10
|
+
### Key Features
|
8
11
|
|
9
|
-
|
12
|
+
- **Ruby-Centric Approach**: Built leveraging Ruby's expressive syntax,
|
13
|
+
metaprogramming capabilities, and dynamic nature
|
14
|
+
- **Multi-Functional Tools**: From simple CLI interfaces to sophisticated
|
15
|
+
automation workflows
|
16
|
+
- **Modern Integration**: Seamlessly integrates with popular development
|
17
|
+
frameworks, external services (including LLMs via Ollama), and system tools
|
18
|
+
- **Modular Architecture**: Lightweight design allowing selective tool usage
|
19
|
+
without heavy dependencies
|
20
|
+
- **Composability**: Tools designed to work together or independently
|
10
21
|
|
11
|
-
|
22
|
+
### Technical Approach
|
12
23
|
|
13
|
-
|
14
|
-
|
15
|
-
|
24
|
+
The utilities embrace Ruby's strengths through:
|
25
|
+
- Dynamic method dispatch and metaprogramming techniques
|
26
|
+
- Expressive DSLs for configuration and tool definition
|
27
|
+
- Seamless integration with Git, vim, SSH, and terminal multiplexers
|
28
|
+
- Performance-conscious design with pattern matching for pruning operations
|
16
29
|
|
17
|
-
##
|
30
|
+
## 🛠️ Installation
|
18
31
|
|
19
|
-
|
20
|
-
- improve backup mechanism for new configuration, interactivity?
|
32
|
+
Add this gem to your Gemfile:
|
21
33
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
34
|
+
```ruby
|
35
|
+
gem 'utils'
|
36
|
+
```
|
37
|
+
|
38
|
+
And install it using Bundler:
|
39
|
+
|
40
|
+
```bash
|
41
|
+
bundle install
|
42
|
+
```
|
43
|
+
|
44
|
+
Or install the gem directly:
|
45
|
+
|
46
|
+
```bash
|
47
|
+
gem install utils
|
48
|
+
```
|
49
|
+
|
50
|
+
## 🧰 Utilities
|
51
|
+
|
52
|
+
### 🔍 Searching
|
53
|
+
|
54
|
+
- **`blameline`** - Show git blame line for a file and line number
|
55
|
+
- **`create_cstags`** - Create cscope tags file for current directory
|
56
|
+
- **`create_tags`** - Create ctags tags file for current directory
|
57
|
+
- **`discover`** - Find files with specific content patterns
|
58
|
+
- **`git-versions`** - Show git versions of files and directories
|
59
|
+
- **`long_lines`** - Finds long lines with author attribution
|
60
|
+
- **`search`** - Search for text in files recursively
|
61
|
+
|
62
|
+
### ✍️ Editing
|
63
|
+
|
64
|
+
- **`classify`** - Classify files by type using file command
|
65
|
+
- **`edit_wait`** - Edit a file and wait for changes to be saved
|
66
|
+
- **`edit`** - Edit a file using default editor
|
67
|
+
- **`print_method`** - Extracts complete method definitions from Ruby source
|
68
|
+
files
|
69
|
+
- **`sedit`** - Edit a file with sed commands
|
70
|
+
- **`strip_spaces`** - Removes trailing whitespace with tab conversion options
|
71
|
+
- **`sync_dir`** - Sync directories with rsync
|
72
|
+
- **`untest`** - Remove test files from current directory
|
73
|
+
|
74
|
+
### 🧪 Testing
|
75
|
+
|
76
|
+
- **`json_check`** - Validate JSON syntax in files
|
77
|
+
- **`on_change`** - Monitors files for changes and executes commands
|
78
|
+
- **`probe`** - Test runner supporting RSpec, Test::Unit, Cucumber with
|
79
|
+
server/client functionality
|
80
|
+
- **`yaml_check`** - Validate YAML syntax in files
|
81
|
+
|
82
|
+
### 📚 Documenting
|
83
|
+
|
84
|
+
- **`changes`** - Generate changelogs using Git history and LLM summaries
|
85
|
+
- **`code_comment`** - Generates YARD documentation using LLM assistance
|
86
|
+
- **`commit_message`** - Generate commit messages via LLM from git diff
|
87
|
+
- **`rd2md`** - Convert RDoc to Markdown
|
88
|
+
|
89
|
+
### ⚙️ Configuring
|
90
|
+
|
91
|
+
- **`git-empty`** - Create empty git repository with default files
|
92
|
+
- **`myex`** - Processes MySQL dump files (list, create, truncate, insert,
|
93
|
+
search)
|
94
|
+
- **`path`** - Show or modify PATH environment variable
|
95
|
+
- **`utils-utilsrc`** - Manages `~/.utilsrc` configuration file with
|
96
|
+
show/diff/edit capabilities
|
97
|
+
- **`vcf2alias`** - Converts VCard contacts to Mutt email aliases
|
98
|
+
|
99
|
+
### 🌐 Networking
|
100
|
+
|
101
|
+
- **`serve`** - Simple HTTP server launcher
|
102
|
+
- **`ssh-tunnel`** - Create SSH tunnel to remote host
|
103
|
+
|
104
|
+
### 🎨 Slacking
|
105
|
+
|
106
|
+
- **`ascii7`** - Generate ASCII art from text
|
107
|
+
- **`enum`** - Enumerate files and directories with line counts
|
108
|
+
- **`rainbow`** - Display rainbow-colored banner text
|
109
|
+
|
110
|
+
## ⚙️ Configuration
|
111
|
+
|
112
|
+
The `~/.utilsrc` configuration file uses Ruby syntax to define settings for
|
113
|
+
various utility components. This file allows you to customize the behavior of
|
114
|
+
different utilities without modifying their source code.
|
115
|
+
|
116
|
+
Each configuration block corresponds to a specific utility or category of
|
117
|
+
utilities. The settings within each block control how those utilities behave
|
118
|
+
during execution. The configuration system supports:
|
119
|
+
|
120
|
+
- **Pattern matching**: Regular expressions for including/excluding files and
|
121
|
+
directories
|
122
|
+
- **Performance optimization**: Caching mechanisms and pruning rules to avoid
|
123
|
+
unnecessary processing
|
124
|
+
- **Integration capabilities**: Settings for connecting with external tools
|
125
|
+
like SSH, vim, and terminal multiplexers
|
126
|
+
- **Environment customization**: Ability to set environment variables and
|
127
|
+
default paths
|
128
|
+
|
129
|
+
The configuration is loaded at runtime and can be modified without requiring a
|
130
|
+
restart of the utilities. Changes take effect immediately for subsequent
|
131
|
+
operations.
|
132
|
+
|
133
|
+
⚠️ **Important Note**: Since this is Ruby syntax, you have access to full Ruby
|
134
|
+
capabilities within the configuration blocks. You can use variables, methods,
|
135
|
+
conditional logic, and other Ruby features to create dynamic configurations
|
136
|
+
when needed.
|
137
|
+
|
138
|
+
```ruby
|
139
|
+
# vim: set ft=ruby:
|
140
|
+
|
141
|
+
# ~/.utilsrc - Utility configuration file
|
142
|
+
# This file contains configuration settings for various utility components
|
143
|
+
|
144
|
+
## Search Configuration
|
145
|
+
search do
|
146
|
+
# Directories to prune during search operations
|
147
|
+
# These are excluded from the search scope to improve performance
|
148
|
+
prune_dirs /\A(\.svn|\.git|\.terraform|CVS|tmp|coverage|corpus|pkg|\.yardoc)\z/
|
149
|
+
|
150
|
+
# Files to skip during search operations
|
151
|
+
# Excludes temporary files, log files, and system files
|
152
|
+
skip_files /(\A\.|\.sw[pon]\z|\.(log|fnm|jpg|jpeg|png|pdf|svg)\z|\Atags\z|~\z)/i
|
153
|
+
end
|
154
|
+
|
155
|
+
## Discovery Configuration
|
156
|
+
discover do
|
157
|
+
# Directories to prune during discovery operations
|
158
|
+
# Excludes version control systems, temporary directories, and build artifacts
|
159
|
+
prune_dirs /\A(\.svn|\.git|\.terraform|\.yardoc|CVS|tmp|coverage|corpus|pkg|\.yardoc)\z/
|
160
|
+
|
161
|
+
# Files to skip during discovery operations
|
162
|
+
# Excludes hidden files, swap files, and log files
|
163
|
+
skip_files /(\A\.|\.sw[pon]\z|\.log\z|~\z)/
|
164
|
+
|
165
|
+
# Cache index expiration time in seconds (1 hour = 3600 seconds)
|
166
|
+
index_expire_after 3_600
|
167
|
+
|
168
|
+
# Maximum number of matches to return (0 = no limit)
|
169
|
+
# Prevents overwhelming output when many files match the search criteria
|
170
|
+
max_matches 10
|
171
|
+
end
|
172
|
+
|
173
|
+
## Space Stripping Configuration
|
174
|
+
strip_spaces do
|
175
|
+
# Directories to prune during space stripping operations
|
176
|
+
# Excludes hidden directories and system directories
|
177
|
+
prune_dirs /\A(\..*|CVS|pkg|\.yardoc)\z/
|
178
|
+
|
179
|
+
# Files to skip during space stripping operations
|
180
|
+
# Excludes hidden files, swap files, and log files
|
181
|
+
skip_files /(\A\.|\.sw[pon]\z|\.log\z|~\z)/
|
182
|
+
end
|
183
|
+
|
184
|
+
## Probe Configuration
|
185
|
+
probe do
|
186
|
+
# Test framework to use for probing
|
187
|
+
test_framework :'test-unit'
|
188
|
+
|
189
|
+
# Directories to include in probe operations
|
190
|
+
# Specifies where to look for test files and source code
|
191
|
+
include_dirs %w[lib test tests ext spec]
|
192
|
+
end
|
193
|
+
|
194
|
+
## SSH Tunnel Configuration
|
195
|
+
ssh_tunnel do
|
196
|
+
# Terminal multiplexer to use (supports :tmux or other terminal managers)
|
197
|
+
terminal_multiplexer :tmux
|
198
|
+
|
199
|
+
# Login session path for SSH connections
|
200
|
+
login_session "/home/#{ENV['USER']}"
|
201
|
+
|
202
|
+
# Environment variables to set for the tunnel
|
203
|
+
env(
|
204
|
+
FOO: 'test' # Example environment variable - adjust as needed
|
205
|
+
)
|
206
|
+
|
207
|
+
# Enable or disable copy/paste functionality
|
208
|
+
copy_paste true do
|
209
|
+
# Bind address for the tunnel
|
210
|
+
bind_address 'localhost'
|
211
|
+
|
212
|
+
# Port number for the tunnel
|
213
|
+
port 6166
|
214
|
+
|
215
|
+
# Host for the tunnel
|
216
|
+
host 'localhost'
|
217
|
+
|
218
|
+
# Host port for the tunnel
|
219
|
+
host_port 6166
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
## Classification Configuration
|
224
|
+
classify do
|
225
|
+
# Default path shifting value (1 = shift by one directory level)
|
226
|
+
shift_path_by_default 1
|
227
|
+
|
228
|
+
# Path prefixes to check in order for classification
|
229
|
+
# Used to determine how paths should be shifted or categorized
|
230
|
+
shift_path_for_prefix [ # prefixes checked in order
|
231
|
+
'a/b',
|
232
|
+
'c/d/e',
|
233
|
+
]
|
234
|
+
end
|
235
|
+
|
236
|
+
## Sync Directory Configuration
|
237
|
+
sync_dir do
|
238
|
+
# Paths to skip during sync operations
|
239
|
+
# Uses regex pattern to exclude certain directory patterns
|
240
|
+
skip_path %r((\A|/)\.\w)
|
241
|
+
end
|
242
|
+
|
243
|
+
## Edit Configuration
|
244
|
+
edit do
|
245
|
+
# Path to vim executable
|
246
|
+
# Uses shell command to find vim in PATH
|
247
|
+
vim_path `which vim`.chomp
|
248
|
+
|
249
|
+
# Default arguments for vim (nil = no default args)
|
250
|
+
vim_default_args nil
|
251
|
+
end
|
252
|
+
```
|
253
|
+
|
254
|
+
## 👨💻 Author
|
255
|
+
|
256
|
+
[Florian Frank](mailto:flori@ping.de)
|
257
|
+
|
258
|
+
## 📄 License
|
259
|
+
|
260
|
+
GPLv2 [LICENSE](./LICENSE)
|
data/bin/ascii7
CHANGED
@@ -1,4 +1,32 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This script generates a visual representation of how 7-bit ASCII characters #
|
4
|
+
# are interpreted when the upper 2 bits (prefix) are varied while keeping the
|
5
|
+
# lower 5 bits constant. It demonstrates the relationship between binary
|
6
|
+
# patterns and character representations in classic ASCII encoding.
|
7
|
+
#
|
8
|
+
# The output shows:
|
9
|
+
# - First column: Lower 5 bits of ASCII values (0-31 in binary)
|
10
|
+
# - Remaining columns: Character names for each prefix combination (00, 01, 10, 11)
|
11
|
+
# where prefix + lower_bits = full 7-bit ASCII value
|
12
|
+
#
|
13
|
+
# This reveals how early computer systems treated the same bit patterns differently
|
14
|
+
# depending on context or system interpretation, and illustrates the evolution
|
15
|
+
# from control characters to printable ASCII ranges.
|
16
|
+
#
|
17
|
+
# The script uses bit manipulation: (prefix << 5) | lower_bits
|
18
|
+
# to generate all 32 combinations of the lower 5 bits with 4 possible prefixes.
|
19
|
+
#
|
20
|
+
# This demonstrates fundamental concepts in computer science:
|
21
|
+
# - Bit-level character encoding
|
22
|
+
# - Historical ASCII design principles
|
23
|
+
# - Binary representation and manipulation
|
24
|
+
# - Control character vs printable character distinctions
|
25
|
+
#
|
26
|
+
# References:
|
27
|
+
# - Original 7-bit ASCII standard
|
28
|
+
# - Early computer system character set conventions
|
29
|
+
# - Bit manipulation in low-level programming
|
2
30
|
|
3
31
|
map = Hash.new { |h, k| h[k] = k }.merge(
|
4
32
|
" " => "Spc",
|
data/bin/blameline
CHANGED
@@ -1,4 +1,21 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Line blamer - Show Git blame information for lines or files
|
4
|
+
#
|
5
|
+
# Usage: blameline [OPTIONS] [LINES|FILES]
|
6
|
+
#
|
7
|
+
# Displays Git blame information for specified lines or files.
|
8
|
+
#
|
9
|
+
# Options:
|
10
|
+
# -s Read lines from stdin instead of command-line arguments
|
11
|
+
# -h Show this help message
|
12
|
+
#
|
13
|
+
# Examples:
|
14
|
+
# blameline file.rb:23 # Blame all lines in file
|
15
|
+
# blameline -s < lines.txt # Blame lines from stdin
|
16
|
+
# echo some/code:23 | blameline -s # Blame single line from stdin
|
17
|
+
#
|
18
|
+
# Shows author, commit hash, and date for each line of code.
|
2
19
|
|
3
20
|
require 'tins/go'
|
4
21
|
include Tins::GO
|
data/bin/changes
CHANGED
@@ -1,17 +1,62 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Generate changelogs using Git history and LLM summaries
|
4
|
+
#
|
5
|
+
# Usage:
|
6
|
+
# changes pending # Show changes since last version
|
7
|
+
# changes current # Show changes between two latest versions
|
8
|
+
# changes range v1.0.0..v1.2.0 # Show changes in a specific range
|
9
|
+
# changes full # Generate full changelog from first tag
|
10
|
+
# changes add CHANGELOG.md # Append new entries to existing file
|
11
|
+
#
|
12
|
+
# Requires:
|
13
|
+
# - Git repository with version tags (vX.Y.Z format)
|
14
|
+
# - Ollama server running locally or accessible via OLLAMA_URL / OLLAMA_HOST
|
15
|
+
# - Configuration files in ~/.config/changes/
|
16
|
+
# - system.txt: System prompt for LLM
|
17
|
+
# - prompt.txt: Template for changelog generation
|
18
|
+
# - client.json: Ollama client settings
|
19
|
+
# - options.json: Generation options (temperature, etc.)
|
20
|
+
#
|
21
|
+
# Environment variables:
|
22
|
+
# OLLAMA_URL: Base URL of Ollama server OR
|
23
|
+
# OLLAMA_HOST: Host 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
|
2
27
|
|
3
28
|
require 'ollama'
|
4
29
|
include Ollama
|
5
|
-
require 'tins/xt'
|
6
30
|
require 'utils'
|
7
|
-
include Utils::XDGConfig
|
8
31
|
|
32
|
+
# Executes a shell command and returns its output.
|
33
|
+
#
|
34
|
+
# This method runs the provided command in a shell environment and captures its
|
35
|
+
# standard output. If the command fails (returns a non-zero exit status), it
|
36
|
+
# raises an exception with details about the failure.
|
37
|
+
#
|
38
|
+
# @param cmd [ String ] the shell command to be executed
|
39
|
+
#
|
40
|
+
# @return [ String ] the standard output of the executed command
|
41
|
+
#
|
42
|
+
# @raise [ RuntimeError ] if the executed command returns a non-zero exit status
|
9
43
|
def x(cmd)
|
10
44
|
output = `#{cmd}`
|
11
45
|
$?.success? or fail "failed to execute #{cmd.inspect}"
|
12
46
|
output
|
13
47
|
end
|
14
48
|
|
49
|
+
# Finds the highest version tag from a CHANGES file by parsing version strings
|
50
|
+
# in YYYY-MM-DD vMAJOR.MINOR.PATCH format.
|
51
|
+
#
|
52
|
+
# This method reads through the specified file line by line, extracting version
|
53
|
+
# tags that match the pattern "## YYYY-MM-DD vMAJOR.MINOR.PATCH" and determines
|
54
|
+
# the highest version number among them.
|
55
|
+
#
|
56
|
+
# @param filename [ String ] the path to the file containing version tags
|
57
|
+
#
|
58
|
+
# @return [ String, nil ] the highest version string found in the file, or nil
|
59
|
+
# if no valid version tags are present
|
15
60
|
def find_highest_version_tag(filename)
|
16
61
|
File.open(filename, ?r) do |input|
|
17
62
|
tags = []
|
@@ -24,6 +69,17 @@ def find_highest_version_tag(filename)
|
|
24
69
|
end
|
25
70
|
end
|
26
71
|
|
72
|
+
# The compute_change method generates a changelog entry by processing Git log
|
73
|
+
# information and using an LLM to create a formatted summary.
|
74
|
+
#
|
75
|
+
# This method takes two range parameters, computes the Git log between them,
|
76
|
+
# retrieves the commit date, and then uses an LLM to generate a human-readable
|
77
|
+
# changelog entry based on configuration files and prompt templates.
|
78
|
+
#
|
79
|
+
# @param range_from [ Object ] the starting point of the Git log range
|
80
|
+
# @param range_to [ Object ] the ending point of the Git log range
|
81
|
+
#
|
82
|
+
# @return [ String ] a formatted changelog entry including the date and LLM-generated content
|
27
83
|
def compute_change(range_from, range_to)
|
28
84
|
range_from = range_from.to_s.sub(/\Av?/, ?v)
|
29
85
|
if range_to.to_s == 'HEAD'
|
@@ -45,7 +101,7 @@ def compute_change(range_from, range_to)
|
|
45
101
|
EOT
|
46
102
|
end
|
47
103
|
|
48
|
-
config =
|
104
|
+
config = Utils::ConfigDir.new('changes', env_var: 'XDG_CONFIG_HOME')
|
49
105
|
|
50
106
|
base_url = ENV['OLLAMA_URL'] || 'http://%s' % ENV.fetch('OLLAMA_HOST')
|
51
107
|
model = ENV.fetch('OLLAMA_MODEL', 'llama3.1')
|
@@ -156,7 +212,15 @@ when 'full', 'add'
|
|
156
212
|
end
|
157
213
|
end
|
158
214
|
else
|
159
|
-
puts <<~
|
215
|
+
puts <<~EOT
|
160
216
|
Usage: #{File.basename($0)} help|range|full|add|pending
|
161
|
-
|
217
|
+
|
218
|
+
Commands:
|
219
|
+
pending Show changes since last version tag
|
220
|
+
current Show changes between two latest version tags
|
221
|
+
range <range> Show changes for a specific Git range (e.g., v1.0.0..v1.2.0)
|
222
|
+
full Generate complete changelog from first tag
|
223
|
+
add <file> Append new entries to existing changelog file
|
224
|
+
|
225
|
+
EOT
|
162
226
|
end
|
data/bin/classify
CHANGED
@@ -1,11 +1,35 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Ruby module name to file path converter
|
4
|
+
#
|
5
|
+
# This tool helps map between Ruby module naming conventions and filesystem
|
6
|
+
# paths, which is essential for Ruby development, code generation, and
|
7
|
+
# refactoring. It converts between Foo::BarBaz (module names) and foo/bar_baz
|
8
|
+
# (file paths) while supporting various formatting options and project-specific
|
9
|
+
# path shifting.
|
10
|
+
#
|
11
|
+
# Common use cases:
|
12
|
+
# - Converting controller names to file paths in Rails
|
13
|
+
# - Refactoring code by mapping between naming conventions
|
14
|
+
# - Can be used in editor functions for easy access
|
15
|
+
#
|
16
|
+
# Run 'classify -h' for detailed help and examples
|
2
17
|
|
3
18
|
require 'utils'
|
4
|
-
require 'tins/go'
|
5
19
|
include Tins::GO
|
6
|
-
require 'tins/xt/string'
|
7
20
|
require 'term/ansicolor'
|
8
21
|
|
22
|
+
# The path_shifter method processes a string path by splitting it using the
|
23
|
+
# specified separator and then either removing the first n elements or taking a
|
24
|
+
# slice from the end, depending on whether n is positive or negative.
|
25
|
+
#
|
26
|
+
# @param string [ String ] the path string to be processed
|
27
|
+
# @param separator [ String ] the character used to split the path string,
|
28
|
+
# defaults to '/'
|
29
|
+
# @param n [ Integer, nil ] the number of elements to remove from the beginning
|
30
|
+
# of the path if positive, or take from the end if negative
|
31
|
+
#
|
32
|
+
# @return [ String ] the resulting path string after processing
|
9
33
|
def path_shifter(string, separator: ?/, n: nil)
|
10
34
|
n or return string
|
11
35
|
n, path = n.to_i, string.split(separator)
|
@@ -17,6 +41,15 @@ def path_shifter(string, separator: ?/, n: nil)
|
|
17
41
|
path * separator
|
18
42
|
end
|
19
43
|
|
44
|
+
# The underscore method converts a string to underscored format.
|
45
|
+
#
|
46
|
+
# This method processes a string by first applying path shifting based on
|
47
|
+
# options, then applies the standard underscore transformation.
|
48
|
+
# It optionally appends '.rb' to the result if specified in the options.
|
49
|
+
#
|
50
|
+
# @param string [ String ] the input string to be converted
|
51
|
+
#
|
52
|
+
# @return [ String ] the underscored version of the input string
|
20
53
|
def underscore(string)
|
21
54
|
string = path_shifter(string, n: $opts[?n], separator: '::')
|
22
55
|
string = Tins::StringUnderscore.instance_method(:underscore).bind(string).()
|
@@ -24,31 +57,89 @@ def underscore(string)
|
|
24
57
|
string
|
25
58
|
end
|
26
59
|
|
60
|
+
# The parameterize method converts a string into a URL-friendly format by
|
61
|
+
# replacing spaces and special characters with a specified separator.
|
62
|
+
#
|
63
|
+
# This method takes an input string and transforms it into a lowercase,
|
64
|
+
# underscore-separated format suitable for use in URLs or file names. It
|
65
|
+
# handles forward slashes by replacing them with the specified separator
|
66
|
+
# character.
|
67
|
+
#
|
68
|
+
# @param string [ String ] the input string to be parameterized
|
69
|
+
# @param separator [ String ] the character to replace forward slashes with
|
70
|
+
#
|
71
|
+
# @return [ String ] the parameterized string with forward slashes replaced by
|
72
|
+
# the specified separator
|
27
73
|
def parameterize(string, separator)
|
28
74
|
underscore(string).gsub(?/, separator) # quick and dirty
|
29
75
|
end
|
30
76
|
|
77
|
+
# The camelize method converts a string into camelCase format by processing...
|
78
|
+
# It removes the file extension first, then applies camelization to the
|
79
|
+
# remaining string.
|
80
|
+
#
|
81
|
+
# @param string [ String ] the input string to be converted
|
82
|
+
#
|
83
|
+
# @return [ String ] the camelized string result
|
31
84
|
def camelize(string)
|
32
85
|
string = path_shifter(string, n: $opts[?n])
|
33
86
|
string = string.gsub(/#{Regexp.quote(File.extname(string))}\Z/, '')
|
34
87
|
string.camelize
|
35
88
|
end
|
36
89
|
|
90
|
+
# The camelcase? method checks whether a string starts with an uppercase
|
91
|
+
# letter.
|
92
|
+
#
|
93
|
+
# This method determines if the provided string begins with a capital letter,
|
94
|
+
# returning true if it does and false otherwise.
|
95
|
+
#
|
96
|
+
# @param string [ String ] the string to be checked for camelCase format
|
97
|
+
#
|
98
|
+
# @return [ TrueClass, FalseClass ] true if the string starts with an uppercase
|
99
|
+
# letter, false otherwise
|
37
100
|
def camelcase?(string)
|
38
|
-
string
|
101
|
+
string =~ /\A[A-Z]/
|
39
102
|
end
|
40
103
|
|
104
|
+
# The compute_shift method determines the shift value for a string based on
|
105
|
+
# configuration settings.
|
106
|
+
#
|
107
|
+
# This method processes a string by converting it to underscore format and then
|
108
|
+
# checks against configured shift path prefixes to determine an appropriate
|
109
|
+
# shift value.
|
110
|
+
# If a matching prefix is found, it returns the count of forward slashes in the
|
111
|
+
# prefix plus one. Otherwise, it returns the default shift path value from the
|
112
|
+
# configuration.
|
113
|
+
#
|
114
|
+
# @param config [ Object ] the configuration object containing classify
|
115
|
+
# settings
|
116
|
+
# @param string [ String ] the input string to process and determine shift
|
117
|
+
# value for
|
118
|
+
#
|
119
|
+
# @return [ Integer ] the calculated shift value based on prefix matching or
|
120
|
+
# default setting
|
41
121
|
def compute_shift(config, string)
|
42
|
-
string
|
43
|
-
|
122
|
+
string = underscore(string)
|
123
|
+
default = config.classify.shift_path_by_default
|
44
124
|
for prefix in config.classify.shift_path_for_prefix
|
45
125
|
if string.start_with? prefix
|
46
126
|
return prefix.count(?/) + 1
|
47
127
|
end
|
48
128
|
end
|
49
|
-
|
129
|
+
default
|
50
130
|
end
|
51
131
|
|
132
|
+
# The usage method displays the command-line interface help text and exits the
|
133
|
+
# program.
|
134
|
+
#
|
135
|
+
# This method prints a formatted usage message that describes the available
|
136
|
+
# options for the command-line tool, including descriptions of each flag and
|
137
|
+
# their functionality.
|
138
|
+
# It provides information about how to classify and declassify path names into
|
139
|
+
# module namespaces, along with various toggle and formatting options.
|
140
|
+
#
|
141
|
+
# This method always exits the program with status code 0 after displaying
|
142
|
+
# help.
|
52
143
|
def usage
|
53
144
|
puts <<~EOT
|
54
145
|
Usage: #{File.basename($0)} [OPTS]
|
@@ -65,6 +156,32 @@ def usage
|
|
65
156
|
-p SEPARATOR used for declassification
|
66
157
|
-h display this help
|
67
158
|
|
159
|
+
Examples:
|
160
|
+
|
161
|
+
classify Foo::BarBaz ⇢ Foo::BarBaz
|
162
|
+
classify -d Foo::Bar ⇢ foo/bar
|
163
|
+
classify -d foo/bar_baz ⇢ foo/bar_baz
|
164
|
+
classify foo/bar ⇢ Foo::Bar
|
165
|
+
classify -b Foo::BarBaz ⇢ BarBaz
|
166
|
+
classify -d -s Foo::Bar ⇢ foo/bar.rb
|
167
|
+
classify -t Foo::Bar ⇢ foo/bar
|
168
|
+
classify -t foo/bar ⇢ Foo::Bar
|
169
|
+
classify -p . -d Foo::Bar::Baz ⇢ foo.bar.baz
|
170
|
+
classify -p : -d Foo::Bar::Baz ⇢ foo:bar:baz
|
171
|
+
classify -n 1 lib/foo/bar ⇢ Foo::Bar
|
172
|
+
|
173
|
+
With this configuration in .utilsrc:
|
174
|
+
classify do
|
175
|
+
shift_path_by_default 1 # if no prefix matched
|
176
|
+
shift_path_for_prefix [ # prefixes checked in order
|
177
|
+
'a/b',
|
178
|
+
'c/d/e',
|
179
|
+
]
|
180
|
+
end
|
181
|
+
|
182
|
+
classify lib/foo/bar ⇢ Foo::Bar
|
183
|
+
classify a/b/foo/bar ⇢ Foo::Bar
|
184
|
+
classify c/d/e/foo/bar ⇢ Foo::Bar
|
68
185
|
EOT
|
69
186
|
exit 0
|
70
187
|
end
|
@@ -103,6 +220,10 @@ print(
|
|
103
220
|
underscore string
|
104
221
|
end
|
105
222
|
else
|
106
|
-
|
223
|
+
if camelcase?(string)
|
224
|
+
path_shifter(string, separator: '::', n: $opts[?n])
|
225
|
+
else
|
226
|
+
camelize string
|
227
|
+
end
|
107
228
|
end
|
108
229
|
)
|