Salt package installation/uninstallation even and hooks.

This commit is contained in:
Matthias Koefferlein 2022-10-02 19:33:21 +02:00
parent 3b6ef57ddc
commit 2c96cc2a41
7 changed files with 104 additions and 5 deletions

View File

@ -209,4 +209,27 @@
subversion equivalent.
</p>
<h2>Installation Hooks</h2>
<p>
Scripts can register an event through <class_doc href="Application#on_salt_changed"/> which
indicates that packages have been installed or uninstalled.
</p>
<p>
Packages itself can supply special scripts which are executed after a package was installed
or before a package is uninstalled:
</p>
<ul>
<li><tt>_install.lym</tt>: if present, this script is executed after the package is installed.</li>
<li><tt>_uninstall.lym</tt>: if present, this script is executed before the package is uninstalled.</li>
</ul>
<p>
Both scripts need to be stored in the same location as "grain.xml" and have to use
"lym" format. This is the generic XML script format KLayout employs as an interpreter-agnostic
script representation.
</p>
</doc>

View File

@ -24,6 +24,7 @@
#include "layMainWindow.h"
#include "laySignalHandler.h"
#include "gsiDecl.h"
#include "gsiSignals.h"
#include "tlArch.h"
#if defined(HAVE_QTBINDINGS)
@ -243,6 +244,14 @@ static gsi::Methods application_methods ()
"\n"
"There is exactly one instance of the application. This instance can be obtained with this "
"method."
) +
event<C> ("on_salt_changed", &C::salt_changed_event,
"@brief This event is triggered when the package status changes.\n"
"\n"
"Register to this event if you are interested in package changes - i.e. installation or removal of packages or "
"package updates.\n"
"\n"
"This event has been introduced in version 0.28."
)
;
}

View File

@ -672,6 +672,8 @@ ApplicationBase::init_app ()
}
}
sc->salt_changed_event.add (this, &ApplicationBase::salt_changed);
}
if (tc) {
@ -852,6 +854,14 @@ ApplicationBase::add_macro_category (const std::string &name, const std::string
}
}
void
ApplicationBase::salt_changed ()
{
BEGIN_PROTECTED_SILENT
salt_changed_event ();
END_PROTECTED_SILENT
}
ApplicationBase::~ApplicationBase ()
{
tl::set_ui_exception_handlers (0, 0, 0);

View File

@ -26,6 +26,7 @@
#include "layCommon.h"
#include "layBusy.h"
#include "tlEvents.h"
#include <QApplication>
#include <QEventLoop>
@ -76,7 +77,7 @@ class LayoutView;
* and one for the GUI version (derived from QApplication).
*/
class LAY_PUBLIC ApplicationBase
: public gsi::ObjectBase
: public gsi::ObjectBase, public tl::Object
{
public:
/**
@ -313,6 +314,11 @@ public:
*/
void init_app ();
/**
* @brief An event indicating that the package collection has changed
*/
tl::Event salt_changed_event;
/**
* @brief Gets the QApplication object
* This method will return non-null only if a GUI-enabled application is present.
@ -376,6 +382,8 @@ private:
// in order to maintain a valid MainWindow reference for ruby scripts and Ruby's GC all the time.
gsi::Interpreter *mp_ruby_interpreter;
gsi::Interpreter *mp_python_interpreter;
void salt_changed ();
};
/**

View File

@ -26,6 +26,7 @@
#include "tlLog.h"
#include "tlInternational.h"
#include "tlWebDAV.h"
#include "lymMacro.h"
#include <QFileInfo>
#include <QDir>
@ -281,6 +282,21 @@ Salt::remove_grain (const SaltGrain &grain)
QString name = tl::to_qstring (grain.name ());
tl::info << QObject::tr ("Removing package '%1' ..").arg (name);
// Execute "_uninstall.lym" if it exists
try {
QFile uninstall_lym (QDir (tl::to_qstring (grain.path ())).absoluteFilePath (tl::to_qstring ("_uninstall.lym")));
if (uninstall_lym.exists ()) {
lym::Macro uninstall;
uninstall.load_from (tl::to_string (uninstall_lym.fileName ()));
uninstall.set_file_path (tl::to_string (uninstall_lym.fileName ()));
uninstall.run ();
}
} catch (tl::Exception &ex) {
// Errors in the uninstallation script are only logged, but do not prevent uninstallation
tl::error << ex.msg ();
}
bool res = remove_from_collection (m_root, grain.name ());
if (res) {
tl::info << QObject::tr ("Package '%1' removed.").arg (name);
@ -493,10 +509,25 @@ Salt::create_grain (const SaltGrain &templ, SaltGrain &target, double timeout, t
if (res) {
tl::info << QObject::tr ("Package '%1' installed").arg (tl::to_qstring (target.name ()));
target.set_installed_time (QDateTime::currentDateTime ());
target.save ();
// Execute "_install.lym" if it exists
try {
QFile install_lym (QDir (tl::to_qstring (target.path ())).absoluteFilePath (tl::to_qstring ("_install.lym")));
if (install_lym.exists ()) {
lym::Macro install;
install.load_from (tl::to_string (install_lym.fileName ()));
install.set_file_path (tl::to_string (install_lym.fileName ()));
install.run ();
}
} catch (tl::Exception &ex) {
// Errors in the installation script are only logged, but do not prevent installation
tl::error << ex.msg ();
}
tl::info << QObject::tr ("Package '%1' installed").arg (tl::to_qstring (target.name ()));
// NOTE: this is a bit brute force .. we could as well try to insert the new grain into the existing structure
refresh ();

View File

@ -58,13 +58,13 @@ SaltController::initialized (lay::Dispatcher * /*root*/)
connect (m_file_watcher, SIGNAL (fileRemoved (const QString &)), this, SLOT (file_watcher_triggered ()));
}
connect (&m_salt, SIGNAL (collections_changed ()), this, SIGNAL (salt_changed ()));
connect (&m_salt, SIGNAL (collections_changed ()), this, SLOT (emit_salt_changed ()));
}
void
SaltController::uninitialize (lay::Dispatcher * /*root*/)
{
disconnect (&m_salt, SIGNAL (collections_changed ()), this, SIGNAL (salt_changed ()));
disconnect (&m_salt, SIGNAL (collections_changed ()), this, SLOT (emit_salt_changed ()));
if (m_file_watcher) {
disconnect (m_file_watcher, SIGNAL (fileChanged (const QString &)), this, SLOT (file_watcher_triggered ()));
@ -168,7 +168,7 @@ void
SaltController::sync_files ()
{
tl::log << tl::to_string (tr ("Detected file system change in packages - updating"));
emit salt_changed ();
emit_salt_changed ();
}
bool
@ -242,6 +242,13 @@ SaltController::file_watcher_triggered ()
dm_sync_files ();
}
void
SaltController::emit_salt_changed ()
{
salt_changed_event ();
emit salt_changed ();
}
void
SaltController::set_salt_mine_url (const std::string &url)
{

View File

@ -29,6 +29,7 @@
#include "laySalt.h"
#include "tlFileSystemWatcher.h"
#include "tlDeferredExecution.h"
#include "tlEvents.h"
#include <vector>
#include <string>
@ -171,6 +172,11 @@ public:
return m_salt;
}
/**
* @brief Event-style version of "salt_changed"
*/
tl::Event salt_changed_event;
/**
* @brief Gets the singleton instance for this object
*/
@ -182,6 +188,11 @@ private slots:
*/
void file_watcher_triggered ();
/**
* @brief Emits a salt_changed event + signal
*/
void emit_salt_changed ();
signals:
/**
* @brief This signal is emitted if the salt changed