Skip to content

Commit b8bd6b4

Browse files
committed
✨ Add preset type categorization for command specificity
Add support for command-specific instruction presets This enhancement improves preset management by categorizing presets: - Add PresetType enum (Commit, Review, Both) to distinguish usage context - Add specialized review presets: security, performance, architecture, etc. - Update list-presets command to show categorized output by type - Add validation to warn when using incorrect preset types - Update documentation to reflect preset categorization - Modify help text to guide users to appropriate presets Users can now clearly identify which presets are suitable for commit messages versus code reviews, improving the overall experience.
1 parent d3799cb commit b8bd6b4

File tree

8 files changed

+316
-50
lines changed

8 files changed

+316
-50
lines changed

README.md

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -256,24 +256,38 @@ To list available presets:
256256
git-iris list-presets
257257
```
258258

259-
This will display a list of all available presets with a brief description of each.
259+
This will display a list of all available presets with a brief description of each, categorized by type (general, review-specific, or commit-specific).
260260

261261
Some key presets include:
262262

263-
- `default`: Standard commit message style
263+
- `default`: Standard professional style (for both commits and reviews)
264264
- `conventional`: Follows the Conventional Commits specification
265-
- `detailed`: Provides more context and explanation in commit messages
266-
- `concise`: Short and to-the-point commit messages
267-
- `cosmic`: Mystical, space-themed commit messages
268-
- ..and lots more styles
265+
- `detailed`: Provides more context and explanation
266+
- `concise`: Short and to-the-point responses
267+
- `cosmic`: Mystical, space-themed language
268+
269+
For code reviews specifically, Git-Iris includes specialized presets:
270+
271+
- `security`: Focus on security vulnerabilities and best practices
272+
- `performance`: Analyze code for performance optimizations
273+
- `architecture`: Evaluate architectural patterns and design decisions
274+
- `testing`: Focus on test coverage and testing strategies
275+
- `maintainability`: Evaluate code for long-term maintenance
276+
- `conventions`: Check adherence to language and project coding standards
269277

270278
To use a preset for a single commit:
271279

272280
```bash
273281
git-iris gen --preset conventional
274282
```
275283

276-
To set a default preset for all commits:
284+
To use a preset for a code review:
285+
286+
```bash
287+
git-iris review --preset security
288+
```
289+
290+
To set a default preset:
277291

278292
```bash
279293
git-iris config --preset conventional

docs/code-review-docs.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,22 @@ You can use instruction presets to guide the review:
9999
git-iris review --preset security
100100
```
101101

102-
This will apply security-focused instructions to the review process.
102+
Git-Iris now includes several review-specific presets:
103+
104+
- `security` - Focus on security vulnerabilities and best practices
105+
- `performance` - Analyze code for performance optimizations
106+
- `architecture` - Evaluate architectural patterns and design decisions
107+
- `testing` - Focus on test coverage and testing strategies
108+
- `maintainability` - Evaluate code for long-term maintenance
109+
- `conventions` - Check adherence to language and project coding standards
110+
111+
You can view all available presets with:
112+
113+
```bash
114+
git-iris list-presets
115+
```
116+
117+
This will display all presets categorized by their type (general, review-specific, or commit-specific).
103118

104119
## 5. Review Output Format
105120

src/commands.rs

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use crate::ProviderConfig;
22
use crate::common::CommonParams;
33
use crate::config::Config;
4-
use crate::instruction_presets::get_instruction_preset_library;
4+
use crate::instruction_presets::{
5+
PresetType, get_instruction_preset_library, list_presets_formatted_by_type,
6+
};
57
use crate::llm_providers::get_available_providers;
68
use crate::log_debug;
79
use crate::ui;
@@ -10,8 +12,6 @@ use anyhow::{Result, anyhow};
1012
use colored::Colorize;
1113
use std::collections::HashMap;
1214

13-
use unicode_width::UnicodeWidthStr;
14-
1515
/// Handle the 'config' command
1616
#[allow(clippy::too_many_lines)]
1717
pub fn handle_config_command(
@@ -160,44 +160,40 @@ fn parse_additional_params(params: &[String]) -> HashMap<String, String> {
160160

161161
/// Handle the '`list_presets`' command
162162
pub fn handle_list_presets_command() -> Result<()> {
163-
let preset_library = get_instruction_preset_library();
163+
let library = get_instruction_preset_library();
164+
165+
// Get different categories of presets
166+
let both_presets = list_presets_formatted_by_type(&library, Some(PresetType::Both));
167+
let commit_only_presets = list_presets_formatted_by_type(&library, Some(PresetType::Commit));
168+
let review_only_presets = list_presets_formatted_by_type(&library, Some(PresetType::Review));
169+
170+
println!(
171+
"{}",
172+
"\nGit-Iris Instruction Presets\n".bright_magenta().bold()
173+
);
164174

165175
println!(
166176
"{}",
167-
"\n🔮 Available Instruction Presets 🔮"
168-
.bright_purple()
177+
"General Presets (usable for both commit and review):"
178+
.bright_cyan()
169179
.bold()
170180
);
171-
println!("{}", "━".repeat(50).bright_purple());
181+
println!("{both_presets}\n");
172182

173-
let mut presets = preset_library.list_presets();
174-
presets.sort_by(|a, b| a.0.cmp(b.0)); // Sort alphabetically by key
183+
if !commit_only_presets.is_empty() {
184+
println!("{}", "Commit-specific Presets:".bright_green().bold());
185+
println!("{commit_only_presets}\n");
186+
}
175187

176-
let max_key_length = presets
177-
.iter()
178-
.map(|(key, _)| key.width())
179-
.max()
180-
.unwrap_or(0);
181-
182-
for (key, preset) in presets {
183-
println!(
184-
"{} {:<width$} {}",
185-
"•".bright_cyan(),
186-
key.bright_green().bold(),
187-
preset.name.cyan().italic(),
188-
width = max_key_length
189-
);
190-
println!(" {}", format!("\"{}\"", preset.description).bright_white());
191-
println!(); // Add a blank line between presets
188+
if !review_only_presets.is_empty() {
189+
println!("{}", "Review-specific Presets:".bright_blue().bold());
190+
println!("{review_only_presets}\n");
192191
}
193192

194-
println!("{}", "━".repeat(50).bright_purple());
195-
println!(
196-
"{}",
197-
"Use with: git-iris gen --preset <preset-name>"
198-
.bright_yellow()
199-
.italic()
200-
);
193+
println!("{}", "Usage:".bright_yellow().bold());
194+
println!(" git-iris gen --preset <preset-key>");
195+
println!(" git-iris review --preset <preset-key>");
196+
println!("\nPreset types: [B] = Both commands, [C] = Commit only, [R] = Review only");
201197

202198
Ok(())
203199
}

src/commit/cli.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use super::service::IrisCommitService;
33
use crate::common::CommonParams;
44
use crate::config::Config;
55
use crate::context::format_commit_message;
6+
use crate::instruction_presets::PresetType;
67
use crate::llm_providers::LLMProviderType;
78
use crate::messages;
89
use crate::tui::run_tui_commit;
@@ -19,6 +20,14 @@ pub async fn handle_gen_command(
1920
print: bool,
2021
verify: bool,
2122
) -> Result<()> {
23+
// Check if the preset is appropriate for commit messages
24+
if !common.is_valid_preset_for_type(PresetType::Commit) {
25+
ui::print_warning(
26+
"The specified preset may not be suitable for commit messages. Consider using a commit or general preset instead.",
27+
);
28+
ui::print_info("Run 'git-iris list-presets' to see available presets for commits.");
29+
}
30+
2231
let mut config = Config::load()?;
2332
common.apply_to_config(&mut config)?;
2433
let current_dir = std::env::current_dir()?;

src/commit/review.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use super::service::IrisCommitService;
22
use crate::common::CommonParams;
33
use crate::config::Config;
4+
use crate::instruction_presets::PresetType;
45
use crate::llm_providers::LLMProviderType;
56
use crate::messages;
67
use crate::ui;
@@ -11,6 +12,14 @@ use std::sync::Arc;
1112

1213
/// Handles the review command which generates an AI code review of staged changes
1314
pub async fn handle_review_command(common: CommonParams, print: bool) -> Result<()> {
15+
// Check if the preset is appropriate for code reviews
16+
if !common.is_valid_preset_for_type(PresetType::Review) {
17+
ui::print_warning(
18+
"The specified preset may not be suitable for code reviews. Consider using a review or general preset instead.",
19+
);
20+
ui::print_info("Run 'git-iris list-presets' to see available presets for reviews.");
21+
}
22+
1423
let mut config = Config::load()?;
1524
common.apply_to_config(&mut config)?;
1625
let current_dir = std::env::current_dir()?;

src/commit/service.rs

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use super::prompt::{create_system_prompt, create_user_prompt, process_commit_mes
77
use crate::config::Config;
88
use crate::context::{CommitContext, GeneratedMessage, GeneratedReview};
99
use crate::git::{CommitResult, GitRepo};
10+
use crate::instruction_presets::{PresetType, get_instruction_preset_library};
1011
use crate::llm;
1112
use crate::llm_providers::{LLMProviderType, get_provider_metadata};
1213
use crate::log_debug;
@@ -171,7 +172,26 @@ impl IrisCommitService {
171172
instructions: &str,
172173
) -> anyhow::Result<GeneratedMessage> {
173174
let mut config_clone = self.config.clone();
174-
config_clone.instruction_preset = preset.to_string();
175+
176+
// Check if the preset exists and is valid for commits
177+
if preset.is_empty() {
178+
config_clone.instruction_preset = "default".to_string();
179+
} else {
180+
let library = get_instruction_preset_library();
181+
if let Some(preset_info) = library.get_preset(preset) {
182+
if preset_info.preset_type == PresetType::Review {
183+
log_debug!(
184+
"Warning: Preset '{}' is review-specific, not ideal for commits",
185+
preset
186+
);
187+
}
188+
config_clone.instruction_preset = preset.to_string();
189+
} else {
190+
log_debug!("Preset '{}' not found, using default", preset);
191+
config_clone.instruction_preset = "default".to_string();
192+
}
193+
}
194+
175195
config_clone.instructions = instructions.to_string();
176196

177197
let context = self.get_git_info().await?;
@@ -215,7 +235,26 @@ impl IrisCommitService {
215235
instructions: &str,
216236
) -> anyhow::Result<GeneratedReview> {
217237
let mut config_clone = self.config.clone();
218-
config_clone.instruction_preset = preset.to_string();
238+
239+
// Check if the preset exists and is valid for reviews
240+
if preset.is_empty() {
241+
config_clone.instruction_preset = "default".to_string();
242+
} else {
243+
let library = get_instruction_preset_library();
244+
if let Some(preset_info) = library.get_preset(preset) {
245+
if preset_info.preset_type == PresetType::Commit {
246+
log_debug!(
247+
"Warning: Preset '{}' is commit-specific, not ideal for reviews",
248+
preset
249+
);
250+
}
251+
config_clone.instruction_preset = preset.to_string();
252+
} else {
253+
log_debug!("Preset '{}' not found, using default", preset);
254+
config_clone.instruction_preset = "default".to_string();
255+
}
256+
}
257+
219258
config_clone.instructions = instructions.to_string();
220259

221260
let context = self.get_git_info().await?;

src/common.rs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::config::Config;
2-
use crate::instruction_presets::get_instruction_preset_library;
2+
use crate::instruction_presets::{PresetType, get_instruction_preset_library};
33
use crate::llm_providers::LLMProviderType;
44
use anyhow::Result;
55
use clap::Args;
@@ -46,7 +46,10 @@ pub struct CommonParams {
4646
pub instructions: Option<String>,
4747

4848
/// Select an instruction preset
49-
#[arg(long, help = "Select an instruction preset")]
49+
#[arg(
50+
long,
51+
help = "Select an instruction preset (use 'git-iris list-presets' to see available presets for commits and reviews)"
52+
)]
5053
pub preset: Option<String>,
5154

5255
/// Enable or disable Gitmoji
@@ -78,6 +81,16 @@ impl CommonParams {
7881
}
7982
Ok(())
8083
}
84+
85+
/// Check if the provided preset is valid for the specified preset type
86+
pub fn is_valid_preset_for_type(&self, preset_type: PresetType) -> bool {
87+
if let Some(preset_name) = &self.preset {
88+
let library = get_instruction_preset_library();
89+
let valid_presets = library.list_valid_presets_for_command(preset_type);
90+
return valid_presets.iter().any(|(key, _)| *key == preset_name);
91+
}
92+
true // No preset specified is always valid
93+
}
8194
}
8295

8396
/// Validate provider input against available providers
@@ -100,14 +113,14 @@ pub fn get_combined_instructions(config: &Config) -> String {
100113
if let Some(preset_instructions) = preset_library.get_preset(config.instruction_preset.as_str())
101114
{
102115
prompt.push_str(&format!(
103-
"\n\nUse this style for the commit message:\n{}\n\n",
116+
"\n\nUse this style for your output:\n{}\n\n",
104117
preset_instructions.instructions
105118
));
106119
}
107120

108121
if !config.instructions.is_empty() {
109122
prompt.push_str(&format!(
110-
"\n\nAdditional instructions for the commit message:\n{}\n\n",
123+
"\n\nAdditional instructions for the request:\n{}\n\n",
111124
config.instructions
112125
));
113126
}

0 commit comments

Comments
 (0)