1 /**************************************************************************
2 ** This file is part of LiteIDE
3 **
4 ** Copyright (c) 2011-2019 LiteIDE. All rights reserved.
5 **
6 ** This library is free software; you can redistribute it and/or
7 ** modify it under the terms of the GNU Lesser General Public
8 ** License as published by the Free Software Foundation; either
9 ** version 2.1 of the License, or (at your option) any later version.
10 **
11 ** This library is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ** Lesser General Public License for more details.
15 **
16 ** In addition, as a special exception, that plugins developed for LiteIDE,
17 ** are allowed to remain closed sourced and can be distributed under any license .
18 ** These rights are included in the file LGPL_EXCEPTION.txt in this package.
19 **
20 **************************************************************************/
21 // Module: litebuildapi.h
22 // Creator: visualfc <visualfc@gmail.com>
23
24 #ifndef LITEBUILDAPI_H
25 #define LITEBUILDAPI_H
26
27 #include "liteapi/liteapi.h"
28 #include <QProcessEnvironment>
29
30 namespace LiteApi {
31
32 class BuildAction
33 {
34 public:
BuildAction()35 BuildAction():
36 m_debug(false),
37 m_output(false),
38 m_readline(false),
39 m_separator(false),
40 m_killold(false),
41 m_navigate(false),
42 m_folder(false),
43 m_takeall(false)
44 {}
setId(const QString & id)45 void setId(const QString &id) { m_id = id; }
setOs(const QString & os)46 void setOs(const QString &os) { m_os = os; }
setMenu(const QString & menu)47 void setMenu(const QString &menu) { m_menu = menu; }
setKey(const QString & key)48 void setKey(const QString &key) { m_key = key; }
setFunc(const QString & func)49 void setFunc(const QString &func) { m_func = func; }
setCmd(const QString & cmd)50 void setCmd(const QString &cmd) { m_cmd = cmd; }
setArgs(const QString & args)51 void setArgs(const QString &args) { m_args = args; }
setSave(const QString & save)52 void setSave(const QString &save) { m_save = save; }
setDebug(const QString & text)53 void setDebug(const QString &text) {
54 m_debug = QVariant(text).toBool();
55 }
setOutput(const QString & text)56 void setOutput(const QString &text) {
57 m_output = QVariant(text).toBool();
58 }
setReadline(const QString & text)59 void setReadline(const QString &text) {
60 m_readline = QVariant(text).toBool();
61 }
setSeparator(const QString & text)62 void setSeparator(const QString &text) {
63 m_separator = QVariant(text).toBool();
64 }
setKillold(const QString & text)65 void setKillold(const QString &text) {
66 m_killold = QVariant(text).toBool();
67 }
setNavigate(const QString & text)68 void setNavigate(const QString &text) {
69 m_navigate = QVariant(text).toBool();
70 }
setFolder(const QString & text)71 void setFolder(const QString &text) {
72 m_folder = QVariant(text).toBool();
73 }
setTakeall(const QString & text)74 void setTakeall(const QString &text) {
75 m_takeall = QVariant(text).toBool();
76 }
setWork(const QString & work)77 void setWork(const QString &work) { m_work = work; }
setCodec(const QString & codec)78 void setCodec(const QString &codec) { m_codec = codec; }
setRegex(const QString & regex)79 void setRegex(const QString ®ex) { m_regex = regex; }
setImg(const QString & img)80 void setImg(const QString &img) {m_img = img; }
setTask(const QStringList & task)81 void setTask(const QStringList &task) { m_task = task; }
work()82 QString work() const { return m_work; }
id()83 QString id() const { return m_id; }
os()84 QString os() const { return m_os; }
menu()85 QString menu() const { return m_menu; }
key()86 QString key() const { return m_key; }
cmd()87 QString cmd() const { return m_cmd; }
func()88 QString func() const { return m_func; }
args()89 QString args() const { return m_args; }
save()90 QString save() const { return m_save; }
isDebug()91 bool isDebug() const { return m_debug; }
isOutput()92 bool isOutput() const { return m_output; }
isReadline()93 bool isReadline() const {return m_readline; }
isSeparator()94 bool isSeparator() const { return m_separator; }
isFolder()95 bool isFolder() const { return m_folder; }
isKillOld()96 bool isKillOld() const { return m_killold; }
isNavigate()97 bool isNavigate() const { return m_navigate; }
isTakeall()98 bool isTakeall() const { return m_takeall; }
codec()99 QString codec() const { return m_codec; }
regex()100 QString regex() const { return m_regex; }
img()101 QString img() const { return m_img; }
task()102 QStringList task() const { return m_task; }
clear()103 void clear() {
104 m_id.clear();
105 m_cmd.clear();
106 m_key.clear();
107 m_args.clear();
108 m_codec.clear();
109 m_regex.clear();
110 m_img.clear();
111 m_save.clear();
112 m_task.clear();
113 m_debug = false;
114 m_output = false;
115 m_readline = false;
116 m_separator = false;
117 m_killold = false;
118 m_folder = false;
119 m_takeall = false;
120 }
isEmpty()121 bool isEmpty() {
122 return m_id.isEmpty();
123 }
isHidden()124 bool isHidden() {
125 return m_id.isEmpty() || m_id[0].isLower();
126 }
127 protected:
128 QString m_id;
129 QString m_os;
130 QString m_key;
131 QString m_cmd;
132 QString m_func;
133 QString m_args;
134 QString m_codec;
135 QString m_regex;
136 QString m_save;
137 QString m_img;
138 QString m_work;
139 QString m_menu;
140 QStringList m_task;
141 bool m_debug;
142 bool m_output;
143 bool m_readline;
144 bool m_separator;
145 bool m_killold;
146 bool m_navigate;
147 bool m_folder;
148 bool m_takeall;
149 };
150
151 class BuildLookup
152 {
153 public:
BuildLookup()154 BuildLookup() : m_top(1)
155 {
156 }
setMimeType(const QString & type)157 void setMimeType(const QString &type) {m_type=type;}
setFile(const QString & file)158 void setFile(const QString &file) {m_file=file;}
setTop(const QString & top)159 void setTop(const QString &top) {
160 if (top.isEmpty()) {
161 return;
162 }
163 bool ok = false;
164 int value = top.toInt(&ok);
165 if (ok) {
166 m_top=value;
167 }
168 }
mimeType()169 QString mimeType() const {return m_type;}
file()170 QString file() const {return m_file;}
top()171 int top() const {return m_top;}
172 protected:
173 QString m_type;
174 QString m_file;
175 int m_top;
176 };
177
178 class BuildConfig
179 {
180 public:
BuildConfig()181 BuildConfig()
182 {
183 }
setId(const QString & id)184 void setId(const QString &id) { m_id = id; }
setName(const QString & name)185 void setName(const QString &name) { m_name = name; }
setValue(const QString & value)186 void setValue(const QString &value) { m_value = value; }
id()187 QString id() const { return m_id; }
name()188 QString name() const { return m_name; }
value()189 QString value() const { return m_value; }
190 protected:
191 QString m_id;
192 QString m_name;
193 QString m_value;
194 };
195
196 class BuildCustom
197 {
198 public:
BuildCustom()199 BuildCustom() : m_hasShared(false), m_isReadOnly(false), m_isEscaped(false)
200 {
201 }
setId(const QString & id)202 void setId(const QString &id) { m_id = id; }
setName(const QString & name)203 void setName(const QString &name) { m_name = name; }
setValue(const QString & value)204 void setValue(const QString &value) { m_value = value; }
setSharedValue(const QString & value)205 void setSharedValue(const QString &value) {
206 m_hasShared = true;
207 m_sharedValue = value;
208 }
setReadOnly(const QString & value)209 void setReadOnly(const QString &value)
210 {
211 m_isReadOnly = QVariant(value).toBool();
212 }
setEscaped(const QString & value)213 void setEscaped(const QString &value)
214 {
215 m_isEscaped = QVariant(value).toBool();
216 }
id()217 QString id() const { return m_id; }
name()218 QString name() const { return m_name; }
value()219 QString value() const { return m_value; }
hasShared()220 bool hasShared() const { return m_hasShared; }
sharedValue()221 QString sharedValue() const { return m_sharedValue; }
isReadOnly()222 bool isReadOnly() const { return m_isReadOnly; }
isEscaped()223 bool isEscaped() const { return m_isEscaped; }
224 protected:
225 QString m_id;
226 QString m_name;
227 QString m_value;
228 QString m_sharedValue;
229 bool m_hasShared;
230 bool m_isReadOnly;
231 bool m_isEscaped;
232 };
233
234 class BuildTarget
235 {
236 public:
BuildTarget()237 BuildTarget()
238 {
239 }
setId(const QString & id)240 void setId(const QString &id) { m_id = id; }
setCmd(const QString & cmd)241 void setCmd(const QString &cmd) { m_cmd = cmd; }
setDebug(const QString & debug)242 void setDebug(const QString &debug) { m_debug = debug; }
setArgs(const QString & args)243 void setArgs(const QString &args) { m_args = args; }
setWork(const QString & work)244 void setWork(const QString &work) { m_work = work; }
setBuildArgs(const QString & args)245 void setBuildArgs(const QString &args) { m_buildArgs = args; }
id()246 QString id() const { return m_id; }
cmd()247 QString cmd() const { return m_cmd; }
debug()248 QString debug() const { return m_debug; }
args()249 QString args() const { return m_args; }
work()250 QString work() const { return m_work; }
buildArgs()251 QString buildArgs() const { return m_buildArgs; }
isEmpty()252 bool isEmpty() {
253 return m_id.isEmpty();
254 }
255 protected:
256 QString m_id;
257 QString m_cmd;
258 QString m_debug;
259 QString m_buildArgs;
260 QString m_args;
261 QString m_work;
262 };
263
264 class IBuild : public QObject
265 {
266 Q_OBJECT
267 public:
QObject(parent)268 IBuild(QObject *parent = 0): QObject(parent) {}
~IBuild()269 virtual ~IBuild() {}
270 virtual QString mimeType() const = 0;
271 virtual QString id() const = 0;
272 virtual QString work() const = 0;
273 virtual QString lock() const = 0;
274 virtual QList<BuildAction*> actionList() const = 0;
275 virtual QList<BuildLookup*> lookupList() const = 0;
276 virtual QList<BuildConfig*> configList() const = 0;
277 virtual QList<BuildCustom*> customList() const = 0;
278 virtual QList<BuildTarget*> targetList() const = 0;
279 virtual BuildAction *findAction(const QString &name) = 0;
280 virtual QList<QAction*> actions() = 0;
281 signals:
282 void buildAction(LiteApi::IBuild *build, LiteApi::BuildAction *act);
283 };
284
285 class IBuildManager : public IManager
286 {
287 Q_OBJECT
288 public:
IManager(parent)289 IBuildManager(QObject *parent = 0) : IManager(parent) {}
290 virtual void addBuild(IBuild *build) = 0;
291 virtual void removeBuild(IBuild *build) = 0;
292 virtual IBuild *findBuild(const QString &mimeType) = 0;
293 virtual QList<IBuild*> buildList() const = 0;
294 virtual void setCurrentBuild(IBuild *build) = 0;
295 virtual IBuild *currentBuild() const = 0;
296 signals:
297 void buildChanged(LiteApi::IBuild*);
298 };
299
300 struct TargetInfo {
301 QString buildRootPath;
302 QString targetName;
303 QString debugName;
304 QString buildArgs;
305 QString targetArgs;
306 QString targetWorkDir;
307 };
308
309 class ILiteBuild : public IObject
310 {
311 Q_OBJECT
312 public:
ILiteBuild(QObject * parent)313 ILiteBuild(QObject *parent) : IObject(parent)
314 {
315 }
316 public:
317 virtual QString buildTag() const = 0;
318 virtual QMap<QString,QString> buildEnvMap() const = 0;
319 virtual TargetInfo getTargetInfo() = 0;
320 virtual IBuildManager *buildManager() const = 0;
321 virtual QString envValue(LiteApi::IBuild *build, const QString &value) = 0;
322 virtual QString buildPathEnvValue(LiteApi::IBuild *build, const QString &buildFilePath, const QString &value) = 0;
323 virtual void appendOutput(const QString &str, const QBrush &brush, bool active, bool updateExistsTextColor = true) = 0;
324 virtual void execCommand(const QString &cmd, const QString &args, const QString &workDir, bool updateExistsTextColor = true, bool activateOutputCheck = true, bool navigate = true, bool command = true) = 0;
325 virtual bool execGoCommand(const QStringList &args, const QString &work, bool waitFinish = true) = 0;
326 public slots:
327 virtual void execBuildAction(LiteApi::IBuild*,LiteApi::BuildAction*) = 0;
328 };
329
sourceBuildFilePath(const QString & filePath)330 inline QString sourceBuildFilePath(const QString &filePath)
331 {
332 QFileInfo info(filePath);
333 if (info.isDir()) {
334 return info.filePath();
335 }
336 return info.path();
337 }
338
editorBuildFilePath(IEditor * editor)339 inline QString editorBuildFilePath(IEditor *editor)
340 {
341 QString buildFilePath;
342 if (editor) {
343 QString filePath = editor->filePath();
344 if (!filePath.isEmpty()) {
345 buildFilePath = QFileInfo(filePath).path();
346 }
347 }
348 return buildFilePath;
349 }
350
351
getLiteBuild(LiteApi::IApplication * app)352 inline ILiteBuild *getLiteBuild(LiteApi::IApplication* app)
353 {
354 return LiteApi::findExtensionObject<ILiteBuild*>(app,"LiteApi.ILiteBuild");
355 }
356
getGoBuild(LiteApi::IApplication * app)357 inline IBuild *getGoBuild(LiteApi::IApplication *app)
358 {
359 ILiteBuild *build = getLiteBuild(app);
360 if (!build) {
361 return 0;
362 }
363 return build->buildManager()->findBuild("text/x-gosrc");
364 }
365
parserArgumentValue(const QString & opt,const QString & text)366 inline QString parserArgumentValue(const QString &opt, const QString &text)
367 {
368 int pos = text.indexOf(opt);
369 if (pos == -1) {
370 return QString();
371 }
372 QString value = text.mid(pos+opt.length());
373 if (value.startsWith('=')) {
374 value = value.mid(1);
375 } else if (value.startsWith(' ')) {
376 value = value.trimmed();
377 }
378 if (value.isEmpty()) {
379 return QString();
380 }
381 if (value.startsWith('\'')) {
382 int pos = value.indexOf('\'',1);
383 if (pos != -1) {
384 return value.left(pos+1);
385 }
386 } else if (value.startsWith('\"')) {
387 int pos = value.indexOf('\"',1);
388 if (pos != -1) {
389 return value.left(pos+1);
390 }
391 } else {
392 int pos = value.indexOf(' ');
393 if (pos != -1) {
394 return value.left(pos);
395 }
396 return value;
397 }
398 return QString();
399 }
400
getGoBuildFlagsArgument(LiteApi::IApplication * app,const QString & buildFilePath,const QString & opt)401 inline QString getGoBuildFlagsArgument(LiteApi::IApplication *app, const QString &buildFilePath, const QString &opt)
402 {
403 ILiteBuild *liteBuild = getLiteBuild(app);
404 LiteApi::IBuild *build = getGoBuild(app);
405 if (!liteBuild || !build ) {
406 return QString();
407 }
408 QString value = liteBuild->buildPathEnvValue(build,buildFilePath,"$(BUILDFLAGS)");
409 QString tags = parserArgumentValue(opt,value);
410 if (tags.isEmpty()) {
411 value = liteBuild->buildPathEnvValue(build,buildFilePath,"$(BUILDARGS)");
412 tags = parserArgumentValue(opt,value);
413 }
414 return tags;
415 }
416
getGoBuildFlagsArgument(LiteApi::IApplication * app,LiteApi::IEditor * editor,const QString & opt)417 inline QString getGoBuildFlagsArgument(LiteApi::IApplication *app, LiteApi::IEditor *editor, const QString &opt)
418 {
419 ILiteBuild *liteBuild = getLiteBuild(app);
420 if (!liteBuild) {
421 return QString();
422 }
423 QString buildFilePath = editorBuildFilePath(editor);
424 return getGoBuildFlagsArgument(app,buildFilePath,opt);
425 }
426
427 } //namespace LiteApi
428
429
430 #endif //LITEBUILDAPI_H
431
432