function printBuildDuration(build) { if (build.status !== STATUS_TYPES.inProgress) { return gray(formatMs(build.durationMillis)); } // if there any remaining time info, it will be added under __meta__ property if (!build.__meta__) return gray('N/A'); return `Remaining time: ${build.__meta__.remainingTime}`; }
function mapRunningBuilds(runningBuilds) { let title = ''; return runningBuilds.map(({ id, name, startTimeMillis }) => { title = name; if (startTimeMillis) { title += gray(` (Started ${ago(new Date(startTimeMillis), 'hour')})`); } return { value: id, title, }; }); }
path(message) { const [first, ...rest] = message.split('/').reverse(); return underline(gray(rest.reverse().join('/')) + '/' + first); }
adornment(symbol) { return gray(symbol); }
const save_asset = async ({asset_url, asset_name, asset_id, asset_size, chapter_path, lecture_index}) => { const asset_name_with_path = path.join(chapter_path, asset_name); const downloading_asset_name_with_path = asset_size < 100000 ? asset_name_with_path : path.join(chapter_path, `${lecture_index} downloading asset ${asset_id}`); await stream_download( asset_url, downloading_asset_name_with_path ).catch(error => { throw error; }); if (asset_size > 100000 || !asset_size) { fs.rename(downloading_asset_name_with_path, asset_name_with_path, error => { if (error) { handle_error({error, message: `Unable to rename asset ${yellow(asset_name)}`}); } }); } console.log(`\n ${gray(inverse(' Asset '))} ${asset_name} ${green_bg('Done')}`); }
list.push(`${icon}${stage.name} ${gray(`(Duration ${formatMs(stage.duration)})`)}`); });
test('when the build has failed', async () => { await reportBuildStages(branchName, queuedItemNumber, spinnerStub); // 1st set of data arrived emitter.emit('data', { status: STATUS_TYPES.inProgress, stages: [stageStub] }); // 2nd set of data arrived, but unfortunately build has failed emitter.emit('data', { status: STATUS_TYPES.failed, stages: [{ ...stageStub, status: STATUS_TYPES.failed }], }); emitter.emit('end', STATUS_TYPES.failed); expect(console.log).toHaveBeenCalledWith(yellow('Build Stages')); expect(process.stdout.write.mock.calls[1][0]).toEqual( expect.stringContaining(`foo ${gray('(Duration 01 sec)')}`) ); expect(process.stdout.write.mock.calls[3][0]).toEqual( expect.stringContaining( `${BUILD_STATUS.FAILED.icon} foo ${gray('(Duration 01 sec)')}` ) ); expect(process.stdout.write.mock.calls[4][0]).toEqual( expect.stringContaining(`${BUILD_STATUS.FAILED.icon} Build has ${red('FAILED')}`) ); });
// Download files with link from Udemy const download_asset_file = async ({chapter_path, lecture_index, asset}) => { const asset_name = safe_name(`${lecture_index} ${asset['filename']}`); const asset_name_with_path = path.join(chapter_path, asset_name); const asset_url = asset['url_set']['File'][0]['file']; const asset_id = asset['id']; const asset_size = asset['file_size']; if (path_exists(asset_name_with_path)) { return console.log(`\n ${gray(inverse(' Asset '))} ${asset_name} ${yellow('(already downloaded)')}`); } await save_asset({ asset_url, asset_name, asset_id, asset_size, chapter_path, lecture_index }).catch(error => { process.stderr.write(`\n ${gray(inverse(' Asset '))} ${asset_name}`); throw error; }); }
expect(clearInterval).not.toHaveBeenCalled(); expect(process.stdout.write.mock.calls[1][0]).toEqual( expect.stringContaining(`foo ${gray('(Duration 01 sec)')}`) ); expect(setInterval).toHaveBeenCalled(); expect(process.stdout.write.mock.calls[3][0]).toEqual( expect.stringContaining( `${BUILD_STATUS.SUCCESS.icon} foo ${gray('(Duration 01 sec)')}`
test('when the build has been aborted', async () => { await reportBuildStages(branchName, queuedItemNumber, spinnerStub); // 1st set of data arrived emitter.emit('data', { status: STATUS_TYPES.inProgress, stages: [stageStub] }); // 2nd set of data arrived, but unfortunately build has been aborted emitter.emit('data', { status: STATUS_TYPES.aborted, stages: [{ ...stageStub, status: STATUS_TYPES.aborted }], }); emitter.emit('end', STATUS_TYPES.aborted); expect(console.log).toHaveBeenCalledWith(yellow('Build Stages')); expect(process.stdout.write.mock.calls[1][0]).toEqual( expect.stringContaining(`foo ${gray('(Duration 01 sec)')}`) ); expect(process.stdout.write.mock.calls[3][0]).toEqual( expect.stringContaining( `${BUILD_STATUS.ABORTED.icon} foo ${gray('(Duration 01 sec)')}` ) ); expect(process.stdout.write.mock.calls[4][0]).toEqual( expect.stringContaining( `${BUILD_STATUS.ABORTED.icon} Build has been ${yellow('ABORTED')}` ) ); });
test('when the build is unstable', async () => { await reportBuildStages(branchName, queuedItemNumber, spinnerStub); // 1st set of data arrived emitter.emit('data', { status: STATUS_TYPES.inProgress, stages: [stageStub] }); // 2nd set of data arrived, but unfortunately build is unstable emitter.emit('data', { status: STATUS_TYPES.unstable, stages: [{ ...stageStub, status: STATUS_TYPES.unstable }], }); emitter.emit('end', STATUS_TYPES.unstable); expect(console.log).toHaveBeenCalledWith(yellow('Build Stages')); expect(process.stdout.write.mock.calls[1][0]).toEqual( expect.stringContaining(`foo ${gray('(Duration 01 sec)')}`) ); expect(process.stdout.write.mock.calls[3][0]).toEqual( expect.stringContaining( `${BUILD_STATUS.UNSTABLE.icon} foo ${gray('(Duration 01 sec)')}` ) ); expect(process.stdout.write.mock.calls[4][0]).toEqual( expect.stringContaining( `${BUILD_STATUS.UNSTABLE.icon} Build is ${yellow('UNSTABLE')}` ) ); });
diffSame(val) { return gray(val); }