Skip to content

Commit dbd9c4b

Browse files
authored
Introduce facts-tracker (facebook#7747)
* Introduce facts-tracker We want to be able to track various things like number of files that are flowified, number of tests passing with Fiber... This introduces a tool that lets you do that. The API is very simple, you execute the script with a list of tuples [key value] and it's going to create a `facts` branch and put a txt file for each fact and values over time. ``` node scripts/facts-tracker/index.js \ "flow-files" "$COUNT_WITH_FLOW/$COUNT_ALL_FILES" ``` Test Plan: This is tricky to test because Travis only exposes the private variables (github token) when it processes a committed file and not on branches. The reason is that otherwise anyone could send a pull requests that does `echo $GITHUB_TOKEN` and steal your token. Given this constraint, I did all the work using two of my repos: - https://github.com/vjeux/facts-tracker - https://github.com/vjeux/facts-tracker-test and am sending this pull request that should work as is /fingers crossed/, but we won't be able to test it out until it is committed. Note that once this lands, I'm going to kill those two repos. * Update with all the suggested changes * Branch on a flow type in travis.yml * Use $GITHUB_TOKEN * properly escape it
1 parent d9957ac commit dbd9c4b

File tree

2 files changed

+188
-0
lines changed

2 files changed

+188
-0
lines changed

.travis.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,16 @@ script:
7979
./node_modules/.bin/grunt jest:normal
8080
git checkout -- src/renderers/dom/shared/ReactDOMFeatureFlags.js
8181
./node_modules/.bin/gulp react:extract-errors
82+
elif [ "$TEST_TYPE" = flow ]; then
83+
set -e
84+
./node_modules/.bin/grunt flow
85+
86+
ALL_FILES=`find src -name '*.js' | grep -v umd/ | grep -v __tests__ | grep -v __mocks__`
87+
COUNT_ALL_FILES=`echo $ALL_FILES | wc -l`
88+
COUNT_WITH_FLOW=`grep '@flow' $ALL_FILES | perl -pe 's/:.+//' | wc -l`
89+
node scripts/facts-tracker/index.js \
90+
"flow-files" "$COUNT_WITH_FLOW/$COUNT_ALL_FILES"
91+
8292
else
8393
./node_modules/.bin/grunt $TEST_TYPE
8494
fi

scripts/facts-tracker/index.js

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* Copyright (c) 2013-present, Facebook, Inc.
5+
* All rights reserved.
6+
*
7+
* This source code is licensed under the BSD-style license found in the
8+
* LICENSE file in the root directory of this source tree. An additional grant
9+
* of patent rights can be found in the PATENTS file in the same directory.
10+
*/
11+
12+
'use strict';
13+
14+
var fs = require('fs');
15+
var path = require('path');
16+
var execSync = require('child_process').execSync;
17+
18+
function escape(value) {
19+
return '\'' + value.replace(/'/g, "'\\''") + '\'';
20+
}
21+
22+
var cwd = null;
23+
function exec(command) {
24+
console.error('>', command.replace(process.env.GITHUB_TOKEN, '************'));
25+
return execSync(command, cwd ? {cwd: cwd} : undefined).toString();
26+
}
27+
28+
var isInsideOfTravis = !!process.env.TRAVIS_REPO_SLUG;
29+
30+
if (isInsideOfTravis) {
31+
if (process.env.TRAVIS_BRANCH !== 'master') {
32+
console.error('facts-tracker: Branch is not master, exiting...');
33+
process.exit(0);
34+
}
35+
36+
if (process.env.TRAVIS_PULL_REQUEST !== 'false') {
37+
console.error('facts-tracker: This is a pull request, exiting...');
38+
process.exit(0);
39+
}
40+
41+
if (!process.env.GITHUB_USER || !process.env.GITHUB_TOKEN) {
42+
console.error(
43+
'In order to use facts-tracker, you need to configure a ' +
44+
'few environment variables in order to be able to commit to the ' +
45+
'repository. Follow those steps to get you setup:\n' +
46+
'\n' +
47+
'Go to https://github.com/settings/tokens/new\n' +
48+
' - Fill "Token description" with "facts-tracker for ' +
49+
process.env.TRAVIS_REPO_SLUG + '"\n' +
50+
' - Check "public_repo"\n' +
51+
' - Press "Generate Token"\n' +
52+
'\n' +
53+
'In a different tab, go to https://travis-ci.org/' +
54+
process.env.TRAVIS_REPO_SLUG + '/settings\n' +
55+
' - Make sure "Build only if .travis.yml is present" is ON\n' +
56+
' - Fill "Name" with "GITHUB_TOKEN" and "Value" with the token you ' +
57+
'just generated. Press "Add"\n' +
58+
' - Fill "Name" with "GITHUB_USER" and "Value" with the name of the ' +
59+
'account you generated the token with. Press "Add"\n' +
60+
'\n' +
61+
'Once this is done, commit anything to the repository to restart ' +
62+
'Travis and it should work :)'
63+
);
64+
process.exit(1);
65+
}
66+
67+
exec(
68+
'echo "machine github.com login $GITHUB_USER password $GITHUB_TOKEN"' +
69+
'> ~/.netrc'
70+
);
71+
exec(
72+
'git config --global user.name ' +
73+
escape(process.env.GITHUB_USER_NAME || 'facts-tracker')
74+
);
75+
exec(
76+
'git config --global user.email ' +
77+
escape(process.env.GITHUB_USER_EMAIL || '[email protected]')
78+
);
79+
}
80+
81+
if (process.argv.length <= 2) {
82+
console.error('Usage: facts-tracker <name1> <value1> <name2> <value2>...');
83+
process.exit(1);
84+
}
85+
86+
function getRepoSlug() {
87+
if (isInsideOfTravis) {
88+
return process.env.TRAVIS_REPO_SLUG;
89+
}
90+
91+
var remotes = exec('git remote -v').split('\n');
92+
for (var i = 0; i < remotes.length; ++i) {
93+
var match = remotes[i].match(/^origin\t[^:]+:([^\.]+).+\(fetch\)/);
94+
if (match) {
95+
return match[1];
96+
}
97+
}
98+
99+
console.error('Cannot find repository slug, sorry.');
100+
process.exit(1);
101+
}
102+
103+
var repoSlug = getRepoSlug();
104+
var currentCommitHash = exec('git rev-parse HEAD').trim();
105+
var currentTimestamp = new Date().toISOString()
106+
.replace('T', ' ')
107+
.replace(/\..+/, '');
108+
109+
function checkoutFactsFolder() {
110+
var factsFolder = '../' + repoSlug.split('/')[1] + '-facts';
111+
if (!fs.existsSync(factsFolder)) {
112+
var escapedRepoURL;
113+
if (isInsideOfTravis) {
114+
escapedRepoURL = 'https://[email protected]/' + escape(repoSlug) + '.git';
115+
} else {
116+
escapedRepoURL = escape('[email protected]:' + repoSlug + '.git');
117+
}
118+
119+
exec(
120+
'git clone ' +
121+
'--branch facts ' +
122+
'--depth=5 ' +
123+
escapedRepoURL + ' ' +
124+
escape(factsFolder)
125+
);
126+
}
127+
128+
cwd = path.resolve(factsFolder);
129+
exec('git fetch');
130+
if (exec('git status --porcelain')) {
131+
console.error('facts-tracker: `git status` is not clean, aborting.');
132+
process.exit(1);
133+
}
134+
exec('git rebase origin/facts');
135+
}
136+
checkoutFactsFolder();
137+
138+
for (var i = 2; i < process.argv.length; i += 2) {
139+
var name = process.argv[i].trim();
140+
var value = process.argv[i + 1];
141+
if (value.indexOf('\n') !== -1) {
142+
console.error(
143+
'facts-tracker: skipping', name,
144+
'as the value contains new lines:', value
145+
);
146+
continue;
147+
}
148+
149+
var filename = name + '.txt';
150+
try {
151+
var lastLine = exec('tail -n 1 ' + escape(filename));
152+
} catch (e) {
153+
// ignore error
154+
}
155+
var lastValue = lastLine && lastLine
156+
.replace(/^[^\t]+\t[^\t]+\t/, '') // commit hash \t timestamp \t
157+
.slice(0, -1); // trailing \n
158+
159+
if (value !== lastValue) {
160+
fs.appendFileSync(
161+
path.resolve(cwd, filename),
162+
currentCommitHash + '\t' + currentTimestamp + '\t' + value + '\n'
163+
);
164+
}
165+
166+
console.log(name);
167+
console.log(lastValue);
168+
console.log(value);
169+
}
170+
171+
if (exec('git status --porcelain')) {
172+
exec('git add --all');
173+
exec('git commit -m ' + escape('Adding facts for ' + currentCommitHash));
174+
exec('git push origin facts');
175+
} else {
176+
console.error('facts-tracker: nothing to update');
177+
}
178+
cwd = null;

0 commit comments

Comments
 (0)