Archiver.st
author Claus Gittinger <cg@exept.de>
Wed, 29 Jul 2009 20:02:02 +0200
changeset 2570 4e663bc64364
parent 1599 629a6e0ae68a
permissions -rw-r--r--
changed #requestPackage
     1 "{ Package: 'stx:libtool2' }"
     2 
     3 Object subclass:#Archiver
     4 	instanceVariableNames:'process temporaryDirectory fileName outStream errorStream
     5 		synchron'
     6 	classVariableNames:''
     7 	poolDictionaries:''
     8 	category:'System-Support-FileFormats'
     9 !
    10 
    11 Archiver subclass:#GZipArchive
    12 	instanceVariableNames:''
    13 	classVariableNames:''
    14 	poolDictionaries:''
    15 	privateIn:Archiver
    16 !
    17 
    18 Archiver subclass:#TarArchive
    19 	instanceVariableNames:'fileName'
    20 	classVariableNames:''
    21 	poolDictionaries:''
    22 	privateIn:Archiver
    23 !
    24 
    25 Archiver subclass:#TarGZipArchive
    26 	instanceVariableNames:'tarArchiver tarFile'
    27 	classVariableNames:''
    28 	poolDictionaries:''
    29 	privateIn:Archiver
    30 !
    31 
    32 
    33 !Archiver class methodsFor:'instance creation'!
    34 
    35 with:aFilename
    36 
    37     | instance |
    38 
    39     instance := self new.
    40     instance fileName:aFilename.
    41     ^ instance
    42 ! !
    43 
    44 !Archiver class methodsFor:'classAccess'!
    45 
    46 gzipArchive
    47 
    48     ^ GZipArchive
    49 !
    50 
    51 tarArchive
    52 
    53     ^ TarArchive
    54 !
    55 
    56 tarGZipArchive
    57 
    58     ^ TarGZipArchive
    59 ! !
    60 
    61 !Archiver class methodsFor:'common options'!
    62 
    63 MinusSign
    64 
    65     ^ $-
    66 !
    67 
    68 PipeSign
    69 
    70     ^ $>
    71 ! !
    72 
    73 !Archiver methodsFor:'accessing'!
    74 
    75 errorStream
    76     "return the value of the instance variable 'errorStream' (automatically generated)"
    77 
    78     ^ errorStream
    79 !
    80 
    81 errorStream:something
    82     "set the value of the instance variable 'errorStream' (automatically generated)"
    83 
    84     errorStream := something.
    85 !
    86 
    87 fileName
    88     "return the value of the instance variable 'fileName' (automatically generated)"
    89 
    90     ^ fileName
    91 !
    92 
    93 fileName:something
    94     "set the value of the instance variable 'fileName' (automatically generated)"
    95 
    96     fileName := something.
    97 !
    98 
    99 outStream
   100     "return the value of the instance variable 'outStream' (automatically generated)"
   101 
   102     ^ outStream
   103 !
   104 
   105 outStream:something
   106     "set the value of the instance variable 'outStream' (automatically generated)"
   107 
   108     outStream := something.
   109 !
   110 
   111 process
   112     "return the value of the instance variable 'process' (automatically generated)"
   113 
   114     ^ process
   115 !
   116 
   117 process:something
   118     "set the value of the instance variable 'process' (automatically generated)"
   119 
   120     process := something.
   121 !
   122 
   123 synchron
   124     "return the value of the instance variable 'synchron' (automatically generated)"
   125 
   126     ^ synchron
   127 !
   128 
   129 synchron:something
   130     "set the value of the instance variable 'synchron' (automatically generated)"
   131 
   132     synchron := something.
   133 !
   134 
   135 temporaryDirectory
   136     "return the value of the instance variable 'temporaryDirectory' (automatically generated)"
   137 
   138     temporaryDirectory isNil ifTrue:[
   139         temporaryDirectory := Filename newTemporary.
   140         temporaryDirectory makeDirectory.
   141     ].
   142     ^ temporaryDirectory
   143 ! !
   144 
   145 !Archiver methodsFor:'actions'!
   146 
   147 addFilesToArchiv:colOfFiles
   148 
   149     self subclassResponsibility.
   150 !
   151 
   152 extractTo:aColOfFiles
   153 
   154     self subclassResponsibility.
   155 !
   156 
   157 listFilesFromArchiv
   158 
   159     self subclassResponsibility.
   160 !
   161 
   162 removeFilesFromArchiv:aColOfFiles
   163 
   164     self subclassResponsibility.
   165 ! !
   166 
   167 !Archiver methodsFor:'actions private'!
   168 
   169 removeTemporaryDirectory
   170 
   171     | tmp |
   172 
   173     temporaryDirectory notNil ifTrue:[
   174         tmp := self temporaryDirectory.
   175         (FileDirectory directoryNamed:(tmp directory)) removeDirectory:tmp baseName.
   176         temporaryDirectory := nil.
   177     ].
   178 !
   179 
   180 stopProcess
   181 
   182     process notNil ifTrue:[
   183         process terminateWithAllSubprocesses.
   184         process waitUntilTerminated.
   185     ].
   186 ! !
   187 
   188 !Archiver methodsFor:'command execution'!
   189 
   190 executeCommand:cmd directory:aDirectory
   191 
   192 
   193     synchron isNil ifTrue:[synchron := true].
   194     synchron ifTrue:[
   195          OperatingSystem 
   196             executeCommand:cmd
   197             inputFrom:nil
   198             outputTo:outStream
   199             errorTo:errorStream
   200             inDirectory:aDirectory
   201             lineWise:true
   202             onError:[:status| false].
   203     ] ifFalse:[
   204         process := Process for:[
   205                 [ 
   206                      OperatingSystem 
   207                         executeCommand:cmd
   208                         inputFrom:nil
   209                         outputTo:outStream
   210                         errorTo:errorStream
   211                         inDirectory:aDirectory
   212                         lineWise:true
   213                         onError:[:status| false].
   214                 ] 
   215                 valueNowOrOnUnwindDo:[
   216                     process := nil.
   217                 ].
   218 
   219         ] priority:(Processor systemBackgroundPriority).
   220         process name:('ArchivFileCommand command >', cmd).
   221         process resume.
   222     ]
   223 !
   224 
   225 outStream:aOutStream errorStream:aErrorStream
   226 
   227     outStream := aOutStream.
   228     errorStream := aErrorStream.
   229 !
   230 
   231 outStream:aOutStream errorStream:aErrorStream synchron:aBoolean
   232 
   233     outStream := aOutStream.
   234     errorStream := aErrorStream.
   235     synchron := aBoolean
   236 ! !
   237 
   238 !Archiver methodsFor:'initialization & release'!
   239 
   240 release
   241 
   242     self stopProcess.
   243     self removeTemporaryDirectory.
   244 ! !
   245 
   246 !Archiver::GZipArchive class methodsFor:'zip archiv command options'!
   247 
   248 GZipArchivFileOption
   249     ^ 'f'
   250 !
   251 
   252 GZipArchivUnzipCommand
   253     ^ 'gunzip'
   254 !
   255 
   256 GZipArchivWriteToStdioOption
   257     ^ 'c'
   258 !
   259 
   260 GZipArchivZipCommand
   261     ^ 'gzip'
   262 ! !
   263 
   264 !Archiver::GZipArchive methodsFor:'actions'!
   265 
   266 unzipTo:aDirectory
   267 
   268     | cmd file newFile|
   269 
   270     (aDirectory exists not) ifTrue:[
   271         DialogBox warn:'cant unzip to not existing directory ', aDirectory asString.
   272     ].
   273     (aDirectory isDirectory not) ifTrue:[
   274         DialogBox warn:'cant unzip to file ', aDirectory asString.
   275     ].
   276     file := self fileName.
   277     (file directory asString = aDirectory asString) ifFalse:[
   278         file copyTo:(aDirectory construct:(file baseName)).
   279     ].
   280     newFile := aDirectory construct:(file baseName).
   281     cmd := self getUnzipCommandForFile:newFile.
   282     self executeCommand:cmd directory:aDirectory. 
   283 !
   284 
   285 zipFile:aFile to:newFile
   286 
   287     | cmd directory|
   288 
   289     directory := newFile directory.
   290     (directory exists not) ifTrue:[
   291         DialogBox warn:'cant unzip to not existing directory ', directory asString.
   292     ].
   293     (directory isDirectory not) ifTrue:[
   294         DialogBox warn:'cant unzip to file ', directory asString.
   295     ].
   296     cmd := self getZipCommandForFile:aFile to:newFile.
   297     self executeCommand:cmd directory:directory.
   298     newFile exists ifTrue:[
   299         self fileName:newFile.
   300     ].
   301 ! !
   302 
   303 !Archiver::GZipArchive methodsFor:'command strings'!
   304 
   305 getUnzipCommand
   306 
   307     | stream cmd|
   308 
   309     stream := WriteStream on:''.
   310     stream nextPutAll:self class GZipArchivUnzipCommand.
   311     stream space.
   312     stream nextPutAll:self fileName baseName.
   313     cmd := stream contents.
   314     stream close.
   315     ^ cmd
   316 !
   317 
   318 getUnzipCommandForFile:aFileName
   319 
   320     | stream cmd|
   321 
   322     stream := WriteStream on:''.
   323     stream nextPutAll:self class GZipArchivUnzipCommand.
   324     stream space.
   325     stream nextPutAll:aFileName asString.
   326     cmd := stream contents.
   327     stream close.
   328     ^ cmd
   329 !
   330 
   331 getZipCommandForFile:aFileName
   332 
   333     | stream cmd|
   334 
   335     stream := WriteStream on:''.
   336     stream nextPutAll:self class GZipArchivZipCommand.
   337     stream space.
   338     stream nextPutAll:aFileName asString.
   339     cmd := stream contents.
   340     stream close.
   341     ^ cmd
   342 !
   343 
   344 getZipCommandForFile:aFile to:newFile
   345     | stream cmd|
   346 
   347     stream := WriteStream on:''.
   348     stream nextPutAll:self class GZipArchivZipCommand.
   349     stream space.
   350     stream nextPut:self class MinusSign.
   351     stream nextPutAll:self class GZipArchivWriteToStdioOption.
   352     stream space.
   353     stream nextPutAll:aFile asString.
   354     stream space.
   355     stream nextPut:self class PipeSign.
   356     stream space.
   357     stream nextPutAll:newFile asString.
   358     cmd := stream contents.
   359     stream close.
   360     ^ cmd
   361 ! !
   362 
   363 !Archiver::TarArchive class methodsFor:'command strings'!
   364 
   365 TarArchivAddOption
   366     ^ 'r'
   367 !
   368 
   369 TarArchivCommand
   370     ^ 'tar'
   371 !
   372 
   373 TarArchivDeleteOption
   374     ^ '--delete'
   375 !
   376 
   377 TarArchivFileOption
   378     ^ 'f'
   379 !
   380 
   381 TarArchivListContentsOption
   382     ^ 't'
   383 !
   384 
   385 TarArchivListOptions
   386     ^ self TarArchivListContentsOption , self TarArchivVerboseOption 
   387         , self TarArchivFileOption
   388 !
   389 
   390 TarArchivListZippedOptions
   391     ^ self TarArchivListContentsOption , self TarArchivVerboseOption 
   392         , self TarArchivFileOption , self TarArchivZipOption
   393 !
   394 
   395 TarArchivUnpackInDirectoryOption
   396     ^ '-C '
   397 !
   398 
   399 TarArchivUnpackOption
   400     ^ 'x'
   401 !
   402 
   403 TarArchivVerboseOption
   404     ^ 'v'
   405 !
   406 
   407 TarArchivZipOption
   408     ^ 'z'
   409 ! !
   410 
   411 !Archiver::TarArchive methodsFor:'actions'!
   412 
   413 addFilesToArchiv:colOfFiles
   414 
   415     | cmd tempDir archivFile archivInTemp|
   416 
   417     tempDir := self temporaryDirectory.
   418     archivFile := self fileName.
   419     archivInTemp := tempDir construct:(archivFile baseName).
   420     "/ copy files to be added to tempDir
   421     colOfFiles do:[ :file |
   422         file recursiveCopyTo:(tempDir construct:(file baseName))
   423     ].
   424 
   425     "/ copy tar archiv to tempDir
   426     archivFile copyTo:archivInTemp.
   427 
   428     "/ addFiles to the tar archive
   429     cmd := self getAddFilesToTarArchiveCommandForArchiv:archivInTemp with:colOfFiles.
   430     self executeCommand:cmd directory:tempDir.
   431 
   432     "/ copy tar archiv back
   433     archivInTemp copyTo:(self fileName).
   434 !
   435 
   436 extractTo:aDirectory 
   437 
   438     ^ self extractTo:aDirectory with:nil
   439 !
   440 
   441 extractTo:aDirectory with:files
   442 
   443     |execDir cmd|
   444 
   445     execDir := self fileName directory.
   446     cmd := self getExtractSelectedFilesCommandForDirectory:aDirectory withSelection:files.
   447     self executeCommand:cmd directory:execDir.
   448 !
   449 
   450 extractWithOutDirectoryTo:aDirectory with:files
   451 
   452     |execDir tempDir tempFile|
   453 
   454     execDir := self fileName directory.
   455     tempDir := self temporaryDirectory.
   456     self extractTo:tempDir with:files.
   457     files do:[ : aFileString |
   458         tempFile := self temporaryDirectory construct:aFileString.
   459         tempFile exists ifTrue:[
   460             tempFile recursiveCopyTo:(aDirectory construct:(aFileString fileName asFilename baseName)).
   461         ].
   462     ].
   463 !
   464 
   465 listFilesFromArchiv
   466 
   467     self listFilesFromArchiv:nil
   468 !
   469 
   470 listFilesFromArchiv:newColOfFiles
   471 
   472     | cmd dir|
   473 
   474     self fileName isNil ifTrue:[ ^ self].
   475     dir := self fileName directory.
   476     cmd := self getFileListFromArchivCommand:newColOfFiles.
   477     self executeCommand:cmd directory:dir 
   478 !
   479 
   480 removeFilesFromArchiv:aColOfFiles
   481 
   482     |cmd|
   483 
   484     cmd := self getRemoveFilesFromTarArchivFor:aColOfFiles.
   485     self executeCommand:cmd directory:(self fileName directory). 
   486 ! !
   487 
   488 !Archiver::TarArchive methodsFor:'command strings'!
   489 
   490 getAddFilesToTarArchiveCommand:aColOfFiles 
   491     |filename cmd stream|
   492 
   493     filename := self fileName.
   494     filename exists ifTrue:[
   495         stream := WriteStream on:''.
   496         stream nextPutAll:self class TarArchivCommand.
   497         stream space.
   498         stream nextPutAll:self class TarArchivAddOption.
   499         stream nextPutAll:self class TarArchivFileOption.
   500         stream space.
   501         stream nextPutAll:filename asString.
   502         aColOfFiles do:[:el | 
   503             stream space.
   504             stream nextPutAll:(el asString)
   505         ].
   506         cmd := stream contents
   507     ].
   508     ^ cmd
   509 !
   510 
   511 getAddFilesToTarArchiveCommandForArchiv:archivFile with:aColOfFiles 
   512     | cmd stream|
   513 
   514     archivFile exists ifTrue:[
   515         stream := WriteStream on:''.
   516         stream nextPutAll:self class TarArchivCommand.
   517         stream space.
   518         stream nextPutAll:self class TarArchivAddOption.
   519         stream nextPutAll:self class TarArchivFileOption.
   520         stream space.
   521         stream nextPutAll:archivFile asString.
   522         aColOfFiles do:[:el | 
   523             stream space.
   524             stream nextPutAll:(el baseName)
   525         ].
   526         cmd := stream contents
   527     ].
   528     ^ cmd
   529 !
   530 
   531 getExtractSelectedFilesCommandForDirectory:dir withSelection:sel 
   532     | stream cmd|
   533 
   534     stream := WriteStream on:''.
   535     stream nextPutAll:self class TarArchivCommand.
   536     stream space.
   537     stream nextPutAll:self class TarArchivUnpackOption.
   538     stream nextPutAll:self class TarArchivFileOption.
   539     stream space.
   540     stream nextPutAll:self fileName asString.
   541     stream space.
   542     stream nextPutAll:self class TarArchivUnpackInDirectoryOption.
   543     stream space.
   544     stream nextPutAll:dir asString.
   545     sel notNil ifTrue:[
   546         sel do:[:el | 
   547             stream space.
   548             stream nextPutAll:(el fileName asString)
   549         ].
   550     ].
   551     cmd := stream contents.
   552     stream close.
   553     ^ cmd
   554 !
   555 
   556 getFileListFromArchivCommand:aColOfFiles 
   557 
   558     | stream cmd|
   559 
   560     stream := WriteStream on:''.
   561     stream nextPutAll:self class TarArchivCommand.
   562     stream space.
   563     stream nextPutAll:self class TarArchivListOptions.
   564     stream space.
   565     stream nextPutAll:self fileName baseName.
   566     aColOfFiles notNil ifTrue:[
   567         aColOfFiles do:[:el | 
   568             stream space.
   569             stream nextPutAll:(el baseName)
   570         ]
   571     ].
   572     cmd := stream contents.
   573     stream close.
   574     ^ cmd
   575 !
   576 
   577 getRemoveFilesFromTarArchivFor:sel 
   578     | stream filename|
   579 
   580     filename := self fileName.
   581     filename exists ifTrue:[
   582         stream := WriteStream on:''.
   583         stream nextPutAll:self class TarArchivCommand.
   584         stream space.
   585         stream nextPutAll:self class TarArchivDeleteOption.
   586         stream space.
   587         stream nextPut:self class MinusSign.
   588         stream nextPutAll:self class TarArchivFileOption.
   589         stream space.
   590         stream nextPutAll:filename asString.
   591         sel do:[:el | 
   592             stream space.
   593             stream nextPutAll:el
   594         ].
   595         ^ stream contents
   596     ]
   597 ! !
   598 
   599 !Archiver::TarGZipArchive methodsFor:'accessing'!
   600 
   601 fileName:aFile
   602 
   603     | tempDir file gzipArchiver suffix|
   604 
   605     super fileName:aFile.
   606     " unzip file in tempDirectory and do all the things with tar file "
   607     tempDir := self temporaryDirectory.
   608     gzipArchiver := Archiver::GZipArchive with:(self fileName).
   609     gzipArchiver unzipTo:tempDir.
   610     suffix := self fileName suffix.
   611     file := self fileName withoutSuffix.
   612     file := file baseName.
   613     suffix = 'tgz' ifTrue:[
   614         file := file , '.tar'
   615     ].
   616     tarFile := self temporaryDirectory construct:file.
   617     tarArchiver := TarArchive with:tarFile.
   618 ! !
   619 
   620 !Archiver::TarGZipArchive methodsFor:'actions'!
   621 
   622 addFilesToArchiv:colOfFiles
   623 
   624     self setCommandOptions.
   625     tarArchiver addFilesToArchiv:colOfFiles.
   626     self synchronize.
   627 !
   628 
   629 extractTo:aDirectory 
   630 
   631     self extractTo:aDirectory with:nil.
   632 !
   633 
   634 extractTo:aDirectory with:col
   635 
   636     self setCommandOptions.
   637     tarArchiver extractTo:aDirectory with:col.
   638 !
   639 
   640 extractWithOutDirectoryTo:aDirectory with:files
   641 
   642     self setCommandOptions.
   643     tarArchiver extractWithOutDirectoryTo:aDirectory with:files.
   644 !
   645 
   646 listFilesFromArchiv
   647 
   648     self listFilesFromArchiv:nil
   649 !
   650 
   651 listFilesFromArchiv:newColOfFiles
   652 
   653     self setCommandOptions.
   654     ^ tarArchiver listFilesFromArchiv:newColOfFiles.
   655 !
   656 
   657 removeFilesFromArchiv:aColOfFiles
   658 
   659     self setCommandOptions.
   660     tarArchiver removeFilesFromArchiv:aColOfFiles.
   661     self synchronize.
   662 ! !
   663 
   664 !Archiver::TarGZipArchive methodsFor:'actions private'!
   665 
   666 setCommandOptions
   667 
   668     tarArchiver outStream:(self outStream).
   669     tarArchiver errorStream:(self errorStream).
   670     tarArchiver synchron:(self synchron).
   671 !
   672 
   673 synchronize
   674 
   675     |gzipArchiver|
   676 
   677     gzipArchiver := GZipArchive with:nil.
   678     gzipArchiver zipFile:(tarArchiver fileName) to:(self fileName).
   679 ! !
   680 
   681 !Archiver::TarGZipArchive methodsFor:'initialization & release'!
   682 
   683 release
   684 
   685     super release.
   686     tarArchiver release.
   687 ! !
   688 
   689 !Archiver class methodsFor:'documentation'!
   690 
   691 version
   692     ^ '$Header$'
   693 ! !