From fd6e173bcaf1e4e3753b3d9549888adde88e9a70 Mon Sep 17 00:00:00 2001 From: guinux <nuxgui@gmail.com> Date: Fri, 24 Aug 2018 18:32:36 +0200 Subject: [PATCH] enhance modularity and add python bindings --- examples/{ => alpm}/pactree.vala | 0 examples/python/empty_transaction.py | 53 + examples/python/list_installed_pkgs.py | 15 + examples/python/list_installed_pkgs_async.py | 28 + resources/pamac.manager.gresource.xml | 4 + resources/pamac.transaction.gresource.xml | 4 - src/clean_cache.vala | 4 +- src/cli.vala | 2456 +++++------------- src/common.vala | 1 - src/common_daemon.vala | 52 + src/database.vala | 555 ++++ src/installer.vala | 90 +- src/manager.vala | 1 + src/manager_window.vala | 492 ++-- src/meson.build | 51 +- src/pamac_config.vala | 37 +- src/preferences_dialog.vala | 52 +- src/system_daemon.vala | 106 +- src/transaction-cli.vala | 479 ++++ src/transaction-gtk.vala | 480 ++++ src/transaction.vala | 1555 +++-------- src/tray.vala | 8 +- src/updates_priv.vala | 26 + src/user_daemon.vala | 58 +- src/version.vala | 2 +- 25 files changed, 3139 insertions(+), 3470 deletions(-) rename examples/{ => alpm}/pactree.vala (100%) create mode 100755 examples/python/empty_transaction.py create mode 100755 examples/python/list_installed_pkgs.py create mode 100755 examples/python/list_installed_pkgs_async.py create mode 100644 src/common_daemon.vala create mode 100644 src/database.vala create mode 100644 src/transaction-cli.vala create mode 100644 src/transaction-gtk.vala create mode 100644 src/updates_priv.vala diff --git a/examples/pactree.vala b/examples/alpm/pactree.vala similarity index 100% rename from examples/pactree.vala rename to examples/alpm/pactree.vala diff --git a/examples/python/empty_transaction.py b/examples/python/empty_transaction.py new file mode 100755 index 00000000..b359f8fe --- /dev/null +++ b/examples/python/empty_transaction.py @@ -0,0 +1,53 @@ +#!/usr/bin/python + +import gi +gi.require_version('Pamac', '1.0') +from gi.repository import GLib, Pamac + +def on_emit_action (transaction, action, data): + print(action) + +def on_emit_action_progress (transaction, action, status, progress, data): + print("{} {}".format(action, status)) + +def on_emit_warning (transaction, message, data): + print(message) + +def on_emit_error (transaction, message, details, details_length, data): + if details_length > 0: + print("{}:".format(message)) + for detail in details: + print(detail) + else: + print(message) + +def start_transaction(): + # /!\ the transaction will run without confirmation /!\ + # you need to override Transaction.ask_confirmation() method + # in order to implement your own confirmation step + to_install = [] + to_remove = [] + to_load = [] + to_build = [] + overwrite_files = [] + if transaction.get_lock(): + transaction.start (to_install, to_remove, to_load, to_build, overwrite_files) + # launch a loop to wait for finished signal to be emitted + loop.run() + +def on_trans_finished (transaction, success, data): + transaction.unlock() + loop.quit() + +if __name__ == "__main__": + loop = GLib.MainLoop() + config = Pamac.Config(conf_path="/etc/pamac.conf") + db = Pamac.Database(config=config) + transaction = Pamac.Transaction(database=db) + data = None + transaction.connect ("emit-action", on_emit_action, data) + transaction.connect ("emit-action-progress", on_emit_action_progress, data) + transaction.connect ("emit-error", on_emit_error, data) + transaction.connect ("emit-warning", on_emit_warning, data) + transaction.connect ("finished", on_trans_finished, data) + start_transaction() diff --git a/examples/python/list_installed_pkgs.py b/examples/python/list_installed_pkgs.py new file mode 100755 index 00000000..a422b790 --- /dev/null +++ b/examples/python/list_installed_pkgs.py @@ -0,0 +1,15 @@ +#!/usr/bin/python + +import gi +gi.require_version('Pamac', '1.0') +from gi.repository import Pamac + +def list_installed_pkgs(): + pkgs = db.get_installed_pkgs() + for pkg in pkgs: + print(pkg.name, pkg.version) + +if __name__ == "__main__": + config = Pamac.Config(conf_path="/etc/pamac.conf") + db = Pamac.Database(config=config) + list_installed_pkgs() diff --git a/examples/python/list_installed_pkgs_async.py b/examples/python/list_installed_pkgs_async.py new file mode 100755 index 00000000..ded6c960 --- /dev/null +++ b/examples/python/list_installed_pkgs_async.py @@ -0,0 +1,28 @@ +#!/usr/bin/python + +import gi +gi.require_version('Pamac', '1.0') +from gi.repository import GLib, Pamac + +def on_installed_pkgs_ready_callback(source_object, result, user_data): + try: + pkgs = source_object.get_installed_pkgs_finish(result) + except GLib.GError as e: + print("Error: ", e.message) + else: + for pkg in pkgs: + print(pkg.name, pkg.version) + finally: + loop.quit() + +def list_installed_pkgs_async(): + pkgs = db.get_installed_pkgs_async(on_installed_pkgs_ready_callback, None) + # launch a loop to wait for the callback to be called + loop.run() + +if __name__ == "__main__": + loop = GLib.MainLoop() + config = Pamac.Config(conf_path="/etc/pamac.conf") + db = Pamac.Database(config=config) + list_installed_pkgs_async() + diff --git a/resources/pamac.manager.gresource.xml b/resources/pamac.manager.gresource.xml index b1b7a6b3..3e773005 100644 --- a/resources/pamac.manager.gresource.xml +++ b/resources/pamac.manager.gresource.xml @@ -13,4 +13,8 @@ <file preprocess="to-pixdata">package-upgrade.png</file> <file preprocess="to-pixdata">package-generic.png</file> </gresource> + <gresource prefix="/org/manjaro/pamac/preferences"> + <file preprocess="xml-stripblanks">preferences_dialog.ui</file> + <file preprocess="xml-stripblanks">choose_ignorepkgs_dialog.ui</file> + </gresource> </gresources> diff --git a/resources/pamac.transaction.gresource.xml b/resources/pamac.transaction.gresource.xml index 90c24d15..8963a0b2 100644 --- a/resources/pamac.transaction.gresource.xml +++ b/resources/pamac.transaction.gresource.xml @@ -6,8 +6,4 @@ <file preprocess="xml-stripblanks">choose_provider_dialog.ui</file> <file preprocess="xml-stripblanks">transaction_sum_dialog.ui</file> </gresource> - <gresource prefix="/org/manjaro/pamac/preferences"> - <file preprocess="xml-stripblanks">preferences_dialog.ui</file> - <file preprocess="xml-stripblanks">choose_ignorepkgs_dialog.ui</file> - </gresource> </gresources> diff --git a/src/clean_cache.vala b/src/clean_cache.vala index 060496b6..5bbc563c 100644 --- a/src/clean_cache.vala +++ b/src/clean_cache.vala @@ -20,11 +20,11 @@ int main () { var pamac_config = new Pamac.Config ("/etc/pamac.conf"); string rm_only_uninstalled_str = ""; - if (pamac_config.rm_only_uninstalled) { + if (pamac_config.clean_rm_only_uninstalled) { rm_only_uninstalled_str = "-u"; } try { - Process.spawn_command_line_sync ("paccache -q --nocolor %s -r -k %llu".printf (rm_only_uninstalled_str, pamac_config.keep_num_pkgs)); + Process.spawn_command_line_sync ("paccache -q --nocolor %s -r -k %llu".printf (rm_only_uninstalled_str, pamac_config.clean_keep_num_pkgs)); } catch (SpawnError e) { stderr.printf ("SpawnError: %s\n", e.message); } diff --git a/src/cli.vala b/src/cli.vala index 1c6c6a98..b1ea7758 100644 --- a/src/cli.vala +++ b/src/cli.vala @@ -18,136 +18,42 @@ */ namespace Pamac { - [DBus (name = "org.manjaro.pamac.user")] - interface UserDaemon : Object { - public abstract AlpmPackage get_installed_pkg (string pkgname) throws Error; - public abstract AlpmPackage[] get_installed_pkgs_sync () throws Error; - public abstract AlpmPackage[] get_foreign_pkgs_sync () throws Error; - public abstract AlpmPackage[] get_orphans_sync () throws Error; - public abstract AlpmPackage find_installed_satisfier (string depstring) throws Error; - public abstract AlpmPackage get_sync_pkg (string pkgname) throws Error; - public abstract AlpmPackage find_sync_satisfier (string depstring) throws Error; - public abstract AlpmPackage[] search_pkgs_sync (string search_string) throws Error; - public abstract async AURPackage[] search_in_aur (string search_string) throws Error; - public abstract string[] get_repos_names () throws Error; - public abstract AlpmPackage[] get_repo_pkgs_sync (string repo) throws Error; - public abstract string[] get_groups_names () throws Error; - public abstract AlpmPackage[] get_group_pkgs_sync (string groupname) throws Error; - public abstract AlpmPackageDetails get_pkg_details (string pkgname, string app_name) throws Error; - public abstract string[] get_pkg_files (string pkgname) throws Error; - public abstract HashTable<string,Variant> search_files (string[] files) throws Error; - public abstract async AURPackageDetails get_aur_details (string pkgname) throws Error; - public abstract void start_get_updates (bool check_aur_updates, bool refresh_files_dbs) throws Error; - [DBus (no_reply = true)] - public abstract void quit () throws Error; - public signal void get_updates_finished (Updates updates); - } - [DBus (name = "org.manjaro.pamac.system")] - interface SystemDaemon : Object { - public abstract void set_environment_variables (HashTable<string,string> variables) throws Error; - public abstract ErrorInfos get_current_error () throws Error; - public abstract bool get_lock () throws Error; - public abstract bool unlock () throws Error; - public abstract void start_get_authorization () throws Error; - public abstract void clean_cache (uint64 keep_nb, bool only_uninstalled) throws Error; - public abstract void start_set_pkgreason (string pkgname, uint reason) throws Error; - public abstract void start_refresh (bool force) throws Error; - public abstract void start_sysupgrade_prepare (bool enable_downgrade, string[] temporary_ignorepkgs, string[] to_build, string[] overwrite_files) throws Error; - public abstract void start_trans_prepare (int transflags, string[] to_install, string[] to_remove, string[] to_load, string[] to_build, string[] overwrite_files) throws Error; - public abstract void choose_provider (int provider) throws Error; - public abstract TransactionSummary get_transaction_summary () throws Error; - public abstract void start_trans_commit () throws Error; - public abstract void trans_release () throws Error; - public abstract void trans_cancel () throws Error; - public abstract void start_get_updates (bool check_aur_updates) throws Error; - [DBus (no_reply = true)] - public abstract void quit () throws Error; - public signal void get_updates_finished (Updates updates); - public signal void emit_event (uint primary_event, uint secondary_event, string[] details); - public signal void emit_providers (string depend, string[] providers); - public signal void emit_progress (uint progress, string pkgname, uint percent, uint n_targets, uint current_target); - public signal void emit_download (string filename, uint64 xfered, uint64 total); - public signal void emit_totaldownload (uint64 total); - public signal void emit_log (uint level, string msg); - public signal void set_pkgreason_finished (); - public signal void refresh_finished (bool success); - public signal void trans_prepare_finished (bool success); - public signal void trans_commit_finished (bool success); - public signal void get_authorization_finished (bool authorized); - } - class Cli: GLib.Application { - enum TransType { - STANDARD = (1 << 0), - UPDATE = (1 << 1), - BUILD = (1 << 2) - } public ApplicationCommandLine cmd; - UserDaemon user_daemon; - SystemDaemon system_daemon; - Pamac.Config pamac_config; - int transflags; + public TransactionCli transaction; + public Database database; + delegate void TransactionAction (); string[] to_install; string[] to_remove; string[] to_load; string[] to_build; - uint64 total_download; - uint64 already_downloaded; - string previous_textbar; - float previous_percent; - string previous_filename; - string current_action; - string previous_action; - bool enable_aur; bool force_refresh; bool enable_downgrade; - bool sysupgrade_after_trans; - bool no_confirm_commit; - bool building; - bool asking_user_input; - uint64 previous_xfered; - uint64 download_rate; - uint64 rates_nb; - Timer timer; - string aur_build_dir; string[] temporary_ignorepkgs; string[] overwrite_files; - Queue<string> to_build_queue; - string[] aur_pkgs_to_install; - string[] to_install_first; - Cancellable build_cancellable; Subprocess pkttyagent; public Cli () { application_id = "org.manjaro.pamac.cli"; flags = ApplicationFlags.HANDLES_COMMAND_LINE; - pamac_config = new Pamac.Config ("/etc/pamac.conf"); - transflags = 0; to_install = {}; to_remove = {}; to_load = {}; to_build = {}; - // progress data - previous_textbar = ""; - previous_filename = ""; - previous_action = ""; - enable_aur = false; force_refresh = false; enable_downgrade = false; - sysupgrade_after_trans = false; - no_confirm_commit = false; - building = false; - asking_user_input = false; - timer = new Timer (); - aur_build_dir = pamac_config.aur_build_dir; - temporary_ignorepkgs = {}; overwrite_files = {}; - to_build_queue = new Queue<string> (); - build_cancellable = new Cancellable (); + var config = new Config ("/etc/pamac.conf"); + database = new Database (config); + transaction = new TransactionCli (database); + transaction.finished.connect (on_transaction_finished); + transaction.sysupgrade_finished.connect (on_transaction_finished); + transaction.refresh_finished.connect (on_refresh_finished); + // Use tty polkit authentication agent try { - user_daemon = Bus.get_proxy_sync (BusType.SESSION, "org.manjaro.pamac.user", "/org/manjaro/pamac/user"); + pkttyagent = new Subprocess.newv ({"pkttyagent"}, SubprocessFlags.NONE); } catch (Error e) { - print_error (e.message); + stdout.printf ("%s: %s\n", dgettext (null, "Error"), e.message); } // watch CTRl + C Unix.signal_add (Posix.Signal.INT, trans_cancel); @@ -273,7 +179,7 @@ namespace Pamac { if (args[2] == "--help" || args[2] == "-h") { display_build_help (); } else if (args[2] == "--builddir") { - aur_build_dir = args[3]; + transaction.database.config.aur_build_dir = args[3]; build_pkgs (args[4:args.length]); } else { build_pkgs (args[2:args.length]); @@ -338,7 +244,8 @@ namespace Pamac { if (args[2] == "--help" || args[2] == "-h") { display_checkupdates_help (); } else if (args[2] == "--aur" || args[2] == "-a") { - enable_aur = true; + transaction.database.config.enable_aur = true; + transaction.database.config.check_aur_updates = true; checkupdates (); } else { display_checkupdates_help (); @@ -356,9 +263,10 @@ namespace Pamac { error = true; break; } else if (arg == "--aur"|| arg == "-a") { - enable_aur = true; + transaction.database.config.enable_aur = true; + transaction.database.config.check_aur_updates = true; } else if (arg == "--builddir") { - aur_build_dir = args[i+1]; + transaction.database.config.aur_build_dir = args[i+1]; i++; } else if (arg == "--force-refresh") { force_refresh = true; @@ -382,7 +290,7 @@ namespace Pamac { i++; } if (!error) { - start_refresh (); + try_lock_and_run (start_refresh); } } else { display_help (); @@ -392,70 +300,23 @@ namespace Pamac { public override void shutdown () { base.shutdown (); - try { - user_daemon.quit (); - if (system_daemon != null) { - system_daemon.quit (); - pkttyagent.force_exit (); - } - } catch (Error e) { - print_error (e.message); - } + database.stop_daemon (); + transaction.stop_daemon (); + pkttyagent.force_exit (); } bool trans_cancel () { - if (building) { - build_cancellable.cancel (); - } else if (asking_user_input) { - try { - system_daemon.trans_release (); - } catch (Error e) { - print_error (e.message); - } + if (transaction.asking_user_input) { + transaction.release (); } else { - try { - system_daemon.trans_cancel (); - } catch (Error e) { - print_error (e.message); - } + transaction.cancel (); } - stdout.printf ("\n%s.\n", dgettext (null, "Transaction cancelled")); + stdout.printf ("\n"); this.release (); cmd.set_exit_status (1); return false; } - void connecting_system_daemon () { - if (system_daemon == null) { - try { - system_daemon = Bus.get_proxy_sync (BusType.SYSTEM, "org.manjaro.pamac.system", "/org/manjaro/pamac/system"); - // Set environment variables - system_daemon.set_environment_variables (pamac_config.environment_variables); - system_daemon.emit_event.connect (on_emit_event); - system_daemon.emit_providers.connect (on_emit_providers); - system_daemon.emit_progress.connect (on_emit_progress); - system_daemon.emit_download.connect (on_emit_download); - system_daemon.emit_totaldownload.connect (on_emit_totaldownload); - system_daemon.emit_log.connect (on_emit_log); - system_daemon.trans_prepare_finished.connect (on_trans_prepare_finished); - system_daemon.trans_commit_finished.connect (on_trans_commit_finished); - // Use tty polkit authentication agent - pkttyagent = new Subprocess.newv ({"pkttyagent"}, SubprocessFlags.NONE); - } catch (Error e) { - print_error (e.message); - } - } - } - - int get_term_width () { - int width = 80; - Linux.winsize win; - if (Linux.ioctl (Posix.STDOUT_FILENO, Linux.Termios.TIOCGWINSZ, out win) == 0) { - width = win.ws_col; - } - return width; - } - string concatenate_strings (string[] list) { var str_builder = new StringBuilder (); foreach (unowned string str in list) { @@ -468,7 +329,7 @@ namespace Pamac { } string[] split_string (string str, int margin, int width = 0) { - int term_width = get_term_width (); + int term_width = transaction.get_term_width (); if (width == 0) { width = term_width; } @@ -517,31 +378,8 @@ namespace Pamac { stdout.printf ("%s\n", str_builder.str); } - void print_progress (string action, string state, bool new_line) { - var str_builder = new StringBuilder (); - str_builder.append (action); - int width = get_term_width () - action.char_count () - 1; - if (new_line) { - stdout.printf ("%s %*s\n", action, width, state); - } else { - stdout.printf ("%s %*s\r", action, width, state); - } - stdout.flush (); - } - - void print_error (string msg, string[] details = {}) { - if (details.length > 0) { - if (details.length == 1) { - stdout.printf ("%s: %s: %s\n", dgettext (null, "Error"), msg, details[0]); - } else { - stdout.printf ("%s: %s:\n", dgettext (null, "Error"), msg); - foreach (unowned string detail in details) { - stdout.printf ("%s\n", detail); - } - } - } else { - stdout.printf ("%s: %s\n", dgettext (null, "Error"), msg); - } + void print_error (string message) { + stdout.printf ("%s: %s\n", dgettext (null, "Error"), message); cmd.set_exit_status (1); } @@ -807,29 +645,84 @@ namespace Pamac { } void search_pkgs (string search_string) { - try { - var pkgs = user_daemon.search_pkgs_sync (search_string); + var pkgs = database.search_pkgs (search_string); + if (pkgs.length == 0) { + cmd.set_exit_status (1); + return; + } + int version_length = 0; + int repo_length = 0; + foreach (unowned AlpmPackage pkg in pkgs) { + if (pkg.version.length > version_length) { + version_length = pkg.version.length; + } + if (pkg.repo.length > repo_length) { + repo_length = pkg.repo.length; + } + } + int available_width = transaction.get_term_width () - (version_length + repo_length + 3); + foreach (unowned AlpmPackage pkg in pkgs) { + string name = pkg.name; + if (pkg.origin == 2) { + name = "%s [%s]".printf (pkg.name, dgettext (null, "Installed")); + } + var str_builder = new StringBuilder (); + str_builder.append (name); + str_builder.append (" "); + int diff = available_width - name.char_count (); + if (diff > 0) { + while (diff > 0) { + str_builder.append (" "); + diff--; + } + } + str_builder.append ("%-*s %s \n".printf (version_length, pkg.version, pkg.repo)); + stdout.printf ("%s", str_builder.str); + string[] cuts = split_string (pkg.desc, 2, available_width); + foreach (unowned string cut in cuts) { + print_aligned ("", cut, 2); + } + } + } + + void search_in_aur (string search_string) { + this.hold (); + database.search_in_aur_async.begin (search_string, (obj,res) => { + AURPackage[] pkgs = database.search_in_aur_async.end (res); if (pkgs.length == 0) { + this.release (); cmd.set_exit_status (1); return; } int version_length = 0; - int repo_length = 0; - foreach (unowned AlpmPackage pkg in pkgs) { + foreach (unowned AURPackage pkg in pkgs) { if (pkg.version.length > version_length) { version_length = pkg.version.length; } - if (pkg.repo.length > repo_length) { - repo_length = pkg.repo.length; - } } - int available_width = get_term_width () - (version_length + repo_length + 3); - foreach (unowned AlpmPackage pkg in pkgs) { + int aur_length = dgettext (null, "AUR").char_count (); + int available_width = transaction.get_term_width () - (version_length + aur_length + 3); + // sort aur pkgs by popularity + var results = new List<AURPackage?> (); + foreach (unowned AURPackage pkg in pkgs) { + results.append (pkg); + } + results.sort ((pkg1, pkg2) => { + double diff = pkg2.popularity - pkg1.popularity; + if (diff < 0) { + return -1; + } else if (diff > 0) { + return 1; + } else { + return 0; + } + }); + foreach (unowned AURPackage pkg in results) { + var str_builder = new StringBuilder (); string name = pkg.name; - if (pkg.origin == 2) { + if (pkg.installed_version != "") { name = "%s [%s]".printf (pkg.name, dgettext (null, "Installed")); } - var str_builder = new StringBuilder (); str_builder.append (name); str_builder.append (" "); int diff = available_width - name.char_count (); @@ -839,76 +732,13 @@ namespace Pamac { diff--; } } - str_builder.append ("%-*s %s \n".printf (version_length, pkg.version, pkg.repo)); + str_builder.append ("%-*s %s \n".printf (version_length, pkg.version, dgettext (null, "AUR"))); stdout.printf ("%s", str_builder.str); string[] cuts = split_string (pkg.desc, 2, available_width); foreach (unowned string cut in cuts) { print_aligned ("", cut, 2); } } - } catch (Error e) { - print_error (e.message); - } - } - - void search_in_aur (string search_string) { - this.hold (); - user_daemon.search_in_aur.begin (search_string, (obj,res) => { - try { - AURPackage[] pkgs = user_daemon.search_in_aur.end (res); - if (pkgs.length == 0) { - this.release (); - cmd.set_exit_status (1); - return; - } - int version_length = 0; - foreach (unowned AURPackage pkg in pkgs) { - if (pkg.version.length > version_length) { - version_length = pkg.version.length; - } - } - int aur_length = dgettext (null, "AUR").char_count (); - int available_width = get_term_width () - (version_length + aur_length + 3); - // sort aur pkgs by popularity - var results = new List<AURPackage?> (); - foreach (unowned AURPackage pkg in pkgs) { - results.append (pkg); - } - results.sort ((pkg1, pkg2) => { - double diff = pkg2.popularity - pkg1.popularity; - if (diff < 0) { - return -1; - } else if (diff > 0) { - return 1; - } else { - return 0; - } - }); - foreach (unowned AURPackage pkg in results) { - var str_builder = new StringBuilder (); - string name = pkg.name; - if (pkg.installed_version != "") { - name = "%s [%s]".printf (pkg.name, dgettext (null, "Installed")); - } - str_builder.append (name); - str_builder.append (" "); - int diff = available_width - name.char_count (); - if (diff > 0) { - while (diff > 0) { - str_builder.append (" "); - diff--; - } - } - str_builder.append ("%-*s %s \n".printf (version_length, pkg.version, dgettext (null, "AUR"))); - stdout.printf ("%s", str_builder.str); - string[] cuts = split_string (pkg.desc, 2, available_width); - foreach (unowned string cut in cuts) { - print_aligned ("", cut, 2); - } - } - } catch (Error e) { - print_error (e.message); - } this.release (); }); } @@ -944,40 +774,253 @@ namespace Pamac { } } foreach (unowned string pkgname in pkgnames) { - try { - var details = user_daemon.get_pkg_details (pkgname, ""); + var details = database.get_pkg_details (pkgname, ""); + if (details.name == "") { + print_error (dgettext (null, "target not found: %s").printf (pkgname) + "\n"); + continue; + } + // Name + print_aligned (properties[0], ": %s".printf (details.name), max_length); + // Version + print_aligned (properties[1], ": %s".printf (details.version), max_length); + // Description + string[] cuts = split_string (details.desc, max_length + 2); + print_aligned (properties[2], ": %s".printf (cuts[0]), max_length); + int i = 1; + while (i < cuts.length) { + print_aligned ("", "%s".printf (cuts[i]), max_length + 2); + i++; + } + // URL + print_aligned (properties[3], ": %s".printf (details.url), max_length); + // Licenses + print_aligned (properties[4], ": %s".printf (details.licenses[0]), max_length); + i = 1; + while (i < details.licenses.length) { + print_aligned ("", "%s".printf (details.licenses[i]), max_length + 2); + i++; + } + // Repository + print_aligned (properties[5], ": %s".printf (details.repo), max_length); + // Size + print_aligned (properties[6], ": %s".printf (format_size (details.size)), max_length); + // Groups + if (details.groups.length > 0) { + cuts = split_string (concatenate_strings (details.groups), max_length + 2); + print_aligned (properties[7], ": %s".printf (cuts[0]), max_length); + i = 1; + while (i < cuts.length) { + print_aligned ("", "%s".printf (cuts[i]), max_length + 2); + i++; + } + } + // Depends + if (details.depends.length > 0) { + cuts = split_string (concatenate_strings (details.depends), max_length + 2); + print_aligned (properties[8], ": %s".printf (cuts[0]), max_length); + i = 1; + while (i < cuts.length) { + print_aligned ("", "%s".printf (cuts[i]), max_length + 2); + i++; + } + } + // Opt depends + if (details.optdepends.length > 0) { + string depstring = details.optdepends[0]; + var satisfier = AlpmPackage (); + satisfier = database.find_installed_satisfier (depstring); + if (satisfier.name != "") { + depstring = "%s [%s]".printf (depstring, dgettext (null, "Installed")); + } + cuts = split_string (depstring, max_length + 2); + print_aligned (properties[9], ": %s".printf (cuts[0]), max_length); + i = 1; + while (i < cuts.length) { + print_aligned ("", "%s".printf (cuts[i]), max_length + 2); + i++; + } + i = 1; + while (i < details.optdepends.length) { + depstring = details.optdepends[i]; + satisfier = AlpmPackage (); + satisfier = database.find_installed_satisfier (depstring); + if (satisfier.name != "") { + depstring = "%s [%s]".printf (depstring, dgettext (null, "Installed")); + } + cuts = split_string (depstring, max_length + 2); + int j = 0; + while (j < cuts.length) { + print_aligned ("", "%s".printf (cuts[j]), max_length + 2); + j++; + } + i++; + } + } + // Required by + if (details.requiredby.length > 0) { + cuts = split_string (concatenate_strings (details.requiredby), max_length + 2); + print_aligned (properties[10], ": %s".printf (cuts[0]), max_length); + i = 1; + while (i < cuts.length) { + print_aligned ("", "%s".printf (cuts[i]), max_length + 2); + i++; + } + } + // Optional for + if (details.optionalfor.length > 0) { + cuts = split_string (concatenate_strings (details.optionalfor), max_length + 2); + print_aligned (properties[11], ": %s".printf (cuts[0]), max_length); + i = 1; + while (i < cuts.length) { + print_aligned ("", "%s".printf (cuts[i]), max_length + 2); + i++; + } + } + // Provides + if (details.provides.length > 0) { + cuts = split_string (concatenate_strings (details.provides), max_length + 2); + print_aligned (properties[12], ": %s".printf (cuts[0]), max_length); + i = 1; + while (i < cuts.length) { + print_aligned ("", "%s".printf (cuts[i]), max_length + 2); + i++; + } + } + // Replaces + if (details.replaces.length > 0) { + cuts = split_string (concatenate_strings (details.replaces), max_length + 2); + print_aligned (properties[13], ": %s".printf (cuts[0]), max_length); + i = 1; + while (i < cuts.length) { + print_aligned ("", "%s".printf (cuts[i]), max_length + 2); + i++; + } + } + // Conflicts + if (details.conflicts.length > 0) { + cuts = split_string (concatenate_strings (details.conflicts), max_length + 2); + print_aligned (properties[14], ": %s".printf (cuts[0]), max_length); + i = 1; + while (i < cuts.length) { + print_aligned ("", "%s".printf (cuts[i]), max_length + 2); + i++; + } + } + // Maintainer + cuts = split_string (details.packager, max_length + 2); + print_aligned (properties[15], ": %s".printf (cuts[0]), max_length); + i = 1; + while (i < cuts.length) { + print_aligned ("", "%s".printf (cuts[i]), max_length + 2); + i++; + } + // Build date + print_aligned (properties[16], ": %s".printf (details.builddate), max_length); + // Install date + if (details.installdate != "") { + print_aligned (properties[17], ": %s".printf (details.installdate), max_length); + } + // Reason + if (details.reason != "") { + cuts = split_string (details.reason, max_length + 2); + print_aligned (properties[18], ": %s".printf (cuts[0]), max_length); + i = 1; + while (i < cuts.length) { + print_aligned ("", "%s".printf (cuts[i]), max_length + 2); + i++; + } + } + // Signature + if (details.has_signature != "") { + print_aligned (properties[19], ": %s".printf (details.has_signature), max_length); + } + // Backup files + if (details.backups.length > 0) { + print_aligned (properties[20], ": %s".printf (details.backups[0]), max_length); + i = 1; + while (i < details.backups.length) { + print_aligned ("", "%s".printf (details.backups[i]), max_length + 2); + i++; + } + } + stdout.printf ("\n"); + } + } + + void display_aur_infos (string[] pkgnames) { + string[] properties = {}; + properties += dgettext (null, "Name"); + properties += dgettext (null, "Package Base"); + properties += dgettext (null, "Version"); + properties += dgettext (null, "Description"); + properties += dgettext (null, "URL"); + properties += dgettext (null, "Licenses"); + properties += dgettext (null, "Depends On"); + properties += dgettext (null, "Make Dependencies"); + properties += dgettext (null, "Check Dependencies"); + properties += dgettext (null, "Optional Dependencies"); + properties += dgettext (null, "Provides"); + properties += dgettext (null, "Replaces"); + properties += dgettext (null, "Conflicts With"); + properties += dgettext (null, "Packager"); + properties += dgettext (null, "First Submitted"); + properties += dgettext (null, "Last Modified"); + properties += dgettext (null, "Votes"); + properties += dgettext (null, "Out of Date"); + int max_length = 0; + foreach (unowned string prop in properties) { + // use char_count to handle special characters + if (prop.char_count () > max_length) { + max_length = prop.length; + } + } + foreach (string pkgname in pkgnames) { + this.hold (); + database.get_aur_details_async.begin (pkgname, (obj, res) => { + var details = database.get_aur_details_async.end (res); if (details.name == "") { print_error (dgettext (null, "target not found: %s").printf (pkgname) + "\n"); - continue; + this.release (); + return; } // Name print_aligned (properties[0], ": %s".printf (details.name), max_length); + // Package Base + if (details.packagebase != details.name) { + print_aligned (properties[1], ": %s".printf (details.packagebase), max_length); + } // Version - print_aligned (properties[1], ": %s".printf (details.version), max_length); + print_aligned (properties[2], ": %s".printf (details.version), max_length); // Description string[] cuts = split_string (details.desc, max_length + 2); - print_aligned (properties[2], ": %s".printf (cuts[0]), max_length); + print_aligned (properties[3], ": %s".printf (cuts[0]), max_length); int i = 1; while (i < cuts.length) { print_aligned ("", "%s".printf (cuts[i]), max_length + 2); i++; } // URL - print_aligned (properties[3], ": %s".printf (details.url), max_length); + print_aligned (properties[4], ": %s".printf (details.url), max_length); // Licenses - print_aligned (properties[4], ": %s".printf (details.licenses[0]), max_length); + print_aligned (properties[5], ": %s".printf (details.licenses[0]), max_length); i = 1; while (i < details.licenses.length) { print_aligned ("", "%s".printf (details.licenses[i]), max_length + 2); i++; } - // Repository - print_aligned (properties[5], ": %s".printf (details.repo), max_length); - // Size - print_aligned (properties[6], ": %s".printf (format_size (details.size)), max_length); - // Groups - if (details.groups.length > 0) { - cuts = split_string (concatenate_strings (details.groups), max_length + 2); + // Depends + if (details.depends.length > 0) { + cuts = split_string (concatenate_strings (details.depends), max_length + 2); + print_aligned (properties[6], ": %s".printf (cuts[0]), max_length); + i = 1; + while (i < cuts.length) { + print_aligned ("", "%s".printf (cuts[i]), max_length + 2); + i++; + } + } + // Make Depends + if (details.makedepends.length > 0) { + cuts = split_string (concatenate_strings (details.makedepends), max_length + 2); print_aligned (properties[7], ": %s".printf (cuts[0]), max_length); i = 1; while (i < cuts.length) { @@ -985,9 +1028,9 @@ namespace Pamac { i++; } } - // Depends - if (details.depends.length > 0) { - cuts = split_string (concatenate_strings (details.depends), max_length + 2); + // Check Depends + if (details.checkdepends.length > 0) { + cuts = split_string (concatenate_strings (details.checkdepends), max_length + 2); print_aligned (properties[8], ": %s".printf (cuts[0]), max_length); i = 1; while (i < cuts.length) { @@ -999,11 +1042,7 @@ namespace Pamac { if (details.optdepends.length > 0) { string depstring = details.optdepends[0]; var satisfier = AlpmPackage (); - try { - satisfier = user_daemon.find_installed_satisfier (depstring); - } catch (Error e) { - print_error (e.message); - } + satisfier = database.find_installed_satisfier (depstring); if (satisfier.name != "") { depstring = "%s [%s]".printf (depstring, dgettext (null, "Installed")); } @@ -1018,11 +1057,7 @@ namespace Pamac { while (i < details.optdepends.length) { depstring = details.optdepends[i]; satisfier = AlpmPackage (); - try { - satisfier = user_daemon.find_installed_satisfier (depstring); - } catch (Error e) { - print_error (e.message); - } + satisfier = database.find_installed_satisfier (depstring); if (satisfier.name != "") { depstring = "%s [%s]".printf (depstring, dgettext (null, "Installed")); } @@ -1035,30 +1070,10 @@ namespace Pamac { i++; } } - // Required by - if (details.requiredby.length > 0) { - cuts = split_string (concatenate_strings (details.requiredby), max_length + 2); - print_aligned (properties[10], ": %s".printf (cuts[0]), max_length); - i = 1; - while (i < cuts.length) { - print_aligned ("", "%s".printf (cuts[i]), max_length + 2); - i++; - } - } - // Optional for - if (details.optionalfor.length > 0) { - cuts = split_string (concatenate_strings (details.optionalfor), max_length + 2); - print_aligned (properties[11], ": %s".printf (cuts[0]), max_length); - i = 1; - while (i < cuts.length) { - print_aligned ("", "%s".printf (cuts[i]), max_length + 2); - i++; - } - } // Provides if (details.provides.length > 0) { cuts = split_string (concatenate_strings (details.provides), max_length + 2); - print_aligned (properties[12], ": %s".printf (cuts[0]), max_length); + print_aligned (properties[10], ": %s".printf (cuts[0]), max_length); i = 1; while (i < cuts.length) { print_aligned ("", "%s".printf (cuts[i]), max_length + 2); @@ -1068,7 +1083,7 @@ namespace Pamac { // Replaces if (details.replaces.length > 0) { cuts = split_string (concatenate_strings (details.replaces), max_length + 2); - print_aligned (properties[13], ": %s".printf (cuts[0]), max_length); + print_aligned (properties[11], ": %s".printf (cuts[0]), max_length); i = 1; while (i < cuts.length) { print_aligned ("", "%s".printf (cuts[i]), max_length + 2); @@ -1078,7 +1093,7 @@ namespace Pamac { // Conflicts if (details.conflicts.length > 0) { cuts = split_string (concatenate_strings (details.conflicts), max_length + 2); - print_aligned (properties[14], ": %s".printf (cuts[0]), max_length); + print_aligned (properties[12], ": %s".printf (cuts[0]), max_length); i = 1; while (i < cuts.length) { print_aligned ("", "%s".printf (cuts[i]), max_length + 2); @@ -1086,231 +1101,22 @@ namespace Pamac { } } // Maintainer - cuts = split_string (details.packager, max_length + 2); - print_aligned (properties[15], ": %s".printf (cuts[0]), max_length); - i = 1; - while (i < cuts.length) { - print_aligned ("", "%s".printf (cuts[i]), max_length + 2); - i++; - } - // Build date - print_aligned (properties[16], ": %s".printf (details.builddate), max_length); - // Install date - if (details.installdate != "") { - print_aligned (properties[17], ": %s".printf (details.installdate), max_length); - } - // Reason - if (details.reason != "") { - cuts = split_string (details.reason, max_length + 2); - print_aligned (properties[18], ": %s".printf (cuts[0]), max_length); - i = 1; - while (i < cuts.length) { - print_aligned ("", "%s".printf (cuts[i]), max_length + 2); - i++; - } - } - // Signature - if (details.has_signature != "") { - print_aligned (properties[19], ": %s".printf (details.has_signature), max_length); - } - // Backup files - if (details.backups.length > 0) { - print_aligned (properties[20], ": %s".printf (details.backups[0]), max_length); - i = 1; - while (i < details.backups.length) { - print_aligned ("", "%s".printf (details.backups[i]), max_length + 2); - i++; - } + if (details.maintainer != "") { + print_aligned (properties[13], ": %s".printf (details.maintainer), max_length); + } + // First Submitted + print_aligned (properties[14], ": %s".printf (details.firstsubmitted), max_length); + // Last Modified + print_aligned (properties[15], ": %s".printf (details.lastmodified), max_length); + // Votes + print_aligned (properties[16], ": %s".printf (details.numvotes.to_string ()), max_length); + // Last Modified + if (details.outofdate != "") { + print_aligned (properties[17], ": %s".printf (details.outofdate), max_length); } stdout.printf ("\n"); - } catch (Error e) { - print_error (e.message); - } - } - } - - void display_aur_infos (string[] pkgnames) { - string[] properties = {}; - properties += dgettext (null, "Name"); - properties += dgettext (null, "Package Base"); - properties += dgettext (null, "Version"); - properties += dgettext (null, "Description"); - properties += dgettext (null, "URL"); - properties += dgettext (null, "Licenses"); - properties += dgettext (null, "Depends On"); - properties += dgettext (null, "Make Dependencies"); - properties += dgettext (null, "Check Dependencies"); - properties += dgettext (null, "Optional Dependencies"); - properties += dgettext (null, "Provides"); - properties += dgettext (null, "Replaces"); - properties += dgettext (null, "Conflicts With"); - properties += dgettext (null, "Packager"); - properties += dgettext (null, "First Submitted"); - properties += dgettext (null, "Last Modified"); - properties += dgettext (null, "Votes"); - properties += dgettext (null, "Out of Date"); - int max_length = 0; - foreach (unowned string prop in properties) { - // use char_count to handle special characters - if (prop.char_count () > max_length) { - max_length = prop.length; - } - } - foreach (string pkgname in pkgnames) { - this.hold (); - user_daemon.get_aur_details.begin (pkgname, (obj, res) => { - try { - var details = user_daemon.get_aur_details.end (res); - if (details.name == "") { - print_error (dgettext (null, "target not found: %s").printf (pkgname) + "\n"); - this.release (); - return; - } - // Name - print_aligned (properties[0], ": %s".printf (details.name), max_length); - // Package Base - if (details.packagebase != details.name) { - print_aligned (properties[1], ": %s".printf (details.packagebase), max_length); - } - // Version - print_aligned (properties[2], ": %s".printf (details.version), max_length); - // Description - string[] cuts = split_string (details.desc, max_length + 2); - print_aligned (properties[3], ": %s".printf (cuts[0]), max_length); - int i = 1; - while (i < cuts.length) { - print_aligned ("", "%s".printf (cuts[i]), max_length + 2); - i++; - } - // URL - print_aligned (properties[4], ": %s".printf (details.url), max_length); - // Licenses - print_aligned (properties[5], ": %s".printf (details.licenses[0]), max_length); - i = 1; - while (i < details.licenses.length) { - print_aligned ("", "%s".printf (details.licenses[i]), max_length + 2); - i++; - } - // Depends - if (details.depends.length > 0) { - cuts = split_string (concatenate_strings (details.depends), max_length + 2); - print_aligned (properties[6], ": %s".printf (cuts[0]), max_length); - i = 1; - while (i < cuts.length) { - print_aligned ("", "%s".printf (cuts[i]), max_length + 2); - i++; - } - } - // Make Depends - if (details.makedepends.length > 0) { - cuts = split_string (concatenate_strings (details.makedepends), max_length + 2); - print_aligned (properties[7], ": %s".printf (cuts[0]), max_length); - i = 1; - while (i < cuts.length) { - print_aligned ("", "%s".printf (cuts[i]), max_length + 2); - i++; - } - } - // Check Depends - if (details.checkdepends.length > 0) { - cuts = split_string (concatenate_strings (details.checkdepends), max_length + 2); - print_aligned (properties[8], ": %s".printf (cuts[0]), max_length); - i = 1; - while (i < cuts.length) { - print_aligned ("", "%s".printf (cuts[i]), max_length + 2); - i++; - } - } - // Opt depends - if (details.optdepends.length > 0) { - string depstring = details.optdepends[0]; - var satisfier = AlpmPackage (); - try { - satisfier = user_daemon.find_installed_satisfier (depstring); - } catch (Error e) { - print_error (e.message); - } - if (satisfier.name != "") { - depstring = "%s [%s]".printf (depstring, dgettext (null, "Installed")); - } - cuts = split_string (depstring, max_length + 2); - print_aligned (properties[9], ": %s".printf (cuts[0]), max_length); - i = 1; - while (i < cuts.length) { - print_aligned ("", "%s".printf (cuts[i]), max_length + 2); - i++; - } - i = 1; - while (i < details.optdepends.length) { - depstring = details.optdepends[i]; - satisfier = AlpmPackage (); - try { - satisfier = user_daemon.find_installed_satisfier (depstring); - } catch (Error e) { - print_error (e.message); - } - if (satisfier.name != "") { - depstring = "%s [%s]".printf (depstring, dgettext (null, "Installed")); - } - cuts = split_string (depstring, max_length + 2); - int j = 0; - while (j < cuts.length) { - print_aligned ("", "%s".printf (cuts[j]), max_length + 2); - j++; - } - i++; - } - } - // Provides - if (details.provides.length > 0) { - cuts = split_string (concatenate_strings (details.provides), max_length + 2); - print_aligned (properties[10], ": %s".printf (cuts[0]), max_length); - i = 1; - while (i < cuts.length) { - print_aligned ("", "%s".printf (cuts[i]), max_length + 2); - i++; - } - } - // Replaces - if (details.replaces.length > 0) { - cuts = split_string (concatenate_strings (details.replaces), max_length + 2); - print_aligned (properties[11], ": %s".printf (cuts[0]), max_length); - i = 1; - while (i < cuts.length) { - print_aligned ("", "%s".printf (cuts[i]), max_length + 2); - i++; - } - } - // Conflicts - if (details.conflicts.length > 0) { - cuts = split_string (concatenate_strings (details.conflicts), max_length + 2); - print_aligned (properties[12], ": %s".printf (cuts[0]), max_length); - i = 1; - while (i < cuts.length) { - print_aligned ("", "%s".printf (cuts[i]), max_length + 2); - i++; - } - } - // Maintainer - if (details.maintainer != "") { - print_aligned (properties[13], ": %s".printf (details.maintainer), max_length); - } - // First Submitted - print_aligned (properties[14], ": %s".printf (details.firstsubmitted), max_length); - // Last Modified - print_aligned (properties[15], ": %s".printf (details.lastmodified), max_length); - // Votes - print_aligned (properties[16], ": %s".printf (details.numvotes.to_string ()), max_length); - // Last Modified - if (details.outofdate != "") { - print_aligned (properties[17], ": %s".printf (details.outofdate), max_length); - } - stdout.printf ("\n"); - } catch (Error e) { - print_error (e.message); - } - this.release (); - }); + this.release (); + }); } } @@ -1341,9 +1147,9 @@ namespace Pamac { } int total_width = name_length + version_length + repo_length + size_length + 4; int margin = 0; - if (get_term_width () > total_width) { + if (transaction.get_term_width () > total_width) { // divide available space between columns - int available_width = get_term_width () - total_width; + int available_width = transaction.get_term_width () - total_width; margin = available_width / 4; // get left space to size size_length += available_width - (margin * 4); @@ -1352,7 +1158,7 @@ namespace Pamac { // use this code to correctly aligned text with special characters var str_builder = new StringBuilder (); string name = pkg.name; - if (pkg.installed_version != "") { + if (print_installed && pkg.installed_version != "") { name = "%s [%s]".printf (pkg.name, dgettext (null, "Installed")); } str_builder.append (name); @@ -1372,54 +1178,34 @@ namespace Pamac { } void list_installed () { - try { - var pkgs = user_daemon.get_installed_pkgs_sync (); - print_pkgs (pkgs, false); - } catch (Error e) { - print_error (e.message); - } + var pkgs = database.get_installed_pkgs (); + print_pkgs (pkgs, false); } void list_orphans () { - try { - var pkgs = user_daemon.get_orphans_sync (); - print_pkgs (pkgs, false); - } catch (Error e) { - print_error (e.message); - } + var pkgs = database.get_orphans (); + print_pkgs (pkgs, false); } void list_foreign () { - try { - var pkgs = user_daemon.get_foreign_pkgs_sync (); - print_pkgs (pkgs, false); - } catch (Error e) { - print_error (e.message); - } + var pkgs = database.get_foreign_pkgs (); + print_pkgs (pkgs, false); } void list_groups (string[] names) { if (names.length == 0) { - try { - string[] grpnames = user_daemon.get_groups_names (); - foreach (unowned string name in grpnames) { - stdout.printf ("%s\n", name); - } - } catch (Error e) { - print_error (e.message); + string[] grpnames = database.get_groups_names (); + foreach (unowned string name in grpnames) { + stdout.printf ("%s\n", name); } return; } foreach (unowned string name in names) { - try { - var pkgs = user_daemon.get_group_pkgs_sync (name); - if (pkgs.length == 0) { - print_error (dgettext (null, "target not found: %s").printf (name)); - } else { - print_pkgs (pkgs, true); - } - } catch (Error e) { - print_error (e.message); + var pkgs = database.get_group_pkgs (name); + if (pkgs.length == 0) { + print_error (dgettext (null, "target not found: %s").printf (name)); + } else { + print_pkgs (pkgs, true); } stdout.printf ("\n"); } @@ -1427,26 +1213,18 @@ namespace Pamac { void list_repos (string[] names) { if (names.length == 0) { - try { - string[] grpnames = user_daemon.get_repos_names (); - foreach (unowned string name in grpnames) { - stdout.printf ("%s\n", name); - } - } catch (Error e) { - print_error (e.message); + string[] grpnames = database.get_repos_names (); + foreach (unowned string name in grpnames) { + stdout.printf ("%s\n", name); } return; } foreach (unowned string name in names) { - try { - var pkgs = user_daemon.get_repo_pkgs_sync (name); - if (pkgs.length == 0) { - print_error (dgettext (null, "target not found: %s").printf (name)); - } else { - print_pkgs (pkgs, true); - } - } catch (Error e) { - print_error (e.message); + var pkgs = database.get_repo_pkgs (name); + if (pkgs.length == 0) { + print_error (dgettext (null, "target not found: %s").printf (name)); + } else { + print_pkgs (pkgs, true); } stdout.printf ("\n"); } @@ -1454,74 +1232,45 @@ namespace Pamac { void list_files (string[] names) { foreach (unowned string name in names) { - try { - string[] files = user_daemon.get_pkg_files (name); - if (files.length == 0) { - print_error (dgettext (null, "target not found: %s").printf (name)); - } else { - foreach (unowned string path in files) { - stdout.printf ("%s\n", path); - } + string[] files = database.get_pkg_files (name); + if (files.length == 0) { + print_error (dgettext (null, "target not found: %s").printf (name)); + } else { + foreach (unowned string path in files) { + stdout.printf ("%s\n", path); } - } catch (Error e) { - print_error (e.message); } stdout.printf ("\n"); } } void search_files (string[] files) { - try { - HashTable<string, Variant> result = user_daemon.search_files (files); - if (result.size () == 0) { - foreach (unowned string file in files) { - stdout.printf (dgettext (null, "No package owns %s\n").printf (file)); - } - cmd.set_exit_status (1); - return; + HashTable<string, Variant> result = database.search_files (files); + if (result.size () == 0) { + foreach (unowned string file in files) { + stdout.printf (dgettext (null, "No package owns %s\n").printf (file)); } - var iter = HashTableIter<string, Variant> (result); - unowned string pkgname; - unowned Variant files_list; - while (iter.next (out pkgname, out files_list)) { - foreach (unowned string file in (string[]) files_list) { - stdout.printf ("%s\n", dgettext (null, "%s is owned by %s").printf (file, pkgname)); - } - } - } catch (Error e) { - print_error (e.message); + cmd.set_exit_status (1); + return; } - } - - AlpmPackage get_installed_pkg (string pkgname) { - try { - return user_daemon.get_installed_pkg (pkgname); - } catch (Error e) { - print_error (e.message); - return AlpmPackage () { - name = "", - version = "", - desc = "", - repo = "", - icon = "" - }; + var iter = HashTableIter<string, Variant> (result); + unowned string pkgname; + unowned Variant files_list; + while (iter.next (out pkgname, out files_list)) { + foreach (unowned string file in (string[]) files_list) { + stdout.printf ("%s\n", dgettext (null, "%s is owned by %s").printf (file, pkgname)); + } } } void checkupdates () { this.hold (); - user_daemon.get_updates_finished.connect (on_get_updates_finished); - try { - user_daemon.start_get_updates (enable_aur, false); - } catch (Error e) { - print_error (e.message); - user_daemon.get_updates_finished.disconnect (on_get_updates_finished); - this.release (); - } + database.start_get_updates (); + database.get_updates_finished.connect (on_get_updates_finished); } void on_get_updates_finished (Updates updates) { - user_daemon.get_updates_finished.disconnect (on_get_updates_for_sysupgrade_finished); + database.get_updates_finished.disconnect (on_get_updates_finished); uint updates_nb = updates.repos_updates.length + updates.aur_updates.length; if (updates_nb == 0) { stdout.printf ("%s\n", dgettext (null, "Your system is up-to-date")); @@ -1556,9 +1305,9 @@ namespace Pamac { } int total_width = name_length + version_length + repo_length + 3; int margin = 0; - if (get_term_width () > total_width) { + if (transaction.get_term_width () > total_width) { // divide available space between columns - int available_width = get_term_width () - total_width; + int available_width = transaction.get_term_width () - total_width; margin = available_width / 3; // get left space to repo repo_length += available_width - (margin * 3); @@ -1580,1321 +1329,294 @@ namespace Pamac { } void install_pkgs (string[] targets) { - try { - foreach (unowned string target in targets) { - bool found = false; - // check for local or remote path - if (".pkg.tar" in target) { - if ("://" in target) { - if ("file://" in target) { - // handle file:// uri - var file = File.new_for_uri (target); - string? absolute_path = file.get_path (); - if (absolute_path != null) { - to_load += absolute_path; - found = true; - } - } else { - // add url in to_load, pkg will be downloaded by system_daemon - to_load += target; - found = true; - } - } else { - // handle local or absolute path - var file = File.new_for_path (target); + foreach (unowned string target in targets) { + bool found = false; + // check for local or remote path + if (".pkg.tar" in target) { + if ("://" in target) { + if ("file://" in target) { + // handle file:// uri + var file = File.new_for_uri (target); string? absolute_path = file.get_path (); if (absolute_path != null) { to_load += absolute_path; found = true; } + } else { + // add url in to_load, pkg will be downloaded by system_daemon + to_load += target; + found = true; } } else { - var pkg = user_daemon.find_sync_satisfier (target); - if (pkg.name != "") { - to_install += target; + // handle local or absolute path + var file = File.new_for_path (target); + string? absolute_path = file.get_path (); + if (absolute_path != null) { + to_load += absolute_path; found = true; - } else { - string[] groupnames = user_daemon.get_groups_names (); - if (target in groupnames) { - ask_group_confirmation (target); - found = true; - } } } - if (!found) { - print_error (dgettext (null, "target not found: %s").printf (target)); - return; + } else { + var pkg = database.find_sync_satisfier (target); + if (pkg.name != "") { + to_install += target; + found = true; + } else { + string[] groupnames = database.get_groups_names (); + if (target in groupnames) { + ask_group_confirmation (target); + found = true; + } } } - } catch (Error e) { - print_error (e.message); + if (!found) { + print_error (dgettext (null, "target not found: %s").printf (target)); + return; + } } if (to_install.length == 0 && to_load.length == 0) { stdout.printf (dgettext (null, "Nothing to do") + ".\n"); return; } // do not install a package if it is already installed and up to date - transflags = (1 << 13); //Alpm.TransFlag.NEEDED - stdout.printf (dgettext (null, "Preparing") + "...\n"); - this.hold (); - start_trans_prepare (); + transaction.flags = (1 << 13); //Alpm.TransFlag.NEEDED + try_lock_and_run (start_transaction); } void ask_group_confirmation (string grpname) { - try { - var pkgs = user_daemon.get_group_pkgs_sync (grpname); - // print pkgs - int name_length = 0; - int version_length = 0; - int repo_length = 0; - foreach (unowned AlpmPackage pkg in pkgs) { - if (pkg.name.length > name_length) { - name_length = pkg.name.length; - } - if (pkg.version.length > version_length) { - version_length = pkg.version.length; - } - if (pkg.repo.length > repo_length) { - repo_length = pkg.repo.length; - } + var pkgs = database.get_group_pkgs (grpname); + // print pkgs + int name_length = 0; + int version_length = 0; + int repo_length = 0; + foreach (unowned AlpmPackage pkg in pkgs) { + if (pkg.name.length > name_length) { + name_length = pkg.name.length; } - int num_length = pkgs.length.to_string ().length + 1; - int total_width = num_length + name_length + version_length + repo_length + 4; - int margin = 0; - if (get_term_width () > total_width) { - // divide available space between columns - int available_width = get_term_width () - total_width; - margin = available_width / 3; - // get left space to repo - repo_length += available_width - (margin * 3); + if (pkg.version.length > version_length) { + version_length = pkg.version.length; } - stdout.printf ("%s:\n".printf (dngettext (null, "There is %u member in group %s", - "There are %u members in group %s", pkgs.length).printf (pkgs.length, grpname))); - int num = 1; - foreach (unowned AlpmPackage pkg in pkgs) { - stdout.printf ("%*s %-*s %-*s %s \n", num_length, "%i:".printf (num), - name_length + margin, pkg.name, - version_length + margin, pkg.version, - pkg.repo); - num++; - } - // get user input - asking_user_input = true; - while (true) { - stdout.printf ("%s: ", dgettext (null, "Enter a selection (default=all)")); - string ans = stdin.read_line (); - int64 nb; - int64[] numbers = {}; - // remvove trailing newline - ans = ans.replace ("\n", ""); - // just return use default - if (ans == "") { - foreach (unowned AlpmPackage pkg in pkgs) { - to_install += pkg.name; - } - break; - } else { - // split "," - string[] splitted = ans.split (","); - foreach (unowned string part in splitted) { - // check for range - if ("-" in part) { - string[] splitted2 = part.split ("-", 2); - // get all numbers in range - int64 beg_num, end_num; - if (int64.try_parse (splitted2[0], out beg_num)) { - if (int64.try_parse (splitted2[1], out end_num)) { - nb = beg_num; - while (nb <= end_num) { - if (nb >= 1 && nb < pkgs.length) { - numbers += nb; - } - nb++; + if (pkg.repo.length > repo_length) { + repo_length = pkg.repo.length; + } + } + int num_length = pkgs.length.to_string ().length + 1; + int total_width = num_length + name_length + version_length + repo_length + 4; + int margin = 0; + if (transaction.get_term_width () > total_width) { + // divide available space between columns + int available_width = transaction.get_term_width () - total_width; + margin = available_width / 3; + // get left space to repo + repo_length += available_width - (margin * 3); + } + stdout.printf ("%s:\n".printf (dngettext (null, "There is %u member in group %s", + "There are %u members in group %s", pkgs.length).printf (pkgs.length, grpname))); + int num = 1; + foreach (unowned AlpmPackage pkg in pkgs) { + stdout.printf ("%*s %-*s %-*s %s \n", num_length, "%i:".printf (num), + name_length + margin, pkg.name, + version_length + margin, pkg.version, + pkg.repo); + num++; + } + // get user input + transaction.asking_user_input = true; + while (true) { + stdout.printf ("%s: ", dgettext (null, "Enter a selection (default=all)")); + string ans = stdin.read_line (); + int64 nb; + int64[] numbers = {}; + // remvove trailing newline + ans = ans.replace ("\n", ""); + // just return use default + if (ans == "") { + foreach (unowned AlpmPackage pkg in pkgs) { + to_install += pkg.name; + } + break; + } else { + // split "," + string[] splitted = ans.split (","); + foreach (unowned string part in splitted) { + // check for range + if ("-" in part) { + string[] splitted2 = part.split ("-", 2); + // get all numbers in range + int64 beg_num, end_num; + if (int64.try_parse (splitted2[0], out beg_num)) { + if (int64.try_parse (splitted2[1], out end_num)) { + nb = beg_num; + while (nb <= end_num) { + if (nb >= 1 && nb < pkgs.length) { + numbers += nb; } + nb++; } } - } else if (int64.try_parse (part, out nb)) { - if (nb >= 1 && nb < pkgs.length) { - numbers += nb; - } + } + } else if (int64.try_parse (part, out nb)) { + if (nb >= 1 && nb < pkgs.length) { + numbers += nb; } } } - stdout.printf ("\n"); - if (numbers.length > 0) { - foreach (int64 number in numbers) { - to_install += pkgs[number -1].name; - } - break; + } + stdout.printf ("\n"); + if (numbers.length > 0) { + foreach (int64 number in numbers) { + to_install += pkgs[number -1].name; } + break; } - } catch (Error e) { - print_error (e.message); } } void reinstall_pkgs (string[] names) { - try { - foreach (unowned string name in names) { - bool found = false; - string version = ""; - var local_pkg = user_daemon.get_installed_pkg (name); - if (local_pkg.name != "") { - version = local_pkg.version; - var sync_pkg = user_daemon.get_sync_pkg (name); - if (sync_pkg.name != "") { - if (local_pkg.version == sync_pkg.version) { - to_install += name; - found = true; - } - } - } else { - string[] groupnames = user_daemon.get_groups_names (); - if (name in groupnames) { + foreach (unowned string name in names) { + bool found = false; + string version = ""; + var local_pkg = database.get_installed_pkg (name); + if (local_pkg.name != "") { + version = local_pkg.version; + var sync_pkg = database.get_sync_pkg (name); + if (sync_pkg.name != "") { + if (local_pkg.version == sync_pkg.version) { + to_install += name; found = true; - var pkgs = user_daemon.get_group_pkgs_sync (name); - foreach (unowned AlpmPackage pkg in pkgs) { - if (pkg.version == pkg.installed_version) { - to_install += name; - } - } } } - if (!found) { - if (version == "") { - print_error (dgettext (null, "target not found: %s").printf (name)); - } else { - print_error (dgettext (null, "target not found: %s").printf (name + "-" + version)); + } else { + string[] groupnames = database.get_groups_names (); + if (name in groupnames) { + found = true; + var pkgs = database.get_group_pkgs (name); + foreach (unowned AlpmPackage pkg in pkgs) { + if (pkg.version == pkg.installed_version) { + to_install += name; + } } - return; } } - } catch (Error e) { - print_error (e.message); + if (!found) { + if (version == "") { + print_error (dgettext (null, "target not found: %s").printf (name)); + } else { + print_error (dgettext (null, "target not found: %s").printf (name + "-" + version)); + } + return; + } } - if (to_install.length == 0 && to_load.length == 0) { + if (to_install.length == 0) { stdout.printf (dgettext (null, "Nothing to do") + ".\n"); return; } - stdout.printf (dgettext (null, "Preparing") + "...\n"); - this.hold (); - start_trans_prepare (); + try_lock_and_run (start_transaction); } void remove_pkgs (string[] names, bool recurse = false) { bool group_found = false; - try { - foreach (unowned string name in names) { - bool found = false; - var local_pkg = user_daemon.get_installed_pkg (name); - if (local_pkg.name != "") { - to_remove += name; + foreach (unowned string name in names) { + bool found = false; + var local_pkg = database.get_installed_pkg (name); + if (local_pkg.name != "") { + to_remove += name; + found = true; + } else { + string[] groupnames = database.get_groups_names (); + if (name in groupnames) { found = true; - } else { - string[] groupnames = user_daemon.get_groups_names (); - if (name in groupnames) { - found = true; - var pkgs = user_daemon.get_group_pkgs_sync (name); - foreach (unowned AlpmPackage pkg in pkgs) { - if (pkg.version == pkg.installed_version) { - to_remove += pkg.name; - group_found = true; - } + var pkgs = database.get_group_pkgs (name); + foreach (unowned AlpmPackage pkg in pkgs) { + if (pkg.version == pkg.installed_version) { + to_remove += pkg.name; + group_found = true; } } } - if (!found) { - print_error (dgettext (null, "target not found: %s").printf (name)); - return; - } } - } catch (Error e) { - print_error (e.message); + if (!found) { + print_error (dgettext (null, "target not found: %s").printf (name)); + return; + } } if (to_remove.length == 0) { stdout.printf (dgettext (null, "Nothing to do") + ".\n"); return; } if (group_found) { - transflags |= (1 << 15); //Alpm.TransFlag.UNNEEDED + transaction.flags = (1 << 15); //Alpm.TransFlag.UNNEEDED } else { - transflags |= (1 << 4); //Alpm.TransFlag.CASCADE + transaction.flags = (1 << 4); //Alpm.TransFlag.CASCADE } if (recurse) { - transflags |= (1 << 5); //Alpm.TransFlag.RECURSE + transaction.flags |= (1 << 5); //Alpm.TransFlag.RECURSE } - stdout.printf (dgettext (null, "Preparing") + "...\n"); - this.hold (); - start_trans_prepare (); + try_lock_and_run (start_transaction); } void remove_orphans () { - try { - var pkgs = user_daemon.get_orphans_sync (); - foreach (unowned AlpmPackage pkg in pkgs) { - to_remove += pkg.name; - } - stdout.printf (dgettext (null, "Preparing") + "...\n"); - transflags = (1 << 4); //Alpm.TransFlag.CASCADE - transflags |= (1 << 5); //Alpm.TransFlag.RECURSE - this.hold (); - start_trans_prepare (); - } catch (Error e) { - print_error (e.message); + var pkgs = database.get_orphans (); + foreach (unowned AlpmPackage pkg in pkgs) { + to_remove += pkg.name; } + transaction.flags = (1 << 4); //Alpm.TransFlag.CASCADE + transaction.flags |= (1 << 5); //Alpm.TransFlag.RECURSE + try_lock_and_run (start_transaction); } - void start_get_updates_for_sysupgrade () { - if (!sysupgrade_after_trans) { - stdout.printf (dgettext (null, "Starting full system upgrade") + "...\n"); - } - sysupgrade_after_trans = false; - system_daemon.get_updates_finished.connect (on_get_updates_for_sysupgrade_finished); - try { - system_daemon.start_get_updates (enable_aur); - } catch (Error e) { - print_error (e.message); - system_daemon.get_updates_finished.disconnect (on_get_updates_for_sysupgrade_finished); - this.release (); - } + void build_pkgs (string[] to_build) { + this.to_build = to_build; + try_lock_and_run (start_transaction); } - void on_get_updates_for_sysupgrade_finished (Updates updates) { - system_daemon.get_updates_finished.disconnect (on_get_updates_for_sysupgrade_finished); - to_install_first = {}; - // get syncfirst updates - if (updates.is_syncfirst) { - foreach (unowned AlpmPackage infos in updates.repos_updates) { - to_install_first += infos.name; - } - start_sysupgrade_prepare (); - } else { - if (updates.aur_updates.length != 0) { - string[] to_build = {}; - foreach (unowned AURPackage infos in updates.aur_updates) { - if (!(infos.name in temporary_ignorepkgs)) { - to_build += infos.name; - } - } - if (updates.repos_updates.length != 0) { - start_sysupgrade_prepare (to_build); - } else { - // only aur updates - this.release (); - build_pkgs (to_build); - } - } else { - if (updates.repos_updates.length != 0) { - start_sysupgrade_prepare (); - } else { - stdout.printf (dgettext (null, "Nothing to do") + ".\n"); - unlock (); - this.release (); - } - } - } - } - - void build_pkgs (string[] to_build) { - this.to_build = to_build; - this.hold (); - start_trans_prepare (); - } - - async void build_aur_packages () { - string pkgname = to_build_queue.pop_head (); - stdout.printf ("%s...\n", dgettext (null, "Building %s").printf (pkgname)); - build_cancellable.reset (); - string [] built_pkgs = {}; - int status = 1; - string builddir; - if (aur_build_dir == "/tmp") { - builddir = "/tmp/pamac-build-%s".printf (Environment.get_user_name ()); - } else { - builddir = aur_build_dir; - } - status = yield spawn_cmdline ({"mkdir", "-p", builddir}); - if (status == 0) { - status = yield spawn_cmdline ({"rm", "-rf", pkgname}, builddir); - if (!build_cancellable.is_cancelled ()) { - if (status == 0) { - building = true; - status = yield spawn_cmdline ({"git", "clone", "https://aur.archlinux.org/%s.git".printf (pkgname)}, builddir); - if (status == 0) { - string pkgdir = "%s/%s".printf (builddir, pkgname); - status = yield spawn_cmdline ({"makepkg", "-cf"}, pkgdir); - building = false; - if (status == 0) { - // get built pkgs path - var launcher = new SubprocessLauncher (SubprocessFlags.STDOUT_PIPE); - launcher.set_cwd (pkgdir); - try { - Subprocess process = launcher.spawnv ({"makepkg", "--packagelist"}); - yield process.wait_async (null); - if (process.get_if_exited ()) { - status = process.get_exit_status (); - } - if (status == 0) { - var dis = new DataInputStream (process.get_stdout_pipe ()); - string? line; - // Read lines until end of file (null) is reached - while ((line = dis.read_line ()) != null) { - var file = GLib.File.new_for_path (line); - string filename = file.get_basename (); - string name_version_release = filename.slice (0, filename.last_index_of_char ('-')); - string name_version = name_version_release.slice (0, name_version_release.last_index_of_char ('-')); - string name = name_version.slice (0, name_version.last_index_of_char ('-')); - if (name in aur_pkgs_to_install) { - if (!(line in built_pkgs)) { - built_pkgs += line; - } - } - } - } - } catch (Error e) { - print_error (e.message); - } - } - } - } - } else { - status = 1; - } - } - if (status == 0 && built_pkgs.length > 0) { - no_confirm_commit = true; - stdout.printf ("\n"); - to_build = {}; - to_install = {}; - to_load = built_pkgs; - start_trans_prepare (); - } else { - on_trans_commit_finished (false); - } - } - - async int spawn_cmdline (string[] args, string? working_directory = null) { - int status = 1; - var launcher = new SubprocessLauncher (SubprocessFlags.NONE); - launcher.set_cwd (working_directory); - launcher.set_environ (Environ.get ()); - try { - Subprocess process = launcher.spawnv (args); - try { - yield process.wait_async (build_cancellable); - if (process.get_if_exited ()) { - status = process.get_exit_status (); - } - } catch (Error e) { - // cancelled - process.send_signal (Posix.Signal.INT); - process.send_signal (Posix.Signal.KILL); - } - } catch (Error e) { - print_error (e.message); - } - return status; - } - - bool get_lock () { - bool locked = false; - connecting_system_daemon (); - try { - locked = system_daemon.get_lock (); - } catch (Error e) { - print_error (e.message); - } - return locked; - } - - void unlock () { - try { - system_daemon.unlock (); - } catch (Error e) { - print_error (e.message); - } - } - - async bool check_authorization () { - SourceFunc callback = check_authorization.callback; - bool authorized = false; - ulong handler_id = system_daemon.get_authorization_finished.connect ((authorized_) => { - authorized = authorized_; - Idle.add ((owned) callback); - }); - try { - system_daemon.start_get_authorization (); - } catch (Error e) { - print_error (e.message); - } - yield; - system_daemon.disconnect (handler_id); - return authorized; - } - - void start_refresh () { - this.hold (); - if (get_lock ()) { - // let's time to pkttyagent to get registred - Timeout.add (200, () => { - check_authorization.begin ((obj, res) => { - bool authorized = check_authorization.end (res); - if (authorized) { - stdout.printf ("%s...\n", dgettext (null, "Synchronizing package databases")); - try { - system_daemon.refresh_finished.connect (on_refresh_finished); - system_daemon.start_refresh (force_refresh); - } catch (Error e) { - print_error (e.message); - system_daemon.refresh_finished.disconnect (on_refresh_finished); - } - } else { - unlock (); - this.release (); - cmd.set_exit_status (1); - } - }); - return false; - }); - } else { - stdout.printf (dgettext (null, "Waiting for another package manager to quit") + "...\n"); - Timeout.add (5000, () => { - bool locked = get_lock (); - if (locked) { - check_authorization.begin ((obj, res) => { - bool authorized = check_authorization.end (res); - if (authorized) { - stdout.printf ("%s...\n", dgettext (null, "Synchronizing package databases")); - try { - system_daemon.refresh_finished.connect (on_refresh_finished); - system_daemon.start_refresh (force_refresh); - } catch (Error e) { - print_error (e.message); - system_daemon.refresh_finished.disconnect (on_refresh_finished); - } - } else { - unlock (); - this.release (); - cmd.set_exit_status (1); - } - }); - } - return !locked; - }); - } - } - - void on_refresh_finished (bool success) { - previous_filename = ""; - system_daemon.refresh_finished.disconnect (on_refresh_finished); - if (success) { - start_get_updates_for_sysupgrade (); - } else { - unlock (); - this.release (); - cmd.set_exit_status (1); - } - } - - void start_trans_prepare () { - if (get_lock ()) { - try { - system_daemon.start_trans_prepare (transflags, to_install, to_remove, to_load, to_build, overwrite_files); - } catch (Error e) { - print_error (e.message); - on_trans_prepare_finished (false); - } + void start_transaction () { + this.hold (); + transaction.start (to_install, to_remove, to_load, to_build, overwrite_files); + } + + void try_lock_and_run (TransactionAction action) { + if (transaction.get_lock ()) { + action (); } else { stdout.printf (dgettext (null, "Waiting for another package manager to quit") + "...\n"); + this.hold (); Timeout.add (5000, () => { - bool locked = get_lock (); + bool locked = transaction.get_lock (); if (locked) { - try { - system_daemon.start_trans_prepare (transflags, to_install, to_remove, to_load, to_build, overwrite_files); - } catch (Error e) { - print_error (e.message); - } + this.release (); + action (); } return !locked; }); } } - void start_sysupgrade_prepare (string[] to_build = {}) { - try { - // this will respond with on_trans_prepare_finished signal - system_daemon.start_sysupgrade_prepare (false, temporary_ignorepkgs, to_build, overwrite_files); - } catch (Error e) { - print_error (e.message); - on_trans_prepare_finished (false); - } - } - - TransType set_transaction_sum () { - // return 0 if transaction_sum is empty, 2, if there are only aur updates, 1 otherwise - TransType type = 0; - uint64 dsize = 0; - uint64 rsize = 0; - int64 isize = 0; - int max_name_length = 0; - int max_version_length = 0; - int max_installed_version_length = 0; - int max_size_length = 0; - int margin = 0; - var summary = TransactionSummary (); - try { - summary = system_daemon.get_transaction_summary (); - } catch (Error e) { - print_error (e.message); - } - // first pass to compute trans type, pkgs size and strings length - if (summary.to_remove.length > 0) { - type |= TransType.STANDARD; - if (!no_confirm_commit) { - foreach (unowned AlpmPackage infos in summary.to_remove) { - rsize += infos.size; - if (infos.name.length > max_name_length) { - max_name_length = infos.name.length; - } - if (infos.version.length > max_version_length) { - max_version_length = infos.version.length; - } - } - } - } - if (summary.aur_conflicts_to_remove.length > 0) { - if (!no_confirm_commit) { - // do not add type enum because it is just infos - foreach (unowned AlpmPackage infos in summary.aur_conflicts_to_remove) { - rsize += infos.size; - if (infos.name.length > max_name_length) { - max_name_length = infos.name.length; - } - if (infos.version.length > max_version_length) { - max_version_length = infos.version.length; - } - } - } - } - if (summary.to_downgrade.length > 0) { - type |= TransType.STANDARD; - if (!no_confirm_commit) { - foreach (unowned AlpmPackage infos in summary.to_downgrade) { - dsize += infos.download_size; - var pkg = get_installed_pkg (infos.name); - isize += ((int64) infos.size - (int64) pkg.size); - if (infos.name.length > max_name_length) { - max_name_length = infos.name.length; - } - if (infos.version.length > max_version_length) { - max_version_length = infos.version.length; - } - if (infos.installed_version.length > max_installed_version_length) { - max_installed_version_length = infos.installed_version.length; - } - string size = format_size (pkg.size); - if (size.length > max_size_length) { - max_size_length = size.length; - } - } - } - } - if (summary.to_build.length > 0) { - type |= TransType.BUILD; - // populate build queue - foreach (unowned string name in summary.aur_pkgbases_to_build) { - to_build_queue.push_tail (name); - } - aur_pkgs_to_install = {}; - foreach (unowned AURPackage infos in summary.to_build) { - aur_pkgs_to_install += infos.name; - if (!no_confirm_commit) { - if (infos.name.length > max_name_length) { - max_name_length = infos.name.length; - } - if (infos.version.length > max_version_length) { - max_version_length = infos.version.length; - } - } - } - } - if (summary.to_install.length > 0) { - type |= TransType.STANDARD; - if (!no_confirm_commit) { - foreach (unowned AlpmPackage infos in summary.to_install) { - dsize += infos.download_size; - var pkg = get_installed_pkg (infos.name); - isize += ((int64) infos.size - (int64) pkg.size); - if (infos.name.length > max_name_length) { - max_name_length = infos.name.length; - } - if (infos.version.length > max_version_length) { - max_version_length = infos.version.length; - } - string size = format_size (pkg.size); - if (size.length > max_size_length) { - max_size_length = size.length; - } - } - } - } - if (summary.to_reinstall.length > 0) { - type |= TransType.STANDARD; - if (!no_confirm_commit) { - foreach (unowned AlpmPackage infos in summary.to_reinstall) { - dsize += infos.download_size; - var pkg = get_installed_pkg (infos.name); - if (infos.name.length > max_name_length) { - max_name_length = infos.name.length; - } - if (infos.version.length > max_version_length) { - max_version_length = infos.version.length; - } - string size = format_size (pkg.size); - if (size.length > max_size_length) { - max_size_length = size.length; - } - } - } - } - if (summary.to_upgrade.length > 0) { - type |= TransType.UPDATE; - if (!no_confirm_commit) { - foreach (unowned AlpmPackage infos in summary.to_upgrade) { - dsize += infos.download_size; - var pkg = get_installed_pkg (infos.name); - isize += ((int64) infos.size - (int64) pkg.size); - if (infos.name.length > max_name_length) { - max_name_length = infos.name.length; - } - if (infos.version.length > max_version_length) { - max_version_length = infos.version.length; - } - if (infos.installed_version.length > max_installed_version_length) { - max_installed_version_length = infos.installed_version.length; - } - string size = format_size (pkg.size); - if (size.length > max_size_length) { - max_size_length = size.length; - } - } - } - } - // second pass to print details - if (!no_confirm_commit) { - max_installed_version_length += 2; // because of (%s) - int total_width = max_name_length + max_version_length + max_installed_version_length + max_size_length + 6; - if (get_term_width () > total_width) { - // divide available space between columns - int available_width = get_term_width () - total_width; - margin = available_width / 4; - // get left space to size - max_size_length += available_width - (margin * 4); - } - if (summary.to_upgrade.length > 0) { - stdout.printf (dgettext (null, "To upgrade") + " (%u):\n".printf (summary.to_upgrade.length)); - foreach (unowned AlpmPackage infos in summary.to_upgrade) { - stdout.printf (" %-*s %-*s %-*s %*s \n", max_name_length + margin, infos.name, - max_version_length + margin, infos.version, - max_installed_version_length + margin, "(%s)".printf (infos.installed_version), - max_size_length + margin, format_size (infos.size)); - } - } - if (summary.to_reinstall.length > 0) { - stdout.printf (dgettext (null, "To reinstall") + " (%u):\n".printf (summary.to_reinstall.length)); - foreach (unowned AlpmPackage infos in summary.to_reinstall) { - stdout.printf (" %-*s %-*s %*s \n", max_name_length + margin, infos.name, - max_version_length + margin, infos.version, - max_size_length + margin, format_size (infos.size)); - } - } - if (summary.to_install.length > 0) { - stdout.printf (dgettext (null, "To install") + " (%u):\n".printf (summary.to_install.length)); - foreach (unowned AlpmPackage infos in summary.to_install) { - stdout.printf (" %-*s %-*s %*s \n", max_name_length + margin, infos.name, - max_version_length + margin, infos.version, - max_size_length + margin, format_size (infos.size)); - } - } - if (summary.to_build.length > 0) { - stdout.printf (dgettext (null, "To build") + " (%u):\n".printf (summary.to_build.length)); - foreach (unowned AURPackage infos in summary.to_build) { - stdout.printf (" %-*s %-*s\n", max_name_length + margin, infos.name, - max_version_length + margin, infos.version); - } - } - if (summary.to_downgrade.length > 0) { - stdout.printf (dgettext (null, "To downgrade") + " (%u):\n".printf (summary.to_downgrade.length)); - foreach (unowned AlpmPackage infos in summary.to_downgrade) { - stdout.printf (" %-*s %-*s %-*s %*s \n", max_name_length + margin, infos.name, - max_version_length + margin, infos.version, - max_installed_version_length + margin, "(%s)".printf (infos.installed_version), - max_size_length + margin, format_size (infos.size)); - } - } - bool to_remove_printed = false; - if (summary.to_remove.length > 0) { - stdout.printf (dgettext (null, "To remove") + " (%u):\n".printf (summary.to_remove.length)); - to_remove_printed = true; - foreach (unowned AlpmPackage infos in summary.to_remove) { - stdout.printf (" %-*s %-*s\n", max_name_length + margin, infos.name, - max_version_length + margin, infos.version); - } - } - if (summary.aur_conflicts_to_remove.length > 0) { - if (!to_remove_printed) { - stdout.printf (dgettext (null, "To remove") + " (%u):\n".printf (summary.aur_conflicts_to_remove.length)); - } - foreach (unowned AlpmPackage infos in summary.aur_conflicts_to_remove) { - stdout.printf (" %-*s %-*s\n", max_name_length + margin, infos.name, - max_version_length + margin, infos.version); - } - } - stdout.printf ("\n"); - if (dsize > 0) { - stdout.printf ("%s: %s\n", dgettext (null, "Total download size"), format_size (dsize)); - } - if (isize > 0) { - stdout.printf ("%s: %s\n", dgettext (null, "Total installed size"), format_size (isize)); - } else if (isize < 0) { - stdout.printf ("%s: -%s\n", dgettext (null, "Total installed size"), format_size (isize.abs ())); - } - if (rsize > 0) { - stdout.printf ("%s: %s\n", dgettext (null, "Total removed size"), format_size (rsize)); - } - } - return type; + void start_refresh () { + this.hold (); + // let's time to pkttyagent to get registred + Timeout.add (200, () => { + transaction.start_refresh (force_refresh); + return false; + }); } - void on_trans_prepare_finished (bool success) { + void on_refresh_finished (bool success) { if (success) { - TransType type = set_transaction_sum (); - if (to_install_first.length != 0) { - if (ask_confirmation ()) { - sysupgrade_after_trans = true; - no_confirm_commit = true; - trans_release (); - to_install = to_install_first; - start_trans_prepare (); - to_install_first = {}; - } else { - stdout.printf (dgettext (null, "Transaction cancelled") + ".\n"); - trans_release (); - unlock (); - this.release (); - cmd.set_exit_status (1); - } - } else if (no_confirm_commit) { - // no_confirm_commit or only updates - start_trans_commit (); - } else if (type != 0) { - if (ask_confirmation ()) { - if (type == Type.BUILD) { - // there only AUR packages to build - trans_release (); - on_trans_commit_finished (true); - } else { - start_trans_commit (); - } - } else { - stdout.printf (dgettext (null, "Transaction cancelled") + ".\n"); - trans_release (); - unlock (); - this.release (); - cmd.set_exit_status (1); - } - } else { - stdout.printf (dgettext (null, "Nothing to do") + ".\n"); - trans_release (); - unlock (); - this.release (); - } + transaction.start_sysupgrade (enable_downgrade, temporary_ignorepkgs, overwrite_files); } else { - var err = get_current_error (); - if (err.message != "") { - print_error (err.message, err.details); - } - unlock (); + transaction.unlock (); this.release (); cmd.set_exit_status (1); } } - bool ask_confirmation () { - stdout.printf ("%s ? %s ", dgettext (null, "Commit transaction"), dgettext (null, "[y/N]")); - char buf[32]; - if (stdin.gets (buf) != null) { - string ans = (string) buf; - // remove trailing newline and uppercase - ans = ans.replace ("\n", "").down (); - // just return use default - if (ans != "") { - if (ans == dgettext (null, "y") || - ans == dgettext (null, "yes")) { - return true; - } - } - } - return false; - } - - void start_trans_commit () { - try { - asking_user_input = true; - system_daemon.start_trans_commit (); - } catch (Error e) { - print_error (e.message); - on_trans_commit_finished (false); - } - } - - void on_trans_commit_finished (bool success) { - asking_user_input = false; - // needed before build_aur_packages - no_confirm_commit = false; - if (success) { - if (to_build_queue.get_length () != 0) { - stdout.printf ("\n"); - check_authorization.begin ((obj, res) => { - bool authorized = check_authorization.end (res); - if (authorized) { - build_aur_packages.begin (); - } else { - to_build_queue.clear (); - on_trans_commit_finished (false); - } - }); - } else { - if (sysupgrade_after_trans) { - no_confirm_commit = true; - start_get_updates_for_sysupgrade (); - } else { - stdout.printf (dgettext (null, "Transaction successfully finished") + ".\n"); - unlock (); - this.release (); - } - } - } else { - var err = get_current_error (); - if (err.message != "") { - print_error (err.message, err.details); - } - to_build_queue.clear (); - unlock (); - this.release (); + void on_transaction_finished (bool success) { + transaction.unlock (); + this.release (); + if (!success) { cmd.set_exit_status (1); } - total_download = 0; - already_downloaded = 0; - previous_filename = ""; - } - - void trans_release () { - try { - system_daemon.trans_release (); - } catch (Error e) { - print_error (e.message); - } - } - - ErrorInfos get_current_error () { - try { - return system_daemon.get_current_error (); - } catch (Error e) { - print_error (e.message); - return ErrorInfos (); - } - } - - void on_emit_event (uint primary_event, uint secondary_event, string[] details) { - string? action = null; - switch (primary_event) { - case 1: //Alpm.Event.Type.CHECKDEPS_START - action = dgettext (null, "Checking dependencies") + "...\n"; - asking_user_input = false; - break; - case 3: //Alpm.Event.Type.FILECONFLICTS_START - current_action = dgettext (null, "Checking file conflicts") + "..."; - break; - case 5: //Alpm.Event.Type.RESOLVEDEPS_START - action = dgettext (null, "Resolving dependencies") + "...\n"; - asking_user_input = false; - break; - case 7: //Alpm.Event.Type.INTERCONFLICTS_START - action = dgettext (null, "Checking inter-conflicts") + "...\n"; - break; - case 11: //Alpm.Event.Type.PACKAGE_OPERATION_START - switch (secondary_event) { - // special case handle differently - case 1: //Alpm.Package.Operation.INSTALL - previous_filename = details[0]; - current_action = dgettext (null, "Installing %s").printf ("%s (%s)".printf (details[0], details[1])) + "..."; - break; - case 2: //Alpm.Package.Operation.UPGRADE - previous_filename = details[0]; - current_action = dgettext (null, "Upgrading %s").printf ("%s (%s -> %s)".printf (details[0], details[1], details[2])) + "..."; - break; - case 3: //Alpm.Package.Operation.REINSTALL - previous_filename = details[0]; - current_action = dgettext (null, "Reinstalling %s").printf ("%s (%s)".printf (details[0], details[1])) + "..."; - break; - case 4: //Alpm.Package.Operation.DOWNGRADE - previous_filename = details[0]; - current_action = dgettext (null, "Downgrading %s").printf ("%s (%s -> %s)".printf (details[0], details[1], details[2])) + "..."; - break; - case 5: //Alpm.Package.Operation.REMOVE - previous_filename = details[0]; - current_action = dgettext (null, "Removing %s").printf ("%s (%s)".printf (details[0], details[1])) + "..."; - break; - } - break; - case 13: //Alpm.Event.Type.INTEGRITY_START - current_action = dgettext (null, "Checking integrity") + "..."; - break; - case 15: //Alpm.Event.Type.LOAD_START - current_action = dgettext (null, "Loading packages files") + "..."; - break; - case 17: //Alpm.Event.Type.DELTA_INTEGRITY_START - action = dgettext (null, "Checking delta integrity") + "...\n"; - break; - case 19: //Alpm.Event.Type.DELTA_PATCHES_START - action = dgettext (null, "Applying deltas") + "...\n"; - break; - case 21: //Alpm.Event.Type.DELTA_PATCH_START - action = dgettext (null, "Generating %s with %s").printf (details[0], details[1]) + "...\n"; - break; - case 22: //Alpm.Event.Type.DELTA_PATCH_DONE - action = dgettext (null, "Generation succeeded") + "...\n"; - break; - case 23: //Alpm.Event.Type.DELTA_PATCH_FAILED - action = dgettext (null, "Generation failed") + "...\n"; - break; - case 24: //Alpm.Event.Type.SCRIPTLET_INFO - // hooks output are also emitted as SCRIPTLET_INFO - //if (previous_filename != "") { - //stdout.printf (dgettext (null, "Configuring %s").printf (previous_filename) + "...\n"); - //} - foreach (unowned string detail in split_string (details[0].replace ("\n", ""), 0, get_term_width ())) { - stdout.printf ("%s\n", detail); - } - break; - case 25: //Alpm.Event.Type.RETRIEVE_START - action = dgettext (null, "Downloading") + "...\n"; - asking_user_input = false; - break; - case 26: //Alpm.Event.Type.RETRIEVE_DONE - case 27: //Alpm.Event.Type.RETRIEVE_FAILED - stdout.printf ("\n"); - break; - case 28: //Alpm.Event.Type.PKGDOWNLOAD_START - // special case handle differently - string name_version_release = details[0].slice (0, details[0].last_index_of_char ('-')); - current_action = dgettext (null, "Downloading %s").printf (name_version_release) + "..."; - break; - case 31: //Alpm.Event.Type.DISKSPACE_START - current_action = dgettext (null, "Checking available disk space") + "..."; - break; - case 33: //Alpm.Event.Type.OPTDEP_REMOVAL - action = dgettext (null, "Warning") + ": " + dgettext (null, "%s optionally requires %s").printf (details[0], details[1]) + "\n"; - break; - case 34: //Alpm.Event.Type.DATABASE_MISSING - action = dgettext (null, "Database file for %s does not exist").printf (details[0]) + "\n"; - break; - case 35: //Alpm.Event.Type.KEYRING_START - current_action = dgettext (null, "Checking keyring") + "..."; - break; - case 37: //Alpm.Event.Type.KEY_DOWNLOAD_START - action = dgettext (null, "Downloading required keys") + "...\n"; - break; - case 39: //Alpm.Event.Type.PACNEW_CREATED - action = dgettext (null, "%s installed as %s.pacnew").printf (details[0], details[0]) + "\n"; - break; - case 40: //Alpm.Event.Type.PACSAVE_CREATED - action = dgettext (null, "%s installed as %s.pacsave").printf (details[0], details[0]) + "\n"; - break; - case 41: //Alpm.Event.Type.HOOK_START - switch (secondary_event) { - case 1: //Alpm.HookWhen.PRE_TRANSACTION - action = dgettext (null, "Running pre-transaction hooks") + ":\n"; - break; - case 2: //Alpm.HookWhen.POST_TRANSACTION - previous_filename = ""; - action = dgettext (null, "Running post-transaction hooks") + ":\n"; - break; - default: - break; - } - break; - case 43: // Alpm.Event.Type.HOOK_RUN_START - if (details[1] != "") { - print_progress (details[1], "[%s/%s]".printf (details[2], details[3]), true); - } else { - print_progress (details[0], "[%s/%s]".printf (details[2], details[3]), true); - } - break; - default: - break; - } - if (action != null) { - stdout.printf (action); - } - } - - void on_emit_providers (string depend, string[] providers) { - AlpmPackage[] pkgs = {}; - foreach (unowned string pkgname in providers) { - try { - var pkg = user_daemon.get_sync_pkg (pkgname); - if (pkg.name != "") { - pkgs += pkg; - } - } catch (Error e) { - print_error (e.message); - } - } - // print pkgs - int name_length = 0; - int version_length = 0; - int repo_length = 0; - foreach (unowned AlpmPackage pkg in pkgs) { - if (pkg.name.length > name_length) { - name_length = pkg.name.length; - } - if (pkg.version.length > version_length) { - version_length = pkg.version.length; - } - if (pkg.repo.length > repo_length) { - repo_length = pkg.repo.length; - } - } - int num_length = providers.length.to_string ().length + 1; - int total_width = num_length + name_length + version_length + repo_length + 4; - int margin = 0; - if (get_term_width () > total_width) { - // divide available space between columns - int available_width = get_term_width () - total_width; - margin = available_width / 3; - // get left space to repo - repo_length += available_width - (margin * 3); - } - stdout.printf ("%s:\n".printf (dgettext (null, "Choose a provider for %s").printf (depend))); - int num = 1; - foreach (unowned AlpmPackage pkg in pkgs) { - stdout.printf ("%*s %-*s %-*s %-*s \n", num_length, "%i:".printf (num), - name_length + margin, pkg.name, - version_length + margin, pkg.version, - repo_length + margin, pkg.repo); - num++; - } - // get user input - asking_user_input = true; - while (true) { - stdout.printf ("%s: ", dgettext (null, "Enter a number (default=%d)").printf (1)); - string ans = stdin.read_line (); - int64 nb; - // remvove trailing newline - ans = ans.replace ("\n", ""); - // just return use default - if (ans == "") { - nb = 1; - } else if (!int64.try_parse (ans, out nb)) { - nb = 0; - } - stdout.printf ("\n"); - if (nb >= 1 && nb <= providers.length) { - int index = (int) nb - 1; - try { - system_daemon.choose_provider (index); - } catch (Error e) { - print_error (e.message); - } - break; - } - } - } - - void on_emit_progress (uint progress, string pkgname, uint percent, uint n_targets, uint current_target) { - switch (progress) { - case 0: //Alpm.Progress.ADD_START - case 1: //Alpm.Progress.UPGRADE_START - case 2: //Alpm.Progress.DOWNGRADE_START - case 3: //Alpm.Progress.REINSTALL_START - case 4: //Alpm.Progress.REMOVE_START - case 5: //Alpm.Progress.CONFLICTS_START - case 6: //Alpm.Progress.DISKSPACE_START - case 7: //Alpm.Progress.INTEGRITY_START - case 8: //Alpm.Progress.LOAD_START - case 9: //Alpm.Progress.KEYRING_START - if (current_action == previous_action) { - if (percent != previous_percent) { - previous_percent = percent; - if (percent != 100) { - print_progress (current_action, "[%u/%u]".printf (current_target, n_targets), false); - } else { - print_progress (current_action, "[%u/%u]".printf (current_target, n_targets), true); - } - } - } else { - previous_action = current_action; - previous_percent = percent; - if (percent != 100) { - print_progress (current_action, "[%u/%u]".printf (current_target, n_targets), false); - } else { - print_progress (current_action, "[%u/%u]".printf (current_target, n_targets), true); - } - } - break; - default: - break; - } - } - - void on_emit_download (string filename, uint64 xfered, uint64 total) { - var text = new StringBuilder (); - float fraction; - if (total_download > 0) { - if (xfered == 0) { - // start download pkg is handled by Alpm.Event.Type.PKGDOWNLOAD_START - previous_xfered = 0; - fraction = previous_percent; - text.append (previous_textbar); - timer.start (); - } else { - if (timer.elapsed () > 0.1) { - download_rate = ((download_rate * rates_nb) + (uint64) ((xfered - previous_xfered) / timer.elapsed ())) / (rates_nb + 1); - rates_nb++; - } - previous_xfered = xfered; - uint64 downloaded_total = xfered + already_downloaded; - fraction = (float) downloaded_total / total_download; - if (fraction <= 1) { - text.append ("%s/%s ".printf (format_size (xfered + already_downloaded), format_size (total_download))); - uint64 remaining_seconds = 0; - if (download_rate > 0) { - remaining_seconds = (total_download - downloaded_total) / download_rate; - } - // display remaining time after 5s and only if more than 10s are remaining - if (remaining_seconds > 9 && rates_nb > 9) { - if (remaining_seconds <= 50) { - text.append (dgettext (null, "About %u seconds remaining").printf ((uint) Math.ceilf ((float) remaining_seconds / 10) * 10)); - } else { - uint remaining_minutes = (uint) Math.ceilf ((float) remaining_seconds / 60); - text.append (dngettext (null, "About %lu minute remaining", - "About %lu minutes remaining", remaining_minutes).printf (remaining_minutes)); - } - } - } else { - text.append ("%s".printf (format_size (xfered + already_downloaded))); - } - if (xfered == total) { - previous_filename = ""; - already_downloaded += total; - } else { - timer.start (); - } - } - } else { - if (xfered == 0) { - previous_xfered = 0; - download_rate = 0; - rates_nb = 0; - fraction = 0; - timer.start (); - if (filename.has_suffix (".db") || filename.has_suffix (".files")) { - current_action = dgettext (null, "Refreshing %s").printf (filename) + "..."; - } else { - // case of download pkg from url start - string name_version_release = filename.slice (0, filename.last_index_of_char ('-')); - current_action = dgettext (null, "Downloading %s").printf (name_version_release) + "..."; - } - } else if (xfered == total) { - timer.stop (); - fraction = 1; - previous_filename = ""; - } else { - if (timer.elapsed () > 0.1) { - download_rate = ((download_rate * rates_nb) + (uint64) ((xfered - previous_xfered) / timer.elapsed ())) / (rates_nb + 1); - rates_nb++; - } - previous_xfered = xfered; - fraction = (float) xfered / total; - if (fraction <= 1) { - text.append ("%s/%s ".printf (format_size (xfered), format_size (total))); - uint64 remaining_seconds = 0; - if (download_rate > 0) { - remaining_seconds = (total - xfered) / download_rate; - } - // display remaining time after 5s and only if more than 10s are remaining - if (remaining_seconds > 9 && rates_nb > 9) { - if (remaining_seconds <= 50) { - text.append (dgettext (null, "About %u seconds remaining").printf ((uint) Math.ceilf ((float) remaining_seconds / 10) * 10)); - } else { - uint remaining_minutes = (uint) Math.ceilf ((float) remaining_seconds / 60); - text.append (dngettext (null, "About %lu minute remaining", - "About %lu minutes remaining", remaining_minutes).printf (remaining_minutes)); - } - } - } else { - text.append ("%s".printf (format_size (xfered))); - } - // reinitialize timer - timer.start (); - } - } - if (current_action == previous_action) { - previous_textbar = text.str; - // clean line - stdout.printf ("\r%*s", get_term_width (), ""); - stdout.printf ("\r%s", text.str); - stdout.flush (); - } else { - previous_action = current_action; - // clean line - stdout.printf ("\r%*s", get_term_width (), ""); - stdout.printf ("\r%s\n", current_action); - stdout.printf (text.str); - stdout.flush (); - } - } - - void on_emit_totaldownload (uint64 total) { - download_rate = 0; - rates_nb = 0; - previous_percent = 0; - previous_textbar = ""; - total_download = total; - // this is emitted at the end of the total download - // with the value 0 so stop our timer - if (total == 0) { - timer.stop (); - } - } - - void on_emit_log (uint level, string msg) { - // msg ends with \n - string? line = null; - if (level == 1) { //Alpm.LogLevel.ERROR - if (previous_filename != "") { - line = dgettext (null, "Error") + ": " + previous_filename + ": " + msg; - } else { - line = dgettext (null, "Error") + ": " + msg; - } - } else if (level == (1 << 1)) { //Alpm.LogLevel.WARNING - // do not show warning when manjaro-system remove db.lck - if (previous_filename != "manjaro-system") { - if (previous_filename != "") { - line = dgettext (null, "Warning") + ": " + previous_filename + ": " + msg; - } else { - line = dgettext (null, "Warning") + ": " + msg; - } - } - } - if (line != null) { - // keep a nice output in case of download - stdout.printf ("\r%s", line); - stdout.printf (previous_textbar); - stdout.flush (); - } } public static int main (string[] args) { diff --git a/src/common.vala b/src/common.vala index d126b57c..53cc04d7 100644 --- a/src/common.vala +++ b/src/common.vala @@ -30,7 +30,6 @@ namespace Pamac { } public struct Updates { - public bool is_syncfirst; public AlpmPackage[] repos_updates; public AURPackage[] aur_updates; } diff --git a/src/common_daemon.vala b/src/common_daemon.vala new file mode 100644 index 00000000..0cfc8da2 --- /dev/null +++ b/src/common_daemon.vala @@ -0,0 +1,52 @@ +/* + * pamac-vala + * + * Copyright (C) 2014-2018 Guillaume Benoit <guillaume@manjaro.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a get of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +namespace Pamac { + public struct TransactionSummary { + public AlpmPackage[] to_install; + public AlpmPackage[] to_upgrade; + public AlpmPackage[] to_downgrade; + public AlpmPackage[] to_reinstall; + public AlpmPackage[] to_remove; + public AURPackage[] to_build; + public AlpmPackage[] aur_conflicts_to_remove; + public string[] aur_pkgbases_to_build; + } + + public struct Updates { + public AlpmPackage[] repos_updates; + public AURPackage[] aur_updates; + } + + public struct UpdatesPriv { + public bool syncfirst; + public AlpmPackage[] repos_updates; + public AURPackage[] aur_updates; + } + + public struct ErrorInfos { + public uint no; + public string message; + public string[] details; + public ErrorInfos () { + message = ""; + } + } +} + diff --git a/src/database.vala b/src/database.vala new file mode 100644 index 00000000..5219251c --- /dev/null +++ b/src/database.vala @@ -0,0 +1,555 @@ +/* + * pamac-vala + * + * Copyright (C) 2014-2018 Guillaume Benoit <guillaume@manjaro.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a get of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +namespace Pamac { + [DBus (name = "org.manjaro.pamac.user")] + interface UserDaemon : Object { + public abstract void enable_appstream () throws Error; + public abstract void refresh_handle () throws Error; + public abstract string[] get_mirrors_countries () throws Error; + public abstract string get_mirrors_choosen_country () throws Error; + public abstract string get_lockfile () throws Error; + public abstract AlpmPackage get_installed_pkg (string pkgname) throws Error; + public abstract bool get_checkspace () throws Error; + public abstract string[] get_ignorepkgs () throws Error; + public abstract bool should_hold (string pkgname) throws Error; + public abstract uint get_pkg_reason (string pkgname) throws Error; + public abstract uint get_pkg_origin (string pkgname) throws Error; + public abstract AlpmPackage[] get_installed_pkgs () throws Error; + public abstract AlpmPackage[] get_installed_apps () throws Error; + public abstract AlpmPackage[] get_explicitly_installed_pkgs () throws Error; + public abstract AlpmPackage[] get_foreign_pkgs () throws Error; + public abstract AlpmPackage[] get_orphans () throws Error; + public abstract async AlpmPackage[] get_installed_pkgs_async () throws Error; + public abstract async AlpmPackage[] get_installed_apps_async () throws Error; + public abstract async AlpmPackage[] get_explicitly_installed_pkgs_async () throws Error; + public abstract async AlpmPackage[] get_foreign_pkgs_async() throws Error; + public abstract async AlpmPackage[] get_orphans_async () throws Error; + public abstract AlpmPackage find_installed_satisfier (string depstring) throws Error; + public abstract AlpmPackage get_sync_pkg (string pkgname) throws Error; + public abstract AlpmPackage find_sync_satisfier (string depstring) throws Error; + public abstract AlpmPackage[] search_pkgs (string search_string) throws Error; + public abstract async AlpmPackage[] search_pkgs_async (string search_string) throws Error; + public abstract async AURPackage[] search_in_aur_async (string search_string) throws Error; + public abstract HashTable<string, Variant> search_files (string[] files) throws Error; + public abstract AlpmPackage[] get_category_pkgs (string category) throws Error; + public abstract async AlpmPackage[] get_category_pkgs_async (string category) throws Error; + public abstract string[] get_repos_names () throws Error; + public abstract AlpmPackage[] get_repo_pkgs (string repo) throws Error; + public abstract async AlpmPackage[] get_repo_pkgs_async (string repo) throws Error; + public abstract string[] get_groups_names () throws Error; + public abstract AlpmPackage[] get_group_pkgs (string groupname) throws Error; + public abstract async AlpmPackage[] get_group_pkgs_async (string groupname) throws Error; + public abstract AlpmPackageDetails get_pkg_details (string pkgname, string app_name) throws Error; + public abstract string[] get_pkg_files (string pkgname) throws Error; + public abstract async AURPackageDetails get_aur_details_async (string pkgname) throws Error; + public abstract string[] get_pkg_uninstalled_optdeps (string pkgname) throws Error; + public abstract void start_get_updates (bool check_aur_updates, bool refresh_files_dbs) throws Error; + [DBus (no_reply = true)] + public abstract void quit () throws Error; + public signal void emit_get_updates_progress (uint percent); + public signal void get_updates_finished (Updates updates); + } + + public class Database: Object { + UserDaemon user_daemon; + + public signal void get_updates_progress (uint percent); + public signal void get_updates_finished (Updates updates); + + public Config config { get; construct set; } + + public Database (Config config) { + Object (config: config); + } + + construct { + connecting_user_daemon (); + if (config.enable_aur == false) { + config.check_aur_updates = false; + } + } + + // destruction + ~Database () { + stop_daemon (); + } + + void connecting_user_daemon () { + if (user_daemon == null) { + try { + user_daemon = Bus.get_proxy_sync (BusType.SESSION, "org.manjaro.pamac.user", "/org/manjaro/pamac/user"); + } catch (Error e) { + stderr.printf ("Error: %s\n", e.message); + } + } + } + + public void stop_daemon () { + try { + user_daemon.quit (); + } catch (Error e) { + stderr.printf ("quit: %s\n", e.message); + } + } + + public void enable_appstream () { + try { + user_daemon.enable_appstream (); + } catch (Error e) { + stderr.printf ("enable_appstream: %s\n", e.message); + } + } + + public void refresh () { + try { + user_daemon.refresh_handle (); + } catch (Error e) { + stderr.printf ("refresh_handle: %s\n", e.message); + } + } + + public string[] get_mirrors_countries () { + string[] countries = {}; + try { + countries = user_daemon.get_mirrors_countries (); + } catch (Error e) { + stderr.printf ("get_mirrors_countries: %s\n", e.message); + } + return countries; + } + + public string get_mirrors_choosen_country () { + string country = ""; + try { + country = user_daemon.get_mirrors_choosen_country (); + } catch (Error e) { + stderr.printf ("get_mirrors_choosen_country: %s\n", e.message); + } + return country; + } + + public bool get_checkspace () { + bool checkspace = false; + try { + checkspace = user_daemon.get_checkspace (); + } catch (Error e) { + stderr.printf ("get_checkspace: %s\n", e.message); + } + return checkspace; + } + + public string[] get_ignorepkgs () { + string[] ignorepkgs = {}; + try { + ignorepkgs = user_daemon.get_ignorepkgs (); + } catch (Error e) { + stderr.printf ("get_ignorepkgs: %s\n", e.message); + } + return ignorepkgs; + } + + public AlpmPackage get_installed_pkg (string pkgname) { + try { + return user_daemon.get_installed_pkg (pkgname); + } catch (Error e) { + stderr.printf ("get_installed_pkg: %s\n", e.message); + return AlpmPackage () { + name = "", + version = "", + desc = "", + repo = "", + icon = "" + }; + } + } + + public AlpmPackage find_installed_satisfier (string depstring) { + try { + return user_daemon.find_installed_satisfier (depstring); + } catch (Error e) { + stderr.printf ("find_installed_satisfier: %s\n", e.message); + return AlpmPackage () { + name = "", + version = "", + desc = "", + repo = "" + }; + } + } + + public bool should_hold (string pkgname) { + bool should_hold = false; + try { + should_hold = user_daemon.should_hold (pkgname); + } catch (Error e) { + stderr.printf ("should_hold: %s\n", e.message); + } + return should_hold; + } + + public uint get_pkg_reason (string pkgname) { + uint reason = 0; + try { + reason = user_daemon.get_pkg_reason (pkgname); + } catch (Error e) { + stderr.printf ("get_pkg_reason: %s\n", e.message); + } + return reason; + } + + public uint get_pkg_origin (string pkgname) { + uint origin = 0; + try { + origin = user_daemon.get_pkg_origin (pkgname); + } catch (Error e) { + stderr.printf ("get_pkg_origin: %s\n", e.message); + } + return origin; + } + + public AlpmPackage[] get_installed_pkgs () { + AlpmPackage[] pkgs = {}; + try { + pkgs = user_daemon.get_installed_pkgs (); + } catch (Error e) { + stderr.printf ("get_installed_pkgs: %s\n", e.message); + } + return pkgs; + } + + public AlpmPackage[] get_installed_apps () { + AlpmPackage[] pkgs = {}; + try { + pkgs = user_daemon.get_installed_apps (); + } catch (Error e) { + stderr.printf ("get_installed_apps: %s\n", e.message); + } + return pkgs; + } + + public AlpmPackage[] get_explicitly_installed_pkgs () { + AlpmPackage[] pkgs = {}; + try { + pkgs = user_daemon.get_explicitly_installed_pkgs (); + } catch (Error e) { + stderr.printf ("get_explicitly_installed_pkgs: %s\n", e.message); + } + return pkgs; + } + + public AlpmPackage[] get_foreign_pkgs () { + AlpmPackage[] pkgs = {}; + try { + pkgs = user_daemon.get_foreign_pkgs (); + } catch (Error e) { + stderr.printf ("get_foreign_pkgs: %s\n", e.message); + } + return pkgs; + } + + public AlpmPackage[] get_orphans () { + AlpmPackage[] pkgs = {}; + try { + pkgs = user_daemon.get_orphans (); + } catch (Error e) { + stderr.printf ("get_orphans: %s\n", e.message); + } + return pkgs; + } + + public async AlpmPackage[] get_installed_pkgs_async () { + AlpmPackage[] pkgs = {}; + try { + pkgs = yield user_daemon.get_installed_pkgs_async (); + } catch (Error e) { + stderr.printf ("get_installed_pkgs_async: %s\n", e.message); + } + return pkgs; + } + + public async AlpmPackage[] get_installed_apps_async () { + AlpmPackage[] pkgs = {}; + try { + pkgs = yield user_daemon.get_installed_apps_async (); + } catch (Error e) { + stderr.printf ("get_installed_apps_async: %s\n", e.message); + } + return pkgs; + } + + public async AlpmPackage[] get_explicitly_installed_pkgs_async () { + AlpmPackage[] pkgs = {}; + try { + pkgs = yield user_daemon.get_explicitly_installed_pkgs_async (); + } catch (Error e) { + stderr.printf ("get_explicitly_installed_pkgs_async: %s\n", e.message); + } + return pkgs; + } + + public async AlpmPackage[] get_foreign_pkgs_async () { + AlpmPackage[] pkgs = {}; + try { + pkgs = yield user_daemon.get_foreign_pkgs_async (); + } catch (Error e) { + stderr.printf ("get_foreign_pkgs_async: %s\n", e.message); + } + return pkgs; + } + + public async AlpmPackage[] get_orphans_async () { + AlpmPackage[] pkgs = {}; + try { + pkgs = yield user_daemon.get_orphans_async (); + } catch (Error e) { + stderr.printf ("get_orphans_async: %s\n", e.message); + } + return pkgs; + } + + public AlpmPackage get_sync_pkg (string pkgname) { + try { + return user_daemon.get_sync_pkg (pkgname); + } catch (Error e) { + stderr.printf ("get_sync_pkg: %s\n", e.message); + return AlpmPackage () { + name = "", + version = "", + desc = "", + repo = "" + }; + } + } + + public AlpmPackage find_sync_satisfier (string depstring) { + try { + return user_daemon.find_sync_satisfier (depstring); + } catch (Error e) { + stderr.printf ("find_sync_satisfier: %s\n", e.message); + return AlpmPackage () { + name = "", + version = "", + desc = "", + repo = "" + }; + } + } + + public AlpmPackage[] search_pkgs (string search_string) { + AlpmPackage[] pkgs = {}; + try { + pkgs = user_daemon.search_pkgs (search_string); + } catch (Error e) { + stderr.printf ("search_pkgs: %s\n", e.message); + } + return pkgs; + } + + public async AlpmPackage[] search_pkgs_async (string search_string) { + AlpmPackage[] pkgs = {}; + try { + pkgs = yield user_daemon.search_pkgs_async (search_string); + } catch (Error e) { + stderr.printf ("search_pkgs_async: %s\n", e.message); + } + return pkgs; + } + + public async AURPackage[] search_in_aur_async (string search_string) { + AURPackage[] pkgs = {}; + if (config.enable_aur) { + try { + pkgs = yield user_daemon.search_in_aur_async (search_string); + } catch (Error e) { + stderr.printf ("search_in_aur_async: %s\n", e.message); + } + } + return pkgs; + } + + public HashTable<string, Variant> search_files (string[] files) { + var result = new HashTable<string, Variant> (str_hash, str_equal); + try { + result = user_daemon.search_files (files); + } catch (Error e) { + stderr.printf ("search_files: %s\n", e.message); + } + return result; + } + + public AlpmPackage[] get_category_pkgs (string category) { + AlpmPackage[] pkgs = {}; + try { + pkgs = user_daemon.get_category_pkgs (category); + } catch (Error e) { + stderr.printf ("get_category_pkgs: %s\n", e.message); + } + return pkgs; + } + + public async AlpmPackage[] get_category_pkgs_async (string category) { + AlpmPackage[] pkgs = {}; + try { + pkgs = yield user_daemon.get_category_pkgs_async (category); + } catch (Error e) { + stderr.printf ("get_category_pkgs_async: %s\n", e.message); + } + return pkgs; + } + + public string[] get_repos_names () { + string[] repos_names = {}; + try { + repos_names = user_daemon.get_repos_names (); + } catch (Error e) { + stderr.printf ("get_repos_names: %s\n", e.message); + } + return repos_names; + } + + public AlpmPackage[] get_repo_pkgs (string repo) { + AlpmPackage[] pkgs = {}; + try { + pkgs = user_daemon.get_repo_pkgs (repo); + } catch (Error e) { + stderr.printf ("get_repo_pkgs: %s\n", e.message); + } + return pkgs; + } + + public async AlpmPackage[] get_repo_pkgs_async (string repo) { + AlpmPackage[] pkgs = {}; + try { + pkgs = yield user_daemon.get_repo_pkgs_async (repo); + } catch (Error e) { + stderr.printf ("get_repo_pkgs_async: %s\n", e.message); + } + return pkgs; + } + + public string[] get_groups_names () { + string[] groups_names = {}; + try { + groups_names = user_daemon.get_groups_names (); + } catch (Error e) { + stderr.printf ("get_groups_names: %s\n", e.message); + } + return groups_names; + } + + public AlpmPackage[] get_group_pkgs (string group_name) { + AlpmPackage[] pkgs = {}; + try { + pkgs = user_daemon.get_group_pkgs (group_name); + } catch (Error e) { + stderr.printf ("get_group_pkgs: %s\n", e.message); + } + return pkgs; + } + + public async AlpmPackage[] get_group_pkgs_async (string group_name) { + AlpmPackage[] pkgs = {}; + try { + pkgs = yield user_daemon.get_group_pkgs_async (group_name); + } catch (Error e) { + stderr.printf ("get_group_pkgs_async: %s\n", e.message); + } + return pkgs; + } + + public string[] get_pkg_uninstalled_optdeps (string pkgname) { + string[] optdeps = {}; + try { + optdeps = user_daemon.get_pkg_uninstalled_optdeps (pkgname); + } catch (Error e) { + stderr.printf ("get_pkg_uninstalled_optdeps: %s\n", e.message); + } + return optdeps; + } + + public AlpmPackageDetails get_pkg_details (string pkgname, string app_name) { + try { + return user_daemon.get_pkg_details (pkgname, app_name); + } catch (Error e) { + stderr.printf ("get_pkg_details: %s\n", e.message); + return AlpmPackageDetails () { + name = "", + version = "", + desc = "", + repo = "", + url = "", + packager = "", + builddate = "", + installdate = "", + reason = "", + has_signature = "" + }; + } + } + + public string[] get_pkg_files (string pkgname) { + try { + return user_daemon.get_pkg_files (pkgname); + } catch (Error e) { + stderr.printf ("get_pkg_files: %s\n", e.message); + return {}; + } + } + + public async AURPackageDetails get_aur_details_async (string pkgname) { + var pkg = AURPackageDetails () { + name = "", + version = "", + desc = "", + packagebase = "", + url = "", + maintainer = "" + }; + if (config.enable_aur) { + try { + pkg = yield user_daemon.get_aur_details_async (pkgname); + } catch (Error e) { + stderr.printf ("get_aur_details_async: %s\n", e.message); + } + } + return pkg; + } + + public void start_get_updates () { + user_daemon.emit_get_updates_progress.connect (on_emit_get_updates_progress); + user_daemon.get_updates_finished.connect (on_get_updates_finished); + try { + user_daemon.start_get_updates (config.check_aur_updates, false); + } catch (Error e) { + stderr.printf ("start_get_updates: %s\n", e.message); + } + } + + void on_emit_get_updates_progress (uint percent) { + get_updates_progress (percent); + } + + void on_get_updates_finished (Updates updates) { + user_daemon.emit_get_updates_progress.disconnect (on_emit_get_updates_progress); + user_daemon.get_updates_finished.disconnect (on_get_updates_finished); + get_updates_finished (updates); + } + } +} diff --git a/src/installer.vala b/src/installer.vala index f9abf2d4..f5820ac4 100644 --- a/src/installer.vala +++ b/src/installer.vala @@ -21,7 +21,8 @@ namespace Pamac { public class Installer: Gtk.Application { ApplicationCommandLine cmd; - Transaction transaction; + Database database; + TransactionGtk transaction; ProgressDialog progress_dialog; bool important_details; @@ -38,11 +39,13 @@ namespace Pamac { base.startup (); important_details = false; + var pamac_config = new Config ("/etc/pamac.conf"); + database = new Database (pamac_config); // integrate progress box and term widget progress_dialog = new ProgressDialog (); - transaction = new Transaction (progress_dialog as Gtk.ApplicationWindow); - transaction.mode = Transaction.Mode.INSTALLER; + transaction = new TransactionGtk (database, progress_dialog as Gtk.ApplicationWindow); transaction.finished.connect (on_transaction_finished); + transaction.sysupgrade_finished.connect (on_transaction_finished); transaction.important_details_outpout.connect (on_important_details_outpout); progress_dialog.box.pack_start (transaction.progress_box); progress_dialog.box.reorder_child (transaction.progress_box, 0); @@ -55,40 +58,64 @@ namespace Pamac { public override int command_line (ApplicationCommandLine cmd) { this.cmd = cmd; string[] args = cmd.get_arguments (); - foreach (unowned string target in args[1:args.length]) { - // check for local or remote path - if (".pkg.tar" in target) { - if ("://" in target) { - if ("file://" in target) { - // handle file:// uri - var file = File.new_for_uri (target); - string? absolute_path = file.get_path (); - if (absolute_path != null) { - transaction.to_load.add (absolute_path); + string[] to_install = {}; + string[] to_remove = {}; + string[] to_load = {}; + if (args.length == 1) { + display_help (); + return cmd.get_exit_status (); + } + if (args[1] == "--help" || args[1] == "-h") { + display_help (); + return cmd.get_exit_status (); + } else { + bool add_to_remove = false; + int i = 1; + while (i < args.length) { + unowned string target = args[i]; + if (target == "--remove") { + add_to_remove = true; + } else { + if (add_to_remove) { + to_remove += target; + } else if (".pkg.tar" in target) { + // check for local or remote path + if ("://" in target) { + if ("file://" in target) { + // handle file:// uri + var file = File.new_for_uri (target); + string? absolute_path = file.get_path (); + if (absolute_path != null) { + to_load += absolute_path; + } + } else { + // add url in to_load, pkg will be downloaded by system_daemon + to_load += target; + } + } else { + // handle local or absolute path + var file = File.new_for_path (target); + string? absolute_path = file.get_path (); + if (absolute_path != null) { + to_load += absolute_path; + } } } else { - // add url in to_load, pkg will be downloaded by system_daemon - transaction.to_load.add (target); - } - } else { - // handle local or absolute path - var file = File.new_for_path (target); - string? absolute_path = file.get_path (); - if (absolute_path != null) { - transaction.to_load.add (absolute_path); + to_install += target; } } - } else { - transaction.to_install.add (target); + i++; } } - if (transaction.to_install.length == 0 && transaction.to_load.length == 0) { + if (to_install.length == 0 + && to_load.length == 0 + && to_remove.length == 0) { stdout.printf (dgettext (null, "Nothing to do") + ".\n"); } else { this.hold (); progress_dialog.show (); if (transaction.get_lock ()) { - transaction.run (); + transaction.start (to_install, to_remove, to_load, {}, {}); } else { transaction.progress_box.action_label.label = dgettext (null, "Waiting for another package manager to quit") + "..."; transaction.start_progressbar_pulse (); @@ -96,7 +123,7 @@ namespace Pamac { bool locked = transaction.get_lock (); if (locked) { transaction.stop_progressbar_pulse (); - transaction.run (); + transaction.start (to_install, to_remove, to_load, {}, {}); } return !locked; }); @@ -105,6 +132,15 @@ namespace Pamac { return cmd.get_exit_status (); } + void display_help () { + stdout.printf (dgettext (null, "Install packages from repositories, path or url")); + stdout.printf (" / "); + stdout.printf (dgettext (null, "Remove packages")); + stdout.printf ("\n\n"); + stdout.printf ("pamac-installer <%s> [--remove] [%s]".printf (dgettext (null, "package(s)"), dgettext (null, "package(s)"))); + stdout.printf ("\n"); + } + void on_important_details_outpout (bool must_show) { important_details = true; progress_dialog.expander.expanded = true; diff --git a/src/manager.vala b/src/manager.vala index 8ec1929b..a0d68580 100644 --- a/src/manager.vala +++ b/src/manager.vala @@ -106,6 +106,7 @@ namespace Pamac { public override void shutdown () { base.shutdown (); if (!pamac_run) { + manager_window.database.stop_daemon (); manager_window.transaction.stop_daemon (); } } diff --git a/src/manager_window.vala b/src/manager_window.vala index 485553ce..6504f63b 100644 --- a/src/manager_window.vala +++ b/src/manager_window.vala @@ -170,8 +170,15 @@ namespace Pamac { public Queue<string> display_package_queue; string current_package_displayed; - - public Transaction transaction; + public GenericSet<string?> to_install; + public GenericSet<string?> to_remove; + public GenericSet<string?> to_load; + public GenericSet<string?> to_build; + public GenericSet<string?> to_update; + public GenericSet<string?> temporary_ignorepkgs; + + public TransactionGtk transaction; + public Database database; delegate void TransactionAction (); bool refreshing; @@ -185,8 +192,6 @@ namespace Pamac { AlpmPackage[] repos_updates; AURPackage[] aur_updates; - bool extern_lock; - uint search_entry_timeout_id; string search_string; Gtk.Label pending_label; @@ -263,20 +268,20 @@ namespace Pamac { if (origin == 2) { //origin == Alpm.Package.From.LOCALDB if (unlikely (transaction.transaction_summary.contains (pkgname))) { pixbuf = installed_locked_icon; - } else if (unlikely (transaction.should_hold (pkgname))) { + } else if (unlikely (database.should_hold (pkgname))) { pixbuf = installed_locked_icon; - } else if (unlikely (transaction.to_install.contains (pkgname))) { + } else if (unlikely (to_install.contains (pkgname))) { pixbuf = to_reinstall_icon; - } else if (unlikely (transaction.to_remove.contains (pkgname))) { + } else if (unlikely (to_remove.contains (pkgname))) { pixbuf = to_remove_icon; } else { pixbuf = installed_icon; } } else if (unlikely (transaction.transaction_summary.contains (pkgname))) { pixbuf = available_locked_icon; - } else if (unlikely (transaction.to_install.contains (pkgname))) { + } else if (unlikely (to_install.contains (pkgname))) { pixbuf = to_install_icon; - } else if (unlikely (transaction.to_update.contains (pkgname))) { + } else if (unlikely (to_update.contains (pkgname))) { pixbuf = to_upgrade_icon; } else { pixbuf = uninstalled_icon; @@ -305,7 +310,7 @@ namespace Pamac { string pkgname; treemodel.get (treeiter, 0, out origin, 1, out pkgname); if (filters_stack.visible_child_name == "updates") { - if (unlikely (transaction.temporary_ignorepkgs.contains (pkgname))) { + if (unlikely (temporary_ignorepkgs.contains (pkgname))) { pixbuf = uninstalled_icon; } else { pixbuf = to_upgrade_icon; @@ -313,16 +318,16 @@ namespace Pamac { } else if ((uint) origin == 2) { //origin == Alpm.Package.From.LOCALDB if (unlikely (transaction.transaction_summary.contains (pkgname))) { pixbuf = installed_locked_icon; - } else if (unlikely (transaction.should_hold (pkgname))) { + } else if (unlikely (database.should_hold (pkgname))) { pixbuf = installed_locked_icon; - } else if (unlikely (transaction.to_install.contains (pkgname))) { + } else if (unlikely (to_install.contains (pkgname))) { pixbuf = to_reinstall_icon; - } else if (unlikely (transaction.to_remove.contains (pkgname))) { + } else if (unlikely (to_remove.contains (pkgname))) { pixbuf = to_remove_icon; } else { pixbuf = installed_icon; } - } else if (unlikely (transaction.to_build.contains (pkgname))) { + } else if (unlikely (to_build.contains (pkgname))) { pixbuf = to_install_icon; } else { pixbuf = uninstalled_icon; @@ -345,28 +350,38 @@ namespace Pamac { stderr.printf ("%s\n", e.message); } - transaction = new Transaction (this as Gtk.ApplicationWindow); + var config = new Config ("/etc/pamac.conf"); + database = new Database (config); + database.enable_appstream (); + database.get_updates_progress.connect (on_get_updates_progress); + database.get_updates_finished.connect (on_get_updates_finished); + + transaction = new TransactionGtk (database, this as Gtk.ApplicationWindow); + transaction.no_confirm_upgrade = true; transaction.start_downloading.connect (on_start_downloading); transaction.stop_downloading.connect (on_stop_downloading); transaction.start_building.connect (on_start_building); transaction.stop_building.connect (on_stop_building); transaction.important_details_outpout.connect (on_important_details_outpout); + transaction.refresh_finished.connect (on_refresh_finished); + transaction.sysupgrade_finished.connect (on_transaction_finished); transaction.finished.connect (on_transaction_finished); transaction.write_pamac_config_finished.connect (on_write_pamac_config_finished); transaction.set_pkgreason_finished.connect (on_set_pkgreason_finished); - transaction.generate_mirrors_list.connect (on_generate_mirrors_list); + transaction.start_generating_mirrors_list.connect (on_start_generating_mirrors_list); transaction.generate_mirrors_list_finished.connect (on_generate_mirrors_list_finished); - transaction.run_preferences_dialog_finished.connect (on_run_preferences_dialog_finished); - transaction.get_updates_progress.connect (on_get_updates_progress); - transaction.get_updates_finished.connect (on_get_updates_finished); // integrate progress box and term widget main_stack.add_named (transaction.term_window, "term"); transaction_infobox.pack_start (transaction.progress_box); - Timeout.add (500, check_extern_lock); - display_package_queue = new Queue<string> (); + to_install = new GenericSet<string?> (str_hash, str_equal); + to_remove = new GenericSet<string?> (str_hash, str_equal); + to_load = new GenericSet<string?> (str_hash, str_equal); + to_build = new GenericSet<string?> (str_hash, str_equal); + to_update = new GenericSet<string?> (str_hash, str_equal); + temporary_ignorepkgs = new GenericSet<string?> (str_hash, str_equal); main_stack.notify["visible-child"].connect (on_main_stack_visible_child_changed); filters_stack.notify["visible-child"].connect (on_filters_stack_visible_child_changed); @@ -400,24 +415,6 @@ namespace Pamac { } } - bool check_extern_lock () { - if (extern_lock) { - if (!transaction.lockfile.query_exists ()) { - extern_lock = false; - transaction.refresh_handle (); - scroll_to_top = false; - refresh_packages_list (); - } - } else { - if (transaction.lockfile.query_exists ()) { - if (!transaction_running && !refreshing && !sysupgrade_running) { - extern_lock = true; - } - } - } - return true; - } - void on_write_pamac_config_finished (bool recurse, uint64 refresh_period, bool no_update_hide_icon, bool enable_aur) { support_aur (enable_aur); @@ -425,12 +422,11 @@ namespace Pamac { void on_set_pkgreason_finished () { transaction.unlock (); - transaction.refresh_handle (); scroll_to_top = false; refresh_packages_list (); if (main_stack.visible_child_name == "details") { - if (transaction.get_installed_pkg (current_package_displayed).name != "" - || transaction.get_sync_pkg (current_package_displayed).name != "") { + if (database.get_installed_pkg (current_package_displayed).name != "" + || database.get_sync_pkg (current_package_displayed).name != "") { display_package_properties (current_package_displayed); } else { display_aur_properties (current_package_displayed); @@ -495,7 +491,7 @@ namespace Pamac { string name; uint64 dsize; packages_list.get (iter, 1, out name, 5, out dsize); - if (transaction.to_update.contains (name)) { + if (to_update.contains (name)) { total_dsize += dsize; } return false; @@ -506,7 +502,7 @@ namespace Pamac { transaction.progress_box.action_label.label = ""; } if (!transaction_running && !generate_mirrors_list && !refreshing && !sysupgrade_running - && (transaction.to_update.length > 0)) { + && (to_update.length > 0)) { apply_button.sensitive = true; } else { apply_button.sensitive = false; @@ -514,7 +510,7 @@ namespace Pamac { cancel_button.sensitive = false; show_transaction_infobox (); } else { - uint total_pending = transaction.to_install.length + transaction.to_remove.length + transaction.to_build.length; + uint total_pending = to_install.length + to_remove.length + to_build.length; if (total_pending == 0) { if (filters_stack.visible_child_name != "pending") { active_pending_row (false); @@ -540,8 +536,8 @@ namespace Pamac { void show_default_pkgs () { this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); origin_stack.visible_child_name = "repos"; - transaction.get_installed_apps.begin ((obj, res) => { - populate_packages_list (transaction.get_installed_apps.end (res)); + database.get_installed_apps_async.begin ((obj, res) => { + populate_packages_list (database.get_installed_apps_async.end (res)); }); } @@ -584,13 +580,13 @@ namespace Pamac { active_pending_row (false); filters_listbox.select_row (filters_listbox.get_row_at_index (0)); - foreach (unowned string repo in transaction.get_repos_names ()) { + foreach (unowned string repo in database.get_repos_names ()) { label = create_list_label (repo); repos_listbox.add (label); } repos_listbox.select_row (repos_listbox.get_row_at_index (0)); - foreach (unowned string group in transaction.get_groups_names ()) { + foreach (unowned string group in database.get_groups_names ()) { label = create_list_label (group); groups_listbox.add (label); } @@ -658,7 +654,13 @@ namespace Pamac { files_row.add (label); properties_listbox.add (files_row); properties_listbox.select_row (properties_listbox.get_row_at_index (0)); + } + void clear_lists () { + to_install.remove_all (); + to_remove.remove_all (); + to_build.remove_all (); + to_load.remove_all (); } void on_mark_explicit_button_clicked (Gtk.Button button) { @@ -702,7 +704,7 @@ namespace Pamac { container.foreach ((widget) => { if (widget.name == "GtkButton") { var dep_button = widget as Gtk.Button; - AlpmPackage pkg = transaction.find_sync_satisfier (dep_button.label); + AlpmPackage pkg = database.find_sync_satisfier (dep_button.label); if (pkg.name != "") { dep_name = pkg.name; } @@ -715,10 +717,10 @@ namespace Pamac { string dep_name = find_install_button_dep_name (button); if (button.active) { button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); - transaction.to_install.add (dep_name); + to_install.add (dep_name); } else { button.get_style_context ().remove_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); - transaction.to_install.remove (dep_name); + to_install.remove (dep_name); } set_pendings_operations (); } @@ -740,13 +742,13 @@ namespace Pamac { dep_button.relief = Gtk.ReliefStyle.NONE; dep_button.clicked.connect (on_dep_button_clicked); box2.pack_start (dep_button, false); - if (transaction.find_installed_satisfier (dep).name == "") { + if (database.find_installed_satisfier (dep).name == "") { var install_dep_button = new Gtk.ToggleButton.with_label (dgettext (null, "Install")); install_dep_button.margin = 3; install_dep_button.toggled.connect (on_install_dep_button_toggled); box2.pack_end (install_dep_button, false); string dep_name = find_install_button_dep_name (install_dep_button); - install_dep_button.active = (dep_name in transaction.to_install); + install_dep_button.active = (dep_name in to_install); } box.pack_start (box2); } else { @@ -806,7 +808,7 @@ namespace Pamac { } void set_package_details (string pkgname, string app_name) { - AlpmPackageDetails details = transaction.get_pkg_details (pkgname, app_name); + AlpmPackageDetails details = database.get_pkg_details (pkgname, app_name); // download screenshot app_screenshot.pixbuf = null; if (details.screenshot != "") { @@ -865,17 +867,17 @@ namespace Pamac { if (details.origin == 2) { //Alpm.Package.From.LOCALDB install_togglebutton.visible = false; remove_togglebutton.visible = true; - remove_togglebutton.active = transaction.to_remove.contains (details.name); + remove_togglebutton.active = to_remove.contains (details.name); reinstall_togglebutton.visible = false; - AlpmPackage find_pkg = transaction.get_sync_pkg (details.name); + AlpmPackage find_pkg = database.get_sync_pkg (details.name); if (find_pkg.name != "") { if (find_pkg.version == details.version) { reinstall_togglebutton.visible = true; - reinstall_togglebutton.active = transaction.to_install.contains (details.name); + reinstall_togglebutton.active = to_install.contains (details.name); } } else { - transaction.get_aur_details.begin (details.name, (obj, res) => { - AURPackageDetails aur_details = transaction.get_aur_details.end (res); + database.get_aur_details_async.begin (details.name, (obj, res) => { + AURPackageDetails aur_details = database.get_aur_details_async.end (res); if (aur_details.name != "") { // always show reinstall button for VCS package if (aur_details.name.has_suffix ("-git") || @@ -884,7 +886,7 @@ namespace Pamac { aur_details.name.has_suffix ("-hg") || aur_details.version == details.version) { reinstall_togglebutton.visible = true; - reinstall_togglebutton.active = transaction.to_build.contains (details.name); + reinstall_togglebutton.active = to_build.contains (details.name); } } }); @@ -893,7 +895,7 @@ namespace Pamac { remove_togglebutton.visible = false; reinstall_togglebutton.visible = false; install_togglebutton.visible = true; - install_togglebutton.active = transaction.to_install.contains (details.name); + install_togglebutton.active = to_install.contains (details.name); } // details details_grid.foreach (destroy_widget); @@ -1016,8 +1018,8 @@ namespace Pamac { while (Gtk.events_pending ()) { Gtk.main_iteration (); } - transaction.get_aur_details.begin (pkgname, (obj, res) => { - AURPackageDetails details = transaction.get_aur_details.end (res); + database.get_aur_details_async.begin (pkgname, (obj, res) => { + AURPackageDetails details = database.get_aur_details_async.end (res); // infos name_label.set_markup ("<big><b>%s %s</b></big>".printf (details.name, details.version)); app_image.pixbuf = package_icon; @@ -1034,11 +1036,11 @@ namespace Pamac { } licenses_label.set_text (licenses.str); install_togglebutton.visible = true; - install_togglebutton.active = transaction.to_build.contains (details.name); - AlpmPackage pkg = transaction.get_installed_pkg (details.name); + install_togglebutton.active = to_build.contains (details.name); + AlpmPackage pkg = database.get_installed_pkg (details.name); if (pkg.name != "") { remove_togglebutton.visible = true; - remove_togglebutton.active = transaction.to_remove.contains (pkg.name); + remove_togglebutton.active = to_remove.contains (pkg.name); } // details properties_listbox.visible = true; @@ -1122,16 +1124,16 @@ namespace Pamac { void on_install_togglebutton_toggled () { if (install_togglebutton.active) { install_togglebutton.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); - if (transaction.get_pkg_origin (current_package_displayed) == 3) { //Alpm.Package.From.SYNCDB - transaction.to_install.add (current_package_displayed); + if (database.get_pkg_origin (current_package_displayed) == 3) { //Alpm.Package.From.SYNCDB + to_install.add (current_package_displayed); } else { - transaction.to_build.add (current_package_displayed); + to_build.add (current_package_displayed); } } else { install_togglebutton.get_style_context ().remove_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); - if (transaction.to_install.remove (current_package_displayed)) { + if (to_install.remove (current_package_displayed)) { } else { - transaction.to_build.remove (current_package_displayed); + to_build.remove (current_package_displayed); } } set_pendings_operations (); @@ -1143,11 +1145,11 @@ namespace Pamac { reinstall_togglebutton.active = false; reinstall_togglebutton.get_style_context ().remove_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); remove_togglebutton.get_style_context ().add_class (Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION); - transaction.to_install.remove (current_package_displayed); - transaction.to_remove.add (current_package_displayed); + to_install.remove (current_package_displayed); + to_remove.add (current_package_displayed); } else { remove_togglebutton.get_style_context ().remove_class (Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION); - transaction.to_remove.remove (current_package_displayed); + to_remove.remove (current_package_displayed); } set_pendings_operations (); } @@ -1158,18 +1160,18 @@ namespace Pamac { remove_togglebutton.active = false; remove_togglebutton.get_style_context ().remove_class (Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION); reinstall_togglebutton.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); - transaction.to_remove.remove (current_package_displayed); - AlpmPackage find_pkg = transaction.get_sync_pkg (current_package_displayed); + to_remove.remove (current_package_displayed); + AlpmPackage find_pkg = database.get_sync_pkg (current_package_displayed); if (find_pkg.name != "") { - transaction.to_install.add (current_package_displayed); + to_install.add (current_package_displayed); } else { // availability in AUR was checked in set_package_details - transaction.to_build.add (current_package_displayed); + to_build.add (current_package_displayed); } } else { reinstall_togglebutton.get_style_context ().remove_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); - transaction.to_install.remove (current_package_displayed); - transaction.to_build.remove (current_package_displayed); + to_install.remove (current_package_displayed); + to_build.remove (current_package_displayed); } set_pendings_operations (); } @@ -1319,7 +1321,7 @@ namespace Pamac { public void refresh_packages_list () { button_back.visible = (main_stack.visible_child_name != "browse" || filters_stack.visible_child_name != "filters"); if (filters_stack.visible_child_name != "pending") { - uint total_pending = transaction.to_install.length + transaction.to_remove.length + transaction.to_build.length; + uint total_pending = to_install.length + to_remove.length + to_build.length; if (total_pending == 0) { active_pending_row (false); } @@ -1406,7 +1408,7 @@ namespace Pamac { select_all_button.visible = false; apply_button.sensitive = false; this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - transaction.start_get_updates (); + database.start_get_updates (); break; case "pending": this.title = dgettext (null, "Pending"); @@ -1415,23 +1417,23 @@ namespace Pamac { save_packages_sort_order (); // order pending by name packages_list.set_sort_column_id (2, Gtk.SortType.ASCENDING); - if (transaction.to_build.length != 0) { + if (to_build.length != 0) { show_sidebar (); } else { hide_sidebar (); } AlpmPackage[] pkgs = {}; - foreach (unowned string pkgname in transaction.to_install) { - AlpmPackage pkg = transaction.get_installed_pkg (pkgname); + foreach (unowned string pkgname in to_install) { + AlpmPackage pkg = database.get_installed_pkg (pkgname); if (pkg.name == "") { - pkg = transaction.get_sync_pkg (pkgname); + pkg = database.get_sync_pkg (pkgname); } if (pkg.name != "") { pkgs += pkg; } } - foreach (unowned string pkgname in transaction.to_remove) { - AlpmPackage pkg = transaction.get_installed_pkg (pkgname); + foreach (unowned string pkgname in to_remove) { + AlpmPackage pkg = database.get_installed_pkg (pkgname); if (pkg.name != "") { pkgs += pkg; } @@ -1439,11 +1441,11 @@ namespace Pamac { if (pkgs.length > 0) { populate_packages_list (pkgs); } - if (transaction.to_build.length != 0) { + if (to_build.length != 0) { AURPackage[] aur_pkgs = {}; - foreach (unowned string pkgname in transaction.to_build) { - transaction.get_aur_details.begin (pkgname, (obj, res) => { - AURPackageDetails details_pkg = transaction.get_aur_details.end (res); + foreach (unowned string pkgname in to_build) { + database.get_aur_details_async.begin (pkgname, (obj, res) => { + AURPackageDetails details_pkg = database.get_aur_details_async.end (res); if (details_pkg.name != "") { var aur_pkg = AURPackage () { name = details_pkg.name, @@ -1510,36 +1512,36 @@ namespace Pamac { string depstring = button.label; // if depstring contains a version restriction search a satisfier directly if (">" in depstring || "=" in depstring || "<" in depstring) { - var pkg = transaction.find_installed_satisfier (depstring); + var pkg = database.find_installed_satisfier (depstring); if (pkg.name != "") { display_package_properties (pkg.name); } else { - pkg = transaction.find_sync_satisfier (depstring); + pkg = database.find_sync_satisfier (depstring); if (pkg.name != "") { display_package_properties (pkg.name); } } } else { // just search for the name first to search for AUR after - if (transaction.get_installed_pkg (depstring).name != "") { + if (database.get_installed_pkg (depstring).name != "") { display_package_properties (depstring); - } else if (transaction.get_sync_pkg (depstring).name != "") { + } else if (database.get_sync_pkg (depstring).name != "") { display_package_properties (depstring); } else { this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); while (Gtk.events_pending ()) { Gtk.main_iteration (); } - transaction.get_aur_details.begin (depstring, (obj, res) => { + database.get_aur_details_async.begin (depstring, (obj, res) => { this.get_window ().set_cursor (null); - if (transaction.get_aur_details.end (res).name != "") { + if (database.get_aur_details_async.end (res).name != "") { display_aur_properties (depstring); } else { - var pkg = transaction.find_installed_satisfier (depstring); + var pkg = database.find_installed_satisfier (depstring); if (pkg.name != "") { display_package_properties (pkg.name); } else { - pkg = transaction.find_sync_satisfier (depstring); + pkg = database.find_sync_satisfier (depstring); if (pkg.name != "") { display_package_properties (pkg.name); } @@ -1557,7 +1559,7 @@ namespace Pamac { while (Gtk.events_pending ()) { Gtk.main_iteration (); } - string[] files = transaction.get_pkg_files (current_package_displayed); + string[] files = database.get_pkg_files (current_package_displayed); StringBuilder text = new StringBuilder (); foreach (unowned string file in files) { if (text.len > 0) { @@ -1580,19 +1582,19 @@ namespace Pamac { string pkgname; packages_list.get (iter, 0, out origin, 1, out pkgname); if (!transaction.transaction_summary.contains (pkgname)) { - if (transaction.to_install.remove (pkgname)) { - } else if (transaction.to_remove.remove (pkgname)) { + if (to_install.remove (pkgname)) { + } else if (to_remove.remove (pkgname)) { } else { if (origin == 2) { //Alpm.Package.From.LOCALDB - if (!transaction.should_hold (pkgname)) { - transaction.to_remove.add (pkgname); + if (!database.should_hold (pkgname)) { + to_remove.add (pkgname); } - } else if (transaction.to_update.remove (pkgname)) { - transaction.temporary_ignorepkgs.add (pkgname); - } else if (transaction.temporary_ignorepkgs.remove (pkgname)) { - transaction.to_update.add (pkgname); + } else if (to_update.remove (pkgname)) { + temporary_ignorepkgs.add (pkgname); + } else if (temporary_ignorepkgs.remove (pkgname)) { + to_update.add (pkgname); } else { - transaction.to_install.add (pkgname); + to_install.add (pkgname); } } } @@ -1625,21 +1627,21 @@ namespace Pamac { string pkgname; aur_list.get (iter, 0, out origin, 1, out pkgname); if (filters_stack.visible_child_name == "updates") { - if (transaction.to_update.remove (pkgname)) { - transaction.temporary_ignorepkgs.add (pkgname); - } else if (transaction.temporary_ignorepkgs.remove (pkgname)) { - transaction.to_update.add (pkgname); + if (to_update.remove (pkgname)) { + temporary_ignorepkgs.add (pkgname); + } else if (temporary_ignorepkgs.remove (pkgname)) { + to_update.add (pkgname); } } else if (origin == 2) { //Alpm.Package.From.LOCALDB if (!transaction.transaction_summary.contains (pkgname)) { - if (transaction.to_remove.remove (pkgname)) { - } else if (!transaction.should_hold (pkgname)) { - transaction.to_remove.add (pkgname); + if (to_remove.remove (pkgname)) { + } else if (!database.should_hold (pkgname)) { + to_remove.add (pkgname); } } - } else if (transaction.to_build.remove (pkgname)) { + } else if (to_build.remove (pkgname)) { } else { - transaction.to_build.add (pkgname); + to_build.add (pkgname); } set_pendings_operations (); } @@ -1653,18 +1655,18 @@ namespace Pamac { case "details": string? pkgname = display_package_queue.pop_tail (); if (pkgname != null) { - AlpmPackage pkg = transaction.get_installed_pkg (pkgname); + AlpmPackage pkg = database.get_installed_pkg (pkgname); if (pkg.name == "") { - pkg = transaction.get_sync_pkg (pkgname); + pkg = database.get_sync_pkg (pkgname); } if (pkg.name == "") { - transaction.get_aur_details.begin (pkgname, (obj, res) => { - if (transaction.get_aur_details.end (res).name != "") { + database.get_aur_details_async.begin (pkgname, (obj, res) => { + if (database.get_aur_details_async.end (res).name != "") { display_aur_properties (pkgname); } else { - pkg = transaction.find_installed_satisfier (pkgname); + pkg = database.find_installed_satisfier (pkgname); if (pkg.name == "") { - pkg = transaction.find_sync_satisfier (pkgname); + pkg = database.find_sync_satisfier (pkgname); } if (pkg.name != "") { display_package_properties (pkgname); @@ -1688,12 +1690,12 @@ namespace Pamac { void on_install_item_activate () { foreach (unowned string pkgname in selected_pkgs) { - if (transaction.get_pkg_origin (pkgname) == 3) { //Alpm.Package.From.SYNCDB - transaction.to_install.add (pkgname); + if (database.get_pkg_origin (pkgname) == 3) { //Alpm.Package.From.SYNCDB + to_install.add (pkgname); } } foreach (unowned string pkgname in selected_aur) { - transaction.to_build.add (pkgname); + to_build.add (pkgname); } set_pendings_operations (); } @@ -1711,10 +1713,10 @@ namespace Pamac { void on_remove_item_activate () { foreach (unowned string pkgname in selected_pkgs) { - transaction.to_install.remove (pkgname); - if (!transaction.should_hold (pkgname)) { - if (transaction.get_pkg_origin (pkgname) == 2) { //Alpm.Package.From.LOCALDB - transaction.to_remove.add (pkgname); + to_install.remove (pkgname); + if (!database.should_hold (pkgname)) { + if (database.get_pkg_origin (pkgname) == 2) { //Alpm.Package.From.LOCALDB + to_remove.add (pkgname); } } } @@ -1723,18 +1725,18 @@ namespace Pamac { void on_deselect_item_activate () { foreach (unowned string pkgname in selected_pkgs) { - if (transaction.to_install.remove (pkgname)) { - } else if (transaction.to_update.remove (pkgname)) { - transaction.temporary_ignorepkgs.add (pkgname); + if (to_install.remove (pkgname)) { + } else if (to_update.remove (pkgname)) { + temporary_ignorepkgs.add (pkgname); } else { - transaction.to_remove.remove (pkgname); + to_remove.remove (pkgname); } } foreach (unowned string pkgname in selected_aur) { - if (transaction.to_build.remove (pkgname)) { + if (to_build.remove (pkgname)) { } else { - transaction.to_update.remove (pkgname); - transaction.temporary_ignorepkgs.add (pkgname); + to_update.remove (pkgname); + temporary_ignorepkgs.add (pkgname); } } set_pendings_operations (); @@ -1742,12 +1744,12 @@ namespace Pamac { void on_upgrade_item_activate () { foreach (unowned string pkgname in selected_pkgs) { - transaction.temporary_ignorepkgs.remove (pkgname); - transaction.to_update.add (pkgname); + temporary_ignorepkgs.remove (pkgname); + to_update.add (pkgname); } foreach (unowned string pkgname in selected_aur) { - transaction.temporary_ignorepkgs.remove (pkgname); - transaction.to_update.add (pkgname); + temporary_ignorepkgs.remove (pkgname); + to_update.add (pkgname); } set_pendings_operations (); } @@ -1811,7 +1813,7 @@ namespace Pamac { int index = row.get_index (); switch (index) { case 0: // repos - if ((transaction.to_install.length + transaction.to_remove.length) > 0) { + if ((to_install.length + to_remove.length) > 0) { origin_stack.visible_child_name = "repos"; } else { origin_stack.visible_child_name = "no_item"; @@ -1843,8 +1845,8 @@ namespace Pamac { while (Gtk.events_pending ()) { Gtk.main_iteration (); } - transaction.search_pkgs.begin (search_string, (obj, res) => { - populate_packages_list (transaction.search_pkgs.end (res)); + database.search_pkgs_async.begin (search_string, (obj, res) => { + populate_packages_list (database.search_pkgs_async.end (res)); }); break; case 1: // aur @@ -1862,8 +1864,8 @@ namespace Pamac { while (Gtk.events_pending ()) { Gtk.main_iteration (); } - transaction.search_in_aur.begin (search_string, (obj, res) => { - populate_aur_list (transaction.search_in_aur.end (res)); + database.search_in_aur_async.begin (search_string, (obj, res) => { + populate_aur_list (database.search_in_aur_async.end (res)); }); break; default: @@ -1909,11 +1911,11 @@ namespace Pamac { packages_list.get (iter, 0, out origin, 1, out pkgname, 3, out pkgversion); selected_pkgs.append (pkgname); details_item.sensitive = true; - if (transaction.to_install.contains (pkgname) - || transaction.to_remove.contains (pkgname) - || transaction.to_update.contains (pkgname)) { + if (to_install.contains (pkgname) + || to_remove.contains (pkgname) + || to_update.contains (pkgname)) { deselect_item.sensitive = true; - } else if (transaction.temporary_ignorepkgs.contains (pkgname)) { + } else if (temporary_ignorepkgs.contains (pkgname)) { upgrade_item.sensitive = true; } else if (origin == 2) { //Alpm.Package.From.LOCALDB remove_item.sensitive = true; @@ -1930,14 +1932,14 @@ namespace Pamac { packages_list.get (iter, 0, out origin, 1, out pkgname); selected_pkgs.append (pkgname); if (!deselect_item.sensitive) { - if (transaction.to_install.contains (pkgname) - || transaction.to_remove.contains (pkgname) - || transaction.to_update.contains (pkgname)) { + if (to_install.contains (pkgname) + || to_remove.contains (pkgname) + || to_update.contains (pkgname)) { deselect_item.sensitive = true; } } if (origin == 3) { //Alpm.Package.From.SYNCDB - if (transaction.temporary_ignorepkgs.contains (pkgname)) { + if (temporary_ignorepkgs.contains (pkgname)) { upgrade_item.sensitive = true; } else { install_item.sensitive = true; @@ -1998,7 +2000,7 @@ namespace Pamac { aur_list.get_iter (out iter, path); string pkgname; aur_list.get (iter, 1, out pkgname); - AlpmPackage pkg = transaction.get_installed_pkg (pkgname); + AlpmPackage pkg = database.get_installed_pkg (pkgname); if (pkg.name != "") { selected_pkgs.append (pkgname); // there is for sure a pkg to remove @@ -2008,17 +2010,17 @@ namespace Pamac { } } foreach (unowned string pkgname in selected_aur) { - if (transaction.to_build.contains (pkgname)) { + if (to_build.contains (pkgname)) { deselect_item.sensitive = true; } else { install_item.sensitive = true; } } foreach (unowned string pkgname in selected_pkgs) { - if (transaction.to_remove.contains (pkgname) - || transaction.to_update.contains (pkgname)) { + if (to_remove.contains (pkgname) + || to_update.contains (pkgname)) { deselect_item.sensitive = true; - } else if (transaction.temporary_ignorepkgs.contains (pkgname)) { + } else if (temporary_ignorepkgs.contains (pkgname)) { upgrade_item.sensitive = true; } } @@ -2116,17 +2118,17 @@ namespace Pamac { }); switch (origin_stack.visible_child_name) { case "repos": - transaction.search_pkgs.begin (search_string, (obj, res) => { - if (transaction.enable_aur) { + database.search_pkgs_async.begin (search_string, (obj, res) => { + if (database.config.enable_aur) { show_sidebar (); } else { hide_sidebar (); } - var pkgs = transaction.search_pkgs.end (res); - if (pkgs.length == 0 && transaction.enable_aur) { + var pkgs = database.search_pkgs_async.end (res); + if (pkgs.length == 0 && database.config.enable_aur) { packages_list.clear (); - transaction.search_in_aur.begin (search_string, (obj, res) => { - if (transaction.search_in_aur.end (res).length > 0) { + database.search_in_aur_async.begin (search_string, (obj, res) => { + if (database.search_in_aur_async.end (res).length > 0) { origin_stack.visible_child_name = "aur"; } else { populate_packages_list (pkgs); @@ -2139,14 +2141,14 @@ namespace Pamac { aur_list.clear (); break; case "aur": - transaction.search_in_aur.begin (search_string, (obj, res) => { - populate_aur_list (transaction.search_in_aur.end (res)); + database.search_in_aur_async.begin (search_string, (obj, res) => { + populate_aur_list (database.search_in_aur_async.end (res)); }); packages_list.clear (); break; case "updated": // select repos - if (transaction.enable_aur) { + if (database.config.enable_aur) { show_sidebar (); } else { hide_sidebar (); @@ -2155,7 +2157,7 @@ namespace Pamac { break; case "no_item": // select repos - if (transaction.enable_aur) { + if (database.config.enable_aur) { show_sidebar (); } else { hide_sidebar (); @@ -2233,8 +2235,8 @@ namespace Pamac { } else if (category == dgettext (null, "System Tools")) { matching_cat = "System"; } - transaction.get_category_pkgs.begin (matching_cat, (obj, res) => { - populate_packages_list (transaction.get_category_pkgs.end (res)); + database.get_category_pkgs_async.begin (matching_cat, (obj, res) => { + populate_packages_list (database.get_category_pkgs_async.end (res)); }); } @@ -2245,8 +2247,8 @@ namespace Pamac { var label = row.get_child () as Gtk.Label; string group_name = label.label; this.title = group_name; - transaction.get_group_pkgs.begin (group_name, (obj, res) => { - populate_packages_list (transaction.get_group_pkgs.end (res)); + database.get_group_pkgs_async.begin (group_name, (obj, res) => { + populate_packages_list (database.get_group_pkgs_async.end (res)); }); } @@ -2259,23 +2261,23 @@ namespace Pamac { int index = row.get_index (); switch (index) { case 0: // Installed - transaction.get_installed_pkgs.begin ((obj, res) => { - populate_packages_list (transaction.get_installed_pkgs.end (res)); + database.get_installed_pkgs_async.begin ((obj, res) => { + populate_packages_list (database.get_installed_pkgs_async.end (res)); }); break; case 1: // Explicitly installed - transaction.get_explicitly_installed_pkgs.begin ((obj, res) => { - populate_packages_list (transaction.get_explicitly_installed_pkgs.end (res)); + database.get_explicitly_installed_pkgs_async.begin ((obj, res) => { + populate_packages_list (database.get_explicitly_installed_pkgs_async.end (res)); }); break; case 2: // Orphans - transaction.get_orphans.begin ((obj, res) => { - populate_packages_list (transaction.get_orphans.end (res)); + database.get_orphans_async.begin ((obj, res) => { + populate_packages_list (database.get_orphans_async.end (res)); }); break; case 3: // Foreign - transaction.get_foreign_pkgs.begin ((obj, res) => { - populate_packages_list (transaction.get_foreign_pkgs.end (res)); + database.get_foreign_pkgs_async.begin ((obj, res) => { + populate_packages_list (database.get_foreign_pkgs_async.end (res)); }); break; default: @@ -2290,8 +2292,8 @@ namespace Pamac { var label = row.get_child () as Gtk.Label; string repo = label.label; this.title = repo; - transaction.get_repo_pkgs.begin (repo, (obj, res) => { - populate_packages_list (transaction.get_repo_pkgs.end (res)); + database.get_repo_pkgs_async.begin (repo, (obj, res) => { + populate_packages_list (database.get_repo_pkgs_async.end (res)); }); } @@ -2400,7 +2402,7 @@ namespace Pamac { SList<string> packages_paths = chooser.get_filenames (); if (packages_paths.length () != 0) { foreach (unowned string path in packages_paths) { - transaction.to_load.add (path); + to_load.add (path); } chooser.destroy (); try_lock_and_run (run_transaction); @@ -2417,18 +2419,33 @@ namespace Pamac { void on_preferences_button_clicked () { if (transaction.get_lock ()) { this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); - transaction.run_preferences_dialog (); + run_preferences_dialog (); } else { transaction.display_error (dgettext (null, "Waiting for another package manager to quit"), {}); } } + public void run_preferences_dialog () { + transaction.check_authorization.begin ((obj, res) => { + bool authorized = transaction.check_authorization.end (res); + if (authorized) { + var preferences_dialog = new PreferencesDialog (transaction); + preferences_dialog.run (); + preferences_dialog.destroy (); + while (Gtk.events_pending ()) { + Gtk.main_iteration (); + } + } + on_run_preferences_dialog_finished (); + }); + } + void on_run_preferences_dialog_finished () { transaction.unlock (); if (filters_stack.visible_child_name == "updates") { origin_stack.visible_child_name = "checking"; checking_spinner.active = true; - transaction.start_get_updates (); + database.start_get_updates (); } else { this.get_window ().set_cursor (null); } @@ -2456,7 +2473,7 @@ namespace Pamac { if (transaction_running || sysupgrade_running) { main_stack.visible_child_name = "term"; } else { - uint total_pending = transaction.to_install.length + transaction.to_remove.length + transaction.to_build.length; + uint total_pending = to_install.length + to_remove.length + to_build.length; if (total_pending == 0) { main_stack.visible_child_name = "term"; } @@ -2468,6 +2485,7 @@ namespace Pamac { if (filters_stack.visible_child_name == "updates") { force_refresh = false; refreshing = true; + sysupgrade_running = true; try_lock_and_run (run_refresh); } else { try_lock_and_run (run_transaction); @@ -2489,7 +2507,23 @@ namespace Pamac { apply_button.sensitive = false; cancel_button.sensitive = false; show_transaction_infobox (); - transaction.run (); + string[] to_install_ = {}; + string[] to_remove_ = {}; + string[] to_load_ = {}; + string[] to_build_ = {}; + foreach (unowned string name in to_install) { + to_install_ += name; + } + foreach (unowned string name in to_remove) { + to_remove_ += name; + } + foreach (unowned string path in to_load) { + to_load_ += path; + } + foreach (unowned string name in to_build) { + to_build_ += name; + } + transaction.start (to_install_, to_remove_, to_load_, to_build_, {}); // let time to update packages states Timeout.add (500, () => { refresh_state_icons (); @@ -2501,7 +2535,11 @@ namespace Pamac { sysupgrade_running = true; apply_button.sensitive = false; cancel_button.sensitive = false; - transaction.sysupgrade (false); + string[] temp_ign_pkgs = {}; + foreach (unowned string name in temporary_ignorepkgs) { + temp_ign_pkgs += name; + } + transaction.start_sysupgrade (false, temp_ign_pkgs, {}); // let time to update packages states Timeout.add (500, () => { refresh_state_icons (); @@ -2514,7 +2552,7 @@ namespace Pamac { if (waiting) { waiting = false; transaction.stop_progressbar_pulse (); - transaction.to_load.remove_all (); + to_load.remove_all (); transaction.unlock (); set_pendings_operations (); } else if (transaction_running) { @@ -2526,15 +2564,15 @@ namespace Pamac { } else if (sysupgrade_running) { sysupgrade_running = false; transaction.cancel (); - transaction.to_build.remove_all (); + to_build.remove_all (); } else { - transaction.clear_lists (); + clear_lists (); set_pendings_operations (); scroll_to_top = false; refresh_packages_list (); if (main_stack.visible_child_name == "details") { - if (transaction.get_installed_pkg (current_package_displayed).name != "" - || transaction.get_sync_pkg (current_package_displayed).name != "") { + if (database.get_installed_pkg (current_package_displayed).name != "" + || database.get_sync_pkg (current_package_displayed).name != "") { display_package_properties (current_package_displayed); } else { display_aur_properties (current_package_displayed); @@ -2549,6 +2587,7 @@ namespace Pamac { [GtkCallback] void on_refresh_button_clicked () { force_refresh = true; + refreshing = true; try_lock_and_run (run_refresh); } @@ -2577,7 +2616,7 @@ namespace Pamac { } void populate_updates () { - transaction.to_update.remove_all (); + to_update.remove_all (); if ((repos_updates.length + aur_updates.length) == 0) { if (!refreshing && !transaction_running && !sysupgrade_running) { hide_transaction_infobox (); @@ -2587,15 +2626,15 @@ namespace Pamac { } else { if (repos_updates.length > 0) { foreach (unowned AlpmPackage pkg in repos_updates) { - if (!transaction.temporary_ignorepkgs.contains (pkg.name)) { - transaction.to_update.add (pkg.name); + if (!temporary_ignorepkgs.contains (pkg.name)) { + to_update.add (pkg.name); } } } if (aur_updates.length > 0) { foreach (unowned AURPackage pkg in aur_updates) { - if (!transaction.temporary_ignorepkgs.contains (pkg.name)) { - transaction.to_update.add (pkg.name); + if (!temporary_ignorepkgs.contains (pkg.name)) { + to_update.add (pkg.name); } } show_sidebar (); @@ -2638,7 +2677,7 @@ namespace Pamac { } } - void on_generate_mirrors_list () { + void on_start_generating_mirrors_list () { generate_mirrors_list = true; apply_button.sensitive = false; show_transaction_infobox (); @@ -2648,11 +2687,35 @@ namespace Pamac { generate_mirrors_list = false; } + void on_refresh_finished (bool success) { + refreshing = false; + if (sysupgrade_running) { + run_sysupgrade (); + } else { + database.refresh (); + scroll_to_top = false; + refresh_packages_list (); + if (main_stack.visible_child_name == "details") { + if (database.get_installed_pkg (current_package_displayed).name != "" + || database.get_sync_pkg (current_package_displayed).name != "") { + display_package_properties (current_package_displayed); + } else { + display_aur_properties (current_package_displayed); + } + } else if (main_stack.visible_child_name == "term") { + button_back.visible = true; + } + } + } + void on_transaction_finished (bool success) { - transaction.refresh_handle (); + transaction.unlock (); + database.refresh (); + scroll_to_top = false; + refresh_packages_list (); if (main_stack.visible_child_name == "details") { - if (transaction.get_installed_pkg (current_package_displayed).name != "" - || transaction.get_sync_pkg (current_package_displayed).name != "") { + if (database.get_installed_pkg (current_package_displayed).name != "" + || database.get_sync_pkg (current_package_displayed).name != "") { display_package_properties (current_package_displayed); } else { display_aur_properties (current_package_displayed); @@ -2660,22 +2723,15 @@ namespace Pamac { } else if (main_stack.visible_child_name == "term") { button_back.visible = true; } - transaction.to_load.remove_all (); - if (refreshing) { - refreshing = false; - run_sysupgrade (); - } else if (sysupgrade_running) { + if (sysupgrade_running) { sysupgrade_running = false; - transaction.to_build.remove_all (); - transaction.unlock (); - scroll_to_top = false; - refresh_packages_list (); + to_build.remove_all (); } else { transaction_running = false; generate_mirrors_list = false; - transaction.unlock (); - scroll_to_top = false; - refresh_packages_list (); + } + if (success) { + clear_lists (); } set_pendings_operations (); } diff --git a/src/meson.build b/src/meson.build index 0fe02463..bc174612 100644 --- a/src/meson.build +++ b/src/meson.build @@ -31,16 +31,9 @@ common_vala_args = ['--pkg=posix', '--target-glib=2.38'] common_c_args = ['-DGETTEXT_PACKAGE="pamac"'] common_sources = ['common.vala', 'package.vala', 'pamac_config.vala'] -transaction_sources = ['transaction.vala', 'choose_provider_dialog.vala', 'transaction_sum_dialog.vala', 'progress_box.vala'] +transaction_gtk_sources = ['transaction-gtk.vala', 'choose_provider_dialog.vala', 'transaction_sum_dialog.vala', 'progress_box.vala'] preferences_sources = ['preferences_dialog.vala', 'choose_ignorepkgs_dialog.vala'] -executable('pamac', - sources: [common_sources, 'version.vala','cli.vala'], - dependencies: [gio, posix, math], - vala_args: [common_vala_args, '--pkg=linux'], - c_args: common_c_args, - install: true) - executable('pamac-clean-cache', sources: ['pamac_config.vala', 'clean_cache.vala'], dependencies: [gio], @@ -72,25 +65,51 @@ executable('pamac-user-daemon', install : true) executable('pamac-system-daemon', - sources: [common_sources, 'alpm_config.vala', 'aur.vala', 'system_daemon.vala'], + sources: ['common_daemon.vala', 'package.vala', 'pamac_config.vala', 'alpm_config.vala', 'aur.vala', 'system_daemon.vala'], dependencies: [vala_deps, alpm_deps, json, libsoup, polkit, libcurl, appstream], vala_args: [common_vala_args, alpm_vala_args, '--thread'], c_args: [common_c_args, alpm_c_args], install : true) libpamac = library('pamac', - sources: [common_sources, transaction_sources, preferences_sources, transaction_resources], - dependencies: [gtk3, gdk3, vte3, libnotify, posix, math], + sources: [common_sources, 'updates_priv.vala', 'database.vala', 'transaction.vala', 'transaction-cli.vala'], + dependencies: [gio, posix, math], + vala_args: [common_vala_args, '--pkg=linux'], + c_args: common_c_args, + vala_gir: 'Pamac-1.0.gir', + install: true, + install_dir: [true, true, true, true]) + +libpamac_dep = declare_dependency(link_with: libpamac) + +executable('pamac', + sources: ['version.vala','cli.vala'], + dependencies: [gio, posix, math, libpamac_dep], + vala_args: common_vala_args, + c_args: common_c_args, + install: true) + +libpamac_gtk = library('pamac-gtk', + sources: [transaction_gtk_sources, transaction_resources], + dependencies: [gio, gtk3, vte3, libnotify, posix, math, libpamac_dep], vala_args: common_vala_args, c_args: common_c_args, install: true, install_dir: [true, true, true]) -libpamac_dep = declare_dependency(link_with: libpamac) +# create typelib files +g_ir_compiler = find_program('g-ir-compiler') +custom_target('pamac typelib', command: [g_ir_compiler, '--shared-library', 'libpamac', '--output', '@OUTPUT@', join_paths(meson.current_build_dir(), 'Pamac-1.0.gir')], + output: 'Pamac-1.0.typelib', + depends: libpamac, + install: true, + install_dir: join_paths(get_option('libdir'), 'girepository-1.0')) + +libpamac_gtk_dep = declare_dependency(link_with: libpamac_gtk) executable('pamac-manager', - sources: ['version.vala', 'history_dialog.vala', 'manager_window.vala', 'manager.vala', manager_resources], - dependencies: [vala_deps, gtk3, gdk3, gdk_pixbuf2, libsoup, libpamac_dep], + sources: ['version.vala', 'history_dialog.vala', preferences_sources, 'manager_window.vala', 'manager.vala', manager_resources], + dependencies: [gtk3, libsoup, libpamac_dep, libpamac_gtk_dep], vala_args: common_vala_args, c_args: common_c_args, install: true) @@ -98,10 +117,10 @@ executable('pamac-manager', # create pamac-updater symlink meson.add_install_script('sh', '-c', 'ln -sf pamac-manager ${DESTDIR}/${MESON_INSTALL_PREFIX}/@0@/pamac-updater'.format(get_option('bindir'))) - + executable('pamac-installer', sources: ['progress_dialog.vala', 'installer.vala', installer_resources], - dependencies: [gtk3, libpamac_dep], + dependencies: [gtk3, libpamac_dep, libpamac_gtk_dep], vala_args: common_vala_args, c_args: common_c_args, install: true) diff --git a/src/pamac_config.vala b/src/pamac_config.vala index 00d5048a..10668eb8 100644 --- a/src/pamac_config.vala +++ b/src/pamac_config.vala @@ -18,27 +18,30 @@ */ namespace Pamac { - public class Config { - string conf_path; + public class Config: Object { HashTable<string,string> _environment_variables; - public bool recurse { get; private set; } - public uint64 refresh_period { get; private set; } - public bool no_update_hide_icon { get; private set; } - public bool enable_aur { get; private set; } - public string aur_build_dir { get; private set; } - public bool check_aur_updates { get; private set; } - public bool download_updates { get; private set; } - public uint64 keep_num_pkgs { get; private set; } - public bool rm_only_uninstalled { get; private set; } + public string conf_path { get; construct; } + public bool recurse { get; set; } + public uint64 refresh_period { get; set; } + public bool no_update_hide_icon { get; set; } + public bool enable_aur { get; set; } + public string aur_build_dir { get; set; } + public bool check_aur_updates { get; set; } + public bool download_updates { get; set; } + public uint64 clean_keep_num_pkgs { get; set; } + public bool clean_rm_only_uninstalled { get; set; } public unowned HashTable<string,string> environment_variables { get { return _environment_variables; } } - public Config (string path) { - conf_path = path; + public Config (string conf_path) { + Object(conf_path: conf_path); + } + + construct { //get environment variables _environment_variables = new HashTable<string,string> (str_hash, str_equal); var utsname = Posix.utsname(); @@ -76,8 +79,8 @@ namespace Pamac { aur_build_dir = "/tmp"; check_aur_updates = false; download_updates = false; - keep_num_pkgs = 3; - rm_only_uninstalled = false; + clean_keep_num_pkgs = 3; + clean_rm_only_uninstalled = false; parse_file (conf_path); } @@ -112,10 +115,10 @@ namespace Pamac { } else if (key == "KeepNumPackages") { if (splitted.length == 2) { unowned string val = splitted[1]._strip (); - keep_num_pkgs = uint64.parse (val); + clean_keep_num_pkgs = uint64.parse (val); } } else if (key == "OnlyRmUninstalled") { - rm_only_uninstalled = true; + clean_rm_only_uninstalled = true; } else if (key == "NoUpdateHideIcon") { no_update_hide_icon = true; } else if (key == "EnableAUR") { diff --git a/src/preferences_dialog.vala b/src/preferences_dialog.vala index cea978fb..b400c52c 100644 --- a/src/preferences_dialog.vala +++ b/src/preferences_dialog.vala @@ -62,11 +62,11 @@ namespace Pamac { Gtk.CheckButton cache_only_uninstalled_checkbutton; Gtk.ListStore ignorepkgs_liststore; - Transaction transaction; + TransactionGtk transaction; uint64 previous_refresh_period; string preferences_choosen_country; - public PreferencesDialog (Transaction transaction) { + public PreferencesDialog (TransactionGtk transaction) { int use_header_bar; Gtk.Settings.get_default ().get ("gtk-dialogs-use-header", out use_header_bar); Object (transient_for: transaction.application_window, use_header_bar: use_header_bar); @@ -75,9 +75,9 @@ namespace Pamac { refresh_period_label.set_markup (dgettext (null, "How often to check for updates, value in hours") +":"); cache_keep_nb_label.set_markup (dgettext (null, "Number of versions of each package to keep in the cache") +":"); aur_build_dir_label.set_markup (dgettext (null, "Build directory") +":"); - remove_unrequired_deps_button.active = transaction.recurse; - check_space_button.active = transaction.get_checkspace (); - if (transaction.refresh_period == 0) { + remove_unrequired_deps_button.active = transaction.database.config.recurse; + check_space_button.active = transaction.database.get_checkspace (); + if (transaction.database.config.refresh_period == 0) { check_updates_button.active = false; refresh_period_label.sensitive = false; // set default value @@ -89,18 +89,18 @@ namespace Pamac { ignorepkgs_box.sensitive = false; } else { check_updates_button.active = true; - refresh_period_spin_button.value = transaction.refresh_period; - previous_refresh_period = transaction.refresh_period; + refresh_period_spin_button.value = transaction.database.config.refresh_period; + previous_refresh_period = transaction.database.config.refresh_period; } - no_update_hide_icon_checkbutton.active = transaction.no_update_hide_icon; - download_updates_checkbutton.active = transaction.download_updates; - cache_keep_nb_spin_button.value = transaction.keep_num_pkgs; - cache_only_uninstalled_checkbutton.active = transaction.rm_only_uninstalled; + no_update_hide_icon_checkbutton.active = transaction.database.config.no_update_hide_icon; + download_updates_checkbutton.active = transaction.database.config.download_updates; + cache_keep_nb_spin_button.value = transaction.database.config.clean_keep_num_pkgs; + cache_only_uninstalled_checkbutton.active = transaction.database.config.clean_rm_only_uninstalled; // populate ignorepkgs_liststore ignorepkgs_liststore = new Gtk.ListStore (1, typeof (string)); ignorepkgs_treeview.set_model (ignorepkgs_liststore); - foreach (unowned string ignorepkg in transaction.get_ignorepkgs ()) { + foreach (unowned string ignorepkg in transaction.database.get_ignorepkgs ()) { ignorepkgs_liststore.insert_with_values (null, -1, 0, ignorepkg); } remove_unrequired_deps_button.state_set.connect (on_remove_unrequired_deps_button_state_set); @@ -114,17 +114,17 @@ namespace Pamac { cache_only_uninstalled_checkbutton.toggled.connect (on_cache_only_uninstalled_checkbutton_toggled); transaction.write_pamac_config_finished.connect (on_write_pamac_config_finished); - AlpmPackage pkg = transaction.find_installed_satisfier ("pacman-mirrors"); + AlpmPackage pkg = transaction.database.find_installed_satisfier ("pacman-mirrors"); if (pkg.name == "") { mirrors_config_box.visible = false; } else { mirrors_country_comboboxtext.append_text (dgettext (null, "Worldwide")); mirrors_country_comboboxtext.active = 0; if (transaction.preferences_available_countries.length == 0) { - transaction.preferences_available_countries = transaction.get_mirrors_countries (); + transaction.preferences_available_countries = transaction.database.get_mirrors_countries (); } int index = 1; - preferences_choosen_country = transaction.get_mirrors_choosen_country (); + preferences_choosen_country = transaction.database.get_mirrors_choosen_country (); foreach (unowned string country in transaction.preferences_available_countries) { mirrors_country_comboboxtext.append_text (country); if (country == preferences_choosen_country) { @@ -135,18 +135,18 @@ namespace Pamac { mirrors_country_comboboxtext.changed.connect (on_mirrors_country_comboboxtext_changed); } - enable_aur_button.active = transaction.enable_aur; - aur_build_dir_label.sensitive = transaction.enable_aur; - aur_build_dir_file_chooser.sensitive = transaction.enable_aur; - aur_build_dir_file_chooser.set_filename (transaction.aur_build_dir); + enable_aur_button.active = transaction.database.config.enable_aur; + aur_build_dir_label.sensitive = transaction.database.config.enable_aur; + aur_build_dir_file_chooser.sensitive = transaction.database.config.enable_aur; + aur_build_dir_file_chooser.set_filename (transaction.database.config.aur_build_dir); // add /tmp choice always visible try { aur_build_dir_file_chooser.add_shortcut_folder ("/tmp"); } catch (GLib.Error e) { stderr.printf ("%s\n", e.message); } - check_aur_updates_checkbutton.active = transaction.check_aur_updates; - check_aur_updates_checkbutton.sensitive = transaction.enable_aur; + check_aur_updates_checkbutton.active = transaction.database.config.check_aur_updates; + check_aur_updates_checkbutton.sensitive = transaction.database.config.enable_aur; enable_aur_button.state_set.connect (on_enable_aur_button_state_set); aur_build_dir_file_chooser.file_set.connect (on_aur_build_dir_set); check_aur_updates_checkbutton.toggled.connect (on_check_aur_updates_checkbutton_toggled); @@ -268,10 +268,10 @@ namespace Pamac { while (Gtk.events_pending ()) { Gtk.main_iteration (); } - transaction.get_installed_pkgs.begin ((obj, res) => { - var pkgs = transaction.get_installed_pkgs.end (res); + transaction.database.get_installed_pkgs_async.begin ((obj, res) => { + var pkgs = transaction.database.get_installed_pkgs_async.end (res); // make a copy of ignorepkgs to store uninstalled ones - string[] ignorepkgs = transaction.get_ignorepkgs (); + string[] ignorepkgs = transaction.database.get_ignorepkgs (); var ignorepkgs_set = new GenericSet<string?> (str_hash, str_equal); foreach (unowned string ignorepkg in ignorepkgs) { ignorepkgs_set.add (ignorepkg); @@ -342,7 +342,7 @@ namespace Pamac { void on_write_alpm_config_finished (bool checkspace) { check_space_button.state = checkspace; ignorepkgs_liststore.clear (); - foreach (unowned string ignorepkg in transaction.get_ignorepkgs ()) { + foreach (unowned string ignorepkg in transaction.database.get_ignorepkgs ()) { ignorepkgs_liststore.insert_with_values (null, -1, 0, ignorepkg); } } @@ -363,7 +363,7 @@ namespace Pamac { [GtkCallback] void on_cache_clean_button_clicked () { - transaction.clean_cache (transaction.keep_num_pkgs, transaction.rm_only_uninstalled); + transaction.clean_cache (transaction.database.config.clean_keep_num_pkgs, transaction.database.config.clean_rm_only_uninstalled); } } } diff --git a/src/system_daemon.vala b/src/system_daemon.vala index f13363d5..040177d2 100644 --- a/src/system_daemon.vala +++ b/src/system_daemon.vala @@ -86,7 +86,7 @@ namespace Pamac { public signal void emit_log (uint level, string msg); public signal void set_pkgreason_finished (); public signal void refresh_finished (bool success); - public signal void get_updates_finished (Updates updates); + public signal void get_updates_finished (UpdatesPriv updates); public signal void download_updates_finished (); public signal void trans_prepare_finished (bool success); public signal void trans_commit_finished (bool success); @@ -107,6 +107,7 @@ namespace Pamac { aurdb_path = "/tmp/pamac-aur"; aur_updates_results = new Json.Array (); timer = new Timer (); + current_error = ErrorInfos (); lock_id = new BusName (""); refresh_handle (); check_old_lock (); @@ -306,7 +307,7 @@ namespace Pamac { public void start_write_pamac_config (HashTable<string,Variant> new_pamac_conf, GLib.BusName sender) throws Error { check_authorization.begin (sender, (obj, res) => { - var pamac_config = new Pamac.Config ("/etc/pamac.conf"); + var pamac_config = new Config ("/etc/pamac.conf"); bool authorized = check_authorization.end (res); if (authorized ) { pamac_config.write (new_pamac_conf); @@ -754,6 +755,7 @@ namespace Pamac { } private void get_updates () { + bool syncfirst = false; AlpmPackage[] updates_infos = {}; unowned Alpm.Package? pkg = null; unowned Alpm.Package? candidate = null; @@ -764,76 +766,72 @@ namespace Pamac { if (candidate != null) { var infos = initialise_pkg_struct (candidate); updates_infos += (owned) infos; + syncfirst = true; } } } - if (updates_infos.length != 0) { - var updates = Updates () { - is_syncfirst = true, - repos_updates = (owned) updates_infos, - aur_updates = {} - }; - get_updates_finished (updates); - } else { - string[] local_pkgs = {}; - unowned Alpm.List<unowned Alpm.Package> pkgcache = alpm_handle.localdb.pkgcache; - while (pkgcache != null) { - unowned Alpm.Package installed_pkg = pkgcache.data; - // check if installed_pkg is in IgnorePkg or IgnoreGroup - if (alpm_handle.should_ignore (installed_pkg) == 0) { + string[] local_pkgs = {}; + unowned Alpm.List<unowned Alpm.Package> pkgcache = alpm_handle.localdb.pkgcache; + while (pkgcache != null) { + unowned Alpm.Package installed_pkg = pkgcache.data; + // check if installed_pkg is in IgnorePkg or IgnoreGroup + if (alpm_handle.should_ignore (installed_pkg) == 0) { + if (syncfirst) { + candidate = null; + } else { candidate = installed_pkg.sync_newversion (alpm_handle.syncdbs); - if (candidate != null) { - var infos = initialise_pkg_struct (candidate); - updates_infos += (owned) infos; - } else { - if (check_aur_updates && (!aur_updates_checked)) { - // check if installed_pkg is a local pkg - unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs; - while (syncdbs != null) { - unowned Alpm.DB db = syncdbs.data; - pkg = Alpm.find_satisfier (db.pkgcache, installed_pkg.name); - if (pkg != null) { - break; - } - syncdbs.next (); - } - if (pkg == null) { - local_pkgs += installed_pkg.name; + } + if (candidate != null) { + var infos = initialise_pkg_struct (candidate); + updates_infos += (owned) infos; + } else { + if (check_aur_updates && (!aur_updates_checked)) { + // check if installed_pkg is a local pkg + unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs; + while (syncdbs != null) { + unowned Alpm.DB db = syncdbs.data; + pkg = Alpm.find_satisfier (db.pkgcache, installed_pkg.name); + if (pkg != null) { + break; } + syncdbs.next (); + } + if (pkg == null) { + local_pkgs += installed_pkg.name; } } } - pkgcache.next (); } - if (check_aur_updates) { - // get aur updates - if (!aur_updates_checked) { - AUR.multiinfo.begin (local_pkgs, (obj, res) => { - aur_updates_results = AUR.multiinfo.end (res); - aur_updates_checked = true; - var updates = Updates () { - is_syncfirst = false, - repos_updates = (owned) updates_infos, - aur_updates = get_aur_updates_infos () - }; - get_updates_finished (updates); - }); - } else { - var updates = Updates () { - is_syncfirst = false, + pkgcache.next (); + } + if (check_aur_updates) { + // get aur updates + if (!aur_updates_checked) { + AUR.multiinfo.begin (local_pkgs, (obj, res) => { + aur_updates_results = AUR.multiinfo.end (res); + aur_updates_checked = true; + var updates = UpdatesPriv () { + syncfirst = syncfirst, repos_updates = (owned) updates_infos, aur_updates = get_aur_updates_infos () }; get_updates_finished (updates); - } + }); } else { - var updates = Updates () { - is_syncfirst = false, + var updates = UpdatesPriv () { + syncfirst = syncfirst, repos_updates = (owned) updates_infos, - aur_updates = {} + aur_updates = get_aur_updates_infos () }; get_updates_finished (updates); } + } else { + var updates = UpdatesPriv () { + syncfirst = syncfirst, + repos_updates = (owned) updates_infos, + aur_updates = {} + }; + get_updates_finished (updates); } } diff --git a/src/transaction-cli.vala b/src/transaction-cli.vala new file mode 100644 index 00000000..35081168 --- /dev/null +++ b/src/transaction-cli.vala @@ -0,0 +1,479 @@ +/* + * pamac-vala + * + * Copyright (C) 2018 Guillaume Benoit <guillaume@manjaro.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a get of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +namespace Pamac { + public class TransactionCli: Transaction { + bool downloading; + string current_line; + string current_action; + + public bool asking_user_input { get; set; } + + public TransactionCli (Database database) { + Object (database: database); + } + + construct { + downloading = false; + current_line = ""; + current_action = ""; + asking_user_input = false; + // connect to signal + emit_action.connect (print_action); + emit_action_progress.connect (print_action_progress); + emit_hook_progress.connect (print_hook_progress); + emit_script_output.connect (on_emit_script_output); + emit_warning.connect (print_warning); + emit_error.connect (print_error); + refresh_finished.connect (on_refresh_finished); + finished.connect (on_finished); + sysupgrade_finished.connect (on_finished); + start_downloading.connect (() => { + downloading = true; + }); + stop_downloading.connect (() => { + downloading = false; + }); + } + + protected override async int run_cmd_line (string[] args, string working_directory, Cancellable cancellable) { + int status = 1; + var launcher = new SubprocessLauncher (SubprocessFlags.NONE); + launcher.set_cwd (working_directory); + launcher.set_environ (Environ.get ()); + try { + Subprocess process = launcher.spawnv (args); + try { + yield process.wait_async (cancellable); + if (process.get_if_exited ()) { + status = process.get_exit_status (); + } + } catch (Error e) { + // cancelled + process.send_signal (Posix.Signal.INT); + process.send_signal (Posix.Signal.KILL); + } + } catch (Error e) { + print_error (e.message, {}); + } + return status; + } + + public int get_term_width () { + int width = 80; + Linux.winsize win; + if (Linux.ioctl (Posix.STDOUT_FILENO, Linux.Termios.TIOCGWINSZ, out win) == 0) { + width = win.ws_col; + } + return width; + } + + void display_current_line () { + if (current_line != "") { + // clean line + stdout.printf ("\r%*s\r", get_term_width (), ""); + stdout.printf (current_line); + stdout.printf ("\n"); + current_line = ""; + } + } + + void on_emit_script_output (string line) { + display_current_line (); + stdout.printf (line); + stdout.printf ("\n"); + } + + void print_action (string action) { + if (action == dgettext (null, "Checking dependencies") + || action == dgettext (null, "Resolving dependencies") + || action == dgettext (null, "Downloading")) { + asking_user_input = false; + } + display_current_line (); + current_line = ""; + stdout.printf (action); + stdout.printf ("\n"); + } + + void print_action_progress (string action, string status, double progress) { + if (downloading) { + if (progress == 0) { + current_action = action; + current_line = status; + stdout.printf (action); + stdout.printf ("\n"); + stdout.printf (status); + } else if (progress == 1) { + current_line = ""; + // clean line + stdout.printf ("\r%*s\r", get_term_width (), ""); + } else if (action == current_action) { + current_line = status; + // clean line + stdout.printf ("\r%*s\r", get_term_width (), ""); + stdout.printf (status); + } else { + current_action = action; + current_line = status; + // clean line + stdout.printf ("\r%*s\r", get_term_width (), ""); + stdout.printf (action); + stdout.printf ("\n"); + stdout.printf (status); + } + } else { + if (action != current_action) { + current_action = action; + display_current_line (); + } + int width = get_term_width () - action.char_count () - 1; + string current_status = "[%s]".printf (status); + current_line = "%s %*s".printf (action, width, current_status); + stdout.printf (current_line); + stdout.printf ("\r"); + } + stdout.flush (); + } + + void print_hook_progress (string action, string details, string status, double progress) { + if (action != current_action) { + current_action = action; + display_current_line (); + stdout.printf (action); + stdout.printf ("\n"); + } + int width = get_term_width () - details.char_count () - 1; + string current_status = "[%s]".printf (status); + stdout.printf ("%s %*s\n".printf (details, width, current_status)); + } + + void print_warning (string line) { + display_current_line (); + stdout.printf (line); + stdout.printf ("\n"); + } + + void print_error (string message, string[] details) { + display_current_line (); + if (downloading) { + // when downloading errors have no details + stdout.printf ("%s\n", message); + } else if (details.length > 0) { + if (details.length == 1) { + stdout.printf ("%s: %s: %s\n", dgettext (null, "Error"), message, details[0]); + } else { + stdout.printf ("%s: %s:\n", dgettext (null, "Error"), message); + foreach (unowned string detail in details) { + stdout.printf ("%s\n", detail); + } + } + } else { + stdout.printf ("%s: %s\n", dgettext (null, "Error"), message); + } + } + + protected override int choose_provider (string depend, string[] providers) { + AlpmPackage[] pkgs = {}; + foreach (unowned string pkgname in providers) { + var pkg = database.get_sync_pkg (pkgname); + if (pkg.name != "") { + pkgs += pkg; + } + } + // print pkgs + int name_length = 0; + int version_length = 0; + int repo_length = 0; + foreach (unowned AlpmPackage pkg in pkgs) { + if (pkg.name.length > name_length) { + name_length = pkg.name.length; + } + if (pkg.version.length > version_length) { + version_length = pkg.version.length; + } + if (pkg.repo.length > repo_length) { + repo_length = pkg.repo.length; + } + } + int num_length = providers.length.to_string ().length + 1; + int total_width = num_length + name_length + version_length + repo_length + 4; + int margin = 0; + if (get_term_width () > total_width) { + // divide available space between columns + int available_width = get_term_width () - total_width; + margin = available_width / 3; + // get left space to repo + repo_length += available_width - (margin * 3); + } + stdout.printf ("%s:\n".printf (dgettext (null, "Choose a provider for %s").printf (depend))); + int num = 1; + foreach (unowned AlpmPackage pkg in pkgs) { + stdout.printf ("%*s %-*s %-*s %-*s \n", num_length, "%i:".printf (num), + name_length + margin, pkg.name, + version_length + margin, pkg.version, + repo_length + margin, pkg.repo); + num++; + } + // get user input + asking_user_input = true; + while (true) { + stdout.printf ("%s: ", dgettext (null, "Enter a number (default=%d)").printf (1)); + string ans = stdin.read_line (); + int64 nb; + // remvove trailing newline + ans = ans.replace ("\n", ""); + // just return use default + if (ans == "") { + nb = 1; + } else if (!int64.try_parse (ans, out nb)) { + nb = 0; + } + stdout.printf ("\n"); + if (nb >= 1 && nb <= providers.length) { + int index = (int) nb - 1; + return index; + } + } + } + + protected override bool ask_confirmation (TransactionSummary summary) { + uint64 dsize = 0; + uint64 rsize = 0; + int64 isize = 0; + int max_name_length = 0; + int max_version_length = 0; + int max_installed_version_length = 0; + int max_size_length = 0; + int margin = 0; + // first pass to compute pkgs size and strings length + if (summary.to_remove.length > 0) { + foreach (unowned AlpmPackage infos in summary.to_remove) { + rsize += infos.size; + if (infos.name.length > max_name_length) { + max_name_length = infos.name.length; + } + if (infos.version.length > max_version_length) { + max_version_length = infos.version.length; + } + } + } + if (summary.aur_conflicts_to_remove.length > 0) { + foreach (unowned AlpmPackage infos in summary.aur_conflicts_to_remove) { + rsize += infos.size; + if (infos.name.length > max_name_length) { + max_name_length = infos.name.length; + } + if (infos.version.length > max_version_length) { + max_version_length = infos.version.length; + } + } + } + if (summary.to_downgrade.length > 0) { + foreach (unowned AlpmPackage infos in summary.to_downgrade) { + dsize += infos.download_size; + var pkg = database.get_installed_pkg (infos.name); + isize += ((int64) infos.size - (int64) pkg.size); + if (infos.name.length > max_name_length) { + max_name_length = infos.name.length; + } + if (infos.version.length > max_version_length) { + max_version_length = infos.version.length; + } + if (infos.installed_version.length > max_installed_version_length) { + max_installed_version_length = infos.installed_version.length; + } + string size = format_size (pkg.size); + if (size.length > max_size_length) { + max_size_length = size.length; + } + } + } + if (summary.to_build.length > 0) { + foreach (unowned AURPackage infos in summary.to_build) { + if (infos.name.length > max_name_length) { + max_name_length = infos.name.length; + } + if (infos.version.length > max_version_length) { + max_version_length = infos.version.length; + } + } + } + if (summary.to_install.length > 0) { + foreach (unowned AlpmPackage infos in summary.to_install) { + dsize += infos.download_size; + var pkg = database.get_installed_pkg (infos.name); + isize += ((int64) infos.size - (int64) pkg.size); + if (infos.name.length > max_name_length) { + max_name_length = infos.name.length; + } + if (infos.version.length > max_version_length) { + max_version_length = infos.version.length; + } + string size = format_size (pkg.size); + if (size.length > max_size_length) { + max_size_length = size.length; + } + } + } + if (summary.to_reinstall.length > 0) { + foreach (unowned AlpmPackage infos in summary.to_reinstall) { + dsize += infos.download_size; + var pkg = database.get_installed_pkg (infos.name); + if (infos.name.length > max_name_length) { + max_name_length = infos.name.length; + } + if (infos.version.length > max_version_length) { + max_version_length = infos.version.length; + } + string size = format_size (pkg.size); + if (size.length > max_size_length) { + max_size_length = size.length; + } + } + } + if (summary.to_upgrade.length > 0) { + foreach (unowned AlpmPackage infos in summary.to_upgrade) { + dsize += infos.download_size; + var pkg = database.get_installed_pkg (infos.name); + isize += ((int64) infos.size - (int64) pkg.size); + if (infos.name.length > max_name_length) { + max_name_length = infos.name.length; + } + if (infos.version.length > max_version_length) { + max_version_length = infos.version.length; + } + if (infos.installed_version.length > max_installed_version_length) { + max_installed_version_length = infos.installed_version.length; + } + string size = format_size (pkg.size); + if (size.length > max_size_length) { + max_size_length = size.length; + } + } + } + // second pass to print details + max_installed_version_length += 2; // because of (%s) + int total_width = max_name_length + max_version_length + max_installed_version_length + max_size_length + 6; + if (get_term_width () > total_width) { + // divide available space between columns + int available_width = get_term_width () - total_width; + margin = available_width / 4; + // get left space to size + max_size_length += available_width - (margin * 4); + } + if (summary.to_upgrade.length > 0) { + stdout.printf (dgettext (null, "To upgrade") + " (%u):\n".printf (summary.to_upgrade.length)); + foreach (unowned AlpmPackage infos in summary.to_upgrade) { + stdout.printf (" %-*s %-*s %-*s %*s \n", max_name_length + margin, infos.name, + max_version_length + margin, infos.version, + max_installed_version_length + margin, "(%s)".printf (infos.installed_version), + max_size_length + margin, format_size (infos.size)); + } + } + if (summary.to_reinstall.length > 0) { + stdout.printf (dgettext (null, "To reinstall") + " (%u):\n".printf (summary.to_reinstall.length)); + foreach (unowned AlpmPackage infos in summary.to_reinstall) { + stdout.printf (" %-*s %-*s %*s \n", max_name_length + margin, infos.name, + max_version_length + margin, infos.version, + max_size_length + margin, format_size (infos.size)); + } + } + if (summary.to_install.length > 0) { + stdout.printf (dgettext (null, "To install") + " (%u):\n".printf (summary.to_install.length)); + foreach (unowned AlpmPackage infos in summary.to_install) { + stdout.printf (" %-*s %-*s %*s \n", max_name_length + margin, infos.name, + max_version_length + margin, infos.version, + max_size_length + margin, format_size (infos.size)); + } + } + if (summary.to_build.length > 0) { + stdout.printf (dgettext (null, "To build") + " (%u):\n".printf (summary.to_build.length)); + foreach (unowned AURPackage infos in summary.to_build) { + stdout.printf (" %-*s %-*s\n", max_name_length + margin, infos.name, + max_version_length + margin, infos.version); + } + } + if (summary.to_downgrade.length > 0) { + stdout.printf (dgettext (null, "To downgrade") + " (%u):\n".printf (summary.to_downgrade.length)); + foreach (unowned AlpmPackage infos in summary.to_downgrade) { + stdout.printf (" %-*s %-*s %-*s %*s \n", max_name_length + margin, infos.name, + max_version_length + margin, infos.version, + max_installed_version_length + margin, "(%s)".printf (infos.installed_version), + max_size_length + margin, format_size (infos.size)); + } + } + bool to_remove_printed = false; + if (summary.to_remove.length > 0) { + stdout.printf (dgettext (null, "To remove") + " (%u):\n".printf (summary.to_remove.length)); + to_remove_printed = true; + foreach (unowned AlpmPackage infos in summary.to_remove) { + stdout.printf (" %-*s %-*s\n", max_name_length + margin, infos.name, + max_version_length + margin, infos.version); + } + } + if (summary.aur_conflicts_to_remove.length > 0) { + if (!to_remove_printed) { + stdout.printf (dgettext (null, "To remove") + " (%u):\n".printf (summary.aur_conflicts_to_remove.length)); + } + foreach (unowned AlpmPackage infos in summary.aur_conflicts_to_remove) { + stdout.printf (" %-*s %-*s\n", max_name_length + margin, infos.name, + max_version_length + margin, infos.version); + } + } + stdout.printf ("\n"); + if (dsize > 0) { + stdout.printf ("%s: %s\n", dgettext (null, "Total download size"), format_size (dsize)); + } + if (isize > 0) { + stdout.printf ("%s: %s\n", dgettext (null, "Total installed size"), format_size (isize)); + } else if (isize < 0) { + stdout.printf ("%s: -%s\n", dgettext (null, "Total installed size"), format_size (isize.abs ())); + } + if (rsize > 0) { + stdout.printf ("%s: %s\n", dgettext (null, "Total removed size"), format_size (rsize)); + } + // ask user confirmation + asking_user_input = true; + stdout.printf ("%s ? %s ", dgettext (null, "Commit transaction"), dgettext (null, "[y/N]")); + char buf[32]; + if (stdin.gets (buf) != null) { + string ans = (string) buf; + // remove trailing newline and uppercase + ans = ans.replace ("\n", "").down (); + // just return use default + if (ans != "") { + if (ans == dgettext (null, "y") || + ans == dgettext (null, "yes")) { + return true; + } + } + } + return false; + } + + void on_refresh_finished (bool success) { + asking_user_input = false; + } + + void on_finished (bool success) { + asking_user_input = false; + } + } +} diff --git a/src/transaction-gtk.vala b/src/transaction-gtk.vala new file mode 100644 index 00000000..145b35d3 --- /dev/null +++ b/src/transaction-gtk.vala @@ -0,0 +1,480 @@ +/* + * pamac-vala + * + * Copyright (C) 2014-2018 Guillaume Benoit <guillaume@manjaro.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a get of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +namespace Pamac { + public class TransactionGtk: Transaction { + //dialogs + public string[] preferences_available_countries; + TransactionSumDialog transaction_sum_dialog; + public GenericSet<string?> transaction_summary; + StringBuilder warning_textbuffer; + string current_action; + public ProgressBox progress_box; + uint pulse_timeout_id; + Vte.Terminal term; + Vte.Pty pty; + public Gtk.ScrolledWindow term_window; + //parent window + public Gtk.ApplicationWindow? application_window { get; construct; } + + public TransactionGtk (Database database, Gtk.ApplicationWindow? application_window) { + Object (database: database, application_window: application_window); + } + + construct { + //creating dialogs + this.application_window = application_window; + transaction_sum_dialog = new TransactionSumDialog (application_window); + transaction_summary = new GenericSet<string?> (str_hash, str_equal); + warning_textbuffer = new StringBuilder (); + current_action = ""; + progress_box = new ProgressBox (); + progress_box.progressbar.text = ""; + //creating terminal + term = new Vte.Terminal (); + term.set_scrollback_lines (-1); + term.expand = true; + term.visible = true; + var black = Gdk.RGBA (); + black.parse ("black"); + term.set_color_cursor (black); + term.button_press_event.connect (on_term_button_press_event); + term.key_press_event.connect (on_term_key_press_event); + // creating pty for term + try { + pty = term.pty_new_sync (Vte.PtyFlags.NO_HELPER); + } catch (Error e) { + stderr.printf ("Error: %s\n", e.message); + } + // add term in a grid with a scrollbar + term_window = new Gtk.ScrolledWindow (null, term.vadjustment); + term_window.expand = true; + term_window.visible = true; + term_window.propagate_natural_height = true; + term_window.add (term); + // connect to signal + emit_action.connect (display_action); + emit_action_progress.connect (display_action_progress); + emit_hook_progress.connect (display_hook_progress); + emit_script_output.connect (show_in_term); + emit_warning.connect ((msg) => { + warning_textbuffer.append (msg + "\n"); + }); + emit_error.connect (display_error); + refresh_finished.connect (on_refresh_finished); + finished.connect (on_finished); + sysupgrade_finished.connect (on_finished); + start_generating_mirrors_list.connect (start_progressbar_pulse); + generate_mirrors_list_finished.connect (reset_progress_box); + start_building.connect (start_progressbar_pulse); + stop_building.connect (stop_progressbar_pulse); + // notify + Notify.init (dgettext (null, "Package Manager")); + // flags + flags = (1 << 4); //Alpm.TransFlag.CASCADE + if (database.config.recurse) { + flags |= (1 << 5); //Alpm.TransFlag.RECURSE + } + } + + bool on_term_button_press_event (Gdk.EventButton event) { + // Check if right mouse button was clicked + if (event.type == Gdk.EventType.BUTTON_PRESS && event.button == 3) { + if (term.get_has_selection ()) { + var right_click_menu = new Gtk.Menu (); + var copy_item = new Gtk.MenuItem.with_label (dgettext (null, "Copy")); + copy_item.activate.connect (() => {term.copy_clipboard ();}); + right_click_menu.append (copy_item); + right_click_menu.show_all (); + right_click_menu.popup_at_pointer (event); + return true; + } + } + return false; + } + + bool on_term_key_press_event (Gdk.EventKey event) { + // Check if Ctrl + c keys were pressed + if (((event.state & Gdk.ModifierType.CONTROL_MASK) != 0) && (Gdk.keyval_name (event.keyval) == "c")) { + term.copy_clipboard (); + return true; + } + return false; + } + + void show_in_term (string message) { + term.set_pty (pty); + try { + Process.spawn_async (null, {"echo", message}, null, SpawnFlags.SEARCH_PATH, pty.child_setup, null); + } catch (SpawnError e) { + stderr.printf ("SpawnError: %s\n", e.message); + } + } + + protected override async int run_cmd_line (string[] args, string working_directory, Cancellable cancellable) { + int status = 1; + term.set_pty (pty); + var launcher = new SubprocessLauncher (SubprocessFlags.NONE); + launcher.set_cwd (working_directory); + launcher.set_environ (Environ.get ()); + launcher.set_child_setup (pty.child_setup); + try { + Subprocess process = launcher.spawnv (args); + try { + yield process.wait_async (cancellable); + if (process.get_if_exited ()) { + status = process.get_exit_status (); + } + } catch (Error e) { + // cancelled + process.send_signal (Posix.Signal.INT); + process.send_signal (Posix.Signal.KILL); + } + } catch (Error e) { + stderr.printf ("Error: %s\n", e.message); + } + return status; + } + + void display_action (string action) { + if (action != current_action) { + current_action = action; + show_in_term (action); + progress_box.action_label.label = action; + progress_box.progressbar.fraction = 0; + progress_box.progressbar.text = ""; + } + } + + void display_action_progress (string action, string status, double progress) { + if (action != current_action) { + current_action = action; + show_in_term (action); + progress_box.action_label.label = action; + } + progress_box.progressbar.fraction = progress; + progress_box.progressbar.text = status; + } + + void display_hook_progress (string action, string details, string status, double progress) { + if (action != current_action) { + current_action = action; + show_in_term (action); + progress_box.action_label.label = action; + } + show_in_term (details); + progress_box.progressbar.fraction = progress; + progress_box.progressbar.text = status; + } + + public void reset_progress_box () { + current_action = ""; + progress_box.action_label.label = ""; + stop_progressbar_pulse (); + progress_box.progressbar.fraction = 0; + progress_box.progressbar.text = ""; + } + + public void start_progressbar_pulse () { + stop_progressbar_pulse (); + pulse_timeout_id = Timeout.add (500, (GLib.SourceFunc) progress_box.progressbar.pulse); + } + + public void stop_progressbar_pulse () { + if (pulse_timeout_id != 0) { + Source.remove (pulse_timeout_id); + pulse_timeout_id = 0; + progress_box.progressbar.fraction = 0; + } + } + + protected override int choose_provider (string depend, string[] providers) { + var choose_provider_dialog = new ChooseProviderDialog (application_window); + choose_provider_dialog.title = dgettext (null, "Choose a provider for %s").printf (depend); + unowned Gtk.Box box = choose_provider_dialog.get_content_area (); + Gtk.RadioButton? last_radiobutton = null; + Gtk.RadioButton? first_radiobutton = null; + foreach (unowned string provider in providers) { + var radiobutton = new Gtk.RadioButton.with_label_from_widget (last_radiobutton, provider); + radiobutton.visible = true; + // active first provider + if (last_radiobutton == null) { + radiobutton.active = true; + first_radiobutton = radiobutton; + } + last_radiobutton = radiobutton; + box.add (radiobutton); + } + choose_provider_dialog.run (); + // get active provider + int index = 0; + // list is given in reverse order so reverse it ! + SList<unowned Gtk.RadioButton> list = last_radiobutton.get_group ().copy (); + list.reverse (); + foreach (var radiobutton in list) { + if (radiobutton.active) { + break; + } + index++; + } + choose_provider_dialog.destroy (); + return index; + } + + protected override bool ask_confirmation (TransactionSummary summary) { + show_warnings (true); + uint64 dsize = 0; + transaction_summary.remove_all (); + transaction_sum_dialog.sum_list.clear (); + var iter = Gtk.TreeIter (); + if (summary.to_remove.length > 0) { + foreach (unowned AlpmPackage infos in summary.to_remove) { + transaction_summary.add (infos.name); + transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, + 1, infos.name, + 2, infos.version); + } + Gtk.TreePath path = transaction_sum_dialog.sum_list.get_path (iter); + int pos = (path.get_indices ()[0]) - (summary.to_remove.length - 1); + transaction_sum_dialog.sum_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); + transaction_sum_dialog.sum_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "To remove") + ":")); + } + if (summary.aur_conflicts_to_remove.length > 0) { + // do not add type enum because it is just infos + foreach (unowned AlpmPackage infos in summary.aur_conflicts_to_remove) { + transaction_summary.add (infos.name); + transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, + 1, infos.name, + 2, infos.version); + } + Gtk.TreePath path = transaction_sum_dialog.sum_list.get_path (iter); + int pos = (path.get_indices ()[0]) - (summary.aur_conflicts_to_remove.length - 1); + transaction_sum_dialog.sum_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); + transaction_sum_dialog.sum_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "To remove") + ":")); + } + if (summary.to_downgrade.length > 0) { + foreach (unowned AlpmPackage infos in summary.to_downgrade) { + dsize += infos.download_size; + transaction_summary.add (infos.name); + transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, + 1, infos.name, + 2, infos.version, + 3, "(%s)".printf (infos.installed_version)); + } + Gtk.TreePath path = transaction_sum_dialog.sum_list.get_path (iter); + int pos = (path.get_indices ()[0]) - (summary.to_downgrade.length - 1); + transaction_sum_dialog.sum_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); + transaction_sum_dialog.sum_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "To downgrade") + ":")); + } + if (summary.to_build.length > 0) { + foreach (unowned AURPackage infos in summary.to_build) { + transaction_summary.add (infos.name); + transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, + 1, infos.name, + 2, infos.version); + } + Gtk.TreePath path = transaction_sum_dialog.sum_list.get_path (iter); + int pos = (path.get_indices ()[0]) - (summary.to_build.length - 1); + transaction_sum_dialog.sum_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); + transaction_sum_dialog.sum_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "To build") + ":")); + } + if (summary.to_install.length > 0) { + foreach (unowned AlpmPackage infos in summary.to_install) { + dsize += infos.download_size; + transaction_summary.add (infos.name); + transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, + 1, infos.name, + 2, infos.version); + } + Gtk.TreePath path = transaction_sum_dialog.sum_list.get_path (iter); + int pos = (path.get_indices ()[0]) - (summary.to_install.length - 1); + transaction_sum_dialog.sum_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); + transaction_sum_dialog.sum_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "To install") + ":")); + } + if (summary.to_reinstall.length > 0) { + foreach (unowned AlpmPackage infos in summary.to_reinstall) { + dsize += infos.download_size; + transaction_summary.add (infos.name); + transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, + 1, infos.name, + 2, infos.version); + } + Gtk.TreePath path = transaction_sum_dialog.sum_list.get_path (iter); + int pos = (path.get_indices ()[0]) - (summary.to_reinstall.length - 1); + transaction_sum_dialog.sum_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); + transaction_sum_dialog.sum_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "To reinstall") + ":")); + } + if (summary.to_upgrade.length > 0) { + if (!no_confirm_upgrade) { + foreach (unowned AlpmPackage infos in summary.to_upgrade) { + dsize += infos.download_size; + transaction_summary.add (infos.name); + transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, + 1, infos.name, + 2, infos.version, + 3, "(%s)".printf (infos.installed_version)); + } + Gtk.TreePath path = transaction_sum_dialog.sum_list.get_path (iter); + int pos = (path.get_indices ()[0]) - (summary.to_upgrade.length - 1); + transaction_sum_dialog.sum_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); + transaction_sum_dialog.sum_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "To upgrade") + ":")); + } + } + if (dsize == 0) { + transaction_sum_dialog.top_label.visible = false; + } else { + transaction_sum_dialog.top_label.set_markup ("<b>%s: %s</b>".printf (dgettext (null, "Total download size"), format_size (dsize))); + transaction_sum_dialog.top_label.visible = true; + } + if (transaction_sum_dialog.run () == Gtk.ResponseType.OK) { + transaction_sum_dialog.hide (); + return true; + } else { + transaction_sum_dialog.hide (); + transaction_summary.remove_all (); + } + return false; + } + + void show_warnings (bool block) { + if (warning_textbuffer.len > 0) { + var flags = Gtk.DialogFlags.MODAL; + int use_header_bar; + Gtk.Settings.get_default ().get ("gtk-dialogs-use-header", out use_header_bar); + if (use_header_bar == 1) { + flags |= Gtk.DialogFlags.USE_HEADER_BAR; + } + var dialog = new Gtk.Dialog.with_buttons (dgettext (null, "Warning"), + application_window, + flags); + dialog.border_width = 6; + dialog.icon_name = "system-software-install"; + dialog.deletable = false; + unowned Gtk.Widget widget = dialog.add_button (dgettext (null, "_Close"), Gtk.ResponseType.CLOSE); + widget.can_focus = true; + widget.has_focus = true; + widget.can_default = true; + widget.has_default = true; + var scrolledwindow = new Gtk.ScrolledWindow (null, null); + var label = new Gtk.Label (warning_textbuffer.str); + label.selectable = true; + label.margin = 12; + scrolledwindow.visible = true; + label.visible = true; + scrolledwindow.add (label); + scrolledwindow.expand = true; + unowned Gtk.Box box = dialog.get_content_area (); + box.add (scrolledwindow); + dialog.default_width = 600; + dialog.default_height = 300; + if (block) { + dialog.run (); + dialog.destroy (); + } else { + dialog.show (); + dialog.response.connect (() => { + dialog.destroy (); + }); + } + warning_textbuffer = new StringBuilder (); + } + } + + public void display_error (string message, string[] details) { + reset_progress_box (); + var flags = Gtk.DialogFlags.MODAL; + int use_header_bar; + Gtk.Settings.get_default ().get ("gtk-dialogs-use-header", out use_header_bar); + if (use_header_bar == 1) { + flags |= Gtk.DialogFlags.USE_HEADER_BAR; + } + var dialog = new Gtk.Dialog.with_buttons (message, + application_window, + flags); + dialog.border_width = 6; + dialog.icon_name = "system-software-install"; + var textbuffer = new StringBuilder (); + if (details.length != 0) { + show_in_term (message + ":"); + foreach (unowned string detail in details) { + show_in_term (detail); + textbuffer.append (detail + "\n"); + } + } else { + show_in_term (message); + textbuffer.append (message); + } + dialog.deletable = false; + unowned Gtk.Widget widget = dialog.add_button (dgettext (null, "_Close"), Gtk.ResponseType.CLOSE); + widget.can_focus = true; + widget.has_focus = true; + widget.can_default = true; + widget.has_default = true; + var scrolledwindow = new Gtk.ScrolledWindow (null, null); + var label = new Gtk.Label (textbuffer.str); + label.selectable = true; + label.margin = 12; + scrolledwindow.visible = true; + label.visible = true; + scrolledwindow.add (label); + scrolledwindow.expand = true; + unowned Gtk.Box box = dialog.get_content_area (); + box.add (scrolledwindow); + dialog.default_width = 600; + dialog.default_height = 300; + dialog.show (); + dialog.response.connect (() => { + dialog.destroy (); + }); + Timeout.add (1000, () => { + try { + var notification = new Notify.Notification (dgettext (null, "Package Manager"), + message, + "system-software-update"); + notification.show (); + } catch (Error e) { + stderr.printf ("Notify Error: %s", e.message); + } + return false; + }); + } + + void on_refresh_finished (bool success) { + reset_progress_box (); + show_in_term (""); + } + + void on_finished (bool success) { + if (success) { + try { + var notification = new Notify.Notification (dgettext (null, "Package Manager"), + dgettext (null, "Transaction successfully finished"), + "system-software-update"); + notification.show (); + } catch (Error e) { + stderr.printf ("Notify Error: %s", e.message); + } + } + transaction_summary.remove_all (); + reset_progress_box (); + show_in_term (""); + show_warnings (false); + } + } +} diff --git a/src/transaction.vala b/src/transaction.vala index 0dd63783..07321a44 100644 --- a/src/transaction.vala +++ b/src/transaction.vala @@ -18,44 +18,6 @@ */ namespace Pamac { - [DBus (name = "org.manjaro.pamac.user")] - interface UserDaemon : Object { - public abstract void enable_appstream () throws Error; - public abstract void refresh_handle () throws Error; - public abstract string[] get_mirrors_countries () throws Error; - public abstract string get_mirrors_choosen_country () throws Error; - public abstract string get_lockfile () throws Error; - public abstract AlpmPackage get_installed_pkg (string pkgname) throws Error; - public abstract bool get_checkspace () throws Error; - public abstract string[] get_ignorepkgs () throws Error; - public abstract bool should_hold (string pkgname) throws Error; - public abstract uint get_pkg_reason (string pkgname) throws Error; - public abstract uint get_pkg_origin (string pkgname) throws Error; - public abstract async AlpmPackage[] get_installed_pkgs () throws Error; - public abstract async AlpmPackage[] get_installed_apps () throws Error; - public abstract async AlpmPackage[] get_explicitly_installed_pkgs () throws Error; - public abstract async AlpmPackage[] get_foreign_pkgs () throws Error; - public abstract async AlpmPackage[] get_orphans () throws Error; - public abstract AlpmPackage find_installed_satisfier (string depstring) throws Error; - public abstract AlpmPackage get_sync_pkg (string pkgname) throws Error; - public abstract AlpmPackage find_sync_satisfier (string depstring) throws Error; - public abstract async AlpmPackage[] search_pkgs (string search_string) throws Error; - public abstract async AURPackage[] search_in_aur (string search_string) throws Error; - public abstract async AlpmPackage[] get_category_pkgs (string category) throws Error; - public abstract string[] get_repos_names () throws Error; - public abstract async AlpmPackage[] get_repo_pkgs (string repo) throws Error; - public abstract string[] get_groups_names () throws Error; - public abstract async AlpmPackage[] get_group_pkgs (string groupname) throws Error; - public abstract AlpmPackageDetails get_pkg_details (string pkgname, string app_name) throws Error; - public abstract string[] get_pkg_files (string pkgname) throws Error; - public abstract async AURPackageDetails get_aur_details (string pkgname) throws Error; - public abstract string[] get_pkg_uninstalled_optdeps (string pkgname) throws Error; - public abstract void start_get_updates (bool check_aur_updates, bool refresh_files_dbs) throws Error; - [DBus (no_reply = true)] - public abstract void quit () throws Error; - public signal void emit_get_updates_progress (uint percent); - public signal void get_updates_finished (Updates updates); - } [DBus (name = "org.manjaro.pamac.system")] interface SystemDaemon : Object { public abstract void set_environment_variables (HashTable<string,string> variables) throws Error; @@ -79,7 +41,7 @@ namespace Pamac { public abstract void start_get_updates (bool check_aur_updates) throws Error; [DBus (no_reply = true)] public abstract void quit () throws Error; - public signal void get_updates_finished (Updates updates); + public signal void get_updates_finished (UpdatesPriv updates); public signal void emit_event (uint primary_event, uint secondary_event, string[] details); public signal void emit_providers (string depend, string[] providers); public signal void emit_progress (uint progress, string pkgname, uint percent, uint n_targets, uint current_target); @@ -100,198 +62,114 @@ namespace Pamac { } public class Transaction: Object { - enum Type { - STANDARD = (1 << 0), - UPDATE = (1 << 1), - BUILD = (1 << 2) + INSTALL = (1 << 0), + REMOVE = (1 << 1), + UPDATE = (1 << 2), + BUILD = (1 << 3) } - - public enum Mode { - MANAGER, - INSTALLER - } - - UserDaemon user_daemon; SystemDaemon system_daemon; - - public Mode mode; - Pamac.Config pamac_config; - public bool check_aur_updates { get { return pamac_config.check_aur_updates; } } - public bool enable_aur { get { return pamac_config.enable_aur; } } - public unowned GLib.HashTable<string,string> environment_variables { get {return pamac_config.environment_variables; } } - public bool no_update_hide_icon { get { return pamac_config.no_update_hide_icon; } } - public bool download_updates { get { return pamac_config.download_updates; } } - public bool recurse { get { return pamac_config.recurse; } } - public uint64 refresh_period { get { return pamac_config.refresh_period; } } - public string aur_build_dir { get { return pamac_config.aur_build_dir; } } - public uint64 keep_num_pkgs { get { return pamac_config.keep_num_pkgs; } } - public bool rm_only_uninstalled { get { return pamac_config.rm_only_uninstalled; } } - - //Alpm.TransFlag - int flags; - - public GenericSet<string?> to_install; - public GenericSet<string?> to_remove; - public GenericSet<string?> to_load; - public GenericSet<string?> to_build; - public GenericSet<string?> to_update; + // run transaction data + string current_action; + string current_status; + double current_progress; + string current_filename; + bool sysupgrade_after_trans; + bool no_confirm_commit; + bool enable_downgrade; + bool sysupgrading; + string[] to_install_first; + string[] temporary_ignorepkgs; + string[] overwrite_files; + // building data Queue<string> to_build_queue; string[] aur_pkgs_to_install; - GenericSet<string?> previous_to_install; - GenericSet<string?> previous_to_remove; - public GenericSet<string?> transaction_summary; - public GenericSet<string?> temporary_ignorepkgs; - public GLib.File lockfile; - + bool building; + Cancellable build_cancellable; + // download data + Timer timer; uint64 total_download; uint64 already_downloaded; - string previous_textbar; - float previous_percent; - string previous_filename; - uint pulse_timeout_id; - bool sysupgrade_after_trans; - bool enable_downgrade; - bool no_confirm_commit; - bool building; uint64 previous_xfered; uint64 download_rate; uint64 rates_nb; - Timer timer; - bool success; - StringBuilder warning_textbuffer; - - //dialogs - public string[] preferences_available_countries; - TransactionSumDialog transaction_sum_dialog; - public ProgressBox progress_box; - Vte.Terminal term; - Vte.Pty pty; - Cancellable build_cancellable; - public Gtk.ScrolledWindow term_window; - //parent window - public Gtk.ApplicationWindow? application_window { get; private set; } + // transaction options + public Database database { get; construct set; } + public int flags { get; set; } //Alpm.TransFlag + public bool no_confirm_upgrade { get; set; } + + public signal void emit_action (string action); + public signal void emit_action_progress (string action, string status, double progress); + public signal void emit_hook_progress (string action, string details, string status, double progress); + public signal void emit_script_output (string message); + public signal void emit_warning (string message); + public signal void emit_error (string message, string[] details); public signal void start_downloading (); public signal void stop_downloading (); public signal void start_building (); public signal void stop_building (); public signal void important_details_outpout (bool must_show); + public signal void refresh_finished (bool success); public signal void finished (bool success); + public signal void sysupgrade_finished (bool success); public signal void set_pkgreason_finished (); public signal void write_pamac_config_finished (bool recurse, uint64 refresh_period, bool no_update_hide_icon, bool enable_aur, string aur_build_dir, bool check_aur_updates, bool download_updates); public signal void write_alpm_config_finished (bool checkspace); - public signal void generate_mirrors_list (); + public signal void start_generating_mirrors_list (); public signal void generate_mirrors_list_finished (); - public signal void run_preferences_dialog_finished (); - public signal void get_updates_progress (uint percent); - public signal void get_updates_finished (Updates updates); - public Transaction (Gtk.ApplicationWindow? application_window) { - mode = Mode.MANAGER; - pamac_config = new Pamac.Config ("/etc/pamac.conf"); - flags = (1 << 4); //Alpm.TransFlag.CASCADE - if (pamac_config.recurse) { - flags |= (1 << 5); //Alpm.TransFlag.RECURSE - } - to_install = new GenericSet<string?> (str_hash, str_equal); - to_remove = new GenericSet<string?> (str_hash, str_equal); - to_load = new GenericSet<string?> (str_hash, str_equal); - to_build = new GenericSet<string?> (str_hash, str_equal); - to_update = new GenericSet<string?> (str_hash, str_equal); - to_build_queue = new Queue<string> (); - previous_to_install = new GenericSet<string?> (str_hash, str_equal); - previous_to_remove = new GenericSet<string?> (str_hash, str_equal); - transaction_summary = new GenericSet<string?> (str_hash, str_equal); - temporary_ignorepkgs = new GenericSet<string?> (str_hash, str_equal); - connecting_user_daemon (); - get_lockfile (); - //creating dialogs - this.application_window = application_window; - preferences_available_countries = {}; - transaction_sum_dialog = new TransactionSumDialog (application_window); - progress_box = new ProgressBox (); - progress_box.progressbar.text = ""; - //creating terminal - term = new Vte.Terminal (); - term.set_scrollback_lines (-1); - term.expand = true; - term.visible = true; - var black = Gdk.RGBA (); - black.parse ("black"); - term.set_color_cursor (black); - term.button_press_event.connect (on_term_button_press_event); - term.key_press_event.connect (on_term_key_press_event); - // creating pty for term - try { - pty = term.pty_new_sync (Vte.PtyFlags.NO_HELPER); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } - // add term in a grid with a scrollbar - term_window = new Gtk.ScrolledWindow (null, term.vadjustment); - term_window.expand = true; - term_window.visible = true; - term_window.propagate_natural_height = true; - term_window.add (term); - build_cancellable = new Cancellable (); - // progress data - previous_textbar = ""; - previous_filename = ""; + public Transaction (Database database) { + Object (database: database); + } + + construct { + // transaction options + flags = 0; + enable_downgrade = false; + no_confirm_upgrade = false; + // run transaction data + current_action = ""; + current_status = ""; + current_filename = ""; sysupgrade_after_trans = false; no_confirm_commit = false; + sysupgrading = false; + to_install_first = {}; + temporary_ignorepkgs = {}; + overwrite_files = {}; + // building data + to_build_queue = new Queue<string> (); + build_cancellable = new Cancellable (); building = false; + // download data timer = new Timer (); - success = false; - warning_textbuffer = new StringBuilder (); - // notify - Notify.init (dgettext (null, "Package Manager")); } - public void run_preferences_dialog () { - check_authorization.begin ((obj, res) => { - bool authorized = check_authorization.end (res); - if (authorized) { - var preferences_dialog = new PreferencesDialog (this); - preferences_dialog.run (); - preferences_dialog.destroy (); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); - } - } - run_preferences_dialog_finished (); - }); + // destruction + ~Transaction () { + stop_daemon (); } - public ErrorInfos get_current_error () { - try { - return system_daemon.get_current_error (); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - return ErrorInfos (); - } + protected virtual bool ask_confirmation (TransactionSummary summary) { + // no confirm + return true; } - public string[] get_mirrors_countries () { - string[] countries = {}; - try { - countries = user_daemon.get_mirrors_countries (); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } - return countries; + protected virtual int choose_provider (string depend, string[] providers) { + // choose first provider + return 0; } - public string get_mirrors_choosen_country () { - string country = ""; + ErrorInfos get_current_error () { try { - country = user_daemon.get_mirrors_choosen_country (); + return system_daemon.get_current_error (); } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); + stderr.printf ("get_current_error: %s\n", e.message); + return ErrorInfos (); } - return country; } public bool get_lock () { @@ -300,7 +178,7 @@ namespace Pamac { try { locked = system_daemon.get_lock (); } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); + stderr.printf ("get_lock: %s\n", e.message); } return locked; } @@ -310,12 +188,12 @@ namespace Pamac { try { unlocked = system_daemon.unlock (); } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); + stderr.printf ("unlock: %s\n", e.message); } return unlocked; } - async bool check_authorization () { + public async bool check_authorization () { SourceFunc callback = check_authorization.callback; bool authorized = false; ulong handler_id = system_daemon.get_authorization_finished.connect ((authorized_) => { @@ -325,7 +203,7 @@ namespace Pamac { try { system_daemon.start_get_authorization (); } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); + stderr.printf ("start_get_authorization: %s\n", e.message); } yield; system_daemon.disconnect (handler_id); @@ -334,119 +212,32 @@ namespace Pamac { public void start_write_pamac_config (HashTable<string,Variant> new_pamac_conf) { try { - system_daemon.write_pamac_config_finished.connect (on_write_pamac_config_finished); system_daemon.start_write_pamac_config (new_pamac_conf); + system_daemon.write_pamac_config_finished.connect (on_write_pamac_config_finished); } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - system_daemon.write_pamac_config_finished.disconnect (on_write_pamac_config_finished); + stderr.printf ("start_write_pamac_config: %s\n", e.message); } } public void start_write_alpm_config (HashTable<string,Variant> new_alpm_conf) { try { - system_daemon.write_alpm_config_finished.connect (on_write_alpm_config_finished); system_daemon.start_write_alpm_config (new_alpm_conf); + system_daemon.write_alpm_config_finished.connect (on_write_alpm_config_finished); } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - system_daemon.write_alpm_config_finished.disconnect (on_write_alpm_config_finished); - } - } - - bool on_term_button_press_event (Gdk.EventButton event) { - // Check if right mouse button was clicked - if (event.type == Gdk.EventType.BUTTON_PRESS && event.button == 3) { - if (term.get_has_selection ()) { - var right_click_menu = new Gtk.Menu (); - var copy_item = new Gtk.MenuItem.with_label (dgettext (null, "Copy")); - copy_item.activate.connect (() => {term.copy_clipboard ();}); - right_click_menu.append (copy_item); - right_click_menu.show_all (); - right_click_menu.popup_at_pointer (event); - return true; - } - } - return false; - } - - bool on_term_key_press_event (Gdk.EventKey event) { - // Check if Ctrl + c keys were pressed - if (((event.state & Gdk.ModifierType.CONTROL_MASK) != 0) && (Gdk.keyval_name (event.keyval) == "c")) { - term.copy_clipboard (); - return true; - } - return false; - } - - void show_in_term (string message) { - term.set_pty (pty); - try { - Process.spawn_async (null, {"echo", message}, null, SpawnFlags.SEARCH_PATH, pty.child_setup, null); - } catch (SpawnError e) { - stderr.printf ("SpawnError: %s\n", e.message); - } - } - - async int spawn_in_term (string[] args, string? working_directory = null) { - int status = 1; - term.set_pty (pty); - var launcher = new SubprocessLauncher (SubprocessFlags.NONE); - launcher.set_cwd (working_directory); - launcher.set_environ (Environ.get ()); - launcher.set_child_setup (pty.child_setup); - try { - Subprocess process = launcher.spawnv (args); - try { - yield process.wait_async (build_cancellable); - if (process.get_if_exited ()) { - status = process.get_exit_status (); - } - } catch (Error e) { - // cancelled - process.send_signal (Posix.Signal.INT); - process.send_signal (Posix.Signal.KILL); - } - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } - return status; - } - - void reset_progress_box (string action) { - show_in_term (action); - progress_box.action_label.label = action; - stop_progressbar_pulse (); - progress_box.progressbar.fraction = 0; - progress_box.progressbar.text = ""; - } - - public void start_progressbar_pulse () { - stop_progressbar_pulse (); - pulse_timeout_id = Timeout.add (500, (GLib.SourceFunc) progress_box.progressbar.pulse); - } - - public void stop_progressbar_pulse () { - if (pulse_timeout_id != 0) { - Source.remove (pulse_timeout_id); - pulse_timeout_id = 0; - progress_box.progressbar.fraction = 0; + stderr.printf ("start_write_alpm_config: %s\n", e.message); } } public void start_generate_mirrors_list (string country) { - string action = dgettext (null, "Refreshing mirrors list") + "..."; - reset_progress_box (action); - start_progressbar_pulse (); + emit_action (dgettext (null, "Refreshing mirrors list") + "..."); important_details_outpout (false); - generate_mirrors_list (); + start_generating_mirrors_list (); try { + system_daemon.start_generate_mirrors_list (country); system_daemon.generate_mirrors_list_data.connect (on_generate_mirrors_list_data); system_daemon.generate_mirrors_list_finished.connect (on_generate_mirrors_list_finished); - system_daemon.start_generate_mirrors_list (country); } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - stop_progressbar_pulse (); - system_daemon.generate_mirrors_list_data.disconnect (on_generate_mirrors_list_data); - system_daemon.generate_mirrors_list_finished.disconnect (on_generate_mirrors_list_finished); + stderr.printf ("start_generate_mirrors_list: %s\n", e.message); } } @@ -454,17 +245,16 @@ namespace Pamac { try { system_daemon.clean_cache (keep_nb, only_uninstalled); } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); + stderr.printf ("clean_cache: %s\n", e.message); } } public void start_set_pkgreason (string pkgname, uint reason) { try { - system_daemon.set_pkgreason_finished.connect (on_set_pkgreason_finished); system_daemon.start_set_pkgreason (pkgname, reason); + system_daemon.set_pkgreason_finished.connect (on_set_pkgreason_finished); } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - system_daemon.set_pkgreason_finished.disconnect (on_set_pkgreason_finished); + stderr.printf ("start_set_pkgreason: %s\n", e.message); } } @@ -472,678 +262,182 @@ namespace Pamac { check_authorization.begin ((obj, res) => { bool authorized = check_authorization.end (res); if (authorized) { - string action = dgettext (null, "Synchronizing package databases") + "..."; - reset_progress_box (action); + emit_action (dgettext (null, "Synchronizing package databases") + "..."); connecting_system_daemon (); connecting_dbus_signals (); try { - system_daemon.refresh_finished.connect (on_refresh_finished); system_daemon.start_refresh (force); + system_daemon.refresh_finished.connect (on_refresh_finished); + start_downloading (); } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - system_daemon.refresh_finished.disconnect (on_refresh_finished); - success = false; - finish_transaction (); + stderr.printf ("start_refresh: %s\n", e.message); + on_refresh_finished (false); } } else { - success = false; - finish_transaction (); + on_refresh_finished (false); } }); } - public void refresh_handle () { - try { - user_daemon.refresh_handle (); - get_lockfile (); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } - } - - void get_lockfile () { - try { - lockfile = GLib.File.new_for_path (user_daemon.get_lockfile ()); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - //try standard lock file - lockfile = GLib.File.new_for_path ("var/lib/pacman/db.lck"); - } - } - - public bool get_checkspace () { - bool checkspace = false; - try { - checkspace = user_daemon.get_checkspace (); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } - return checkspace; - } - - public string[] get_ignorepkgs () { - string[] ignorepkgs = {}; - try { - ignorepkgs = user_daemon.get_ignorepkgs (); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } - return ignorepkgs; - } - - public AlpmPackage get_installed_pkg (string pkgname) { - try { - return user_daemon.get_installed_pkg (pkgname); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - return AlpmPackage () { - name = "", - version = "", - desc = "", - repo = "" - }; - } - } - - public AlpmPackage find_installed_satisfier (string depstring) { - try { - return user_daemon.find_installed_satisfier (depstring); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - return AlpmPackage () { - name = "", - version = "", - desc = "", - repo = "" - }; - } - } - - public bool should_hold (string pkgname) { - bool should_hold = false; - try { - should_hold = user_daemon.should_hold (pkgname); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } - return should_hold; - } - - public uint get_pkg_reason (string pkgname) { - uint reason = 0; - try { - reason = user_daemon.get_pkg_reason (pkgname); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } - return reason; - } - - public uint get_pkg_origin (string pkgname) { - uint origin = 0; - try { - origin = user_daemon.get_pkg_origin (pkgname); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } - return origin; - } - - public async AlpmPackage[] get_installed_pkgs () { - AlpmPackage[] pkgs = {}; - try { - pkgs = yield user_daemon.get_installed_pkgs (); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } - return pkgs; - } - - public async AlpmPackage[] get_installed_apps () { - AlpmPackage[] pkgs = {}; - try { - pkgs = yield user_daemon.get_installed_apps (); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } - return pkgs; - } - - public async AlpmPackage[] get_explicitly_installed_pkgs () { - AlpmPackage[] pkgs = {}; - try { - pkgs = yield user_daemon.get_explicitly_installed_pkgs (); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } - return pkgs; - } - - public async AlpmPackage[] get_foreign_pkgs () { - AlpmPackage[] pkgs = {}; - try { - pkgs = yield user_daemon.get_foreign_pkgs (); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } - return pkgs; - } - - public async AlpmPackage[] get_orphans () { - AlpmPackage[] pkgs = {}; - try { - pkgs = yield user_daemon.get_orphans (); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } - return pkgs; - } - - public AlpmPackage get_sync_pkg (string pkgname) { - try { - return user_daemon.get_sync_pkg (pkgname); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - return AlpmPackage () { - name = "", - version = "", - desc = "", - repo = "" - }; - } - } - - public AlpmPackage find_sync_satisfier (string depstring) { - try { - return user_daemon.find_sync_satisfier (depstring); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - return AlpmPackage () { - name = "", - version = "", - desc = "", - repo = "" - }; - } - } - - public async AlpmPackage[] search_pkgs (string search_string) { - AlpmPackage[] pkgs = {}; - try { - pkgs = yield user_daemon.search_pkgs (search_string); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } - return pkgs; - } - - public async AURPackage[] search_in_aur (string search_string) { - AURPackage[] pkgs = {}; - try { - pkgs = yield user_daemon.search_in_aur (search_string); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } - return pkgs; - } - - public async AlpmPackage[] get_category_pkgs (string category) { - AlpmPackage[] pkgs = {}; - try { - pkgs = yield user_daemon.get_category_pkgs (category); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } - return pkgs; - } - - public string[] get_repos_names () { - string[] repos_names = {}; - try { - repos_names = user_daemon.get_repos_names (); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } - return repos_names; - } - - public async AlpmPackage[] get_repo_pkgs (string repo) { - AlpmPackage[] pkgs = {}; - try { - pkgs = yield user_daemon.get_repo_pkgs (repo); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } - return pkgs; - } - - public string[] get_groups_names () { - string[] groups_names = {}; - try { - groups_names = user_daemon.get_groups_names (); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } - return groups_names; - } - - public async AlpmPackage[] get_group_pkgs (string group_name) { - AlpmPackage[] pkgs = {}; - try { - pkgs = yield user_daemon.get_group_pkgs (group_name); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } - return pkgs; - } - - public string[] get_pkg_uninstalled_optdeps (string pkgname) { - string[] optdeps = {}; - try { - optdeps = user_daemon.get_pkg_uninstalled_optdeps (pkgname); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } - return optdeps; - } - - public AlpmPackageDetails get_pkg_details (string pkgname, string app_name) { - try { - return user_daemon.get_pkg_details (pkgname, app_name); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - return AlpmPackageDetails () { - name = "", - version = "", - desc = "", - repo = "", - url = "", - packager = "", - builddate = "", - installdate = "", - reason = "", - has_signature = "" - }; - } - } - - public string[] get_pkg_files (string pkgname) { - try { - return user_daemon.get_pkg_files (pkgname); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - return {}; - } - } - - public async AURPackageDetails get_aur_details (string pkgname) { - var pkg = AURPackageDetails () { - name = "", - version = "", - desc = "", - packagebase = "", - url = "", - maintainer = "" - }; - try { - pkg = yield user_daemon.get_aur_details (pkgname); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } - return pkg; - } - - public void start_get_updates () { - user_daemon.emit_get_updates_progress.connect (on_emit_get_updates_progress); - user_daemon.get_updates_finished.connect (on_get_updates_finished); - try { - user_daemon.start_get_updates (pamac_config.enable_aur && pamac_config.check_aur_updates, false); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - success = false; - finish_transaction (); - } - } - void start_get_updates_for_sysupgrade () { - system_daemon.get_updates_finished.connect (on_get_updates_for_sysupgrade_finished); try { - system_daemon.start_get_updates (pamac_config.enable_aur && pamac_config.check_aur_updates); + system_daemon.start_get_updates (database.config.check_aur_updates); + system_daemon.get_updates_finished.connect (on_get_updates_for_sysupgrade_finished); } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - success = false; - finish_transaction (); + stderr.printf ("start_get_updates: %s\n", e.message); + finish_transaction (false); } } - void sysupgrade_real (bool enable_downgrade) { - progress_box.progressbar.fraction = 0; - string[] temporary_ignorepkgs_ = {}; - string[] to_build_ = {}; - foreach (unowned string name in to_build) { - to_build_ += name; - } - foreach (unowned string pkgname in temporary_ignorepkgs) { - temporary_ignorepkgs_ += pkgname; - } + void sysupgrade_real (string[] to_build) { connecting_system_daemon (); connecting_dbus_signals (); try { // this will respond with trans_prepare_finished signal - system_daemon.start_sysupgrade_prepare (enable_downgrade, temporary_ignorepkgs_, to_build_, {}); + system_daemon.start_sysupgrade_prepare (enable_downgrade, temporary_ignorepkgs, to_build, overwrite_files); } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - success = false; - finish_transaction (); + stderr.printf ("start_sysupgrade_prepare: %s\n", e.message); + finish_transaction (false); } } - public void sysupgrade (bool enable_downgrade) { + public void start_sysupgrade (bool enable_downgrade, string[] temporary_ignorepkgs, string[] overwrite_files) { this.enable_downgrade = enable_downgrade; - string action = dgettext (null, "Starting full system upgrade") + "..."; - reset_progress_box (action); + this.temporary_ignorepkgs = temporary_ignorepkgs; + this.overwrite_files = overwrite_files; + sysupgrading = true; + emit_action (dgettext (null, "Starting full system upgrade") + "..."); start_get_updates_for_sysupgrade (); } - void on_emit_get_updates_progress (uint percent) { - get_updates_progress (percent); - } - - void on_get_updates_finished (Updates updates) { - user_daemon.emit_get_updates_progress.disconnect (on_emit_get_updates_progress); - user_daemon.get_updates_finished.disconnect (on_get_updates_finished); - get_updates_finished (updates); - } - - void on_get_updates_for_sysupgrade_finished (Updates updates) { + void on_get_updates_for_sysupgrade_finished (UpdatesPriv updates) { system_daemon.get_updates_finished.disconnect (on_get_updates_for_sysupgrade_finished); // get syncfirst updates - if (updates.is_syncfirst) { - clear_lists (); + if (updates.syncfirst) { sysupgrade_after_trans = true; - no_confirm_commit = true; + to_install_first = {}; foreach (unowned AlpmPackage infos in updates.repos_updates) { - to_install.add (infos.name); + to_install_first += infos.name; + } + string[] to_build = {}; + foreach (unowned AURPackage infos in updates.aur_updates) { + if (!(infos.name in temporary_ignorepkgs)) { + to_build += infos.name; + } } // run as a standard transaction - run (); + sysupgrade_real (to_build); } else { if (updates.aur_updates.length != 0) { - clear_lists (); + string[] to_build = {}; foreach (unowned AURPackage infos in updates.aur_updates) { if (!(infos.name in temporary_ignorepkgs)) { - to_build.add (infos.name); + to_build += infos.name; } } if (updates.repos_updates.length != 0) { - sysupgrade_real (enable_downgrade); + sysupgrade_real (to_build); } else { // only aur updates // run as a standard transaction - run (); + start ({}, {}, {}, to_build, overwrite_files); } } else { if (updates.repos_updates.length != 0) { - sysupgrade_real (enable_downgrade); + sysupgrade_real ({}); } else { - finish_transaction (); - stop_progressbar_pulse (); + finish_transaction (true); } } } } - public void clear_lists () { - to_install.remove_all (); - to_remove.remove_all (); - to_build.remove_all (); - to_load.remove_all (); - } - - void clear_previous_lists () { - previous_to_install.remove_all (); - previous_to_remove.remove_all (); - } - - void start_trans_prepare (int transflags, string[] to_install, string[] to_remove, string[] to_load, string[] to_build) { + void start_trans_prepare (string[] to_install, string[] to_remove, string[] to_load, string[] to_build) { try { - system_daemon.start_trans_prepare (transflags, to_install, to_remove, to_load, to_build, {}); + system_daemon.start_trans_prepare (flags, to_install, to_remove, to_load, to_build, overwrite_files); } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - stop_progressbar_pulse (); - success = false; - finish_transaction (); + stderr.printf ("start_trans_prepare: %s\n", e.message); + finish_transaction (false); } } - public void run () { - string action = dgettext (null, "Preparing") + "..."; - reset_progress_box (action); - start_progressbar_pulse (); - string[] to_install_ = {}; - string[] to_remove_ = {}; - string[] to_load_ = {}; - string[] to_build_ = {}; - foreach (unowned string name in to_install) { - to_install_ += name; - } - foreach (unowned string name in to_remove) { - to_remove_ += name; - } - foreach (unowned string path in to_load) { - to_load_ += path; - } - foreach (unowned string name in to_build) { - to_build_ += name; - } + public void start (string[] to_install, string[] to_remove, string[] to_load, string[] to_build, string[] overwrite_files) { + this.overwrite_files = overwrite_files; + emit_action (dgettext (null, "Preparing") + "..."); connecting_system_daemon (); connecting_dbus_signals (); - start_trans_prepare (flags, to_install_, to_remove_, to_load_, to_build_); + start_trans_prepare (to_install, to_remove, to_load, to_build); } - void choose_provider (string depend, string[] providers) { - var choose_provider_dialog = new ChooseProviderDialog (application_window); - choose_provider_dialog.title = dgettext (null, "Choose a provider for %s").printf (depend); - unowned Gtk.Box box = choose_provider_dialog.get_content_area (); - Gtk.RadioButton? last_radiobutton = null; - Gtk.RadioButton? first_radiobutton = null; - foreach (unowned string provider in providers) { - var radiobutton = new Gtk.RadioButton.with_label_from_widget (last_radiobutton, provider); - radiobutton.visible = true; - // active first provider - if (last_radiobutton == null) { - radiobutton.active = true; - first_radiobutton = radiobutton; - } - last_radiobutton = radiobutton; - box.add (radiobutton); - } - choose_provider_dialog.run (); - // get active provider - int index = 0; - // list is given in reverse order so reverse it ! - SList<unowned Gtk.RadioButton> list = last_radiobutton.get_group ().copy (); - list.reverse (); - foreach (var radiobutton in list) { - if (radiobutton.active) { - try { - system_daemon.choose_provider (index); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } + void start_commit () { + if (to_install_first.length > 0) { + release (); + to_build_queue.clear (); + no_confirm_commit = true; + start_trans_prepare (to_install_first, {}, {}, {}); + to_install_first = {}; + } else { + try { + system_daemon.start_trans_commit (); + } catch (Error e) { + stderr.printf ("start_trans_commit: %s\n", e.message); + finish_transaction (false); } - index++; - } - choose_provider_dialog.destroy (); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); } } - Type set_transaction_sum () { - // return 0 if transaction_sum is empty, 2, if there are only aur updates, 1 otherwise - Type type = 0; - uint64 dsize = 0; - transaction_summary.remove_all (); - var summary = TransactionSummary (); - transaction_sum_dialog.sum_list.clear (); + public virtual async int run_cmd_line (string[] args, string working_directory, Cancellable cancellable) { + int status = 1; + var launcher = new SubprocessLauncher (SubprocessFlags.STDOUT_PIPE | SubprocessFlags.STDERR_MERGE); + launcher.set_cwd (working_directory); + launcher.set_environ (Environ.get ()); try { - summary = system_daemon.get_transaction_summary (); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } - var iter = Gtk.TreeIter (); - if (summary.to_remove.length > 0) { - type |= Type.STANDARD; - foreach (unowned AlpmPackage infos in summary.to_remove) { - transaction_summary.add (infos.name); - transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, - 1, infos.name, - 2, infos.version); - } - Gtk.TreePath path = transaction_sum_dialog.sum_list.get_path (iter); - int pos = (path.get_indices ()[0]) - (summary.to_remove.length - 1); - transaction_sum_dialog.sum_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); - transaction_sum_dialog.sum_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "To remove") + ":")); - } - if (summary.aur_conflicts_to_remove.length > 0) { - // do not add type enum because it is just infos - foreach (unowned AlpmPackage infos in summary.aur_conflicts_to_remove) { - transaction_summary.add (infos.name); - transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, - 1, infos.name, - 2, infos.version); - } - Gtk.TreePath path = transaction_sum_dialog.sum_list.get_path (iter); - int pos = (path.get_indices ()[0]) - (summary.aur_conflicts_to_remove.length - 1); - transaction_sum_dialog.sum_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); - transaction_sum_dialog.sum_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "To remove") + ":")); - } - if (summary.to_downgrade.length > 0) { - type |= Type.STANDARD; - foreach (unowned AlpmPackage infos in summary.to_downgrade) { - dsize += infos.download_size; - transaction_summary.add (infos.name); - transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, - 1, infos.name, - 2, infos.version, - 3, "(%s)".printf (infos.installed_version)); - } - Gtk.TreePath path = transaction_sum_dialog.sum_list.get_path (iter); - int pos = (path.get_indices ()[0]) - (summary.to_downgrade.length - 1); - transaction_sum_dialog.sum_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); - transaction_sum_dialog.sum_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "To downgrade") + ":")); - } - if (summary.to_build.length > 0) { - type |= Type.BUILD; - // populate build queue - foreach (unowned string name in summary.aur_pkgbases_to_build) { - to_build_queue.push_tail (name); - } - aur_pkgs_to_install = {}; - foreach (unowned AURPackage infos in summary.to_build) { - aur_pkgs_to_install += infos.name; - transaction_summary.add (infos.name); - transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, - 1, infos.name, - 2, infos.version); - } - Gtk.TreePath path = transaction_sum_dialog.sum_list.get_path (iter); - int pos = (path.get_indices ()[0]) - (summary.to_build.length - 1); - transaction_sum_dialog.sum_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); - transaction_sum_dialog.sum_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "To build") + ":")); - } - if (summary.to_install.length > 0) { - type |= Type.STANDARD; - foreach (unowned AlpmPackage infos in summary.to_install) { - dsize += infos.download_size; - transaction_summary.add (infos.name); - transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, - 1, infos.name, - 2, infos.version); - } - Gtk.TreePath path = transaction_sum_dialog.sum_list.get_path (iter); - int pos = (path.get_indices ()[0]) - (summary.to_install.length - 1); - transaction_sum_dialog.sum_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); - transaction_sum_dialog.sum_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "To install") + ":")); - } - if (summary.to_reinstall.length > 0) { - type |= Type.STANDARD; - foreach (unowned AlpmPackage infos in summary.to_reinstall) { - dsize += infos.download_size; - transaction_summary.add (infos.name); - transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, - 1, infos.name, - 2, infos.version); + Subprocess process = launcher.spawnv (args); + var dis = new DataInputStream (process.get_stdout_pipe ()); + string? line; + while ((line = yield dis.read_line_async (Priority.DEFAULT, cancellable)) != null) { + emit_script_output (line); } - Gtk.TreePath path = transaction_sum_dialog.sum_list.get_path (iter); - int pos = (path.get_indices ()[0]) - (summary.to_reinstall.length - 1); - transaction_sum_dialog.sum_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); - transaction_sum_dialog.sum_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "To reinstall") + ":")); - } - if (summary.to_upgrade.length > 0) { - type |= Type.UPDATE; - if (mode == Mode.INSTALLER) { - foreach (unowned AlpmPackage infos in summary.to_upgrade) { - dsize += infos.download_size; - transaction_summary.add (infos.name); - transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, - 1, infos.name, - 2, infos.version, - 3, "(%s)".printf (infos.installed_version)); + try { + yield process.wait_async (cancellable); + if (process.get_if_exited ()) { + status = process.get_exit_status (); } - Gtk.TreePath path = transaction_sum_dialog.sum_list.get_path (iter); - int pos = (path.get_indices ()[0]) - (summary.to_upgrade.length - 1); - transaction_sum_dialog.sum_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos)); - transaction_sum_dialog.sum_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "To upgrade") + ":")); + } catch (Error e) { + // cancelled + process.send_signal (Posix.Signal.INT); + process.send_signal (Posix.Signal.KILL); } - } - if (dsize == 0) { - transaction_sum_dialog.top_label.visible = false; - } else { - transaction_sum_dialog.top_label.set_markup ("<b>%s: %s</b>".printf (dgettext (null, "Total download size"), format_size (dsize))); - transaction_sum_dialog.top_label.visible = true; - } - return type; - } - - void start_commit () { - try { - system_daemon.start_trans_commit (); } catch (Error e) { stderr.printf ("Error: %s\n", e.message); - success = false; - finish_transaction (); } + return status; } - async void build_aur_packages () { + async void build_next_aur_package () { string pkgname = to_build_queue.pop_head (); - string action = dgettext (null, "Building %s").printf (pkgname) + "..."; - reset_progress_box (action); + emit_action (dgettext (null, "Building %s").printf (pkgname) + "..."); build_cancellable.reset (); - start_progressbar_pulse (); important_details_outpout (false); - to_build.remove_all (); string [] built_pkgs = {}; int status = 1; string builddir; - if (aur_build_dir == "/tmp") { + if (database.config.aur_build_dir == "/tmp") { builddir = "/tmp/pamac-build-%s".printf (Environment.get_user_name ()); } else { - builddir = aur_build_dir; + builddir = database.config.aur_build_dir; } - status = yield spawn_in_term ({"mkdir", "-p", builddir}); + status = yield run_cmd_line ({"mkdir", "-p", builddir}, "/", build_cancellable); if (status == 0) { - status = yield spawn_in_term ({"rm", "-rf", pkgname}, builddir); + status = yield run_cmd_line ({"rm", "-rf", pkgname}, builddir, build_cancellable); if (!build_cancellable.is_cancelled ()) { if (status == 0) { building = true; start_building (); - status = yield spawn_in_term ({"git", "clone", "https://aur.archlinux.org/%s.git".printf (pkgname)}, builddir); + status = yield run_cmd_line ({"git", "clone", "https://aur.archlinux.org/%s.git".printf (pkgname)}, builddir, build_cancellable); if (status == 0) { string pkgdir = "%s/%s".printf (builddir, pkgname); - status = yield spawn_in_term ({"makepkg", "-cf"}, pkgdir); + status = yield run_cmd_line ({"makepkg", "-cf"}, pkgdir, build_cancellable); building = false; if (status == 0) { // get built pkgs path @@ -1187,16 +481,12 @@ namespace Pamac { building = false; if (status == 0 && built_pkgs.length > 0) { no_confirm_commit = true; - show_in_term (""); - stop_progressbar_pulse (); - start_trans_prepare (flags, {}, {}, built_pkgs, {}); + emit_script_output (""); + start_trans_prepare ({}, {}, built_pkgs, {}); } else { important_details_outpout (true); - to_load.remove_all (); to_build_queue.clear (); - stop_progressbar_pulse (); - success = false; - finish_transaction (); + finish_transaction (false); } } @@ -1207,117 +497,104 @@ namespace Pamac { try { system_daemon.trans_cancel (); } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); + stderr.printf ("trans_cancel: %s\n", e.message); } } - show_in_term ("\n" + dgettext (null, "Transaction cancelled") + ".\n"); - progress_box.action_label.label = ""; - warning_textbuffer = new StringBuilder (); + emit_script_output (""); + emit_action (dgettext (null, "Transaction cancelled") + "."); + emit_script_output (""); } public void release () { try { system_daemon.trans_release (); } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); + stderr.printf ("trans_release: %s\n", e.message); } - warning_textbuffer = new StringBuilder (); } public void stop_daemon () { try { - user_daemon.quit (); if (system_daemon != null) { system_daemon.quit (); } } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); + stderr.printf ("quit: %s\n", e.message); } } void on_emit_event (uint primary_event, uint secondary_event, string[] details) { - string? action = null; - string? detailed_action = null; switch (primary_event) { case 1: //Alpm.Event.Type.CHECKDEPS_START - action = dgettext (null, "Checking dependencies") + "..."; + emit_action (dgettext (null, "Checking dependencies") + "..."); break; case 3: //Alpm.Event.Type.FILECONFLICTS_START - action = dgettext (null, "Checking file conflicts") + "..."; + current_action = dgettext (null, "Checking file conflicts") + "..."; break; case 5: //Alpm.Event.Type.RESOLVEDEPS_START - action = dgettext (null, "Resolving dependencies") + "..."; + emit_action (dgettext (null, "Resolving dependencies") + "..."); break; case 7: //Alpm.Event.Type.INTERCONFLICTS_START - action = dgettext (null, "Checking inter-conflicts") + "..."; + emit_action (dgettext (null, "Checking inter-conflicts") + "..."); break; case 11: //Alpm.Event.Type.PACKAGE_OPERATION_START switch (secondary_event) { // special case handle differently case 1: //Alpm.Package.Operation.INSTALL - previous_filename = details[0]; - string msg = dgettext (null, "Installing %s").printf (details[0]) + "..."; - progress_box.action_label.label = msg; - show_in_term (dgettext (null, "Installing %s").printf ("%s (%s)".printf (details[0], details[1])) + "..."); + current_filename = details[0]; + current_action = dgettext (null, "Installing %s").printf ("%s (%s)".printf (details[0], details[1])) + "..."; break; case 2: //Alpm.Package.Operation.UPGRADE - previous_filename = details[0]; - string msg = dgettext (null, "Upgrading %s").printf (details[0]) + "..."; - progress_box.action_label.label = msg; - show_in_term (dgettext (null, "Upgrading %s").printf ("%s (%s -> %s)".printf (details[0], details[1], details[2])) + "..."); + current_filename = details[0]; + current_action = dgettext (null, "Upgrading %s").printf ("%s (%s -> %s)".printf (details[0], details[1], details[2])) + "..."; break; case 3: //Alpm.Package.Operation.REINSTALL - previous_filename = details[0]; - string msg = dgettext (null, "Reinstalling %s").printf (details[0]) + "..."; - progress_box.action_label.label = msg; - show_in_term (dgettext (null, "Reinstalling %s").printf ("%s (%s)".printf (details[0], details[1])) + "..."); + current_filename = details[0]; + current_action = dgettext (null, "Reinstalling %s").printf ("%s (%s)".printf (details[0], details[1])) + "..."; break; case 4: //Alpm.Package.Operation.DOWNGRADE - previous_filename = details[0]; - string msg = dgettext (null, "Downgrading %s").printf (details[0]) + "..."; - progress_box.action_label.label = msg; - show_in_term (dgettext (null, "Downgrading %s").printf ("%s (%s -> %s)".printf (details[0], details[1], details[2])) + "..."); + current_filename = details[0]; + current_action = dgettext (null, "Downgrading %s").printf ("%s (%s -> %s)".printf (details[0], details[1], details[2])) + "..."; break; case 5: //Alpm.Package.Operation.REMOVE - previous_filename = details[0]; - string msg = dgettext (null, "Removing %s").printf (details[0]) + "..."; - progress_box.action_label.label = msg; - show_in_term (dgettext (null, "Removing %s").printf ("%s (%s)".printf (details[0], details[1])) + "..."); + current_filename = details[0]; + current_action = dgettext (null, "Removing %s").printf ("%s (%s)".printf (details[0], details[1])) + "..."; break; } break; case 13: //Alpm.Event.Type.INTEGRITY_START - action = dgettext (null, "Checking integrity") + "..."; + current_action = dgettext (null, "Checking integrity") + "..."; break; case 15: //Alpm.Event.Type.LOAD_START - action = dgettext (null, "Loading packages files") + "..."; + current_action = dgettext (null, "Loading packages files") + "..."; break; case 17: //Alpm.Event.Type.DELTA_INTEGRITY_START - action = dgettext (null, "Checking delta integrity") + "..."; + emit_action (dgettext (null, "Checking delta integrity") + "..."); break; case 19: //Alpm.Event.Type.DELTA_PATCHES_START - action = dgettext (null, "Applying deltas") + "..."; + emit_action (dgettext (null, "Applying deltas") + "..."); break; case 21: //Alpm.Event.Type.DELTA_PATCH_START - detailed_action = dgettext (null, "Generating %s with %s").printf (details[0], details[1]) + "..."; + emit_script_output (dgettext (null, "Generating %s with %s").printf (details[0], details[1]) + "..."); break; case 22: //Alpm.Event.Type.DELTA_PATCH_DONE - detailed_action = dgettext (null, "Generation succeeded") + "..."; + emit_script_output (dgettext (null, "Generation succeeded") + "."); break; case 23: //Alpm.Event.Type.DELTA_PATCH_FAILED - detailed_action = dgettext (null, "Generation failed") + "..."; + emit_script_output (dgettext (null, "Generation failed") + "."); break; case 24: //Alpm.Event.Type.SCRIPTLET_INFO // hooks output are also emitted as SCRIPTLET_INFO - if (previous_filename != "") { - progress_box.action_label.label = dgettext (null, "Configuring %s").printf (previous_filename) + "..."; + if (current_filename != "") { + emit_action (dgettext (null, "Configuring %s").printf (current_filename) + "..."); + current_filename = ""; } - detailed_action = details[0].replace ("\n", ""); + emit_script_output (details[0].replace ("\n", "")); important_details_outpout (false); break; case 25: //Alpm.Event.Type.RETRIEVE_START start_downloading (); - action = dgettext (null, "Downloading") + "..."; + emit_action (dgettext (null, "Downloading") + "..."); break; case 26: //Alpm.Event.Type.RETRIEVE_DONE case 27: //Alpm.Event.Type.RETRIEVE_FAILED @@ -1325,89 +602,89 @@ namespace Pamac { break; case 28: //Alpm.Event.Type.PKGDOWNLOAD_START // special case handle differently - show_in_term (dgettext (null, "Downloading %s").printf (details[0]) + "..."); string name_version_release = details[0].slice (0, details[0].last_index_of_char ('-')); string name_version = name_version_release.slice (0, name_version_release.last_index_of_char ('-')); string name = name_version.slice (0, name_version.last_index_of_char ('-')); - progress_box.action_label.label = dgettext (null, "Downloading %s").printf (name) + "..."; + string version_release = details[0].replace (name + "-", "").replace (".pkg.tar.xz", ""); + current_action = dgettext (null, "Downloading %s").printf ("%s (%s)".printf (name, version_release)) + "..."; break; case 31: //Alpm.Event.Type.DISKSPACE_START - action = dgettext (null, "Checking available disk space") + "..."; + current_action = dgettext (null, "Checking available disk space") + "..."; break; case 33: //Alpm.Event.Type.OPTDEP_REMOVAL - detailed_action = dgettext (null, "%s optionally requires %s").printf (details[0], details[1]); - warning_textbuffer.append (detailed_action + "\n"); + emit_warning (dgettext (null, "%s optionally requires %s").printf (details[0], details[1])); break; case 34: //Alpm.Event.Type.DATABASE_MISSING - detailed_action = dgettext (null, "Database file for %s does not exist").printf (details[0]); + emit_script_output (dgettext (null, "Database file for %s does not exist").printf (details[0]) + "."); break; case 35: //Alpm.Event.Type.KEYRING_START - action = dgettext (null, "Checking keyring") + "..."; + current_action = dgettext (null, "Checking keyring") + "..."; break; case 37: //Alpm.Event.Type.KEY_DOWNLOAD_START - action = dgettext (null, "Downloading required keys") + "..."; + emit_action (dgettext (null, "Downloading required keys") + "..."); break; case 39: //Alpm.Event.Type.PACNEW_CREATED - detailed_action = dgettext (null, "%s installed as %s.pacnew").printf (details[0], details[0]); + emit_script_output (dgettext (null, "%s installed as %s.pacnew").printf (details[0], details[0])+ "."); break; case 40: //Alpm.Event.Type.PACSAVE_CREATED - detailed_action = dgettext (null, "%s installed as %s.pacsave").printf (details[0], details[0]); + emit_script_output (dgettext (null, "%s installed as %s.pacsave").printf (details[0], details[0])+ "."); break; case 41: //Alpm.Event.Type.HOOK_START switch (secondary_event) { case 1: //Alpm.HookWhen.PRE_TRANSACTION - action = dgettext (null, "Running pre-transaction hooks") + "..."; + current_action = dgettext (null, "Running pre-transaction hooks") + "..."; break; case 2: //Alpm.HookWhen.POST_TRANSACTION - previous_filename = ""; - action = dgettext (null, "Running post-transaction hooks") + "..."; + current_filename = ""; + current_action = dgettext (null, "Running post-transaction hooks") + "..."; break; default: break; } break; case 43: // Alpm.Event.Type.HOOK_RUN_START - float fraction = (float) int.parse (details[2]) / int.parse (details[3]); - if (fraction != previous_percent) { - previous_percent = fraction; - progress_box.progressbar.fraction = fraction; + double progress = (double) int.parse (details[2]) / int.parse (details[3]); + string status = "%s/%s".printf (details[2], details[3]); + bool changed = false; + if (progress != current_progress) { + current_progress = progress; + changed = true; } - string textbar = "%s/%s".printf (details[2], details[3]); - if (textbar != previous_textbar) { - previous_textbar = textbar; - progress_box.progressbar.text = textbar; + if (status != current_status) { + current_status = status; + changed = true; } - if (details[1] != "") { - detailed_action = details[1]; - } else { - detailed_action = details[0]; + if (changed) { + if (details[1] != "") { + emit_hook_progress (current_action, details[1], current_status, current_progress); + } else { + emit_hook_progress (current_action, details[0], current_status, current_progress); + } } break; default: break; } - if (action != null) { - progress_box.action_label.label = action; - show_in_term (action); - } - if (detailed_action != null) { - show_in_term (detailed_action); - } } void on_emit_providers (string depend, string[] providers) { - choose_provider (depend, providers); + int index = choose_provider (depend, providers); + try { + system_daemon.choose_provider (index); + } catch (Error e) { + stderr.printf ("choose_provider: %s\n", e.message); + } } void on_emit_progress (uint progress, string pkgname, uint percent, uint n_targets, uint current_target) { - float fraction; + double fraction; switch (progress) { case 0: //Alpm.Progress.ADD_START case 1: //Alpm.Progress.UPGRADE_START case 2: //Alpm.Progress.DOWNGRADE_START case 3: //Alpm.Progress.REINSTALL_START case 4: //Alpm.Progress.REMOVE_START - fraction = ((float) (current_target - 1) / n_targets) + ((float) percent / (100 * n_targets)); + fraction = ((double) (current_target - 1) / n_targets) + ((double) percent / (100 * n_targets)); break; case 5: //Alpm.Progress.CONFLICTS_START case 6: //Alpm.Progress.DISKSPACE_START @@ -1415,29 +692,35 @@ namespace Pamac { case 8: //Alpm.Progress.LOAD_START case 9: //Alpm.Progress.KEYRING_START default: - fraction = (float) percent / 100; + fraction = (double) percent / 100; break; } - string textbar = "%lu/%lu".printf (current_target, n_targets); - if (textbar != previous_textbar) { - previous_textbar = textbar; - progress_box.progressbar.text = textbar; + string status = "%lu/%lu".printf (current_target, n_targets); + bool changed = false; + if (fraction != current_progress) { + current_progress = fraction; + changed = true; + } + if (status != current_status) { + current_status = status; + changed = true; } - if (fraction != previous_percent) { - previous_percent = fraction; - progress_box.progressbar.fraction = fraction; + if (changed) { + if (current_action != "") { + emit_action_progress (current_action, current_status, current_progress); + } } } void on_emit_download (string filename, uint64 xfered, uint64 total) { var text = new StringBuilder (); - float fraction; + double fraction; if (total_download > 0) { if (xfered == 0) { // start download pkg is handled by Alpm.Event.Type.PKGDOWNLOAD_START previous_xfered = 0; - fraction = previous_percent; - text.append (previous_textbar); + fraction = current_progress; + text.append (current_status); timer.start (); } else { if (timer.elapsed () > 0.1) { @@ -1446,7 +729,7 @@ namespace Pamac { } previous_xfered = xfered; uint64 downloaded_total = xfered + already_downloaded; - fraction = (float) downloaded_total / total_download; + fraction = (double) downloaded_total / total_download; if (fraction <= 1) { text.append ("%s/%s ".printf (format_size (xfered + already_downloaded), format_size (total_download))); uint64 remaining_seconds = 0; @@ -1467,7 +750,7 @@ namespace Pamac { text.append ("%s".printf (format_size (xfered + already_downloaded))); } if (xfered == total) { - previous_filename = ""; + current_filename = ""; already_downloaded += total; } else { timer.start (); @@ -1481,20 +764,19 @@ namespace Pamac { fraction = 0; timer.start (); if (filename.has_suffix (".db") || filename.has_suffix (".files")) { - string action = dgettext (null, "Refreshing %s").printf (filename) + "..."; - reset_progress_box (action); + current_action = dgettext (null, "Refreshing %s").printf (filename) + "..."; } } else if (xfered == total) { timer.stop (); fraction = 1; - previous_filename = ""; + current_filename = ""; } else { if (timer.elapsed () > 0.1) { download_rate = ((download_rate * rates_nb) + (uint64) ((xfered - previous_xfered) / timer.elapsed ())) / (rates_nb + 1); rates_nb++; } previous_xfered = xfered; - fraction = (float) xfered / total; + fraction = (double) xfered / total; if (fraction <= 1) { text.append ("%s/%s ".printf (format_size (xfered), format_size (total))); uint64 remaining_seconds = 0; @@ -1518,27 +800,25 @@ namespace Pamac { timer.start (); } } - if (fraction != previous_percent) { - previous_percent = fraction; - progress_box.progressbar.fraction = fraction; + if (fraction != current_progress) { + current_progress = fraction; } - if (text.str != previous_textbar) { - previous_textbar = text.str; - progress_box.progressbar.text = text.str; + if (text.str != current_status) { + current_status = text.str; } + emit_action_progress (current_action, current_status, current_progress); } void on_emit_totaldownload (uint64 total) { download_rate = 0; rates_nb = 0; - previous_percent = 0; - previous_textbar = ""; + current_progress = 0; + current_status = ""; total_download = total; // this is emitted at the end of the total download // with the value 0 so stop our timer if (total == 0) { timer.stop (); - progress_box.progressbar.text = ""; } } @@ -1546,343 +826,198 @@ namespace Pamac { // msg ends with \n string? line = null; if (level == 1) { //Alpm.LogLevel.ERROR - if (previous_filename != "") { - line = dgettext (null, "Error") + ": " + previous_filename + ": " + msg; + if (current_filename != "") { + line = dgettext (null, "Error") + ": " + current_filename + ": " + msg; } else { line = dgettext (null, "Error") + ": " + msg; } important_details_outpout (false); + emit_error (line.replace ("\n", ""), {}); } else if (level == (1 << 1)) { //Alpm.LogLevel.WARNING // do not show warning when manjaro-system remove db.lck - if (previous_filename != "manjaro-system") { - if (previous_filename != "") { - line = dgettext (null, "Warning") + ": " + previous_filename + ": " + msg; + if (current_filename != "manjaro-system") { + if (current_filename != "") { + line = dgettext (null, "Warning") + ": " + current_filename + ": " + msg; } else { line = dgettext (null, "Warning") + ": " + msg; } - warning_textbuffer.append (msg); - } - } - if (line != null) { - show_in_term (line.replace ("\n", "")); - } - } - - void show_warnings (bool block = true) { - if (warning_textbuffer.len > 0) { - var flags = Gtk.DialogFlags.MODAL; - int use_header_bar; - Gtk.Settings.get_default ().get ("gtk-dialogs-use-header", out use_header_bar); - if (use_header_bar == 1) { - flags |= Gtk.DialogFlags.USE_HEADER_BAR; + emit_warning (line.replace ("\n", "")); } - var dialog = new Gtk.Dialog.with_buttons (dgettext (null, "Warning"), - application_window, - flags); - dialog.border_width = 6; - dialog.icon_name = "system-software-install"; - dialog.deletable = false; - unowned Gtk.Widget widget = dialog.add_button (dgettext (null, "_Close"), Gtk.ResponseType.CLOSE); - widget.can_focus = true; - widget.has_focus = true; - widget.can_default = true; - widget.has_default = true; - var scrolledwindow = new Gtk.ScrolledWindow (null, null); - var label = new Gtk.Label (warning_textbuffer.str); - label.selectable = true; - label.margin = 12; - scrolledwindow.visible = true; - label.visible = true; - scrolledwindow.add (label); - scrolledwindow.expand = true; - unowned Gtk.Box box = dialog.get_content_area (); - box.add (scrolledwindow); - dialog.default_width = 600; - dialog.default_height = 300; - if (block) { - dialog.run (); - dialog.destroy (); - } else { - dialog.show (); - dialog.response.connect (() => { - dialog.destroy (); - }); - } - warning_textbuffer = new StringBuilder (); } } - public void display_error (string message, string[] details) { - var flags = Gtk.DialogFlags.MODAL; - int use_header_bar; - Gtk.Settings.get_default ().get ("gtk-dialogs-use-header", out use_header_bar); - if (use_header_bar == 1) { - flags |= Gtk.DialogFlags.USE_HEADER_BAR; - } - var dialog = new Gtk.Dialog.with_buttons (message, - application_window, - flags); - dialog.border_width = 6; - dialog.icon_name = "system-software-install"; - var textbuffer = new StringBuilder (); - if (details.length != 0) { - show_in_term (message + ":"); - foreach (unowned string detail in details) { - show_in_term (detail); - textbuffer.append (detail + "\n"); - } - } else { - show_in_term (message); - textbuffer.append (message); - } - dialog.deletable = false; - unowned Gtk.Widget widget = dialog.add_button (dgettext (null, "_Close"), Gtk.ResponseType.CLOSE); - widget.can_focus = true; - widget.has_focus = true; - widget.can_default = true; - widget.has_default = true; - var scrolledwindow = new Gtk.ScrolledWindow (null, null); - var label = new Gtk.Label (textbuffer.str); - label.selectable = true; - label.margin = 12; - scrolledwindow.visible = true; - label.visible = true; - scrolledwindow.add (label); - scrolledwindow.expand = true; - unowned Gtk.Box box = dialog.get_content_area (); - box.add (scrolledwindow); - dialog.default_width = 600; - dialog.default_height = 300; - dialog.show (); - dialog.response.connect (() => { - dialog.destroy (); - }); - Timeout.add (1000, () => { - try { - var notification = new Notify.Notification (dgettext (null, "Package Manager"), - message, - "system-software-update"); - notification.show (); - } catch (Error e) { - stderr.printf ("Notify Error: %s", e.message); - } - return false; - }); - } - void handle_error (ErrorInfos error) { if (error.message != "") { - reset_progress_box (""); - display_error (error.message, error.details); + emit_error (error.message, error.details); } - finish_transaction (); + finish_transaction (false); } - void finish_transaction () { + void finish_transaction (bool success) { disconnecting_dbus_signals (); - transaction_summary.remove_all (); - reset_progress_box (""); - if (success) { - try { - var notification = new Notify.Notification (dgettext (null, "Package Manager"), - dgettext (null, "Transaction successfully finished"), - "system-software-update"); - notification.show (); - } catch (Error e) { - stderr.printf ("Notify Error: %s", e.message); - } + database.refresh (); + if (sysupgrading) { + sysupgrade_finished (success); + sysupgrading = false; + } else { + finished (success); } - finished (success); - success = false; } void on_refresh_finished (bool success) { - stop_progressbar_pulse (); - this.success = success; - if (success) { - finished (success); - reset_progress_box (""); - success = false; - } else { - handle_error (get_current_error ()); + stop_downloading (); + if (!success) { + var error = get_current_error (); + if (error.message != "") { + emit_error (error.message, error.details); + } } - previous_filename = ""; + current_filename = ""; disconnecting_dbus_signals (); system_daemon.refresh_finished.disconnect (on_refresh_finished); + database.refresh (); + refresh_finished (success); } void on_trans_prepare_finished (bool success) { - stop_progressbar_pulse (); - this.success = success; if (success) { - show_warnings (); - Type type = set_transaction_sum (); - if (mode != Mode.INSTALLER && (no_confirm_commit || type == Type.UPDATE)) { - // no_confirm_commit or only updates - to_install.remove_all (); + var summary = TransactionSummary (); + try { + summary = system_daemon.get_transaction_summary (); + } catch (Error e) { + stderr.printf ("get_transaction_summary: %s\n", e.message); + } + Type type = 0; + if ((summary.to_install.length + + summary.to_downgrade.length + + summary.to_reinstall.length) > 0) { + type |= Type.INSTALL; + } + if (summary.to_remove.length > 0) { + type |= Type.REMOVE; + } + if (summary.to_upgrade.length > 0) { + type |= Type.UPDATE; + } + if (summary.to_build.length > 0) { + type |= Type.BUILD; + // populate build queue + foreach (unowned string name in summary.aur_pkgbases_to_build) { + to_build_queue.push_tail (name); + } + aur_pkgs_to_install = {}; + foreach (unowned AURPackage infos in summary.to_build) { + aur_pkgs_to_install += infos.name; + } + } + if (no_confirm_commit + || (no_confirm_upgrade && ((type & Type.REMOVE) == 0))) { start_commit (); } else if (type != 0) { - if (transaction_sum_dialog.run () == Gtk.ResponseType.OK) { - transaction_sum_dialog.hide (); - while (Gtk.events_pending ()) { - Gtk.main_iteration (); - } + if (ask_confirmation (summary)) { if (type == Type.BUILD) { // there only AUR packages to build release (); on_trans_commit_finished (true); } else { - // backup to_install and to_remove - foreach (unowned string name in to_install) { - previous_to_install.add (name); - } - foreach (unowned string name in to_remove) { - previous_to_remove.add (name); - } - to_install.remove_all (); - to_remove.remove_all (); start_commit (); } } else { - transaction_sum_dialog.hide (); - unowned string action = dgettext (null, "Transaction cancelled"); - show_in_term (action + ".\n"); - progress_box.action_label.label = action; + emit_action (dgettext (null, "Transaction cancelled") + "."); release (); - transaction_summary.remove_all (); to_build_queue.clear (); sysupgrade_after_trans = false; - this.success = false; - finish_transaction (); + finish_transaction (false); } } else { //var err = ErrorInfos (); //err.message = dgettext (null, "Nothing to do") + "\n"; - show_in_term (dgettext (null, "Nothing to do") + ".\n"); + emit_action (dgettext (null, "Nothing to do") + "."); release (); - clear_lists (); - finish_transaction (); + finish_transaction (true); //handle_error (err); } } else { - to_load.remove_all (); - warning_textbuffer = new StringBuilder (); handle_error (get_current_error ()); } } void on_trans_commit_finished (bool success) { - this.success = success; - // needed before build_aur_packages and remove_makedeps + // needed before build_aur_packages no_confirm_commit = false; if (success) { - show_warnings (false); - to_load.remove_all (); if (to_build_queue.get_length () != 0) { - show_in_term (""); - clear_previous_lists (); + emit_script_output (""); check_authorization.begin ((obj, res) => { bool authorized = check_authorization.end (res); if (authorized) { - build_aur_packages.begin (); + build_next_aur_package.begin (); } else { to_build_queue.clear (); on_trans_commit_finished (false); } }); } else { - clear_previous_lists (); if (sysupgrade_after_trans) { sysupgrade_after_trans = false; + no_confirm_commit = true; disconnecting_dbus_signals (); - sysupgrade (false); + start_sysupgrade (enable_downgrade, temporary_ignorepkgs, {}); } else { - unowned string action = dgettext (null, "Transaction successfully finished"); - show_in_term (action + ".\n"); - progress_box.action_label.label = action; - finish_transaction (); + emit_action (dgettext (null, "Transaction successfully finished") + "."); + finish_transaction (true); } } } else { - // if it is an authentication or a download error, database was not modified var err = get_current_error (); - if (err.message == dgettext (null, "Authentication failed") - || err.no == 54) { //Alpm.Errno.EXTERNAL_DOWNLOAD - // recover old pkgnames - foreach (unowned string name in previous_to_install) { - to_install.add (name); - } - foreach (unowned string name in previous_to_remove) { - to_remove.add (name); - } - } else { - to_load.remove_all (); - } - clear_previous_lists (); to_build_queue.clear (); - warning_textbuffer = new StringBuilder (); handle_error (err); } total_download = 0; already_downloaded = 0; - previous_filename = ""; + current_filename = ""; } void on_set_pkgreason_finished () { system_daemon.set_pkgreason_finished.disconnect (on_set_pkgreason_finished); + database.refresh (); set_pkgreason_finished (); } void on_write_pamac_config_finished (bool recurse, uint64 refresh_period, bool no_update_hide_icon, - bool enable_aur, string aur_build_dir, bool check_aur_updates) { + bool enable_aur, string aur_build_dir, bool check_aur_updates, + bool download_updates) { system_daemon.write_pamac_config_finished.disconnect (on_write_pamac_config_finished); - pamac_config.reload (); - flags = (1 << 4); //Alpm.TransFlag.CASCADE - if (pamac_config.recurse) { - flags |= (1 << 5); //Alpm.TransFlag.RECURSE - } + database.config.reload (); write_pamac_config_finished (recurse, refresh_period, no_update_hide_icon, enable_aur, aur_build_dir, check_aur_updates, download_updates); } void on_write_alpm_config_finished (bool checkspace) { - refresh_handle (); system_daemon.write_alpm_config_finished.disconnect (on_write_alpm_config_finished); + database.refresh (); write_alpm_config_finished (checkspace); } void on_generate_mirrors_list_data (string line) { - show_in_term (line); + emit_script_output (line); } void on_generate_mirrors_list_finished () { - refresh_handle (); system_daemon.generate_mirrors_list_data.disconnect (on_generate_mirrors_list_data); system_daemon.generate_mirrors_list_finished.disconnect (on_generate_mirrors_list_finished); - reset_progress_box (""); generate_mirrors_list_finished (); } - void connecting_user_daemon () { - if (user_daemon == null) { - try { - user_daemon = Bus.get_proxy_sync (BusType.SESSION, "org.manjaro.pamac.user", "/org/manjaro/pamac/user"); - user_daemon.enable_appstream (); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } - } - } - void connecting_system_daemon () { if (system_daemon == null) { try { system_daemon = Bus.get_proxy_sync (BusType.SYSTEM, "org.manjaro.pamac.system", "/org/manjaro/pamac/system"); // Set environment variables - system_daemon.set_environment_variables (pamac_config.environment_variables); + system_daemon.set_environment_variables (database.config.environment_variables); } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); + stderr.printf ("set_environment_variables: %s\n", e.message); } } } diff --git a/src/tray.vala b/src/tray.vala index 42bc10c9..61513b88 100644 --- a/src/tray.vala +++ b/src/tray.vala @@ -86,7 +86,7 @@ namespace Pamac { try { system_daemon = Bus.get_proxy_sync (BusType.SYSTEM, "org.manjaro.pamac.system", "/org/manjaro/pamac/system"); // Set environment variables - var pamac_config = new Pamac.Config ("/etc/pamac.conf"); + var pamac_config = new Config ("/etc/pamac.conf"); system_daemon.set_environment_variables (pamac_config.environment_variables); system_daemon.download_updates_finished.connect (on_download_updates_finished); } catch (Error e) { @@ -150,7 +150,7 @@ namespace Pamac { public abstract void set_icon_visible (bool visible); bool check_updates () { - var pamac_config = new Pamac.Config ("/etc/pamac.conf"); + var pamac_config = new Config ("/etc/pamac.conf"); if (pamac_config.refresh_period != 0) { try { user_daemon.start_get_updates (pamac_config.enable_aur && pamac_config.check_aur_updates, true); @@ -163,7 +163,7 @@ namespace Pamac { void on_get_updates_finished (Updates updates) { updates_nb = updates.repos_updates.length + updates.aur_updates.length; - var pamac_config = new Pamac.Config ("/etc/pamac.conf"); + var pamac_config = new Config ("/etc/pamac.conf"); if (updates_nb == 0) { set_icon (noupdate_icon_name); set_tooltip (noupdate_info); @@ -297,7 +297,7 @@ namespace Pamac { Intl.textdomain ("pamac"); Intl.setlocale (LocaleCategory.ALL, ""); - var pamac_config = new Pamac.Config ("/etc/pamac.conf"); + var pamac_config = new Config ("/etc/pamac.conf"); // if refresh period is 0, just return so tray will exit if (pamac_config.refresh_period == 0) { return; diff --git a/src/updates_priv.vala b/src/updates_priv.vala new file mode 100644 index 00000000..b3ce3bb5 --- /dev/null +++ b/src/updates_priv.vala @@ -0,0 +1,26 @@ +/* + * pamac-vala + * + * Copyright (C) 2018 Guillaume Benoit <guillaume@manjaro.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a get of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +namespace Pamac { + struct UpdatesPriv { + bool syncfirst; + AlpmPackage[] repos_updates; + AURPackage[] aur_updates; + } +} diff --git a/src/user_daemon.vala b/src/user_daemon.vala index 12ce4e7a..e0ad8ff5 100644 --- a/src/user_daemon.vala +++ b/src/user_daemon.vala @@ -420,11 +420,11 @@ namespace Pamac { return pkgs; } - public async AlpmPackage[] get_installed_pkgs () throws Error { - return get_installed_pkgs_sync (); + public async AlpmPackage[] get_installed_pkgs_async () throws Error { + return get_installed_pkgs (); } - public AlpmPackage[] get_installed_pkgs_sync () throws Error { + public AlpmPackage[] get_installed_pkgs () throws Error { AlpmPackage[] pkgs = {}; unowned Alpm.List<unowned Alpm.Package> pkgcache = alpm_handle.localdb.pkgcache; while (pkgcache != null) { @@ -437,7 +437,11 @@ namespace Pamac { return pkgs; } - public async AlpmPackage[] get_installed_apps () throws Error { + public async AlpmPackage[] get_installed_apps_async () throws Error { + return get_installed_apps (); + } + + public AlpmPackage[] get_installed_apps () throws Error { AlpmPackage[] pkgs = {}; app_store.get_apps ().foreach ((app) => { unowned string pkgname = app.get_pkgname_default (); @@ -463,7 +467,11 @@ namespace Pamac { return pkgs; } - public async AlpmPackage[] get_explicitly_installed_pkgs () throws Error { + public async AlpmPackage[] get_explicitly_installed_pkgs_async () throws Error { + return get_explicitly_installed_pkgs (); + } + + public AlpmPackage[] get_explicitly_installed_pkgs () throws Error { AlpmPackage[] pkgs = {}; unowned Alpm.List<unowned Alpm.Package> pkgcache = alpm_handle.localdb.pkgcache; while (pkgcache != null) { @@ -478,11 +486,11 @@ namespace Pamac { return pkgs; } - public async AlpmPackage[] get_foreign_pkgs () throws Error { - return get_foreign_pkgs_sync (); + public async AlpmPackage[] get_foreign_pkgs_async () throws Error { + return get_foreign_pkgs (); } - public AlpmPackage[] get_foreign_pkgs_sync () throws Error { + public AlpmPackage[] get_foreign_pkgs() throws Error { AlpmPackage[] pkgs = {}; unowned Alpm.List<unowned Alpm.Package> pkgcache = alpm_handle.localdb.pkgcache; while (pkgcache != null) { @@ -508,11 +516,11 @@ namespace Pamac { return pkgs; } - public async AlpmPackage[] get_orphans () throws Error { - return get_orphans_sync (); + public async AlpmPackage[] get_orphans_async () throws Error { + return get_orphans (); } - public AlpmPackage[] get_orphans_sync () throws Error { + public AlpmPackage[] get_orphans () throws Error { AlpmPackage[] pkgs = {}; unowned Alpm.List<unowned Alpm.Package> pkgcache = alpm_handle.localdb.pkgcache; while (pkgcache != null) { @@ -627,11 +635,11 @@ namespace Pamac { return result; } - public async AlpmPackage[] search_pkgs (string search_string) throws Error { - return search_pkgs_sync (search_string); + public async AlpmPackage[] search_pkgs_async (string search_string) throws Error { + return search_pkgs (search_string); } - public AlpmPackage[] search_pkgs_sync (string search_string) throws Error { + public AlpmPackage[] search_pkgs(string search_string) throws Error { AlpmPackage[] pkgs = {}; Alpm.List<unowned Alpm.Package> alpm_pkgs = search_all_dbs (search_string); unowned Alpm.List<unowned Alpm.Package> list = alpm_pkgs; @@ -661,7 +669,7 @@ namespace Pamac { }; } - public async AURPackage[] search_in_aur (string search_string) throws Error { + public async AURPackage[] search_in_aur_async (string search_string) throws Error { if (!aur_search_results.contains (search_string)) { Json.Array pkgs = yield AUR.search (search_string.split (" ")); aur_search_results.insert (search_string, pkgs); @@ -678,7 +686,7 @@ namespace Pamac { return result; } - public async AURPackageDetails get_aur_details (string pkgname) throws Error { + public async AURPackageDetails get_aur_details_async (string pkgname) throws Error { string name = ""; string version = ""; string desc = ""; @@ -834,11 +842,11 @@ namespace Pamac { return repos_names; } - public async AlpmPackage[] get_repo_pkgs (string repo) throws Error { - return get_repo_pkgs_sync (repo); + public async AlpmPackage[] get_repo_pkgs_async (string repo) throws Error { + return get_repo_pkgs (repo); } - public AlpmPackage[] get_repo_pkgs_sync (string repo) throws Error { + public AlpmPackage[] get_repo_pkgs (string repo) throws Error { AlpmPackage[] pkgs = {}; unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs; while (syncdbs != null) { @@ -922,11 +930,11 @@ namespace Pamac { return result; } - public async AlpmPackage[] get_group_pkgs (string groupname) throws Error { - return get_group_pkgs_sync (groupname); + public async AlpmPackage[] get_group_pkgs_async (string groupname) throws Error { + return get_group_pkgs (groupname); } - public AlpmPackage[] get_group_pkgs_sync (string groupname) throws Error { + public AlpmPackage[] get_group_pkgs (string groupname) throws Error { AlpmPackage[] pkgs = {}; Alpm.List<unowned Alpm.Package> alpm_pkgs = group_pkgs (groupname); unowned Alpm.List<unowned Alpm.Package> list = alpm_pkgs; @@ -940,7 +948,11 @@ namespace Pamac { return pkgs; } - public async AlpmPackage[] get_category_pkgs (string category) throws Error { + public async AlpmPackage[] get_category_pkgs_async (string category) throws Error { + return get_category_pkgs (category); + } + + public AlpmPackage[] get_category_pkgs (string category) throws Error { AlpmPackage[] pkgs = {}; app_store.get_apps ().foreach ((app) => { app.get_categories ().foreach ((cat_name) => { diff --git a/src/version.vala b/src/version.vala index 4e33643c..89b6ebad 100644 --- a/src/version.vala +++ b/src/version.vala @@ -1 +1 @@ -const string VERSION = "6.5.0"; +const string VERSION = "6.9.0"; -- GitLab