@@ -6,6 +6,9 @@ import getFullSourceSpace from 'contentful-batch-libs/dist/get/get-full-source-s
66import Promise from 'bluebird'
77import jsonStringifySafe from 'json-stringify-safe'
88import log from 'npmlog'
9+ import Listr from 'listr'
10+ import UpdateRenderer from 'listr-update-renderer'
11+ import VerboseRenderer from 'listr-verbose-renderer'
912import { resolve } from 'path'
1013import { startCase } from 'lodash'
1114import Table from 'cli-table2'
@@ -22,7 +25,8 @@ export default function runContentfulExport (usageParams) {
2225 skipContent : false ,
2326 skipWebhooks : false ,
2427 maxAllowedLimit : 1000 ,
25- saveFile : true
28+ saveFile : true ,
29+ useVerboseRenderer : false
2630 }
2731
2832 summary . startTime = moment ( )
@@ -52,104 +56,128 @@ export default function runContentfulExport (usageParams) {
5256 opts . errorLogFile = opts . exportDir + '/contentful-export-' + Date . now ( ) + '.log'
5357 }
5458
55- const clients = createClients ( opts )
56- return getFullSourceSpace ( {
57- managementClient : clients . source . management ,
58- spaceId : clients . source . spaceId ,
59- maxAllowedLimit : opts . maxAllowedLimit ,
60- includeDrafts : opts . includeDrafts ,
61- skipContentModel : opts . skipContentModel ,
62- skipContent : opts . skipContent ,
63- skipWebhooks : opts . skipWebhooks ,
64- skipRoles : opts . skipRoles
65- } )
66- . then ( ( response ) => {
67- if ( ! opts . downloadAssets ) {
68- return response
59+ const listrOptions = opts . useVerboseRenderer
60+ ? {
61+ renderer : VerboseRenderer
62+ }
63+ : {
64+ renderer : UpdateRenderer ,
65+ collapse : false
66+ }
67+
68+ const tasks = new Listr ( [
69+ {
70+ title : 'Initialize clients' ,
71+ task : ( ctx ) => {
72+ ctx . clients = createClients ( opts )
6973 }
70- summary . assetDownloads = {
71- successCount : 0 ,
72- warningCount : 0 ,
73- errorCount : 0
74+ } ,
75+ {
76+ title : 'Fetching data from space' ,
77+ task : ( ctx ) => {
78+ return getFullSourceSpace ( {
79+ managementClient : ctx . clients . source . management ,
80+ spaceId : ctx . clients . source . spaceId ,
81+ maxAllowedLimit : opts . maxAllowedLimit ,
82+ includeDrafts : opts . includeDrafts ,
83+ skipContentModel : opts . skipContentModel ,
84+ skipContent : opts . skipContent ,
85+ skipWebhooks : opts . skipWebhooks ,
86+ skipRoles : opts . skipRoles ,
87+ listrOptions
88+ } )
7489 }
75-
76- log . info ( 'export' , 'Downloading ' + response . assets . length + ' assets' )
77-
78- return Promise . map ( response . assets , ( asset ) => {
79- if ( ! asset . fields . file ) {
80- log . warn ( 'export' , '-> asset has no file(s)' , jsonStringifySafe ( asset ) )
81- summary . assetDownloads . warningCount ++
82- return
83- }
84- const locales = Object . keys ( asset . fields . file )
85- return Promise . mapSeries ( locales , ( locale ) => {
86- const url = asset . fields . file [ locale ] . url || asset . fields . file [ locale ] . upload
87- if ( ! url ) {
88- log . warn ( 'export' , '-> asset no file(s) for locale' , locale , jsonStringifySafe ( asset ) )
89- summary . assetDownloads . warningCount ++
90+ } ,
91+ {
92+ title : 'Download assets' ,
93+ task : ( ctx ) => {
94+ let successCount = 0
95+ let warningCount = 0
96+ let errorCount = 0
97+
98+ log . info ( 'export' , `Downloading ${ ctx . data . assets . length } assets` )
99+
100+ return Promise . map ( ctx . data . assets , ( asset ) => {
101+ if ( ! asset . fields . file ) {
102+ log . warn ( '-> asset has no file(s)' , jsonStringifySafe ( asset ) )
103+ warningCount ++
90104 return
91105 }
92- return downloadAsset ( url , opts . exportDir )
93- . then ( ( downLoadedFile ) => {
94- log . info ( 'export' , '-> ' + downLoadedFile )
95- summary . assetDownloads . successCount ++
96- } )
97- . catch ( ( error ) => {
98- log . error ( 'export' , '-> error downloading ' + url + ' => ' + error . message )
99- log . error ( 'export' , JSON . stringify ( error , null , 2 ) )
100- summary . assetDownloads . errorCount ++
106+ const locales = Object . keys ( asset . fields . file )
107+ return Promise . mapSeries ( locales , ( locale ) => {
108+ const url = asset . fields . file [ locale ] . url || asset . fields . file [ locale ] . upload
109+ return downloadAsset ( url , opts . exportDir )
110+ . then ( ( downLoadedFile ) => {
111+ log . info ( 'export' , '-> ' + downLoadedFile )
112+ successCount ++
113+ } )
114+ . catch ( ( error ) => {
115+ log . error ( 'export' , '-> error downloading ' + url + ' => ' + error . message )
116+ log . error ( 'export' , JSON . stringify ( error , null , 2 ) )
117+ errorCount ++
118+ } )
101119 } )
120+ } , {
121+ concurrency : 6
102122 } )
103- } , {
104- concurrency : 6
105- } )
106- . then ( ( ) => {
107- log . info ( 'export' , 'Finished loading files for ' + response . assets . length + ' assets.' )
108- return response
109- } )
110- } )
111- . then ( ( response ) => {
112- if ( opts . saveFile ) {
123+ . then ( ( ) => {
124+ ctx . assetDownloads = {
125+ successCount,
126+ warningCount,
127+ errorCount
128+ }
129+ } )
130+ } ,
131+ skip : ( ) => ! opts . downloadAssets
132+ } ,
133+ {
134+ title : 'Writing data to file' ,
135+ task : ( ctx ) => {
113136 fs . existsSync ( opts . exportDir ) || fs . mkdirSync ( opts . exportDir )
114- const responseFile = `${ opts . exportDir } /contentful-export-${ clients . source . spaceId } -${ Date . now ( ) } .json`
115- log . info ( 'export' , 'Writing space data to json file at : ' + responseFile )
116- fs . writeFileSync ( responseFile , jsonStringifySafe ( response , null , 4 ) )
117- }
118- return response
119- } )
120- . then ( ( response ) => {
121- const responseTable = new Table ( )
137+ ctx . responseFile = `${ opts . exportDir } /contentful-export-${ ctx . clients . source . spaceId } -${ Date . now ( ) } .json`
138+ return fs . writeFileSync ( ctx . responseFile , jsonStringifySafe ( ctx . data , null , 4 ) )
139+ } ,
140+ skip : ( ) => ! opts . saveFile
141+ }
142+ ] , listrOptions )
143+
144+ return tasks . run ( {
145+ data : { }
146+ } )
147+ . then ( ( ctx ) => {
148+ const responseTable = new Table ( )
122149
123- responseTable . push ( [ { colSpan : 2 , content : 'Exported entities' } ] )
150+ responseTable . push ( [ { colSpan : 2 , content : 'Exported entities' } ] )
124151
125- Object . keys ( response ) . forEach ( ( type ) => {
126- responseTable . push ( [ startCase ( type ) , response [ type ] . length ] )
127- } )
152+ Object . keys ( ctx . data ) . forEach ( ( type ) => {
153+ responseTable . push ( [ startCase ( type ) , ctx . data [ type ] . length ] )
154+ } )
128155
129- console . log ( responseTable . toString ( ) )
156+ console . log ( responseTable . toString ( ) )
130157
131- if ( 'assetDownloads' in summary ) {
132- const downloadsTable = new Table ( )
133- downloadsTable . push ( [ { colSpan : 2 , content : 'Asset file download results' } ] )
134- downloadsTable . push ( [ 'Successful' , summary . assetDownloads . successCount ] )
135- downloadsTable . push ( [ 'Warnings ' , summary . assetDownloads . warningCount ] )
136- downloadsTable . push ( [ 'Errors ' , summary . assetDownloads . errorCount ] )
137- console . log ( downloadsTable . toString ( ) )
138- }
158+ if ( 'assetDownloads' in summary ) {
159+ const downloadsTable = new Table ( )
160+ downloadsTable . push ( [ { colSpan : 2 , content : 'Asset file download results' } ] )
161+ downloadsTable . push ( [ 'Successful' , ctx . assetDownloads . successCount ] )
162+ downloadsTable . push ( [ 'Warnings ' , ctx . assetDownloads . warningCount ] )
163+ downloadsTable . push ( [ 'Errors ' , ctx . assetDownloads . errorCount ] )
164+ console . log ( downloadsTable . toString ( ) )
165+ }
139166
140- const durationHuman = summary . startTime . fromNow ( true )
141- const durationSeconds = moment ( ) . diff ( summary . startTime , 'seconds' )
167+ const durationHuman = summary . startTime . fromNow ( true )
168+ const durationSeconds = moment ( ) . diff ( summary . startTime , 'seconds' )
142169
143- log . info ( 'export' , `The export took ${ durationHuman } (${ durationSeconds } s)` )
144-
145- return response
146- } )
147- . catch ( ( err ) => {
148- const { sourceSpace, errorLogFile } = opts
149- dumpErrorBuffer ( {
150- sourceSpace,
151- errorLogFile
152- } )
153- throw err
170+ log . info ( 'export' , `The export took ${ durationHuman } (${ durationSeconds } s)` )
171+ if ( opts . saveFile ) {
172+ log . info ( 'export' , `Stored space data to json file at: ${ ctx . responseFile } ` )
173+ }
174+ } )
175+ . catch ( ( err ) => {
176+ const { sourceSpace, errorLogFile } = opts
177+ dumpErrorBuffer ( {
178+ sourceSpace,
179+ errorLogFile
154180 } )
181+ throw err
182+ } )
155183}
0 commit comments