-
Notifications
You must be signed in to change notification settings - Fork 0
feat(drive): add tree command #66
Copy link
Copy link
Closed
Description
Summary
Add gro drive tree command to display the folder structure of Google Drive in a tree format.
Usage
gro drive tree # Show folder tree from root
gro drive tree <folder-id> # Show tree from specific folder
gro drive tree --depth 3 # Limit depth
gro drive tree --files # Include files, not just folders
gro drive tree --json # JSON outputFlags
| Flag | Short | Default | Description |
|---|---|---|---|
--depth |
-d |
2 | Maximum depth to traverse |
--files |
- | false | Include files in addition to folders |
--json |
-j |
false | Output as JSON |
Implementation
Files to Create/Modify
-
internal/cmd/drive/tree.go- Tree command implementation -
internal/cmd/drive/tree_test.go- Unit tests -
internal/cmd/drive/drive.go- Register tree subcommand
Data Structure
type TreeNode struct {
ID string `json:"id"`
Name string `json:"name"`
Type string `json:"type"` // "folder" or file type
Children []*TreeNode `json:"children,omitempty"`
}Algorithm
func buildTree(folderID string, depth int, includeFiles bool) (*TreeNode, error) {
if depth <= 0 {
return nil, nil
}
// Get folder info
folder, err := client.GetFile(folderID)
// List children
query := fmt.Sprintf("'%s' in parents and trashed = false", folderID)
if !includeFiles {
query += " and mimeType = 'application/vnd.google-apps.folder'"
}
children, err := client.ListFiles(query, 100)
node := &TreeNode{
ID: folder.ID,
Name: folder.Name,
Type: "folder",
}
// Recursively build children
for _, child := range children {
if child.MimeType == folderMimeType {
childNode, _ := buildTree(child.ID, depth-1, includeFiles)
node.Children = append(node.Children, childNode)
} else {
node.Children = append(node.Children, &TreeNode{
ID: child.ID,
Name: child.Name,
Type: getTypeName(child.MimeType),
})
}
}
return node, nil
}Text Output Format
My Drive
├── Projects
│ ├── Q4 Planning
│ │ └── Budget.xlsx
│ └── Marketing
│ ├── Campaigns
│ └── Assets
├── Documents
│ ├── Reports
│ └── Templates
└── Shared with me
└── Team Files
Without --files:
My Drive
├── Projects
│ ├── Q4 Planning
│ └── Marketing
│ ├── Campaigns
│ └── Assets
├── Documents
│ ├── Reports
│ └── Templates
└── Shared with me
└── Team Files
JSON Output
{
"id": "root",
"name": "My Drive",
"type": "folder",
"children": [
{
"id": "1abc...",
"name": "Projects",
"type": "folder",
"children": [
{
"id": "2def...",
"name": "Q4 Planning",
"type": "folder",
"children": [
{
"id": "3ghi...",
"name": "Budget.xlsx",
"type": "spreadsheet"
}
]
}
]
}
]
}Performance Considerations
- Default depth of 2 to avoid excessive API calls
- Consider pagination for folders with many children
- Could add
--max-childrenflag to limit children per folder
Acceptance Criteria
- Shows folder structure from root by default
- Shows tree from specific folder when folder-id provided
- Respects depth limit
-
--filesflag includes files in output - Tree characters render correctly (├── └── │)
- JSON output works
- Handles empty folders gracefully
-
make verifypasses
Blocked By
- feat(drive): add Drive client foundation and parent command #61 (foundation)
- feat(drive): add list command #62 (list) - reuses listing logic
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels