@@ -51,14 +51,22 @@ impl Helper for SheetsHelper {
5151 . help ( "JSON array of rows, e.g. '[[\" a\" ,\" b\" ],[\" c\" ,\" d\" ]]'" )
5252 . value_name ( "JSON" ) ,
5353 )
54+ . arg (
55+ Arg :: new ( "range" )
56+ . long ( "range" )
57+ . help ( "Target range in A1 notation (e.g. 'Sheet2!A1'). Defaults to 'A1' (first sheet)" )
58+ . value_name ( "RANGE" ) ,
59+ )
5460 . after_help (
5561 r#"EXAMPLES:
5662 gws sheets +append --spreadsheet ID --values 'Alice,100,true'
5763 gws sheets +append --spreadsheet ID --json-values '[["a","b"],["c","d"]]'
64+ gws sheets +append --spreadsheet ID --range "Sheet2!A1" --values 'Alice,100'
5865
5966TIPS:
6067 Use --values for simple single-row appends.
61- Use --json-values for bulk multi-row inserts."# ,
68+ Use --json-values for bulk multi-row inserts.
69+ Use --range to target a specific sheet tab (default: A1, i.e. first sheet)."# ,
6270 ) ,
6371 ) ;
6472
@@ -212,11 +220,9 @@ fn build_append_request(
212220 GwsError :: Discovery ( "Method 'spreadsheets.values.append' not found" . to_string ( ) )
213221 } ) ?;
214222
215- let range = "A1" ;
216-
217223 let params = json ! ( {
218224 "spreadsheetId" : config. spreadsheet_id,
219- "range" : range,
225+ "range" : config . range,
220226 "valueInputOption" : "USER_ENTERED"
221227 } ) ;
222228
@@ -262,6 +268,8 @@ fn build_read_request(
262268pub struct AppendConfig {
263269 /// The ID of the spreadsheet to append to.
264270 pub spreadsheet_id : String ,
271+ /// Target range in A1 notation (e.g. "Sheet2!A1"). Defaults to "A1".
272+ pub range : String ,
265273 /// The rows to append, where each inner Vec represents one row.
266274 pub values : Vec < Vec < String > > ,
267275}
@@ -289,8 +297,14 @@ pub fn parse_append_args(matches: &ArgMatches) -> AppendConfig {
289297 Vec :: new ( )
290298 } ;
291299
300+ let range = matches
301+ . get_one :: < String > ( "range" )
302+ . cloned ( )
303+ . unwrap_or_else ( || "A1" . to_string ( ) ) ;
304+
292305 AppendConfig {
293306 spreadsheet_id : matches. get_one :: < String > ( "spreadsheet" ) . unwrap ( ) . clone ( ) ,
307+ range,
294308 values,
295309 }
296310}
@@ -353,7 +367,8 @@ mod tests {
353367 let cmd = Command :: new ( "test" )
354368 . arg ( Arg :: new ( "spreadsheet" ) . long ( "spreadsheet" ) )
355369 . arg ( Arg :: new ( "values" ) . long ( "values" ) )
356- . arg ( Arg :: new ( "json-values" ) . long ( "json-values" ) ) ;
370+ . arg ( Arg :: new ( "json-values" ) . long ( "json-values" ) )
371+ . arg ( Arg :: new ( "range" ) . long ( "range" ) ) ;
357372 cmd. try_get_matches_from ( args) . unwrap ( )
358373 }
359374
@@ -369,17 +384,32 @@ mod tests {
369384 let doc = make_mock_doc ( ) ;
370385 let config = AppendConfig {
371386 spreadsheet_id : "123" . to_string ( ) ,
387+ range : "A1" . to_string ( ) ,
372388 values : vec ! [ vec![ "a" . to_string( ) , "b" . to_string( ) , "c" . to_string( ) ] ] ,
373389 } ;
374390 let ( params, body, scopes) = build_append_request ( & config, & doc) . unwrap ( ) ;
375391
376392 assert ! ( params. contains( "123" ) ) ;
377393 assert ! ( params. contains( "USER_ENTERED" ) ) ;
394+ assert ! ( params. contains( "A1" ) ) ;
378395 assert ! ( body. contains( "a" ) ) ;
379396 assert ! ( body. contains( "b" ) ) ;
380397 assert_eq ! ( scopes[ 0 ] , "https://scope" ) ;
381398 }
382399
400+ #[ test]
401+ fn test_build_append_request_with_range ( ) {
402+ let doc = make_mock_doc ( ) ;
403+ let config = AppendConfig {
404+ spreadsheet_id : "123" . to_string ( ) ,
405+ range : "Sheet2!A1" . to_string ( ) ,
406+ values : vec ! [ vec![ "x" . to_string( ) ] ] ,
407+ } ;
408+ let ( params, _body, _scopes) = build_append_request ( & config, & doc) . unwrap ( ) ;
409+ let parsed: serde_json:: Value = serde_json:: from_str ( & params) . unwrap ( ) ;
410+ assert_eq ! ( parsed[ "range" ] , "Sheet2!A1" ) ;
411+ }
412+
383413 #[ test]
384414 fn test_build_read_request ( ) {
385415 let doc = make_mock_doc ( ) ;
@@ -399,9 +429,32 @@ mod tests {
399429 let matches = make_matches_append ( & [ "test" , "--spreadsheet" , "123" , "--values" , "a,b,c" ] ) ;
400430 let config = parse_append_args ( & matches) ;
401431 assert_eq ! ( config. spreadsheet_id, "123" ) ;
432+ assert_eq ! ( config. range, "A1" ) ;
402433 assert_eq ! ( config. values, vec![ vec![ "a" , "b" , "c" ] ] ) ;
403434 }
404435
436+ #[ test]
437+ fn test_parse_append_args_with_range ( ) {
438+ let matches = make_matches_append ( & [
439+ "test" ,
440+ "--spreadsheet" ,
441+ "123" ,
442+ "--range" ,
443+ "Sheet2!A1" ,
444+ "--values" ,
445+ "a,b" ,
446+ ] ) ;
447+ let config = parse_append_args ( & matches) ;
448+ assert_eq ! ( config. range, "Sheet2!A1" ) ;
449+ }
450+
451+ #[ test]
452+ fn test_parse_append_args_default_range ( ) {
453+ let matches = make_matches_append ( & [ "test" , "--spreadsheet" , "123" , "--values" , "a" ] ) ;
454+ let config = parse_append_args ( & matches) ;
455+ assert_eq ! ( config. range, "A1" ) ;
456+ }
457+
405458 #[ test]
406459 fn test_parse_append_args_json_single_row ( ) {
407460 let matches = make_matches_append ( & [
@@ -436,6 +489,7 @@ mod tests {
436489 let doc = make_mock_doc ( ) ;
437490 let config = AppendConfig {
438491 spreadsheet_id : "123" . to_string ( ) ,
492+ range : "A1" . to_string ( ) ,
439493 values : vec ! [
440494 vec![ "Alice" . to_string( ) , "100" . to_string( ) ] ,
441495 vec![ "Bob" . to_string( ) , "200" . to_string( ) ] ,
0 commit comments