gem_hadar 1.26.0 → 1.27.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f3fefed7b5fd9123e2944de9cf2defcd9f1794aaa7d0058621539b22a2e076d3
4
- data.tar.gz: 8734f8f3cf30c0a0b501e5484a58bc5b4bbc4190258133f6de7b1105f17c7383
3
+ metadata.gz: db714afa72ba58c1676c20ec7efdfe235300f384f839ea663880b0ae976a9a0b
4
+ data.tar.gz: 6f1ebe9a6446fc600e00d0964a9f3f215cccc264454468bec4dc93e9ff8c674a
5
5
  SHA512:
6
- metadata.gz: 867a63019ba90544ba9b0c91478482128d3527221d9c11473929d9f18b5c74673d2fc3ab5844bc26779680b724965a9a7a455518286c5ca9a496342371c31c1a
7
- data.tar.gz: a6fa278536336a668d025947b3d9f274d4cc02ae9e2a3d50bb2a2a87b42ee2d351bfb191d9eb472bd215b521c34b561c4ee5d9f15cfcec93576f98871df23c10
6
+ metadata.gz: c89a930270aa72bb13179e6bedd38c4cc5971f8924aba2f86c588925a62baf5141191d065289f6b7a75d1e05f99beb17b91db78f09c23529ab04625d3147b271
7
+ data.tar.gz: 5a1eddb1dba0410f324a519b3b445036ec8c6e53c2406968161169133d9f7fd17c1e4e558f9fa72d4b1bdbca4f532ec0e93a4ef616a0796521f2de2d86452dc2
data/README.md CHANGED
@@ -85,6 +85,151 @@ or can be installed via
85
85
  $ gem install gem_hadar
86
86
  ```
87
87
 
88
+ ## Configuration
89
+
90
+ ### Environment Variables
91
+
92
+ The following environment variables can be used to configure `gem_hadar`:
93
+
94
+ | Variable | Description | Default |
95
+ |----------|-------------|---------|
96
+ | `GEM_HOST_API_KEY` | API key for gem hosting services | Not set |
97
+ | `GITHUB_API_TOKEN` | GitHub personal access token for releases | Not set |
98
+ | `OLLAMA_MODEL` | Ollama model name for AI generation | `llama3.1` |
99
+ | `OLLAMA_HOST` | Ollama server host URL | `localhost:11434` |
100
+ | `OLLAMA_URL` | Direct Ollama API URL (takes precedence over `OLLAMA_HOST`) | Not set |
101
+ | `OLLAMA_MODEL_OPTIONS` | JSON configuration for Ollama model | Not set |
102
+ | `HOME` | User's home directory (used for config file locations) | System default |
103
+ | `XDG_CONFIG_HOME` | XDG configuration directory override | System default |
104
+ | `MAKE` | Make program to use for building extensions | `gmake` or `make` |
105
+ | `VERSION` | Override the version string for some tasks | Not set |
106
+ | `FORCE` | Force certain operations (1 to enable) | 0 |
107
+ | `GIT_REMOTE` | Git remote name(s) for operations, space separated | `origin` |
108
+ | `GITHUB_RELEASE_ENABLED` | Enable GitHub releases (yes/no) | Auto-detected |
109
+ | `EDITOR` | Editor to use for interactive tasks | `vi` |
110
+
111
+ ### Rubygems API
112
+
113
+ To publish gems to RubyGems.org, you'll need to set up an API key:
114
+
115
+ 1. Generate a new API key at: https://rubygems.org/profile/api\_keys/new
116
+ 2. Set the environment variable:
117
+
118
+ ```bash
119
+ export GEM_HOST_API_KEY="your_api_key_here"
120
+ ```
121
+
122
+ **Security Note**: Never commit your API key to version control. Use a `.env`
123
+ file or your shell's configuration with appropriate loading mechanisms.
124
+
125
+ This key is required for tasks like `rake release` which push the gem package to RubyGems.org.
126
+
127
+ ### Github API
128
+
129
+ To enable GitHub release creation and other GitHub API interactions, you'll
130
+ need to set up a personal access token.
131
+
132
+ 1. Generate a new token at: https://github.com/settings/tokens/new
133
+ 2. Grant it `repo` scope for full repository access
134
+ 3. Set the environment variable:
135
+
136
+ ```bash
137
+ export GITHUB_API_TOKEN="your_token_here"
138
+ ```
139
+
140
+ **Security Note**: Never commit your token to version control. Use a `.env`
141
+ file or your shell's configuration with appropriate loading mechanisms.
142
+
143
+ This token is required for tasks like `rake github:release` which create GitHub
144
+ releases with AI-generated changelogs.
145
+
146
+ ### Local Ollama AI
147
+
148
+ The gem supports AI-powered changelog generation using Ollama. To configure
149
+ this functionality:
150
+
151
+ 1. Install and run Ollama locally: https://ollama.com/download
152
+ 2. Pull the desired model (e.g., `ollama pull deepseek-r1:32b`)
153
+ 3. Set the following environment variables:
154
+
155
+ ```bash
156
+ export OLLAMA_HOST="http://localhost:11434"
157
+ export OLLAMA_MODEL="deepseek-r1:32b"
158
+ export OLLAMA_MODEL_OPTIONS='{"num_ctx":16384,"seed":-1,"num_predict":512,"temperature":0.4,"top_p":0.95,"top_k":20,"min_p":0}'
159
+ ```
160
+
161
+ The default model is `llama3.1` and the default host is
162
+ `http://localhost:11434`. These can be overridden based on your local Ollama
163
+ setup.
164
+
165
+ The model options example configures:
166
+
167
+ - `num_ctx`: Context window size (16384 tokens)
168
+ - `temperature`: Response randomness (0.4 for balanced output)
169
+ - `num_predict`: Maximum tokens to generate (512)
170
+ - `top_p`, `top_k`, `min_p`: Sampling parameters for controlled generation
171
+
172
+ This functionality is used by the `rake github:release` and `rake version:bump`
173
+ task to generate AI-powered changelogs or suggest a version bump.
174
+
175
+ ### Custom AI Prompts
176
+
177
+ To customize the AI prompts used by `gem_hadar`, you can override the default
178
+ prompt files in your XDG configuration directory.
179
+
180
+ First, display the current default prompts using:
181
+
182
+ ```bash
183
+ $ rake gem_hadar:config
184
+ ```
185
+
186
+ This will show you the `XDG_CONFIG_HOME`, default system and user prompts for
187
+ version bumping and release generation. The output includes the exact template
188
+ variables that are available for use in your custom prompts.
189
+
190
+ Then, create the following files in your XDG configuration home directory:
191
+
192
+ - `version_bump_system_prompt.txt`
193
+ - `version_bump_prompt.txt`
194
+ - `release_system_prompt.txt`
195
+ - `release_prompt.txt`
196
+
197
+ Start with the default values shown by `rake gem_hadar:config` and modify them
198
+ to suit your needs. The prompts support standard Ruby string interpolation with
199
+ the following variables:
200
+
201
+ For version bump prompts:
202
+ - `%{version}` - Current gem version
203
+ - `%{log_diff}` - Git diff of changes
204
+
205
+ For release prompts:
206
+ - `%{name}` - Gem name
207
+ - `%{version}` - New version being released
208
+ - `%{log_diff}` - Git diff of changes
209
+
210
+ This approach ensures your custom prompts work correctly with the template
211
+ variables while maintaining consistency with the gem's expected input format.
212
+
213
+ ### Output current configuration
214
+
215
+ To debug or verify your `gem_hadar` configuration, you can use the following
216
+ rake task:
217
+
218
+ ```bash
219
+ $ rake gem_hadar:config
220
+ ```
221
+
222
+ This task displays all current configuration values including:
223
+ - GitHub API token (masked)
224
+ - RubyGems API key (masked)
225
+ - Ollama model settings
226
+ - Repository information (gem name, version)
227
+ - Build parameters (MAKE, EDITOR)
228
+ - Git configuration (remote)
229
+ - Other flags (FORCE, VERSION, GITHUB_RELEASE_ENABLED)
230
+ - XDG/HOME directories
231
+ - AI prompt defaults
232
+
88
233
  ## Usage
89
234
 
90
235
  ### Pre-requisites
@@ -160,6 +305,115 @@ end
160
305
 
161
306
  Note that `gem_hadar` is ["self hosted"](Rakefile)
162
307
 
308
+ ### Configuration settings in the GemHadar block
309
+
310
+ #### Core Required Attributes (Mapped to GemSpec)
311
+
312
+ - **`name`** - Required gem name (raises error if not set)
313
+ - **`version`** - Required version with fallback to `VERSION` file or ENV override
314
+ - **`authors`** - Required author names (mapped from `author`)
315
+ - **`email`** - Required author email (raises error if not set)
316
+ - **`homepage`** - Required homepage URL (raises error if not set). **Validation**: When `developing` is false, validates that the URL returns an HTTP OK status after following redirects.
317
+ - **`summary`** - Required summary description (raises error if not set)
318
+ - **`description`** - Required full description (raises error if not set)
319
+
320
+ #### Core Recommended Attributes
321
+
322
+ - **`licenses`** - Default: `Set[]`. License information for the gem
323
+ - **`required_ruby_version`** - Default: `nil`. Ruby version requirement
324
+
325
+ #### Build and Package Configuration
326
+
327
+ - **`require_paths`** - Default: `Set['lib']` (mapped to `require_paths`)
328
+ - **`test_dir`** - Default: `nil`
329
+ - **`spec_dir`** - Default: `nil`
330
+ - **`extensions`** - Default: `FileList['ext/**/extconf.rb']` (mapped to `extensions`)
331
+ - **`make`** - Default: `ENV['MAKE']` or system detection
332
+ - **`executables`** - Default: `Set[]` (mapped to `executables`)
333
+ - **`ignore_files`** - Default: `Set[]`
334
+ - **`package_ignore_files`** - Default: `Set[]`
335
+
336
+ #### Documentation and Files
337
+
338
+ - **`readme`** - Default: `nil`
339
+ - **`title`** - Default: `nil`
340
+ - **`doc_files`** - Default: `nil`
341
+ - **`yard_dir`** - Default: `nil`
342
+
343
+ #### Testing Configuration
344
+
345
+ - **`test_files`** - Default: `nil`
346
+ - **`spec_pattern`** - Default: `nil`
347
+ - **`bindir`** - Default: `nil` (mapped to `bindir`)
348
+
349
+ #### RVM Configuration (Nested)
350
+
351
+ ```ruby
352
+ rvm do
353
+ use # Default: detected ruby version from `rvm tools strings`
354
+ gemset # Default: gem name
355
+ end
356
+ ```
357
+
358
+ #### Task Dependencies
359
+
360
+ - **`default_task_dependencies`** - Default: `[:gemspec, :test]`
361
+ - **`build_task_dependencies`** - Default: `[:clobber, :gemspec, :package, :'version:tag']`
362
+ - **`push_task_dependencies`** - Default: `[:modified, :build, :master:push, :version:push, :gem:push, :github:release]`
363
+
364
+ #### Configuration Flags
365
+
366
+ - **`developing`** - Default: `false`. When set to `true`, skips URL validation including homepage link verification for faster development cycles.
367
+
368
+ ### Paths and Module Types
369
+
370
+ - **`path_name`** - Default: `name`. Returns the raw gem name value by default.
371
+ It is used for generating file paths and module names. This is particularly
372
+ useful for creating consistent directory structures and file naming
373
+ conventions. It's used internally by `GemHadar` to create the root directory
374
+ for the gem (`lib/my_gem` for name "my\_gem") and generate a `version.rb` file
375
+ in that location.
376
+
377
+ This can be changed for nested namespaces if desired.
378
+
379
+ **Example**: For gems in namespaces like `ACME` like
380
+ `ACME::BrainfuckCompiler`, you might set `path_name` to
381
+ `"acme/brainfuck_compiler"` to create the directory structure
382
+ `lib/acme/brainfuck_compiler/`.
383
+
384
+ - **`path_module`** - Default: `path_name.camelize`. Automatically converts the
385
+ gem name to CamelCase format (e.g., "my\_gem" becomes "MyGem",
386
+ "namespace/my\_gem" becomes "Namespace::MyGem") for use in Ruby module and
387
+ class declarations, ensuring consistency with Ruby naming
388
+ conventions. This value can be overridden if needed.
389
+
390
+ - **`module_type`** - Default: `:module`. Determines whether the generated code
391
+ structure for the version module should be a `:module` or `:class`. This
392
+ controls the type of Ruby construct created when generating code skeletons and
393
+ version files. The value
394
+ can be set to either:
395
+
396
+ - `:module` (default) - Generates module-based structure
397
+ - `:class` - Generates class-based structure
398
+
399
+ This is used in the generated `version.rb` file to create either:
400
+ ```ruby
401
+ module MyGem
402
+ # ... version constants
403
+ end
404
+ ```
405
+ or
406
+ ```ruby
407
+ class MyGem
408
+ # ... version constants
409
+ end
410
+ ```
411
+
412
+ These computed values serve as intelligent defaults that can be overridden
413
+ based on your specific requirements. They are automatically derived from other
414
+ DSL accessors and provide powerful convenience features that enable `GemHadar`
415
+ to generate consistent, well-structured Ruby code automatically.
416
+
163
417
  ### Available Tasks
164
418
 
165
419
  You can list all available tasks with:
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.26.0
1
+ 1.27.0
data/gem_hadar.gemspec CHANGED
@@ -1,9 +1,9 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: gem_hadar 1.26.0 ruby lib
2
+ # stub: gem_hadar 1.27.0 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "gem_hadar".freeze
6
- s.version = "1.26.0".freeze
6
+ s.version = "1.27.0".freeze
7
7
 
8
8
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
9
9
  s.require_paths = ["lib".freeze]
@@ -22,7 +22,7 @@ Gem::Specification.new do |s|
22
22
 
23
23
  s.specification_version = 4
24
24
 
25
- s.add_development_dependency(%q<gem_hadar>.freeze, ["~> 1.26".freeze])
25
+ s.add_development_dependency(%q<gem_hadar>.freeze, ["~> 1.27".freeze])
26
26
  s.add_runtime_dependency(%q<tins>.freeze, ["~> 1.0".freeze])
27
27
  s.add_runtime_dependency(%q<term-ansicolor>.freeze, ["~> 1.0".freeze])
28
28
  s.add_runtime_dependency(%q<ollama-ruby>.freeze, ["~> 1.0".freeze])
@@ -1,4 +1,20 @@
1
+ require 'pathname'
2
+
1
3
  module GemHadar::Utils
4
+ # The xdg_config_home method determines the path to the XDG configuration
5
+ # directory.
6
+ #
7
+ # It first checks if the XDG_CONFIG_HOME environment variable is set and not
8
+ # empty. If it is set, the method returns the value as a Pathname object. If
9
+ # XDG_CONFIG_HOME is not set, it defaults to using the HOME environment
10
+ # variable to construct the path within the standard .config directory.
11
+ #
12
+ # @return [ Pathname ] the Pathname object representing the XDG configuration directory
13
+ def xdg_config_home
14
+ ENV['XDG_CONFIG_HOME'].full? { Pathname.new(_1) } ||
15
+ Pathname.new(ENV.fetch('HOME')) + '.config'
16
+ end
17
+
2
18
  # The xdg_config_filename method constructs the full path to a configuration
3
19
  # file based on the XDG Base Directory specification.
4
20
  #
@@ -12,11 +28,7 @@ module GemHadar::Utils
12
28
  #
13
29
  # @return [ String ] the full path to the configuration file
14
30
  def xdg_config_filename(name)
15
- if xdg = ENV['XDG_CONFIG_HOME'].full?
16
- File.join(xdg, name)
17
- else
18
- File.join(ENV.fetch('HOME'), '.config', name)
19
- end
31
+ xdg_config_home + name
20
32
  end
21
33
 
22
34
  memoize method:
@@ -1,6 +1,6 @@
1
1
  class GemHadar
2
2
  # GemHadar version
3
- VERSION = '1.26.0'
3
+ VERSION = '1.27.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:
data/lib/gem_hadar.rb CHANGED
@@ -1082,12 +1082,79 @@ class GemHadar
1082
1082
  task :yard => %i[ yard:private yard:view ]
1083
1083
  end
1084
1084
 
1085
+ def config_task
1086
+ namespace :gem_hadar do
1087
+ desc "Display current gem_hadar configuration"
1088
+ task :config do
1089
+ puts "=== GemHadar Configuration ==="
1090
+
1091
+ # RubyGems
1092
+ if ENV['GEM_HOST_API_KEY'].present?
1093
+ puts "RubyGems API Key: *** (set)"
1094
+ else
1095
+ puts "RubyGems API Key: Not set"
1096
+ end
1097
+
1098
+ # GitHub
1099
+ if ENV['GITHUB_API_TOKEN'].present?
1100
+ puts "GitHub API Token: *** (set)"
1101
+ else
1102
+ puts "GitHub API Token: Not set"
1103
+ end
1104
+
1105
+ # Ollama
1106
+ puts "Ollama Model: #{ollama_model} (default is #{ollama_model_default})"
1107
+
1108
+ if url = ollama_client&.full?(:base_url)&.to_s
1109
+ puts "Ollama Base URL: #{url.inspect}"
1110
+ else
1111
+ puts "Ollama Base URL: Not set"
1112
+ end
1113
+
1114
+ if ENV['OLLAMA_MODEL_OPTIONS']
1115
+ puts "Ollama Model Options: #{ENV['OLLAMA_MODEL_OPTIONS']}"
1116
+ else
1117
+ puts "Ollama Model Options: Not set (using defaults)"
1118
+ end
1119
+
1120
+ # XDG config home
1121
+ puts "XDG config home: #{xdg_config_home.to_s.inspect}"
1122
+
1123
+ # General
1124
+ puts "Gem Name: #{name}"
1125
+ puts "Version: #{version}"
1126
+
1127
+ # Build/Development
1128
+ puts "MAKE: #{ENV['MAKE'] || 'Not set (will use gmake or make)'}"
1129
+ puts "EDITOR: #{ENV['EDITOR'] || 'Not set (will use vi)'}"
1130
+
1131
+ # Git
1132
+ puts "Git Remote(s): #{ENV['GIT_REMOTE'] || 'origin'}"
1133
+
1134
+ # Other
1135
+ puts "Force Operations: #{ENV['FORCE'] || '0'}"
1136
+ puts "Version Override: #{ENV['VERSION'] || 'Not set'}"
1137
+ puts "GitHub Release Enabled: #{ENV['GITHUB_RELEASE_ENABLED'] || 'Not set'}"
1138
+
1139
+ puts "\n=== AI Prompt Configuration (Default Values) ==="
1140
+ arrow = ?⤵
1141
+ puts bold{"version_bump_system_prompt.txt"} + "#{arrow}\n" + italic{default_version_bump_system_prompt}
1142
+ puts bold{"version_bump_prompt.txt"} + "#{arrow}\n#{default_version_bump_prompt}"
1143
+ puts bold{"release_system_prompt.txt"} + "#{arrow}\n" + italic{default_git_release_system_prompt}
1144
+ puts bold{"release_prompt.txt"} + "#{arrow}\n" + italic{default_git_release_prompt}
1145
+
1146
+ puts "=== End Configuration ==="
1147
+ end
1148
+ end
1149
+ end
1150
+
1085
1151
  # The create_all_tasks method sets up and registers all the Rake tasks for
1086
1152
  # the gem project.
1087
1153
  #
1088
1154
  # @return [GemHadar] the instance of GemHadar
1089
1155
  def create_all_tasks
1090
1156
  default_task
1157
+ config_task
1091
1158
  build_task
1092
1159
  rvm_task
1093
1160
  version_task
@@ -1144,20 +1211,53 @@ class GemHadar
1144
1211
  temp_file&.close&.unlink
1145
1212
  end
1146
1213
 
1214
+ dsl_accessor :ollama_model_default, 'llama3.1'.freeze
1215
+
1216
+ # The ollama_model method retrieves the name of the Ollama AI model to be
1217
+ # used for generating responses.
1218
+ #
1219
+ # It first checks the OLLAMA_MODEL environment variable for a custom model
1220
+ # specification. If the environment variable is not set, it falls back to
1221
+ # using the default model name, which is determined by the
1222
+ # ollama_model_default dsl method.
1223
+ #
1224
+ # @return [ String ] the name of the Ollama AI model to be used
1225
+ def ollama_model
1226
+ ENV.fetch('OLLAMA_MODEL', ollama_model_default)
1227
+ end
1228
+
1229
+ # The ollama_client method creates and returns an Ollama::Client instance
1230
+ # configured with a base URL derived from environment variables.
1231
+ #
1232
+ # It first checks for the OLLAMA_URL environment variable to determine the
1233
+ # base URL. If that is not set, it falls back to using the OLLAMA_HOST
1234
+ # environment variable, defaulting to 'localhost:11434' if that is also not
1235
+ # set. The method then constructs the full base URL and initializes an
1236
+ # Ollama::Client with appropriate timeouts for read and connect operations.
1237
+ #
1238
+ # @return [Ollama::Client, nil] An initialized Ollama::Client instance if a valid base URL is present, otherwise nil.
1239
+ def ollama_client
1240
+ base_url = ENV['OLLAMA_URL']
1241
+ if base_url.blank?
1242
+ host = ENV.fetch('OLLAMA_HOST', 'localhost:11434')
1243
+ base_url = 'http://%s' % host
1244
+ end
1245
+ base_url.present? or return
1246
+ ollama = Ollama::Client.new(base_url:, read_timeout: 600, connect_timeout: 60)
1247
+ end
1248
+
1147
1249
  # Generates a response from an AI model using the Ollama::Client.
1148
1250
  #
1149
1251
  # @param [String] system The system prompt for the AI model.
1150
1252
  # @param [String] prompt The user prompt to generate a response to.
1151
1253
  # @return [String, nil] The generated response or nil if generation fails.
1152
1254
  def ollama_generate(system:, prompt:)
1153
- base_url = ENV['OLLAMA_URL']
1154
- if base_url.blank? && host = ENV['OLLAMA_HOST'].full?
1155
- base_url = 'http://%s' % host
1255
+ unless ollama = ollama_client
1256
+ warn "Ollama is not configured. => Returning."
1257
+ return
1156
1258
  end
1157
- base_url.present? or return
1158
- ollama = Ollama::Client.new(base_url:, read_timeout: 600, connect_timeout: 60)
1159
- model = ENV.fetch('OLLAMA_MODEL', 'llama3.1')
1160
- options = ENV['OLLAMA_OPTIONS'].full? { |o| JSON.parse(o) } || {}
1259
+ model = ollama_model
1260
+ options = ENV['OLLAMA_MODEL_OPTIONS'].full? { |o| JSON.parse(o) } || {}
1161
1261
  options |= { "temperature" => 0, "top_p" => 1, "min_p" => 0.1 }
1162
1262
  ollama.generate(model:, system:, prompt:, options:, stream: false, think: false).response
1163
1263
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gem_hadar
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.26.0
4
+ version: 1.27.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Frank
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: '1.26'
18
+ version: '1.27'
19
19
  type: :development
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
- version: '1.26'
25
+ version: '1.27'
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: tins
28
28
  requirement: !ruby/object:Gem::Requirement