Skip to content

Commit 3c5a7c8

Browse files
committed
feat(size): add size check for environment or globally
1 parent dc9b6ec commit 3c5a7c8

File tree

4 files changed

+117
-2
lines changed

4 files changed

+117
-2
lines changed

README.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ A powerful CLI tool for managing Python virtual environments with ease.
1414
- Clean cache and temporary files
1515
- Smart environment activation
1616
- Shell completion for bash, zsh, fish, and powershell
17+
- Size check for environments
1718

1819
| Feature | venv-manager | virtualenv | pyenv-virtualenv | Poetry | Pipenv |
1920
|---------|-------------|------------|-----------------|--------|--------|
@@ -34,8 +35,8 @@ curl -sSL https://raw.githubusercontent.com/jacopobonomi/venv_manager/main/insta
3435

3536
```bash
3637
# Clone repository
37-
git clone https://github.com/jacopobonomi/venv-manager
38-
cd venv-manager
38+
git clone https://github.com/jacopobonomi/venv_manager
39+
cd venv_manager
3940

4041
# Install
4142
make install
@@ -59,6 +60,12 @@ venv-manager packages myenv
5960
# Upgrade all packages
6061
venv-manager upgrade myenv
6162

63+
# Check environment size
64+
venv-manager size myenv
65+
66+
# Check all environments size
67+
venv-manager size --global
68+
6269
# Global operations
6370
venv-manager --global clean
6471

@@ -80,11 +87,13 @@ source <(venv-manager completion bash)
8087
| `install <n> <reqs>` | Install requirements |
8188
| `upgrade <n>` | Upgrade packages |
8289
| `clean <n>` | Clean cache files |
90+
| `size <n>` | Check environment size |
8391
| `completion [bash|zsh|fish|powershell]` | Generate shell completion scripts |
8492

8593
## Development 🛠️
8694

8795
Requirements:
96+
8897
- Go 1.21+
8998
- Python 3.x
9099

cmd/venv-manager/main.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"path/filepath"
77

88
"github.com/jacopobonomi/venv-manager/internal/manager"
9+
"github.com/jacopobonomi/venv-manager/internal/utils"
910
"github.com/spf13/cobra"
1011
)
1112

@@ -42,6 +43,7 @@ func init() {
4243
rootCmd.AddCommand(cleanCmd())
4344
rootCmd.AddCommand(activateCmd())
4445
rootCmd.AddCommand(deactivateCmd())
46+
rootCmd.AddCommand(sizeCmd())
4547
rootCmd.AddCommand(completionCmd())
4648
}
4749

@@ -266,6 +268,41 @@ func deactivateCmd() *cobra.Command {
266268
return cmd
267269
}
268270

271+
func sizeCmd() *cobra.Command {
272+
cmd := &cobra.Command{
273+
Use: "size [name]",
274+
Short: "Check the size of a virtual environment",
275+
Run: func(cmd *cobra.Command, args []string) {
276+
mgr.SetGlobal(globalFlag)
277+
name := ""
278+
if len(args) > 0 && !globalFlag {
279+
name = args[0]
280+
}
281+
282+
// Display appropriate header
283+
if name != "" {
284+
fmt.Printf("%s📊 Size of virtual environment '%s':%s\n", colorYellow, name, colorReset)
285+
} else if globalFlag {
286+
fmt.Printf("%s📊 Sizes of all virtual environments:%s\n", colorYellow, colorReset)
287+
}
288+
289+
// Get sizes from manager
290+
sizes, err := mgr.GetSize(name)
291+
if err != nil {
292+
fmt.Fprintf(os.Stderr, "%s%v%s\n", colorRed, err, colorReset)
293+
os.Exit(1)
294+
}
295+
296+
// Display results
297+
for venvName, size := range sizes {
298+
sizeStr := utils.FormatSize(size)
299+
fmt.Printf("- %s: %s\n", venvName, sizeStr)
300+
}
301+
},
302+
}
303+
return cmd
304+
}
305+
269306
func main() {
270307
if err := rootCmd.Execute(); err != nil {
271308
fmt.Fprintf(os.Stderr, "%s%v%s\n", colorRed, err, colorReset)

internal/manager/manager.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,3 +301,38 @@ func (m *Manager) ListPackages(name string) ([]string, error) {
301301
}
302302
return result, nil
303303
}
304+
305+
func (m *Manager) GetSize(name string) (map[string]int64, error) {
306+
sizes := make(map[string]int64)
307+
308+
if name != "" {
309+
venvPath := filepath.Join(m.baseDir, name)
310+
if !m.fs.Exists(venvPath) {
311+
return nil, fmt.Errorf("venv '%s' does not exist", name)
312+
}
313+
314+
size, err := m.fs.GetDirSize(venvPath)
315+
if err != nil {
316+
return nil, err
317+
}
318+
sizes[name] = size
319+
} else if m.global {
320+
venvs, err := m.List()
321+
if err != nil {
322+
return nil, err
323+
}
324+
325+
for _, venv := range venvs {
326+
venvPath := filepath.Join(m.baseDir, venv)
327+
size, err := m.fs.GetDirSize(venvPath)
328+
if err != nil {
329+
return nil, err
330+
}
331+
sizes[venv] = size
332+
}
333+
} else {
334+
return nil, fmt.Errorf("please specify a venv name or use --global flag")
335+
}
336+
337+
return sizes, nil
338+
}

internal/utils/filesystem.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package utils
22

33
import (
4+
"fmt"
45
"os"
6+
"path/filepath"
57
)
68

79
type FileSystem interface {
@@ -10,6 +12,7 @@ type FileSystem interface {
1012
Exists(path string) bool
1113
IsDir(path string) bool
1214
ReadDir(path string) ([]os.DirEntry, error)
15+
GetDirSize(path string) (int64, error)
1316
}
1417

1518
type RealFileSystem struct{}
@@ -39,3 +42,34 @@ func (fs *RealFileSystem) IsDir(path string) bool {
3942
func (fs *RealFileSystem) ReadDir(path string) ([]os.DirEntry, error) {
4043
return os.ReadDir(path)
4144
}
45+
46+
func (fs *RealFileSystem) GetDirSize(path string) (int64, error) {
47+
var size int64
48+
err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error {
49+
if err != nil {
50+
return err
51+
}
52+
if !info.IsDir() {
53+
size += info.Size()
54+
}
55+
return nil
56+
})
57+
return size, err
58+
}
59+
60+
func FormatSize(bytes int64) string {
61+
const (
62+
KB = 1024
63+
MB = 1024 * KB
64+
GB = 1024 * MB
65+
)
66+
67+
if bytes < KB {
68+
return fmt.Sprintf("%d B", bytes)
69+
} else if bytes < MB {
70+
return fmt.Sprintf("%.2f KB", float64(bytes)/KB)
71+
} else if bytes < GB {
72+
return fmt.Sprintf("%.2f MB", float64(bytes)/MB)
73+
}
74+
return fmt.Sprintf("%.2f GB", float64(bytes)/GB)
75+
}

0 commit comments

Comments
 (0)