Allow specifying script lines via CLI args

This commit is contained in:
Martchus 2018-04-07 22:28:21 +02:00
parent ec131f297f
commit 5726bab292
3 changed files with 41 additions and 16 deletions

View File

@ -610,12 +610,13 @@ void Application::editConfig(const ArgumentOccurrence &)
m_requiresMainEventLoop = false;
// wait until config is available
if (!(m_args.script.isPresent() ? waitForConfigAndStatus() : waitForConfig())) {
const bool viaJavaScript(m_args.script.isPresent() || m_args.jsLines.isPresent());
if (!(viaJavaScript ? waitForConfigAndStatus() : waitForConfig())) {
return;
}
cerr << Phrases::Override;
const auto newConfig(m_args.script.isPresent() ? editConfigViaScript() : editConfigViaEditor());
const auto newConfig(viaJavaScript ? editConfigViaScript() : editConfigViaEditor());
if (newConfig.isEmpty()) {
// just return here; an error message should have already been printed by editConfigVia*()
return;
@ -740,17 +741,35 @@ QByteArray Application::editConfigViaEditor() const
QByteArray Application::editConfigViaScript() const
{
#if defined(SYNCTHINGCTL_USE_SCRIPT) || defined(SYNCTHINGCTL_USE_JSENGINE)
// read script file
QFile scriptFile(QString::fromLocal8Bit(m_args.script.firstValue()));
if (!scriptFile.open(QFile::ReadOnly)) {
cerr << Phrases::Error << "Unable to open specified script file \"" << m_args.script.firstValue() << "\"." << Phrases::EndFlush;
return QByteArray();
}
const auto script(scriptFile.readAll());
if (script.isEmpty()) {
cerr << Phrases::Error << "Unable to read any bytes from specified script file \"" << m_args.script.firstValue() << "\"."
<< Phrases::EndFlush;
return QByteArray();
// get script
QByteArray script;
QString scriptFileName;
if (m_args.script.isPresent()) {
// read script file
QFile scriptFile(QString::fromLocal8Bit(m_args.script.firstValue()));
if (!scriptFile.open(QFile::ReadOnly)) {
cerr << Phrases::Error << "Unable to open specified script file \"" << m_args.script.firstValue() << "\"." << Phrases::EndFlush;
return QByteArray();
}
script = scriptFile.readAll();
scriptFileName = scriptFile.fileName();
if (script.isEmpty()) {
cerr << Phrases::Error << "Unable to read any bytes from specified script file \"" << m_args.script.firstValue() << "\"."
<< Phrases::EndFlush;
return QByteArray();
}
} else if (m_args.jsLines.isPresent()) {
// construct script from CLI arguments
int requiredSize = 0;
for (const auto *line : m_args.jsLines.values()) {
requiredSize += strlen(line);
requiredSize += 1;
}
script.reserve(requiredSize);
for (const auto *line : m_args.jsLines.values()) {
script += line;
script += '\n';
}
}
// define function to print error
@ -781,7 +800,7 @@ QByteArray Application::editConfigViaScript() const
engine.globalObject().setProperty("console", engine.newQObject(&console));
// evaluate the user provided script
const auto res(engine.evaluate(QString::fromUtf8(script), scriptFile.fileName()));
const auto res(engine.evaluate(QString::fromUtf8(script), scriptFileName));
if (res.isError()) {
cerr << Phrases::Error << "Unable to evaluate the specified script file \"" << m_args.script.firstValue() << "\"." << Phrases::End;
printError(res);

View File

@ -23,6 +23,7 @@ Args::Args()
, pausePwd("pause", 'p', "pauses the current working directory")
, resumePwd("resume", '\0', "resumes the current working directory")
, script("script", '\0', "runs the specified UTF-8 encoded ECMAScript on the configuration rather than opening an editor", { "path" })
, jsLines("js-lines", '\0', "runs the specified ECMAScript lines on the configuration rather than opening an editor", { "line" })
, dryRun("dry-run", '\0', "writes the altered configuration to stdout instead of posting it to Syncthing")
, dir("dir", 'd', "specifies a directory by ID", { "ID" })
, dev("dev", '\0', "specifies a device by ID or name", { "ID/name" })
@ -49,7 +50,12 @@ Args::Args()
waitForIdle.setExample(PROJECT_NAME " wait-for-idle --timeout 1800000 --at-least 5000 && systemctl poweroff\n" PROJECT_NAME
" wait-for-idle --dir dir1 --dir dir2 --dev dev1 --dev dev2 --at-least 5000");
pwd.setSubArguments({ &statusPwd, &rescanPwd, &pausePwd, &resumePwd });
edit.setSubArguments({ &editor, &script, &dryRun });
for (auto *arg : { &editor, &script, &jsLines }) {
arg->setCombinable(false);
}
jsLines.setRequiredValueCount(Argument::varValueCount);
edit.setSubArguments({ &editor, &script, &jsLines, &dryRun });
rescan.setValueNames({ "dir ID" });
rescan.setRequiredValueCount(Argument::varValueCount);

View File

@ -14,7 +14,7 @@ struct Args {
NoColorArgument noColor;
OperationArgument status, log, stop, restart, rescan, rescanAll, pause, resume, waitForIdle, pwd, cat, edit;
OperationArgument statusPwd, rescanPwd, pausePwd, resumePwd;
ConfigValueArgument script, dryRun;
ConfigValueArgument script, jsLines, dryRun;
ConfigValueArgument dir, dev, allDirs, allDevs;
ConfigValueArgument atLeast, timeout;
ConfigValueArgument editor;