mirror of
https://github.com/balena-io/etcher.git
synced 2025-07-16 07:46:31 +00:00
fix(GUI): duplicate drives in Windows (#790)
If a drive contains multiple partitions that Windows recognises and mounts, then `drivelist` will incorrectly display separate drive objects for each partition, causing `ngRepeat` to complain in the drive selector component. The issue was fixed by grouping the mountpoints of all recognised partitions in a single drive object, as we do with the other supported operating systems. After the fix, `drivelist` also removed its `name` property (since its now always equal to `device`), so some extra logic to compute an appropriate display name for the drive has been introduced to `DriveScannerService`. Fixes: https://github.com/resin-io/etcher/issues/720 See: https://github.com/resin-io-modules/drivelist/pull/100 Change-Type: patch Changelog-Entry: Fix duplicate drives in Windows. Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
This commit is contained in:
parent
a6624cc344
commit
bc985f08a9
@ -21,6 +21,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const Rx = require('rx');
|
const Rx = require('rx');
|
||||||
|
const os = require('os');
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const angular = require('angular');
|
const angular = require('angular');
|
||||||
const EventEmitter = require('events').EventEmitter;
|
const EventEmitter = require('events').EventEmitter;
|
||||||
@ -40,6 +41,18 @@ driveScanner.factory('DriveScannerService', (SettingsModel) => {
|
|||||||
return Rx.Observable.fromNodeCallback(drivelist.list)();
|
return Rx.Observable.fromNodeCallback(drivelist.list)();
|
||||||
})
|
})
|
||||||
.map((drives) => {
|
.map((drives) => {
|
||||||
|
|
||||||
|
// Calculate an appropriate "display name"
|
||||||
|
drives = _.map(drives, (drive) => {
|
||||||
|
drive.name = drive.device;
|
||||||
|
|
||||||
|
if (os.platform() === 'win32' && drive.mountpoint) {
|
||||||
|
drive.name = drive.mountpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
return drive;
|
||||||
|
});
|
||||||
|
|
||||||
if (SettingsModel.get('unsafeMode')) {
|
if (SettingsModel.get('unsafeMode')) {
|
||||||
return drives;
|
return drives;
|
||||||
}
|
}
|
||||||
|
56
npm-shrinkwrap.json
generated
56
npm-shrinkwrap.json
generated
@ -1153,14 +1153,14 @@
|
|||||||
"resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz"
|
"resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz"
|
||||||
},
|
},
|
||||||
"drivelist": {
|
"drivelist": {
|
||||||
"version": "3.3.4",
|
"version": "4.0.0",
|
||||||
"from": "drivelist@3.3.4",
|
"from": "drivelist@4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/drivelist/-/drivelist-3.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/drivelist/-/drivelist-4.0.0.tgz",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lodash": {
|
"lodash": {
|
||||||
"version": "3.10.1",
|
"version": "4.16.4",
|
||||||
"from": "lodash@>=3.0.1 <4.0.0",
|
"from": "lodash@>=4.16.4 <5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz"
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.16.4.tgz"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -3568,6 +3568,40 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"module-deps": {
|
||||||
|
"version": "4.0.8",
|
||||||
|
"from": "module-deps@>=4.0.8 <5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/module-deps/-/module-deps-4.0.8.tgz",
|
||||||
|
"dependencies": {
|
||||||
|
"isarray": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"from": "isarray@~1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
|
||||||
|
},
|
||||||
|
"readable-stream": {
|
||||||
|
"version": "2.1.5",
|
||||||
|
"from": "readable-stream@^2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz"
|
||||||
|
},
|
||||||
|
"through2": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"from": "through2@^2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.1.tgz",
|
||||||
|
"dependencies": {
|
||||||
|
"readable-stream": {
|
||||||
|
"version": "2.0.6",
|
||||||
|
"from": "readable-stream@>=2.0.0 <2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"xtend": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"from": "xtend@^4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"moment": {
|
"moment": {
|
||||||
"version": "2.13.0",
|
"version": "2.13.0",
|
||||||
"from": "moment@>=2.8.0 <3.0.0",
|
"from": "moment@>=2.8.0 <3.0.0",
|
||||||
@ -4304,6 +4338,11 @@
|
|||||||
"from": "bluebird@>=2.9.34 <3.0.0",
|
"from": "bluebird@>=2.9.34 <3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.10.2.tgz"
|
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.10.2.tgz"
|
||||||
},
|
},
|
||||||
|
"drivelist": {
|
||||||
|
"version": "3.3.4",
|
||||||
|
"from": "drivelist@>=3.1.0 <4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/drivelist/-/drivelist-3.3.4.tgz"
|
||||||
|
},
|
||||||
"lodash": {
|
"lodash": {
|
||||||
"version": "3.10.1",
|
"version": "3.10.1",
|
||||||
"from": "lodash@>=3.10.0 <4.0.0",
|
"from": "lodash@>=3.10.0 <4.0.0",
|
||||||
@ -4906,6 +4945,11 @@
|
|||||||
"from": "timers-browserify@>=1.0.1 <2.0.0",
|
"from": "timers-browserify@>=1.0.1 <2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz"
|
"resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz"
|
||||||
},
|
},
|
||||||
|
"tmp": {
|
||||||
|
"version": "0.0.28",
|
||||||
|
"from": "tmp@0.0.28",
|
||||||
|
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.28.tgz"
|
||||||
|
},
|
||||||
"tn1150": {
|
"tn1150": {
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"from": "tn1150@>=0.1.0 <0.2.0",
|
"from": "tn1150@>=0.1.0 <0.2.0",
|
||||||
|
@ -66,7 +66,7 @@
|
|||||||
"bluebird": "^3.0.5",
|
"bluebird": "^3.0.5",
|
||||||
"bootstrap-sass": "^3.3.5",
|
"bootstrap-sass": "^3.3.5",
|
||||||
"chalk": "^1.1.3",
|
"chalk": "^1.1.3",
|
||||||
"drivelist": "^3.3.4",
|
"drivelist": "^4.0.0",
|
||||||
"electron-is-running-in-asar": "^1.0.0",
|
"electron-is-running-in-asar": "^1.0.0",
|
||||||
"etcher-image-stream": "^5.1.0",
|
"etcher-image-stream": "^5.1.0",
|
||||||
"etcher-image-write": "^8.1.3",
|
"etcher-image-write": "^8.1.3",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const m = require('mochainon');
|
const m = require('mochainon');
|
||||||
|
const os = require('os');
|
||||||
const angular = require('angular');
|
const angular = require('angular');
|
||||||
const drivelist = require('drivelist');
|
const drivelist = require('drivelist');
|
||||||
require('angular-mocks');
|
require('angular-mocks');
|
||||||
@ -73,42 +74,29 @@ describe('Browser: DriveScanner', function() {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('given available drives', function() {
|
describe('given linux', function() {
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
this.drivesListStub = m.sinon.stub(drivelist, 'list');
|
this.osPlatformStub = m.sinon.stub(os, 'platform');
|
||||||
this.drivesListStub.yields(null, [
|
this.osPlatformStub.returns('linux');
|
||||||
{
|
|
||||||
device: '/dev/sda',
|
|
||||||
description: 'WDC WD10JPVX-75J',
|
|
||||||
size: '931.5G',
|
|
||||||
mountpoint: '/',
|
|
||||||
system: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
device: '/dev/sdb',
|
|
||||||
description: 'Foo',
|
|
||||||
size: '14G',
|
|
||||||
mountpoint: '/mnt/foo',
|
|
||||||
system: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
device: '/dev/sdc',
|
|
||||||
description: 'Bar',
|
|
||||||
size: '14G',
|
|
||||||
mountpoint: '/mnt/bar',
|
|
||||||
system: false
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function() {
|
afterEach(function() {
|
||||||
this.drivesListStub.restore();
|
this.osPlatformStub.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should emit the non removable drives', function(done) {
|
describe('given available drives', function() {
|
||||||
DriveScannerService.on('drives', function(drives) {
|
|
||||||
m.chai.expect(drives).to.deep.equal([
|
beforeEach(function() {
|
||||||
|
this.drivesListStub = m.sinon.stub(drivelist, 'list');
|
||||||
|
this.drivesListStub.yields(null, [
|
||||||
|
{
|
||||||
|
device: '/dev/sda',
|
||||||
|
description: 'WDC WD10JPVX-75J',
|
||||||
|
size: '931.5G',
|
||||||
|
mountpoint: '/',
|
||||||
|
system: true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
device: '/dev/sdb',
|
device: '/dev/sdb',
|
||||||
description: 'Foo',
|
description: 'Foo',
|
||||||
@ -124,12 +112,116 @@ describe('Browser: DriveScanner', function() {
|
|||||||
system: false
|
system: false
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
DriveScannerService.stop();
|
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
DriveScannerService.start();
|
afterEach(function() {
|
||||||
|
this.drivesListStub.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit the non removable drives', function(done) {
|
||||||
|
DriveScannerService.on('drives', function(drives) {
|
||||||
|
m.chai.expect(drives).to.deep.equal([
|
||||||
|
{
|
||||||
|
device: '/dev/sdb',
|
||||||
|
name: '/dev/sdb',
|
||||||
|
description: 'Foo',
|
||||||
|
size: '14G',
|
||||||
|
mountpoint: '/mnt/foo',
|
||||||
|
system: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
device: '/dev/sdc',
|
||||||
|
name: '/dev/sdc',
|
||||||
|
description: 'Bar',
|
||||||
|
size: '14G',
|
||||||
|
mountpoint: '/mnt/bar',
|
||||||
|
system: false
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
DriveScannerService.stop();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
DriveScannerService.start();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('given windows', function() {
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
this.osPlatformStub = m.sinon.stub(os, 'platform');
|
||||||
|
this.osPlatformStub.returns('win32');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function() {
|
||||||
|
this.osPlatformStub.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('given available drives', function() {
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
this.drivesListStub = m.sinon.stub(drivelist, 'list');
|
||||||
|
this.drivesListStub.yields(null, [
|
||||||
|
{
|
||||||
|
device: '\\\\.\\PHYSICALDRIVE1',
|
||||||
|
description: 'WDC WD10JPVX-75J',
|
||||||
|
size: '931.5G',
|
||||||
|
mountpoint: 'C:',
|
||||||
|
system: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
device: '\\\\.\\PHYSICALDRIVE2',
|
||||||
|
description: 'Foo',
|
||||||
|
size: '14G',
|
||||||
|
mountpoint: null,
|
||||||
|
system: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
device: '\\\\.\\PHYSICALDRIVE3',
|
||||||
|
description: 'Bar',
|
||||||
|
size: '14G',
|
||||||
|
mountpoint: 'F:',
|
||||||
|
system: false
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function() {
|
||||||
|
this.drivesListStub.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit the non removable drives', function(done) {
|
||||||
|
DriveScannerService.on('drives', function(drives) {
|
||||||
|
m.chai.expect(drives).to.deep.equal([
|
||||||
|
{
|
||||||
|
device: '\\\\.\\PHYSICALDRIVE2',
|
||||||
|
name: '\\\\.\\PHYSICALDRIVE2',
|
||||||
|
description: 'Foo',
|
||||||
|
size: '14G',
|
||||||
|
mountpoint: null,
|
||||||
|
system: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
device: '\\\\.\\PHYSICALDRIVE3',
|
||||||
|
name: 'F:',
|
||||||
|
description: 'Bar',
|
||||||
|
size: '14G',
|
||||||
|
mountpoint: 'F:',
|
||||||
|
system: false
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
DriveScannerService.stop();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
DriveScannerService.start();
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user