@@ -19,13 +19,32 @@ import * as Archiver from 'archiver';
19
19
import * as path from 'path' ;
20
20
import ignore from 'ignore' ;
21
21
22
+ /**
23
+ * OnZipEntryFunction is a function that is called for each entry in the
24
+ * archive.
25
+ */
26
+ export type OnZipEntryFunction = ( entry : Archiver . EntryData ) => void ;
27
+
28
+ /**
29
+ * ZipOptions is used as input to the zip function.
30
+ */
31
+ export type ZipOptions = {
32
+ onZipEntry ?: OnZipEntryFunction ;
33
+ } ;
34
+
22
35
/**
23
36
* Zip a directory.
24
37
*
25
38
* @param dirPath Directory to zip.
39
+ * @param outputPath Path to output file.
40
+ * @param opts Options with which to invoke the zip.
26
41
* @returns filepath of the created zip file.
27
42
*/
28
- export function zipDir ( dirPath : string , outputPath : string ) : Promise < string > {
43
+ export function zipDir (
44
+ dirPath : string ,
45
+ outputPath : string ,
46
+ opts ?: ZipOptions ,
47
+ ) : Promise < string > {
29
48
// Check dirpath
30
49
if ( ! fs . existsSync ( dirPath ) ) {
31
50
throw new Error ( `Unable to find ${ dirPath } ` ) ;
@@ -37,15 +56,15 @@ export function zipDir(dirPath: string, outputPath: string): Promise<string> {
37
56
38
57
// Initialize archive
39
58
const archive = Archiver . create ( 'zip' , { zlib : { level : 7 } } ) ;
40
- archive . on ( 'warning' , ( err : Archiver . ArchiverError ) => {
41
- reject ( err ) ;
42
- } ) ;
43
- archive . on ( 'error' , ( err : Archiver . ArchiverError ) => {
44
- reject ( err ) ;
45
- } ) ;
46
- output . on ( 'finish' , ( ) => {
47
- resolve ( outputPath ) ;
59
+ archive . on ( 'entry' , ( entry ) => {
60
+ // For some reason, TypeScript complains if this guard is outside the
61
+ // closure. It would be more performant just not create this listener, but
62
+ // alas...
63
+ if ( opts ?. onZipEntry ) opts . onZipEntry ( entry ) ;
48
64
} ) ;
65
+ archive . on ( 'warning' , ( err ) => reject ( err ) ) ;
66
+ archive . on ( 'error' , ( err ) => reject ( err ) ) ;
67
+ output . on ( 'finish' , ( ) => resolve ( outputPath ) ) ;
49
68
50
69
// Pipe all archive data to be written
51
70
archive . pipe ( output ) ;
@@ -85,3 +104,23 @@ export function getGcloudIgnores(dir: string): string[] {
85
104
. split ( / \r ? \n / )
86
105
. map ( ( s ) => s . trim ( ) ) ;
87
106
}
107
+
108
+ /**
109
+ * RealEntryData is an extended form of entry data.
110
+ */
111
+ type RealEntryData = Archiver . EntryData & {
112
+ sourcePath ?: string ;
113
+ type ?: string ;
114
+ } ;
115
+
116
+ /**
117
+ * formatEntry formats the given entry data into a single-line string.
118
+ * @returns string
119
+ */
120
+ export function formatEntry ( entry : RealEntryData ) : string {
121
+ const name = entry . name ;
122
+ const mode = entry . mode || '000' ;
123
+ const sourcePath = entry . sourcePath || 'unknown' ;
124
+ const type = ( entry . type || 'unknown' ) . toUpperCase ( ) [ 0 ] ;
125
+ return `[${ type } ] (${ mode } ) ${ name } => ${ sourcePath } ` ;
126
+ }
0 commit comments