1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use crate::core::lifecycle::LifecyclePhase;
use std::str::FromStr;
/// Goal parser - parses Maven goals and maps them to lifecycle phases
pub struct GoalParser;
/// Parsed goal information
#[derive(Debug, Clone)]
pub enum Goal {
/// Lifecycle phase goal (e.g., "compile", "package")
Phase(LifecyclePhase),
/// Plugin goal (e.g., "compiler:compile", "surefire:test")
Plugin {
group_id: Option<String>,
artifact_id: String,
goal: String,
},
}
impl GoalParser {
pub fn new() -> Self {
Self
}
/// Parse a goal string into a Goal
pub fn parse(&self, goal_str: &str) -> Result<Goal, String> {
// Check if it's a lifecycle phase
if let Ok(phase) = LifecyclePhase::from_str(goal_str) {
return Ok(Goal::Phase(phase));
}
// Check if it's a plugin goal (format: groupId:artifactId:goal or artifactId:goal)
if goal_str.contains(':') {
let parts: Vec<&str> = goal_str.split(':').collect();
match parts.len() {
2 => {
// artifactId:goal
Ok(Goal::Plugin {
group_id: None,
artifact_id: parts[0].to_string(),
goal: parts[1].to_string(),
})
}
3 => {
// groupId:artifactId:goal
Ok(Goal::Plugin {
group_id: Some(parts[0].to_string()),
artifact_id: parts[1].to_string(),
goal: parts[2].to_string(),
})
}
_ => Err(format!("Invalid goal format: {goal_str}")),
}
} else {
Err(format!("Unknown goal: {goal_str}"))
}
}
/// Parse multiple goals
pub fn parse_goals(&self, goals: &[String]) -> Result<Vec<Goal>, String> {
goals.iter()
.map(|g| self.parse(g))
.collect()
}
/// Get target phase from goals (highest phase if multiple phases specified)
pub fn get_target_phase(&self, goals: &[String]) -> Option<LifecyclePhase> {
let all_phases = LifecyclePhase::all();
let mut target_phase: Option<&LifecyclePhase> = None;
for goal_str in goals {
if let Ok(Goal::Phase(phase)) = self.parse(goal_str) {
// Find the phase in the lifecycle
if let Some(pos) = all_phases.iter().position(|p| p == &phase) {
let phase_ref = &all_phases[pos];
match target_phase {
None => target_phase = Some(phase_ref),
Some(current) => {
// Keep the later phase
if let Some(current_pos) = all_phases.iter().position(|p| p == current) {
if pos > current_pos {
target_phase = Some(phase_ref);
}
}
}
}
}
}
}
target_phase.cloned()
}
}
impl Default for GoalParser {
fn default() -> Self {
Self::new()
}
}