@@ -3,18 +3,12 @@ use std::fs;
33use anyhow:: { bail, Context as _, Result } ;
44use clap:: { Arg , ArgMatches , Command } ;
55use log:: debug;
6- use serde:: { Deserialize , Serialize } ;
76
7+ use crate :: api:: { Api , BulkCodeMapping , BulkCodeMappingsRequest } ;
88use crate :: config:: Config ;
9+ use crate :: utils:: formatting:: Table ;
910use crate :: utils:: vcs;
1011
11- #[ derive( Debug , Deserialize , Serialize ) ]
12- #[ serde( rename_all = "camelCase" ) ]
13- struct CodeMapping {
14- stack_root : String ,
15- source_root : String ,
16- }
17-
1812pub fn make_command ( command : Command ) -> Command {
1913 command
2014 . about ( "Upload code mappings for a project from a JSON file." )
@@ -39,11 +33,15 @@ pub fn make_command(command: Command) -> Command {
3933}
4034
4135pub fn execute ( matches : & ArgMatches ) -> Result < ( ) > {
36+ let config = Config :: current ( ) ;
37+ let org = config. get_org ( matches) ?;
38+ let project = config. get_project ( matches) ?;
39+
4240 #[ expect( clippy:: unwrap_used, reason = "path is a required argument" ) ]
4341 let path = matches. get_one :: < String > ( "path" ) . unwrap ( ) ;
4442 let data = fs:: read ( path) . with_context ( || format ! ( "Failed to read mappings file '{path}'" ) ) ?;
4543
46- let mappings: Vec < CodeMapping > =
44+ let mappings: Vec < BulkCodeMapping > =
4745 serde_json:: from_slice ( & data) . context ( "Failed to parse mappings JSON" ) ?;
4846
4947 if mappings. is_empty ( ) {
@@ -74,21 +72,19 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
7472 } ) ?;
7573 // Prefer explicit config (SENTRY_VCS_REMOTE / ini), then inspect
7674 // the repo for the best remote (upstream > origin > first).
77- let config = Config :: current ( ) ;
7875 let configured_remote = config. get_cached_vcs_remote ( ) ;
79- let remote_name =
80- if vcs:: git_repo_remote_url ( & git_repo, & configured_remote) . is_ok ( ) {
81- debug ! ( "Using configured VCS remote: {configured_remote}" ) ;
82- configured_remote
83- } else if let Some ( best) = vcs:: find_best_remote ( & git_repo) ? {
84- debug ! ( "Configured remote '{configured_remote}' not found, using: {best}" ) ;
85- best
86- } else {
87- bail ! (
88- "No remotes found in the git repository. \
76+ let remote_name = if vcs:: git_repo_remote_url ( & git_repo, & configured_remote) . is_ok ( ) {
77+ debug ! ( "Using configured VCS remote: {configured_remote}" ) ;
78+ configured_remote
79+ } else if let Some ( best) = vcs:: find_best_remote ( & git_repo) ? {
80+ debug ! ( "Configured remote '{configured_remote}' not found, using: {best}" ) ;
81+ best
82+ } else {
83+ bail ! (
84+ "No remotes found in the git repository. \
8985 Use --repo and --default-branch to specify manually."
90- ) ;
91- } ;
86+ ) ;
87+ } ;
9288
9389 let repo_name = match explicit_repo {
9490 Some ( r) => r. to_owned ( ) ,
@@ -121,9 +117,57 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
121117 }
122118 } ;
123119
124- println ! ( "Found {} code mapping(s) in {path}" , mappings. len( ) ) ;
125- println ! ( "Repository: {repo_name}" ) ;
126- println ! ( "Default branch: {default_branch}" ) ;
120+ let mapping_count = mappings. len ( ) ;
121+ let request = BulkCodeMappingsRequest {
122+ project,
123+ repository : repo_name,
124+ default_branch,
125+ mappings,
126+ } ;
127+
128+ println ! ( "Uploading {mapping_count} code mapping(s)..." ) ;
129+
130+ let api = Api :: current ( ) ;
131+ let response = api
132+ . authenticated ( ) ?
133+ . bulk_upload_code_mappings ( & org, & request) ?;
134+
135+ // Display results
136+ let mut table = Table :: new ( ) ;
137+ table
138+ . title_row ( )
139+ . add ( "Stack Root" )
140+ . add ( "Source Root" )
141+ . add ( "Status" ) ;
142+
143+ for result in & response. mappings {
144+ let status = match result. status . as_str ( ) {
145+ "error" => match & result. detail {
146+ Some ( detail) => format ! ( "error: {detail}" ) ,
147+ None => "error" . to_owned ( ) ,
148+ } ,
149+ s => s. to_owned ( ) ,
150+ } ;
151+ table
152+ . add_row ( )
153+ . add ( & result. stack_root )
154+ . add ( & result. source_root )
155+ . add ( & status) ;
156+ }
157+
158+ table. print ( ) ;
159+ println ! ( ) ;
160+ println ! (
161+ "Created: {}, Updated: {}, Errors: {}" ,
162+ response. created, response. updated, response. errors
163+ ) ;
164+
165+ if response. errors > 0 {
166+ bail ! (
167+ "{} mapping(s) failed to upload. See errors above." ,
168+ response. errors
169+ ) ;
170+ }
127171
128172 Ok ( ( ) )
129173}
0 commit comments