Skip to content

Commit 3a576e6

Browse files
committed
more bug fixes and verbose mode
1 parent 50a97c2 commit 3a576e6

File tree

6 files changed

+32
-22
lines changed

6 files changed

+32
-22
lines changed

MANUAL.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ DESCRIPTION
1212

1313
* This application recursively extracts compressed archives.
1414
* Provide directories to search or provide files to extract.
15-
* Supports ZIP, RAR, GZIP, BZIP2, TAR, TGZ, TBZ2, 7ZIP, ISO9660
16-
* ie. *.zip *.rar *.r00 *.gz *.bz2 *.tar *.tgz *.tbz2 *.7z *.iso
15+
* Supports: ZIP, RAR, GZIP, BZIP2, TAR, TGZ, TBZ2, 7ZIP, ISO9660
16+
* Supports: Z, AR, BR, CPIO, DEB, LZ/4, LZIP, LZMA2, S2, SNAPPY
17+
* Supports: RPM, SZ, TLZ, TXZ, ZLIB, ZSTD, BROTLI, ZZ
18+
* ie: *.zip *.rar *.r00 *.gz *.bz2 *.tar *.tgz *.tbz2 *.7z *.iso (and others)
1719

1820
OPTIONS
1921
---
@@ -58,6 +60,9 @@ OPTIONS
5860
This option determines if the archives will be extracted to their
5961
parent folder. Using this flag will override the --output option.
6062

63+
-V, --verbose
64+
Verbose logging prints the extracted file paths.
65+
6166
-D, --debug
6267
Enable debug output.
6368

@@ -83,6 +88,8 @@ Example TOML job file:
8388
min_depth = 1
8489
file_mode = 644
8590
dir_mode = 755
91+
verbose = false
92+
debug = false
8693
preserve_paths = false
8794

8895
AUTHOR

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ toolchain go1.24.2
77
require (
88
github.com/spf13/pflag v1.0.6
99
golift.io/version v0.0.2
10-
golift.io/xtractr v0.2.3-0.20250419070747-b391d40d7453
10+
golift.io/xtractr v0.2.3-0.20250419170021-53bfe05970fe
1111
)
1212

1313
require (

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,8 @@ golift.io/cnfgfile v0.0.0-20240713024420-a5436d84eb48 h1:c7cJWRr0cUnFHKtq072esKz
255255
golift.io/cnfgfile v0.0.0-20240713024420-a5436d84eb48/go.mod h1:zHm9o8SkZ6Mm5DfGahsrEJPsogyR0qItP59s5lJ98/I=
256256
golift.io/version v0.0.2 h1:i0gXRuSDHKs4O0sVDUg4+vNIuOxYoXhaxspftu2FRTE=
257257
golift.io/version v0.0.2/go.mod h1:76aHNz8/Pm7CbuxIsDi97jABL5Zui3f2uZxDm4vB6hU=
258-
golift.io/xtractr v0.2.3-0.20250419070747-b391d40d7453 h1:JnozjdGe8GNAgcLDxd6WjWxVpktsmqJzP2PMT+DulhE=
259-
golift.io/xtractr v0.2.3-0.20250419070747-b391d40d7453/go.mod h1:invEOYfyBnFtegY2V2n+9K5bUEHB8pGZng1BK0U2r38=
258+
golift.io/xtractr v0.2.3-0.20250419170021-53bfe05970fe h1:fCqAf/BYLNy5BdX6IeeGIGutHqOANjIfKeYANd5Cktg=
259+
golift.io/xtractr v0.2.3-0.20250419170021-53bfe05970fe/go.mod h1:invEOYfyBnFtegY2V2n+9K5bUEHB8pGZng1BK0U2r38=
260260
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
261261
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
262262
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=

main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ func parseFlags(pwd string) (*xt.Job, *flags) {
3232
flag.StringSliceVarP(&job.Passwords, "password", "P", nil, "Attempt these passwords for rar and 7zip archives.")
3333
flag.BoolVarP(&job.SquashRoot, "squash-root", "S", false,
3434
"If archive contains only 1 folder at in the root, its contents are moved into output folder.")
35+
flag.BoolVarP(&job.Verbose, "verbose", "V", false, "Verbose output prints the file list that was extracted.")
3536
flag.BoolVarP(&job.DebugLog, "debug", "D", false, "Enable debug output.")
3637
flag.StringSliceVarP(&flags.JobFiles, "job-file", "j", nil, "Read additional extraction jobs from these files.")
3738
flag.BoolVarP(&job.Preserve, "preserve-paths", "p", false, "Recreate directory hierarchy while extracting.")

pkg/xt/job.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ type Job struct {
2121
SquashRoot bool `json:"squashRoot" toml:"squash_root" xml:"squash_root" yaml:"squashRoot"`
2222
DebugLog bool `json:"debugLog" toml:"debug_log" xml:"debug_log" yaml:"debugLog"`
2323
Preserve bool `json:"preservePaths" toml:"preserve_paths" xml:"preserve_paths" yaml:"preservePaths"`
24+
Verbose bool `json:"verbose" toml:"verbose" xml:"verbose" yaml:"verbose"`
2425
}
2526

2627
// ParseJobs checks for and reads more jobs in from 0 or more job files.
@@ -48,8 +49,8 @@ func (j *Job) String() string {
4849
sSfx = "s"
4950
}
5051

51-
return fmt.Sprintf("%d path%s, f/d-mode:%s/%s, min/max-depth: %d/%d output: %s",
52-
len(j.Paths), sSfx, j.FileMode, j.DirMode, j.MinDepth, j.MaxDepth, j.Output)
52+
return fmt.Sprintf("%d path%s, f/d-mode:%s/%s, min/max-depth: %d/%d, preserve/squash: %v/%v output: %s",
53+
len(j.Paths), sSfx, j.FileMode, j.DirMode, j.MinDepth, j.MaxDepth, j.Preserve, j.SquashRoot, j.Output)
5354
}
5455

5556
// Debugf prints a log message if debug is enabled.

pkg/xt/xt.go

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,19 @@ func Extract(job *Job) {
2828
start := time.Now()
2929

3030
for folder, files := range archives {
31-
for _, archiveName := range files {
31+
for _, archive := range files {
3232
count++
33-
log.Printf("==> Extracting Archive (%d/%d): %s", count, total, archiveName)
33+
log.Printf("==> Extracting Archive (%d/%d): %s", count, total, archive)
3434

35-
fSize, files, duration, err := job.processArchive(folder, archiveName)
35+
output, fSize, files, duration, err := job.processArchive(folder, archive)
3636
if err != nil {
3737
log.Printf("[ERROR] Extracting: %v", err)
3838
} else {
39-
log.Printf("==> Extracted Archive %s in %v: bytes: %d, files: %d",
40-
archiveName, duration.Round(time.Millisecond), fSize, len(files))
39+
log.Printf("==> Extracted Archive %s to %s in %v: bytes: %d, files: %d",
40+
archive, output, duration.Round(time.Millisecond), fSize, len(files))
4141
}
4242

43-
if len(files) > 0 {
43+
if len(files) > 0 && job.Verbose {
4444
log.Printf("==> Files:\n - %s", strings.Join(files, "\n - "))
4545
}
4646

@@ -49,13 +49,13 @@ func Extract(job *Job) {
4949
}
5050
}
5151

52-
log.Printf("==> Done.\n==> Extracted %d archives; wrote %d files totalling %d bytes in %v",
53-
total, fCount, size, time.Since(start).Round(time.Millisecond))
52+
log.Printf("==> Done.\n==> Extracted %d archives; wrote %d bytes into %d files in %v",
53+
total, size, fCount, time.Since(start).Round(time.Millisecond))
5454
}
5555

56-
func (j *Job) processArchive(folder, archiveName string) (int64, []string, time.Duration, error) {
56+
func (j *Job) processArchive(folder, archive string) (string, int64, []string, time.Duration, error) {
5757
file := &xtractr.XFile{
58-
FilePath: archiveName, // Path to archive being extracted.
58+
FilePath: archive, // Path to archive being extracted.
5959
OutputDir: j.Output, // Folder to extract archive into.
6060
FileMode: j.FileMode.Mode(), // Write files with this mode.
6161
DirMode: j.DirMode.Mode(), // Write folders with this mode.
@@ -69,17 +69,17 @@ func (j *Job) processArchive(folder, archiveName string) (int64, []string, time.
6969
// Remove input path prefix from fileName,
7070
// append fileName.Dir to job.Output,
7171
// extract file into job.Output/file(sub)Folder(s).
72-
file.OutputDir = filepath.Join(j.Output, filepath.Dir(strings.TrimPrefix(folder, archiveName)))
72+
file.OutputDir = filepath.Join(j.Output, filepath.Dir(strings.TrimPrefix(archive, folder)))
7373
}
7474

7575
start := time.Now()
7676

7777
size, files, _, err := xtractr.ExtractFile(file)
7878
if err != nil {
79-
return size, files, time.Since(start), fmt.Errorf("archive: %s: %w", archiveName, err)
79+
err = fmt.Errorf("archive: %s: %w", archive, err)
8080
}
8181

82-
return size, files, time.Since(start), nil
82+
return file.OutputDir, size, files, time.Since(start), err
8383
}
8484

8585
func (j *Job) getArchives() xtractr.ArchiveList {
@@ -102,13 +102,14 @@ func (j *Job) getArchives() xtractr.ArchiveList {
102102
exclude = xtractr.AllExcept(j.Include...)
103103
}
104104

105-
for folder, fileList := range xtractr.FindCompressedFiles(xtractr.Filter{
105+
for _, fileList := range xtractr.FindCompressedFiles(xtractr.Filter{
106106
Path: fileName,
107107
ExcludeSuffix: exclude,
108108
MaxDepth: int(j.MaxDepth),
109109
MinDepth: int(j.MinDepth),
110110
}) {
111-
archives[folder] = fileList
111+
// Group archive lists by the parent search folder that found them.
112+
archives[fileName] = append(archives[fileName], fileList...)
112113
}
113114
}
114115

0 commit comments

Comments
 (0)