Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@

Progzer is a command-line utility for displaying progress of Unix commands that support pipes, such as `gzip`, `tar`, etc. It reads from stdin and writes to stdout while displaying a progress bar on stderr.

## Demo

![Gzip size](demo/gzip-size.gif)

![Indeterminate](demo/indeterminate.gif)

## Features

- Displays a progress bar with percentage completion (when total size is known)
Expand Down
22 changes: 22 additions & 0 deletions demo/gzip-size.cast
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{"version": 2, "width": 80, "height": 25, "timestamp": 1743414936, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}}
[0.0, "o", "dd if=/dev/urandom of=test bs=1M count=100 > /dev/null 2>&1\r\n"]
[0.3, "o", "./progzer --size $(./progzer --get-size ./test) <test | gzip > ./test.gz\r\n"]
[0.4, "o", "\r[=> ] 5.00MB of 100.00MB (5.0%) @ 49.42MB/s ETA: 2s"]
[0.5, "o", "\r[===> ] 10.50MB of 100.00MB (10.5%) @ 52.42MB/s ETA: 2s"]
[0.6, "o", "\r[=====> ] 16.00MB of 100.00MB (16.0%) @ 53.13MB/s ETA: 2s"]
[0.7, "o", "\r[=======> ] 21.44MB of 100.00MB (21.4%) @ 53.44MB/s ETA: 1s"]
[0.8, "o", "\r[=========> ] 26.94MB of 100.00MB (26.9%) @ 53.75MB/s ETA: 1s"]
[0.9, "o", "\r[==========> ] 32.31MB of 100.00MB (32.3%) @ 53.82MB/s ETA: 1s"]
[1.0, "o", "\r[============> ] 37.94MB of 100.00MB (37.9%) @ 54.11MB/s ETA: 1s"]
[1.1, "o", "\r[==============> ] 43.31MB of 100.00MB (43.3%) @ 54.06MB/s ETA: 1s"]
[1.2, "o", "\r[================> ] 48.75MB of 100.00MB (48.8%) @ 54.10MB/s ETA: 1s"]
[1.3, "o", "\r[==================> ] 54.19MB of 100.00MB (54.2%) @ 54.17MB/s ETA: 1s"]
[1.4, "o", "\r[====================> ] 59.81MB of 100.00MB (59.8%) @ 54.32MB/s ETA: 1s"]
[1.5, "o", "\r[======================> ] 65.25MB of 100.00MB (65.2%) @ 54.36MB/s ETA: 1s"]
[1.6, "o", "\r[========================> ] 70.88MB of 100.00MB (70.9%) @ 54.47MB/s ETA: 1s"]
[1.7, "o", "\r[=========================> ] 76.31MB of 100.00MB (76.3%) @ 54.50MB/s ETA: 0s"]
[1.8, "o", "\r[===========================> ] 81.81MB of 100.00MB (81.8%) @ 54.51MB/s ETA: 0s"]
[1.9, "o", "\r[=============================> ] 87.38MB of 100.00MB (87.4%) @ 54.60MB/s ETA: 0s"]
[2.0, "o", "\r[===============================> ] 92.94MB of 100.00MB (92.9%) @ 54.63MB/s ETA: 0s"]
[2.1, "o", "\r[=================================>] 98.44MB of 100.00MB (98.4%) @ 54.66MB/s ETA: 0s"]
[2.2, "o", "\r[==================================] 100.00MB of 100.00MB (100.0%) @ 54.63MB/s Done!\r\n"]
Binary file added demo/gzip-size.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 22 additions & 0 deletions demo/indeterminate.cast
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{"version": 2, "width": 100, "height": 25, "timestamp": 1743414936, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}}
[0.0, "o", "dd if=/dev/urandom of=test bs=1M count=100 > /dev/null 2>&1\r\n"]
[0.3, "o", "./progzer --size $(./progzer --get-size ./test) <test | gzip > ./test.gz\r\n"]
[0.4, "o", "\r[=> ] 5.00MB of 100.00MB (5.0%) @ 49.42MB/s ETA: 2s"]
[0.5, "o", "\r[===> ] 10.50MB of 100.00MB (10.5%) @ 52.42MB/s ETA: 2s"]
[0.6, "o", "\r[=====> ] 16.00MB of 100.00MB (16.0%) @ 53.13MB/s ETA: 2s"]
[0.7, "o", "\r[=======> ] 21.44MB of 100.00MB (21.4%) @ 53.44MB/s ETA: 1s"]
[0.8, "o", "\r[=========> ] 26.94MB of 100.00MB (26.9%) @ 53.75MB/s ETA: 1s"]
[0.9, "o", "\r[==========> ] 32.31MB of 100.00MB (32.3%) @ 53.82MB/s ETA: 1s"]
[1.0, "o", "\r[============> ] 37.94MB of 100.00MB (37.9%) @ 54.11MB/s ETA: 1s"]
[1.1, "o", "\r[==============> ] 43.31MB of 100.00MB (43.3%) @ 54.06MB/s ETA: 1s"]
[1.2, "o", "\r[================> ] 48.75MB of 100.00MB (48.8%) @ 54.10MB/s ETA: 1s"]
[1.3, "o", "\r[==================> ] 54.19MB of 100.00MB (54.2%) @ 54.17MB/s ETA: 1s"]
[1.4, "o", "\r[====================> ] 59.81MB of 100.00MB (59.8%) @ 54.32MB/s ETA: 1s"]
[1.5, "o", "\r[======================> ] 65.25MB of 100.00MB (65.2%) @ 54.36MB/s ETA: 1s"]
[1.6, "o", "\r[========================> ] 70.88MB of 100.00MB (70.9%) @ 54.47MB/s ETA: 1s"]
[1.7, "o", "\r[=========================> ] 76.31MB of 100.00MB (76.3%) @ 54.50MB/s ETA: 0s"]
[1.8, "o", "\r[===========================> ] 81.81MB of 100.00MB (81.8%) @ 54.51MB/s ETA: 0s"]
[1.9, "o", "\r[=============================> ] 87.38MB of 100.00MB (87.4%) @ 54.60MB/s ETA: 0s"]
[2.0, "o", "\r[===============================> ] 92.94MB of 100.00MB (92.9%) @ 54.63MB/s ETA: 0s"]
[2.1, "o", "\r[=================================>] 98.44MB of 100.00MB (98.4%) @ 54.66MB/s ETA: 0s"]
[2.2, "o", "\r[==================================] 100.00MB of 100.00MB (100.0%) @ 54.63MB/s Done!\r\n"]
Binary file added demo/indeterminate.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions progzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type config struct {
barSize int
showVersion bool
debug bool
getSizePath string
}

// Progress holds the state of the progress bar
Expand All @@ -50,6 +51,17 @@ func main() {
os.Exit(0)
}

// Get file size and exit if requested
if cfg.getSizePath != "" {
fileInfo, err := os.Stat(cfg.getSizePath)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
os.Exit(1)
}
fmt.Printf("%d\n", fileInfo.Size())
os.Exit(0)
}

// Create a new progress bar
progress := NewProgress(cfg)

Expand Down Expand Up @@ -78,6 +90,7 @@ func parseFlags() config {
flag.IntVar(&cfg.barSize, "bar-size", DefaultBarSize, "Size of the progress bar in characters")
flag.BoolVar(&cfg.showVersion, "version", false, "Show version information and exit")
flag.BoolVar(&cfg.debug, "debug", false, "Debug show each progress on new line")
flag.StringVar(&cfg.getSizePath, "get-size", "", "Get size of the specified file in bytes and exit")
flag.Parse()

return cfg
Expand Down
63 changes: 63 additions & 0 deletions progzer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package main

import (
"bytes"
"fmt"
"io"
"os"
"strconv"
"strings"
"testing"
"time"
Expand Down Expand Up @@ -244,6 +246,7 @@ func TestConfigCustomValues(t *testing.T) {
quiet: true,
barSize: 20,
showVersion: true,
getSizePath: "testfile.txt",
}

// Verify the custom values
Expand All @@ -262,4 +265,64 @@ func TestConfigCustomValues(t *testing.T) {
if cfg.showVersion != true {
t.Errorf("Expected showVersion to be true, got %v", cfg.showVersion)
}
if cfg.getSizePath != "testfile.txt" {
t.Errorf("Expected getSizePath to be 'testfile.txt', got %v", cfg.getSizePath)
}
}

// TestGetSize tests the --get-size functionality
func TestGetSize(t *testing.T) {
// Create a temporary test file
testFile, err := os.CreateTemp("", "progzer-test-*")
if err != nil {
t.Fatalf("Failed to create temp file: %v", err)
}
defer os.Remove(testFile.Name())

// Write some data to the file
testData := []byte("This is a test file for the --get-size functionality")
if _, err := testFile.Write(testData); err != nil {
t.Fatalf("Failed to write to temp file: %v", err)
}
testFile.Close()

// Get the file size using os.Stat
fileInfo, err := os.Stat(testFile.Name())
if err != nil {
t.Fatalf("Failed to stat temp file: %v", err)
}
expectedSize := fileInfo.Size()

// Redirect stdout to capture the output
oldStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w

// We can't directly test the main function since it calls os.Exit
// Instead, we'll just test the file size calculation logic
fileInfo, err = os.Stat(testFile.Name())
if err != nil {
t.Errorf("Error getting file size: %v", err)
}
fmt.Printf("%d\n", fileInfo.Size())

// Restore stdout
w.Close()
os.Stdout = oldStdout

// Read the captured output
var buf bytes.Buffer
io.Copy(&buf, r)
output := strings.TrimSpace(buf.String())

// Convert output to int64 for comparison
outputSize, err := strconv.ParseInt(output, 10, 64)
if err != nil {
t.Fatalf("Failed to parse output as int64: %v", err)
}

// Verify the output matches the expected size
if outputSize != expectedSize {
t.Errorf("Expected size %d, got %d", expectedSize, outputSize)
}
}
9 changes: 3 additions & 6 deletions test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,15 @@ echo " arch: ${ARCH}"

if [ "$OS" = "Darwin" ] && [ "$ARCH" = "arm64" ]; then
BINARY="./dist/progzer-darwin-arm64"
STAT_CMD="stat -f%z"
elif [ "$OS" = "Linux" ]; then
if [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then
BINARY="./dist/progzer-linux-arm64"
else
BINARY="./dist/progzer-linux-amd64"
fi
STAT_CMD="stat -c%s"
else
# default to linux-amd64 for other platforms
BINARY="./dist/progzer-linux-amd64"
STAT_CMD="stat -c%s"
fi

# if exists local binary
Expand All @@ -64,8 +61,8 @@ echo ""
echo " creating a random 100MB test file..."
dd if=/dev/urandom of=test_file bs=1M count=100 >/dev/null 2>&1

# Get file size using the appropriate stat command
FILE_SIZE=$(${STAT_CMD} test_file)
# Get file size using the new --get-size flag
FILE_SIZE=$(${BINARY} --get-size test_file)
FILE_SUM=$(sha256sum test_file | cut -d ' ' -f1)

echo " file size (bytes): ${FILE_SIZE}"
Expand All @@ -78,7 +75,7 @@ echo ""
${BINARY} --size "${FILE_SIZE}" <test_file | gzip -n >test_file.gz
CHECK_SUM=$(
# shellcheck disable=SC2094
${BINARY} --size "$(${STAT_CMD} test_file.gz)" <test_file.gz |
${BINARY} --size "$(${BINARY} --get-size test_file.gz)" <test_file.gz |
gzip -dk |
sha256sum |
cut -d ' ' -f1
Expand Down
Loading