mirror of
https://github.com/balena-io/etcher.git
synced 2025-07-28 05:36:34 +00:00
feat(GUI): use resin-corvus
in AnalyticsService (#1208)
Change-Type: patch Changelog-Entry: Start reporting errors to Sentry instead of to TrackJS. Fixes: https://github.com/resin-io/etcher/issues/1027
This commit is contained in:
parent
1d14f8ad08
commit
91a1c3d107
@ -44,7 +44,7 @@ install:
|
|||||||
./scripts/build/docker/run-command.sh -r "${TARGET_ARCH}" -s "${PWD}" -c "make info && make electron-develop";
|
./scripts/build/docker/run-command.sh -r "${TARGET_ARCH}" -s "${PWD}" -c "make info && make electron-develop";
|
||||||
else
|
else
|
||||||
pip install codespell==1.9.2 awscli;
|
pip install codespell==1.9.2 awscli;
|
||||||
npm install -g bower asar;
|
npm install -g asar;
|
||||||
brew install afsctool jq;
|
brew install afsctool jq;
|
||||||
make info;
|
make info;
|
||||||
travis_wait make electron-develop;
|
travis_wait make electron-develop;
|
||||||
|
39
Makefile
39
Makefile
@ -135,6 +135,18 @@ endif
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------
|
||||||
|
# Analytics
|
||||||
|
# ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
ifndef ANALYTICS_SENTRY_TOKEN
|
||||||
|
$(warning No Sentry token found (ANALYTICS_SENTRY_TOKEN is not set))
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef ANALYTICS_MIXPANEL_TOKEN
|
||||||
|
$(warning No Mixpanel token found (ANALYTICS_MIXPANEL_TOKEN is not set))
|
||||||
|
endif
|
||||||
|
|
||||||
# ---------------------------------------------------------------------
|
# ---------------------------------------------------------------------
|
||||||
# Extra variables
|
# Extra variables
|
||||||
# ---------------------------------------------------------------------
|
# ---------------------------------------------------------------------
|
||||||
@ -189,18 +201,29 @@ $(BUILD_DIRECTORY)/node-$(TARGET_PLATFORM)-$(TARGET_ARCH)-dependencies/node_modu
|
|||||||
-t node \
|
-t node \
|
||||||
-s "$(TARGET_PLATFORM)"
|
-s "$(TARGET_PLATFORM)"
|
||||||
|
|
||||||
$(BUILD_DIRECTORY)/electron-$(TARGET_PLATFORM)-$(TARGET_ARCH)-dependencies/bower_components: bower.json \
|
|
||||||
| $(BUILD_DIRECTORY)/electron-$(TARGET_PLATFORM)-$(TARGET_ARCH)-dependencies
|
|
||||||
./scripts/build/dependencies-bower.sh -p -x $|
|
|
||||||
|
|
||||||
$(BUILD_DIRECTORY)/electron-$(TARGET_PLATFORM)-$(APPLICATION_VERSION)-$(TARGET_ARCH)-app: \
|
$(BUILD_DIRECTORY)/electron-$(TARGET_PLATFORM)-$(APPLICATION_VERSION)-$(TARGET_ARCH)-app: \
|
||||||
$(BUILD_DIRECTORY)/electron-$(TARGET_PLATFORM)-$(TARGET_ARCH)-dependencies/node_modules \
|
$(BUILD_DIRECTORY)/electron-$(TARGET_PLATFORM)-$(TARGET_ARCH)-dependencies/node_modules \
|
||||||
$(BUILD_DIRECTORY)/electron-$(TARGET_PLATFORM)-$(TARGET_ARCH)-dependencies/bower_components \
|
| $(BUILD_DIRECTORY) $(BUILD_TEMPORARY_DIRECTORY)
|
||||||
| $(BUILD_DIRECTORY)
|
|
||||||
./scripts/build/electron-create-resources-app.sh -s . -o $@ \
|
./scripts/build/electron-create-resources-app.sh -s . -o $@ \
|
||||||
-v $(APPLICATION_VERSION) \
|
-v $(APPLICATION_VERSION) \
|
||||||
-f "$(APPLICATION_FILES)"
|
-f "$(APPLICATION_FILES)"
|
||||||
$(foreach prerequisite,$^,$(call execute-command,cp -RLf $(prerequisite) $@))
|
cp -RLf $< $@
|
||||||
|
|
||||||
|
ifdef ANALYTICS_SENTRY_TOKEN
|
||||||
|
./scripts/build/jq-insert.sh \
|
||||||
|
-p ".analytics.sentry.token" \
|
||||||
|
-v "$(ANALYTICS_SENTRY_TOKEN)" \
|
||||||
|
-f $@/package.json \
|
||||||
|
-t $(BUILD_TEMPORARY_DIRECTORY)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef ANALYTICS_MIXPANEL_TOKEN
|
||||||
|
./scripts/build/jq-insert.sh \
|
||||||
|
-p ".analytics.mixpanel.token" \
|
||||||
|
-v "$(ANALYTICS_MIXPANEL_TOKEN)" \
|
||||||
|
-f $@/package.json \
|
||||||
|
-t $(BUILD_TEMPORARY_DIRECTORY)
|
||||||
|
endif
|
||||||
|
|
||||||
$(BUILD_DIRECTORY)/electron-$(TARGET_PLATFORM)-$(APPLICATION_VERSION)-$(TARGET_ARCH)-app.asar: \
|
$(BUILD_DIRECTORY)/electron-$(TARGET_PLATFORM)-$(APPLICATION_VERSION)-$(TARGET_ARCH)-app.asar: \
|
||||||
$(BUILD_DIRECTORY)/electron-$(TARGET_PLATFORM)-$(APPLICATION_VERSION)-$(TARGET_ARCH)-app \
|
$(BUILD_DIRECTORY)/electron-$(TARGET_PLATFORM)-$(APPLICATION_VERSION)-$(TARGET_ARCH)-app \
|
||||||
@ -484,7 +507,6 @@ electron-develop:
|
|||||||
-v "$(ELECTRON_VERSION)" \
|
-v "$(ELECTRON_VERSION)" \
|
||||||
-t electron \
|
-t electron \
|
||||||
-s "$(TARGET_PLATFORM)"
|
-s "$(TARGET_PLATFORM)"
|
||||||
./scripts/build/dependencies-bower.sh
|
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@echo "Available targets: $(TARGETS)"
|
@echo "Available targets: $(TARGETS)"
|
||||||
@ -510,6 +532,5 @@ clean:
|
|||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
rm -rf node_modules
|
rm -rf node_modules
|
||||||
rm -rf bower_components
|
|
||||||
|
|
||||||
.DEFAULT_GOAL = help
|
.DEFAULT_GOAL = help
|
||||||
|
@ -27,7 +27,7 @@ matrix:
|
|||||||
install:
|
install:
|
||||||
- ps: Install-Product node $env:nodejs_version x64
|
- ps: Install-Product node $env:nodejs_version x64
|
||||||
- npm install -g npm@4.4.4
|
- npm install -g npm@4.4.4
|
||||||
- npm install -g bower rimraf asar
|
- npm install -g rimraf asar
|
||||||
- choco install nsis -version 2.51
|
- choco install nsis -version 2.51
|
||||||
- choco install jq
|
- choco install jq
|
||||||
- choco install curl
|
- choco install curl
|
||||||
|
13
bower.json
13
bower.json
@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "etcher",
|
|
||||||
"ignore": [
|
|
||||||
"**/.*",
|
|
||||||
"node_modules",
|
|
||||||
"bower_components",
|
|
||||||
"test",
|
|
||||||
"tests"
|
|
||||||
],
|
|
||||||
"dependencies": {
|
|
||||||
"angular-mixpanel": "~1.1.2"
|
|
||||||
}
|
|
||||||
}
|
|
@ -10,7 +10,6 @@ Prerequisites
|
|||||||
### Common
|
### Common
|
||||||
|
|
||||||
- [NodeJS](https://nodejs.org) (at least v6)
|
- [NodeJS](https://nodejs.org) (at least v6)
|
||||||
- [Bower](http://bower.io)
|
|
||||||
- [Python](https://www.python.org)
|
- [Python](https://www.python.org)
|
||||||
- [jq](https://stedolan.github.io/jq/)
|
- [jq](https://stedolan.github.io/jq/)
|
||||||
- [Asar](https://github.com/electron/asar)
|
- [Asar](https://github.com/electron/asar)
|
||||||
|
@ -11,17 +11,6 @@
|
|||||||
<!-- See https://github.com/visionmedia/debug#browser-support -->
|
<!-- See https://github.com/visionmedia/debug#browser-support -->
|
||||||
<script>window.localStorage.debug = '*';</script>
|
<script>window.localStorage.debug = '*';</script>
|
||||||
|
|
||||||
<script>
|
|
||||||
window._trackJs = {
|
|
||||||
token: '032448bc3d9e4cffb1e9b43d29d6c142',
|
|
||||||
application: 'etcher',
|
|
||||||
console: {
|
|
||||||
error: false
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
<script src="../../node_modules/trackjs/tracker.js"></script>
|
|
||||||
|
|
||||||
<script src="./app.js"></script>
|
<script src="./app.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body ng-app="Etcher">
|
<body ng-app="Etcher">
|
||||||
|
@ -20,85 +20,31 @@
|
|||||||
* @module Etcher.Modules.Analytics
|
* @module Etcher.Modules.Analytics
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const _ = require('lodash');
|
|
||||||
const angular = require('angular');
|
const angular = require('angular');
|
||||||
const isRunningInAsar = require('electron-is-running-in-asar');
|
const _ = require('lodash');
|
||||||
const errors = require('../../shared/errors');
|
const resinCorvus = require('resin-corvus/browser');
|
||||||
const os = require('os');
|
|
||||||
const packageJSON = require('../../../package.json');
|
const packageJSON = require('../../../package.json');
|
||||||
const arch = require('arch');
|
|
||||||
const utils = require('../../shared/utils');
|
|
||||||
const settings = require('../models/settings');
|
const settings = require('../models/settings');
|
||||||
|
|
||||||
// Force Mixpanel snippet to load Mixpanel locally
|
|
||||||
// instead of using a CDN for performance reasons
|
|
||||||
window.MIXPANEL_CUSTOM_LIB_URL = '../../bower_components/mixpanel/mixpanel.js';
|
|
||||||
|
|
||||||
require('../../../bower_components/mixpanel/mixpanel-jslib-snippet.js');
|
|
||||||
require('../../../bower_components/angular-mixpanel/src/angular-mixpanel');
|
|
||||||
const MODULE_NAME = 'Etcher.Modules.Analytics';
|
const MODULE_NAME = 'Etcher.Modules.Analytics';
|
||||||
const analytics = angular.module(MODULE_NAME, [
|
const analytics = angular.module(MODULE_NAME, []);
|
||||||
'analytics.mixpanel'
|
|
||||||
]);
|
|
||||||
|
|
||||||
/**
|
analytics.run(() => {
|
||||||
* @summary Get host architecture
|
resinCorvus.install({
|
||||||
* @function
|
services: {
|
||||||
* @private
|
sentry: _.get(packageJSON, [ 'analytics', 'sentry', 'token' ]),
|
||||||
*
|
mixpanel: _.get(packageJSON, [ 'analytics', 'mixpanel', 'token' ])
|
||||||
* @description
|
},
|
||||||
* We need this because node's os.arch() returns the process architecture
|
options: {
|
||||||
* See: https://github.com/nodejs/node-v0.x-archive/issues/2862
|
release: packageJSON.version,
|
||||||
*
|
shouldReport: () => {
|
||||||
* @returns {String} Host architecture
|
return settings.get('errorReporting');
|
||||||
*
|
}
|
||||||
* @example
|
}
|
||||||
* if (getHostArchitecture() === 'x64') {
|
|
||||||
* console.log('Host architecture is x64');
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
const getHostArchitecture = () => {
|
|
||||||
return _.includes([ 'ia32', 'x64' ], process.arch) ? _.replace(arch(), 'x86', 'ia32') : process.arch;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Mixpanel integration
|
|
||||||
// https://github.com/kuhnza/angular-mixpanel
|
|
||||||
|
|
||||||
analytics.config(($mixpanelProvider) => {
|
|
||||||
$mixpanelProvider.apiKey('63e5fc4563e00928da67d1226364dd4c');
|
|
||||||
|
|
||||||
$mixpanelProvider.superProperties({
|
|
||||||
electron: process.versions.electron,
|
|
||||||
node: process.version,
|
|
||||||
arch: process.arch,
|
|
||||||
version: packageJSON.version,
|
|
||||||
osPlatform: os.platform(),
|
|
||||||
hostArch: getHostArchitecture(),
|
|
||||||
osRelease: os.release(),
|
|
||||||
cpuCores: os.cpus().length,
|
|
||||||
totalMemory: os.totalmem(),
|
|
||||||
startFreeMemory: os.freemem()
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// TrackJS integration
|
analytics.service('AnalyticsService', function() {
|
||||||
// http://docs.trackjs.com/tracker/framework-integrations
|
|
||||||
|
|
||||||
analytics.run(($window) => {
|
|
||||||
|
|
||||||
// Don't configure TrackJS when
|
|
||||||
// running inside the test suite
|
|
||||||
if (window.mocha) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$window.trackJs.configure({
|
|
||||||
userId: os.userInfo().username,
|
|
||||||
version: packageJSON.version
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
analytics.service('AnalyticsService', function($log, $window, $mixpanel) {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @summary Log a debug message
|
* @summary Log a debug message
|
||||||
@ -106,22 +52,14 @@ analytics.service('AnalyticsService', function($log, $window, $mixpanel) {
|
|||||||
* @public
|
* @public
|
||||||
*
|
*
|
||||||
* @description
|
* @description
|
||||||
* This function sends the debug message to TrackJS only.
|
* This function sends the debug message to error reporting services.
|
||||||
*
|
*
|
||||||
* @param {String} message - message
|
* @param {String} message - message
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* AnalyticsService.log('Hello World');
|
* AnalyticsService.log('Hello World');
|
||||||
*/
|
*/
|
||||||
this.logDebug = (message) => {
|
this.logDebug = resinCorvus.logDebug;
|
||||||
const debugMessage = `${new Date()} ${message}`;
|
|
||||||
|
|
||||||
if (settings.get('errorReporting') && isRunningInAsar()) {
|
|
||||||
$window.trackJs.console.debug(debugMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
$log.debug(debugMessage);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @summary Log an event
|
* @summary Log an event
|
||||||
@ -129,7 +67,7 @@ analytics.service('AnalyticsService', function($log, $window, $mixpanel) {
|
|||||||
* @public
|
* @public
|
||||||
*
|
*
|
||||||
* @description
|
* @description
|
||||||
* This function sends the debug message to TrackJS and Mixpanel.
|
* This function sends the debug message to product analytics services.
|
||||||
*
|
*
|
||||||
* @param {String} message - message
|
* @param {String} message - message
|
||||||
* @param {Object} [data] - event data
|
* @param {Object} [data] - event data
|
||||||
@ -139,23 +77,7 @@ analytics.service('AnalyticsService', function($log, $window, $mixpanel) {
|
|||||||
* image: '/dev/disk2'
|
* image: '/dev/disk2'
|
||||||
* });
|
* });
|
||||||
*/
|
*/
|
||||||
this.logEvent = (message, data) => {
|
this.logEvent = resinCorvus.logEvent;
|
||||||
const debugData = utils.hideAbsolutePathsInObject(utils.makeFlatStartCaseObject(data));
|
|
||||||
|
|
||||||
if (settings.get('errorReporting') && isRunningInAsar()) {
|
|
||||||
$mixpanel.track(message, debugData);
|
|
||||||
}
|
|
||||||
|
|
||||||
const debugMessage = _.attempt(() => {
|
|
||||||
if (debugData) {
|
|
||||||
return `${message} (${JSON.stringify(debugData)})`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return message;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.logDebug(debugMessage);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @summary Log an exception
|
* @summary Log an exception
|
||||||
@ -163,24 +85,14 @@ analytics.service('AnalyticsService', function($log, $window, $mixpanel) {
|
|||||||
* @public
|
* @public
|
||||||
*
|
*
|
||||||
* @description
|
* @description
|
||||||
* This function logs an exception in TrackJS.
|
* This function logs an exception to error reporting services.
|
||||||
*
|
*
|
||||||
* @param {Error} exception - exception
|
* @param {Error} exception - exception
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* AnalyticsService.logException(new Error('Something happened'));
|
* AnalyticsService.logException(new Error('Something happened'));
|
||||||
*/
|
*/
|
||||||
this.logException = (exception) => {
|
this.logException = resinCorvus.logException;
|
||||||
if (_.every([
|
|
||||||
settings.get('errorReporting'),
|
|
||||||
isRunningInAsar(),
|
|
||||||
errors.shouldReport(exception)
|
|
||||||
])) {
|
|
||||||
$window.trackJs.track(exception);
|
|
||||||
}
|
|
||||||
|
|
||||||
$log.error(exception);
|
|
||||||
};
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -122,29 +122,6 @@ const getUserFriendlyMessageProperty = (error, property) => {
|
|||||||
return _.invoke(exports.HUMAN_FRIENDLY, [ code, property ], error);
|
return _.invoke(exports.HUMAN_FRIENDLY, [ code, property ], error);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Check whether an error should be reported to TrackJS
|
|
||||||
* @function
|
|
||||||
* @public
|
|
||||||
*
|
|
||||||
* @description
|
|
||||||
* In order to determine whether the error should be reported, we
|
|
||||||
* check a property called `report`. For backwards compatibility, and
|
|
||||||
* to properly handle errors that we don't control, an error without
|
|
||||||
* this property is reported automatically.
|
|
||||||
*
|
|
||||||
* @param {Error} error - error
|
|
||||||
* @returns {Boolean} whether the error should be reported
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* if (errors.shouldReport(new Error('foo'))) {
|
|
||||||
* console.log('We should report this error');
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
exports.shouldReport = (error) => {
|
|
||||||
return !_.has(error, [ 'report' ]) || Boolean(error.report);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @summary Check if a string is blank
|
* @summary Check if a string is blank
|
||||||
* @function
|
* @function
|
||||||
|
@ -1,135 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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');
|
|
||||||
_.mixin(require('lodash-deep'));
|
|
||||||
const flatten = require('flat').flatten;
|
|
||||||
const deepMapKeys = require('deep-map-keys');
|
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Create a flattened copy of the object with all keys transformed in start case
|
|
||||||
* @function
|
|
||||||
* @public
|
|
||||||
*
|
|
||||||
* @param {*} object - object to transform
|
|
||||||
* @returns {*} transformed object
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* const object = makeFlatStartCaseObject({
|
|
||||||
* image: {
|
|
||||||
* size: 10000000000,
|
|
||||||
* recommendedSize: 10000000000
|
|
||||||
* }
|
|
||||||
* })
|
|
||||||
*
|
|
||||||
* console.log(object)
|
|
||||||
* > {
|
|
||||||
* > 'Image Size': 10000000000,
|
|
||||||
* > 'Image Recommended Size': 10000000000
|
|
||||||
* > }
|
|
||||||
*/
|
|
||||||
exports.makeFlatStartCaseObject = (object) => {
|
|
||||||
if (_.isUndefined(object)) {
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transform primitives to objects
|
|
||||||
if (!_.isObject(object)) {
|
|
||||||
return {
|
|
||||||
Value: object
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_.isArray(object)) {
|
|
||||||
return _.map(object, (property) => {
|
|
||||||
if (_.isObject(property)) {
|
|
||||||
return exports.makeFlatStartCaseObject(property);
|
|
||||||
}
|
|
||||||
|
|
||||||
return property;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const transformedKeysObject = deepMapKeys(object, (key) => {
|
|
||||||
|
|
||||||
// Preserve environment variables
|
|
||||||
const regex = /^[A-Z_]+$/;
|
|
||||||
if (regex.test(key)) {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _.startCase(key);
|
|
||||||
});
|
|
||||||
|
|
||||||
return flatten(transformedKeysObject, {
|
|
||||||
delimiter: ' ',
|
|
||||||
safe: true
|
|
||||||
});
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Create an object clone with all absolute paths replaced with the path basename
|
|
||||||
* @function
|
|
||||||
* @public
|
|
||||||
*
|
|
||||||
* @param {Object} object - original object
|
|
||||||
* @returns {Object} transformed object
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* const anonymized = utils.hideAbsolutePathsInObject({
|
|
||||||
* path1: '/home/john/rpi.img',
|
|
||||||
* simpleProperty: null,
|
|
||||||
* nested: {
|
|
||||||
* path2: '/home/john/another-image.img',
|
|
||||||
* path3: 'yet-another-image.img',
|
|
||||||
* otherProperty: false
|
|
||||||
* }
|
|
||||||
* });
|
|
||||||
*
|
|
||||||
* console.log(anonymized);
|
|
||||||
* > {
|
|
||||||
* > path1: 'rpi.img',
|
|
||||||
* > simpleProperty: null,
|
|
||||||
* > nested: {
|
|
||||||
* > path2: 'another-image.img',
|
|
||||||
* > path3: 'yet-another-image.img',
|
|
||||||
* > otherProperty: false
|
|
||||||
* > }
|
|
||||||
* > }
|
|
||||||
*/
|
|
||||||
exports.hideAbsolutePathsInObject = (object) => {
|
|
||||||
return _.deepMapValues(object, (value) => {
|
|
||||||
if (!_.isString(value)) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't alter disk devices, even though they appear as full paths
|
|
||||||
if (_.some([
|
|
||||||
_.startsWith(value, '/dev/'),
|
|
||||||
_.startsWith(value, '\\\\.\\')
|
|
||||||
])) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return path.isAbsolute(value) ? path.basename(value) : value;
|
|
||||||
});
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
83
npm-shrinkwrap.json
generated
83
npm-shrinkwrap.json
generated
@ -159,7 +159,7 @@
|
|||||||
},
|
},
|
||||||
"arch": {
|
"arch": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"from": "arch@2.1.0",
|
"from": "arch@>=2.1.0 <3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/arch/-/arch-2.1.0.tgz"
|
"resolved": "https://registry.npmjs.org/arch/-/arch-2.1.0.tgz"
|
||||||
},
|
},
|
||||||
"archiver": {
|
"archiver": {
|
||||||
@ -1050,6 +1050,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"cookie": {
|
||||||
|
"version": "0.3.1",
|
||||||
|
"from": "cookie@0.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz"
|
||||||
|
},
|
||||||
"cookiejar": {
|
"cookiejar": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"from": "cookiejar@2.0.1",
|
"from": "cookiejar@2.0.1",
|
||||||
@ -1266,7 +1271,7 @@
|
|||||||
},
|
},
|
||||||
"deep-map-keys": {
|
"deep-map-keys": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"from": "deep-map-keys@1.2.0",
|
"from": "deep-map-keys@>=1.2.0 <2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/deep-map-keys/-/deep-map-keys-1.2.0.tgz"
|
"resolved": "https://registry.npmjs.org/deep-map-keys/-/deep-map-keys-1.2.0.tgz"
|
||||||
},
|
},
|
||||||
"defaults": {
|
"defaults": {
|
||||||
@ -1396,6 +1401,16 @@
|
|||||||
"resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"detect-node": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"from": "detect-node@>=2.0.3 <3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.3.tgz"
|
||||||
|
},
|
||||||
|
"detect-process": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"from": "detect-process@>=1.0.4 <2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/detect-process/-/detect-process-1.0.4.tgz"
|
||||||
|
},
|
||||||
"detective": {
|
"detective": {
|
||||||
"version": "4.5.0",
|
"version": "4.5.0",
|
||||||
"from": "detective@>=4.0.0 <5.0.0",
|
"from": "detective@>=4.0.0 <5.0.0",
|
||||||
@ -2524,7 +2539,7 @@
|
|||||||
},
|
},
|
||||||
"flat": {
|
"flat": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"from": "flat@2.0.1",
|
"from": "flat@>=2.0.1 <3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/flat/-/flat-2.0.1.tgz"
|
"resolved": "https://registry.npmjs.org/flat/-/flat-2.0.1.tgz"
|
||||||
},
|
},
|
||||||
"flat-cache": {
|
"flat-cache": {
|
||||||
@ -3345,6 +3360,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.2.tgz",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"is-electron": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"from": "is-electron@>=2.0.0 <3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-electron/-/is-electron-2.0.0.tgz"
|
||||||
|
},
|
||||||
"is-electron-renderer": {
|
"is-electron-renderer": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"from": "is-electron-renderer@>=2.0.0 <3.0.0",
|
"from": "is-electron-renderer@>=2.0.0 <3.0.0",
|
||||||
@ -3452,6 +3472,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"is-phantom": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"from": "is-phantom@>=1.0.1 <2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-phantom/-/is-phantom-1.0.1.tgz"
|
||||||
|
},
|
||||||
"is-posix-bracket": {
|
"is-posix-bracket": {
|
||||||
"version": "0.1.1",
|
"version": "0.1.1",
|
||||||
"from": "is-posix-bracket@>=0.1.0 <0.2.0",
|
"from": "is-posix-bracket@>=0.1.0 <0.2.0",
|
||||||
@ -3595,8 +3620,7 @@
|
|||||||
"json-stringify-safe": {
|
"json-stringify-safe": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"from": "json-stringify-safe@>=5.0.0 <5.1.0",
|
"from": "json-stringify-safe@>=5.0.0 <5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz"
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"json3": {
|
"json3": {
|
||||||
"version": "3.3.2",
|
"version": "3.3.2",
|
||||||
@ -3720,7 +3744,7 @@
|
|||||||
},
|
},
|
||||||
"lodash-deep": {
|
"lodash-deep": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"from": "lodash-deep@2.0.0",
|
"from": "lodash-deep@>=2.0.0 <3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/lodash-deep/-/lodash-deep-2.0.0.tgz"
|
"resolved": "https://registry.npmjs.org/lodash-deep/-/lodash-deep-2.0.0.tgz"
|
||||||
},
|
},
|
||||||
"lodash-es": {
|
"lodash-es": {
|
||||||
@ -3924,6 +3948,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.1.tgz",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"lsmod": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"from": "lsmod@1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lsmod/-/lsmod-1.0.0.tgz"
|
||||||
|
},
|
||||||
"lzma-native": {
|
"lzma-native": {
|
||||||
"version": "1.5.2",
|
"version": "1.5.2",
|
||||||
"from": "lzma-native@>=1.1.0 <2.0.0",
|
"from": "lzma-native@>=1.1.0 <2.0.0",
|
||||||
@ -4658,6 +4687,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"mixpanel": {
|
||||||
|
"version": "0.6.0",
|
||||||
|
"from": "mixpanel@>=0.6.0 <0.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mixpanel/-/mixpanel-0.6.0.tgz"
|
||||||
|
},
|
||||||
|
"mixpanel-browser": {
|
||||||
|
"version": "2.11.0",
|
||||||
|
"from": "mixpanel-browser@>=2.11.0 <3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mixpanel-browser/-/mixpanel-browser-2.11.0.tgz"
|
||||||
|
},
|
||||||
"mkdirp": {
|
"mkdirp": {
|
||||||
"version": "0.5.1",
|
"version": "0.5.1",
|
||||||
"from": "mkdirp@>=0.5.0 <0.6.0",
|
"from": "mkdirp@>=0.5.0 <0.6.0",
|
||||||
@ -5492,6 +5531,23 @@
|
|||||||
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.3.tgz",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"raven": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"from": "raven@>=1.1.4 <2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/raven/-/raven-1.2.1.tgz",
|
||||||
|
"dependencies": {
|
||||||
|
"uuid": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"from": "uuid@3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.0.tgz"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"raven-js": {
|
||||||
|
"version": "3.14.0",
|
||||||
|
"from": "raven-js@>=3.12.1 <4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/raven-js/-/raven-js-3.14.0.tgz"
|
||||||
|
},
|
||||||
"rc": {
|
"rc": {
|
||||||
"version": "1.1.7",
|
"version": "1.1.7",
|
||||||
"from": "rc@>=1.1.2 <2.0.0",
|
"from": "rc@>=1.1.2 <2.0.0",
|
||||||
@ -5789,6 +5845,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"resin-corvus": {
|
||||||
|
"version": "1.0.0-beta.20",
|
||||||
|
"from": "resin-corvus@latest",
|
||||||
|
"resolved": "https://registry.npmjs.org/resin-corvus/-/resin-corvus-1.0.0-beta.20.tgz",
|
||||||
|
"dependencies": {
|
||||||
|
"lodash": {
|
||||||
|
"version": "4.17.4",
|
||||||
|
"from": "lodash@>=4.17.4 <5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"resolve": {
|
"resolve": {
|
||||||
"version": "1.3.2",
|
"version": "1.3.2",
|
||||||
"from": "resolve@>=1.1.4 <2.0.0",
|
"from": "resolve@>=1.1.4 <2.0.0",
|
||||||
@ -6213,8 +6281,7 @@
|
|||||||
"stack-trace": {
|
"stack-trace": {
|
||||||
"version": "0.0.9",
|
"version": "0.0.9",
|
||||||
"from": "stack-trace@>=0.0.0 <0.1.0",
|
"from": "stack-trace@>=0.0.0 <0.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.9.tgz",
|
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.9.tgz"
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"stream-browserify": {
|
"stream-browserify": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
|
@ -68,22 +68,18 @@
|
|||||||
"angular-seconds-to-date": "^1.0.0",
|
"angular-seconds-to-date": "^1.0.0",
|
||||||
"angular-ui-bootstrap": "^2.5.0",
|
"angular-ui-bootstrap": "^2.5.0",
|
||||||
"angular-ui-router": "^0.4.2",
|
"angular-ui-router": "^0.4.2",
|
||||||
"arch": "^2.1.0",
|
|
||||||
"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",
|
||||||
"command-join": "^2.0.0",
|
"command-join": "^2.0.0",
|
||||||
"deep-map-keys": "^1.2.0",
|
|
||||||
"drivelist": "^5.0.16",
|
"drivelist": "^5.0.16",
|
||||||
"electron-is-running-in-asar": "^1.0.0",
|
"electron-is-running-in-asar": "^1.0.0",
|
||||||
"etcher-image-write": "^9.0.1",
|
"etcher-image-write": "^9.0.1",
|
||||||
"etcher-latest-version": "^1.0.0",
|
"etcher-latest-version": "^1.0.0",
|
||||||
"file-type": "^4.1.0",
|
"file-type": "^4.1.0",
|
||||||
"flat": "^2.0.1",
|
|
||||||
"flexboxgrid": "^6.3.0",
|
"flexboxgrid": "^6.3.0",
|
||||||
"immutable": "^3.8.1",
|
"immutable": "^3.8.1",
|
||||||
"lodash": "^4.5.1",
|
"lodash": "^4.5.1",
|
||||||
"lodash-deep": "^2.0.0",
|
|
||||||
"lzma-native": "^1.5.2",
|
"lzma-native": "^1.5.2",
|
||||||
"mime-types": "^2.1.15",
|
"mime-types": "^2.1.15",
|
||||||
"mountutils": "^1.0.3",
|
"mountutils": "^1.0.3",
|
||||||
@ -94,6 +90,7 @@
|
|||||||
"redux-localstorage": "^0.4.1",
|
"redux-localstorage": "^0.4.1",
|
||||||
"resin-cli-form": "^1.4.1",
|
"resin-cli-form": "^1.4.1",
|
||||||
"resin-cli-visuals": "^1.2.8",
|
"resin-cli-visuals": "^1.2.8",
|
||||||
|
"resin-corvus": "^1.0.0-beta.20",
|
||||||
"rx": "^4.1.0",
|
"rx": "^4.1.0",
|
||||||
"semver": "^5.1.0",
|
"semver": "^5.1.0",
|
||||||
"sudo-prompt": "^6.1.0",
|
"sudo-prompt": "^6.1.0",
|
||||||
|
@ -26,7 +26,7 @@ RUN apt-get update && apt-get install -y \
|
|||||||
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash - \
|
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash - \
|
||||||
&& apt-get install -y nodejs
|
&& apt-get install -y nodejs
|
||||||
RUN npm config set spin=false
|
RUN npm config set spin=false
|
||||||
RUN npm install -g bower asar electron-installer-debian
|
RUN npm install -g asar electron-installer-debian
|
||||||
|
|
||||||
# Python
|
# Python
|
||||||
RUN pip install codespell==1.9.2 awscli
|
RUN pip install codespell==1.9.2 awscli
|
||||||
|
@ -26,7 +26,7 @@ RUN apt-get update && apt-get install -y \
|
|||||||
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash - \
|
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash - \
|
||||||
&& apt-get install -y nodejs
|
&& apt-get install -y nodejs
|
||||||
RUN npm config set spin=false
|
RUN npm config set spin=false
|
||||||
RUN npm install -g bower asar electron-installer-debian
|
RUN npm install -g asar electron-installer-debian
|
||||||
|
|
||||||
# Python
|
# Python
|
||||||
RUN pip install codespell==1.9.2 awscli
|
RUN pip install codespell==1.9.2 awscli
|
||||||
|
@ -26,7 +26,7 @@ RUN apt-get update && apt-get install -y \
|
|||||||
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash - \
|
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash - \
|
||||||
&& apt-get install -y nodejs
|
&& apt-get install -y nodejs
|
||||||
RUN npm config set spin=false
|
RUN npm config set spin=false
|
||||||
RUN npm install -g bower asar electron-installer-debian
|
RUN npm install -g asar electron-installer-debian
|
||||||
|
|
||||||
# Python
|
# Python
|
||||||
RUN pip install codespell==1.9.2 awscli
|
RUN pip install codespell==1.9.2 awscli
|
||||||
|
@ -19,42 +19,42 @@
|
|||||||
set -u
|
set -u
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
./scripts/build/check-dependency.sh bower
|
./scripts/build/check-dependency.sh jq
|
||||||
|
|
||||||
function usage() {
|
function usage() {
|
||||||
echo "Usage: $0"
|
echo "Usage: $0"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Options"
|
echo "Options"
|
||||||
echo ""
|
echo ""
|
||||||
echo " -x <install prefix>"
|
echo " -p <property>"
|
||||||
echo " -p production install"
|
echo " -v <value>"
|
||||||
|
echo " -f <file>"
|
||||||
|
echo " -t <temporary directory>"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
ARGV_PREFIX=""
|
ARGV_PROPERTY=""
|
||||||
ARGV_PRODUCTION=false
|
ARGV_VALUE=""
|
||||||
|
ARGV_FILE=""
|
||||||
|
ARGV_TEMPORARY_DIRECTORY=""
|
||||||
|
|
||||||
while getopts ":x:p" option; do
|
while getopts ":p:v:f:t:" option; do
|
||||||
case $option in
|
case $option in
|
||||||
x) ARGV_PREFIX=$OPTARG ;;
|
p) ARGV_PROPERTY=$OPTARG ;;
|
||||||
p) ARGV_PRODUCTION=true ;;
|
v) ARGV_VALUE=$OPTARG ;;
|
||||||
|
f) ARGV_FILE=$OPTARG ;;
|
||||||
|
t) ARGV_TEMPORARY_DIRECTORY="$OPTARG" ;;
|
||||||
*) usage ;;
|
*) usage ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
INSTALL_OPTS="--allow-root"
|
if [ -z "$ARGV_PROPERTY" ] ||
|
||||||
|
[ -z "$ARGV_VALUE" ] ||
|
||||||
if [ "$ARGV_PRODUCTION" == "true" ]; then
|
[ -z "$ARGV_FILE" ] ||
|
||||||
INSTALL_OPTS="$INSTALL_OPTS --production"
|
[ -z "$ARGV_TEMPORARY_DIRECTORY" ]; then
|
||||||
fi
|
usage
|
||||||
|
|
||||||
if [ -n "$ARGV_PREFIX" ]; then
|
|
||||||
cp "$PWD/bower.json" "$ARGV_PREFIX/bower.json"
|
|
||||||
pushd "$ARGV_PREFIX"
|
|
||||||
bower install $INSTALL_OPTS
|
|
||||||
popd
|
|
||||||
rm "$ARGV_PREFIX/bower.json"
|
|
||||||
else
|
|
||||||
bower install $INSTALL_OPTS
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
TEMPORARY_FILE="$ARGV_TEMPORARY_DIRECTORY/$(basename "$ARGV_FILE").TMP"
|
||||||
|
jq "$ARGV_PROPERTY=\"$ARGV_VALUE\"" "$ARGV_FILE" > "$TEMPORARY_FILE"
|
||||||
|
mv "$TEMPORARY_FILE" "$ARGV_FILE"
|
@ -36,97 +36,6 @@ describe('Shared: Errors', function() {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('.shouldReport()', function() {
|
|
||||||
|
|
||||||
it('should return true for a string error', function() {
|
|
||||||
const error = 'foo';
|
|
||||||
m.chai.expect(errors.shouldReport(error)).to.be.true;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return true for a number 0 error', function() {
|
|
||||||
const error = 0;
|
|
||||||
m.chai.expect(errors.shouldReport(error)).to.be.true;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return true for a number 1 error', function() {
|
|
||||||
const error = 1;
|
|
||||||
m.chai.expect(errors.shouldReport(error)).to.be.true;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return true for a number -1 error', function() {
|
|
||||||
const error = -1;
|
|
||||||
m.chai.expect(errors.shouldReport(error)).to.be.true;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return true for an array error', function() {
|
|
||||||
const error = [ 1, 2, 3 ];
|
|
||||||
m.chai.expect(errors.shouldReport(error)).to.be.true;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return true for an undefined error', function() {
|
|
||||||
const error = undefined;
|
|
||||||
m.chai.expect(errors.shouldReport(error)).to.be.true;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return true for a null error', function() {
|
|
||||||
const error = null;
|
|
||||||
m.chai.expect(errors.shouldReport(error)).to.be.true;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return true for an empty object error', function() {
|
|
||||||
const error = {};
|
|
||||||
m.chai.expect(errors.shouldReport(error)).to.be.true;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return true for a basic error', function() {
|
|
||||||
const error = new Error('foo');
|
|
||||||
m.chai.expect(errors.shouldReport(error)).to.be.true;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return true for an error with a report true property', function() {
|
|
||||||
const error = new Error('foo');
|
|
||||||
error.report = true;
|
|
||||||
m.chai.expect(errors.shouldReport(error)).to.be.true;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false for an error with a report false property', function() {
|
|
||||||
const error = new Error('foo');
|
|
||||||
error.report = false;
|
|
||||||
m.chai.expect(errors.shouldReport(error)).to.be.false;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false for an error with a report undefined property', function() {
|
|
||||||
const error = new Error('foo');
|
|
||||||
error.report = undefined;
|
|
||||||
m.chai.expect(errors.shouldReport(error)).to.be.false;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false for an error with a report null property', function() {
|
|
||||||
const error = new Error('foo');
|
|
||||||
error.report = null;
|
|
||||||
m.chai.expect(errors.shouldReport(error)).to.be.false;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false for an error with a report 0 property', function() {
|
|
||||||
const error = new Error('foo');
|
|
||||||
error.report = 0;
|
|
||||||
m.chai.expect(errors.shouldReport(error)).to.be.false;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return true for an error with a report 1 property', function() {
|
|
||||||
const error = new Error('foo');
|
|
||||||
error.report = 1;
|
|
||||||
m.chai.expect(errors.shouldReport(error)).to.be.true;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should cast the report property to boolean', function() {
|
|
||||||
const error = new Error('foo');
|
|
||||||
error.report = '';
|
|
||||||
m.chai.expect(errors.shouldReport(error)).to.be.false;
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('.getTitle()', function() {
|
describe('.getTitle()', function() {
|
||||||
|
|
||||||
it('should accept a string', function() {
|
it('should accept a string', function() {
|
||||||
@ -480,25 +389,25 @@ describe('Shared: Errors', function() {
|
|||||||
|
|
||||||
describe('.createError()', function() {
|
describe('.createError()', function() {
|
||||||
|
|
||||||
it('should report the resulting error by default', function() {
|
it('should not set `error.report` by default', function() {
|
||||||
const error = errors.createError('Foo', 'Something happened');
|
const error = errors.createError('Foo', 'Something happened');
|
||||||
m.chai.expect(errors.shouldReport(error)).to.be.true;
|
m.chai.expect(error.report).to.be.undefined;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not report the error if report is false', function() {
|
it('should set `error.report` to false if `options.report` is false', function() {
|
||||||
const error = errors.createError('Foo', 'Something happened', {
|
const error = errors.createError('Foo', 'Something happened', {
|
||||||
report: false
|
report: false
|
||||||
});
|
});
|
||||||
|
|
||||||
m.chai.expect(errors.shouldReport(error)).to.be.false;
|
m.chai.expect(error.report).to.be.false;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not report the error if report evaluates to false', function() {
|
it('should set `error.report` to false if `options.report` evaluates to false', function() {
|
||||||
const error = errors.createError('Foo', 'Something happened', {
|
const error = errors.createError('Foo', 'Something happened', {
|
||||||
report: 0
|
report: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
m.chai.expect(errors.shouldReport(error)).to.be.false;
|
m.chai.expect(error.report).to.be.false;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be an instance of Error', function() {
|
it('should be an instance of Error', function() {
|
||||||
@ -550,9 +459,9 @@ describe('Shared: Errors', function() {
|
|||||||
|
|
||||||
describe('.createUserError()', function() {
|
describe('.createUserError()', function() {
|
||||||
|
|
||||||
it('should not report the resulting error', function() {
|
it('should set the `report` flag to `false`', function() {
|
||||||
const error = errors.createUserError('Foo', 'Something happened');
|
const error = errors.createUserError('Foo', 'Something happened');
|
||||||
m.chai.expect(errors.shouldReport(error)).to.be.false;
|
m.chai.expect(error.report).to.be.false;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be an instance of Error', function() {
|
it('should be an instance of Error', function() {
|
||||||
|
@ -1,336 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 utils = require('../../lib/shared/utils');
|
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
describe('Shared: Utils', function() {
|
|
||||||
|
|
||||||
describe('.makeFlatStartCaseObject()', function() {
|
|
||||||
|
|
||||||
it('should return undefined if given undefined', function() {
|
|
||||||
m.chai.expect(utils.makeFlatStartCaseObject(undefined)).to.be.undefined;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return flat object with start case keys if given nested object', function() {
|
|
||||||
const object = {
|
|
||||||
person: {
|
|
||||||
firstName: 'John',
|
|
||||||
lastName: 'Doe',
|
|
||||||
address: {
|
|
||||||
streetNumber: 13,
|
|
||||||
streetName: 'Elm'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
m.chai.expect(utils.makeFlatStartCaseObject(object)).to.deep.equal({
|
|
||||||
'Person First Name': 'John',
|
|
||||||
'Person Last Name': 'Doe',
|
|
||||||
'Person Address Street Number': 13,
|
|
||||||
'Person Address Street Name': 'Elm'
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return an object with the key `value` if given `false`', function() {
|
|
||||||
m.chai.expect(utils.makeFlatStartCaseObject(false)).to.deep.equal({
|
|
||||||
Value: false
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return an object with the key `value` if given `null`', function() {
|
|
||||||
m.chai.expect(utils.makeFlatStartCaseObject(null)).to.deep.equal({
|
|
||||||
Value: null
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should preserve environment variable', function() {
|
|
||||||
m.chai.expect(utils.makeFlatStartCaseObject({
|
|
||||||
ETCHER_DISABLE_UPDATES: true
|
|
||||||
})).to.deep.equal({
|
|
||||||
ETCHER_DISABLE_UPDATES: true
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should preserve environment variables inside objects', function() {
|
|
||||||
m.chai.expect(utils.makeFlatStartCaseObject({
|
|
||||||
foo: {
|
|
||||||
FOO_BAR_BAZ: 3
|
|
||||||
}
|
|
||||||
})).to.deep.equal({
|
|
||||||
'Foo FOO_BAR_BAZ': 3
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should insert space after key starting with number', function() {
|
|
||||||
m.chai.expect(utils.makeFlatStartCaseObject({
|
|
||||||
foo: {
|
|
||||||
'1key': 1
|
|
||||||
}
|
|
||||||
})).to.deep.equal({
|
|
||||||
'Foo 1 Key': 1
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not modify start case keys', function() {
|
|
||||||
m.chai.expect(utils.makeFlatStartCaseObject({
|
|
||||||
Foo: {
|
|
||||||
'Start Case Key': 42
|
|
||||||
}
|
|
||||||
})).to.deep.equal({
|
|
||||||
'Foo Start Case Key': 42
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not modify arrays', function() {
|
|
||||||
m.chai.expect(utils.makeFlatStartCaseObject([ 1, 2, {
|
|
||||||
nested: 3
|
|
||||||
} ])).to.deep.equal([ 1, 2, {
|
|
||||||
Nested: 3
|
|
||||||
} ]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not modify nested arrays', function() {
|
|
||||||
m.chai.expect(utils.makeFlatStartCaseObject({
|
|
||||||
values: [ 1, 2, {
|
|
||||||
nested: 3
|
|
||||||
} ]
|
|
||||||
})).to.deep.equal({
|
|
||||||
Values: [ 1, 2, {
|
|
||||||
Nested: 3
|
|
||||||
} ]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should leave nested arrays nested', function() {
|
|
||||||
m.chai.expect(utils.makeFlatStartCaseObject([ 1, 2, [ 3, 4 ] ])).to.deep.equal([ 1, 2, [ 3, 4 ] ]);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('.hideAbsolutePathsInObject()', function() {
|
|
||||||
|
|
||||||
it('should return undefined if given undefined', function() {
|
|
||||||
m.chai.expect(utils.hideAbsolutePathsInObject(undefined)).to.be.undefined;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return null if given null', function() {
|
|
||||||
m.chai.expect(utils.hideAbsolutePathsInObject(null)).to.be.null;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return a clone of the object if there are no paths in the object', function() {
|
|
||||||
const object = {
|
|
||||||
numberProperty: 1,
|
|
||||||
nested: {
|
|
||||||
otherProperty: 'value'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
m.chai.expect(utils.hideAbsolutePathsInObject(object)).to.not.equal(object);
|
|
||||||
m.chai.expect(utils.hideAbsolutePathsInObject(object)).to.deep.equal(object);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('given UNIX paths', function() {
|
|
||||||
|
|
||||||
beforeEach(function() {
|
|
||||||
this.isAbsolute = path.isAbsolute;
|
|
||||||
this.basename = path.basename;
|
|
||||||
path.isAbsolute = path.posix.isAbsolute;
|
|
||||||
path.basename = path.posix.basename;
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(function() {
|
|
||||||
path.isAbsolute = this.isAbsolute;
|
|
||||||
path.basename = this.basename;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should replace absolute paths with the basename', function() {
|
|
||||||
const object = {
|
|
||||||
prop1: 'some value',
|
|
||||||
prop2: '/home/john/rpi.img'
|
|
||||||
};
|
|
||||||
|
|
||||||
m.chai.expect(utils.hideAbsolutePathsInObject(object)).to.deep.equal({
|
|
||||||
prop1: 'some value',
|
|
||||||
prop2: 'rpi.img'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should replace nested absolute paths with the basename', function() {
|
|
||||||
const object = {
|
|
||||||
nested: {
|
|
||||||
path: '/home/john/rpi.img'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
m.chai.expect(utils.hideAbsolutePathsInObject(object)).to.deep.equal({
|
|
||||||
nested: {
|
|
||||||
path: 'rpi.img'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not alter /dev/sdb', function() {
|
|
||||||
const object = {
|
|
||||||
nested: {
|
|
||||||
path: '/dev/sdb'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
m.chai.expect(utils.hideAbsolutePathsInObject(object)).to.deep.equal({
|
|
||||||
nested: {
|
|
||||||
path: '/dev/sdb'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not alter relative paths', function() {
|
|
||||||
const object = {
|
|
||||||
path: 'foo/bar'
|
|
||||||
};
|
|
||||||
|
|
||||||
m.chai.expect(utils.hideAbsolutePathsInObject(object)).to.deep.equal({
|
|
||||||
path: 'foo/bar'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle arrays', function() {
|
|
||||||
m.chai.expect(utils.hideAbsolutePathsInObject({
|
|
||||||
foo: 'foo',
|
|
||||||
bar: [
|
|
||||||
{
|
|
||||||
path: '/foo/bar/baz'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/foo/bar/baz'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/foo/bar/baz'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
})).to.deep.equal({
|
|
||||||
foo: 'foo',
|
|
||||||
bar: [
|
|
||||||
{
|
|
||||||
path: 'baz'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'baz'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'baz'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('given Windows paths', function() {
|
|
||||||
|
|
||||||
beforeEach(function() {
|
|
||||||
this.isAbsolute = path.isAbsolute;
|
|
||||||
this.basename = path.basename;
|
|
||||||
path.isAbsolute = path.win32.isAbsolute;
|
|
||||||
path.basename = path.win32.basename;
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(function() {
|
|
||||||
path.isAbsolute = this.isAbsolute;
|
|
||||||
path.basename = this.basename;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should replace absolute paths with the basename', function() {
|
|
||||||
const object = {
|
|
||||||
prop1: 'some value',
|
|
||||||
prop2: 'C:\\Users\\John\\rpi.img'
|
|
||||||
};
|
|
||||||
|
|
||||||
m.chai.expect(utils.hideAbsolutePathsInObject(object)).to.deep.equal({
|
|
||||||
prop1: 'some value',
|
|
||||||
prop2: 'rpi.img'
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should replace nested absolute paths with the basename', function() {
|
|
||||||
const object = {
|
|
||||||
nested: {
|
|
||||||
path: 'C:\\Users\\John\\rpi.img'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
m.chai.expect(utils.hideAbsolutePathsInObject(object)).to.deep.equal({
|
|
||||||
nested: {
|
|
||||||
path: 'rpi.img'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not alter \\\\.\\PHYSICALDRIVE1', function() {
|
|
||||||
const object = {
|
|
||||||
nested: {
|
|
||||||
path: '\\\\.\\PHYSICALDRIVE1'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
m.chai.expect(utils.hideAbsolutePathsInObject(object)).to.deep.equal({
|
|
||||||
nested: {
|
|
||||||
path: '\\\\.\\PHYSICALDRIVE1'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not alter relative paths', function() {
|
|
||||||
const object = {
|
|
||||||
path: 'foo\\bar'
|
|
||||||
};
|
|
||||||
|
|
||||||
m.chai.expect(utils.hideAbsolutePathsInObject(object)).to.deep.equal({
|
|
||||||
path: 'foo\\bar'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle arrays', function() {
|
|
||||||
m.chai.expect(utils.hideAbsolutePathsInObject({
|
|
||||||
foo: 'foo',
|
|
||||||
bar: [ {
|
|
||||||
path: 'C:\\foo\\bar\\baz'
|
|
||||||
}, {
|
|
||||||
path: 'C:\\foo\\bar\\baz'
|
|
||||||
}, {
|
|
||||||
path: 'C:\\foo\\bar\\baz'
|
|
||||||
} ]
|
|
||||||
})).to.deep.equal({
|
|
||||||
foo: 'foo',
|
|
||||||
bar: [ {
|
|
||||||
path: 'baz'
|
|
||||||
}, {
|
|
||||||
path: 'baz'
|
|
||||||
}, {
|
|
||||||
path: 'baz'
|
|
||||||
} ]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
Loading…
x
Reference in New Issue
Block a user