-
Notifications
You must be signed in to change notification settings - Fork 0
/
cipes.js
185 lines (157 loc) · 5.51 KB
/
cipes.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#!/usr/bin/env node
'use strict';
/**
* Main entry point of the pupil application
*/
const ctx = require('./lib/context.js');
const opn = require('opn');
const _ = require('lodash');
const Promise = require('bluebird');
Promise.config({
longStackTraces: true
});
const Repository = require('./lib/git.js');
const {app, argv, httpServer, io} = require('./lib/context.js');
const config = require('./lib/config.js');
const idx = require('./lib/indexers');
const getUrlProvider = require('./lib/url-providers');
const ProgressReporter = require('./lib/progress-reporter.js');
const path = require('path');
const Commit = require('./lib/models/Commit.js');
const File = require('./lib/models/File.js');
const Hunk = require('./lib/models/Hunk.js');
const Issue = require('./lib/models/Issue.js');
const Build = require('./lib/models/Build.js');
const Stakeholder = require('./lib/models/Stakeholder.js');
const CommitStakeholderConnection = require('./lib/models/CommitStakeholderConnection.js');
const IssueStakeholderConnection = require('./lib/models/IssueStakeholderConnection.js');
const IssueCommitConnection = require('./lib/models/IssueCommitConnection.js');
const CommitCommitConnection = require('./lib/models/CommitCommitConnection.js');
// set up the endpoints
app.get('/api/commits', require('./lib/endpoints/get-commits.js'));
app.get('/api/config', require('./lib/endpoints/get-config.js'));
// proxy to the FOXX-service
app.get('/graphQl', require('./lib/endpoints/graphQl.js'));
app.post('/graphQl', require('./lib/endpoints/graphQl.js'));
// configuration endpoint (not really used atm)
app.post('/api/config', require('./lib/endpoints/update-config.js'));
const port = config.get().port;
httpServer.listen(port, function() {
console.log(`Listening on http://localhost:${port}`);
});
const indexers = {
vcs: null,
its: null,
ci: null
};
let reporter = new ProgressReporter(io, ['commits', 'issues', 'builds']);
// kickstart the indexing process
Repository.fromPath(ctx.targetPath)
.tap(function(repo) {
ctx.repo = repo;
config.setSource(repo.pathFromRoot('.pupilrc'));
// configure everything in the context
require('./lib/setup-db.js');
return ensureDb(repo);
})
.then(function() {
// be sure to re-index when the configuration changes
config.on('updated', () => {
reIndex(); // do not wait for indexing to complete on config update
// explicitly return null to silence bluebird warning
return null;
});
// immediately run all indexers
return reIndex();
function reIndex() {
console.log('Indexing data...', ctx.repo.path);
indexers.vcs = idx.makeVCSIndexer(ctx.repo, reporter);
if (ctx.argv.its) {
indexers.its = idx.makeITSIndexer(ctx.repo, reporter);
}
if (ctx.argv.ci) {
indexers.ci = idx.makeCIIndexer(ctx.repo, reporter);
}
return getUrlProvider(ctx.repo)
.then(urlProvider => (ctx.urlProvider = urlProvider))
.then(() => Promise.props(indexers))
.thenReturn(_.values(indexers))
.filter(indexer => indexer !== null)
.map(indexer => indexer.index())
.then(() => Commit.deduceStakeholders())
.then(() => Issue.deduceStakeholders())
.then(() => createManualIssueReferences(config.get('issueReferences')))
.then(() => console.log('Indexing finished'))
.catch(e => e.name === 'Gitlab401Error', function() {
console.warn(
'Unable to access GitLab API. Please configure a valid private access token in the UI.'
);
});
}
});
process.on('SIGINT', function() {
if (ctx.quitRequested) {
console.log('Shutting down immediately!');
process.exit(1);
}
console.log('Let me finish up here, ... (Ctrl+C to force quit)');
ctx.quit();
_(indexers)
.values()
.each(idx => idx.stop());
});
/**
* Ensures that the db is set up correctly and the GraphQL-Service is installed
*/
function ensureDb(repo) {
return ctx.db
.ensureDatabase('pupil-' + repo.getName())
.then(function() {
if (argv.clean) {
return ctx.db.truncate();
}
})
.then(function() {
return Promise.join(
ctx.db.ensureService(path.join(__dirname, 'foxx'), '/pupil-ql'),
Commit.ensureCollection(),
File.ensureCollection(),
Hunk.ensureCollection(),
Stakeholder.ensureCollection(),
Issue.ensureCollection(),
Build.ensureCollection(),
CommitStakeholderConnection.ensureCollection(),
IssueStakeholderConnection.ensureCollection(),
IssueCommitConnection.ensureCollection(),
CommitCommitConnection.ensureCollection()
);
});
}
function createManualIssueReferences(issueReferences) {
return Promise.map(_.keys(issueReferences), sha => {
const iid = issueReferences[sha];
return Promise.join(Commit.findOneBySha(sha), Issue.findOneByIid(iid)).spread(
(commit, issue) => {
if (!commit) {
console.warn(`Ignored issue #${iid} referencing non-existing commit ${sha}`);
return;
}
if (!issue) {
console.warn(
`Ignored issue #${iid} referencing commit ${sha} because the issue does not exist`
);
return;
}
const existingMention = _.find(issue.mentions, mention => mention.commit === sha);
if (!existingMention) {
issue.mentions.push({
createdAt: commit.date,
commit: sha,
manual: true
});
return issue.save();
}
}
);
});
}