mirror of
https://github.com/balena-io/etcher.git
synced 2025-07-29 06:06:33 +00:00
refactor(GUI): make use of etcher-latest-version
(#544)
The code that performs an HTTP request to the S3 bucket where released are stored and determines which is the latest available version was extracted to a separate module called `etcher-latest-version`, mainly for the website to be able to re-use this functionality. See: https://github.com/resin-io-modules/etcher-latest-version Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
This commit is contained in:
parent
f277724749
commit
c434746a49
@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Resin.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const semver = require('semver');
|
||||
const xml = require('xml2js');
|
||||
|
||||
module.exports = function($q, $http, UPDATE_NOTIFIER_URL) {
|
||||
|
||||
/**
|
||||
* @summary Get the latest published Etcher version
|
||||
* @function
|
||||
* @public
|
||||
*
|
||||
* @description
|
||||
* This function performs its job by querying the publicily accessible
|
||||
* S3 bucket where we store the builds and uses the `node-semver` module
|
||||
* to determine which is the latest one.
|
||||
*
|
||||
* @fulfil {String} - latest version
|
||||
* @returns {Promise}
|
||||
*
|
||||
* @example
|
||||
* UpdateNotifierS3Service.getLatestVersion().then((latestVersion) => {
|
||||
* console.log('The latest version is: ' + latestVersion);
|
||||
* });
|
||||
*/
|
||||
this.getLatestVersion = () => {
|
||||
return $http.get(UPDATE_NOTIFIER_URL).then((response) => {
|
||||
return $q((resolve, reject) => {
|
||||
xml.parseString(response.data, (error, result) => {
|
||||
if (error) {
|
||||
return reject(error);
|
||||
}
|
||||
|
||||
const bucketEntries = result.ListBucketResult.Contents;
|
||||
return resolve(_.reduce(bucketEntries, (latest, entry) => {
|
||||
const version = _.chain(entry.Key)
|
||||
.first()
|
||||
.split('/')
|
||||
.nth(1)
|
||||
.value();
|
||||
|
||||
return semver.gt(version, latest) ? version : latest;
|
||||
|
||||
// This is a good accumulator default value since
|
||||
// every version is semantically greater than this.
|
||||
}, '0.0.0'));
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
};
|
@ -17,8 +17,40 @@
|
||||
'use strict';
|
||||
|
||||
const semver = require('semver');
|
||||
const etcherLatestVersion = require('etcher-latest-version');
|
||||
|
||||
module.exports = function($uibModal, UPDATE_NOTIFIER_SLEEP_TIME, ManifestBindService, UpdateNotifierS3Service, SettingsModel) {
|
||||
module.exports = function($uibModal, $http, $q, UPDATE_NOTIFIER_SLEEP_TIME, ManifestBindService, SettingsModel) {
|
||||
|
||||
/**
|
||||
* @summary Get the latest available Etcher version
|
||||
* @function
|
||||
* @private
|
||||
*
|
||||
* @fulfil {String} - latest version
|
||||
* @returns {Promise}
|
||||
*
|
||||
* @example
|
||||
* UpdateNotifierService.getLatestVersion().then((latestVersion) => {
|
||||
* console.log(`The latest version is: ${latestVersion}`);
|
||||
* });
|
||||
*/
|
||||
this.getLatestVersion = () => {
|
||||
return $q((resolve, reject) => {
|
||||
return etcherLatestVersion((url, callback) => {
|
||||
return $http.get(url).then((response) => {
|
||||
return callback(null, response.data);
|
||||
}).catch((error) => {
|
||||
return callback(error);
|
||||
});
|
||||
}, (error, latestVersion) => {
|
||||
if (error) {
|
||||
return reject(error);
|
||||
}
|
||||
|
||||
return resolve(latestVersion);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @summary Check if the current version is the latest version
|
||||
@ -36,7 +68,7 @@ module.exports = function($uibModal, UPDATE_NOTIFIER_SLEEP_TIME, ManifestBindSer
|
||||
* });
|
||||
*/
|
||||
this.isLatestVersion = () => {
|
||||
return UpdateNotifierS3Service.getLatestVersion().then((version) => {
|
||||
return this.getLatestVersion().then((version) => {
|
||||
return semver.gte(ManifestBindService.get('version'), version);
|
||||
});
|
||||
};
|
||||
|
@ -29,10 +29,8 @@ const UpdateNotifier = angular.module(MODULE_NAME, [
|
||||
require('../../os/open-external/open-external')
|
||||
]);
|
||||
|
||||
UpdateNotifier.constant('UPDATE_NOTIFIER_URL', 'https://resin-production-downloads.s3.amazonaws.com');
|
||||
UpdateNotifier.constant('UPDATE_NOTIFIER_SLEEP_TIME', 7 * 24 * 60 * 60 * 100);
|
||||
UpdateNotifier.controller('UpdateNotifierController', require('./controllers/update-notifier'));
|
||||
UpdateNotifier.service('UpdateNotifierService', require('./services/update-notifier'));
|
||||
UpdateNotifier.service('UpdateNotifierS3Service', require('./services/update-notifier-s3'));
|
||||
|
||||
module.exports = MODULE_NAME;
|
||||
|
12
npm-shrinkwrap.json
generated
12
npm-shrinkwrap.json
generated
@ -1551,6 +1551,18 @@
|
||||
"from": "etcher-image-write@>=5.0.2 <6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/etcher-image-write/-/etcher-image-write-5.0.2.tgz"
|
||||
},
|
||||
"etcher-latest-version": {
|
||||
"version": "1.0.0",
|
||||
"from": "etcher-latest-version@latest",
|
||||
"resolved": "https://registry.npmjs.org/etcher-latest-version/-/etcher-latest-version-1.0.0.tgz",
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "5.2.0",
|
||||
"from": "semver@>=5.2.0 <6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.2.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"event-emitter": {
|
||||
"version": "0.3.4",
|
||||
"from": "event-emitter@>=0.3.4 <0.4.0",
|
||||
|
@ -69,6 +69,7 @@
|
||||
"electron-is-running-in-asar": "^1.0.0",
|
||||
"etcher-image-stream": "^2.2.0",
|
||||
"etcher-image-write": "^5.0.2",
|
||||
"etcher-latest-version": "^1.0.0",
|
||||
"file-tail": "^0.3.0",
|
||||
"flexboxgrid": "^6.3.0",
|
||||
"immutable": "^3.8.1",
|
||||
@ -87,7 +88,6 @@
|
||||
"trackjs": "^2.1.16",
|
||||
"umount": "^1.1.3",
|
||||
"username": "^2.1.0",
|
||||
"xml2js": "^0.4.16",
|
||||
"yargs": "^4.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -101,16 +101,6 @@ describe('Browser: UpdateNotifier', function() {
|
||||
let UpdateNotifierService;
|
||||
let ManifestBindService;
|
||||
|
||||
beforeEach(function() {
|
||||
angular.mock.module(function($provide) {
|
||||
$provide.value('UpdateNotifierS3Service', {
|
||||
getLatestVersion: function() {
|
||||
return $q.resolve(ManifestBindService.get('version'));
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(angular.mock.inject(function(_$q_, _$rootScope_, _UpdateNotifierService_, _ManifestBindService_) {
|
||||
$q = _$q_;
|
||||
$rootScope = _$rootScope_;
|
||||
@ -118,6 +108,15 @@ describe('Browser: UpdateNotifier', function() {
|
||||
ManifestBindService = _ManifestBindService_;
|
||||
}));
|
||||
|
||||
beforeEach(function() {
|
||||
this.getLatestVersionStub = m.sinon.stub(UpdateNotifierService, 'getLatestVersion');
|
||||
this.getLatestVersionStub.returns($q.resolve(ManifestBindService.get('version')));
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
this.getLatestVersionStub.restore();
|
||||
});
|
||||
|
||||
it('should resolve true', function() {
|
||||
let result = null;
|
||||
|
||||
@ -137,22 +136,21 @@ describe('Browser: UpdateNotifier', function() {
|
||||
let $rootScope;
|
||||
let UpdateNotifierService;
|
||||
|
||||
beforeEach(function() {
|
||||
angular.mock.module(function($provide) {
|
||||
$provide.value('UpdateNotifierS3Service', {
|
||||
getLatestVersion: function() {
|
||||
return $q.resolve('99999.9.9');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(angular.mock.inject(function(_$q_, _$rootScope_, _UpdateNotifierService_) {
|
||||
$q = _$q_;
|
||||
$rootScope = _$rootScope_;
|
||||
UpdateNotifierService = _UpdateNotifierService_;
|
||||
}));
|
||||
|
||||
beforeEach(function() {
|
||||
this.getLatestVersionStub = m.sinon.stub(UpdateNotifierService, 'getLatestVersion');
|
||||
this.getLatestVersionStub.returns($q.resolve('99999.9.9'));
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
this.getLatestVersionStub.restore();
|
||||
});
|
||||
|
||||
it('should resolve false', function() {
|
||||
let result = null;
|
||||
|
||||
@ -172,22 +170,21 @@ describe('Browser: UpdateNotifier', function() {
|
||||
let $rootScope;
|
||||
let UpdateNotifierService;
|
||||
|
||||
beforeEach(function() {
|
||||
angular.mock.module(function($provide) {
|
||||
$provide.value('UpdateNotifierS3Service', {
|
||||
getLatestVersion: function() {
|
||||
return $q.resolve('0.0.0');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(angular.mock.inject(function(_$q_, _$rootScope_, _UpdateNotifierService_) {
|
||||
$q = _$q_;
|
||||
$rootScope = _$rootScope_;
|
||||
UpdateNotifierService = _UpdateNotifierService_;
|
||||
}));
|
||||
|
||||
beforeEach(function() {
|
||||
this.getLatestVersionStub = m.sinon.stub(UpdateNotifierService, 'getLatestVersion');
|
||||
this.getLatestVersionStub.returns($q.resolve('0.0.0'));
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
this.getLatestVersionStub.restore();
|
||||
});
|
||||
|
||||
it('should resolve true', function() {
|
||||
let result = null;
|
||||
|
||||
@ -205,120 +202,4 @@ describe('Browser: UpdateNotifier', function() {
|
||||
|
||||
});
|
||||
|
||||
describe('UpdateNotifierS3Service', function() {
|
||||
|
||||
let UpdateNotifierS3Service;
|
||||
let $rootScope;
|
||||
|
||||
beforeEach(angular.mock.inject(function(_$rootScope_, _UpdateNotifierS3Service_) {
|
||||
$rootScope = _$rootScope_;
|
||||
UpdateNotifierS3Service = _UpdateNotifierS3Service_;
|
||||
}));
|
||||
|
||||
describe('given a mocked S3 XML response', function() {
|
||||
|
||||
let $httpBackend;
|
||||
let UPDATE_NOTIFIER_URL;
|
||||
|
||||
beforeEach(angular.mock.inject(function($injector) {
|
||||
$httpBackend = $injector.get('$httpBackend');
|
||||
UPDATE_NOTIFIER_URL = $injector.get('UPDATE_NOTIFIER_URL');
|
||||
|
||||
$httpBackend.whenGET(UPDATE_NOTIFIER_URL).respond(`
|
||||
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
|
||||
<Name>resin-production-downloads</Name>
|
||||
<Prefix/>
|
||||
<Marker/>
|
||||
<MaxKeys>1000</MaxKeys>
|
||||
<IsTruncated>false</IsTruncated>
|
||||
<Contents>
|
||||
<Key>etcher/1.0.0-beta.0/Etcher-darwin-x64.dmg</Key>
|
||||
<LastModified>2016-03-10T17:34:21.000Z</LastModified>
|
||||
<ETag>"5a715255aa25686688bf1e23bc1d3fc6"</ETag>
|
||||
<Size>46109720</Size>
|
||||
<StorageClass>STANDARD</StorageClass>
|
||||
</Contents>
|
||||
<Contents>
|
||||
<Key>etcher/1.0.0-beta.1/Etcher-darwin-x64.dmg</Key>
|
||||
<LastModified>2016-04-08T20:12:03.000Z</LastModified>
|
||||
<ETag>"cc1d6d9d53385e3edd099416fcd894c1"</ETag>
|
||||
<Size>47071474</Size>
|
||||
<StorageClass>STANDARD</StorageClass>
|
||||
</Contents>
|
||||
<Contents>
|
||||
<Key>etcher/1.0.0-beta.2/Etcher-darwin-x64.dmg</Key>
|
||||
<LastModified>2016-04-08T19:03:18.000Z</LastModified>
|
||||
<ETag>"5f1849f7781197ce2ee6129c16bcd498"</ETag>
|
||||
<Size>48650090</Size>
|
||||
<StorageClass>STANDARD</StorageClass>
|
||||
</Contents>
|
||||
<Contents>
|
||||
<Key>etcher/1.0.0-beta.3/Etcher-darwin-x64.dmg</Key>
|
||||
<LastModified>2016-04-18T01:32:09.000Z</LastModified>
|
||||
<ETag>"c173895886f44d115c66e7206ce3dff8"</ETag>
|
||||
<Size>50585335</Size>
|
||||
<StorageClass>STANDARD</StorageClass>
|
||||
</Contents>
|
||||
<Contents>
|
||||
<Key>etcher/1.0.0-beta.3/Etcher-darwin-x64.zip</Key>
|
||||
<LastModified>2016-04-18T01:42:37.000Z</LastModified>
|
||||
<ETag>"e9f6e957e65373b232530215d98df141"</ETag>
|
||||
<Size>129327442</Size>
|
||||
<StorageClass>STANDARD</StorageClass>
|
||||
</Contents>
|
||||
<Contents>
|
||||
<Key>etcher/1.0.0-beta.4/Etcher-darwin-x64.dmg</Key>
|
||||
<LastModified>2016-04-22T17:29:49.000Z</LastModified>
|
||||
<ETag>"bccb0024c58747a9b7516cbdfc5a7ecb"</ETag>
|
||||
<Size>55240852</Size>
|
||||
<StorageClass>STANDARD</StorageClass>
|
||||
</Contents>
|
||||
<Contents>
|
||||
<Key>etcher/1.0.0-beta.4/Etcher-darwin-x64.zip</Key>
|
||||
<LastModified>2016-04-22T17:43:27.000Z</LastModified>
|
||||
<ETag>"c93e26e68b3c4f2b7e8e88e6befc8e64"</ETag>
|
||||
<Size>135443284</Size>
|
||||
<StorageClass>STANDARD</StorageClass>
|
||||
</Contents>
|
||||
<Contents>
|
||||
<Key>etcher/1.0.0-beta.5/Etcher-darwin-x64.dmg</Key>
|
||||
<LastModified>2016-05-04T08:27:11.000Z</LastModified>
|
||||
<ETag>"fb596bfdb8bbaf09807b5fc4a940ce14"</ETag>
|
||||
<Size>77757305</Size>
|
||||
<StorageClass>STANDARD</StorageClass>
|
||||
</Contents>
|
||||
<Contents>
|
||||
<Key>etcher/1.0.0-beta.5/Etcher-darwin-x64.zip</Key>
|
||||
<LastModified>2016-05-04T08:39:56.000Z</LastModified>
|
||||
<ETag>"3f11c1b6f06644f9ceb2aea4b1947fdf"</ETag>
|
||||
<Size>157933876</Size>
|
||||
<StorageClass>STANDARD</StorageClass>
|
||||
</Contents>
|
||||
</ListBucketResult>
|
||||
`);
|
||||
}));
|
||||
|
||||
afterEach(function() {
|
||||
$httpBackend.verifyNoOutstandingExpectation();
|
||||
$httpBackend.verifyNoOutstandingRequest();
|
||||
});
|
||||
|
||||
it('should resolve the latest version', function() {
|
||||
$httpBackend.expectGET(UPDATE_NOTIFIER_URL);
|
||||
|
||||
let latestVersion = null;
|
||||
UpdateNotifierS3Service.getLatestVersion().then(function(result) {
|
||||
latestVersion = result;
|
||||
});
|
||||
|
||||
$rootScope.$apply();
|
||||
$httpBackend.flush();
|
||||
|
||||
m.chai.expect(latestVersion).to.equal('1.0.0-beta.5');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user