Skip to content

Commit 5ad1893

Browse files
committed
feat(sheets): add --range flag to +append for targeting specific tabs
Previously +append always used hardcoded "A1" range, limiting appends to the first sheet. Add optional --range flag (default: "A1") to allow appending to any sheet tab using A1 notation.
1 parent c7c6646 commit 5ad1893

File tree

3 files changed

+67
-5
lines changed

3 files changed

+67
-5
lines changed

.changeset/sheets-append-range.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@googleworkspace/cli": minor
3+
---
4+
5+
Add `--range` flag to `sheets +append` for targeting specific sheet tabs

crates/google-workspace-cli/src/helpers/sheets.rs

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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
5966
TIPS:
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(
262268
pub 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()],

skills/gws-sheets-append/SKILL.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,21 @@ gws sheets +append --spreadsheet <ID>
3030
| `--spreadsheet` ||| Spreadsheet ID |
3131
| `--values` ||| Comma-separated values (simple strings) |
3232
| `--json-values` ||| JSON array of rows, e.g. '[["a","b"],["c","d"]]' |
33+
| `--range` || `A1` | Target range in A1 notation (e.g. 'Sheet2!A1') to select a specific tab |
3334

3435
## Examples
3536

3637
```bash
3738
gws sheets +append --spreadsheet ID --values 'Alice,100,true'
3839
gws sheets +append --spreadsheet ID --json-values '[["a","b"],["c","d"]]'
40+
gws sheets +append --spreadsheet ID --range "Sheet2!A1" --values 'Alice,100'
3941
```
4042

4143
## Tips
4244

4345
- Use --values for simple single-row appends.
4446
- Use --json-values for bulk multi-row inserts.
47+
- Use --range to append to a specific sheet tab (default: A1, i.e. first sheet).
4548

4649
> [!CAUTION]
4750
> This is a **write** command — confirm with the user before executing.

0 commit comments

Comments
 (0)