mirror of
https://github.com/ThatGuySam/doesitarm.git
synced 2026-05-18 06:44:46 -07:00
Only scan bundle execuable macho file
This commit is contained in:
parent
148f1c41b1
commit
879d27dcb4
1 changed files with 65 additions and 75 deletions
|
|
@ -279,8 +279,26 @@ export default class AppFilesScanner {
|
||||||
return await parseMacho( machOFile )
|
return await parseMacho( machOFile )
|
||||||
}
|
}
|
||||||
|
|
||||||
classifyArchitecture () {
|
getBundleExecutablePath ( info ) {
|
||||||
|
if ( info.CFBundleExecutable.includes('/') ) return `/Contents/${ info.CFBundleExecutable }`
|
||||||
|
|
||||||
|
return `/Contents/MacOS/${ info.CFBundleExecutable }`
|
||||||
|
}
|
||||||
|
|
||||||
|
classifyBinaryEntryArchitecture ( binaryEntry ) {
|
||||||
|
// Find an ARM Architecture
|
||||||
|
const armArchitecture = binaryEntry.architectures.find( architecture => {
|
||||||
|
// if ( architecture.processorType === 0 ) return false
|
||||||
|
|
||||||
|
// If processorType not a string
|
||||||
|
// then return false
|
||||||
|
if ( !isString(architecture.processorType) ) return false
|
||||||
|
|
||||||
|
return architecture.processorType.toLowerCase().includes('arm')
|
||||||
|
})
|
||||||
|
|
||||||
|
// Was an ARM Architecture found
|
||||||
|
return (armArchitecture !== undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
async submitScanInfo ({
|
async submitScanInfo ({
|
||||||
|
|
@ -413,8 +431,6 @@ export default class AppFilesScanner {
|
||||||
// Parse the Info.plist data
|
// Parse the Info.plist data
|
||||||
const info = plist.parse( infoXml )
|
const info = plist.parse( infoXml )
|
||||||
|
|
||||||
// console.log('info', info)
|
|
||||||
|
|
||||||
file.appVersion = info.CFBundleShortVersionString
|
file.appVersion = info.CFBundleShortVersionString
|
||||||
file.displayName = info.CFBundleDisplayName
|
file.displayName = info.CFBundleDisplayName
|
||||||
|
|
||||||
|
|
@ -444,86 +460,65 @@ export default class AppFilesScanner {
|
||||||
|
|
||||||
console.log(`Parsing Macho ${ file.machOEntries.length } files`)
|
console.log(`Parsing Macho ${ file.machOEntries.length } files`)
|
||||||
|
|
||||||
const parsedMachoEntries = await Promise.all( file.machOEntries.map( async ( machOEntry, machEntryIndex ) => {
|
// console.log('info.CFBundleExecutable', info.CFBundleExecutable)
|
||||||
console.log('Parsing ', machOEntry.filename, machOEntry.uncompressedSize / 1000 )
|
// console.log('info', info)
|
||||||
|
// console.log('file.machOEntries', file.machOEntries)
|
||||||
|
|
||||||
if ( machEntryIndex === 0 ) {
|
const bundelExecutablePath = this.getBundleExecutablePath( info )
|
||||||
file.displayBinarySize = prettyBytes( machOEntry.uncompressedSize )
|
|
||||||
file.binarySize = machOEntry.uncompressedSize
|
const bundleExecutables = file.machOEntries.filter( machoEntry => {
|
||||||
|
return machoEntry.filename.includes(bundelExecutablePath)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Warn if Bundle Executable doesn't look right
|
||||||
|
if ( bundleExecutables.length > 1) {
|
||||||
|
console.warn('More than one root bundleExecutable found', bundleExecutables)
|
||||||
|
} else if ( bundleExecutables.length === 0 ) {
|
||||||
|
console.warn('No root bundleExecutable found', bundleExecutables)
|
||||||
|
}
|
||||||
|
|
||||||
|
const [ bundleExecutable ] = bundleExecutables
|
||||||
|
|
||||||
|
console.log('Parsing ', bundleExecutable.filename, bundleExecutable.uncompressedSize / 1000 )
|
||||||
|
|
||||||
|
file.displayBinarySize = prettyBytes( bundleExecutable.uncompressedSize )
|
||||||
|
file.binarySize = bundleExecutable.uncompressedSize
|
||||||
|
|
||||||
|
// Get blob data from zip
|
||||||
|
// https://gildas-lormeau.github.io/zip.js/core-api.html#zip-entry
|
||||||
|
const bundleExecutableBlob = await bundleExecutable.getData(
|
||||||
|
// writer
|
||||||
|
// https://gildas-lormeau.github.io/zip.js/core-api.html#zip-writing
|
||||||
|
new zip.BlobWriter(),
|
||||||
|
// options
|
||||||
|
{
|
||||||
|
useWebWorkers: true
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// Get blob data from zip
|
const mainExecutableMeta = await this.parseMachOBlob( bundleExecutableBlob, file.name )
|
||||||
// https://gildas-lormeau.github.io/zip.js/core-api.html#zip-entry
|
console.log( 'mainExecutableMeta', mainExecutableMeta )
|
||||||
const machOBlob = await machOEntry.getData(
|
|
||||||
// writer
|
|
||||||
// https://gildas-lormeau.github.io/zip.js/core-api.html#zip-writing
|
|
||||||
// new zip.TextWriter(),
|
|
||||||
new zip.BlobWriter(),
|
|
||||||
// options
|
|
||||||
{
|
|
||||||
useWebWorkers: true,
|
|
||||||
// onprogress: (index, max) => {
|
|
||||||
// const percentageNumber = (index / max * 100)
|
|
||||||
// // onprogress callback
|
|
||||||
// console.log(`Writer progress ${percentageNumber}`)
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
return await this.parseMachOBlob( machOBlob, file.name )
|
const binarySupportsNative = this.classifyBinaryEntryArchitecture( mainExecutableMeta )
|
||||||
} ) )
|
|
||||||
|
|
||||||
// console.log('parsedMachoEntries', parsedMachoEntries)
|
|
||||||
|
|
||||||
// file.statusMessage = `🏁 Scan Finished. ${file.machOEntries.length} Mach-o files`
|
|
||||||
// file.statusMessage = `🏁 Scan Finished. `
|
|
||||||
console.log(`Searching ${ parsedMachoEntries.length } binaries for architecture info`)
|
|
||||||
|
|
||||||
|
|
||||||
let supportedBinaries = 0
|
if ( binarySupportsNative ) {
|
||||||
let unsupportedBinaries = 0
|
|
||||||
|
|
||||||
// Count supported and unsupported binaries
|
|
||||||
parsedMachoEntries.forEach( binaryEntry => {
|
|
||||||
const armBinary = binaryEntry.architectures.find( architecture => {
|
|
||||||
if ( architecture.processorType === 0 ) return false
|
|
||||||
|
|
||||||
return architecture.processorType.toLowerCase().includes('arm')
|
|
||||||
})
|
|
||||||
|
|
||||||
if ( armBinary !== undefined ) {
|
|
||||||
supportedBinaries++
|
|
||||||
} else {
|
|
||||||
unsupportedBinaries++
|
|
||||||
}
|
|
||||||
} )
|
|
||||||
|
|
||||||
console.log(`Found ${ supportedBinaries } supportedBinaries and ${unsupportedBinaries} unsupportedBinaries`)
|
|
||||||
|
|
||||||
// console.log('supportedBinaries', supportedBinaries)
|
|
||||||
// console.log('unsupportedBinaries', unsupportedBinaries)
|
|
||||||
|
|
||||||
if (supportedBinaries !== 0 && unsupportedBinaries !== 0) {
|
|
||||||
file.statusMessage = `🔶 App has some support. `
|
|
||||||
} else if ( unsupportedBinaries !== 0 ) {
|
|
||||||
file.statusMessage = `🔶 This app file is not natively compatible with Apple Silicon and may only run via Rosetta 2 translation, however, software vendors will sometimes will ship separate install files for Intel and ARM instead of a single one. `
|
|
||||||
} else if ( supportedBinaries !== 0 ) {
|
|
||||||
file.statusMessage = '✅ This app is natively compatible with Apple Silicon!'
|
file.statusMessage = '✅ This app is natively compatible with Apple Silicon!'
|
||||||
|
|
||||||
// Shift this scan to the top
|
// Shift this scan to the top
|
||||||
this.files.unshift( this.files.splice( scanIndex, 1 )[0] )
|
this.files.unshift( this.files.splice( scanIndex, 1 )[0] )
|
||||||
|
} else {
|
||||||
|
file.statusMessage = `🔶 This app file is not natively compatible with Apple Silicon and may only run via Rosetta 2 translation, however, software vendors will sometimes will ship separate install files for Intel and ARM instead of a single one. `
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log('parsedMachoEntries', JSON.parse( JSON.stringify(parsedMachoEntries) ))
|
|
||||||
console.log( 'parsedMachoEntries', parsedMachoEntries )
|
|
||||||
|
|
||||||
this.submitScanInfo ({
|
this.submitScanInfo ({
|
||||||
filename: file.name,
|
filename: file.name,
|
||||||
appVersion: file.appVersion,
|
appVersion: file.appVersion,
|
||||||
result: file.statusMessage,
|
result: file.statusMessage,
|
||||||
machoMeta: parsedMachoEntries.map( machoMeta => {
|
machoMeta: {
|
||||||
|
...mainExecutableMeta,
|
||||||
const architectures = machoMeta.architectures.map( architecture => {
|
file: undefined,
|
||||||
|
architectures: mainExecutableMeta.architectures.map( architecture => {
|
||||||
return {
|
return {
|
||||||
bits: architecture.bits,
|
bits: architecture.bits,
|
||||||
fileType: architecture.fileType,
|
fileType: architecture.fileType,
|
||||||
|
|
@ -535,13 +530,7 @@ export default class AppFilesScanner {
|
||||||
processorType: architecture.processorType,
|
processorType: architecture.processorType,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
},
|
||||||
return {
|
|
||||||
...machoMeta,
|
|
||||||
file: undefined, // Remove file
|
|
||||||
architectures
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
infoPlist: info
|
infoPlist: info
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -593,12 +582,13 @@ export default class AppFilesScanner {
|
||||||
})
|
})
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|
||||||
// Go through and set all files to finished to clean up any straglers
|
// Go through and set all files to finished to clean up any straglers
|
||||||
this.files.forEach( file => {
|
this.files.forEach( file => {
|
||||||
file.status = 'finished'
|
file.status = 'finished'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
console.log('All Scans Finished')
|
||||||
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue