Skip to content

feat: support multipart doc media uploads#294

Merged
fangshuyu-768 merged 1 commit intomainfrom
feat/doc-media-chunked-upload
Apr 8, 2026
Merged

feat: support multipart doc media uploads#294
fangshuyu-768 merged 1 commit intomainfrom
feat/doc-media-chunked-upload

Conversation

@liujinkun2025
Copy link
Copy Markdown
Collaborator

@liujinkun2025 liujinkun2025 commented Apr 7, 2026

Summary

Add multipart upload support for doc media flows so docs +media-upload and docs +media-insert can handle files larger than 20MB. This also extracts the shared Drive media upload logic into a common helper and keeps the user-facing docs +media- insert dry-run flow expressed as 4/5 high-level steps.

Changes

  • Add shared Drive media upload helpers for upload_all and multipart upload_prepare -> upload_part -> upload_finish
  • Update docs +media-upload to auto-switch to multipart upload for files larger than 20MB
  • Update docs +media-insert to auto-switch to multipart upload, keep rollback behavior, and keep dry-run output user-oriented
  • Refactor drive import media upload code to reuse the shared helper
  • Clean up and relocate unit tests so shared upload behavior is tested in shortcuts/common
  • Update the lark-doc-media-insert reference to reflect automatic multipart upload for files larger than 20MB

Test Plan

  • Unit tests pass (make unit-test)
  • Manual local verification confirms lark-cli docs +media-insert works as expected for both a normal image upload and a file upload larger than 20MB

Related Issues

  • None

Summary by CodeRabbit

  • New Features

    • Automatic single-part vs multipart Drive media upload with progress output and returned file token; dry-run shows planned upload sequence (prepare→parts→finish or upload_all).
  • Documentation

    • Updated file flag/docs to state files over the threshold use chunked (multipart) upload.
  • Tests

    • Added end-to-end and dry-run tests for both upload flows; removed obsolete legacy multipart tests.
  • Chores / Refactor

    • Centralized upload logic, unified size-threshold handling, and improved file validation and error messaging.

@github-actions github-actions bot added domain/ccm PR touches the ccm domain size/L Large or sensitive change across domains or core paths labels Apr 7, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 7, 2026

📝 Walkthrough

Walkthrough

Adds a shared Drive media uploader with single-part (upload_all) and multipart (upload_prepareupload_part* → upload_finish) flows, moves upload logic from multiple shortcuts into shortcuts/common/drive_media_upload.go, updates dry-run planning/tests, and centralizes response parsing and error wrapping.

Changes

Cohort / File(s) Summary
Common Upload Module
shortcuts/common/drive_media_upload.go, shortcuts/common/drive_media_upload_test.go
New shared uploader: UploadDriveMediaAll and UploadDriveMediaMultipart, MaxDriveMediaUploadSinglePartSize, multipart session/config types, parsing/extraction/wrapping helpers, and comprehensive HTTP-level tests for single-part, multipart, error paths, and network wrapping.
Doc Media Shortcuts
shortcuts/doc/doc_media_upload.go, shortcuts/doc/doc_media_insert.go, shortcuts/doc/doc_media_test.go
Replaced inline upload logic with calls to common upload helpers; DryRun now emits either upload_all or multipart sequence based on MaxDriveMediaUploadSinglePartSize; runtime validation changed to require regular files; tests updated to assert multipart dry-run flows.
Drive Import & Upload
shortcuts/drive/drive_import_common.go, shortcuts/drive/drive_import.go, shortcuts/drive/drive_upload.go
Removed local multipart orchestration and parsing; now use common upload helpers and MaxDriveMediaUploadSinglePartSize threshold; use safe path validation and VFS for file I/O; removed redundant imports.
Drive Tests Adjustments
shortcuts/drive/..._test.go, shortcuts/drive/drive_import_common_test.go, shortcuts/drive/drive_import_test.go, shortcuts/drive/drive_io_test.go, shortcuts/drive/drive_move_*.go, shortcuts/drive/drive_task_result_test.go
Deleted duplicated multipart tests moved to common tests, removed registerDriveBotTokenStub usages, and updated tests to reference MaxDriveMediaUploadSinglePartSize for multipart triggering.
Doc Tests & Utilities
shortcuts/doc/doc_media_test.go
Added dry-run tests and helpers to generate sized test files and decode/validate multipart dry-run outputs and step ordering.
Docs & CLI Help
skills/lark-doc/references/lark-doc-media-insert.md
Updated --file help to state files larger than the single-part threshold automatically use chunked (分片) upload.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant LocalFile
    participant DriveAPI
    Client->>LocalFile: stat/open file → determine size
    alt size <= single-part limit
        Client->>DriveAPI: POST /open-apis/drive/v1/medias/upload_all (multipart/form-data)
        DriveAPI-->>Client: { code, data{ file_token } }
    else multipart
        Client->>DriveAPI: POST /open-apis/drive/v1/medias/upload_prepare (json)
        DriveAPI-->>Client: { upload_id, block_size, block_num }
        loop seq = 1..block_num
            Client->>LocalFile: read block (block_size)
            Client->>DriveAPI: POST /open-apis/drive/v1/medias/upload_part (multipart: seq, upload_id, chunk)
            DriveAPI-->>Client: { code, data }
        end
        Client->>DriveAPI: POST /open-apis/drive/v1/medias/upload_finish (json: upload_id, block_num)
        DriveAPI-->>Client: { code, data{ file_token } }
    end
    Client->>LocalFile: close file
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

Suggested reviewers

  • liangshuo-1
  • fangshuyu-768

Poem

🐰 I nibble bytes and split them small,
I hop each chunk and send them all,
Prepare, part, finish — token bright,
I thump my feet, uploads take flight,
Rabbit smiles — the bytes sleep tight.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.26% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change—adding multipart upload support for document media operations. It is directly related to the core objective of the changeset.
Description check ✅ Passed The description follows the template structure with a Summary, Changes, Test Plan (with checkboxes marked complete), and Related Issues. All required sections are present and substantively completed.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/doc-media-chunked-upload

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
shortcuts/common/drive_media_upload_test.go (1)

412-426: Consider adding config directory isolation.

Per coding guidelines, test config state should be isolated using t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir()). While the atomic counter provides AppID uniqueness, adding config directory isolation would ensure complete test isolation.

💡 Suggested improvement
 func newDriveMediaUploadTestRuntime(t *testing.T) (*RuntimeContext, *httpmock.Registry) {
 	t.Helper()
+	t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir())
 
 	cfg := &core.CliConfig{
 		AppID: fmt.Sprintf("common-drive-media-test-%d", commonDriveMediaUploadTestSeq.Add(1)), AppSecret: "test-secret", Brand: core.BrandFeishu,
 	}

Based on learnings: "Isolate config state in Go tests by using t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir())"

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shortcuts/common/drive_media_upload_test.go` around lines 412 - 426, The test
helper newDriveMediaUploadTestRuntime should isolate CLI config state by setting
a temporary config dir; call t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir())
near the top of newDriveMediaUploadTestRuntime (before creating cfg or calling
cmdutil.TestFactory) so each test uses its own config directory and avoids
shared state.
shortcuts/drive/drive_import_common.go (1)

86-95: Consider using vfs.Stat instead of os.Stat for filesystem access.

Per coding guidelines, filesystem operations should use vfs.* instead of os.*. However, since this line existed before this PR (it's not marked with ~), this may be pre-existing technical debt rather than a new violation introduced by this change.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shortcuts/drive/drive_import_common.go` around lines 86 - 95, Replace the
direct os.Stat call in uploadMediaForImport with the virtual filesystem helper:
call vfs.Stat (matching the project's vfs API) to get importInfo and err, update
imports accordingly, and keep the same error handling/flow (i.e., return
output.ErrValidation(...) on error and pass importInfo.Size() into
validateDriveImportFileSize). Ensure the change is made in the
uploadMediaForImport function and that validateDriveImportFileSize continues to
be called with the same filePath, docType, and fileSize.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@shortcuts/common/drive_media_upload.go`:
- Around line 52-85: The file open calls in UploadDriveMediaAll and
uploadDriveMediaMultipartParts must validate the file paths using
validate.SafeInputPath before calling os.Open; update UploadDriveMediaAll
(around the os.Open(cfg.FilePath) call) and uploadDriveMediaMultipartParts
(around the os.Open usage at the other site) to call
validate.SafeInputPath(cfg.FilePath) (or the equivalent variable) and return a
validation error if it fails, then proceed to os.Open only after the path is
validated to match the project's safe-path pattern.

---

Nitpick comments:
In `@shortcuts/common/drive_media_upload_test.go`:
- Around line 412-426: The test helper newDriveMediaUploadTestRuntime should
isolate CLI config state by setting a temporary config dir; call
t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir()) near the top of
newDriveMediaUploadTestRuntime (before creating cfg or calling
cmdutil.TestFactory) so each test uses its own config directory and avoids
shared state.

In `@shortcuts/drive/drive_import_common.go`:
- Around line 86-95: Replace the direct os.Stat call in uploadMediaForImport
with the virtual filesystem helper: call vfs.Stat (matching the project's vfs
API) to get importInfo and err, update imports accordingly, and keep the same
error handling/flow (i.e., return output.ErrValidation(...) on error and pass
importInfo.Size() into validateDriveImportFileSize). Ensure the change is made
in the uploadMediaForImport function and that validateDriveImportFileSize
continues to be called with the same filePath, docType, and fileSize.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 32e66156-b312-4cb3-b63d-97fcecd1d735

📥 Commits

Reviewing files that changed from the base of the PR and between bb38ecd and 411d631.

📒 Files selected for processing (8)
  • shortcuts/common/drive_media_upload.go
  • shortcuts/common/drive_media_upload_test.go
  • shortcuts/doc/doc_media_insert.go
  • shortcuts/doc/doc_media_test.go
  • shortcuts/doc/doc_media_upload.go
  • shortcuts/drive/drive_import_common.go
  • shortcuts/drive/drive_import_common_test.go
  • skills/lark-doc/references/lark-doc-media-insert.md
💤 Files with no reviewable changes (1)
  • shortcuts/drive/drive_import_common_test.go

@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Apr 7, 2026

Greptile Summary

This PR adds multipart upload support for doc media flows, extracts a shared UploadDriveMediaAll/UploadDriveMediaMultipart helper in shortcuts/common, and wires both docs +media-upload and docs +media-insert to auto-select the upload path based on the 20 MB threshold. The refactoring is well-structured and the drive import path is cleanly updated to reuse the new helpers.

  • P1 — panic risk in uploadDriveMediaMultipartParts: the read buffer is allocated as min(blockSize, fileSize) but the loop computes chunkSize = session.BlockSize unconditionally when remaining == 0, so a second iteration on a small file would index out of bounds; allocate the buffer as session.BlockSize to fix.

Confidence Score: 4/5

Safe to merge after fixing the buffer sizing panic risk in uploadDriveMediaMultipartParts.

One P1 finding: the buffer in uploadDriveMediaMultipartParts is capped to min(blockSize, fileSize) but the loop slice can reach session.BlockSize when remaining==0, causing a panic on a second iteration. This is a real runtime crash path (even if it requires an inconsistent server response), warranting a fix before merge. All other findings are P2 style concerns.

shortcuts/common/drive_media_upload.go — the uploadDriveMediaMultipartParts buffer sizing logic (lines 186–194)

Vulnerabilities

No security concerns identified. All upload paths call validate.SafeInputPath before opening files, and no secrets or credentials are introduced.

Important Files Changed

Filename Overview
shortcuts/common/drive_media_upload.go New shared helper for Drive media upload_all and multipart upload; contains a panic-risk in uploadDriveMediaMultipartParts where the buffer is sized to min(blockSize, fileSize) but the loop indexes up to session.BlockSize unconditionally when remaining==0.
shortcuts/doc/doc_media_insert.go Refactored to delegate upload logic to common helpers and support multipart; filePath = safeFilePath was removed, leading to redundant double-validation but no security risk.
shortcuts/doc/doc_media_upload.go Adds uploadDocMediaFile helper and docMediaShouldUseMultipart; auto-selects upload_all vs multipart cleanly based on file size threshold.
shortcuts/drive/drive_import_common.go Refactored to reuse common.UploadDriveMediaAll and common.UploadDriveMediaMultipart; logic is correct and thresholds are appropriately delegated to the common constant.
shortcuts/common/drive_media_upload_test.go Good coverage of upload_all, multipart prepare/part/finish flows, error cases; multipart body decoder helper is still duplicated across packages (flagged in a prior thread).
shortcuts/doc/doc_media_test.go Added tests for multipart dry-run selection in both media-upload and media-insert; covers wiki resolution, file-not-found, and overwrite protection flows.
shortcuts/drive/drive_upload.go Unchanged in logic; still uses the separate files/upload_* endpoint with its own inline multipart code — intentional, as it is a different API surface from medias/upload_*.
skills/lark-doc/references/lark-doc-media-insert.md Documentation updated to reflect automatic multipart upload for files over 20MB; accurate and consistent with code behavior.

Sequence Diagram

sequenceDiagram
    participant CLI
    participant common.UploadDriveMedia
    participant LarkAPI

    CLI->>CLI: stat(filePath)
    alt fileSize <= 20MB
        CLI->>common.UploadDriveMedia: UploadDriveMediaAll(cfg)
        common.UploadDriveMedia->>LarkAPI: POST /drive/v1/medias/upload_all
        LarkAPI-->>common.UploadDriveMedia: file_token
        common.UploadDriveMedia-->>CLI: file_token
    else fileSize > 20MB
        CLI->>common.UploadDriveMedia: UploadDriveMediaMultipart(cfg)
        common.UploadDriveMedia->>LarkAPI: POST /drive/v1/medias/upload_prepare
        LarkAPI-->>common.UploadDriveMedia: upload_id, block_size, block_num
        loop for each block (seq 0..block_num-1)
            common.UploadDriveMedia->>LarkAPI: POST /drive/v1/medias/upload_part
            LarkAPI-->>common.UploadDriveMedia: ok
        end
        common.UploadDriveMedia->>LarkAPI: POST /drive/v1/medias/upload_finish
        LarkAPI-->>common.UploadDriveMedia: file_token
        common.UploadDriveMedia-->>CLI: file_token
    end
Loading

Reviews (5): Last reviewed commit: "support multipart doc media uploads" | Re-trigger Greptile

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 7, 2026

🚀 PR Preview Install Guide

🧰 CLI update

npm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@04fdb548a340dadde56de2e2b5f4039ecf7d371b

🧩 Skill update

npx skills add larksuite/cli#feat/doc-media-chunked-upload -y -g

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (1)
shortcuts/common/drive_media_upload.go (1)

52-57: ⚠️ Potential issue | 🟠 Major

Validate and preflight the file path inside the shared uploader.

UploadDriveMediaAll and the multipart path still touch raw file paths, and multipart does not surface path/open failures until after upload_prepare has already created a remote session. Please safe-validate once inside the common helper and pass the sanitized/opened file into the part loop so callers cannot bypass the repo’s path guard. As per coding guidelines, **/*.go: Validate paths using validate.SafeInputPath before any file I/O operations.

Also applies to: 87-116, 170-175

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shortcuts/common/drive_media_upload.go` around lines 52 - 57,
UploadDriveMediaAll currently opens cfg.FilePath directly; validate and sanitize
the path first using validate.SafeInputPath before any file I/O, then open the
returned safe path and pass the opened file handle (not the raw path) into the
multipart/part loop so path/open failures surface before upload_prepare creates
a remote session. Update UploadDriveMediaAll to call
validate.SafeInputPath(cfg.FilePath), handle/return validation errors, open the
sanitized path, defer close, and refactor the multipart upload code to accept
the io.Reader/File (the opened file) instead of re-opening the raw path so
callers cannot bypass the repo path guard.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@shortcuts/common/drive_media_upload.go`:
- Around line 177-182: session.BlockSize must be bounded by the actual local
file size before allocating buffer to avoid OOM: retrieve the local file size
(e.g., via file.Stat().Size() or existing localFileSize variable), compute
allowed := min(session.BlockSize, localFileSize - currentOffset) and also clamp
to the existing maxInt check, then allocate buffer using make([]byte,
int(allowed)) instead of make([]byte, int(session.BlockSize)); ensure allowed is
>= 1 and fall back to a safe default or return an error if it's invalid.

In `@shortcuts/doc/doc_media_insert.go`:
- Around line 82-83: The dry-run helper appendDocMediaInsertUploadDryRun is
creating an upload preview that doesn't include the same payload fields used in
real execution (uploadDocMediaFile attaches the document "extra" field and the
single-part path includes "size"), so update appendDocMediaInsertUploadDryRun to
include the document extra metadata and the size field in its generated request
body for both multipart and single-part flows so the preview matches what
uploadDocMediaFile actually sends; ensure the same keys/naming are used as in
uploadDocMediaFile and mirror any conditional logic for multipart vs single-part
inserts.

In `@shortcuts/doc/doc_media_upload.go`:
- Around line 43-75: The dry-run for single-part uploads is missing the "size"
field so it doesn't match the real UploadDriveMediaAll request; update the
single-part branch (the code that sets body["file"] = "@" + filePath and returns
dry.Desc("multipart/form-data upload")...) to include the same "size" key as the
real request (set body["size"] to the file size or placeholder "<file_size>" so
the dry run mirrors UploadDriveMediaAll), ensuring the dry-run Body payload keys
match those used when not using docMediaShouldUseMultipart.

---

Duplicate comments:
In `@shortcuts/common/drive_media_upload.go`:
- Around line 52-57: UploadDriveMediaAll currently opens cfg.FilePath directly;
validate and sanitize the path first using validate.SafeInputPath before any
file I/O, then open the returned safe path and pass the opened file handle (not
the raw path) into the multipart/part loop so path/open failures surface before
upload_prepare creates a remote session. Update UploadDriveMediaAll to call
validate.SafeInputPath(cfg.FilePath), handle/return validation errors, open the
sanitized path, defer close, and refactor the multipart upload code to accept
the io.Reader/File (the opened file) instead of re-opening the raw path so
callers cannot bypass the repo path guard.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3a9326a7-daf4-491f-9402-3df64057b744

📥 Commits

Reviewing files that changed from the base of the PR and between 411d631 and 2f072cf.

📒 Files selected for processing (6)
  • shortcuts/common/drive_media_upload.go
  • shortcuts/doc/doc_media_insert.go
  • shortcuts/doc/doc_media_test.go
  • shortcuts/doc/doc_media_upload.go
  • shortcuts/drive/drive_import.go
  • shortcuts/drive/drive_import_common.go
💤 Files with no reviewable changes (1)
  • shortcuts/drive/drive_import.go
✅ Files skipped from review due to trivial changes (1)
  • shortcuts/drive/drive_import_common.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • shortcuts/doc/doc_media_test.go

@liujinkun2025 liujinkun2025 force-pushed the feat/doc-media-chunked-upload branch from 2f072cf to 769ab52 Compare April 7, 2026 14:21
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
shortcuts/drive/drive_upload.go (1)

184-184: ⚠️ Potential issue | 🟡 Minor

Use vfs.Open instead of os.Open for filesystem access.

The multipart upload loop uses os.Open while other file operations in this file correctly use vfs.Open (line 99) and vfs.Stat (line 70). As per coding guidelines, all filesystem access should use vfs.* for consistency and testability.

🔧 Proposed fix
-		partFile, err := os.Open(filePath)
+		partFile, err := vfs.Open(filePath)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shortcuts/drive/drive_upload.go` at line 184, Replace the direct os.Open call
with the VFS wrapper: open the part file using vfs.Open(filePath) instead of
os.Open(filePath) (the variable partFile and error handling usage should remain
the same), ensure the import set is updated (remove unused "os" if no longer
needed), and keep the existing defer/Close logic unchanged so the multipart
upload loop continues to use vfs for filesystem access and remains testable;
update any error messages referencing os.Open to reflect vfs.Open if present.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@shortcuts/drive/drive_upload.go`:
- Line 184: Replace the direct os.Open call with the VFS wrapper: open the part
file using vfs.Open(filePath) instead of os.Open(filePath) (the variable
partFile and error handling usage should remain the same), ensure the import set
is updated (remove unused "os" if no longer needed), and keep the existing
defer/Close logic unchanged so the multipart upload loop continues to use vfs
for filesystem access and remains testable; update any error messages
referencing os.Open to reflect vfs.Open if present.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 518afbed-666a-4a55-9816-32a852516b52

📥 Commits

Reviewing files that changed from the base of the PR and between 2f072cf and 769ab52.

📒 Files selected for processing (16)
  • shortcuts/common/drive_media_upload.go
  • shortcuts/common/drive_media_upload_test.go
  • shortcuts/doc/doc_media_insert.go
  • shortcuts/doc/doc_media_test.go
  • shortcuts/doc/doc_media_upload.go
  • shortcuts/drive/drive_export_test.go
  • shortcuts/drive/drive_import.go
  • shortcuts/drive/drive_import_common.go
  • shortcuts/drive/drive_import_common_test.go
  • shortcuts/drive/drive_import_test.go
  • shortcuts/drive/drive_io_test.go
  • shortcuts/drive/drive_move_common_test.go
  • shortcuts/drive/drive_move_test.go
  • shortcuts/drive/drive_task_result_test.go
  • shortcuts/drive/drive_upload.go
  • skills/lark-doc/references/lark-doc-media-insert.md
💤 Files with no reviewable changes (5)
  • shortcuts/drive/drive_task_result_test.go
  • shortcuts/drive/drive_move_test.go
  • shortcuts/drive/drive_export_test.go
  • shortcuts/drive/drive_import_common_test.go
  • shortcuts/drive/drive_move_common_test.go
✅ Files skipped from review due to trivial changes (2)
  • shortcuts/drive/drive_import_test.go
  • skills/lark-doc/references/lark-doc-media-insert.md
🚧 Files skipped from review as they are similar to previous changes (4)
  • shortcuts/common/drive_media_upload_test.go
  • shortcuts/doc/doc_media_upload.go
  • shortcuts/doc/doc_media_test.go
  • shortcuts/common/drive_media_upload.go

@liujinkun2025 liujinkun2025 force-pushed the feat/doc-media-chunked-upload branch from 769ab52 to 4d4b814 Compare April 8, 2026 04:06
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
shortcuts/doc/doc_media_upload.go (1)

35-75: ⚠️ Potential issue | 🟡 Minor

Add size field to single-part dry-run body for consistency.

The single-part dry-run (lines 72-75) omits the size field, but the real UploadDriveMediaAll always sends it. The multipart dry-run correctly includes "size": "<file_size>" at line 49, but the single-part path should match.

📝 Proposed fix
 		body["file"] = "@" + filePath
+		body["size"] = "<file_size>"
 		return dry.Desc("multipart/form-data upload").
 			POST("/open-apis/drive/v1/medias/upload_all").
 			Body(body)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shortcuts/doc/doc_media_upload.go` around lines 35 - 75, The single-part
dry-run body built in this function is missing the "size" field; update the body
map (the one with keys "file_name", "parent_type", "parent_node" and optional
"extra") to include "size": "<file_size>" before assigning body["file"] and
returning the dry run for the multipart/form-data path (the block that returns
dry.Desc("multipart/form-data
upload").POST("/open-apis/drive/v1/medias/upload_all").Body(body)); this makes
the single-part dry-run consistent with the multipart dry-run that already sets
"size".
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@shortcuts/doc/doc_media_upload.go`:
- Around line 35-75: The single-part dry-run body built in this function is
missing the "size" field; update the body map (the one with keys "file_name",
"parent_type", "parent_node" and optional "extra") to include "size":
"<file_size>" before assigning body["file"] and returning the dry run for the
multipart/form-data path (the block that returns dry.Desc("multipart/form-data
upload").POST("/open-apis/drive/v1/medias/upload_all").Body(body)); this makes
the single-part dry-run consistent with the multipart dry-run that already sets
"size".

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2a53f556-fd46-4cea-8878-47aa03afaf9e

📥 Commits

Reviewing files that changed from the base of the PR and between 769ab52 and 4d4b814.

📒 Files selected for processing (16)
  • shortcuts/common/drive_media_upload.go
  • shortcuts/common/drive_media_upload_test.go
  • shortcuts/doc/doc_media_insert.go
  • shortcuts/doc/doc_media_test.go
  • shortcuts/doc/doc_media_upload.go
  • shortcuts/drive/drive_export_test.go
  • shortcuts/drive/drive_import.go
  • shortcuts/drive/drive_import_common.go
  • shortcuts/drive/drive_import_common_test.go
  • shortcuts/drive/drive_import_test.go
  • shortcuts/drive/drive_io_test.go
  • shortcuts/drive/drive_move_common_test.go
  • shortcuts/drive/drive_move_test.go
  • shortcuts/drive/drive_task_result_test.go
  • shortcuts/drive/drive_upload.go
  • skills/lark-doc/references/lark-doc-media-insert.md
💤 Files with no reviewable changes (5)
  • shortcuts/drive/drive_move_test.go
  • shortcuts/drive/drive_move_common_test.go
  • shortcuts/drive/drive_export_test.go
  • shortcuts/drive/drive_task_result_test.go
  • shortcuts/drive/drive_import_common_test.go
✅ Files skipped from review due to trivial changes (2)
  • skills/lark-doc/references/lark-doc-media-insert.md
  • shortcuts/drive/drive_upload.go
🚧 Files skipped from review as they are similar to previous changes (5)
  • shortcuts/drive/drive_import_test.go
  • shortcuts/drive/drive_import.go
  • shortcuts/common/drive_media_upload_test.go
  • shortcuts/doc/doc_media_insert.go
  • shortcuts/doc/doc_media_test.go

@liujinkun2025 liujinkun2025 force-pushed the feat/doc-media-chunked-upload branch from 4d4b814 to 477e7a5 Compare April 8, 2026 05:07
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
shortcuts/doc/doc_media_test.go (1)

59-79: ⚠️ Potential issue | 🟡 Minor

Use the standard isolated test setup here.

These updated tests still create factories without isolating LARKSUITE_CLI_CONFIG_DIR, and writeSizedDocTestFile goes through os.Create instead of the repo FS abstraction. That keeps the tests on shared config/filesystem behavior instead of the expected harness.

As per coding guidelines, **/*_test.go: Isolate config state in Go tests by using t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir()); and **/*.go: Use vfs.* instead of os.* for all filesystem access plus Validate paths using validate.SafeInputPath before any file I/O operations.

Also applies to: 297-310

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shortcuts/doc/doc_media_test.go` around lines 59 - 79, Tests (e.g.,
TestDocMediaInsertRejectsOldDocURL and the helpers like writeSizedDocTestFile
and mountAndRunDocs using docsTestConfigWithAppID) are not isolating config dir
or using the repo VFS; update the tests to call
t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir()) at start of each test to
isolate config state, replace any os.* usage in writeSizedDocTestFile (and other
test helpers) with the repository vfs.* APIs, and validate file paths with
validate.SafeInputPath before creating/writing files so all filesystem access is
through the virtual FS and paths are safe.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@shortcuts/common/drive_media_upload_test.go`:
- Around line 151-177: The prepare-phase assertions are too loose: ensure the
"parent_node" key is present and explicitly equals the empty string (not just
that casting yields ""), and verify the import "extra" payload is preserved into
upload_prepare by asserting prepareBody contains the extra data (e.g., that
prepareBody["extra"] has obj_type == "sheet" and file_extension == "xlsx" or the
exact extra string passed); update the checks after
decodeCapturedDriveMediaJSONBody(t, prepareStub) to explicitly test presence and
values of "parent_node" and the "extra" fields so
UploadDriveMediaMultipart/prepare handling is validated.
- Around line 411-467: newDriveMediaUploadTestRuntime currently mutates shared
config state; call t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir()) at the top
of newDriveMediaUploadTestRuntime so TestFactory and core.CliConfig use an
isolated config dir. Replace all direct os.* filesystem calls in
withDriveMediaUploadWorkingDir, writeDriveMediaUploadTestFile, and
writeDriveMediaUploadSizedFile with the repo vfs equivalents (e.g.,
vfs.Getwd/vfs.Chdir/vfs.WriteFile/vfs.Create/vfs.Truncate/vfs.Close) and
validate every input path with validate.SafeInputPath before performing I/O.
Ensure t.Cleanup still restores the working dir via vfs and keep the same helper
signatures (withDriveMediaUploadWorkingDir, writeDriveMediaUploadTestFile,
writeDriveMediaUploadSizedFile) and the RuntimeContext creation logic unchanged
aside from the environment isolation.

---

Outside diff comments:
In `@shortcuts/doc/doc_media_test.go`:
- Around line 59-79: Tests (e.g., TestDocMediaInsertRejectsOldDocURL and the
helpers like writeSizedDocTestFile and mountAndRunDocs using
docsTestConfigWithAppID) are not isolating config dir or using the repo VFS;
update the tests to call t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir()) at
start of each test to isolate config state, replace any os.* usage in
writeSizedDocTestFile (and other test helpers) with the repository vfs.* APIs,
and validate file paths with validate.SafeInputPath before creating/writing
files so all filesystem access is through the virtual FS and paths are safe.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 017c3728-7e34-4c4b-9cfb-30b4fc41d0a3

📥 Commits

Reviewing files that changed from the base of the PR and between 4d4b814 and 477e7a5.

📒 Files selected for processing (16)
  • shortcuts/common/drive_media_upload.go
  • shortcuts/common/drive_media_upload_test.go
  • shortcuts/doc/doc_media_insert.go
  • shortcuts/doc/doc_media_test.go
  • shortcuts/doc/doc_media_upload.go
  • shortcuts/drive/drive_export_test.go
  • shortcuts/drive/drive_import.go
  • shortcuts/drive/drive_import_common.go
  • shortcuts/drive/drive_import_common_test.go
  • shortcuts/drive/drive_import_test.go
  • shortcuts/drive/drive_io_test.go
  • shortcuts/drive/drive_move_common_test.go
  • shortcuts/drive/drive_move_test.go
  • shortcuts/drive/drive_task_result_test.go
  • shortcuts/drive/drive_upload.go
  • skills/lark-doc/references/lark-doc-media-insert.md
💤 Files with no reviewable changes (5)
  • shortcuts/drive/drive_move_common_test.go
  • shortcuts/drive/drive_export_test.go
  • shortcuts/drive/drive_import_common_test.go
  • shortcuts/drive/drive_move_test.go
  • shortcuts/drive/drive_task_result_test.go
✅ Files skipped from review due to trivial changes (2)
  • shortcuts/drive/drive_upload.go
  • skills/lark-doc/references/lark-doc-media-insert.md
🚧 Files skipped from review as they are similar to previous changes (5)
  • shortcuts/drive/drive_import_test.go
  • shortcuts/drive/drive_import.go
  • shortcuts/drive/drive_io_test.go
  • shortcuts/common/drive_media_upload.go
  • shortcuts/doc/doc_media_insert.go

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (3)
shortcuts/doc/doc_media_insert.go (1)

82-83: ⚠️ Potential issue | 🟡 Minor

Keep the insert dry-run upload body aligned with execution.

uploadDocMediaFile() always attaches the doc route extra, but the dry-run builder still omits it from both upload_prepare and upload_all. The previewed request shape is therefore still incomplete for docs +media-insert.

🧩 Suggested fix
-		appendDocMediaInsertUploadDryRun(d, filePath, parentType, stepBase+2)
+		appendDocMediaInsertUploadDryRun(d, filePath, parentType, documentID, stepBase+2)
...
-func appendDocMediaInsertUploadDryRun(d *common.DryRunAPI, filePath, parentType string, step int) {
+func appendDocMediaInsertUploadDryRun(d *common.DryRunAPI, filePath, parentType, documentID string, step int) {
+	extra := fmt.Sprintf(`{"drive_route_token":"%s"}`, documentID)
 	// The upload step runs only after the empty placeholder block is created, so
 	// dry-run can refer to that future block ID only symbolically. For large
 	// files, keep multipart internals as substeps of the single user-facing
 	// "upload file" step.
 	if docMediaShouldUseMultipart(filePath) {
 		d.POST("/open-apis/drive/v1/medias/upload_prepare").
 			Desc(fmt.Sprintf("[%da] Initialize multipart upload", step)).
 			Body(map[string]interface{}{
 				"file_name":   filepath.Base(filePath),
 				"parent_type": parentType,
 				"parent_node": "<new_block_id>",
 				"size":        "<file_size>",
+				"extra":       extra,
 			}).
 			POST("/open-apis/drive/v1/medias/upload_part").
@@
 	d.POST("/open-apis/drive/v1/medias/upload_all").
 		Desc(fmt.Sprintf("[%d] Upload local file (multipart/form-data)", step)).
 		Body(map[string]interface{}{
 			"file_name":   filepath.Base(filePath),
 			"parent_type": parentType,
 			"parent_node": "<new_block_id>",
 			"size":        "<file_size>",
+			"extra":       extra,
 			"file":        "@" + filePath,
 		})
 }

Also applies to: 350-389

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shortcuts/doc/doc_media_insert.go` around lines 82 - 83, The dry-run builder
in appendDocMediaInsertUploadDryRun is missing the doc route "extra" that
uploadDocMediaFile always attaches, so align the previewed request shape by
adding the same "extra" doc route to both upload_prepare and upload_all entries
in appendDocMediaInsertUploadDryRun (and any other dry-run builders in the
350-389 region); ensure the keys and values match what uploadDocMediaFile
attaches so the dry-run payload mirrors execution.
shortcuts/common/drive_media_upload_test.go (2)

411-467: ⚠️ Potential issue | 🟠 Major

Make the test harness hermetic and use repo-standard file helpers.

This suite still shares the default CLI config dir, and the new helpers write through os.*. That keeps the tests outside the repo's filesystem/config conventions and can leak machine-local state into the run.

🧪 Suggested starting point
 func newDriveMediaUploadTestRuntime(t *testing.T) (*RuntimeContext, *httpmock.Registry) {
 	t.Helper()
+	t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir())

 	cfg := &core.CliConfig{

As per coding guidelines, **/*_test.go: Isolate config state in Go tests by using t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir()); and **/*.go: Use vfs.* instead of os.* for all filesystem access plus Validate paths using validate.SafeInputPath before any file I/O operations.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shortcuts/common/drive_media_upload_test.go` around lines 411 - 467, The
tests currently touch real filesystem and share the default CLI config dir;
update newDriveMediaUploadTestRuntime to call
t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir()) to isolate config state, and
modify filesystem helpers (withDriveMediaUploadWorkingDir,
writeDriveMediaUploadTestFile, writeDriveMediaUploadSizedFile) to use the repo
vfs utilities instead of os.* (change
os.Getwd/Chdir/WriteFile/Create/Truncate/Close to the vfs equivalents) and
validate all input paths with validate.SafeInputPath before performing any I/O;
keep the same function names so callers remain stable.

167-177: ⚠️ Potential issue | 🟡 Minor

Tighten the upload_prepare assertions.

The current parent_node check still passes when the key is absent, and this path never asserts that the import extra payload survives into upload_prepare. That leaves the import-specific contract under-tested.

🧪 Suggested assertion update
 	prepareBody := decodeCapturedDriveMediaJSONBody(t, prepareStub)
 	if got, _ := prepareBody["parent_type"].(string); got != "ccm_import_open" {
 		t.Fatalf("prepare parent_type = %q, want %q", got, "ccm_import_open")
 	}
-	if got, _ := prepareBody["parent_node"].(string); got != "" {
-		t.Fatalf("prepare parent_node = %q, want empty string", got)
-	}
+	rawParentNode, ok := prepareBody["parent_node"]
+	if !ok {
+		t.Fatal("prepare body missing parent_node")
+	}
+	if got, ok := rawParentNode.(string); !ok || got != "" {
+		t.Fatalf("prepare parent_node = %#v, want empty string", rawParentNode)
+	}
+	if got, _ := prepareBody["extra"].(string); got != `{"obj_type":"sheet","file_extension":"xlsx"}` {
+		t.Fatalf("prepare extra = %q, want import payload", got)
+	}
 	if got, _ := prepareBody["size"].(float64); got != float64(MaxDriveMediaUploadSinglePartSize+1) {
 		t.Fatalf("prepare size = %v, want %d", got, MaxDriveMediaUploadSinglePartSize+1)
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shortcuts/common/drive_media_upload_test.go` around lines 167 - 177, The
prepare-body assertions are too loose: ensure the "parent_node" key is present
and explicitly equals the empty string (not just treating a missing key as ""),
and add an assertion that the import-specific "extra" payload passed into
upload_prepare survives into the captured prepareBody; use
decodeCapturedDriveMediaJSONBody(t, prepareStub) to read prepareBody and assert
prepareBody["parent_node"] exists and is "" and that prepareBody["extra"] (as a
map/object) contains the expected import fields/values from the original import
payload, keeping the existing size check using
MaxDriveMediaUploadSinglePartSize+1.
🧹 Nitpick comments (2)
shortcuts/doc/doc_media_test.go (2)

60-60: Isolate config state in the new factory call sites.

These updated cmdutil.TestFactory usages still run against the default config dir, so local config/cache can leak into the docs test suite. A small helper around TestFactory would fix this once for the file.

As per coding guidelines, **/*_test.go: Isolate config state in Go tests by using t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir()).

Also applies to: 78-78

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shortcuts/doc/doc_media_test.go` at line 60, The TestFactory calls in
doc_media_test.go (e.g., the call using cmdutil.TestFactory and helper
docsTestConfigWithAppID) are using the default config dir and may leak local
config; wrap those calls in a small local helper that first calls
t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir()) and then returns the results
of cmdutil.TestFactory(t, docsTestConfigWithAppID("docs-test-app")) (apply the
same helper to the other site at the second call around line ~78) so each test
gets an isolated config/cache directory before invoking TestFactory.

297-310: Use the repo filesystem helpers in this test utility.

This new helper writes directly via os.Create, which bypasses the same VFS/path-validation path the command code uses.

♻️ Suggested change
 func writeSizedDocTestFile(t *testing.T, name string, size int64) {
 	t.Helper()

-	fh, err := os.Create(name)
+	safeName, err := validate.SafeInputPath(name)
+	if err != nil {
+		t.Fatalf("SafeInputPath(%q) error: %v", name, err)
+	}
+	fh, err := vfs.Create(safeName)
 	if err != nil {
-		t.Fatalf("Create(%q) error: %v", name, err)
+		t.Fatalf("Create(%q) error: %v", safeName, err)
 	}

As per coding guidelines, **/*.go: Use vfs.* instead of os.* for all filesystem access and Validate paths using validate.SafeInputPath before any file I/O operations.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shortcuts/doc/doc_media_test.go` around lines 297 - 310, The helper
writeSizedDocTestFile currently uses os.Create/Truncate/Close and bypasses the
repository VFS and path validation; update it to call
validate.SafeInputPath(name) before any I/O and use the repository VFS helpers
(e.g. vfs.Create or vfs.OpenFile and then file.Truncate/file.Close or
vfs.Truncate) instead of os.* so the test goes through the same VFS/path checks
as production code; keep the same error handling via t.Fatalf but replace
os.Create, fh.Truncate and fh.Close with their vfs equivalents and
validate.SafeInputPath at the top of the function.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@shortcuts/common/drive_media_upload_test.go`:
- Around line 411-467: The tests currently touch real filesystem and share the
default CLI config dir; update newDriveMediaUploadTestRuntime to call
t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir()) to isolate config state, and
modify filesystem helpers (withDriveMediaUploadWorkingDir,
writeDriveMediaUploadTestFile, writeDriveMediaUploadSizedFile) to use the repo
vfs utilities instead of os.* (change
os.Getwd/Chdir/WriteFile/Create/Truncate/Close to the vfs equivalents) and
validate all input paths with validate.SafeInputPath before performing any I/O;
keep the same function names so callers remain stable.
- Around line 167-177: The prepare-body assertions are too loose: ensure the
"parent_node" key is present and explicitly equals the empty string (not just
treating a missing key as ""), and add an assertion that the import-specific
"extra" payload passed into upload_prepare survives into the captured
prepareBody; use decodeCapturedDriveMediaJSONBody(t, prepareStub) to read
prepareBody and assert prepareBody["parent_node"] exists and is "" and that
prepareBody["extra"] (as a map/object) contains the expected import
fields/values from the original import payload, keeping the existing size check
using MaxDriveMediaUploadSinglePartSize+1.

In `@shortcuts/doc/doc_media_insert.go`:
- Around line 82-83: The dry-run builder in appendDocMediaInsertUploadDryRun is
missing the doc route "extra" that uploadDocMediaFile always attaches, so align
the previewed request shape by adding the same "extra" doc route to both
upload_prepare and upload_all entries in appendDocMediaInsertUploadDryRun (and
any other dry-run builders in the 350-389 region); ensure the keys and values
match what uploadDocMediaFile attaches so the dry-run payload mirrors execution.

---

Nitpick comments:
In `@shortcuts/doc/doc_media_test.go`:
- Line 60: The TestFactory calls in doc_media_test.go (e.g., the call using
cmdutil.TestFactory and helper docsTestConfigWithAppID) are using the default
config dir and may leak local config; wrap those calls in a small local helper
that first calls t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir()) and then
returns the results of cmdutil.TestFactory(t,
docsTestConfigWithAppID("docs-test-app")) (apply the same helper to the other
site at the second call around line ~78) so each test gets an isolated
config/cache directory before invoking TestFactory.
- Around line 297-310: The helper writeSizedDocTestFile currently uses
os.Create/Truncate/Close and bypasses the repository VFS and path validation;
update it to call validate.SafeInputPath(name) before any I/O and use the
repository VFS helpers (e.g. vfs.Create or vfs.OpenFile and then
file.Truncate/file.Close or vfs.Truncate) instead of os.* so the test goes
through the same VFS/path checks as production code; keep the same error
handling via t.Fatalf but replace os.Create, fh.Truncate and fh.Close with their
vfs equivalents and validate.SafeInputPath at the top of the function.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 56149a51-103c-4df1-90e0-f5c17dc2521a

📥 Commits

Reviewing files that changed from the base of the PR and between 4d4b814 and 477e7a5.

📒 Files selected for processing (16)
  • shortcuts/common/drive_media_upload.go
  • shortcuts/common/drive_media_upload_test.go
  • shortcuts/doc/doc_media_insert.go
  • shortcuts/doc/doc_media_test.go
  • shortcuts/doc/doc_media_upload.go
  • shortcuts/drive/drive_export_test.go
  • shortcuts/drive/drive_import.go
  • shortcuts/drive/drive_import_common.go
  • shortcuts/drive/drive_import_common_test.go
  • shortcuts/drive/drive_import_test.go
  • shortcuts/drive/drive_io_test.go
  • shortcuts/drive/drive_move_common_test.go
  • shortcuts/drive/drive_move_test.go
  • shortcuts/drive/drive_task_result_test.go
  • shortcuts/drive/drive_upload.go
  • skills/lark-doc/references/lark-doc-media-insert.md
💤 Files with no reviewable changes (5)
  • shortcuts/drive/drive_move_test.go
  • shortcuts/drive/drive_move_common_test.go
  • shortcuts/drive/drive_export_test.go
  • shortcuts/drive/drive_task_result_test.go
  • shortcuts/drive/drive_import_common_test.go
✅ Files skipped from review due to trivial changes (2)
  • skills/lark-doc/references/lark-doc-media-insert.md
  • shortcuts/drive/drive_io_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • shortcuts/drive/drive_import_test.go
  • shortcuts/drive/drive_upload.go
  • shortcuts/drive/drive_import_common.go

Change-Id: I9d9fb00079dacfc96b5781e12e6ce79945baa2ed
@liujinkun2025 liujinkun2025 force-pushed the feat/doc-media-chunked-upload branch from 477e7a5 to 04fdb54 Compare April 8, 2026 06:42
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
shortcuts/common/drive_media_upload.go (1)

186-191: Consider capping buffer allocation to file size for small files.

While the buffer is bounded by maxInt, a large BlockSize returned by the backend (e.g., 100MB for a 1KB file) would still allocate unnecessarily. This is a defensive improvement rather than a bug, since the actual reads are bounded by remaining.

💡 Optional defensive improvement
 	maxInt := int64(^uint(0) >> 1)
 	bufferSize := session.BlockSize
+	if fileSize > 0 && bufferSize > fileSize {
+		bufferSize = fileSize
+	}
 	if bufferSize <= 0 || bufferSize > maxInt {
 		return output.Errorf(output.ExitAPI, "api_error", "upload prepare failed: invalid block_size returned")
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shortcuts/common/drive_media_upload.go` around lines 186 - 191, The code
allocates buffer sized to session.BlockSize which can be much larger than the
actual remaining file bytes; cap the allocation by taking the minimum of
session.BlockSize, the remaining bytes to upload (compute remaining = totalSize
- uploadedBytes from your upload loop/state), and maxInt before make([]byte,
...). Update the bufferSize calculation (use session.BlockSize, maxInt and
remaining) and replace buffer := make([]byte, int(bufferSize)) so small files
don't allocate oversized buffers.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@shortcuts/common/drive_media_upload.go`:
- Around line 186-191: The code allocates buffer sized to session.BlockSize
which can be much larger than the actual remaining file bytes; cap the
allocation by taking the minimum of session.BlockSize, the remaining bytes to
upload (compute remaining = totalSize - uploadedBytes from your upload
loop/state), and maxInt before make([]byte, ...). Update the bufferSize
calculation (use session.BlockSize, maxInt and remaining) and replace buffer :=
make([]byte, int(bufferSize)) so small files don't allocate oversized buffers.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: afa28e62-9264-41a9-8993-28803635cbf7

📥 Commits

Reviewing files that changed from the base of the PR and between 477e7a5 and 04fdb54.

📒 Files selected for processing (16)
  • shortcuts/common/drive_media_upload.go
  • shortcuts/common/drive_media_upload_test.go
  • shortcuts/doc/doc_media_insert.go
  • shortcuts/doc/doc_media_test.go
  • shortcuts/doc/doc_media_upload.go
  • shortcuts/drive/drive_export_test.go
  • shortcuts/drive/drive_import.go
  • shortcuts/drive/drive_import_common.go
  • shortcuts/drive/drive_import_common_test.go
  • shortcuts/drive/drive_import_test.go
  • shortcuts/drive/drive_io_test.go
  • shortcuts/drive/drive_move_common_test.go
  • shortcuts/drive/drive_move_test.go
  • shortcuts/drive/drive_task_result_test.go
  • shortcuts/drive/drive_upload.go
  • skills/lark-doc/references/lark-doc-media-insert.md
💤 Files with no reviewable changes (5)
  • shortcuts/drive/drive_export_test.go
  • shortcuts/drive/drive_move_test.go
  • shortcuts/drive/drive_task_result_test.go
  • shortcuts/drive/drive_import_common_test.go
  • shortcuts/drive/drive_move_common_test.go
✅ Files skipped from review due to trivial changes (1)
  • skills/lark-doc/references/lark-doc-media-insert.md
🚧 Files skipped from review as they are similar to previous changes (6)
  • shortcuts/drive/drive_import_test.go
  • shortcuts/drive/drive_io_test.go
  • shortcuts/drive/drive_upload.go
  • shortcuts/doc/doc_media_upload.go
  • shortcuts/drive/drive_import_common.go
  • shortcuts/doc/doc_media_insert.go

@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Apr 8, 2026

Greptile encountered an error while reviewing this PR. Please reach out to support@greptile.com for assistance.

@fangshuyu-768 fangshuyu-768 merged commit 6ac5b4d into main Apr 8, 2026
16 checks passed
@fangshuyu-768 fangshuyu-768 deleted the feat/doc-media-chunked-upload branch April 8, 2026 07:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain/ccm PR touches the ccm domain size/L Large or sensitive change across domains or core paths

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants