From db3d4292f4acf2a27f17394a55690d7f82373cf5 Mon Sep 17 00:00:00 2001 From: Juan Cruz Viotti Date: Wed, 28 Jan 2015 08:33:50 -0400 Subject: [PATCH] Add Windows support to device init command --- lib/actions/device.coffee | 40 +++++++-------------------------------- lib/drive/drive.coffee | 38 +++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 33 deletions(-) create mode 100644 lib/drive/drive.coffee diff --git a/lib/actions/device.coffee b/lib/actions/device.coffee index f023c572..2d43a063 100644 --- a/lib/actions/device.coffee +++ b/lib/actions/device.coffee @@ -2,10 +2,9 @@ _ = require('lodash-contrib') async = require('async') resin = require('resin-sdk') os = require('os') -fs = require('fs') -progressStream = require('progress-stream') visuals = require('resin-cli-visuals') commandOptions = require('./command-options') +drive = require('../drive/drive') exports.list = signature: 'devices' @@ -166,18 +165,6 @@ exports.init = options: [ commandOptions.yes ] permission: 'user' action: (params, options, done) -> - if os.platform() is 'win32' - error = new Error('This functionality is only available on UNIX based systems for now.') - return done(error) - - if not fs.existsSync(params.image) - error = new Error("Invalid OS image: #{params.image}") - return done(error) - - if not fs.existsSync(params.device) - error = new Error("Invalid device: #{params.device}") - return done(error) - async.waterfall([ (callback) -> @@ -190,27 +177,14 @@ exports.init = (confirmed, callback) -> return done() if not confirmed - imageFile = fs.createReadStream(params.image) - deviceFile = fs.createWriteStream(params.device) - imageFileSize = fs.statSync(params.image).size + progressBar = null - progress = progressStream - length: imageFileSize - time: 500 - - if not options.quiet - progressBar = new visuals.widgets.Progress('Writing device OS', imageFileSize) - progress.on 'progress', (status) -> + drive.writeImage params.device, params.image, + progress: not options.quiet + onProgress: (status) -> + progressBar ?= new visuals.widgets.Progress('Writing device OS', status.length) progressBar.tick(status.delta) - - imageFile - .pipe(progress) - .pipe(deviceFile) - .on 'error', (error) -> - if error.code is 'EBUSY' - error.message = "Try umounting #{error.path} first." - return callback(error) - .on('close', callback) + , callback ], done) diff --git a/lib/drive/drive.coffee b/lib/drive/drive.coffee new file mode 100644 index 00000000..05bd1ddd --- /dev/null +++ b/lib/drive/drive.coffee @@ -0,0 +1,38 @@ +fs = require('fs') +progressStream = require('progress-stream') + +exports.writeImage = (devicePath, imagePath, options = {}, callback = _.noop) -> + + if not fs.existsSync(imagePath) + return callback(new Error("Invalid OS image: #{imagePath}")) + + if not fs.existsSync(devicePath) + return callback(new Error("Invalid device: #{devicePath}")) + + imageFile = fs.createReadStream(imagePath) + + deviceFile = fs.createWriteStream devicePath, + # Required by Windows to work correctly + flags: 'r+' + + imageFileSize = fs.statSync(imagePath).size + + progress = progressStream + length: imageFileSize + time: 500 + + if options.progress + progress.on('progress', options.onProgress) + + imageFile + .pipe(progress) + .pipe(deviceFile) + + # TODO: We should make use of nodewindows.elevate() + # if we get an EPERM error. + .on 'error', (error) -> + if error.code is 'EBUSY' + error.message = "Try umounting #{error.path} first." + return callback(error) + + .on('close', callback)