mirror of
https://github.com/balena-io/etcher.git
synced 2025-07-24 11:46:31 +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";
|
||||
else
|
||||
pip install codespell==1.9.2 awscli;
|
||||
npm install -g bower asar;
|
||||
npm install -g asar;
|
||||
brew install afsctool jq;
|
||||
make info;
|
||||
travis_wait make electron-develop;
|
||||
|
39
Makefile
39
Makefile
@ -135,6 +135,18 @@ 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
|
||||
# ---------------------------------------------------------------------
|
||||
@ -189,18 +201,29 @@ $(BUILD_DIRECTORY)/node-$(TARGET_PLATFORM)-$(TARGET_ARCH)-dependencies/node_modu
|
||||
-t node \
|
||||
-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)-$(TARGET_ARCH)-dependencies/node_modules \
|
||||
$(BUILD_DIRECTORY)/electron-$(TARGET_PLATFORM)-$(TARGET_ARCH)-dependencies/bower_components \
|
||||
| $(BUILD_DIRECTORY)
|
||||
| $(BUILD_DIRECTORY) $(BUILD_TEMPORARY_DIRECTORY)
|
||||
./scripts/build/electron-create-resources-app.sh -s . -o $@ \
|
||||
-v $(APPLICATION_VERSION) \
|
||||
-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 \
|
||||
@ -484,7 +507,6 @@ electron-develop:
|
||||
-v "$(ELECTRON_VERSION)" \
|
||||
-t electron \
|
||||
-s "$(TARGET_PLATFORM)"
|
||||
./scripts/build/dependencies-bower.sh
|
||||
|
||||
help:
|
||||
@echo "Available targets: $(TARGETS)"
|
||||
@ -510,6 +532,5 @@ clean:
|
||||
|
||||
distclean: clean
|
||||
rm -rf node_modules
|
||||
rm -rf bower_components
|
||||
|
||||
.DEFAULT_GOAL = help
|
||||
|
@ -27,7 +27,7 @@ matrix:
|
||||
install:
|
||||
- ps: Install-Product node $env:nodejs_version x64
|
||||
- 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 jq
|
||||
- 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
|
||||
|
||||
- [NodeJS](https://nodejs.org) (at least v6)
|
||||
- [Bower](http://bower.io)
|
||||
- [Python](https://www.python.org)
|
||||
- [jq](https://stedolan.github.io/jq/)
|
||||
- [Asar](https://github.com/electron/asar)
|
||||
|
@ -11,17 +11,6 @@
|
||||
<!-- See https://github.com/visionmedia/debug#browser-support -->
|
||||
<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>
|
||||
</head>
|
||||
<body ng-app="Etcher">
|
||||
|
@ -20,85 +20,31 @@
|
||||
* @module Etcher.Modules.Analytics
|
||||
*/
|
||||
|
||||
const _ = require('lodash');
|
||||
const angular = require('angular');
|
||||
const isRunningInAsar = require('electron-is-running-in-asar');
|
||||
const errors = require('../../shared/errors');
|
||||
const os = require('os');
|
||||
const _ = require('lodash');
|
||||
const resinCorvus = require('resin-corvus/browser');
|
||||
const packageJSON = require('../../../package.json');
|
||||
const arch = require('arch');
|
||||
const utils = require('../../shared/utils');
|
||||
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 analytics = angular.module(MODULE_NAME, [
|
||||
'analytics.mixpanel'
|
||||
]);
|
||||
const analytics = angular.module(MODULE_NAME, []);
|
||||
|
||||
/**
|
||||
* @summary Get host architecture
|
||||
* @function
|
||||
* @private
|
||||
*
|
||||
* @description
|
||||
* We need this because node's os.arch() returns the process architecture
|
||||
* See: https://github.com/nodejs/node-v0.x-archive/issues/2862
|
||||
*
|
||||
* @returns {String} Host architecture
|
||||
*
|
||||
* @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()
|
||||
analytics.run(() => {
|
||||
resinCorvus.install({
|
||||
services: {
|
||||
sentry: _.get(packageJSON, [ 'analytics', 'sentry', 'token' ]),
|
||||
mixpanel: _.get(packageJSON, [ 'analytics', 'mixpanel', 'token' ])
|
||||
},
|
||||
options: {
|
||||
release: packageJSON.version,
|
||||
shouldReport: () => {
|
||||
return settings.get('errorReporting');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// TrackJS integration
|
||||
// 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) {
|
||||
analytics.service('AnalyticsService', function() {
|
||||
|
||||
/**
|
||||
* @summary Log a debug message
|
||||
@ -106,22 +52,14 @@ analytics.service('AnalyticsService', function($log, $window, $mixpanel) {
|
||||
* @public
|
||||
*
|
||||
* @description
|
||||
* This function sends the debug message to TrackJS only.
|
||||
* This function sends the debug message to error reporting services.
|
||||
*
|
||||
* @param {String} message - message
|
||||
*
|
||||
* @example
|
||||
* AnalyticsService.log('Hello World');
|
||||
*/
|
||||
this.logDebug = (message) => {
|
||||
const debugMessage = `${new Date()} ${message}`;
|
||||
|
||||
if (settings.get('errorReporting') && isRunningInAsar()) {
|
||||
$window.trackJs.console.debug(debugMessage);
|
||||
}
|
||||
|
||||
$log.debug(debugMessage);
|
||||
};
|
||||
this.logDebug = resinCorvus.logDebug;
|
||||
|
||||
/**
|
||||
* @summary Log an event
|
||||
@ -129,7 +67,7 @@ analytics.service('AnalyticsService', function($log, $window, $mixpanel) {
|
||||
* @public
|
||||
*
|
||||
* @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 {Object} [data] - event data
|
||||
@ -139,23 +77,7 @@ analytics.service('AnalyticsService', function($log, $window, $mixpanel) {
|
||||
* image: '/dev/disk2'
|
||||
* });
|
||||
*/
|
||||
this.logEvent = (message, data) => {
|
||||
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);
|
||||
};
|
||||
this.logEvent = resinCorvus.logEvent;
|
||||
|
||||
/**
|
||||
* @summary Log an exception
|
||||
@ -163,24 +85,14 @@ analytics.service('AnalyticsService', function($log, $window, $mixpanel) {
|
||||
* @public
|
||||
*
|
||||
* @description
|
||||
* This function logs an exception in TrackJS.
|
||||
* This function logs an exception to error reporting services.
|
||||
*
|
||||
* @param {Error} exception - exception
|
||||
*
|
||||
* @example
|
||||
* AnalyticsService.logException(new Error('Something happened'));
|
||||
*/
|
||||
this.logException = (exception) => {
|
||||
if (_.every([
|
||||
settings.get('errorReporting'),
|
||||
isRunningInAsar(),
|
||||
errors.shouldReport(exception)
|
||||
])) {
|
||||
$window.trackJs.track(exception);
|
||||
}
|
||||
|
||||
$log.error(exception);
|
||||
};
|
||||
this.logException = resinCorvus.logException;
|
||||
|
||||
});
|
||||
|
||||
|
@ -122,29 +122,6 @@ const getUserFriendlyMessageProperty = (error, property) => {
|
||||
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
|
||||
* @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": {
|
||||
"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"
|
||||
},
|
||||
"archiver": {
|
||||
@ -1050,6 +1050,11 @@
|
||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"cookie": {
|
||||
"version": "0.3.1",
|
||||
"from": "cookie@0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz"
|
||||
},
|
||||
"cookiejar": {
|
||||
"version": "2.0.1",
|
||||
"from": "cookiejar@2.0.1",
|
||||
@ -1266,7 +1271,7 @@
|
||||
},
|
||||
"deep-map-keys": {
|
||||
"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"
|
||||
},
|
||||
"defaults": {
|
||||
@ -1396,6 +1401,16 @@
|
||||
"resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz",
|
||||
"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": {
|
||||
"version": "4.5.0",
|
||||
"from": "detective@>=4.0.0 <5.0.0",
|
||||
@ -2524,7 +2539,7 @@
|
||||
},
|
||||
"flat": {
|
||||
"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"
|
||||
},
|
||||
"flat-cache": {
|
||||
@ -3345,6 +3360,11 @@
|
||||
"resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.2.tgz",
|
||||
"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": {
|
||||
"version": "2.0.1",
|
||||
"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",
|
||||
"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": {
|
||||
"version": "0.1.1",
|
||||
"from": "is-posix-bracket@>=0.1.0 <0.2.0",
|
||||
@ -3595,8 +3620,7 @@
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
"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",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz"
|
||||
},
|
||||
"json3": {
|
||||
"version": "3.3.2",
|
||||
@ -3720,7 +3744,7 @@
|
||||
},
|
||||
"lodash-deep": {
|
||||
"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"
|
||||
},
|
||||
"lodash-es": {
|
||||
@ -3924,6 +3948,11 @@
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.1.tgz",
|
||||
"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": {
|
||||
"version": "1.5.2",
|
||||
"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": {
|
||||
"version": "0.5.1",
|
||||
"from": "mkdirp@>=0.5.0 <0.6.0",
|
||||
@ -5492,6 +5531,23 @@
|
||||
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.3.tgz",
|
||||
"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": {
|
||||
"version": "1.1.7",
|
||||
"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": {
|
||||
"version": "1.3.2",
|
||||
"from": "resolve@>=1.1.4 <2.0.0",
|
||||
@ -6213,8 +6281,7 @@
|
||||
"stack-trace": {
|
||||
"version": "0.0.9",
|
||||
"from": "stack-trace@>=0.0.0 <0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.9.tgz",
|
||||
"dev": true
|
||||
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.9.tgz"
|
||||
},
|
||||
"stream-browserify": {
|
||||
"version": "2.0.1",
|
||||
|
@ -68,22 +68,18 @@
|
||||
"angular-seconds-to-date": "^1.0.0",
|
||||
"angular-ui-bootstrap": "^2.5.0",
|
||||
"angular-ui-router": "^0.4.2",
|
||||
"arch": "^2.1.0",
|
||||
"bluebird": "^3.0.5",
|
||||
"bootstrap-sass": "^3.3.5",
|
||||
"chalk": "^1.1.3",
|
||||
"command-join": "^2.0.0",
|
||||
"deep-map-keys": "^1.2.0",
|
||||
"drivelist": "^5.0.16",
|
||||
"electron-is-running-in-asar": "^1.0.0",
|
||||
"etcher-image-write": "^9.0.1",
|
||||
"etcher-latest-version": "^1.0.0",
|
||||
"file-type": "^4.1.0",
|
||||
"flat": "^2.0.1",
|
||||
"flexboxgrid": "^6.3.0",
|
||||
"immutable": "^3.8.1",
|
||||
"lodash": "^4.5.1",
|
||||
"lodash-deep": "^2.0.0",
|
||||
"lzma-native": "^1.5.2",
|
||||
"mime-types": "^2.1.15",
|
||||
"mountutils": "^1.0.3",
|
||||
@ -94,6 +90,7 @@
|
||||
"redux-localstorage": "^0.4.1",
|
||||
"resin-cli-form": "^1.4.1",
|
||||
"resin-cli-visuals": "^1.2.8",
|
||||
"resin-corvus": "^1.0.0-beta.20",
|
||||
"rx": "^4.1.0",
|
||||
"semver": "^5.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 - \
|
||||
&& apt-get install -y nodejs
|
||||
RUN npm config set spin=false
|
||||
RUN npm install -g bower asar electron-installer-debian
|
||||
RUN npm install -g asar electron-installer-debian
|
||||
|
||||
# Python
|
||||
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 - \
|
||||
&& apt-get install -y nodejs
|
||||
RUN npm config set spin=false
|
||||
RUN npm install -g bower asar electron-installer-debian
|
||||
RUN npm install -g asar electron-installer-debian
|
||||
|
||||
# Python
|
||||
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 - \
|
||||
&& apt-get install -y nodejs
|
||||
RUN npm config set spin=false
|
||||
RUN npm install -g bower asar electron-installer-debian
|
||||
RUN npm install -g asar electron-installer-debian
|
||||
|
||||
# Python
|
||||
RUN pip install codespell==1.9.2 awscli
|
||||
|
@ -19,42 +19,42 @@
|
||||
set -u
|
||||
set -e
|
||||
|
||||
./scripts/build/check-dependency.sh bower
|
||||
./scripts/build/check-dependency.sh jq
|
||||
|
||||
function usage() {
|
||||
echo "Usage: $0"
|
||||
echo ""
|
||||
echo "Options"
|
||||
echo ""
|
||||
echo " -x <install prefix>"
|
||||
echo " -p production install"
|
||||
echo " -p <property>"
|
||||
echo " -v <value>"
|
||||
echo " -f <file>"
|
||||
echo " -t <temporary directory>"
|
||||
exit 1
|
||||
}
|
||||
|
||||
ARGV_PREFIX=""
|
||||
ARGV_PRODUCTION=false
|
||||
ARGV_PROPERTY=""
|
||||
ARGV_VALUE=""
|
||||
ARGV_FILE=""
|
||||
ARGV_TEMPORARY_DIRECTORY=""
|
||||
|
||||
while getopts ":x:p" option; do
|
||||
while getopts ":p:v:f:t:" option; do
|
||||
case $option in
|
||||
x) ARGV_PREFIX=$OPTARG ;;
|
||||
p) ARGV_PRODUCTION=true ;;
|
||||
p) ARGV_PROPERTY=$OPTARG ;;
|
||||
v) ARGV_VALUE=$OPTARG ;;
|
||||
f) ARGV_FILE=$OPTARG ;;
|
||||
t) ARGV_TEMPORARY_DIRECTORY="$OPTARG" ;;
|
||||
*) usage ;;
|
||||
esac
|
||||
done
|
||||
|
||||
INSTALL_OPTS="--allow-root"
|
||||
|
||||
if [ "$ARGV_PRODUCTION" == "true" ]; then
|
||||
INSTALL_OPTS="$INSTALL_OPTS --production"
|
||||
fi
|
||||
|
||||
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
|
||||
if [ -z "$ARGV_PROPERTY" ] ||
|
||||
[ -z "$ARGV_VALUE" ] ||
|
||||
[ -z "$ARGV_FILE" ] ||
|
||||
[ -z "$ARGV_TEMPORARY_DIRECTORY" ]; then
|
||||
usage
|
||||
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() {
|
||||
|
||||
it('should accept a string', function() {
|
||||
@ -480,25 +389,25 @@ describe('Shared: Errors', 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');
|
||||
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', {
|
||||
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', {
|
||||
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() {
|
||||
@ -550,9 +459,9 @@ describe('Shared: Errors', 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');
|
||||
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() {
|
||||
|
@ -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