mirror of
https://github.com/balena-io/etcher.git
synced 2025-07-19 01:06:36 +00:00
refactor(GUI): integrate etcher-latest-version
into the main repo (#1183)
`etcher-latest-version` was kept in a separate repository in order to re-use it with the Etcher website, however the Etcher website is not using it at all, and we're moving towards having the website in the main repository. Therefore, this commit brings back the logic from `etcher-latest-version`, but introduces it as `lib/shared/s3-packages.js`, in order to not tie ourselves to the AngularJS framework, and as a step towards the Etcher SDK. As a nice little bonus, this commit adds support for an `ETCHER_FAKE_S3_LATEST_VERSION` environment variable that can be used to trick Etcher that there is an available update, and therefore show the update notifier modal. Also, this commit adds support for snapshot builds update-checks, by checking the `resin-nightly-downloads` S3 bucket if the current version contains a git commit hash build number. If the version is not a production release, then the update notifier modal doesn't present the checkbox to disable update notifications for X days. We also add a property called `updates.semverRange` to `package.json`, which can be used to fine control which versions are considered as candidates for an update notification. This commit adds a setting called `includeUnstableChannel`, which can be used to tweak whether unstable (beta) releases are considered or not when checking for the latest available version. See: https://github.com/resin-io-modules/etcher-latest-version Fixes: https://github.com/resin-io/etcher/issues/953 Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
This commit is contained in:
parent
9acebda035
commit
d3b35742a6
@ -18,6 +18,8 @@ Preparing a new version
|
||||
- Re-take `screenshot.png` so it displays the latest version in the bottom
|
||||
right corner.
|
||||
|
||||
- Revise the `updates.semverRange` version in `package.json`
|
||||
|
||||
- Commit the changes with the version number as the commit title, including the
|
||||
`v` prefix, to `master`. For example:
|
||||
|
||||
|
@ -4,6 +4,48 @@ Publishing Etcher
|
||||
This is a small guide to package and publish Etcher to all supported operating
|
||||
systems.
|
||||
|
||||
Release Types
|
||||
-------------
|
||||
|
||||
Etcher supports **production** and **snapshot** release types. Each is
|
||||
published to a different S3 bucket, and production release types are code
|
||||
signed, while snapshot release types aren't and include a short git commit-hash
|
||||
as a build number. For example, `1.0.0-beta.19` is a production release type,
|
||||
while `1.0.0-beta.19+531ab82` is a snapshot release type.
|
||||
|
||||
In terms of comparison: `1.0.0-beta.19` (production) < `1.0.0-beta.19+531ab82`
|
||||
(snapshot) < `1.0.0-rc.1` (production) < `1.0.0-rc.1+7fde24a` (snapshot) <
|
||||
`1.0.0` (production) < `1.0.0+2201e5f` (snapshot). Keep in mind that if you're
|
||||
running a production release type, you'll only be prompted to update to
|
||||
production release types, and if you're running a snapshot release type, you'll
|
||||
only be prompted to update to other snapshot release types.
|
||||
|
||||
The build system creates (and publishes) snapshot release types by default, but
|
||||
you can build a specific release type by setting the `RELEASE_TYPE` make
|
||||
variable. For example:
|
||||
|
||||
```sh
|
||||
make <target> RELEASE_TYPE=snapshot
|
||||
make <target> RELEASE_TYPE=production
|
||||
```
|
||||
|
||||
We can control the version range a specific Etcher version will consider when
|
||||
showing the update notification dialog by tweaking the `updates.semverRange`
|
||||
property of `package.json`.
|
||||
|
||||
Update Channels
|
||||
---------------
|
||||
|
||||
Etcher has a setting to include the unstable update channel. If this option is
|
||||
set, Etcher will consider both stable and unstable versions when showing the
|
||||
update notifier dialog. Unstable versions are the ones that contain a `beta`
|
||||
pre-release tag. For example:
|
||||
|
||||
- Production unstable version: `1.4.0-beta.1`
|
||||
- Snapshot unstable version: `1.4.0-beta.1+7fde24a`
|
||||
- Production stable version: `1.4.0`
|
||||
- Snapshot stable version: `1.4.0+7fde24a`
|
||||
|
||||
Signing
|
||||
-------
|
||||
|
||||
@ -29,40 +71,31 @@ employee by asking for it from the relevant people.
|
||||
Packaging
|
||||
---------
|
||||
|
||||
The resulting installers will be saved to `release/out`.
|
||||
|
||||
Run the following commands:
|
||||
|
||||
### OS X
|
||||
|
||||
Run the following command:
|
||||
|
||||
```sh
|
||||
make electron-installer-dmg
|
||||
make electron-installer-app-zip
|
||||
```
|
||||
|
||||
The resulting installers will be saved to `release/out`.
|
||||
|
||||
### GNU/Linux
|
||||
|
||||
Run the following command:
|
||||
|
||||
```sh
|
||||
make electron-installer-appimage
|
||||
make electron-installer-debian
|
||||
```
|
||||
|
||||
The resulting installers will be saved to `release/out`.
|
||||
|
||||
### Windows
|
||||
|
||||
Run the following command:
|
||||
|
||||
```sh
|
||||
make electron-installer-zip
|
||||
make electron-installer-nsis
|
||||
```
|
||||
|
||||
The resulting installers will be saved to `etcher-release/installers`.
|
||||
|
||||
Publishing to Bintray
|
||||
---------------------
|
||||
|
||||
@ -76,7 +109,7 @@ Make sure you set the following environment variables:
|
||||
Run the following command:
|
||||
|
||||
```sh
|
||||
make publish-bintray-debian RELEASE_TYPE=<production|snapshot>
|
||||
make publish-bintray-debian
|
||||
```
|
||||
|
||||
Publishing to S3
|
||||
@ -91,7 +124,7 @@ Run the following command to publish all files for the current combination of
|
||||
_platform_ and _arch_ (building them if necessary):
|
||||
|
||||
```sh
|
||||
make publish-aws-s3 RELEASE_TYPE=<production|snapshot>
|
||||
make publish-aws-s3
|
||||
```
|
||||
|
||||
Also add links to each AWS S3 file in [GitHub Releases][github-releases]. See
|
||||
|
@ -149,6 +149,21 @@ In Windows:
|
||||
set ETCHER_DISABLE_UPDATES=1
|
||||
```
|
||||
|
||||
Simulate an update alert
|
||||
------------------------
|
||||
|
||||
You can set the `ETCHER_FAKE_S3_LATEST_VERSION` environment variable to a valid
|
||||
semver version (greater than the current version) to trick the application into
|
||||
thinking that what you put there is the latest available version, therefore
|
||||
causing the update notification dialog to be presented at startup.
|
||||
|
||||
Note that the value of the variable will be ignored if it doesn't match the
|
||||
release type of the current application version. For example, setting the
|
||||
variable to a production version (e.g. `ETCHER_FAKE_S3_LATEST_VERSION=2.0.0`)
|
||||
will be ignored if you're running a snapshot build, and vice-versa.
|
||||
|
||||
See [`PUBLISHING.md`][publishing] for more details about release types.
|
||||
|
||||
Recovering broken drives
|
||||
------------------------
|
||||
|
||||
@ -223,6 +238,7 @@ platforms.
|
||||
[electron]: http://electron.atom.io
|
||||
[electron-supported-platforms]: https://github.com/electron/electron/blob/master/docs/tutorial/supported-platforms.md
|
||||
[etcher-cli]: https://github.com/resin-io/etcher/blob/master/docs/CLI.md
|
||||
[publishing]: https://github.com/resin-io/etcher/blob/master/docs/PUBLISHING.md
|
||||
[windows-usb-tool]: https://www.microsoft.com/en-us/download/windows-usb-dvd-download-tool
|
||||
[rufus]: https://rufus.akeo.ie
|
||||
[unetbootin]: https://unetbootin.github.io
|
||||
|
@ -28,10 +28,15 @@ var angular = require('angular');
|
||||
|
||||
const electron = require('electron');
|
||||
const Bluebird = require('bluebird');
|
||||
const semver = require('semver');
|
||||
const _ = require('lodash');
|
||||
const EXIT_CODES = require('../shared/exit-codes');
|
||||
const messages = require('../shared/messages');
|
||||
const s3Packages = require('../shared/s3-packages');
|
||||
const release = require('../shared/release');
|
||||
const packageJSON = require('../../package.json');
|
||||
const flashState = require('./models/flash-state');
|
||||
const settings = require('./models/settings');
|
||||
const windowProgress = require('./os/window-progress');
|
||||
|
||||
const Store = require('./models/store');
|
||||
@ -86,23 +91,40 @@ app.run(() => {
|
||||
app.run((AnalyticsService, ErrorService, UpdateNotifierService, SelectionStateModel) => {
|
||||
AnalyticsService.logEvent('Application start');
|
||||
|
||||
const shouldCheckForUpdates = UpdateNotifierService.shouldCheckForUpdates();
|
||||
const currentVersion = packageJSON.version;
|
||||
const currentReleaseType = release.getReleaseType(currentVersion);
|
||||
const shouldCheckForUpdates = UpdateNotifierService.shouldCheckForUpdates({
|
||||
ignoreSleepUpdateCheck: currentReleaseType !== release.RELEASE_TYPE.PRODUCTION
|
||||
});
|
||||
|
||||
if (!shouldCheckForUpdates || process.env.ETCHER_DISABLE_UPDATES) {
|
||||
if (_.some([
|
||||
!shouldCheckForUpdates,
|
||||
process.env.ETCHER_DISABLE_UPDATES,
|
||||
currentReleaseType === release.RELEASE_TYPE.UNKNOWN
|
||||
])) {
|
||||
AnalyticsService.logEvent('Not checking for updates', {
|
||||
shouldCheckForUpdates,
|
||||
disableUpdatesEnvironmentVariable: process.env.ETCHER_DISABLE_UPDATES
|
||||
disableUpdatesEnvironmentVariable: process.env.ETCHER_DISABLE_UPDATES,
|
||||
releaseType: currentReleaseType
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const updateSemverRange = packageJSON.updates.semverRange;
|
||||
const includeUnstableChannel = settings.get('includeUnstableUpdateChannel');
|
||||
|
||||
AnalyticsService.logEvent('Checking for updates', {
|
||||
currentVersion: packageJSON.version
|
||||
currentVersion,
|
||||
releaseType: currentReleaseType,
|
||||
updateSemverRange,
|
||||
includeUnstableChannel
|
||||
});
|
||||
|
||||
UpdateNotifierService.isLatestVersion().then((isLatestVersion) => {
|
||||
|
||||
if (isLatestVersion) {
|
||||
s3Packages.getLatestVersion(currentReleaseType, {
|
||||
range: updateSemverRange,
|
||||
includeUnstableChannel
|
||||
}).then((latestVersion) => {
|
||||
if (semver.gte(currentVersion, latestVersion || '0.0.0')) {
|
||||
AnalyticsService.logEvent('Update notification skipped', {
|
||||
reason: 'Latest version'
|
||||
});
|
||||
@ -121,12 +143,14 @@ app.run((AnalyticsService, ErrorService, UpdateNotifierService, SelectionStateMo
|
||||
return Bluebird.resolve();
|
||||
}
|
||||
|
||||
AnalyticsService.logEvent('Notifying update');
|
||||
|
||||
return UpdateNotifierService.notify();
|
||||
AnalyticsService.logEvent('Notifying update', {
|
||||
latestVersion
|
||||
});
|
||||
|
||||
return UpdateNotifierService.notify(latestVersion, {
|
||||
allowSleepUpdateCheck: currentReleaseType === release.RELEASE_TYPE.PRODUCTION
|
||||
});
|
||||
}).catch(ErrorService.reportException);
|
||||
|
||||
});
|
||||
|
||||
app.run((AnalyticsService) => {
|
||||
|
@ -17,104 +17,35 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const semver = require('semver');
|
||||
const etcherLatestVersion = require('etcher-latest-version');
|
||||
const units = require('../../../../shared/units');
|
||||
const settings = require('../../../models/settings');
|
||||
|
||||
module.exports = function($http, $q, ModalService, UPDATE_NOTIFIER_SLEEP_DAYS, ManifestBindService) {
|
||||
module.exports = function(ModalService, UPDATE_NOTIFIER_SLEEP_DAYS) {
|
||||
|
||||
/**
|
||||
* @summary The current application version
|
||||
* @constant
|
||||
* @private
|
||||
* @type {String}
|
||||
*/
|
||||
const CURRENT_VERSION = ManifestBindService.get('version');
|
||||
|
||||
/**
|
||||
* @summary Get the latest available Etcher version
|
||||
* @function
|
||||
* @private
|
||||
* @description
|
||||
* We assume the received latest version number will not increase
|
||||
* while Etcher is running and memoize it
|
||||
*
|
||||
* @fulfil {String} - latest version
|
||||
* @returns {Promise}
|
||||
*
|
||||
* @example
|
||||
* UpdateNotifierService.getLatestVersion().then((latestVersion) => {
|
||||
* console.log(`The latest version is: ${latestVersion}`);
|
||||
* });
|
||||
*/
|
||||
this.getLatestVersion = _.memoize(() => {
|
||||
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) {
|
||||
|
||||
// The error status equals this number if the request
|
||||
// couldn't be made successfully, for example, because
|
||||
// of a timeout on an unstable network connection.
|
||||
const ERROR_CODE_UNSUCCESSFUL_REQUEST = -1;
|
||||
|
||||
if (error.status === ERROR_CODE_UNSUCCESSFUL_REQUEST) {
|
||||
return resolve(CURRENT_VERSION);
|
||||
}
|
||||
|
||||
return reject(error);
|
||||
}
|
||||
|
||||
return resolve(latestVersion);
|
||||
});
|
||||
});
|
||||
|
||||
// Arbitrary identifier for the memoization function
|
||||
}, _.constant('latest-version'));
|
||||
|
||||
/**
|
||||
* @summary Check if the current version is the latest version
|
||||
* @function
|
||||
* @public
|
||||
*
|
||||
* @fulfil {Boolean} - is latest version
|
||||
* @returns {Promise}
|
||||
*
|
||||
* @example
|
||||
* UpdateNotifierService.isLatestVersion().then((isLatestVersion) => {
|
||||
* if (!isLatestVersion) {
|
||||
* console.log('There is an update available');
|
||||
* }
|
||||
* });
|
||||
*/
|
||||
this.isLatestVersion = () => {
|
||||
return this.getLatestVersion().then((version) => {
|
||||
return semver.gte(CURRENT_VERSION, version);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @summary Determine if its time to check for updates
|
||||
* @summary Determine if it's time to check for updates
|
||||
* @function
|
||||
* @public
|
||||
*
|
||||
* @param {Object} [options] - options
|
||||
* @param {Boolean} [options.ignoreSleepUpdateCheck] - ignore sleep update check
|
||||
* @returns {Boolean} should check for updates
|
||||
*
|
||||
* @example
|
||||
* if (UpdateNotifierService.shouldCheckForUpdates()) {
|
||||
* if (UpdateNotifierService.shouldCheckForUpdates({
|
||||
* ignoreSleepUpdateCheck: false
|
||||
* })) {
|
||||
* console.log('We should check for updates!');
|
||||
* }
|
||||
*/
|
||||
this.shouldCheckForUpdates = () => {
|
||||
this.shouldCheckForUpdates = (options = {}) => {
|
||||
const lastUpdateNotify = settings.get('lastUpdateNotify');
|
||||
|
||||
if (!settings.get('sleepUpdateCheck') || !lastUpdateNotify) {
|
||||
if (_.some([
|
||||
!settings.get('sleepUpdateCheck'),
|
||||
!lastUpdateNotify,
|
||||
_.get(options, [ 'ignoreSleepUpdateCheck' ], false)
|
||||
])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -131,24 +62,28 @@ module.exports = function($http, $q, ModalService, UPDATE_NOTIFIER_SLEEP_DAYS, M
|
||||
* @function
|
||||
* @public
|
||||
*
|
||||
* @param {String} version - version
|
||||
* @param {Object} [options] - options
|
||||
* @param {Boolean} [options.allowSleepUpdateCheck=true] - allow sleeping the update check
|
||||
* @returns {Promise}
|
||||
*
|
||||
* @example
|
||||
* UpdateNotifierService.notify();
|
||||
* UpdateNotifierService.notify('1.0.0-beta.16', {
|
||||
* allowSleepUpdateCheck: true
|
||||
* });
|
||||
*/
|
||||
this.notify = () => {
|
||||
return this.getLatestVersion().then((version) => {
|
||||
return ModalService.open({
|
||||
template: './components/update-notifier/templates/update-notifier-modal.tpl.html',
|
||||
controller: 'UpdateNotifierController as modal',
|
||||
size: 'update-notifier',
|
||||
resolve: {
|
||||
options: _.constant({
|
||||
version
|
||||
})
|
||||
}
|
||||
}).result;
|
||||
});
|
||||
this.notify = (version, options = {}) => {
|
||||
return ModalService.open({
|
||||
template: './components/update-notifier/templates/update-notifier-modal.tpl.html',
|
||||
controller: 'UpdateNotifierController as modal',
|
||||
size: 'update-notifier',
|
||||
resolve: {
|
||||
options: _.constant({
|
||||
version,
|
||||
allowSleepUpdateCheck: _.get(options, [ 'allowSleepUpdateCheck' ], true)
|
||||
})
|
||||
}
|
||||
}).result;
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -6,7 +6,7 @@
|
||||
<div class="modal-body">
|
||||
<p>Etcher {{ ::modal.options.version }} is available for download</p>
|
||||
|
||||
<div class="checkbox">
|
||||
<div class="checkbox" ng-if="modal.options.allowSleepUpdateCheck">
|
||||
<label>
|
||||
<input type="checkbox"
|
||||
ng-model="modal.sleepUpdateCheck"
|
||||
|
@ -24,7 +24,6 @@ const angular = require('angular');
|
||||
const MODULE_NAME = 'Etcher.Components.UpdateNotifier';
|
||||
const UpdateNotifier = angular.module(MODULE_NAME, [
|
||||
require('../modal/modal'),
|
||||
require('../../utils/manifest-bind/manifest-bind'),
|
||||
require('../../os/open-external/open-external'),
|
||||
require('../../modules/analytics')
|
||||
]);
|
||||
|
@ -6586,7 +6586,7 @@ body {
|
||||
|
||||
.page-settings .subtitle {
|
||||
color: #fff;
|
||||
margin-top: 30px;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 15px; }
|
||||
|
||||
/*
|
||||
|
@ -23,7 +23,9 @@ const persistState = require('redux-localstorage');
|
||||
const uuidV4 = require('uuid/v4');
|
||||
const constraints = require('../../shared/drive-constraints');
|
||||
const errors = require('../../shared/errors');
|
||||
const release = require('../../shared/release');
|
||||
const fileExtensions = require('../../shared/file-extensions');
|
||||
const packageJSON = require('../../../package.json');
|
||||
|
||||
/**
|
||||
* @summary Application default state
|
||||
@ -46,6 +48,7 @@ const DEFAULT_STATE = Immutable.fromJS({
|
||||
unmountOnSuccess: true,
|
||||
validateWriteOnSuccess: true,
|
||||
sleepUpdateCheck: false,
|
||||
includeUnstableUpdateChannel: !release.isStableRelease(packageJSON.version),
|
||||
lastUpdateNotify: null
|
||||
}
|
||||
});
|
||||
|
@ -28,6 +28,6 @@
|
||||
|
||||
.page-settings .subtitle {
|
||||
color: $palette-theme-dark-foreground;
|
||||
margin-top: 30px;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
@ -40,6 +40,16 @@
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox"
|
||||
ng-model="settings.currentData.includeUnstableUpdateChannel"
|
||||
ng-change="settings.toggle('includeUnstableUpdateChannel')">
|
||||
|
||||
<span>Include unstable update channel</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<h3 class="subtitle">Advanced</h3>
|
||||
|
||||
<div class="checkbox">
|
||||
|
103
lib/shared/release.js
Normal file
103
lib/shared/release.js
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2017 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');
|
||||
|
||||
/**
|
||||
* @summary Application release types
|
||||
* @namespace RELEASE_TYPE
|
||||
* @public
|
||||
*/
|
||||
exports.RELEASE_TYPE = {
|
||||
|
||||
/**
|
||||
* @property {String} PRODUCTION
|
||||
* @memberof RELEASE_TYPE
|
||||
* @description
|
||||
* Production release type
|
||||
*/
|
||||
PRODUCTION: 'PRODUCTION',
|
||||
|
||||
/**
|
||||
* @property {String} SNAPSHOT
|
||||
* @memberof RELEASE_TYPE
|
||||
* @description
|
||||
* Snapshot release type
|
||||
*/
|
||||
SNAPSHOT: 'SNAPSHOT',
|
||||
|
||||
/**
|
||||
* @property {String} UNKNOWN
|
||||
* @memberof RELEASE_TYPE
|
||||
* @description
|
||||
* Unknown release type
|
||||
*/
|
||||
UNKNOWN: 'UNKNOWN'
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @summary Get the release type from a version string
|
||||
* @function
|
||||
* @public
|
||||
*
|
||||
* @param {String} version - application version
|
||||
* @returns {RELEASE_TYPE} release type
|
||||
*
|
||||
* @example
|
||||
* const version = require('../../package.json').version;
|
||||
* const releaseType = release.getReleaseType(version);
|
||||
*
|
||||
* if (releaseType === release.RELEASE_TYPE.PRODUCTION) {
|
||||
* console.log('This is a production release!');
|
||||
* }
|
||||
*/
|
||||
exports.getReleaseType = (version) => {
|
||||
const GIT_HASH_REGEX = /^[0-9a-f]{7,40}$/;
|
||||
const buildNumber = _.get(semver.parse(version), [ 'build' ]);
|
||||
|
||||
if (!_.isNil(buildNumber)) {
|
||||
if (_.isEmpty(buildNumber)) {
|
||||
return exports.RELEASE_TYPE.PRODUCTION;
|
||||
}
|
||||
|
||||
if (GIT_HASH_REGEX.test(_.first(buildNumber))) {
|
||||
return exports.RELEASE_TYPE.SNAPSHOT;
|
||||
}
|
||||
}
|
||||
|
||||
return exports.RELEASE_TYPE.UNKNOWN;
|
||||
};
|
||||
|
||||
/**
|
||||
* @summary Check if a version is a stable release
|
||||
* @function
|
||||
* @public
|
||||
*
|
||||
* @param {String} version - version
|
||||
* @returns {Boolean} whether the version is a stable release
|
||||
*
|
||||
* @example
|
||||
* if (release.isStableRelease('1.0.0')) {
|
||||
* console.log('This is a stable release');
|
||||
* }
|
||||
*/
|
||||
exports.isStableRelease = (version) => {
|
||||
return _.isEmpty(_.get(semver.parse(version), [ 'prerelease' ]));
|
||||
};
|
245
lib/shared/s3-packages.js
Normal file
245
lib/shared/s3-packages.js
Normal file
@ -0,0 +1,245 @@
|
||||
/*
|
||||
* Copyright 2017 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 Bluebird = require('bluebird');
|
||||
const request = Bluebird.promisifyAll(require('request'));
|
||||
const xml = Bluebird.promisifyAll(require('xml2js'));
|
||||
const release = require('./release');
|
||||
|
||||
/**
|
||||
* @summary Etcher S3 bucket URLs
|
||||
* @namespace BUCKET_URL
|
||||
* @public
|
||||
*/
|
||||
exports.BUCKET_URL = {
|
||||
|
||||
/**
|
||||
* @property {String} PRODUCTION
|
||||
* @memberof BUCKET_URL
|
||||
* @description
|
||||
* Etcher production S3 bucket URL
|
||||
*/
|
||||
PRODUCTION: 'https://resin-production-downloads.s3.amazonaws.com',
|
||||
|
||||
/**
|
||||
* @property {String} SNAPSHOT
|
||||
* @memberof BUCKET_URL
|
||||
* @description
|
||||
* Etcher snapshot S3 bucket URL
|
||||
*/
|
||||
SNAPSHOT: 'https://resin-nightly-downloads.s3.amazonaws.com'
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @summary Etcher S3 package name
|
||||
* @constant
|
||||
* @private
|
||||
* @type {String}
|
||||
*/
|
||||
const S3_PACKAGE_NAME = 'etcher';
|
||||
|
||||
/**
|
||||
* @summary Number of packages per Etcher version
|
||||
* @constant
|
||||
* @private
|
||||
* @type {Number}
|
||||
*/
|
||||
const NUMBER_OF_PACKAGES = 8;
|
||||
|
||||
/**
|
||||
* @summary Get the correct S3 bucket url from a release type
|
||||
* @function
|
||||
* @private
|
||||
*
|
||||
* @param {RELEASE_TYPE} releaseType - release type
|
||||
* @returns {?String} S3 bucket url
|
||||
*
|
||||
* @example
|
||||
* const bucketUrl = s3Packages.getBucketUrlFromReleaseType(release.RELEASE_TYPE.PRODUCTION);
|
||||
*
|
||||
* if (bucketUrl) {
|
||||
* console.log(bucketUrl);
|
||||
* }
|
||||
*/
|
||||
exports.getBucketUrlFromReleaseType = (releaseType) => {
|
||||
if (releaseType === release.RELEASE_TYPE.PRODUCTION) {
|
||||
return exports.BUCKET_URL.PRODUCTION;
|
||||
}
|
||||
|
||||
if (releaseType === release.RELEASE_TYPE.SNAPSHOT) {
|
||||
return exports.BUCKET_URL.SNAPSHOT;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* @summary Get all remote versions from an S3 bucket
|
||||
* @function
|
||||
* @private
|
||||
*
|
||||
* @description
|
||||
* We memoize based on the assumption that the received latest version
|
||||
* number will not increase while the application is running.
|
||||
*
|
||||
* @param {String} bucketUrl - s3 bucket url
|
||||
* @fulfil {String[]} - remote versions
|
||||
* @returns {Promise}
|
||||
*
|
||||
* @example
|
||||
* s3Packages.getRemoteVersions(s3Packages.BUCKET_URL.PRODUCTION).then((versions) => {
|
||||
* _.each(versions, (version) => {
|
||||
* console.log(version);
|
||||
* });
|
||||
* });
|
||||
*/
|
||||
exports.getRemoteVersions = _.memoize((bucketUrl) => {
|
||||
if (_.isNil(bucketUrl)) {
|
||||
return Bluebird.reject(new Error(`Invalid bucket url: ${bucketUrl}`));
|
||||
}
|
||||
|
||||
/* eslint-disable lodash/prefer-lodash-method */
|
||||
|
||||
return request.getAsync(bucketUrl)
|
||||
|
||||
/* eslint-enable lodash/prefer-lodash-method */
|
||||
|
||||
.get('body')
|
||||
.then(xml.parseStringAsync)
|
||||
.get('ListBucketResult')
|
||||
.then((bucketResult) => {
|
||||
return _.get(bucketResult, [ 'Contents' ], []);
|
||||
})
|
||||
.reduce((accumulator, entry) => {
|
||||
const [ name, version ] = _.split(_.first(entry.Key), '/');
|
||||
|
||||
if (name === S3_PACKAGE_NAME) {
|
||||
if (_.isNil(accumulator[version])) {
|
||||
accumulator[version] = 1;
|
||||
} else {
|
||||
accumulator[version] += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return accumulator;
|
||||
}, [])
|
||||
.then((versions) => {
|
||||
return _.keys(_.pickBy(versions, (occurrences) => {
|
||||
return occurrences >= NUMBER_OF_PACKAGES;
|
||||
}));
|
||||
})
|
||||
.catch({
|
||||
code: 'ENOTFOUND'
|
||||
}, {
|
||||
code: 'ETIMEDOUT'
|
||||
}, () => {
|
||||
return [];
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary Check if a version satisfies a semver range
|
||||
* @function
|
||||
* @private
|
||||
*
|
||||
* @description
|
||||
* This function is a wrapper around `semver.satisfies`
|
||||
* to make it work fine with pre-release versions.
|
||||
*
|
||||
* @param {String} version - semver version
|
||||
* @param {String} range - semver range
|
||||
* @returns {Boolean} whether the version satisfies the range
|
||||
*
|
||||
* @example
|
||||
* if (semverSatisfies('1.0.0', '>=1.0.0')) {
|
||||
* console.log('The version satisfies the range');
|
||||
* }
|
||||
*/
|
||||
const semverSatisfies = (version, range) => {
|
||||
|
||||
// The `semver` module refuses to apply ranges to prerelease versions
|
||||
// As a workaround, we drop the prerelease tags, if any, apply the range
|
||||
// on that, and keep using the prerelease tag from then on.
|
||||
// See https://github.com/npm/node-semver#prerelease-tags
|
||||
const strippedVersion = `${semver.major(version)}.${semver.minor(version)}.${semver.patch(version)}`;
|
||||
|
||||
return semver.satisfies(strippedVersion, range);
|
||||
};
|
||||
|
||||
/**
|
||||
* @summary Get the latest available version for a given release type
|
||||
* @function
|
||||
* @public
|
||||
*
|
||||
* @param {String} releaseType - release type
|
||||
* @param {Object} [options] - options
|
||||
* @param {String} [options.range] - semver range
|
||||
* @param {Boolean} [options.includeUnstableChannel=false] - include unstable channel
|
||||
* @fulfil {(String|undefined)} - latest version
|
||||
* @returns {Promise}
|
||||
*
|
||||
* @example
|
||||
* s3Packages.getLatestVersion(release.RELEASE_TYPE.PRODUCTION, {
|
||||
* range: '>=2.0.0',
|
||||
* includeUnstableChannel: true
|
||||
* }).then((latestVersion) => {
|
||||
* console.log(`The latest version is: ${latestVersion}`);
|
||||
* });
|
||||
*/
|
||||
exports.getLatestVersion = (releaseType, options = {}) => {
|
||||
|
||||
// For manual testing purposes
|
||||
const ETCHER_FAKE_S3_LATEST_VERSION = process.env.ETCHER_FAKE_S3_LATEST_VERSION;
|
||||
if (!_.isNil(ETCHER_FAKE_S3_LATEST_VERSION)) {
|
||||
if (release.getReleaseType(ETCHER_FAKE_S3_LATEST_VERSION) === releaseType) {
|
||||
return Bluebird.resolve(ETCHER_FAKE_S3_LATEST_VERSION);
|
||||
}
|
||||
|
||||
return Bluebird.resolve();
|
||||
}
|
||||
|
||||
const bucketUrl = exports.getBucketUrlFromReleaseType(releaseType);
|
||||
if (_.isNil(bucketUrl)) {
|
||||
return Bluebird.reject(new Error(`No bucket URL found for release type: ${releaseType}`));
|
||||
}
|
||||
|
||||
/* eslint-disable lodash/prefer-lodash-method */
|
||||
|
||||
return exports.getRemoteVersions(bucketUrl).filter((version) => {
|
||||
|
||||
/* eslint-enable lodash/prefer-lodash-method */
|
||||
|
||||
if (_.some([
|
||||
|
||||
// This check allows us to ignore snapshot builds in production
|
||||
// buckets, and viceversa, which could have been uploaded by mistake.
|
||||
release.getReleaseType(version) !== releaseType,
|
||||
|
||||
!release.isStableRelease(version) && !options.includeUnstableChannel
|
||||
])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return semverSatisfies(version, options.range || '*');
|
||||
}).then((versions) => {
|
||||
return _.last(versions.sort(semver.compare));
|
||||
});
|
||||
};
|
359
npm-shrinkwrap.json
generated
359
npm-shrinkwrap.json
generated
@ -38,13 +38,11 @@
|
||||
"version": "4.11.5",
|
||||
"from": "ajv@>=4.9.1 <5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.5.tgz",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"json-stable-stringify": {
|
||||
"version": "1.0.1",
|
||||
"from": "json-stable-stringify@>=1.0.1 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -342,10 +340,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"assert-plus": {
|
||||
"version": "0.1.5",
|
||||
"from": "assert-plus@>=0.1.5 <0.2.0",
|
||||
"resolved": "http://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz",
|
||||
"dev": true
|
||||
"version": "0.2.0",
|
||||
"from": "assert-plus@>=0.2.0 <0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz"
|
||||
},
|
||||
"assertion-error": {
|
||||
"version": "1.0.2",
|
||||
@ -386,8 +383,7 @@
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"from": "asynckit@>=0.4.0 <0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz"
|
||||
},
|
||||
"autolinker": {
|
||||
"version": "0.15.3",
|
||||
@ -396,16 +392,14 @@
|
||||
"dev": true
|
||||
},
|
||||
"aws-sign2": {
|
||||
"version": "0.5.0",
|
||||
"from": "aws-sign2@>=0.5.0 <0.6.0",
|
||||
"resolved": "http://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz",
|
||||
"dev": true
|
||||
"version": "0.6.0",
|
||||
"from": "aws-sign2@>=0.6.0 <0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz"
|
||||
},
|
||||
"aws4": {
|
||||
"version": "1.6.0",
|
||||
"from": "aws4@>=1.2.1 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz"
|
||||
},
|
||||
"babel-code-frame": {
|
||||
"version": "6.22.0",
|
||||
@ -436,7 +430,6 @@
|
||||
"version": "1.0.1",
|
||||
"from": "bcrypt-pbkdf@>=1.0.0 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"binary": {
|
||||
@ -521,8 +514,7 @@
|
||||
"boom": {
|
||||
"version": "2.10.1",
|
||||
"from": "boom@>=2.0.0 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz"
|
||||
},
|
||||
"bootstrap-sass": {
|
||||
"version": "3.3.6",
|
||||
@ -750,10 +742,9 @@
|
||||
}
|
||||
},
|
||||
"caseless": {
|
||||
"version": "0.9.0",
|
||||
"from": "caseless@>=0.9.0 <0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.9.0.tgz",
|
||||
"dev": true
|
||||
"version": "0.12.0",
|
||||
"from": "caseless@>=0.12.0 <0.13.0",
|
||||
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz"
|
||||
},
|
||||
"center-align": {
|
||||
"version": "0.1.3",
|
||||
@ -860,8 +851,7 @@
|
||||
"co": {
|
||||
"version": "4.6.0",
|
||||
"from": "co@>=4.6.0 <5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz"
|
||||
},
|
||||
"code-context": {
|
||||
"version": "0.5.3",
|
||||
@ -1123,8 +1113,7 @@
|
||||
"cryptiles": {
|
||||
"version": "2.0.5",
|
||||
"from": "cryptiles@>=2.0.0 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz"
|
||||
},
|
||||
"crypto-browserify": {
|
||||
"version": "3.11.0",
|
||||
@ -1171,13 +1160,11 @@
|
||||
"version": "1.14.1",
|
||||
"from": "dashdash@>=1.12.0 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"from": "assert-plus@>=1.0.0 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -1476,7 +1463,6 @@
|
||||
"version": "0.1.1",
|
||||
"from": "ecc-jsbn@>=0.1.1 <0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"electron": {
|
||||
@ -2219,18 +2205,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"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.5",
|
||||
"from": "event-emitter@>=0.3.5 <0.4.0",
|
||||
@ -2294,8 +2268,7 @@
|
||||
"extend": {
|
||||
"version": "3.0.0",
|
||||
"from": "extend@>=3.0.0 <3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz"
|
||||
},
|
||||
"extend-shallow": {
|
||||
"version": "2.0.1",
|
||||
@ -2362,8 +2335,7 @@
|
||||
"extsprintf": {
|
||||
"version": "1.0.2",
|
||||
"from": "extsprintf@1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz"
|
||||
},
|
||||
"eyes": {
|
||||
"version": "0.1.8",
|
||||
@ -2576,14 +2548,12 @@
|
||||
"forever-agent": {
|
||||
"version": "0.6.1",
|
||||
"from": "forever-agent@>=0.6.0 <0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz"
|
||||
},
|
||||
"form-data": {
|
||||
"version": "0.2.0",
|
||||
"from": "form-data@>=0.2.0 <0.3.0",
|
||||
"resolved": "http://registry.npmjs.org/form-data/-/form-data-0.2.0.tgz",
|
||||
"dev": true,
|
||||
"version": "2.1.2",
|
||||
"from": "form-data@>=2.1.1 <2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.2.tgz",
|
||||
"dependencies": {
|
||||
"async": {
|
||||
"version": "0.9.2",
|
||||
@ -2602,6 +2572,16 @@
|
||||
"from": "mime-types@>=2.0.3 <2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.5",
|
||||
"from": "combined-stream@^1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz"
|
||||
},
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"from": "delayed-stream@~1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -2757,13 +2737,11 @@
|
||||
"version": "0.1.6",
|
||||
"from": "getpass@>=0.1.1 <0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.6.tgz",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"from": "assert-plus@>=1.0.0 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -2965,28 +2943,12 @@
|
||||
"har-schema": {
|
||||
"version": "1.0.5",
|
||||
"from": "har-schema@>=1.0.5 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz"
|
||||
},
|
||||
"har-validator": {
|
||||
"version": "1.8.0",
|
||||
"from": "har-validator@>=1.4.0 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-1.8.0.tgz",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"bluebird": {
|
||||
"version": "2.11.0",
|
||||
"from": "bluebird@>=2.9.30 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"commander": {
|
||||
"version": "2.9.0",
|
||||
"from": "commander@^2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
"version": "4.2.1",
|
||||
"from": "har-validator@>=4.2.1 <4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz"
|
||||
},
|
||||
"has": {
|
||||
"version": "1.0.1",
|
||||
@ -3024,10 +2986,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"hawk": {
|
||||
"version": "2.3.1",
|
||||
"from": "hawk@>=2.3.0 <2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/hawk/-/hawk-2.3.1.tgz",
|
||||
"dev": true
|
||||
"version": "3.1.3",
|
||||
"from": "hawk@>=3.1.3 <3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz"
|
||||
},
|
||||
"helper-date": {
|
||||
"version": "0.2.3",
|
||||
@ -3078,8 +3039,7 @@
|
||||
"hoek": {
|
||||
"version": "2.16.3",
|
||||
"from": "hoek@>=2.0.0 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz"
|
||||
},
|
||||
"home-path": {
|
||||
"version": "1.0.3",
|
||||
@ -3137,10 +3097,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"http-signature": {
|
||||
"version": "0.10.1",
|
||||
"from": "http-signature@>=0.10.0 <0.11.0",
|
||||
"resolved": "http://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz",
|
||||
"dev": true
|
||||
"version": "1.1.1",
|
||||
"from": "http-signature@>=1.1.0 <1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz"
|
||||
},
|
||||
"https-browserify": {
|
||||
"version": "0.0.1",
|
||||
@ -3510,8 +3469,7 @@
|
||||
"is-typedarray": {
|
||||
"version": "1.0.0",
|
||||
"from": "is-typedarray@>=1.0.0 <1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz"
|
||||
},
|
||||
"is-unc-path": {
|
||||
"version": "0.1.2",
|
||||
@ -3569,7 +3527,6 @@
|
||||
"version": "1.0.2",
|
||||
"from": "jodid25519@>=1.0.0 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"js-message": {
|
||||
@ -3596,7 +3553,6 @@
|
||||
"version": "0.1.1",
|
||||
"from": "jsbn@>=0.1.0 <0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"json-parse-helpfulerror": {
|
||||
@ -3608,8 +3564,7 @@
|
||||
"json-schema": {
|
||||
"version": "0.2.3",
|
||||
"from": "json-schema@0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz"
|
||||
},
|
||||
"json-stable-stringify": {
|
||||
"version": "0.0.1",
|
||||
@ -3637,8 +3592,7 @@
|
||||
"jsonify": {
|
||||
"version": "0.0.0",
|
||||
"from": "jsonify@>=0.0.0 <0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz"
|
||||
},
|
||||
"jsonparse": {
|
||||
"version": "1.3.0",
|
||||
@ -3662,13 +3616,11 @@
|
||||
"version": "1.4.0",
|
||||
"from": "jsprim@>=1.2.2 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"from": "assert-plus@1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -4723,6 +4675,48 @@
|
||||
"resolved": "https://registry.npmjs.org/mksnapshot/-/mksnapshot-0.1.0.tgz",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"assert-plus": {
|
||||
"version": "0.1.5",
|
||||
"from": "assert-plus@>=0.1.5 <0.2.0",
|
||||
"resolved": "http://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"async": {
|
||||
"version": "0.9.2",
|
||||
"from": "async@>=0.9.0 <0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"aws-sign2": {
|
||||
"version": "0.5.0",
|
||||
"from": "aws-sign2@>=0.5.0 <0.6.0",
|
||||
"resolved": "http://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"bluebird": {
|
||||
"version": "2.11.0",
|
||||
"from": "bluebird@>=2.9.30 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"caseless": {
|
||||
"version": "0.9.0",
|
||||
"from": "caseless@>=0.9.0 <0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.9.0.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"commander": {
|
||||
"version": "2.9.0",
|
||||
"from": "commander@>=2.8.1 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"form-data": {
|
||||
"version": "0.2.0",
|
||||
"from": "form-data@>=0.2.0 <0.3.0",
|
||||
"resolved": "http://registry.npmjs.org/form-data/-/form-data-0.2.0.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "0.18.2",
|
||||
"from": "fs-extra@0.18.2",
|
||||
@ -4734,6 +4728,66 @@
|
||||
"from": "graceful-fs@>=3.0.5 <4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"har-validator": {
|
||||
"version": "1.8.0",
|
||||
"from": "har-validator@>=1.4.0 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-1.8.0.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"hawk": {
|
||||
"version": "2.3.1",
|
||||
"from": "hawk@>=2.3.0 <2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/hawk/-/hawk-2.3.1.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"http-signature": {
|
||||
"version": "0.10.1",
|
||||
"from": "http-signature@>=0.10.0 <0.11.0",
|
||||
"resolved": "http://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.12.0",
|
||||
"from": "mime-db@>=1.12.0 <1.13.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.0.14",
|
||||
"from": "mime-types@>=2.0.1 <2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"node-uuid": {
|
||||
"version": "1.4.7",
|
||||
"from": "node-uuid@>=1.4.0 <1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"oauth-sign": {
|
||||
"version": "0.6.0",
|
||||
"from": "oauth-sign@>=0.6.0 <0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.6.0.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"qs": {
|
||||
"version": "2.4.2",
|
||||
"from": "qs@>=2.4.0 <2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-2.4.2.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"request": {
|
||||
"version": "2.55.0",
|
||||
"from": "request@2.55.0",
|
||||
"resolved": "https://registry.npmjs.org/request/-/request-2.55.0.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"tunnel-agent": {
|
||||
"version": "0.4.3",
|
||||
"from": "tunnel-agent@>=0.4.0 <0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -4882,6 +4936,26 @@
|
||||
"resolved": "https://registry.npmjs.org/netmask/-/netmask-1.0.6.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"nock": {
|
||||
"version": "9.0.9",
|
||||
"from": "nock@9.0.9",
|
||||
"resolved": "https://registry.npmjs.org/nock/-/nock-9.0.9.tgz",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"deep-equal": {
|
||||
"version": "1.0.1",
|
||||
"from": "deep-equal@>=1.0.0 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.4",
|
||||
"from": "lodash@>=4.17.2 <4.18.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node-cmd": {
|
||||
"version": "1.1.1",
|
||||
"from": "node-cmd@>=1.1.1",
|
||||
@ -5027,12 +5101,6 @@
|
||||
"from": "node-stream-zip@>=1.3.4 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.3.4.tgz"
|
||||
},
|
||||
"node-uuid": {
|
||||
"version": "1.4.7",
|
||||
"from": "node-uuid@>=1.4.0 <1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"node.extend": {
|
||||
"version": "1.1.6",
|
||||
"from": "node.extend@>=1.1.5 <1.2.0",
|
||||
@ -5082,10 +5150,9 @@
|
||||
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz"
|
||||
},
|
||||
"oauth-sign": {
|
||||
"version": "0.6.0",
|
||||
"from": "oauth-sign@>=0.6.0 <0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.6.0.tgz",
|
||||
"dev": true
|
||||
"version": "0.8.2",
|
||||
"from": "oauth-sign@>=0.8.1 <0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz"
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.0",
|
||||
@ -5339,8 +5406,7 @@
|
||||
"performance-now": {
|
||||
"version": "0.2.0",
|
||||
"from": "performance-now@>=0.2.0 <0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz"
|
||||
},
|
||||
"pify": {
|
||||
"version": "2.3.0",
|
||||
@ -5463,6 +5529,12 @@
|
||||
"resolved": "https://registry.npmjs.org/prompt/-/prompt-1.0.0.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"propagate": {
|
||||
"version": "0.4.0",
|
||||
"from": "propagate@0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/propagate/-/propagate-0.4.0.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"proxy-agent": {
|
||||
"version": "1.1.1",
|
||||
"from": "proxy-agent@>=1.0.0 <2.0.0",
|
||||
@ -5492,8 +5564,7 @@
|
||||
"punycode": {
|
||||
"version": "1.4.1",
|
||||
"from": "punycode@>=1.3.2 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz"
|
||||
},
|
||||
"q": {
|
||||
"version": "1.4.1",
|
||||
@ -5502,10 +5573,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"qs": {
|
||||
"version": "2.4.2",
|
||||
"from": "qs@>=2.4.0 <2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-2.4.2.tgz",
|
||||
"dev": true
|
||||
"version": "6.4.0",
|
||||
"from": "qs@>=6.4.0 <6.5.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz"
|
||||
},
|
||||
"querystring": {
|
||||
"version": "0.2.0",
|
||||
@ -5770,22 +5840,19 @@
|
||||
}
|
||||
},
|
||||
"request": {
|
||||
"version": "2.55.0",
|
||||
"from": "request@2.55.0",
|
||||
"resolved": "https://registry.npmjs.org/request/-/request-2.55.0.tgz",
|
||||
"dev": true,
|
||||
"version": "2.81.0",
|
||||
"from": "request@2.81.0",
|
||||
"resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz",
|
||||
"dependencies": {
|
||||
"mime-db": {
|
||||
"version": "1.12.0",
|
||||
"from": "mime-db@>=1.12.0 <1.13.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz",
|
||||
"dev": true
|
||||
"combined-stream": {
|
||||
"version": "1.0.5",
|
||||
"from": "combined-stream@>=1.0.5 <1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz"
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.0.14",
|
||||
"from": "mime-types@>=2.0.1 <2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz",
|
||||
"dev": true
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"from": "delayed-stream@>=1.0.0 <1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -5928,8 +5995,7 @@
|
||||
"safe-buffer": {
|
||||
"version": "5.0.1",
|
||||
"from": "safe-buffer@>=5.0.1 <6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz"
|
||||
},
|
||||
"samsam": {
|
||||
"version": "1.1.2",
|
||||
@ -6187,8 +6253,7 @@
|
||||
"sntp": {
|
||||
"version": "1.0.9",
|
||||
"from": "sntp@>=1.0.0 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz"
|
||||
},
|
||||
"socks": {
|
||||
"version": "1.1.10",
|
||||
@ -6256,19 +6321,16 @@
|
||||
"version": "1.11.0",
|
||||
"from": "sshpk@>=1.7.0 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.11.0.tgz",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"asn1": {
|
||||
"version": "0.2.3",
|
||||
"from": "asn1@>=0.2.3 <0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz"
|
||||
},
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"from": "assert-plus@>=1.0.0 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -6386,8 +6448,7 @@
|
||||
"stringstream": {
|
||||
"version": "0.0.5",
|
||||
"from": "stringstream@>=0.0.4 <0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz"
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
@ -6690,8 +6751,7 @@
|
||||
"tough-cookie": {
|
||||
"version": "2.3.2",
|
||||
"from": "tough-cookie@>=0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz"
|
||||
},
|
||||
"tracery": {
|
||||
"version": "1.0.3",
|
||||
@ -6735,16 +6795,14 @@
|
||||
"dev": true
|
||||
},
|
||||
"tunnel-agent": {
|
||||
"version": "0.4.3",
|
||||
"from": "tunnel-agent@>=0.4.0 <0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz",
|
||||
"dev": true
|
||||
"version": "0.6.0",
|
||||
"from": "tunnel-agent@>=0.6.0 <0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz"
|
||||
},
|
||||
"tweetnacl": {
|
||||
"version": "0.14.5",
|
||||
"from": "tweetnacl@>=0.14.0 <0.15.0",
|
||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"type-check": {
|
||||
@ -6955,8 +7013,7 @@
|
||||
"verror": {
|
||||
"version": "1.3.6",
|
||||
"from": "verror@1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz"
|
||||
},
|
||||
"versionist": {
|
||||
"version": "2.8.1",
|
||||
@ -7105,9 +7162,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"xml2js": {
|
||||
"version": "0.4.16",
|
||||
"from": "xml2js@>=0.4.16 <0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.16.tgz"
|
||||
"version": "0.4.17",
|
||||
"from": "xml2js@0.4.17",
|
||||
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.17.tgz"
|
||||
},
|
||||
"xmlbuilder": {
|
||||
"version": "4.2.1",
|
||||
|
@ -2,6 +2,9 @@
|
||||
"name": "etcher",
|
||||
"displayName": "Etcher",
|
||||
"version": "1.0.0-rc.4",
|
||||
"updates": {
|
||||
"semverRange": "<2.0.0"
|
||||
},
|
||||
"main": "lib/start.js",
|
||||
"description": "Flash OS images to SD cards & USB drives, safely and easily.",
|
||||
"productDescription": "Etcher is a powerful OS image flasher built with web technologies to ensure flashing an SDCard or USB drive is a pleasant and safe experience. It protects you from accidentally writing to your hard-drives, ensures every byte of data was written correctly and much more.",
|
||||
@ -89,6 +92,7 @@
|
||||
"path-is-inside": "^1.0.2",
|
||||
"redux": "^3.5.2",
|
||||
"redux-localstorage": "^0.4.1",
|
||||
"request": "^2.81.0",
|
||||
"resin-cli-form": "^1.4.1",
|
||||
"resin-cli-visuals": "^1.2.8",
|
||||
"resin-corvus": "^1.0.0-beta.26",
|
||||
@ -99,6 +103,7 @@
|
||||
"udif": "^0.9.0",
|
||||
"unbzip2-stream": "^1.0.11",
|
||||
"uuid": "^3.0.1",
|
||||
"xml2js": "^0.4.17",
|
||||
"yargs": "^4.6.0",
|
||||
"yauzl": "^2.6.0"
|
||||
},
|
||||
@ -115,6 +120,7 @@
|
||||
"file-exists": "^1.0.0",
|
||||
"html-angular-validate": "^0.1.9",
|
||||
"mochainon": "^1.0.0",
|
||||
"nock": "^9.0.9",
|
||||
"node-sass": "^3.8.0",
|
||||
"sass-lint": "^1.10.2",
|
||||
"tmp": "0.0.31",
|
||||
|
@ -24,177 +24,125 @@ describe('Browser: UpdateNotifier', function() {
|
||||
UPDATE_NOTIFIER_SLEEP_DAYS = _UPDATE_NOTIFIER_SLEEP_DAYS_;
|
||||
}));
|
||||
|
||||
describe('given the `sleepUpdateCheck` is disabled', function() {
|
||||
describe('given ignoreSleepUpdateCheck is false', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
settings.set('sleepUpdateCheck', false);
|
||||
this.ignoreSleepUpdateCheck = false;
|
||||
});
|
||||
|
||||
it('should return true', function() {
|
||||
const result = UpdateNotifierService.shouldCheckForUpdates();
|
||||
m.chai.expect(result).to.be.true;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('given the `sleepUpdateCheck` is enabled', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
settings.set('sleepUpdateCheck', true);
|
||||
});
|
||||
|
||||
describe('given the `lastUpdateNotify` was never updated', function() {
|
||||
describe('given the `sleepUpdateCheck` is disabled', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
settings.set('lastUpdateNotify', undefined);
|
||||
settings.set('sleepUpdateCheck', false);
|
||||
});
|
||||
|
||||
it('should return true', function() {
|
||||
const result = UpdateNotifierService.shouldCheckForUpdates();
|
||||
const result = UpdateNotifierService.shouldCheckForUpdates({
|
||||
ignoreSleepUpdateCheck: this.ignoreSleepUpdateCheck
|
||||
});
|
||||
|
||||
m.chai.expect(result).to.be.true;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('given the `lastUpdateNotify` was very recently updated', function() {
|
||||
describe('given the `sleepUpdateCheck` is enabled', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
settings.set('lastUpdateNotify', Date.now() + 1000);
|
||||
settings.set('sleepUpdateCheck', true);
|
||||
});
|
||||
|
||||
it('should return false', function() {
|
||||
const result = UpdateNotifierService.shouldCheckForUpdates();
|
||||
m.chai.expect(result).to.be.false;
|
||||
describe('given the `lastUpdateNotify` was never updated', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
settings.set('lastUpdateNotify', undefined);
|
||||
});
|
||||
|
||||
it('should return true', function() {
|
||||
const result = UpdateNotifierService.shouldCheckForUpdates({
|
||||
ignoreSleepUpdateCheck: this.ignoreSleepUpdateCheck
|
||||
});
|
||||
|
||||
m.chai.expect(result).to.be.true;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('given the `lastUpdateNotify` was very recently updated', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
settings.set('lastUpdateNotify', Date.now() + 1000);
|
||||
});
|
||||
|
||||
it('should return false', function() {
|
||||
const result = UpdateNotifierService.shouldCheckForUpdates({
|
||||
ignoreSleepUpdateCheck: this.ignoreSleepUpdateCheck
|
||||
});
|
||||
|
||||
m.chai.expect(result).to.be.false;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('given the `lastUpdateNotify` was updated long ago', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
const SLEEP_MS = units.daysToMilliseconds(UPDATE_NOTIFIER_SLEEP_DAYS);
|
||||
settings.set('lastUpdateNotify', Date.now() + SLEEP_MS + 1000);
|
||||
});
|
||||
|
||||
it('should return true', function() {
|
||||
const result = UpdateNotifierService.shouldCheckForUpdates({
|
||||
ignoreSleepUpdateCheck: this.ignoreSleepUpdateCheck
|
||||
});
|
||||
|
||||
m.chai.expect(result).to.be.true;
|
||||
});
|
||||
|
||||
it('should unset the `sleepUpdateCheck` setting', function() {
|
||||
m.chai.expect(settings.get('sleepUpdateCheck')).to.be.true;
|
||||
|
||||
UpdateNotifierService.shouldCheckForUpdates({
|
||||
ignoreSleepUpdateCheck: this.ignoreSleepUpdateCheck
|
||||
});
|
||||
|
||||
m.chai.expect(settings.get('sleepUpdateCheck')).to.be.false;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('given the `lastUpdateNotify` was updated long ago', function() {
|
||||
});
|
||||
|
||||
describe('given ignoreSleepUpdateCheck is true', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
this.ignoreSleepUpdateCheck = true;
|
||||
});
|
||||
|
||||
describe('given the `sleepUpdateCheck` is enabled', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
const SLEEP_MS = units.daysToMilliseconds(UPDATE_NOTIFIER_SLEEP_DAYS);
|
||||
settings.set('lastUpdateNotify', Date.now() + SLEEP_MS + 1000);
|
||||
settings.set('sleepUpdateCheck', true);
|
||||
});
|
||||
|
||||
it('should return true', function() {
|
||||
const result = UpdateNotifierService.shouldCheckForUpdates();
|
||||
m.chai.expect(result).to.be.true;
|
||||
describe('given the `lastUpdateNotify` was very recently updated', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
settings.set('lastUpdateNotify', Date.now() + 1000);
|
||||
});
|
||||
|
||||
it('should return true', function() {
|
||||
const result = UpdateNotifierService.shouldCheckForUpdates({
|
||||
ignoreSleepUpdateCheck: this.ignoreSleepUpdateCheck
|
||||
});
|
||||
|
||||
m.chai.expect(result).to.be.true;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('should unset the `sleepUpdateCheck` setting', function() {
|
||||
m.chai.expect(settings.get('sleepUpdateCheck')).to.be.true;
|
||||
UpdateNotifierService.shouldCheckForUpdates();
|
||||
m.chai.expect(settings.get('sleepUpdateCheck')).to.be.false;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('.isLatestVersion()', function() {
|
||||
|
||||
describe('given the latest version is equal to the current version', function() {
|
||||
|
||||
let $q;
|
||||
let $rootScope;
|
||||
let UpdateNotifierService;
|
||||
let ManifestBindService;
|
||||
|
||||
beforeEach(angular.mock.inject(function(_$q_, _$rootScope_, _UpdateNotifierService_, _ManifestBindService_) {
|
||||
$q = _$q_;
|
||||
$rootScope = _$rootScope_;
|
||||
UpdateNotifierService = _UpdateNotifierService_;
|
||||
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;
|
||||
|
||||
UpdateNotifierService.isLatestVersion().then(function(isLatestVersion) {
|
||||
result = isLatestVersion;
|
||||
});
|
||||
|
||||
$rootScope.$apply();
|
||||
m.chai.expect(result).to.be.true;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('given the latest version is greater than the current version', function() {
|
||||
|
||||
let $q;
|
||||
let $rootScope;
|
||||
let UpdateNotifierService;
|
||||
|
||||
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;
|
||||
|
||||
UpdateNotifierService.isLatestVersion().then(function(isLatestVersion) {
|
||||
result = isLatestVersion;
|
||||
});
|
||||
|
||||
$rootScope.$apply();
|
||||
m.chai.expect(result).to.be.false;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('given the latest version is less than the current version', function() {
|
||||
|
||||
let $q;
|
||||
let $rootScope;
|
||||
let UpdateNotifierService;
|
||||
|
||||
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;
|
||||
|
||||
UpdateNotifierService.isLatestVersion().then(function(isLatestVersion) {
|
||||
result = isLatestVersion;
|
||||
});
|
||||
|
||||
$rootScope.$apply();
|
||||
m.chai.expect(result).to.be.true;
|
||||
});
|
||||
|
||||
});
|
||||
|
132
tests/shared/release.spec.js
Normal file
132
tests/shared/release.spec.js
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright 2017 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 m = require('mochainon');
|
||||
const _ = require('lodash');
|
||||
const release = require('../../lib/shared/release');
|
||||
|
||||
describe('Shared: Release', function() {
|
||||
|
||||
describe('.RELEASE_TYPE', function() {
|
||||
|
||||
it('should be a plain object', function() {
|
||||
m.chai.expect(_.isPlainObject(release.RELEASE_TYPE)).to.be.true;
|
||||
});
|
||||
|
||||
it('should contain keys with different values', function() {
|
||||
const keys = _.keys(release.RELEASE_TYPE);
|
||||
const uniqueValues = _.uniq(_.values(release.RELEASE_TYPE));
|
||||
m.chai.expect(_.size(keys)).to.equal(_.size(uniqueValues));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('.getReleaseType()', function() {
|
||||
|
||||
it('should return the unknown release type if the version is not valid semver', function() {
|
||||
const releaseType = release.getReleaseType('foo.bar');
|
||||
m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.UNKNOWN);
|
||||
});
|
||||
|
||||
describe('given the version has a short git commit hash build number', function() {
|
||||
|
||||
it('should return the snapshot release type', function() {
|
||||
const releaseType = release.getReleaseType('1.0.0+6374412');
|
||||
m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.SNAPSHOT);
|
||||
});
|
||||
|
||||
it('should return the snapshot release type if the version has a pre release tag', function() {
|
||||
const releaseType = release.getReleaseType('1.0.0-beta.19+6374412');
|
||||
m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.SNAPSHOT);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('given the version has a long git commit hash build number', function() {
|
||||
|
||||
it('should return the snapshot release type', function() {
|
||||
const releaseType = release.getReleaseType('1.0.0+6374412554b034799bfc6e13b4e39c3f5e6386e6');
|
||||
m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.SNAPSHOT);
|
||||
});
|
||||
|
||||
it('should return the snapshot release type if the version has a pre release tag', function() {
|
||||
const releaseType = release.getReleaseType('1.0.0-beta.19+6374412554b034799bfc6e13b4e39c3f5e6386e6');
|
||||
m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.SNAPSHOT);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('given the version has no build number', function() {
|
||||
|
||||
it('should return the production release type', function() {
|
||||
const releaseType = release.getReleaseType('1.0.0');
|
||||
m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.PRODUCTION);
|
||||
});
|
||||
|
||||
it('should return the production release type if the version has a pre release tag', function() {
|
||||
const releaseType = release.getReleaseType('1.0.0-beta.19');
|
||||
m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.PRODUCTION);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('given a build number that is not a git commit hash', function() {
|
||||
|
||||
it('should return the unknown release type', function() {
|
||||
const releaseType = release.getReleaseType('1.0.0+foo');
|
||||
m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.UNKNOWN);
|
||||
});
|
||||
|
||||
it('should return the unknown release type if the version has a pre release tag', function() {
|
||||
const releaseType = release.getReleaseType('1.0.0-beta.19+foo');
|
||||
m.chai.expect(releaseType).to.equal(release.RELEASE_TYPE.UNKNOWN);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('.isStableRelease()', function() {
|
||||
|
||||
it('should return true if given a production stable version', function() {
|
||||
m.chai.expect(release.isStableRelease('1.0.0')).to.be.true;
|
||||
});
|
||||
|
||||
it('should return false if given a production release candidate version', function() {
|
||||
m.chai.expect(release.isStableRelease('1.0.0-rc.2')).to.be.false;
|
||||
});
|
||||
|
||||
it('should return false if given a production beta version', function() {
|
||||
m.chai.expect(release.isStableRelease('1.0.0-beta.1')).to.be.false;
|
||||
});
|
||||
|
||||
it('should return true if given a snapshot stable version', function() {
|
||||
m.chai.expect(release.isStableRelease('1.0.0+6374412')).to.be.true;
|
||||
});
|
||||
|
||||
it('should return false if given a snapshot release candidate version', function() {
|
||||
m.chai.expect(release.isStableRelease('1.0.0-rc.2+6374412')).to.be.false;
|
||||
});
|
||||
|
||||
it('should return false if given a snapshot beta version', function() {
|
||||
m.chai.expect(release.isStableRelease('1.0.0-beta.1+6374412')).to.be.false;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
1090
tests/shared/s3-packages.spec.js
Normal file
1090
tests/shared/s3-packages.spec.js
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user