@webprodigies/morphite 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/morphite.mjs +44 -7
  2. package/package.json +1 -1
package/bin/morphite.mjs CHANGED
@@ -282,10 +282,13 @@ async function main() {
282
282
  const destination = join(target, `${manifest.name}.app`)
283
283
  const work = await mkdtemp(join(tmpdir(), 'morphite-installer-'))
284
284
  const cleanup = () => rm(work, { recursive: true, force: true }).catch(() => undefined)
285
- process.once('SIGINT', () => {
285
+ const stopped = () => {
286
286
  live.done()
287
+ note('Stopped. Nothing was changed.', `Run npx ${PACKAGE}@latest again when you’re ready.`)
288
+ say('')
287
289
  void cleanup().then(() => process.exit(130))
288
- })
290
+ }
291
+ process.once('SIGINT', stopped)
289
292
  // A problem after the download started: keep the last line where it stopped, then say what happened.
290
293
  const stop = (title, detail) => {
291
294
  live.done()
@@ -317,15 +320,49 @@ async function main() {
317
320
  // Fetched by this program, the app carries no download mark; clear one defensively all the same.
318
321
  await run('/usr/bin/xattr', ['-dr', 'com.apple.quarantine', candidate]).catch(() => undefined)
319
322
 
320
- // Morphite must be closed before its app is replaced; the person closes it, never this script.
323
+ // Morphite must be closed before its app is replaced. The person quits it from its menu, or
324
+ // presses Enter and the installer asks it to quit the normal way (never a forced stop, so its
325
+ // work ends cleanly). No keyboard shortcut is suggested: ⌘Q here would quit Terminal.
321
326
  let open = await runningFrom([...installed, ...earlier])
322
327
  if (open.length) {
323
328
  const names = open.map((app) => basename(app, '.app')).join(' and ')
324
- live.set(`${bold(`Quit ${names} to continue`)} ${grey('(⌘Q)')}`)
325
- while (open.length) {
326
- await new Promise((resolve) => setTimeout(resolve, 700))
327
- open = await runningFrom([...installed, ...earlier])
329
+ live.clear()
330
+ note(
331
+ `${names} is open.`,
332
+ `Quit it from its menu bar (${names} → Quit), and this ${current ? 'update' : 'install'} continues on its own.`,
333
+ tty ? 'Or press Return to quit it now. Control-C stops without changing anything.' : 'Control-C stops without changing anything.'
334
+ )
335
+ say('')
336
+ const input = tty && process.stdin.isTTY ? process.stdin : null
337
+ const key = (data) => {
338
+ const text = String(data)
339
+ if (text.includes('\u0003')) return stopped()
340
+ if (!/[\r\n]/.test(text)) return
341
+ live.set(grey(`Quitting ${names}…`))
342
+ for (const app of open) {
343
+ const id = earlier.includes(app) ? EARLIER_APP_ID : manifest.bundleId
344
+ void run('/usr/bin/osascript', ['-e', `tell application id ${JSON.stringify(id)} to quit`]).catch(() => undefined)
345
+ }
346
+ }
347
+ if (input) {
348
+ input.setRawMode(true)
349
+ input.resume()
350
+ input.on('data', key)
351
+ }
352
+ live.set(grey(`Waiting for ${names} to quit…`))
353
+ try {
354
+ while (open.length) {
355
+ await new Promise((resolve) => setTimeout(resolve, 700))
356
+ open = await runningFrom([...installed, ...earlier])
357
+ }
358
+ } finally {
359
+ if (input) {
360
+ input.off('data', key)
361
+ input.setRawMode(false)
362
+ input.pause()
363
+ }
328
364
  }
365
+ live.done(grey(`${names} quit`))
329
366
  live.set(grey(`${current ? 'Updating' : 'Installing'} in ${place}…`))
330
367
  }
331
368
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webprodigies/morphite",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Install or update Morphite on your Mac: npx @webprodigies/morphite",
5
5
  "type": "module",
6
6
  "bin": {