@@ -112,8 +112,13 @@ type XFile struct {
112112 Password string
113113 // (RAR/7z) Archive passwords (to try multiple).
114114 Passwords []string
115+ // If the archive only has one directory in the root, then setting
116+ // this true will cause the extracted content to be moved into the
117+ // output folder, and the root folder in the archive to be removed.
118+ SquashRoot bool
115119 // Logger allows printing debug messages.
116- log Logger
120+ log Logger
121+ moveFiles func (fromPath , toPath string , overwrite bool ) ([]string , error )
117122}
118123
119124// Filter is the input to find compressed files.
@@ -313,6 +318,8 @@ func (x *XFile) Extract() (size int64, filesList, archiveList []string, err erro
313318// Returns size of extracted data, list of extracted files, list of archives processed, and/or error.
314319func ExtractFile (xFile * XFile ) (size int64 , filesList , archiveList []string , err error ) {
315320 sName := strings .ToLower (xFile .FilePath )
321+ // just borrowing this... Has to go into an interface to avoid a cycle.
322+ xFile .moveFiles = parseConfig (& Config {Logger : xFile .log }).MoveFiles
316323
317324 for _ , ext := range extension2function {
318325 if strings .HasSuffix (sName , ext .Extension ) {
@@ -541,6 +548,38 @@ func (x *XFile) SetLogger(logger Logger) {
541548 x .log = logger
542549}
543550
551+ // cleanup runs after a successful extract.
552+ // The intent it to move files into their final location.
553+ func (x * XFile ) cleanup (files []string ) ([]string , error ) {
554+ files , err := x .squashRoot (files )
555+ if err != nil {
556+ return files , err
557+ }
558+
559+ return files , nil
560+ }
561+
562+ func (x * XFile ) squashRoot (files []string ) ([]string , error ) {
563+ if ! x .SquashRoot {
564+ return files , nil
565+ }
566+
567+ roots := map [string ]bool {}
568+ //nolint:mnd
569+ for _ , path := range files {
570+ // Remove the output dir suffix, then split on `/` (or `\`) and get the first item.
571+ roots [strings .SplitN (strings .TrimPrefix (path , x .OutputDir ), string (filepath .Separator ), 2 )[0 ]] = true
572+ }
573+
574+ if len (roots ) == 1 { // only 1 root folder...
575+ for root := range roots { // ...move it's content up a level.
576+ return x .moveFiles (filepath .Join (x .OutputDir , root ), x .OutputDir , false )
577+ }
578+ }
579+
580+ return files , nil
581+ }
582+
544583func (x * XFile ) safeDirMode (current os.FileMode ) os.FileMode {
545584 if current .Perm () == 0 {
546585 return x .DirMode
0 commit comments