mirror of
https://gitlab.silvrtree.co.uk/martind2000/nci.git
synced 2025-02-11 14:49:15 +00:00
merge
This commit is contained in:
commit
459825e20b
9
data/projects/culture/config.yaml
Normal file
9
data/projects/culture/config.yaml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
scm:
|
||||||
|
type: git
|
||||||
|
repository: /Users/vladimir/projects/fit/culture/frontend_node
|
||||||
|
rev: master
|
||||||
|
|
||||||
|
steps:
|
||||||
|
sync: npm run sync
|
||||||
|
test: nrun test -R dot
|
||||||
|
pack: nrun packSafe
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
scm:
|
scm:
|
||||||
type: git
|
type: git
|
||||||
repository: ./
|
repository: ../../nci
|
||||||
rev: master
|
rev: master
|
||||||
|
|
||||||
# catchRev:
|
# catchRev:
|
||||||
|
@ -103,32 +103,58 @@ exports.init = function(app, callback) {
|
|||||||
buildsResource.clientEmitSync('cancel', {buildId: build.id});
|
buildsResource.clientEmitSync('cancel', {buildId: build.id});
|
||||||
});
|
});
|
||||||
|
|
||||||
var buildLogLineNumbersHash = {};
|
var buildLogLineNumbersHash = {},
|
||||||
|
lastLinesHash = {};
|
||||||
|
|
||||||
distributor.on('buildData', function(build, data) {
|
distributor.on('buildData', function(build, data) {
|
||||||
var lines = _(data.split('\n')).chain().map(function(line) {
|
var cleanupText = function(text) {
|
||||||
return line.replace('\r', '');
|
return text.replace('\r', '');
|
||||||
}).compact().value(),
|
};
|
||||||
|
|
||||||
|
var splittedData = data.split('\n'),
|
||||||
logLineNumber = buildLogLineNumbersHash[build.id] || 0;
|
logLineNumber = buildLogLineNumbersHash[build.id] || 0;
|
||||||
|
|
||||||
lines = _(lines).map(function(line, index) {
|
lastLinesHash[build.id] = lastLinesHash[build.id] || '';
|
||||||
return {
|
|
||||||
number: logLineNumber + index,
|
|
||||||
text: line
|
|
||||||
};
|
|
||||||
});
|
|
||||||
buildLogLineNumbersHash[build.id] = logLineNumber + lines.length;
|
|
||||||
|
|
||||||
|
// if we don't have last line, so we start new line
|
||||||
|
if (!lastLinesHash[build.id]) {
|
||||||
|
logLineNumber++;
|
||||||
|
}
|
||||||
|
lastLinesHash[build.id] += _(splittedData).first();
|
||||||
|
|
||||||
|
var lines = [{
|
||||||
|
text: cleanupText(lastLinesHash[build.id]),
|
||||||
|
buildId: build.id,
|
||||||
|
number: logLineNumber
|
||||||
|
}];
|
||||||
|
|
||||||
|
if (splittedData.length > 1) {
|
||||||
|
// if we have last '' we have to take all except last
|
||||||
|
// this shown that string ends with eol
|
||||||
|
if (_(splittedData).last() === '') {
|
||||||
|
lastLinesHash[build.id] = '';
|
||||||
|
splittedData = _(splittedData.slice(1)).initial();
|
||||||
|
} else {
|
||||||
|
lastLinesHash[build.id] = _(splittedData).last();
|
||||||
|
splittedData = _(splittedData).tail();
|
||||||
|
}
|
||||||
|
|
||||||
|
lines = lines.concat(_(splittedData).map(function(line) {
|
||||||
|
return {
|
||||||
|
text: cleanupText(line),
|
||||||
|
buildId: build.id,
|
||||||
|
number: ++logLineNumber
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
buildLogLineNumbersHash[build.id] = logLineNumber;
|
||||||
app.dataio.resource('build' + build.id).clientEmitSync(
|
app.dataio.resource('build' + build.id).clientEmitSync(
|
||||||
'data',
|
'data',
|
||||||
{lines: lines}
|
{lines: lines}
|
||||||
);
|
);
|
||||||
|
|
||||||
_(lines).each(function(line) {
|
|
||||||
line.buildId = build.id;
|
|
||||||
});
|
|
||||||
// write build logs to db
|
// write build logs to db
|
||||||
if (lines.length) {
|
|
||||||
db.logLines.put(lines, function(err) {
|
db.logLines.put(lines, function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
logger.error(
|
logger.error(
|
||||||
@ -138,7 +164,6 @@ exports.init = function(app, callback) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
callback(null, distributor);
|
callback(null, distributor);
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
&_code {
|
&_code {
|
||||||
clear: left;
|
clear: left;
|
||||||
height: 500px;
|
|
||||||
min-height: 42px;
|
min-height: 42px;
|
||||||
padding: 15px 0;
|
padding: 15px 0;
|
||||||
color: #F1F1F1;
|
color: #F1F1F1;
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
.terminal
|
.terminal
|
||||||
pre.terminal_code(ref="code")
|
pre.terminal_code
|
||||||
each row, index in this.state.data
|
.terminal_footer(style={height: '30px'})
|
||||||
.code-line(key=index)
|
|
||||||
span.code-line_counter
|
|
||||||
.code-line_body!= row
|
|
||||||
|
@ -6,42 +6,96 @@ define([
|
|||||||
'reflux',
|
'reflux',
|
||||||
'app/stores/terminal',
|
'app/stores/terminal',
|
||||||
'ansi_up',
|
'ansi_up',
|
||||||
'templates/app/components/terminal/terminal'
|
'templates/app/components/terminal/terminal',
|
||||||
], function(_, React, Reflux, terminalStore, ansiUp, template) {
|
], function(_, React, Reflux, terminalStore, ansiUp, template) {
|
||||||
var Component = React.createClass({
|
var Component = React.createClass({
|
||||||
mixins: [Reflux.ListenerMixin],
|
mixins: [Reflux.ListenerMixin],
|
||||||
|
|
||||||
shouldScrollBottom: true,
|
shouldScrollBottom: true,
|
||||||
ignoreScrollEvent: false,
|
data: [],
|
||||||
|
linesCount: 0,
|
||||||
|
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
this.listenTo(terminalStore, this.updateItems);
|
this.listenTo(terminalStore, this.updateItems);
|
||||||
|
var node = document.getElementsByClassName('terminal')[0];
|
||||||
|
this.initialScrollPosition = node.getBoundingClientRect().top;
|
||||||
|
|
||||||
|
window.onscroll = this.onScroll;
|
||||||
|
},
|
||||||
|
componentWillUnmount: function() {
|
||||||
|
window.onscroll = null;
|
||||||
|
},
|
||||||
|
prepareRow: function(row) {
|
||||||
|
return ansiUp.ansi_to_html(row.replace('\r', ''));
|
||||||
},
|
},
|
||||||
prepareOutput: function(output) {
|
prepareOutput: function(output) {
|
||||||
|
var self = this;
|
||||||
return output.map(function(row) {
|
return output.map(function(row) {
|
||||||
return ansiUp.ansi_to_html(row.text);
|
return self.prepareRow(row);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
componentWillUpdate: function() {
|
getTerminal: function() {
|
||||||
var node = this.refs.code.getDOMNode();
|
return document.getElementsByClassName('terminal')[0];
|
||||||
this.shouldScrollBottom = node.scrollTop + node.offsetHeight >= node.scrollHeight;
|
|
||||||
},
|
},
|
||||||
componentDidUpdate: function() {
|
getBody: function() {
|
||||||
|
return document.getElementsByTagName('body')[0];
|
||||||
|
},
|
||||||
|
onScroll: function() {
|
||||||
|
var node = this.getTerminal(),
|
||||||
|
body = this.getBody();
|
||||||
|
|
||||||
|
this.shouldScrollBottom = window.innerHeight + body.scrollTop >=
|
||||||
|
node.offsetHeight + this.initialScrollPosition;
|
||||||
|
},
|
||||||
|
ensureScrollPosition: function() {
|
||||||
if (this.shouldScrollBottom) {
|
if (this.shouldScrollBottom) {
|
||||||
var node = this.refs.code.getDOMNode();
|
var node = this.getTerminal(),
|
||||||
node.scrollTop = node.scrollHeight;
|
body = this.getBody();
|
||||||
|
|
||||||
|
body.scrollTop = this.initialScrollPosition + node.offsetHeight;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
makeCodeLineContent: function(line) {
|
||||||
|
return '<span class="code-line_counter">' + '</span>' +
|
||||||
|
'<div class="code-line_body">' + this.prepareRow(line) + '</div>';
|
||||||
|
},
|
||||||
|
makeCodeLine: function(line, index) {
|
||||||
|
return '<div class="code-line" data-number="' + index + '">' +
|
||||||
|
this.makeCodeLineContent(line) + '</div>';
|
||||||
|
},
|
||||||
|
renderBuffer: _.throttle(function() {
|
||||||
|
var data = this.data,
|
||||||
|
currentLinesCount = data.length,
|
||||||
|
terminal = document.getElementsByClassName('terminal_code')[0],
|
||||||
|
rows = terminal.childNodes;
|
||||||
|
|
||||||
|
if (rows.length) {
|
||||||
|
// replace our last node
|
||||||
|
var index = this.linesCount - 1;
|
||||||
|
rows[index].innerHTML = this.makeCodeLineContent(data[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
terminal.insertAdjacentHTML('beforeend',
|
||||||
|
_(data.slice(this.linesCount)).map(function(line, index) {
|
||||||
|
return self.makeCodeLine(line, self.linesCount + index);
|
||||||
|
}).join('')
|
||||||
|
);
|
||||||
|
|
||||||
|
this.linesCount = currentLinesCount;
|
||||||
|
this.ensureScrollPosition();
|
||||||
|
}, 100),
|
||||||
updateItems: function(build) {
|
updateItems: function(build) {
|
||||||
// listen just our console update
|
// listen just our console update
|
||||||
if (build.buildId === this.props.build) {
|
if (build.buildId === this.props.build) {
|
||||||
this.setState({data: this.prepareOutput(build.data)});
|
this.data = build.data;
|
||||||
|
this.renderBuffer();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render: template,
|
shouldComponentUpdate: function() {
|
||||||
getInitialState: function() {
|
return false;
|
||||||
return {
|
},
|
||||||
data: []
|
render: template
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return Component;
|
return Component;
|
||||||
|
@ -29,16 +29,22 @@ define([
|
|||||||
}
|
}
|
||||||
|
|
||||||
connect.resource(resourceName).subscribe('data', function(data) {
|
connect.resource(resourceName).subscribe('data', function(data) {
|
||||||
output = output.concat(data.lines);
|
var lastLine = _(self.lines).last();
|
||||||
|
if (lastLine && (_(data.lines).first().number === lastLine.number)) {
|
||||||
|
self.lines = _(self.lines).initial();
|
||||||
|
}
|
||||||
|
self.lines = self.lines.concat(data.lines);
|
||||||
self.trigger({
|
self.trigger({
|
||||||
buildId: build.id,
|
buildId: build.id,
|
||||||
name: 'Console for build #' + build.id,
|
name: 'Console for build #' + build.id,
|
||||||
data: output
|
data: _(self.lines).pluck('text')
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.lines = [];
|
||||||
|
this.currentLine = '';
|
||||||
|
|
||||||
// create data resource for completed build
|
// create data resource for completed build
|
||||||
if (build.completed) {
|
if (build.completed) {
|
||||||
connect.resource('projects').sync(
|
connect.resource('projects').sync(
|
||||||
|
Loading…
Reference in New Issue
Block a user