@@ -21,7 +21,7 @@ import (
2121)
2222
2323const (
24- Version = "2 .0.1"
24+ Version = "0 .0.1"
2525 MaxConcurrency = 4
2626 BufferSize = 64 * 1024 // 64KB buffer for file operations
2727)
@@ -156,7 +156,7 @@ func (e *Extractor) cyan(text string) string { return e.logger.cyan(text) }
156156func (e * Extractor ) yellow (text string ) string { return e .logger .yellow (text ) }
157157func (e * Extractor ) blue (text string ) string { return e .logger .blue (text ) }
158158
159- // ValidateInputs performs comprehensive input validation with better error handling
159+ // Input validation
160160func (e * Extractor ) ValidateInputs () error {
161161 if e .config .InputFile == "" {
162162 return fmt .Errorf ("input file is required" )
@@ -188,7 +188,7 @@ func (e *Extractor) ValidateInputs() error {
188188 return fmt .Errorf ("input file is empty: %s" , e .config .InputFile )
189189 }
190190
191- // Handle output directory with better validation
191+ // Handle output directory
192192 if e .config .OutputDir == "" {
193193 e .config .OutputDir = "."
194194 }
@@ -224,7 +224,7 @@ func (e *Extractor) ValidateInputs() error {
224224 return nil
225225}
226226
227- // isDirEmpty checks if a directory is empty with better error handling
227+ // isDirEmpty checks if a directory is empty
228228func (e * Extractor ) isDirEmpty (dir string ) (bool , error ) {
229229 f , err := os .Open (dir )
230230 if err != nil {
@@ -272,7 +272,7 @@ func (e *Extractor) DetectAndValidateArchive(ctx context.Context) (archives.Form
272272 return format , nil
273273}
274274
275- // ExtractArchive performs extraction with improved error handling and progress tracking
275+ // ExtractArchive performs extraction with progress tracking
276276func (e * Extractor ) ExtractArchive (ctx context.Context , format archives.Format ) error {
277277 if err := os .MkdirAll (e .config .OutputDir , 0755 ); err != nil {
278278 return fmt .Errorf ("failed to create output directory: %w" , err )
@@ -831,19 +831,18 @@ func main() {
831831 Name : "extraxtor" ,
832832 Usage : "Archive Extractor with Intelligent Directory Flattening" ,
833833 Version : Version ,
834- Authors : []any {"Rewritten in Go" },
835834 Flags : []cli.Flag {
836835 & cli.StringFlag {Name : "input" , Aliases : []string {"i" }, Usage : "Input archive file" },
837836 & cli.StringFlag {Name : "output" , Aliases : []string {"o" }, Usage : "Output directory (default: current directory)" },
838837 & cli.BoolFlag {Name : "force" , Aliases : []string {"f" }, Usage : "Force extraction, overwrite existing files" },
839838 & cli.BoolFlag {Name : "quiet" , Aliases : []string {"q" }, Usage : "Suppress all output except errors" },
840- & cli.BoolFlag {Name : "debug" , Aliases : []string {"d" }, Usage : "Enable debug output" }, // Changed from verbose to debug
839+ & cli.BoolFlag {Name : "debug" , Aliases : []string {"d" }, Usage : "Enable debug output" },
841840 & cli.BoolFlag {Name : "no-flatten" , Aliases : []string {"n" }, Usage : "Don't flatten nested single directories" },
842841 & cli.BoolFlag {Name : "tree" , Aliases : []string {"t" }, Usage : "Show tree output after extraction" },
843842 },
844843 Action : func (ctx context.Context , c * cli.Command ) error {
845844 config := & Config {
846- Verbose : c .Bool ("debug" ), // Use debug instead of verbose
845+ Verbose : c .Bool ("debug" ),
847846 Quiet : c .Bool ("quiet" ),
848847 Force : c .Bool ("force" ),
849848 Flatten : ! c .Bool ("no-flatten" ),
@@ -912,6 +911,41 @@ func inspectArchive(ctx context.Context, archivePath string, jsonOutput, treeOut
912911 return fmt .Errorf ("unsupported archive format for inspection" )
913912 }
914913
914+ if err := func () error {
915+ defer func () {
916+ if r := recover (); r != nil {
917+ // Silently ignore archives that don't support listing
918+ }
919+ }()
920+
921+ // Test if we can actually list the archive
922+ testHandler := func (ctx context.Context , f archives.FileInfo ) error {
923+ return nil
924+ }
925+
926+ return extractor .Extract (ctx , input , testHandler )
927+ }(); err != nil {
928+ if treeOutput {
929+ fmt .Printf ("Tree view not supported for this archive format\n " )
930+ return nil
931+ }
932+ return fmt .Errorf ("archive format does not support content listing: %w" , err )
933+ }
934+
935+ // Reset file pointer for actual processing
936+ file .Close ()
937+ file , err = os .Open (archivePath )
938+ if err != nil {
939+ return fmt .Errorf ("failed to reopen archive: %w" , err )
940+ }
941+ defer file .Close ()
942+
943+ format , input , err = archives .Identify (ctx , archivePath , file )
944+ if err != nil {
945+ return fmt .Errorf ("failed to re-identify archive format: %w" , err )
946+ }
947+ extractor = format .(archives.Extractor )
948+
915949 var entries []FileEntry
916950 var totalSize int64
917951 var fileCount , dirCount int
@@ -958,13 +992,75 @@ func inspectArchive(ctx context.Context, archivePath string, jsonOutput, treeOut
958992 })
959993 }
960994
961- if treeOutput {
962- for _ , entry := range entries {
963- prefix := map [bool ]string {true : "📁 " , false : "📄 " }[entry .IsDir ]
964- fmt .Printf ("%s%s\n " , prefix , entry .Name )
965- }
966- return nil
967- }
995+ if treeOutput {
996+ fmt .Printf ("Archive: %s\n " , filepath .Base (archivePath ))
997+
998+ // Build tree structure
999+ tree := make (map [string ][]string )
1000+ dirs := make (map [string ]bool )
1001+
1002+ for _ , entry := range entries {
1003+ parts := strings .Split (entry .Name , string (filepath .Separator ))
1004+ for i := 0 ; i < len (parts ); i ++ {
1005+ path := strings .Join (parts [:i + 1 ], string (filepath .Separator ))
1006+ parent := ""
1007+ if i > 0 {
1008+ parent = strings .Join (parts [:i ], string (filepath .Separator ))
1009+ }
1010+
1011+ if entry .IsDir || i < len (parts )- 1 {
1012+ dirs [path ] = true
1013+ }
1014+
1015+ if parent != "" {
1016+ tree [parent ] = append (tree [parent ], parts [i ])
1017+ } else if i == 0 {
1018+ tree ["" ] = append (tree ["" ], parts [i ])
1019+ }
1020+ }
1021+ }
1022+
1023+ // Remove duplicates and sort
1024+ for k := range tree {
1025+ unique := make (map [string ]bool )
1026+ for _ , v := range tree [k ] {
1027+ unique [v ] = true
1028+ }
1029+ tree [k ] = make ([]string , 0 , len (unique ))
1030+ for v := range unique {
1031+ tree [k ] = append (tree [k ], v )
1032+ }
1033+ sort .Strings (tree [k ])
1034+ }
1035+
1036+ // Print tree
1037+ var printTree func (path string , depth int )
1038+ printTree = func (path string , depth int ) {
1039+ children := tree [path ]
1040+ for i , child := range children {
1041+ indent := strings .Repeat (" " , depth )
1042+ connector := "├── "
1043+ if i == len (children )- 1 {
1044+ connector = "└── "
1045+ }
1046+
1047+ childPath := child
1048+ if path != "" {
1049+ childPath = path + string (filepath .Separator ) + child
1050+ }
1051+
1052+ if dirs [childPath ] {
1053+ fmt .Printf ("%s%s📁 %s/\n " , indent , connector , child )
1054+ printTree (childPath , depth + 1 )
1055+ } else {
1056+ fmt .Printf ("%s%s📄 %s\n " , indent , connector , child )
1057+ }
1058+ }
1059+ }
1060+
1061+ printTree ("" , 0 )
1062+ return nil
1063+ }
9681064
9691065 if verbose {
9701066 fmt .Printf ("Archive: %s (%d files, %d directories, %s total)\n \n " ,
0 commit comments