
Since the very first npm install is called while node_modules is empty, we need to ignore it, but we can track the start timestamp and record the install even once the installation is completed.
161 lines
4.0 KiB
JavaScript
161 lines
4.0 KiB
JavaScript
'use strict';
|
|
|
|
let execSync = require('child_process').execSync;
|
|
let fs = require('fs');
|
|
let path = require('path');
|
|
let os = require('os');
|
|
let ua;
|
|
|
|
try {
|
|
ua = require('universal-analytics');
|
|
} catch(e) {
|
|
// ignore errors due to invoking analytics before the first npm install
|
|
}
|
|
|
|
const analyticsFile = path.resolve(path.join(__dirname, '..', '..', '.build-analytics'));
|
|
const analyticsId = "UA-8594346-17"; // Owned by the Angular account
|
|
const analyticsOptions = {
|
|
https: true,
|
|
debug: false
|
|
};
|
|
|
|
let cid = fs.existsSync(analyticsFile) ? fs.readFileSync(analyticsFile, 'utf-8') : null;
|
|
let visitor;
|
|
|
|
if (ua) {
|
|
if (cid) {
|
|
visitor = ua(analyticsId, cid, analyticsOptions);
|
|
} else {
|
|
visitor = ua(analyticsId, analyticsOptions);
|
|
cid = visitor.cid;
|
|
fs.writeFileSync(analyticsFile, cid, 'utf-8');
|
|
}
|
|
}
|
|
|
|
// https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters
|
|
let customParams = {
|
|
// OS Platform (darwin, win32, linux)
|
|
cd1: os.platform,
|
|
// Node.js Version (v4.1.2)
|
|
cd2: process.version,
|
|
// npm Version (2.14.7)
|
|
cd10: getNpmVersion(),
|
|
// TypeScript Version (1.6.2)
|
|
cd3: getTypeScriptVersion(),
|
|
// Dart Version
|
|
cd11: getDartVersion(),
|
|
// Dev Environment
|
|
cd4: process.env.TRAVIS ? 'Travis CI' : 'Local Dev',
|
|
// Travis - Pull Request?
|
|
cd5: process.env.TRAVIS && process.env.TRAVIS_PULL_REQUEST ? 'true' : 'false',
|
|
// Travis - Branch Name (master)
|
|
cd6: process.env.TRAVIS_BRANCH,
|
|
// Travis - Repo Slug (angular/angular)
|
|
cd7: process.env.TRAVIS_REPO_SLUG,
|
|
// HW - CPU Info
|
|
cd8: `${os.cpus().length} x ${os.cpus()[0].model}`,
|
|
// HW - Memory Info
|
|
cd9: `${Math.round(os.totalmem()/1024/1024/1024)}GB`,
|
|
};
|
|
|
|
|
|
|
|
function getTypeScriptVersion() {
|
|
try {
|
|
return require('typescript').version;
|
|
} catch (e) {
|
|
return 'unknown';
|
|
}
|
|
}
|
|
|
|
|
|
function getNpmVersion() {
|
|
try {
|
|
return execSync('npm -v').toString().replace(/\s/, '');
|
|
} catch (e) {
|
|
return 'unknown';
|
|
}
|
|
}
|
|
|
|
|
|
function getDartVersion() {
|
|
try {
|
|
return execSync('dart --version 2>&1').toString().replace(/.+: (\S+) [\s\S]+/, '$1')
|
|
} catch (e) {
|
|
return 'unknown';
|
|
}
|
|
}
|
|
|
|
|
|
function recordEvent(eventType, actionCategory, actionName, duration) {
|
|
// if universal-analytics is not yet installed, don't bother doing anything (e.g. when tracking initial npm install)
|
|
// build-analytics will however store the starting timestamp, so at least we can record the success/error event with duration
|
|
if (!ua) return;
|
|
|
|
if (duration) {
|
|
duration = Math.round(duration);
|
|
}
|
|
|
|
switch (eventType) {
|
|
case 'start':
|
|
visitor.
|
|
event(actionCategory, actionName + ' (start)', 'testLabel', null, customParams).
|
|
send();
|
|
break;
|
|
case 'success':
|
|
visitor.
|
|
event(actionCategory, actionName, 'testLabel', duration, customParams).
|
|
timing(actionCategory, actionName, duration, customParams).
|
|
send();
|
|
break;
|
|
case 'error':
|
|
visitor.
|
|
event(actionCategory, actionName + ' (errored)', 'testLabel', duration, customParams).
|
|
timing(actionCategory, actionName, duration, customParams).
|
|
send();
|
|
break;
|
|
default:
|
|
throw new Error(`unknown event type "${eventType}"`);
|
|
}
|
|
}
|
|
|
|
|
|
module.exports = {
|
|
|
|
installStart: (actionName) => {
|
|
recordEvent('start', 'install', actionName);
|
|
},
|
|
|
|
installSuccess: (actionName, duration) => {
|
|
recordEvent('success', 'install', actionName, duration);
|
|
},
|
|
|
|
installError: (actionName, duration) => {
|
|
recordEvent('error', 'install', actionName, duration);
|
|
},
|
|
|
|
buildStart: (actionName) => {
|
|
recordEvent('start', 'build', actionName);
|
|
},
|
|
|
|
buildSuccess: (actionName, duration) => {
|
|
recordEvent('success', 'build', actionName, duration);
|
|
},
|
|
|
|
buildError: (actionName, duration) => {
|
|
recordEvent('error', 'build', actionName, duration);
|
|
},
|
|
|
|
ciStart: (actionName) => {
|
|
recordEvent('start', 'ci', actionName);
|
|
},
|
|
|
|
ciSuccess: (actionName, duration) => {
|
|
recordEvent('success', 'ci', actionName, duration);
|
|
},
|
|
|
|
ciError: (actionName, duration) => {
|
|
recordEvent('success', 'ci', actionName, duration);
|
|
}
|
|
};
|