mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Merge bf6febf889637df77f905c2f49deefe8449afda3 into 2feb290ae3c6cd88c16e4c27c2006a569e0146e2
This commit is contained in:
commit
3482011b4c
@ -23,6 +23,11 @@
|
|||||||
<label><i class="fa fa-plus"></i> <span data-i18n="exec.label.append"></span></label>
|
<label><i class="fa fa-plus"></i> <span data-i18n="exec.label.append"></span></label>
|
||||||
<input type="checkbox" id="node-input-addpay-cb" style="display:inline-block; width:auto;">
|
<input type="checkbox" id="node-input-addpay-cb" style="display:inline-block; width:auto;">
|
||||||
<input type="text" id="node-input-addpay" style="margin-left: 5px; width:160px;">
|
<input type="text" id="node-input-addpay" style="margin-left: 5px; width:160px;">
|
||||||
|
<span data-i18n="exec.label.as"></span>
|
||||||
|
<select type="text" id="node-input-addpayTo" style="width:25%">
|
||||||
|
<option value="parameter" data-i18n="exec.opt.parameter"></option>
|
||||||
|
<option value="stdin" data-i18n="exec.opt.stdin"></option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-append"> </label>
|
<label for="node-input-append"> </label>
|
||||||
@ -57,6 +62,7 @@
|
|||||||
defaults: {
|
defaults: {
|
||||||
command: {value:""},
|
command: {value:""},
|
||||||
addpay: {value:"", validate: RED.validators.typedInput({ type: 'msg', allowBlank: true })},
|
addpay: {value:"", validate: RED.validators.typedInput({ type: 'msg', allowBlank: true })},
|
||||||
|
addpayTo: { value: "parameter" },
|
||||||
append: {value:""},
|
append: {value:""},
|
||||||
useSpawn: {value:"false"},
|
useSpawn: {value:"false"},
|
||||||
timer: {value:""},
|
timer: {value:""},
|
||||||
@ -84,10 +90,16 @@
|
|||||||
if ($("#node-input-useSpawn").val() === null) {
|
if ($("#node-input-useSpawn").val() === null) {
|
||||||
$("#node-input-useSpawn").val(this.useSpawn.toString());
|
$("#node-input-useSpawn").val(this.useSpawn.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($("#node-input-addpayTo").val() === null) {
|
||||||
|
$("#node-input-addpayTo").val(this.addpayTo.toString());
|
||||||
|
}
|
||||||
|
|
||||||
$("#node-input-addpay-cb").prop("checked", this.addpay === true || (this.addpay !== false && this.addpay !== ""))
|
$("#node-input-addpay-cb").prop("checked", this.addpay === true || (this.addpay !== false && this.addpay !== ""))
|
||||||
var addpayValue = (this.addpay === true)?"payload":((this.addpay === false || this.addpay === "")?"payload":this.addpay);
|
var addpayValue = (this.addpay === true)?"payload":((this.addpay === false || this.addpay === "")?"payload":this.addpay);
|
||||||
$("#node-input-addpay-cb").on("change", function(evt) {
|
$("#node-input-addpay-cb").on("change", function(evt) {
|
||||||
$("#node-input-addpay").typedInput("disable",!$("#node-input-addpay-cb").prop("checked"));
|
$("#node-input-addpay").typedInput("disable",!$("#node-input-addpay-cb").prop("checked"));
|
||||||
|
$("#node-input-addpayTo").prop("disabled", !$("#node-input-addpay-cb").prop("checked"));
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#node-input-addpay").val(addpayValue);
|
$("#node-input-addpay").val(addpayValue);
|
||||||
|
@ -20,6 +20,8 @@ module.exports = function(RED) {
|
|||||||
var exec = require('child_process').exec;
|
var exec = require('child_process').exec;
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var isUtf8 = require('is-utf8');
|
var isUtf8 = require('is-utf8');
|
||||||
|
var stream = require('stream')
|
||||||
|
|
||||||
const isWindows = process.platform === 'win32'
|
const isWindows = process.platform === 'win32'
|
||||||
|
|
||||||
function ExecNode(n) {
|
function ExecNode(n) {
|
||||||
@ -30,6 +32,12 @@ module.exports = function(RED) {
|
|||||||
if (this.addpay === true) {
|
if (this.addpay === true) {
|
||||||
this.addpay = "payload";
|
this.addpay = "payload";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.addpayTo = n.addpayTo;
|
||||||
|
if ( this.addpayTo === undefined ) {
|
||||||
|
this.addpayTo = "parameter"
|
||||||
|
}
|
||||||
|
|
||||||
this.append = (n.append || "").trim();
|
this.append = (n.append || "").trim();
|
||||||
this.useSpawn = (n.useSpawn == "true");
|
this.useSpawn = (n.useSpawn == "true");
|
||||||
this.timer = Number(n.timer || 0)*1000;
|
this.timer = Number(n.timer || 0)*1000;
|
||||||
@ -69,7 +77,7 @@ module.exports = function(RED) {
|
|||||||
// make the extra args into an array
|
// make the extra args into an array
|
||||||
// then prepend with the msg.payload
|
// then prepend with the msg.payload
|
||||||
var arg = node.cmd;
|
var arg = node.cmd;
|
||||||
if (node.addpay) {
|
if (node.addpay && node.addpayTo == "parameter") {
|
||||||
var value = RED.util.getMessageProperty(msg, node.addpay);
|
var value = RED.util.getMessageProperty(msg, node.addpay);
|
||||||
if (value !== undefined) {
|
if (value !== undefined) {
|
||||||
arg += " " + value;
|
arg += " " + value;
|
||||||
@ -137,6 +145,19 @@ module.exports = function(RED) {
|
|||||||
node.error(code,RED.util.cloneMessage(msg));
|
node.error(code,RED.util.cloneMessage(msg));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (node.addpay && node.addpayTo == "stdin") {
|
||||||
|
var value = RED.util.getMessageProperty(msg, node.addpay);
|
||||||
|
if (value !== undefined) {
|
||||||
|
var stdinStream = new stream.Readable();
|
||||||
|
if (!Buffer.isBuffer(value) && (typeof value) !== 'string') {
|
||||||
|
value = JSON.stringify(value)
|
||||||
|
}
|
||||||
|
stdinStream.push(value); // Add data to the internal queue for users of the stream to consume
|
||||||
|
stdinStream.push(null); // Signals the end of the stream (EOF)
|
||||||
|
stdinStream.pipe(child.stdin);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* istanbul ignore else */
|
/* istanbul ignore else */
|
||||||
@ -181,6 +202,19 @@ module.exports = function(RED) {
|
|||||||
child.tout = setTimeout(function() { cleanup(child.pid); }, node.timer);
|
child.tout = setTimeout(function() { cleanup(child.pid); }, node.timer);
|
||||||
}
|
}
|
||||||
node.activeProcesses[child.pid] = child;
|
node.activeProcesses[child.pid] = child;
|
||||||
|
|
||||||
|
if (node.addpay && node.addpayTo == "stdin") {
|
||||||
|
var value = RED.util.getMessageProperty(msg, node.addpay);
|
||||||
|
if (value !== undefined) {
|
||||||
|
var stdinStream = new stream.Readable();
|
||||||
|
if (!Buffer.isBuffer(value) && (typeof value) !== 'string') {
|
||||||
|
value = JSON.stringify(value)
|
||||||
|
}
|
||||||
|
stdinStream.push(value); // Add data to the internal queue for users of the stream to consume
|
||||||
|
stdinStream.push(null); // Signals the end of the stream (EOF)
|
||||||
|
stdinStream.pipe(child.stdin);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -233,14 +233,18 @@
|
|||||||
"stdout": "stdout",
|
"stdout": "stdout",
|
||||||
"stderr": "stderr",
|
"stderr": "stderr",
|
||||||
"retcode": "return code",
|
"retcode": "return code",
|
||||||
"winHide": "Hide console"
|
"winHide": "Hide console",
|
||||||
|
"as": "as"
|
||||||
|
|
||||||
},
|
},
|
||||||
"placeholder": {
|
"placeholder": {
|
||||||
"extraparams": "extra input parameters"
|
"extraparams": "extra input parameters"
|
||||||
},
|
},
|
||||||
"opt": {
|
"opt": {
|
||||||
"exec": "when the command is complete - exec mode",
|
"exec": "when the command is complete - exec mode",
|
||||||
"spawn": "while the command is running - spawn mode"
|
"spawn": "while the command is running - spawn mode",
|
||||||
|
"parameter": "parameter",
|
||||||
|
"stdin": "stdin"
|
||||||
},
|
},
|
||||||
"oldrc": "Use old style output (compatibility mode)"
|
"oldrc": "Use old style output (compatibility mode)"
|
||||||
},
|
},
|
||||||
|
@ -970,4 +970,248 @@ describe('exec node', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('calling exec with addpayTo', function() {
|
||||||
|
it('handle buffer payloads', function(done) {
|
||||||
|
var flow = [{
|
||||||
|
id:"n1",
|
||||||
|
type:"exec",
|
||||||
|
wires:[["n2"],["n3"],["n4"]],
|
||||||
|
command: undefined,
|
||||||
|
addpay: "payload",
|
||||||
|
addpayTo: "stdin",
|
||||||
|
append:"",
|
||||||
|
useSpawn:"false",
|
||||||
|
oldrc:"false"
|
||||||
|
},{
|
||||||
|
id:"n2",
|
||||||
|
type:"helper"
|
||||||
|
},{
|
||||||
|
id:"n3",
|
||||||
|
type:"helper"
|
||||||
|
},{
|
||||||
|
id:"n4",
|
||||||
|
type:"helper"
|
||||||
|
}];
|
||||||
|
|
||||||
|
var expected;
|
||||||
|
if (osType === "Windows_NT") {
|
||||||
|
flow[0].command = "cmd /C cat"
|
||||||
|
expected = "this payload goes to stdin\r\n";
|
||||||
|
} else {
|
||||||
|
flow[0].command = "cat"
|
||||||
|
expected = "this payload goes to stdin\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
helper.load(execNode, flow, function() {
|
||||||
|
var n1 = helper.getNode("n1");
|
||||||
|
var n2 = helper.getNode("n2");
|
||||||
|
var n3 = helper.getNode("n3");
|
||||||
|
var n4 = helper.getNode("n4");
|
||||||
|
var received = 0;
|
||||||
|
var messages = [null,null];
|
||||||
|
|
||||||
|
var completeTest = function() {
|
||||||
|
received = received + 1;
|
||||||
|
if (received < 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
var msg = messages[0];
|
||||||
|
msg.should.have.property("payload");
|
||||||
|
Buffer.isBuffer(msg.payload).should.be.true();
|
||||||
|
|
||||||
|
msg.payload[0].should.be.eql(0x01)
|
||||||
|
msg.payload[1].should.be.eql(0x02)
|
||||||
|
msg.payload[2].should.be.eql(0x03)
|
||||||
|
msg.payload[3].should.be.eql(0x88)
|
||||||
|
|
||||||
|
msg = messages[1];
|
||||||
|
msg.should.have.property("payload");
|
||||||
|
msg.payload.should.have.property("code",0);
|
||||||
|
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
catch(err) {
|
||||||
|
done(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
n2.on("input", function(msg) {
|
||||||
|
messages[0] = msg;
|
||||||
|
completeTest();
|
||||||
|
});
|
||||||
|
n3.on("input", function(msg) {
|
||||||
|
// stderr wire should not receive msg
|
||||||
|
expect("should not be").to.eql("called")
|
||||||
|
});
|
||||||
|
n4.on("input", function(msg) {
|
||||||
|
messages[1] = msg;
|
||||||
|
completeTest();
|
||||||
|
});
|
||||||
|
|
||||||
|
n1.receive({payload:Buffer.from([0x01,0x02,0x03,0x88])});
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('handle string payloads', function(done) {
|
||||||
|
var flow = [{
|
||||||
|
id:"n1",
|
||||||
|
type:"exec",
|
||||||
|
wires:[["n2"],["n3"],["n4"]],
|
||||||
|
command: undefined,
|
||||||
|
addpay: "payload",
|
||||||
|
addpayTo: "stdin",
|
||||||
|
append:"",
|
||||||
|
useSpawn:"false",
|
||||||
|
oldrc:"false"
|
||||||
|
},{
|
||||||
|
id:"n2",
|
||||||
|
type:"helper"
|
||||||
|
},{
|
||||||
|
id:"n3",
|
||||||
|
type:"helper"
|
||||||
|
},{
|
||||||
|
id:"n4",
|
||||||
|
type:"helper"
|
||||||
|
}];
|
||||||
|
|
||||||
|
var expected;
|
||||||
|
if (osType === "Windows_NT") {
|
||||||
|
flow[0].command = "cmd /C cat"
|
||||||
|
expected = "this payload goes to stdin\r\n";
|
||||||
|
} else {
|
||||||
|
flow[0].command = "cat"
|
||||||
|
expected = "this payload goes to stdin\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
helper.load(execNode, flow, function() {
|
||||||
|
var n1 = helper.getNode("n1");
|
||||||
|
var n2 = helper.getNode("n2");
|
||||||
|
var n3 = helper.getNode("n3");
|
||||||
|
var n4 = helper.getNode("n4");
|
||||||
|
var received = 0;
|
||||||
|
var messages = [null,null];
|
||||||
|
|
||||||
|
var completeTest = function() {
|
||||||
|
received = received + 1;
|
||||||
|
if (received < 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
var msg = messages[0];
|
||||||
|
msg.should.have.property("payload");
|
||||||
|
msg.payload.should.be.a.String();
|
||||||
|
msg.payload.should.equal("this payload goes to stdin");
|
||||||
|
|
||||||
|
msg = messages[1];
|
||||||
|
msg.should.have.property("payload");
|
||||||
|
msg.payload.should.have.property("code",0);
|
||||||
|
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
catch(err) {
|
||||||
|
done(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
n2.on("input", function(msg) {
|
||||||
|
messages[0] = msg;
|
||||||
|
completeTest();
|
||||||
|
});
|
||||||
|
n3.on("input", function(msg) {
|
||||||
|
// stderr wire should not receive msg
|
||||||
|
expect("should not be").to.eql("called")
|
||||||
|
});
|
||||||
|
n4.on("input", function(msg) {
|
||||||
|
messages[1] = msg;
|
||||||
|
completeTest();
|
||||||
|
});
|
||||||
|
|
||||||
|
n1.receive({payload:"this payload goes to stdin"});
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
it('handle array as type for payload', function(done) {
|
||||||
|
var flow = [{
|
||||||
|
id:"n1",
|
||||||
|
type:"exec",
|
||||||
|
wires:[["n2"],["n3"],["n4"]],
|
||||||
|
command: undefined,
|
||||||
|
addpay: "payload",
|
||||||
|
addpayTo: "stdin",
|
||||||
|
append:"",
|
||||||
|
useSpawn:"false",
|
||||||
|
oldrc:"false"
|
||||||
|
},{
|
||||||
|
id:"n2",
|
||||||
|
type:"helper"
|
||||||
|
},{
|
||||||
|
id:"n3",
|
||||||
|
type:"helper"
|
||||||
|
},{
|
||||||
|
id:"n4",
|
||||||
|
type:"helper"
|
||||||
|
}];
|
||||||
|
|
||||||
|
var expected;
|
||||||
|
if (osType === "Windows_NT") {
|
||||||
|
flow[0].command = "cmd /C cat"
|
||||||
|
expected = "this payload goes to stdin\r\n";
|
||||||
|
} else {
|
||||||
|
flow[0].command = "cat"
|
||||||
|
expected = "this payload goes to stdin\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
helper.load(execNode, flow, function() {
|
||||||
|
var n1 = helper.getNode("n1");
|
||||||
|
var n2 = helper.getNode("n2");
|
||||||
|
var n3 = helper.getNode("n3");
|
||||||
|
var n4 = helper.getNode("n4");
|
||||||
|
var received = 0;
|
||||||
|
var messages = [null,null];
|
||||||
|
|
||||||
|
var completeTest = function() {
|
||||||
|
received = received + 1;
|
||||||
|
if (received < 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
var msg = messages[0];
|
||||||
|
msg.should.have.property("payload");
|
||||||
|
msg.payload.should.be.a.String();
|
||||||
|
msg.payload.should.equal('[1,2,3,136]');
|
||||||
|
|
||||||
|
msg = messages[1];
|
||||||
|
msg.should.have.property("payload");
|
||||||
|
msg.payload.should.have.property("code",0);
|
||||||
|
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
catch(err) {
|
||||||
|
done(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
n2.on("input", function(msg) {
|
||||||
|
messages[0] = msg;
|
||||||
|
completeTest();
|
||||||
|
});
|
||||||
|
n3.on("input", function(msg) {
|
||||||
|
// stderr wire should not receive msg
|
||||||
|
expect("should not be").to.eql("called")
|
||||||
|
});
|
||||||
|
n4.on("input", function(msg) {
|
||||||
|
messages[1] = msg;
|
||||||
|
completeTest();
|
||||||
|
});
|
||||||
|
|
||||||
|
n1.receive({payload:[0x01,0x02,0x03,0x88]});
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user