Display app and binary size

This commit is contained in:
Sam Carlton 2021-02-03 14:27:36 -06:00
parent da1ce05470
commit b5adbe5b78
2 changed files with 239 additions and 182 deletions

View file

@ -2,7 +2,8 @@ import plist from 'plist'
import parseMacho from './macho/index.js' import parseMacho from './macho/index.js'
// console.log('MachOParser', MachOParser) const prettyBytes = require('pretty-bytes')
const knownArchiveExtensions = new Set([ const knownArchiveExtensions = new Set([
'app', 'app',
@ -43,6 +44,16 @@ function isValidHttpUrl( string ) {
return url.protocol === "http:" || url.protocol === "https:" return url.protocol === "http:" || url.protocol === "https:"
} }
function callWithTimeout(timeout, func) {
return new Promise((resolve, reject) => {
const timer = setTimeout(() => reject(new Error("timeout")), timeout)
func().then(
response => resolve(response),
err => reject(new Error(err))
).finally(() => clearTimeout(timer))
})
}
let zip let zip
export default class AppFilesScanner { export default class AppFilesScanner {
@ -270,28 +281,7 @@ export default class AppFilesScanner {
// Each file scanned: Filename, Type(Drop or URL), File URL, Datetime, Architectures, Mach-o Meta // Each file scanned: Filename, Type(Drop or URL), File URL, Datetime, Architectures, Mach-o Meta
} }
async scan ( fileList ) { async scanFile ( file, scanIndex ) {
// Push files to our files array
Array.from(fileList).forEach( (fileInstance, scanIndex) => {
this.files.unshift( {
status: 'loaded',
displayName: null,
statusMessage: '⏳ File Loaded and Queud',
details: [],
appVersion: null,
name: fileInstance.name,
size: fileInstance.size,
type: fileList.item( scanIndex ).type,
lastModifiedDate: fileInstance.lastModifiedDate,
instance: fileInstance,
item: fileList.item( scanIndex )
} )
})
// Scan for archives
await Promise.all( this.files.map( async (file, scanIndex) => {
// If we've already scanned this // If we've already scanned this
// then skip // then skip
@ -309,6 +299,7 @@ export default class AppFilesScanner {
await new Promise(r => setTimeout(r, 1500 * scanIndex)) await new Promise(r => setTimeout(r, 1500 * scanIndex))
file.statusMessage = '🗃 Decompressing file' file.statusMessage = '🗃 Decompressing file'
console.log(`Decompressing file at ${ file.size }`)
let entries let entries
@ -325,6 +316,7 @@ export default class AppFilesScanner {
} }
file.statusMessage = '👀 Scanning App Files' file.statusMessage = '👀 Scanning App Files'
console.log(`Searching entries`)
const foundEntries = this.findEntries( entries, { const foundEntries = this.findEntries( entries, {
macho: this.matchesMacho, macho: this.matchesMacho,
@ -361,6 +353,7 @@ export default class AppFilesScanner {
const [ rootInfoEntry ] = foundEntries.rootInfo const [ rootInfoEntry ] = foundEntries.rootInfo
// Get blob data from zip // Get blob data from zip
// https://gildas-lormeau.github.io/zip.js/core-api.html#zip-entry
const infoXml = await rootInfoEntry.getData( const infoXml = await rootInfoEntry.getData(
// writer // writer
// https://gildas-lormeau.github.io/zip.js/core-api.html#zip-writing // https://gildas-lormeau.github.io/zip.js/core-api.html#zip-writing
@ -408,13 +401,19 @@ export default class AppFilesScanner {
// info // info
// }) // })
// const machOBlob = await file.machOEntries
console.log(`Parsing Macho ${ file.machOEntries.length } files`)
const parsedMachoEntries = await Promise.all( file.machOEntries.map( async machOEntry => { const parsedMachoEntries = await Promise.all( file.machOEntries.map( async ( machOEntry, machEntryIndex ) => {
// console.log('Parsing ', machOEntry.filename) console.log('Parsing ', machOEntry.filename, machOEntry.uncompressedSize / 1000 )
if ( machEntryIndex === 0 ) {
file.displayBinarySize = prettyBytes( machOEntry.uncompressedSize )
file.binarySize = machOEntry.uncompressedSize
}
// Get blob data from zip // Get blob data from zip
// https://gildas-lormeau.github.io/zip.js/core-api.html#zip-entry
const machOBlob = await machOEntry.getData( const machOBlob = await machOEntry.getData(
// writer // writer
// https://gildas-lormeau.github.io/zip.js/core-api.html#zip-writing // https://gildas-lormeau.github.io/zip.js/core-api.html#zip-writing
@ -437,7 +436,9 @@ export default class AppFilesScanner {
// console.log('parsedMachoEntries', parsedMachoEntries) // console.log('parsedMachoEntries', parsedMachoEntries)
// file.statusMessage = `🏁 Scan Finished. ${file.machOEntries.length} Mach-o files` // file.statusMessage = `🏁 Scan Finished. ${file.machOEntries.length} Mach-o files`
file.statusMessage = `🏁 Scan Finished. ` // file.statusMessage = `🏁 Scan Finished. `
console.log(`Searching ${ parsedMachoEntries.length } binaries for architecture info`)
let supportedBinaries = 0 let supportedBinaries = 0
let unsupportedBinaries = 0 let unsupportedBinaries = 0
@ -457,6 +458,7 @@ export default class AppFilesScanner {
} }
} ) } )
console.log(`Found ${ supportedBinaries } supportedBinaries and ${unsupportedBinaries} unsupportedBinaries`)
// console.log('supportedBinaries', supportedBinaries) // console.log('supportedBinaries', supportedBinaries)
// console.log('unsupportedBinaries', unsupportedBinaries) // console.log('unsupportedBinaries', unsupportedBinaries)
@ -475,6 +477,49 @@ export default class AppFilesScanner {
file.status = 'finished' file.status = 'finished'
return return
}
async scan ( fileList ) {
// Push files to our files array
Array.from(fileList).forEach( (fileInstance, scanIndex) => {
this.files.unshift( {
status: 'loaded',
displayName: null,
statusMessage: '⏳ File Loaded and Queud',
details: [],
appVersion: null,
displayAppSize: prettyBytes( fileInstance.size ),
displayBinarySize: null,
binarySize: null,
name: fileInstance.name,
size: fileInstance.size,
type: fileList.item( scanIndex ).type,
lastModifiedDate: fileInstance.lastModifiedDate,
instance: fileInstance,
item: fileList.item( scanIndex )
} )
})
const scanTimeoutSeconds = 30
// Scan for archives
await Promise.all( this.files.map( ( file, scanIndex ) => {
return new Promise( (resolve, reject) => {
const timer = setTimeout(() => {
file.statusMessage = '❔ Scan timed out'
file.status = 'finished'
reject(new Error('Scan timed out'))
}, scanTimeoutSeconds * 1000)
this.scanFile( file, scanIndex ).then(
response => resolve(response),
err => reject(new Error(err))
).finally(() => clearTimeout(timer))
})
})) }))

View file

@ -89,11 +89,23 @@
<div class="absolute hidden left-0 h-12 w-12 rounded-full md:flex items-center justify-center bg-darker"> <div class="absolute hidden left-0 h-12 w-12 rounded-full md:flex items-center justify-center bg-darker">
{{ appScan.name.charAt(0) }} {{ appScan.name.charAt(0) }}
</div> </div>
{{ appScan.displayName || appScan.name }} {{ appScan.appVersion ? `- v${appScan.appVersion}` : '' }} {{ appScan.displayName || appScan.name }}
{{ appScan.appVersion ? `- v${appScan.appVersion}` : '' }}
{{ appScan.displayAppSize ? `- App ${appScan.displayAppSize}` : '' }}
{{ appScan.displayBinarySize ? `- Binary ${appScan.displayBinarySize}` : '' }}
<div class="text-sm leading-5 font-bold"> <div class="text-sm leading-5 font-bold">
{{ appScan.statusMessage }} {{ appScan.statusMessage }}
</div> </div>
appScan.binarySize: {{ appScan.binarySize }}
<div
v-if="appScan.binarySize && appScan.binarySize < (10 ^ 6)"
class="text-sm leading-5 font-bold"
>
Large Binary - This scan may take a while an/or have issues
</div>
<details class="w-full pt-6"> <details class="w-full pt-6">
<summary class="cursor-pointer mb-3">Details</summary> <summary class="cursor-pointer mb-3">Details</summary>
<div> <div>