Skip to content

Commit

Permalink
Eject sync
Browse files Browse the repository at this point in the history
  • Loading branch information
JrMasterModelBuilder committed Sep 30, 2023
1 parent 5a09d21 commit c28adb3
Showing 1 changed file with 70 additions and 23 deletions.
93 changes: 70 additions & 23 deletions src/mounter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {spawn} from 'node:child_process';
import {spawn, spawnSync} from 'node:child_process';

import {
Plist,
Expand Down Expand Up @@ -121,7 +121,52 @@ export class Mounter {
options: Readonly<IMounterAttachOptions> | null = null,
ejectOnShutdown: Readonly<IMounterEjectOptions> | null = null
) {
// Assemble args.
const devices = await this._runAttach(this._argsAttach(file, options));
const eject = this._createEject(devices, ejectOnShutdown);
return {
devices,
eject
} as IMounterAttachInfo;
}

/**
* Eject a disk image.
*
* @param file Path to device file or volume mount point.
* @param options Options object.
*/
public async eject(
file: string,
options: Readonly<IMounterEjectOptions> | null = null
) {
await this._runEject(this._argsEject(file, options));
}

/**
* Eject a disk image.
*
* @param file Path to device file or volume mount point.
* @param options Options object.
*/
public ejectSync(
file: string,
options: Readonly<IMounterEjectOptions> | null = null
) {
// eslint-disable-next-line no-sync
this._runEjectSync(this._argsEject(file, options));
}

/**
* Create args for attach.
*
* @param file Path to disk image.
* @param options Options object.
* @returns Argument list.
*/
protected _argsAttach(
file: string,
options: Readonly<IMounterAttachOptions> | null = null
) {
const args = ['attach', '-plist'];
if (options) {
if (options.readonly) {
Expand All @@ -132,39 +177,26 @@ export class Mounter {
}
}
args.push(this._fileArg(file));

// Run command.
const devices = await this._runAttach(args);

// Create the eject callback.
const eject = this._createEject(devices, ejectOnShutdown);

const info: IMounterAttachInfo = {
devices,
eject
};
return info;
return args;
}

/**
* Eject a disk image.
* Create args for eject.
*
* @param file Path to device file or volume mount point.
* @param options Options object.
* @returns Argument list.
*/
public async eject(
protected _argsEject(
file: string,
options: Readonly<IMounterEjectOptions> | null = null
) {
// Assemble args.
const args = ['eject'];
if (options && options.force) {
args.push('-force');
}
args.push(this._fileArg(file));

// Run command.
await this._runEject(args);
return args;
}

/**
Expand Down Expand Up @@ -196,12 +228,27 @@ export class Mounter {
*/
protected async _runEject(args: Readonly<string[]>) {
const proc = spawn(this.hdiutil, args);
const code = await new Promise<number | null>((resolve, reject) => {
const status = await new Promise<number | null>((resolve, reject) => {
proc.once('exit', resolve);
proc.once('error', reject);
});
if (code) {
throw new Error(`Eject failed: hdiutil exit code: ${code}`);
if (status) {
throw new Error(`Eject failed: hdiutil exit code: ${status}`);
}
}

/**
* Run hdiutil eject command.
*
* @param args CLI args.
*/
protected _runEjectSync(args: Readonly<string[]>) {
const {status, error} = spawnSync(this.hdiutil, args);
if (error) {
throw error;
}
if (status) {
throw new Error(`Eject failed: hdiutil exit code: ${status}`);
}
}

Expand Down

0 comments on commit c28adb3

Please sign in to comment.