2015-10-23 11:41:54 +00:00
|
|
|
fs = require 'fs'
|
|
|
|
path = require 'path'
|
|
|
|
{spawn} = require 'child_process'
|
2015-06-15 18:28:47 +00:00
|
|
|
|
2015-10-23 11:41:54 +00:00
|
|
|
appFolder = path.dirname process.execPath # i.e. my-app/app-0.1.13/
|
|
|
|
updateExe = path.resolve appFolder, '..', 'Update.exe' # i.e. my-app/Update.exe
|
|
|
|
exeName = path.basename process.execPath
|
2015-06-15 18:28:47 +00:00
|
|
|
|
|
|
|
# Spawn a command and invoke the callback when it completes with an error
|
|
|
|
# and the output from standard out.
|
2015-10-23 11:41:54 +00:00
|
|
|
spawnUpdate = (args, detached, callback) ->
|
2015-06-15 18:28:47 +00:00
|
|
|
try
|
2015-10-23 11:41:54 +00:00
|
|
|
spawnedProcess = spawn updateExe, args, {detached}
|
2015-06-15 18:28:47 +00:00
|
|
|
catch error
|
2015-10-23 11:41:54 +00:00
|
|
|
# Shouldn't happen, but still guard it.
|
|
|
|
process.nextTick -> callback error
|
2015-06-15 18:28:47 +00:00
|
|
|
return
|
|
|
|
|
2015-10-23 11:41:54 +00:00
|
|
|
stdout = ''
|
|
|
|
stderr = ''
|
2015-06-15 18:28:47 +00:00
|
|
|
spawnedProcess.stdout.on 'data', (data) -> stdout += data
|
2015-10-23 11:41:54 +00:00
|
|
|
spawnedProcess.stderr.on 'data', (data) -> stderr += data
|
2015-06-15 18:28:47 +00:00
|
|
|
|
2015-10-23 11:41:54 +00:00
|
|
|
errorEmitted = false
|
|
|
|
spawnedProcess.on 'error', (error) ->
|
|
|
|
errorEmitted = true
|
|
|
|
callback error
|
|
|
|
spawnedProcess.on 'exit', (code, signal) ->
|
|
|
|
# We may have already emitted an error.
|
|
|
|
return if errorEmitted
|
2015-06-15 18:28:47 +00:00
|
|
|
|
2015-10-23 11:41:54 +00:00
|
|
|
# Process terminated with error.
|
|
|
|
if code isnt 0
|
|
|
|
return callback "Command failed: #{signal ? code}\n#{stderr}"
|
2015-06-22 13:16:50 +00:00
|
|
|
|
2015-10-23 11:41:54 +00:00
|
|
|
# Success.
|
|
|
|
callback null, stdout
|
|
|
|
|
|
|
|
# Start an instance of the installed app.
|
|
|
|
exports.processStart = (callback) ->
|
|
|
|
spawnUpdate ['--processStart', exeName], true, ->
|
|
|
|
|
|
|
|
# Download the releases specified by the URL and write new results to stdout.
|
2015-11-13 08:03:40 +00:00
|
|
|
exports.download = (updateURL, callback) ->
|
|
|
|
spawnUpdate ['--download', updateURL], false, (error, stdout) ->
|
2015-06-22 13:16:50 +00:00
|
|
|
return callback(error) if error?
|
|
|
|
|
|
|
|
try
|
|
|
|
# Last line of output is the JSON details about the releases
|
2015-10-23 11:41:54 +00:00
|
|
|
json = stdout.trim().split('\n').pop()
|
2015-06-22 13:16:50 +00:00
|
|
|
update = JSON.parse(json)?.releasesToApply?.pop?()
|
2015-10-23 11:41:54 +00:00
|
|
|
catch
|
|
|
|
return callback "Invalid result:\n#{stdout}"
|
2015-06-22 13:16:50 +00:00
|
|
|
|
2015-10-23 11:41:54 +00:00
|
|
|
callback null, update
|
2015-06-15 18:28:47 +00:00
|
|
|
|
2015-10-23 11:41:54 +00:00
|
|
|
# Update the application to the latest remote version specified by URL.
|
2015-11-13 08:03:40 +00:00
|
|
|
exports.update = (updateURL, callback) ->
|
|
|
|
spawnUpdate ['--update', updateURL], false, callback
|
2015-06-15 18:28:47 +00:00
|
|
|
|
2015-06-22 13:16:50 +00:00
|
|
|
# Is the Update.exe installed with the current application?
|
|
|
|
exports.supported = ->
|
2015-10-23 11:41:54 +00:00
|
|
|
try
|
|
|
|
fs.accessSync updateExe, fs.R_OK
|
|
|
|
return true
|
|
|
|
catch
|
|
|
|
return false
|