diff --git a/src/cli.ts b/src/cli.ts index bad7a04..95b7236 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -70,6 +70,8 @@ async function main() { } const tmpDir = tempy.directory() + process.chdir(tmpDir) + const apktool = new Apktool({ frameworkPath: path.join(tmpDir, 'framework'), customPath: args.apktool, @@ -102,7 +104,16 @@ async function main() { ) console.error( - chalk`\n {red.inverse.bold Failed! } An error occurred:\n\n${message}`, + [ + '', + chalk` {red.inverse.bold Failed! } An error occurred:`, + '', + message, + '', + ` The full logs of all commands are available here:`, + ` ${path.join(tmpDir, 'logs')}`, + '' + ].join('\n'), ) if (process.arch.startsWith('arm')) showArmWarning() diff --git a/src/tools/apktool.ts b/src/tools/apktool.ts index 8c2ee2c..00d129b 100644 --- a/src/tools/apktool.ts +++ b/src/tools/apktool.ts @@ -20,7 +20,7 @@ export default class Apktool extends Tool { 'decode', inputPath, '--output', outputPath, '--frame-path', this.options.frameworkPath, - ]) + ], 'decoding') } encode(inputPath: string, outputPath: string, useAapt2: boolean) { @@ -29,12 +29,12 @@ export default class Apktool extends Tool { '--output', outputPath, '--frame-path', this.options.frameworkPath, ...(useAapt2 ? ['--use-aapt2'] : []), - ]) + ], `encoding-${useAapt2 ? 'aapt2' : 'aapt'}`) } - private run(args: string[]) { + private run(args: string[], logName: string) { return map((line: string) => line.replace(/I: /g, ''))( - observeProcess(executeJar(this.path, args)), + observeProcess(executeJar(this.path, args), logName), ) } diff --git a/src/tools/uber-apk-signer.ts b/src/tools/uber-apk-signer.ts index c8111c9..79ee84b 100644 --- a/src/tools/uber-apk-signer.ts +++ b/src/tools/uber-apk-signer.ts @@ -16,6 +16,7 @@ export default class UberApkSigner extends Tool { ...(zipalign ? [] : ['--skipZipAlign']), ...pathArgs, ]), + 'signing', ) } diff --git a/src/utils/fs.ts b/src/utils/fs.ts index 8105ac3..57a310f 100644 --- a/src/utils/fs.ts +++ b/src/utils/fs.ts @@ -2,6 +2,7 @@ import * as fs from 'fs' import { promises as fsp } from 'fs' import { promisify } from 'util' +export const createWriteStream = fs.createWriteStream export const readFile = promisify(fs.readFile) export const writeFile = fsp.writeFile export const copyFile = fsp.copyFile diff --git a/src/utils/observe-process.ts b/src/utils/observe-process.ts index 72af4ff..d93fdba 100644 --- a/src/utils/observe-process.ts +++ b/src/utils/observe-process.ts @@ -1,14 +1,37 @@ +import * as fs from '../utils/fs' +import * as pathUtils from 'path' import { ExecaChildProcess } from 'execa' import { Observable } from 'rxjs' -export default function observeProcess(process: ExecaChildProcess): Observable { +export default function observeProcess( + process: ExecaChildProcess, + logName: string, +): Observable { return new Observable(subscriber => { - process - .then(() => subscriber.complete()) - .catch(error => subscriber.error(error)) + (async () => { + await fs.mkdir('logs', { recursive: true }) - process.stdout.on('data', (data: Buffer) => { - subscriber.next(data.toString().trim()) - }) + const fileName = pathUtils.join('logs', `${logName}.log`) + const failedFileName = pathUtils.join('logs', `${logName}.failed.log`) + const stream = fs.createWriteStream(fileName) + + process + .then(() => { + stream.close() + subscriber.complete() + }) + .catch(async error => { + stream.close() + await fs.rename(fileName, failedFileName) + + subscriber.error(error) + }) + + process.stdout.on('data', (data: Buffer) => { + subscriber.next(data.toString().trim()) + stream.write(data) + }) + process.stderr.on('data', (data: Buffer) => stream.write(data)) + })() }) }