@@ -125,6 +125,33 @@ pub fn make_command(command: Command) -> Command {
125125 )
126126}
127127
128+ /// Parse plugin info from SENTRY_PIPELINE environment variable.
129+ /// Format: "sentry-gradle-plugin/4.12.0" or "sentry-fastlane-plugin/1.2.3"
130+ /// Returns (plugin_name, plugin_version) if a recognized plugin is found, (None, None) otherwise.
131+ fn parse_plugin_from_pipeline ( pipeline : Option < String > ) -> ( Option < String > , Option < String > ) {
132+ pipeline
133+ . and_then ( |pipeline| {
134+ let parts: Vec < & str > = pipeline. splitn ( 2 , '/' ) . collect ( ) ;
135+ if parts. len ( ) == 2 {
136+ let name = parts[ 0 ] ;
137+ let version = parts[ 1 ] ;
138+
139+ // Only extract known Sentry plugins
140+ if name == "sentry-gradle-plugin" || name == "sentry-fastlane-plugin" {
141+ debug ! ( "Detected {name} version {version} from SENTRY_PIPELINE" ) ;
142+ Some ( ( name. to_owned ( ) , version. to_owned ( ) ) )
143+ } else {
144+ debug ! ( "SENTRY_PIPELINE contains unrecognized plugin: {name}" ) ;
145+ None
146+ }
147+ } else {
148+ debug ! ( "SENTRY_PIPELINE format not recognized: {pipeline}" ) ;
149+ None
150+ }
151+ } )
152+ . unzip ( )
153+ }
154+
128155pub fn execute ( matches : & ArgMatches ) -> Result < ( ) > {
129156 let config = Config :: current ( ) ;
130157 let path_strings = matches
@@ -150,30 +177,7 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
150177 let build_configuration = matches. get_one ( "build_configuration" ) . map ( String :: as_str) ;
151178 let release_notes = matches. get_one ( "release_notes" ) . map ( String :: as_str) ;
152179
153- // Parse plugin info from SENTRY_PIPELINE environment variable
154- // Format: "sentry-gradle-plugin/4.12.0" or "sentry-fastlane-plugin/1.2.3"
155- let ( plugin_name, plugin_version) = config
156- . get_pipeline_env ( )
157- . and_then ( |pipeline| {
158- let parts: Vec < & str > = pipeline. splitn ( 2 , '/' ) . collect ( ) ;
159- if parts. len ( ) == 2 {
160- let name = parts[ 0 ] ;
161- let version = parts[ 1 ] ;
162-
163- // Only extract known Sentry plugins
164- if name == "sentry-gradle-plugin" || name == "sentry-fastlane-plugin" {
165- debug ! ( "Detected {name} version {version} from SENTRY_PIPELINE" ) ;
166- Some ( ( name. to_owned ( ) , version. to_owned ( ) ) )
167- } else {
168- debug ! ( "SENTRY_PIPELINE contains unrecognized plugin: {name}" ) ;
169- None
170- }
171- } else {
172- debug ! ( "SENTRY_PIPELINE format not recognized: {pipeline}" ) ;
173- None
174- }
175- } )
176- . unzip ( ) ;
180+ let ( plugin_name, plugin_version) = parse_plugin_from_pipeline ( config. get_pipeline_env ( ) ) ;
177181
178182 let api = Api :: current ( ) ;
179183 let authenticated_api = api. authenticated ( ) ?;
@@ -1015,4 +1019,58 @@ mod tests {
10151019 ) ;
10161020 Ok ( ( ) )
10171021 }
1022+
1023+ #[ test]
1024+ fn test_parse_gradle_plugin_from_pipeline ( ) {
1025+ let ( name, version) =
1026+ parse_plugin_from_pipeline ( Some ( "sentry-gradle-plugin/4.12.0" . to_owned ( ) ) ) ;
1027+ assert_eq ! ( name, Some ( "sentry-gradle-plugin" . to_owned( ) ) ) ;
1028+ assert_eq ! ( version, Some ( "4.12.0" . to_owned( ) ) ) ;
1029+ }
1030+
1031+ #[ test]
1032+ fn test_parse_fastlane_plugin_from_pipeline ( ) {
1033+ let ( name, version) =
1034+ parse_plugin_from_pipeline ( Some ( "sentry-fastlane-plugin/1.2.3" . to_owned ( ) ) ) ;
1035+ assert_eq ! ( name, Some ( "sentry-fastlane-plugin" . to_owned( ) ) ) ;
1036+ assert_eq ! ( version, Some ( "1.2.3" . to_owned( ) ) ) ;
1037+ }
1038+
1039+ #[ test]
1040+ fn test_parse_unrecognized_plugin_from_pipeline ( ) {
1041+ let ( name, version) =
1042+ parse_plugin_from_pipeline ( Some ( "some-other-plugin/1.0.0" . to_owned ( ) ) ) ;
1043+ assert_eq ! ( name, None , "Unrecognized plugin should return None" ) ;
1044+ assert_eq ! ( version, None , "Unrecognized plugin should return None" ) ;
1045+ }
1046+
1047+ #[ test]
1048+ fn test_parse_invalid_pipeline_format ( ) {
1049+ let ( name, version) = parse_plugin_from_pipeline ( Some ( "no-slash-in-value" . to_owned ( ) ) ) ;
1050+ assert_eq ! ( name, None , "Invalid format should return None" ) ;
1051+ assert_eq ! ( version, None , "Invalid format should return None" ) ;
1052+ }
1053+
1054+ #[ test]
1055+ fn test_parse_empty_pipeline ( ) {
1056+ let ( name, version) = parse_plugin_from_pipeline ( None ) ;
1057+ assert_eq ! ( name, None , "Empty pipeline should return None" ) ;
1058+ assert_eq ! ( version, None , "Empty pipeline should return None" ) ;
1059+ }
1060+
1061+ #[ test]
1062+ fn test_parse_pipeline_with_extra_slashes ( ) {
1063+ let ( name, version) =
1064+ parse_plugin_from_pipeline ( Some ( "sentry-gradle-plugin/4.12.0/extra" . to_owned ( ) ) ) ;
1065+ assert_eq ! (
1066+ name,
1067+ Some ( "sentry-gradle-plugin" . to_owned( ) ) ,
1068+ "Should parse correctly even with extra slashes"
1069+ ) ;
1070+ assert_eq ! (
1071+ version,
1072+ Some ( "4.12.0/extra" . to_owned( ) ) ,
1073+ "Version should include everything after first slash"
1074+ ) ;
1075+ }
10181076}
0 commit comments