mirror of
https://github.com/larksuite/cli.git
synced 2026-09-14 18:42:53 +08:00
c6c040c2c5
* refactor(sheets)!: remove legacy sheets command surface
The `shortcuts/sheets/backward` package kept 42 pre-refactor command names
(`+create`, `+read`, `+write`, `+create-sheet`, `+media-upload`, ...) alive
alongside the refactored ones. Monitoring puts their combined share below 5%,
so they are dropped along with the machinery that carried them.
Removed with the package:
- the `sheetsAliasReplacement` map and `wrapSheetsBackwardDeprecation`, which
tagged each alias with a `_notice` deprecation envelope on execution;
- the deprecated cobra group and the custom `sheets --help` usage template that
existed only to hide it. `applySheetsCompatGroups` becomes
`applySheetsCommandGroups`: it still groups the `+`-shortcuts so the OpenAPI
metaapi subcommands keep filing under cobra's stock "Additional Commands".
The deleted package owned no shared logic. Its `parent_type` mapping for image
uploads was, by its own header, a deliberate mirror of the canonical one in
`shortcuts/sheets/helpers.go`; `common.IsLocalOfficeToken` and the drive upload
helpers are untouched and keep their other callers.
E2E tests still drove the removed commands and are ported to the refactored
surface: `+workbook-create` / `+workbook-info` / `+cells-set` / `+cells-get` /
`+cells-search` / `+sheet-*`. The sub-sheet dry-run assertions had to be
rewritten rather than renamed, because the old commands posted to
`sheets/v2/sheets_batch_update` while the new ones invoke
`modify_workbook_structure` over `sheet_ai/v2`. `+update-sheet` fanned out to
`+sheet-rename` + `+sheet-hide` + `+dim-freeze`. Every migrated command was
verified against a live workbook, which is where the assertions come from:
rename and hide answer with a bare revision counter, so their effect is read
back from `+workbook-info` (`sheet_name`, `is_hidden`).
Also updated, since these referenced the removed surface:
- three `skills/lark-drive` reference docs that instructed agents to run
`sheets +read` / `sheets +find`; these ship embedded in the binary, so the
instructions would have produced unknown-subcommand errors;
- `skill-template/domains/sheets.md`, deleted: every sheets command it named
was removed and the cell payload shape it taught
(`{"type":"formula","text":...}`) is rejected by `+cells-set`;
- stale comments naming `backward.uploadSheetMediaFile` and
`backward/helpers.go`.
`Shortcut.OnInvoke` and `internal/deprecation` now have no producers. Both are
generic framework plumbing wired into the `_notice` envelope in `cmd/root.go`,
so they are left in place; the `OnInvoke` doc comment no longer claims a caller.
BREAKING CHANGE: removes the 42 pre-refactor sheets commands (`+create`,
`+read`, `+write`, `+append`, `+find`, `+set-style`, `+create-sheet`,
`+update-sheet`, `+add-dimension`, `+set-dropdown`, `+media-upload`,
`+create-filter-view`, ...). They now fail with `unknown subcommand` and carry
no deprecation notice, so a caller still on the old names gets no migration
pointer at runtime.
Replacements for all 42, plus the differences that are not simple renames — the
cell payload vocabulary (`{"type":"formula","text":...}` is now rejected),
response field paths, and `+update-sheet` / `+update-dimension` fanning out to
several commands — are documented in
skills/lark-sheets/references/lark-sheets-legacy-command-migration.md, reachable
at runtime via:
lark-cli skills read lark-sheets references/lark-sheets-legacy-command-migration.md
* test(sheets): close the assertion gaps found in review
- The append subtest asserted only the ok envelope, so a +cells-set that
reported success without persisting would pass; the later +cells-search
covers row 2 only. Read A4:C4 back and assert the row landed. Verified
non-vacuous against a live sheet: an unwritten row returns cells carrying
no value, so the read-back fails if the write does not persist.
- Cover the omitted-title +sheet-copy path. The comment on the empty-title
suite states an omitted --title means "let the server name the copy", but
nothing exercised it; the new case pins that new_name is absent from the
payload rather than sent empty.
- Assert tool_name in the shared dry-run loop instead of only in the create
case, so copy / delete / rename / move cannot pass by selecting a different
tool on the same /tools/invoke_write endpoint.
* docs(sheets): fix the migration guide examples found in review
- `+table-put --sheets` requires the `{"sheets":[…]}` envelope; the `+append`
row showed a bare array, which the flag rejects outright ("top level must be
the object {\"sheets\":[…]}, got a bare JSON array"). Verified both forms
against a dry-run before and after.
- Tag the diagnostic fence as `text` (markdownlint MD040).
10 KiB
10 KiB
Sheets CLI E2E Coverage
Metrics
- Denominator: 30 leaf commands
- Covered: 23
- Coverage: 76.7%
- Scope note: this table tracks the commands these E2E tests touch plus the gaps carried over from the pre-refactor surface. It is not a census of the whole sheets shortcut surface, which is far larger; re-auditing it against the current command list is a separate follow-up.
Summary
- TestSheets_CRUDE2EWorkflow: proves
+workbook-create,+workbook-info,+cells-set,+cells-get,+cells-search, and+workbook-export; keyt.Run(...)proof points arecreate spreadsheet with +workbook-create as bot,read data with +cells-get as bot,find cells with +cells-search as bot, andexport spreadsheet with +workbook-export as bot.+cells-searchasserts both halves — one match atA2for a term on the sheet, zero for one that is not — so a search that silently matched everything would still fail. - TestSheets_CreateWorkflowAsUser: proves the UAT path for
sheets +workbook-createandsheets +workbook-infothroughcreate spreadsheet with +workbook-create as userandget spreadsheet info with +workbook-info as user. - TestSheets_SpreadsheetsResource: proves direct
spreadsheets create,spreadsheets get, andspreadsheets patch. - TestSheets_FilterWorkflow: proves
spreadsheet.sheet.filters create,get,update, anddelete, with supporting sheet setup through+workbook-create,+workbook-info, and+cells-set. - TestSheets_SheetShortcutsDryRun: proves request shapes for
+sheet-create,+sheet-copy,+sheet-delete,+sheet-rename, and+sheet-movewithout hitting live APIs — all five reach the backend throughmodify_workbook_structure, so the pinned distinction is theoperationand the fields packed beside it. - TestSheets_SheetShortcutsWorkflow: proves live
+sheet-create,+sheet-copy,+sheet-rename,+sheet-hide,+dim-freeze, and+sheet-deleteflows against a real spreadsheet, verified by reading the workbook back through+workbook-inforather than by matching a field in each command's own response. Rename and hide answer with nothing but a revision counter, so the listing is the only place their effect can be observed (sheet_name,is_hidden);+dim-freezereportsfrozen_rows/frozen_columnsin its own result. - TestSheets_ImageUploadDryRunParentType: dry-run coverage for the drive
parent_typean image upload carries, across every surface a local file enters through —+cells-set-imageand+float-image-create. A native spreadsheet must upload assheet_imageand one backed by an imported office file asoffice_sheet_file; a/wiki/ref must stay native, because a preview cannot resolve the node and so must not read the split out of the node_token. The negative half matters most: the backend does not validateparent_nodeagainstparent_type, so a wrong value uploads successfully and only surfaces later as an image that will not render. - TestSheets_ImageUploadDryRunChunked: dry-run coverage for the 20 MB branch in
+cells-set-image. Under the ceiling the preview shows oneupload_all; one byte past it, theupload_prepare/upload_part/upload_finishtrio Execute actually sends. Before that dispatch existed, an oversized image failed onupload_allwith a bare1061002naming neither the size nor the limit. - Cleanup note: workflow-created spreadsheets are cleaned up via
drive +delete --type sheet; those cleanup-only executions are not counted as command coverage because no testcase asserts delete behavior as the primary proof surface.
Command Table
| Status | Cmd | Type | Testcase | Key parameter shapes | Notes / uncovered reason |
|---|---|---|---|---|---|
| ✓ | sheets +cells-get | shortcut | sheets_crud_workflow_test.go::TestSheets_CRUDE2EWorkflow/read data with +cells-get as bot | --spreadsheet-token; --sheet-id; --range |
values are collected out of the decoded payload, not matched against a fixed path: get_cell_ranges' response nesting is the backend's |
| ✕ | sheets +cells-merge | shortcut | none | no merge workflow yet | |
| ✕ | sheets +cells-replace | shortcut | none | no replace workflow yet | |
| ✓ | sheets +cells-search | shortcut | sheets_crud_workflow_test.go::TestSheets_CRUDE2EWorkflow/find cells with +cells-search as bot | --spreadsheet-token; --sheet-id; --find; --range |
asserts the hit (total_matches 1, address A2) and the miss (total_matches 0) |
| ✓ | sheets +cells-set | shortcut | sheets_crud_workflow_test.go::TestSheets_CRUDE2EWorkflow/write data with +cells-set as bot; sheets_crud_workflow_test.go::TestSheets_CRUDE2EWorkflow/append a row with +cells-set as bot; sheets_filter_workflow_test.go::TestSheets_FilterWorkflow/write test data for filtering as bot | --spreadsheet-token; --sheet-id; --range; --cells |
the append subtest writes past the existing block, which is the auto-expand path the pre-refactor +append relied on |
| ✕ | sheets +cells-set-image | shortcut | dry-run only | live image workflow still missing; parent_type shape covered by sheets_image_upload_dryrun_test.go | |
| ✓ | sheets +cells-set-style | shortcut | sheets_call_compat_workflow_test.go::TestSheets_CallCompatWorkflow/style it with an openpyxl border weight | --spreadsheet-token; --range; --border-styles |
|
| ✕ | sheets +cells-unmerge | shortcut | none | no merge workflow yet | |
| ✓ | sheets +dim-delete | shortcut | sheets_dim_workflow_test.go::TestSheets_DimShortcutsWorkflow | --spreadsheet-token; --sheet-id; --ranges |
|
| ✓ | sheets +dim-freeze | shortcut | sheets_sheet_shortcuts_workflow_test.go::TestSheets_SheetShortcutsWorkflow/freeze rows and columns with +dim-freeze as bot | --spreadsheet-token; --sheet-id; --rows; --cols |
asserts the reported frozen_rows / frozen_columns |
| ✓ | sheets +dim-insert | shortcut | sheets_dim_workflow_test.go::TestSheets_DimShortcutsWorkflow | --spreadsheet-token; --sheet-id; --position; --count |
dry-run inherit-style shape also covered by sheets_sheet_shortcuts_dryrun_test.go |
| ✕ | sheets +dim-move | shortcut | none | no dimension move workflow yet | |
| ✓ | sheets +sheet-copy | shortcut | sheets_sheet_shortcuts_workflow_test.go::TestSheets_SheetShortcutsWorkflow/copy sheet with +sheet-copy as bot | --spreadsheet-token; --sheet-id; optional --title; optional --index |
dry-run shape also covered by sheets_sheet_shortcuts_dryrun_test.go |
| ✓ | sheets +sheet-create | shortcut | sheets_sheet_shortcuts_workflow_test.go::TestSheets_SheetShortcutsWorkflow/create sheet with +sheet-create as bot; sheets_sheet_list_workflow_test.go::TestSheets_SheetListWorkflow | --spreadsheet-token; --title; optional --index |
dry-run shape also covered by sheets_sheet_shortcuts_dryrun_test.go |
| ✓ | sheets +sheet-delete | shortcut | sheets_sheet_shortcuts_workflow_test.go::TestSheets_SheetShortcutsWorkflow/delete sheet with +sheet-delete as bot | --spreadsheet-token; --sheet-id; --yes |
dry-run shape also covered by sheets_sheet_shortcuts_dryrun_test.go |
| ✓ | sheets +sheet-hide | shortcut | sheets_sheet_shortcuts_workflow_test.go::TestSheets_SheetShortcutsWorkflow/hide sheet with +sheet-hide as bot | --spreadsheet-token; --sheet-id |
the command answers with a revision only, so is_hidden is read back from +workbook-info |
| ✓ | sheets +sheet-list | shortcut | sheets_sheet_list_workflow_test.go::TestSheets_SheetListWorkflow | --spreadsheet-token |
pinned to forward +workbook-info's sheets entries verbatim |
| ✕ | sheets +sheet-move | shortcut | dry-run only | no live reordering workflow yet; request shape covered by sheets_sheet_shortcuts_dryrun_test.go | |
| ✓ | sheets +sheet-rename | shortcut | sheets_sheet_shortcuts_workflow_test.go::TestSheets_SheetShortcutsWorkflow/rename sheet with +sheet-rename as bot | --spreadsheet-token; --sheet-id; --title |
dry-run shape also covered by sheets_sheet_shortcuts_dryrun_test.go |
| ✓ | sheets +workbook-create | shortcut | sheets_crud_workflow_test.go::TestSheets_CRUDE2EWorkflow/create spreadsheet with +workbook-create as bot; sheets_filter_workflow_test.go::TestSheets_FilterWorkflow/create spreadsheet with initial data as bot; sheets_create_workflow_test.go::TestSheets_CreateWorkflowAsUser/create spreadsheet with +workbook-create as user | --title; --folder-token |
token read from data.spreadsheet.spreadsheet_token |
| ✓ | sheets +workbook-export | shortcut | sheets_crud_workflow_test.go::TestSheets_CRUDE2EWorkflow/export spreadsheet with +workbook-export as bot | --spreadsheet-token; --file-extension; --output-path |
|
| ✓ | sheets +workbook-info | shortcut | sheets_crud_workflow_test.go::TestSheets_CRUDE2EWorkflow/get spreadsheet info with +workbook-info as bot; sheets_filter_workflow_test.go::TestSheets_FilterWorkflow/get sheet info as bot; sheets_create_workflow_test.go::TestSheets_CreateWorkflowAsUser/get spreadsheet info with +workbook-info as user | --spreadsheet-token |
returns the workbook structure only: sub-sheets under data.sheets, no spreadsheet token echo |
| ✓ | sheets spreadsheet.sheet.filters create | api | sheets_filter_workflow_test.go::TestSheets_FilterWorkflow/create filter with spreadsheet.sheet.filters create as bot | spreadsheet_token; sheet_id in --params; filter JSON in --data |
|
| ✓ | sheets spreadsheet.sheet.filters delete | api | sheets_filter_workflow_test.go::TestSheets_FilterWorkflow/delete filter with spreadsheet.sheet.filters delete as bot | spreadsheet_token; sheet_id in --params |
|
| ✓ | sheets spreadsheet.sheet.filters get | api | sheets_filter_workflow_test.go::TestSheets_FilterWorkflow/get filter with spreadsheet.sheet.filters get as bot | spreadsheet_token; sheet_id in --params |
|
| ✓ | sheets spreadsheet.sheet.filters update | api | sheets_filter_workflow_test.go::TestSheets_FilterWorkflow/update filter with spreadsheet.sheet.filters update as bot | spreadsheet_token; sheet_id in --params; filter JSON in --data |
|
| ✕ | sheets spreadsheet.sheets find | api | none | no direct API workflow yet | |
| ✓ | sheets spreadsheets create | api | sheets_crud_workflow_test.go::TestSheets_SpreadsheetsResource/create spreadsheet with spreadsheets create as bot | title in --data |
|
| ✓ | sheets spreadsheets get | api | sheets_crud_workflow_test.go::TestSheets_SpreadsheetsResource/get spreadsheet with spreadsheets get as bot | spreadsheet_token in --params |
|
| ✓ | sheets spreadsheets patch | api | sheets_crud_workflow_test.go::TestSheets_SpreadsheetsResource/patch spreadsheet with spreadsheets patch as bot | spreadsheet_token in --params; title patch in --data |