Skip to content

Commit e6aeee0

Browse files
committed
chore: update docs
1 parent b6d5ebb commit e6aeee0

4 files changed

Lines changed: 393 additions & 0 deletions

File tree

exec/doc.go

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// Package exec provides simplified command execution utilities for running
2+
// shell commands with enhanced error handling and output management.
3+
//
4+
// The package wraps Go's os/exec with convenience functions that handle
5+
// common patterns like forwarding output to console, capturing combined
6+
// output, and ignoring errors for optional operations.
7+
//
8+
// Key Features:
9+
// - Execute commands with automatic stdout/stderr forwarding
10+
// - Safe execution that never panics on errors
11+
// - Environment variable support
12+
// - Printf-style argument formatting
13+
// - Combined output capture
14+
//
15+
// Basic Execution:
16+
//
17+
// // Execute a command and forward output to console
18+
// err := exec.Exec("ls -la")
19+
//
20+
// // Execute with formatted arguments
21+
// err := exec.Execf("echo 'Hello %s'", "World")
22+
//
23+
// // Execute with custom environment variables
24+
// env := map[string]string{
25+
// "DEBUG": "true",
26+
// "CONFIG_PATH": "/etc/app",
27+
// }
28+
// err := exec.ExecfWithEnv("./script.sh", env)
29+
//
30+
// Safe Execution:
31+
//
32+
// SafeExec executes commands and returns success status instead of errors,
33+
// useful for optional operations or when you want to continue on failure:
34+
//
35+
// // Try to get git branch, continue if git isn't available
36+
// branch, ok := exec.SafeExec("git rev-parse --abbrev-ref HEAD")
37+
// if ok {
38+
// fmt.Printf("Current branch: %s\n", branch)
39+
// }
40+
//
41+
// // Check if a command exists
42+
// _, exists := exec.SafeExec("which docker")
43+
// if exists {
44+
// // Docker is installed
45+
// }
46+
//
47+
// Output Handling:
48+
//
49+
// // Exec forwards both stdout and stderr to console
50+
// err := exec.Exec("make build")
51+
// // User sees all output in real-time
52+
//
53+
// // SafeExec captures output and returns it
54+
// output, ok := exec.SafeExec("cat /etc/hostname")
55+
// if ok {
56+
// fmt.Println("Hostname:", output)
57+
// }
58+
//
59+
// Environment Variables:
60+
//
61+
// // Set environment for command execution
62+
// env := map[string]string{
63+
// "PATH": "/usr/local/bin:/usr/bin",
64+
// "DATABASE_URL": "postgres://localhost/mydb",
65+
// }
66+
// err := exec.ExecfWithEnv("migrate up", env)
67+
//
68+
// Error Handling:
69+
//
70+
// // Exec returns error with command output on failure
71+
// if err := exec.Exec("./deploy.sh"); err != nil {
72+
// // err contains both error and stderr output
73+
// log.Fatal(err)
74+
// }
75+
//
76+
// // SafeExec returns false on any error
77+
// output, ok := exec.SafeExec("risky-command")
78+
// if !ok {
79+
// // Command failed, output is empty string
80+
// log.Warn("Command failed, using default")
81+
// }
82+
//
83+
// Formatted Commands:
84+
//
85+
// // Use printf-style formatting for dynamic commands
86+
// filename := "data.json"
87+
// err := exec.Execf("cat %s | jq .", filename)
88+
//
89+
// // Multiple arguments
90+
// src := "/source"
91+
// dst := "/dest"
92+
// err := exec.Execf("rsync -av %s %s", src, dst)
93+
//
94+
// Common Use Cases:
95+
//
96+
// // Run build commands
97+
// exec.Exec("go build -o app ./cmd/server")
98+
//
99+
// // Check tool availability
100+
// if _, ok := exec.SafeExec("which kubectl"); !ok {
101+
// log.Fatal("kubectl not found in PATH")
102+
// }
103+
//
104+
// // Get version information
105+
// version, ok := exec.SafeExec("app --version")
106+
//
107+
// // Run tests with environment
108+
// env := map[string]string{"TEST_ENV": "integration"}
109+
// exec.ExecfWithEnv("go test ./...", env)
110+
//
111+
// Note: All commands are executed through bash -c, providing full shell
112+
// functionality including pipes, redirects, and variable expansion.
113+
package exec

files/doc.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Package files provides utilities for file operations, archive handling,
2+
// and path manipulation.
3+
//
4+
// The package offers comprehensive support for working with various archive
5+
// formats (tar, zip, gzip, xz), file path validation, glob pattern matching,
6+
// and common file operations.
7+
//
8+
// Key Features:
9+
// - Archive extraction with detailed results and statistics
10+
// - Support for tar, tar.gz, tar.xz, and zip formats
11+
// - Path traversal vulnerability protection
12+
// - Glob pattern matching with doublestar support
13+
// - File compression and decompression
14+
// - Safe file operations with validation
15+
//
16+
// Archive Extraction:
17+
//
18+
// // Simple extraction
19+
// err := files.UnarchiveSimple("package.tar.gz", "/dest")
20+
//
21+
// // Extraction with detailed results
22+
// result, err := files.Unarchive("package.tar.gz", "/dest")
23+
// fmt.Printf("Extracted %d files (%s)\n", len(result.Files), result.String())
24+
//
25+
// // Extraction with options
26+
// result, err := files.Unarchive("archive.zip", "/dest",
27+
// files.WithOverwrite(true))
28+
//
29+
// // Extract only executables
30+
// err := files.UnarchiveExecutables("binaries.tar.gz", "/usr/local/bin")
31+
//
32+
// Compression:
33+
//
34+
// // Gzip a file
35+
// data, err := files.GzipFile("document.txt")
36+
//
37+
// // Create a zip archive
38+
// err := files.Zip("/source/dir", "archive.zip")
39+
//
40+
// // Decompress xz
41+
// err := files.Unxz("file.xz", "file.txt")
42+
//
43+
// // Decompress gzip
44+
// err := files.Ungzip("file.gz", "file.txt")
45+
//
46+
// Path Operations:
47+
//
48+
// // Validate path (check for traversal attacks)
49+
// err := files.ValidatePath("../../etc/passwd") // Returns error
50+
//
51+
// // Check file type by extension
52+
// if files.IsValidPathType("config.yaml", ".yaml", ".yml") {
53+
// // Process YAML file
54+
// }
55+
//
56+
// // Get base name without extension
57+
// name := files.GetBaseName("config.yaml") // "config"
58+
//
59+
// Glob Matching:
60+
//
61+
// // Expand glob patterns
62+
// matches, err := files.UnfoldGlobs("**/*.go", "**/*.yaml")
63+
//
64+
// // Match with doublestar patterns
65+
// files, err := files.DoubleStarGlob("/project", []string{"**/*.go"})
66+
//
67+
// File Operations:
68+
//
69+
// // Check if file exists
70+
// if files.Exists("/path/to/file") {
71+
// // File exists
72+
// }
73+
//
74+
// // Safe read (returns empty string on error)
75+
// content := files.SafeRead("/path/to/file")
76+
//
77+
// // Copy file
78+
// err := files.Copy("/source/file", "/dest/file")
79+
//
80+
// // Copy from reader with permissions
81+
// n, err := files.CopyFromReader(reader, "/dest/file", 0644)
82+
//
83+
// // Create temp file with custom name
84+
// tmpFile := files.TempFileName("prefix-", ".txt")
85+
//
86+
// Archive Results:
87+
//
88+
// The Archive type provides detailed information about extraction operations:
89+
//
90+
// result, _ := files.Unarchive("package.tar.gz", "/dest")
91+
// fmt.Printf("Files: %d\n", len(result.Files))
92+
// fmt.Printf("Directories: %d\n", len(result.Directories))
93+
// fmt.Printf("Symlinks: %d\n", len(result.Symlinks))
94+
// fmt.Printf("Size: %s -> %s (%.1f%% compression)\n",
95+
// formatSize(result.CompressedSize),
96+
// formatSize(result.ExtractedSize),
97+
// result.CompressionRatio*100)
98+
//
99+
// Security:
100+
//
101+
// The package includes protection against path traversal vulnerabilities
102+
// when extracting archives. All paths are validated to ensure they don't
103+
// escape the destination directory.
104+
package files

is/doc.go

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Package is provides simple type checking and environment detection utilities.
2+
//
3+
// The package offers concise boolean functions for common type checks and
4+
// runtime environment detection. All functions follow the pattern is.X()
5+
// for readable, natural-language code.
6+
//
7+
// Key Features:
8+
// - Type checking with reflection
9+
// - File and archive detection
10+
// - Terminal/TTY detection
11+
// - Simple, readable API
12+
//
13+
// Type Checking:
14+
//
15+
// // Check if value is a slice
16+
// data := []string{"a", "b", "c"}
17+
// if is.Slice(data) {
18+
// // data is a slice
19+
// }
20+
//
21+
// // Works with any type
22+
// numbers := []int{1, 2, 3}
23+
// is.Slice(numbers) // true
24+
//
25+
// str := "hello"
26+
// is.Slice(str) // false
27+
//
28+
// File Detection:
29+
//
30+
// // Check if file exists
31+
// if is.File("/etc/hosts") {
32+
// // File exists
33+
// }
34+
//
35+
// // Check if file is an archive
36+
// if is.Archive("package.tar.gz") {
37+
// // Extract the archive
38+
// }
39+
//
40+
// // Supported archive formats
41+
// is.Archive("file.zip") // true
42+
// is.Archive("file.tar.gz") // true
43+
// is.Archive("file.gz") // true
44+
// is.Archive("file.xz") // true
45+
// is.Archive("file.txz") // true
46+
// is.Archive("file.txt") // false
47+
//
48+
// Terminal Detection:
49+
//
50+
// // Check if running in an interactive terminal
51+
// if is.TTY() {
52+
// // Enable colored output, progress bars, etc.
53+
// fmt.Println("\033[32mGreen text\033[0m")
54+
// } else {
55+
// // Plain output for logs, pipes, redirects
56+
// fmt.Println("Plain text")
57+
// }
58+
//
59+
// Common Use Cases:
60+
//
61+
// // Conditional output formatting
62+
// if is.TTY() {
63+
// showProgressBar()
64+
// } else {
65+
// logToFile()
66+
// }
67+
//
68+
// // File processing
69+
// if is.File(configPath) {
70+
// loadConfig(configPath)
71+
// }
72+
//
73+
// // Archive handling
74+
// if is.Archive(input) {
75+
// extractArchive(input)
76+
// } else {
77+
// processFile(input)
78+
// }
79+
//
80+
// // Generic type checking
81+
// if is.Slice(value) {
82+
// processSlice(value)
83+
// }
84+
//
85+
// Limitations:
86+
//
87+
// The Slice function uses reflection and only checks if a value is a slice type.
88+
// It doesn't validate slice element types or other slice properties.
89+
//
90+
// The Archive function only checks file extensions, not actual file content.
91+
// For robust archive detection, consider inspecting file headers/magic numbers.
92+
package is

text/doc.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// Package text provides utilities for text processing, formatting, and
2+
// manipulation.
3+
//
4+
// The package includes functions for humanizing numbers and durations,
5+
// indenting text, parsing extended duration formats, and safe I/O operations.
6+
//
7+
// Key Features:
8+
// - Human-readable formatting for bytes, numbers, and durations
9+
// - Text indentation for hierarchical output
10+
// - Extended duration parsing (days, weeks, years)
11+
// - Safe I/O operations that never panic
12+
//
13+
// Byte and Number Formatting:
14+
//
15+
// // Format bytes in human-readable form
16+
// text.HumanizeBytes(1536) // "1.5 KB"
17+
// text.HumanizeBytes(1048576) // "1.0 MB"
18+
// text.HumanizeBytes(5368709120) // "5.0 GB"
19+
//
20+
// // Format large numbers with thousand separators
21+
// text.HumanizeInt(1000000) // "1,000,000"
22+
// text.HumanizeInt(42) // "42"
23+
//
24+
// Duration Formatting:
25+
//
26+
// // Format durations in human-readable form
27+
// text.HumanizeDuration(90 * time.Minute) // "1h30m"
28+
// text.HumanizeDuration(25 * time.Hour) // "1d1h"
29+
// text.HumanizeDuration(8 * 24 * time.Hour) // "1w1d"
30+
//
31+
// // Calculate age since a time
32+
// created := time.Now().Add(-48 * time.Hour)
33+
// text.Age(created) // "2d"
34+
//
35+
// Duration Parsing:
36+
//
37+
// Parse durations with extended units beyond the standard Go time.Duration:
38+
//
39+
// d, err := text.ParseDuration("3d") // 72 hours
40+
// d, err := text.ParseDuration("1w") // 168 hours
41+
// d, err := text.ParseDuration("2y") // ~17520 hours
42+
// d, err := text.ParseDuration("1d12h30m") // 36.5 hours
43+
//
44+
// Supported units: ns, us/µs, ms, s, m, h, d (days), w (weeks), y (years)
45+
//
46+
// Text Indentation:
47+
//
48+
// // Indent a string
49+
// indented := text.String(" ", "line1\nline2\nline3")
50+
// // " line1\n line2\n line3"
51+
//
52+
// // Indent bytes
53+
// data := []byte("line1\nline2")
54+
// indented := text.Bytes(" ", data)
55+
//
56+
// // Create an indenting writer
57+
// writer := text.NewWriter(os.Stdout, " ")
58+
// fmt.Fprintln(writer, "This will be indented")
59+
// fmt.Fprintln(writer, "So will this")
60+
//
61+
// Safe I/O:
62+
//
63+
// // Read from reader without error handling
64+
// resp, _ := http.Get("https://example.com")
65+
// defer resp.Body.Close()
66+
// content := text.SafeRead(resp.Body) // Empty string on error
67+
//
68+
// Formatting Examples:
69+
//
70+
// // Display file sizes
71+
// fmt.Printf("Size: %s\n", text.HumanizeBytes(fileSize))
72+
//
73+
// // Display request counts
74+
// fmt.Printf("Requests: %s\n", text.HumanizeInt(requestCount))
75+
//
76+
// // Display uptime
77+
// fmt.Printf("Uptime: %s\n", text.HumanizeDuration(time.Since(startTime)))
78+
//
79+
// // Display last updated
80+
// fmt.Printf("Updated: %s ago\n", text.Age(lastModified))
81+
//
82+
// Related Packages:
83+
// - duration: Extended duration parsing (used internally)
84+
package text

0 commit comments

Comments
 (0)