mirror of
https://github.com/gabrie30/ghorg.git
synced 2025-08-06 14:27:28 +02:00
Update/ghorgls (#450)
This commit is contained in:
parent
99958635bc
commit
08add68314
@ -7,6 +7,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|||||||
### Added
|
### Added
|
||||||
- GHORG_NO_DIR_SIZE flag to turn off directory size output which is now enabled by default
|
- GHORG_NO_DIR_SIZE flag to turn off directory size output which is now enabled by default
|
||||||
- GHORG_STATS_ENABLED flag to track clone data over time, set to false by default
|
- GHORG_STATS_ENABLED flag to track clone data over time, set to false by default
|
||||||
|
- Added two new flags to the `ghorg ls` command: `--long` and `--total`, which provide additional information about the cloned directories.
|
||||||
### Changed
|
### Changed
|
||||||
### Deprecated
|
### Deprecated
|
||||||
### Removed
|
### Removed
|
||||||
|
@ -351,7 +351,7 @@ Below are the headers and their descriptions. Note that these headers may change
|
|||||||
- **newClonesCount**: Sum of all new repos cloned
|
- **newClonesCount**: Sum of all new repos cloned
|
||||||
- **existingResourcesPulledCount**: Sum of all repos that were pulled
|
- **existingResourcesPulledCount**: Sum of all repos that were pulled
|
||||||
- **dirSizeInMB**: The size in megabytes of the output dir
|
- **dirSizeInMB**: The size in megabytes of the output dir
|
||||||
- **newCommits**: Sum of all new commits in all repos pulled or cloned
|
- **newCommits**: Sum of all new commits in all repos pulled
|
||||||
- **cloneInfosCount**: Number of clone Info messages
|
- **cloneInfosCount**: Number of clone Info messages
|
||||||
- **cloneErrorsCount**: Number of clone Issues/Errors
|
- **cloneErrorsCount**: Number of clone Issues/Errors
|
||||||
- **updateRemoteCount**: Number of remotes updated
|
- **updateRemoteCount**: Number of remotes updated
|
||||||
|
21
cmd/clone.go
21
cmd/clone.go
@ -19,6 +19,7 @@ import (
|
|||||||
"github.com/gabrie30/ghorg/configs"
|
"github.com/gabrie30/ghorg/configs"
|
||||||
"github.com/gabrie30/ghorg/git"
|
"github.com/gabrie30/ghorg/git"
|
||||||
"github.com/gabrie30/ghorg/scm"
|
"github.com/gabrie30/ghorg/scm"
|
||||||
|
"github.com/gabrie30/ghorg/utils"
|
||||||
"github.com/korovkin/limiter"
|
"github.com/korovkin/limiter"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
@ -1090,7 +1091,7 @@ func printFinishedWithDirSize() {
|
|||||||
|
|
||||||
func getCachedOrCalculatedOutputDirSizeInMb() (float64, error) {
|
func getCachedOrCalculatedOutputDirSizeInMb() (float64, error) {
|
||||||
if !isDirSizeCached {
|
if !isDirSizeCached {
|
||||||
dirSizeMB, err := calculateDirSizeInMb(outputDirAbsolutePath)
|
dirSizeMB, err := utils.CalculateDirSizeInMb(outputDirAbsolutePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@ -1100,24 +1101,6 @@ func getCachedOrCalculatedOutputDirSizeInMb() (float64, error) {
|
|||||||
return cachedDirSizeMB, nil
|
return cachedDirSizeMB, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func calculateDirSizeInMb(path string) (float64, error) {
|
|
||||||
var size int64
|
|
||||||
err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if !info.IsDir() {
|
|
||||||
size += info.Size()
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
const bytesInMegabyte = 1000 * 1000
|
|
||||||
return float64(size) / bytesInMegabyte, nil // Return size in Megabyte
|
|
||||||
}
|
|
||||||
|
|
||||||
func filterByTargetReposPath(cloneTargets []scm.Repo) []scm.Repo {
|
func filterByTargetReposPath(cloneTargets []scm.Repo) []scm.Repo {
|
||||||
|
|
||||||
_, err := os.Stat(os.Getenv("GHORG_TARGET_REPOS_PATH"))
|
_, err := os.Stat(os.Getenv("GHORG_TARGET_REPOS_PATH"))
|
||||||
|
72
cmd/ls.go
72
cmd/ls.go
@ -1,11 +1,13 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gabrie30/ghorg/colorlog"
|
"github.com/gabrie30/ghorg/colorlog"
|
||||||
|
"github.com/gabrie30/ghorg/utils"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -36,9 +38,76 @@ func listGhorgHome() {
|
|||||||
colorlog.PrintError("No clones found. Please clone some and try again.")
|
colorlog.PrintError("No clones found. Please clone some and try again.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
longFormat := false
|
||||||
|
totalFormat := false
|
||||||
|
for _, arg := range os.Args {
|
||||||
|
if arg == "-l" || arg == "--long" {
|
||||||
|
longFormat = true
|
||||||
|
}
|
||||||
|
if arg == "-t" || arg == "--total" {
|
||||||
|
totalFormat = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !longFormat && !totalFormat {
|
||||||
|
for _, f := range files {
|
||||||
|
if f.IsDir() {
|
||||||
|
colorlog.PrintInfo(path + f.Name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var totalDirs int
|
||||||
|
var totalSizeMB float64
|
||||||
|
var totalRepos int
|
||||||
|
|
||||||
for _, f := range files {
|
for _, f := range files {
|
||||||
if f.IsDir() {
|
if f.IsDir() {
|
||||||
colorlog.PrintInfo(path + f.Name())
|
totalDirs++
|
||||||
|
dirPath := filepath.Join(path, f.Name())
|
||||||
|
dirSizeMB, err := utils.CalculateDirSizeInMb(dirPath)
|
||||||
|
if err != nil {
|
||||||
|
colorlog.PrintError(fmt.Sprintf("Error calculating directory size for %s: %v", dirPath, err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
totalSizeMB += dirSizeMB
|
||||||
|
|
||||||
|
// Count the number of directories with a depth of 1 inside
|
||||||
|
subDirCount := 0
|
||||||
|
subFiles, err := os.ReadDir(dirPath)
|
||||||
|
if err != nil {
|
||||||
|
colorlog.PrintError(fmt.Sprintf("Error reading directory contents for %s: %v", dirPath, err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, subFile := range subFiles {
|
||||||
|
if subFile.IsDir() {
|
||||||
|
subDirCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
totalRepos += subDirCount
|
||||||
|
|
||||||
|
if !totalFormat || longFormat {
|
||||||
|
if longFormat {
|
||||||
|
if dirSizeMB > 1000 {
|
||||||
|
dirSizeGB := dirSizeMB / 1000
|
||||||
|
colorlog.PrintInfo(fmt.Sprintf("%-50s %10.2f GB %10d repos", dirPath, dirSizeGB, subDirCount))
|
||||||
|
} else {
|
||||||
|
colorlog.PrintInfo(fmt.Sprintf("%-50s %10.2f MB %10d repos", dirPath, dirSizeMB, subDirCount))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
colorlog.PrintInfo(path + f.Name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if totalFormat {
|
||||||
|
if totalSizeMB > 1000 {
|
||||||
|
totalSizeGB := totalSizeMB / 1000
|
||||||
|
colorlog.PrintInfo(fmt.Sprintf("Total: %d directories, %.2f GB, %d repos", totalDirs, totalSizeGB, totalRepos))
|
||||||
|
} else {
|
||||||
|
colorlog.PrintInfo(fmt.Sprintf("Total: %d directories, %.2f MB, %d repos", totalDirs, totalSizeMB, totalRepos))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,7 +129,6 @@ func listGhorgDir(arg string) {
|
|||||||
colorlog.PrintError("No clones found. Please clone some and try again.")
|
colorlog.PrintError("No clones found. Please clone some and try again.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for _, f := range files {
|
for _, f := range files {
|
||||||
if f.IsDir() {
|
if f.IsDir() {
|
||||||
str := filepath.Join(path, f.Name())
|
str := filepath.Join(path, f.Name())
|
||||||
|
@ -351,6 +351,9 @@ func init() {
|
|||||||
reCloneCmd.Flags().BoolVar(&ghorgReCloneList, "list", false, "Prints reclone commands and optional descriptions to stdout then will exit 0. Does not obsfucate tokens, and is only available as a commandline argument")
|
reCloneCmd.Flags().BoolVar(&ghorgReCloneList, "list", false, "Prints reclone commands and optional descriptions to stdout then will exit 0. Does not obsfucate tokens, and is only available as a commandline argument")
|
||||||
reCloneCmd.Flags().BoolVar(&ghorgReCloneEnvConfigOnly, "env-config-only", false, "GHORG_RECLONE_ENV_CONFIG_ONLY - Only use environment variables to set the configuration for all reclones.")
|
reCloneCmd.Flags().BoolVar(&ghorgReCloneEnvConfigOnly, "env-config-only", false, "GHORG_RECLONE_ENV_CONFIG_ONLY - Only use environment variables to set the configuration for all reclones.")
|
||||||
|
|
||||||
|
lsCmd.Flags().BoolP("long", "l", false, "Display detailed information about each clone directory, including size and number of repositories. Note: This may take longer depending on the number and size of the cloned organizations.")
|
||||||
|
lsCmd.Flags().BoolP("total", "t", false, "Display total amounts of all repos cloned. Note: This may take longer depending on the number and size of the cloned organizations.")
|
||||||
|
|
||||||
rootCmd.AddCommand(lsCmd, versionCmd, cloneCmd, reCloneCmd, examplesCmd)
|
rootCmd.AddCommand(lsCmd, versionCmd, cloneCmd, reCloneCmd, examplesCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
package utils
|
|
||||||
|
|
||||||
// IsStringInSlice check if a string is in a given slice
|
|
||||||
func IsStringInSlice(s string, sl []string) bool {
|
|
||||||
for i := range sl {
|
|
||||||
if sl[i] == s {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
34
utils/utils.go
Normal file
34
utils/utils.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IsStringInSlice check if a string is in a given slice
|
||||||
|
func IsStringInSlice(s string, sl []string) bool {
|
||||||
|
for i := range sl {
|
||||||
|
if sl[i] == s {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func CalculateDirSizeInMb(path string) (float64, error) {
|
||||||
|
var size int64
|
||||||
|
err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !info.IsDir() {
|
||||||
|
size += info.Size()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
const bytesInMegabyte = 1000 * 1000
|
||||||
|
return float64(size) / bytesInMegabyte, nil // Return size in Megabyte
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user