@@ -27,7 +27,10 @@ impl PoetryManager {
2727 if let Some ( executable) = executable {
2828 if executable. is_file ( ) {
2929 let version = Self :: extract_version_from_path ( & executable) ;
30- return Some ( PoetryManager { executable, version } ) ;
30+ return Some ( PoetryManager {
31+ executable,
32+ version,
33+ } ) ;
3134 }
3235 }
3336
@@ -119,7 +122,10 @@ impl PoetryManager {
119122 for executable in search_paths {
120123 if executable. is_file ( ) {
121124 let version = Self :: extract_version_from_path ( & executable) ;
122- return Some ( PoetryManager { executable, version } ) ;
125+ return Some ( PoetryManager {
126+ executable,
127+ version,
128+ } ) ;
123129 }
124130 }
125131
@@ -129,13 +135,19 @@ impl PoetryManager {
129135 let executable = each. join ( "poetry" ) ;
130136 if executable. is_file ( ) {
131137 let version = Self :: extract_version_from_path ( & executable) ;
132- return Some ( PoetryManager { executable, version } ) ;
138+ return Some ( PoetryManager {
139+ executable,
140+ version,
141+ } ) ;
133142 }
134143 if std:: env:: consts:: OS == "windows" {
135144 let executable = each. join ( "poetry.exe" ) ;
136145 if executable. is_file ( ) {
137146 let version = Self :: extract_version_from_path ( & executable) ;
138- return Some ( PoetryManager { executable, version } ) ;
147+ return Some ( PoetryManager {
148+ executable,
149+ version,
150+ } ) ;
139151 }
140152 }
141153 }
@@ -162,7 +174,11 @@ impl PoetryManager {
162174 if let Some ( captures) = HOMEBREW_POETRY_VERSION . captures ( & path_str) {
163175 if let Some ( version_match) = captures. get ( 1 ) {
164176 let version = version_match. as_str ( ) . to_string ( ) ;
165- trace ! ( "Extracted Poetry version {} from Homebrew path: {:?}" , version, resolved) ;
177+ trace ! (
178+ "Extracted Poetry version {} from Homebrew path: {:?}" ,
179+ version,
180+ resolved
181+ ) ;
166182 return Some ( version) ;
167183 }
168184 }
@@ -176,4 +192,97 @@ impl PoetryManager {
176192 tool : EnvManagerType :: Poetry ,
177193 }
178194 }
195+
196+ /// Extracts version from a path string using the Homebrew Cellar regex.
197+ /// This is exposed for testing purposes.
198+ #[ cfg( test) ]
199+ fn extract_version_from_path_str ( path_str : & str ) -> Option < String > {
200+ if let Some ( captures) = HOMEBREW_POETRY_VERSION . captures ( path_str) {
201+ captures. get ( 1 ) . map ( |m| m. as_str ( ) . to_string ( ) )
202+ } else {
203+ None
204+ }
205+ }
206+ }
207+
208+ #[ cfg( test) ]
209+ mod tests {
210+ use super :: * ;
211+
212+ #[ test]
213+ fn test_extract_version_macos_arm ( ) {
214+ // macOS ARM Homebrew path
215+ let path = "/opt/homebrew/Cellar/poetry/1.8.3/bin/poetry" ;
216+ assert_eq ! (
217+ PoetryManager :: extract_version_from_path_str( path) ,
218+ Some ( "1.8.3" . to_string( ) )
219+ ) ;
220+ }
221+
222+ #[ test]
223+ fn test_extract_version_macos_arm_with_revision ( ) {
224+ // macOS ARM Homebrew path with revision suffix
225+ let path = "/opt/homebrew/Cellar/poetry/1.8.3_2/bin/poetry" ;
226+ assert_eq ! (
227+ PoetryManager :: extract_version_from_path_str( path) ,
228+ Some ( "1.8.3" . to_string( ) )
229+ ) ;
230+ }
231+
232+ #[ test]
233+ fn test_extract_version_macos_intel ( ) {
234+ // macOS Intel Homebrew path
235+ let path = "/usr/local/Cellar/poetry/2.0.1/bin/poetry" ;
236+ assert_eq ! (
237+ PoetryManager :: extract_version_from_path_str( path) ,
238+ Some ( "2.0.1" . to_string( ) )
239+ ) ;
240+ }
241+
242+ #[ test]
243+ fn test_extract_version_linux ( ) {
244+ // Linux Homebrew path
245+ let path = "/home/linuxbrew/.linuxbrew/Cellar/poetry/1.7.0/bin/poetry" ;
246+ assert_eq ! (
247+ PoetryManager :: extract_version_from_path_str( path) ,
248+ Some ( "1.7.0" . to_string( ) )
249+ ) ;
250+ }
251+
252+ #[ test]
253+ fn test_extract_version_non_homebrew_path ( ) {
254+ // Non-Homebrew installation paths should return None
255+ let paths = [
256+ "/usr/local/bin/poetry" ,
257+ "/home/user/.local/bin/poetry" ,
258+ "/home/user/.poetry/bin/poetry" ,
259+ "C:\\ Users\\ user\\ AppData\\ Roaming\\ pypoetry\\ venv\\ Scripts\\ poetry.exe" ,
260+ ] ;
261+ for path in paths {
262+ assert_eq ! (
263+ PoetryManager :: extract_version_from_path_str( path) ,
264+ None ,
265+ "Expected None for path: {}" ,
266+ path
267+ ) ;
268+ }
269+ }
270+
271+ #[ test]
272+ fn test_extract_version_invalid_version_format ( ) {
273+ // Invalid version formats should not match
274+ let paths = [
275+ "/opt/homebrew/Cellar/poetry/invalid/bin/poetry" ,
276+ "/opt/homebrew/Cellar/poetry/1.8/bin/poetry" , // Missing patch version
277+ "/opt/homebrew/Cellar/poetry/v1.8.3/bin/poetry" , // Has 'v' prefix
278+ ] ;
279+ for path in paths {
280+ assert_eq ! (
281+ PoetryManager :: extract_version_from_path_str( path) ,
282+ None ,
283+ "Expected None for path: {}" ,
284+ path
285+ ) ;
286+ }
287+ }
179288}
0 commit comments