From b598924ffd72f3158fb6e2db32d0ebb550926ba2 Mon Sep 17 00:00:00 2001 From: guinux <nuxgui@gmail.com> Date: Sat, 13 Oct 2018 15:14:00 +0200 Subject: [PATCH] many improvements --- data/config/pamac.conf | 4 +- examples/python/appstream.py | 4 +- examples/python/test-infos.py | 14 +- po/POTFILES | 1 + po/pamac.pot | 135 ++++--- resources/transaction_sum_dialog.ui | 4 +- src/alpm_config.vala | 15 +- src/alpm_utils.vala | 26 +- src/cli.vala | 47 ++- src/database.vala | 98 ++--- src/installer.vala | 4 +- src/manager_window.vala | 10 +- src/pamac_config.vala | 5 + src/system_daemon.vala | 8 +- src/transaction-cli.vala | 98 +++-- src/transaction-gtk.vala | 336 +++++++++------- src/transaction.vala | 555 +++++++++++++++++--------- src/transaction_interface.vala | 5 +- src/transaction_interface_daemon.vala | 17 +- src/transaction_interface_root.vala | 7 +- src/transaction_sum_dialog.vala | 2 +- 21 files changed, 887 insertions(+), 508 deletions(-) diff --git a/data/config/pamac.conf b/data/config/pamac.conf index 78b652b5..32fb8b47 100644 --- a/data/config/pamac.conf +++ b/data/config/pamac.conf @@ -11,10 +11,10 @@ RefreshPeriod = 6 #NoUpdateHideIcon ## Allow Pamac to search and install packages from AUR: -EnableAUR +#EnableAUR ## When AUR support is enabled check for updates from AUR: -CheckAURUpdates +#CheckAURUpdates ## AUR build directory: BuildDirectory = /var/tmp diff --git a/examples/python/appstream.py b/examples/python/appstream.py index 8a01f964..f4502d2f 100755 --- a/examples/python/appstream.py +++ b/examples/python/appstream.py @@ -26,7 +26,7 @@ if __name__ == "__main__": for pkg in pkgs: print_pkg_name (pkg) print ("") - details = db.get_pkg_details(pkgname, appname) + details = db.get_pkg_details(pkgname, appname, False) print_pkg_details (details) print ("") @@ -36,5 +36,5 @@ if __name__ == "__main__": for pkg in pkgs: print_pkg_name (pkg) print ("") - details = db.get_pkg_details(pkgname, appname) + details = db.get_pkg_details(pkgname, appname, False) print_pkg_details (details) diff --git a/examples/python/test-infos.py b/examples/python/test-infos.py index 7bfb86d1..04e71c52 100755 --- a/examples/python/test-infos.py +++ b/examples/python/test-infos.py @@ -57,23 +57,23 @@ class GetInfosCase(unittest.TestCase): def test_pacman_installed(self): """pacman installed for tests""" - pkg = self.db.get_pkg_details("pacman", "") + pkg = self.db.get_pkg_details("pacman", "", False) self.assertEqual("pacman", pkg.get_name()) self.assertIsNotNone(pkg.props.installed_version) def test_not_installed(self): """detect not installed""" # package not exist - pkg = self.db.get_pkg_details("toto-test", "") + pkg = self.db.get_pkg_details("toto-test", "", False) self.assertNotEqual("toto-test", pkg.get_name()) self.assertEqual(pkg.props.installed_version, "") # package exist - pkg = self.db.get_pkg_details("ruby-yard", "") + pkg = self.db.get_pkg_details("ruby-yard", "", False) self.assertEqual(pkg.props.installed_version, "") def test_giobject_detail_name(self): """attrs .props are same as fonctions""" - pkg = self.db.get_pkg_details("pacman", "") + pkg = self.db.get_pkg_details("pacman", "", False) self.assertEqual(pkg.props.name, pkg.get_name()) def test_giobject_search_name(self): @@ -127,7 +127,7 @@ class GetInfosCase(unittest.TestCase): with self.subTest(pkg=pkg): fdesc = f"/var/lib/pacman/local/{pkg.props.name}-{pkg.props.version}/desc" self.assertTrue(os.path.exists(fdesc)) - package = self.db.get_pkg_details(pkg.props.name, "") + package = self.db.get_pkg_details(pkg.props.name, "", False) result = get_item_desc(fdesc, "%DEPENDS%") for dep in result: self.assertIn(dep, package.props.depends) @@ -149,7 +149,7 @@ class GetInfosCase(unittest.TestCase): def test_date_detail_pacman(self): """valid date and locale date""" - pkg = self.db.get_pkg_details("pacman", "") + pkg = self.db.get_pkg_details("pacman", "", False) fdesc = f"/var/lib/pacman/local/{pkg.props.name}-{pkg.props.version}/desc" self.assertTrue(os.path.exists(fdesc)) result = get_item_desc(fdesc, "%BUILDDATE%") @@ -159,7 +159,7 @@ class GetInfosCase(unittest.TestCase): def test_files(self): """files same as pacman db""" - pkg = self.db.get_pkg_details("pacman", "") + pkg = self.db.get_pkg_details("pacman", "", False) fdesc = f"/var/lib/pacman/local/{pkg.props.name}-{pkg.props.version}/files" self.assertTrue(os.path.exists(fdesc)) myfiles = self.db.get_pkg_files("pacman") diff --git a/po/POTFILES b/po/POTFILES index 28349e21..6e45a6e8 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -1,6 +1,7 @@ data/polkit/org.manjaro.pamac.policy.in src/alpm_utils.vala src/system_daemon.vala +src/database.vala src/transaction.vala src/transaction-gtk.vala src/installer.vala diff --git a/po/pamac.pot b/po/pamac.pot index f12fe604..6fe520fe 100644 --- a/po/pamac.pot +++ b/po/pamac.pot @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Pamac\n" "Report-Msgid-Bugs-To: guillaume@manjaro.org\n" -"POT-Creation-Date: 2018-09-08 17:58+0200\n" +"POT-Creation-Date: 2018-10-13 11:01+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -21,30 +21,10 @@ msgstr "" msgid "Authentication is required" msgstr "" -#: src/alpm_utils.vala +#: src/alpm_utils.vala src/database.vala msgid "Failed to initialize alpm library" msgstr "" -#: src/alpm_utils.vala -msgid "Unknown" -msgstr "" - -#: src/alpm_utils.vala src/manager_window.vala -msgid "Explicitly installed" -msgstr "" - -#: src/alpm_utils.vala src/manager_window.vala -msgid "Installed as a dependency for another package" -msgstr "" - -#: src/alpm_utils.vala -msgid "Yes" -msgstr "" - -#: src/alpm_utils.vala -msgid "No" -msgstr "" - #: src/alpm_utils.vala msgid "Failed to synchronize any databases" msgstr "" @@ -53,11 +33,11 @@ msgstr "" msgid "Failed to init transaction" msgstr "" -#: src/alpm_utils.vala +#: src/alpm_utils.vala src/transaction.vala src/transaction-gtk.vala msgid "Failed to prepare transaction" msgstr "" -#: src/alpm_utils.vala src/cli.vala +#: src/alpm_utils.vala src/transaction.vala src/cli.vala #, c-format msgid "target not found: %s" msgstr "" @@ -125,20 +105,46 @@ msgstr "" msgid "Authentication failed" msgstr "" +#: src/database.vala src/manager_window.vala +msgid "Explicitly installed" +msgstr "" + +#: src/database.vala src/manager_window.vala +msgid "Installed as a dependency for another package" +msgstr "" + +#: src/database.vala +msgid "Unknown" +msgstr "" + +#: src/database.vala +msgid "Yes" +msgstr "" + +#: src/database.vala +msgid "No" +msgstr "" + #: src/transaction.vala -msgid "Refreshing mirrors list" +#, c-format +msgid "Generating %s informations" msgstr "" #: src/transaction.vala -msgid "Synchronizing package databases" +msgid "Refreshing mirrors list" msgstr "" #: src/transaction.vala msgid "Starting full system upgrade" msgstr "" -#: src/transaction.vala src/tray.vala src/manager_window.vala src/cli.vala -msgid "Your system is up-to-date" +#: src/transaction.vala +msgid "Synchronizing package databases" +msgstr "" + +#: src/transaction.vala +#, c-format +msgid "Checking %s dependencies" msgstr "" #: src/transaction.vala @@ -352,6 +358,21 @@ msgstr "" msgid "Total download size" msgstr "" +#: src/transaction-gtk.vala src/transaction-cli.vala +#, c-format +msgid "Edit %s build files" +msgstr "" + +#: src/transaction-gtk.vala src/manager_window.vala +#: resources/transaction_sum_dialog.ui resources/manager_window.ui +#: resources/choose_ignorepkgs_dialog.ui +msgid "_Cancel" +msgstr "" + +#: src/transaction-gtk.vala +msgid "Save" +msgstr "" + #: src/transaction-gtk.vala resources/progress_dialog.ui #: resources/history_dialog.ui resources/preferences_dialog.ui msgid "_Close" @@ -373,6 +394,10 @@ msgstr "" msgid "package(s)" msgstr "" +#: src/tray.vala src/manager_window.vala src/cli.vala +msgid "Your system is up-to-date" +msgstr "" + #: src/tray.vala msgid "_Quit" msgstr "" @@ -409,6 +434,10 @@ msgstr "" msgid "Install" msgstr "" +#: src/manager_window.vala resources/manager_window.ui +msgid "Build" +msgstr "" + #: src/manager_window.vala resources/manager_window.ui msgid "Remove" msgstr "" @@ -508,6 +537,10 @@ msgstr "" msgid "Files" msgstr "" +#: src/manager_window.vala +msgid "Build files" +msgstr "" + #: src/manager_window.vala src/cli.vala msgid "Install Reason" msgstr "" @@ -616,11 +649,6 @@ msgstr "" msgid "Install Local Packages" msgstr "" -#: src/manager_window.vala resources/transaction_sum_dialog.ui -#: resources/manager_window.ui resources/choose_ignorepkgs_dialog.ui -msgid "_Cancel" -msgstr "" - #: src/manager_window.vala msgid "_Open" msgstr "" @@ -655,27 +683,36 @@ msgid "Enter a number (default=%d)" msgstr "" #: src/transaction-cli.vala -msgid "Total installed size" +msgid "[y/N]" msgstr "" #: src/transaction-cli.vala -msgid "Total removed size" +msgid "y" msgstr "" #: src/transaction-cli.vala -msgid "Commit transaction" +msgid "yes" +msgstr "" + +#: src/transaction-cli.vala resources/transaction_sum_dialog.ui +msgid "Edit build files" msgstr "" #: src/transaction-cli.vala -msgid "[y/N]" +msgid "Total installed size" msgstr "" #: src/transaction-cli.vala -msgid "y" +msgid "Total removed size" msgstr "" #: src/transaction-cli.vala -msgid "yes" +msgid "Commit transaction" +msgstr "" + +#: src/transaction-cli.vala +#, c-format +msgid "View %s build files diff" msgstr "" #: src/cli.vala @@ -771,6 +808,12 @@ msgstr "" msgid "dir" msgstr "" +#: src/cli.vala +msgid "" +"ignore a package upgrade, multiple packages can be specified by separating " +"them with a comma" +msgstr "" + #: src/cli.vala msgid "" "overwrite conflicting files, multiple patterns can be specified by " @@ -825,12 +868,6 @@ msgstr "" msgid "enable package downgrades" msgstr "" -#: src/cli.vala -msgid "" -"ignore a package upgrade, multiple packages can be specified by separating " -"them with a comma" -msgstr "" - #: src/cli.vala resources/manager_window.ui msgid "Version" msgstr "" @@ -908,6 +945,10 @@ msgstr "" msgid "About" msgstr "" +#: resources/manager_window.ui +msgid "Select All" +msgstr "" + #: resources/manager_window.ui msgid "State" msgstr "" @@ -925,11 +966,11 @@ msgid "Reinstall" msgstr "" #: resources/manager_window.ui -msgid "_Apply" +msgid "Reset build files" msgstr "" #: resources/manager_window.ui -msgid "Select All" +msgid "_Apply" msgstr "" #: resources/preferences_dialog.ui diff --git a/resources/transaction_sum_dialog.ui b/resources/transaction_sum_dialog.ui index 0276015d..73629440 100644 --- a/resources/transaction_sum_dialog.ui +++ b/resources/transaction_sum_dialog.ui @@ -54,7 +54,7 @@ </packing> </child> <child> - <object class="GtkButton" id="review_button"> + <object class="GtkButton" id="edit_button"> <property name="label" translatable="yes">Edit build files</property> <property name="visible">True</property> <property name="can_focus">True</property> @@ -164,7 +164,7 @@ <action-widgets> <action-widget response="-6">cancel_button</action-widget> <action-widget response="-5">apply_button</action-widget> - <action-widget response="-2">review_button</action-widget> + <action-widget response="-2">edit_button</action-widget> </action-widgets> </template> </interface> diff --git a/src/alpm_config.vala b/src/alpm_config.vala index f08db524..06bafc05 100644 --- a/src/alpm_config.vala +++ b/src/alpm_config.vala @@ -138,14 +138,19 @@ internal class AlpmConfig { Alpm.Errno error = 0; Alpm.Handle? handle = null; if (tmp_db) { - string tmp_dbpath = "/tmp/pamac-checkdbs"; + string tmp_path = "/tmp/pamac"; + string tmp_dbpath = "/tmp/pamac/dbs-%s".printf (Environment.get_user_name ()); try { - var file = GLib.File.new_for_path (tmp_dbpath); + var file = GLib.File.new_for_path (tmp_path); if (!file.query_exists ()) { - Process.spawn_command_line_sync ("mkdir -p %s/sync".printf (tmp_dbpath)); - Process.spawn_command_line_sync ("chmod -R ugo+w %s".printf (tmp_dbpath)); + Process.spawn_command_line_sync ("mkdir -p %s".printf (tmp_path)); + Process.spawn_command_line_sync ("chmod a+w %s".printf (tmp_path)); + } + file = GLib.File.new_for_path (tmp_dbpath); + if (!file.query_exists ()) { + Process.spawn_command_line_sync ("mkdir -p %s".printf (tmp_dbpath)); + Process.spawn_command_line_sync ("ln -s %slocal %s".printf (dbpath, tmp_dbpath)); } - Process.spawn_command_line_sync ("ln -sf %slocal %s".printf (dbpath, tmp_dbpath)); Process.spawn_command_line_sync ("cp -ru %ssync %s".printf (dbpath, tmp_dbpath)); handle = new Alpm.Handle (rootdir, tmp_dbpath, out error); if (error == Alpm.Errno.DB_VERSION) { diff --git a/src/alpm_utils.vala b/src/alpm_utils.vala index 1148222e..2a35252a 100644 --- a/src/alpm_utils.vala +++ b/src/alpm_utils.vala @@ -25,6 +25,7 @@ namespace Pamac { internal AlpmConfig alpm_config; internal Alpm.Handle? alpm_handle; internal Alpm.Handle? files_handle; + internal string tmp_path; internal Cond provider_cond; internal Mutex provider_mutex; internal int? choosen_provider; @@ -51,6 +52,7 @@ namespace Pamac { 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_unresolvables (string[] unresolvables); 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); @@ -64,6 +66,7 @@ namespace Pamac { public AlpmUtils (Config config) { this.config = config; alpm_config = new AlpmConfig ("/etc/pacman.conf"); + tmp_path = "/tmp/pamac"; aur_pkgbases_to_build = new GLib.List<string> (); to_install_as_dep = new HashTable<string, string> (str_hash, str_equal); timer = new Timer (); @@ -161,20 +164,19 @@ namespace Pamac { write_log_file ("synchronizing package lists"); cancellable.reset (); int force = (force_refresh) ? 1 : 0; - string tmp_dbpath = "/tmp/pamac-checkdbs"; if (force_refresh) { // remove dbs in tmp try { - Process.spawn_command_line_sync ("rm -rf %s".printf (tmp_dbpath)); + Process.spawn_command_line_sync ("bash -c 'rm -rf %s/dbs*'".printf (tmp_path)); } catch (SpawnError e) { stderr.printf ("SpawnError: %s\n", e.message); } } else { // try to copy refresh dbs in tmp - var file = GLib.File.new_for_path (tmp_dbpath); + var file = GLib.File.new_for_path (tmp_path); if (file.query_exists ()) { try { - Process.spawn_command_line_sync ("cp -ru %s/sync %s".printf (tmp_dbpath, alpm_handle.dbpath)); + Process.spawn_command_line_sync ("bash -c 'cp -u %s/dbs*/sync/*.{db,files} %ssync'".printf (tmp_path, alpm_handle.dbpath)); } catch (SpawnError e) { stderr.printf ("SpawnError: %s\n", e.message); } @@ -590,6 +592,7 @@ namespace Pamac { internal void trans_prepare () { to_build_pkgs = {}; aur_pkgbases_to_build = new GLib.List<string> (); + to_install_as_dep.remove_all (); launch_trans_prepare_real (); } @@ -653,6 +656,7 @@ namespace Pamac { internal void build_prepare () { to_build_pkgs = {}; aur_pkgbases_to_build = new GLib.List<string> (); + to_install_as_dep.remove_all (); // get an handle with fake aur db and without emit signal callbacks alpm_handle = alpm_config.get_handle (); if (alpm_handle == null) { @@ -665,9 +669,8 @@ namespace Pamac { // emit warnings here alpm_handle.logcb = (Alpm.LogCallBack) cb_log; // fake aur db - string tmp_dbpath = "/tmp/pamac-checkdbs"; try { - Process.spawn_command_line_sync ("cp %s/sync/aur.db %ssync".printf (tmp_dbpath, alpm_handle.dbpath)); + Process.spawn_command_line_sync ("cp %s/aur.db %ssync".printf (tmp_path, alpm_handle.dbpath)); } catch (SpawnError e) { stderr.printf ("SpawnError: %s\n", e.message); } @@ -805,7 +808,8 @@ namespace Pamac { launch_trans_prepare_real (); alpm_handle.logcb = (Alpm.LogCallBack) cb_log; } - } else { + } + if (!success) { trans_release (); } } @@ -1172,6 +1176,14 @@ void cb_question (Alpm.Question.Data data) { data.conflict_remove = 1; break; case Alpm.Question.Type.REMOVE_PKGS: + string[] unresolvables = {}; + unowned Alpm.List<unowned Alpm.Package> list = data.remove_pkgs_packages; + while (list != null) { + unowned Alpm.Package pkg = list.data; + unresolvables += pkg.name; + list.next (); + } + alpm_utils.emit_unresolvables (unresolvables); // Return an error if there are top-level packages which have unresolvable dependencies data.remove_pkgs_skip = 0; break; diff --git a/src/cli.vala b/src/cli.vala index c2b56514..6a9dc567 100644 --- a/src/cli.vala +++ b/src/cli.vala @@ -210,6 +210,11 @@ namespace Pamac { overwrite_files += name; } i++; + } else if (arg == "--ignore") { + foreach (unowned string name in args[i + 1].split(",")) { + temporary_ignorepkgs += name; + } + i++; } else { targets += arg; } @@ -588,7 +593,7 @@ namespace Pamac { i++; } cuts = split_string (dgettext (null, "list files owned by the given packages"), max_length + 2); - print_aligned (" %s [%s]".printf ("-f, --files", dgettext (null, "file(s)")), ": %s".printf (cuts[0]), max_length); + print_aligned (" %s <%s>".printf ("-f, --files", dgettext (null, "package(s)")), ": %s".printf (cuts[0]), max_length); i = 1; while (i < cuts.length) { print_aligned ("", "%s".printf (cuts[i]), max_length + 2); @@ -619,13 +624,20 @@ namespace Pamac { stdout.printf ("\n\n"); stdout.printf (dgettext (null, "options") + ":\n"); int max_length = 25; - string[] cuts = split_string (dgettext (null, "overwrite conflicting files, multiple patterns can be specified by separating them with a comma"), max_length + 2); - print_aligned (" %s <%s>".printf ("--overwrite", dgettext (null, "glob")), ": %s".printf (cuts[0]), max_length); + string[] cuts = split_string (dgettext (null, "ignore a package upgrade, multiple packages can be specified by separating them with a comma"), max_length + 2); + print_aligned (" %s <%s>".printf ("--ignore", dgettext (null, "package(s)")), ": %s".printf (cuts[0]), max_length); int i = 1; while (i < cuts.length) { print_aligned ("", "%s".printf (cuts[i]), max_length + 2); i++; } + cuts = split_string (dgettext (null, "overwrite conflicting files, multiple patterns can be specified by separating them with a comma"), max_length + 2); + print_aligned (" %s <%s>".printf ("--overwrite", dgettext (null, "glob")), ": %s".printf (cuts[0]), max_length); + i = 1; + while (i < cuts.length) { + print_aligned ("", "%s".printf (cuts[i]), max_length + 2); + i++; + } } void display_reinstall_help () { @@ -705,7 +717,7 @@ namespace Pamac { i++; } cuts = split_string (dgettext (null, "ignore a package upgrade, multiple packages can be specified by separating them with a comma"), max_length + 2); - print_aligned (" %s [%s]".printf ("--ignore", dgettext (null, "package(s)")), ": %s".printf (cuts[0]), max_length); + print_aligned (" %s <%s>".printf ("--ignore", dgettext (null, "package(s)")), ": %s".printf (cuts[0]), max_length); i = 1; while (i < cuts.length) { print_aligned ("", "%s".printf (cuts[i]), max_length + 2); @@ -1619,13 +1631,36 @@ namespace Pamac { try_lock_and_run (start_transaction); } + async bool check_build_pkgs () { + bool success = true; + foreach (unowned string pkgname in to_build) { + var aur_pkg = yield database.get_aur_pkg (pkgname); + if (aur_pkg.name == "") { + print_error (dgettext (null, "target not found: %s").printf (pkgname) + "\n"); + success = false; + } + if (!success) { + break; + } + } + return success; + } + void build_pkgs (string[] to_build) { this.to_build = to_build; - try_lock_and_run (start_transaction); + bool success = false; + check_build_pkgs.begin ((obj, res) => { + success = check_build_pkgs.end (res); + loop.quit (); + }); + loop.run (); + if (success) { + try_lock_and_run (start_transaction); + } } void start_transaction () { - transaction.start (to_install, to_remove, to_load, to_build, overwrite_files); + transaction.start (to_install, to_remove, to_load, to_build, temporary_ignorepkgs, overwrite_files); loop.run (); } diff --git a/src/database.vala b/src/database.vala index 038f5141..48b87c40 100644 --- a/src/database.vala +++ b/src/database.vala @@ -69,13 +69,12 @@ namespace Pamac { public void refresh () { alpm_config = new AlpmConfig ("/etc/pacman.conf"); - // use tmp dbs - alpm_handle = alpm_config.get_handle (false, true); + alpm_handle = alpm_config.get_handle (); if (alpm_handle == null) { critical (dgettext (null, "Failed to initialize alpm library")); return; } else { - files_handle = alpm_config.get_handle (true, true); + files_handle = alpm_config.get_handle (true); } refreshed (); } @@ -121,10 +120,6 @@ namespace Pamac { return country; } - internal string get_tmp_db_path () { - return alpm_handle.dbpath; - } - public bool get_checkspace () { return alpm_handle.checkspace == 1 ? true : false; } @@ -958,11 +953,11 @@ namespace Pamac { } // reason if (alpm_pkg.reason == Alpm.Package.Reason.EXPLICIT) { - reason = _("Explicitly installed"); + reason = dgettext (null, "Explicitly installed"); } else if (alpm_pkg.reason == Alpm.Package.Reason.DEPEND) { - reason = _("Installed as a dependency for another package"); + reason = dgettext (null, "Installed as a dependency for another package"); } else { - reason = _("Unknown"); + reason = dgettext (null, "Unknown"); } // install_date time = GLib.Time.local ((time_t) alpm_pkg.installdate); @@ -994,7 +989,7 @@ namespace Pamac { // repos repo = alpm_pkg.db.name; // signature - has_signature = alpm_pkg.base64_sig != null ? _("Yes") : _("No"); + has_signature = alpm_pkg.base64_sig != null ? dgettext (null, "Yes") : dgettext (null, "No"); } // depends list = alpm_pkg.depends; @@ -1097,29 +1092,6 @@ namespace Pamac { return get_pkg_files (pkgname); } - string get_srcinfo_version (string pkgdir_name) { - StringBuilder version = new StringBuilder (); - // assume file exists - var srcinfo = File.new_for_path (pkgdir_name + "/.SRCINFO"); - try { - var dis = new DataInputStream (srcinfo.read ()); - string line; - while ((line = dis.read_line ()) != null) { - if ("pkgver = " in line) { - version.append (line.split ("pkgver = ", 2)[1]); - } else if ("pkgrel = " in line) { - version.append ("-"); - version.append (line.split ("pkgrel = ", 2)[1]); - // we have all we want - break; - } - } - } catch (GLib.Error e) { - stderr.printf ("%s\n", e.message); - } - return version.str; - } - async int launch_subprocess (SubprocessLauncher launcher, string[] cmds) { int status = 1; try { @@ -1136,14 +1108,12 @@ namespace Pamac { public async File? clone_build_files (string pkgname, bool overwrite_files) { int status = 1; - string builddir_name = Path.build_path ("/", config.aur_build_dir, "pamac-build"); string[] cmds; var launcher = new SubprocessLauncher (SubprocessFlags.NONE); - var builddir = File.new_for_path (builddir_name); + var builddir = File.new_for_path (config.aur_build_dir); if (!builddir.query_exists ()) { try { builddir.make_directory_with_parents (); - Process.spawn_command_line_sync ("chmod --quiet -R ugo+w %s".printf (builddir_name)); } catch (Error e) { stderr.printf ("Error: %s\n", e.message); } @@ -1151,16 +1121,11 @@ namespace Pamac { var pkgdir = builddir.get_child (pkgname); if (pkgdir.query_exists ()) { if (overwrite_files) { - launcher.set_cwd (builddir_name); - cmds = {"rm", "-rf %s".printf (pkgdir.get_path ())}; + launcher.set_cwd (config.aur_build_dir); + cmds = {"rm", "-rf", "%s".printf (pkgdir.get_path ())}; yield launch_subprocess (launcher, cmds); cmds = {"git", "clone", "-q", "--depth=1", "https://aur.archlinux.org/%s.git".printf (pkgname)}; } else { - var aur_pkg = yield get_aur_pkg (pkgname); - if (aur_pkg.version == get_srcinfo_version (pkgdir.get_path ())) { - // up to date - return pkgdir; - } // fetch modifications launcher.set_cwd (pkgdir.get_path ()); cmds = {"git", "fetch", "-q"}; @@ -1169,21 +1134,34 @@ namespace Pamac { if (status == 0) { launcher.set_flags (SubprocessFlags.STDOUT_PIPE); try { - Subprocess process = launcher.spawnv ({"git", "diff", "origin/master"}); - yield process.wait_async (); - var dis = new DataInputStream (process.get_stdout_pipe ()); var file = File.new_for_path (Path.build_path ("/", pkgdir.get_path (), "diff")); if (file.query_exists ()) { // delete the file before rewrite it yield file.delete_async (); } - // creating a DataOutputStream to the file - var dos = new DataOutputStream (yield file.create_async (FileCreateFlags.REPLACE_DESTINATION)); - // writing makepkg output to diff - yield dos.splice_async (dis, 0); + cmds = {"git", "diff", "--exit-code", "origin/master"}; + FileEnumerator enumerator = yield pkgdir.enumerate_children_async ("standard::*", FileQueryInfoFlags.NONE); + FileInfo info; + // don't see .SRCINFO diff + while ((info = enumerator.next_file (null)) != null) { + string filename = info.get_name (); + if (filename != ".SRCINFO") { + cmds += filename; + } + } + Subprocess process = launcher.spawnv (cmds); + yield process.wait_async (); if (process.get_if_exited ()) { status = process.get_exit_status (); } + if (status == 1) { + // there is a diff + var dis = new DataInputStream (process.get_stdout_pipe ()); + var dos = new DataOutputStream (yield file.create_async (FileCreateFlags.REPLACE_DESTINATION)); + // writing output to diff + yield dos.splice_async (dis, 0); + status = 0; + } } catch (Error e) { stderr.printf ("Error: %s\n", e.message); } @@ -1197,24 +1175,17 @@ namespace Pamac { if (status == 0) { return pkgdir; } else { - launcher.set_cwd (builddir_name); - cmds = {"rm", "-rf %s".printf (pkgdir.get_path ())}; + launcher.set_cwd (config.aur_build_dir); + cmds = {"rm", "-rf", "%s".printf (pkgdir.get_path ())}; yield launch_subprocess (launcher, cmds); cmds = {"git", "clone", "-q", "--depth=1", "https://aur.archlinux.org/%s.git".printf (pkgname)}; } } } else { - launcher.set_cwd (builddir_name); + launcher.set_cwd (config.aur_build_dir); cmds = {"git", "clone", "-q", "--depth=1", "https://aur.archlinux.org/%s.git".printf (pkgname)}; } status = yield launch_subprocess (launcher, cmds); - if (status == 0) { - try { - Process.spawn_command_line_sync ("chmod --quiet -R ugo+w %s".printf (pkgdir.get_path ())); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } - } if (status == 0) { return pkgdir; } @@ -1308,7 +1279,7 @@ namespace Pamac { licenses += _node.get_string (); }); } else { - licenses += _("Unknown"); + licenses += dgettext (null, "Unknown"); } // depends node = json_object.get_member ("Depends"); @@ -1405,7 +1376,8 @@ namespace Pamac { } public void refresh_tmp_files_dbs () { - unowned Alpm.List<unowned Alpm.DB> syncdbs = files_handle.syncdbs; + var tmp_files_handle = alpm_config.get_handle (true, true); + unowned Alpm.List<unowned Alpm.DB> syncdbs = tmp_files_handle.syncdbs; while (syncdbs != null) { unowned Alpm.DB db = syncdbs.data; db.update (0); diff --git a/src/installer.vala b/src/installer.vala index ab5f407c..c64cca70 100644 --- a/src/installer.vala +++ b/src/installer.vala @@ -114,7 +114,7 @@ namespace Pamac { this.hold (); progress_dialog.show (); if (transaction.get_lock ()) { - transaction.start (to_install, to_remove, to_load, {}, {}); + transaction.start (to_install, to_remove, to_load, {}, {}, {}); progress_dialog.close_button.visible = false; } else { transaction.progress_box.action_label.label = dgettext (null, "Waiting for another package manager to quit") + "..."; @@ -123,7 +123,7 @@ namespace Pamac { bool locked = transaction.get_lock (); if (locked) { transaction.stop_progressbar_pulse (); - transaction.start (to_install, to_remove, to_load, {}, {}); + transaction.start (to_install, to_remove, to_load, {}, {}, {}); } return !locked; }); diff --git a/src/manager_window.vala b/src/manager_window.vala index 49b39778..ddd2eb23 100644 --- a/src/manager_window.vala +++ b/src/manager_window.vala @@ -426,7 +426,7 @@ namespace Pamac { if (!file.query_exists ()) { try { Process.spawn_command_line_sync ("mkdir -p %s".printf (screenshots_tmp_dir)); - Process.spawn_command_line_sync ("chmod -R ugo+w %s".printf (screenshots_tmp_dir)); + Process.spawn_command_line_sync ("chmod -R a+w %s".printf (screenshots_tmp_dir)); } catch (SpawnError e) { stderr.printf ("SpawnError: %s\n", e.message); } @@ -1664,6 +1664,7 @@ namespace Pamac { }); break; case "build_files": + reset_files_button.visible = true; transaction.build_files_notebook.foreach (transaction.destroy_widget); this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH)); while (Gtk.events_pending ()) { @@ -2661,6 +2662,11 @@ namespace Pamac { force_refresh = false; transaction.no_confirm_upgrade = true; try_lock_and_run (run_sysupgrade); + } else if (main_stack.visible_child_name == "details" && + properties_stack.visible_child_name == "build_files") { + transaction.save_build_files.begin (current_package_displayed, () => { + try_lock_and_run (run_transaction); + }); } else { try_lock_and_run (run_transaction); } @@ -2701,7 +2707,7 @@ namespace Pamac { to_build_ += name; previous_to_build.add (name); } - transaction.start (to_install_, to_remove_, to_load_, to_build_, {}); + transaction.start (to_install_, to_remove_, to_load_, to_build_, {}, {}); clear_lists (); // let time to update packages states Timeout.add (500, () => { diff --git a/src/pamac_config.vala b/src/pamac_config.vala index 93af9ff9..30641142 100644 --- a/src/pamac_config.vala +++ b/src/pamac_config.vala @@ -82,6 +82,11 @@ namespace Pamac { clean_keep_num_pkgs = 3; clean_rm_only_uninstalled = false; parse_file (conf_path); + if (aur_build_dir == "/var/tmp") { + aur_build_dir = Path.build_path ("/", aur_build_dir, "pamac-build-%s".printf (Environment.get_user_name ())); + } else { + aur_build_dir = Path.build_path ("/", aur_build_dir, "pamac-build"); + } if (enable_aur == false) { check_aur_updates = false; } diff --git a/src/system_daemon.vala b/src/system_daemon.vala index 98d10950..39fd8b83 100644 --- a/src/system_daemon.vala +++ b/src/system_daemon.vala @@ -50,6 +50,7 @@ namespace Pamac { 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_unresolvables (string[] unresolvables); 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); @@ -86,6 +87,9 @@ namespace Pamac { alpm_utils.emit_providers.connect ((depend, providers) => { emit_providers (depend, providers); }); + alpm_utils.emit_unresolvables.connect ((unresolvables) => { + emit_unresolvables (unresolvables); + }); alpm_utils.emit_progress.connect ((progress, pkgname, percent, n_targets, current_target) => { emit_progress (progress, pkgname, percent, n_targets, current_target); }); @@ -425,8 +429,8 @@ namespace Pamac { } public void start_sysupgrade_prepare (bool enable_downgrade, - string[] temporary_ignorepkgs, string[] to_build, + string[] temporary_ignorepkgs, string[] overwrite_files, GLib.BusName sender) throws Error { if (lock_id != sender) { @@ -459,6 +463,7 @@ namespace Pamac { string[] to_remove, string[] to_load, string[] to_build, + string[] temporary_ignorepkgs, string[] overwrite_files, GLib.BusName sender) throws Error { if (lock_id != sender) { @@ -470,6 +475,7 @@ namespace Pamac { alpm_utils.to_remove = to_remove; alpm_utils.to_load = to_load; alpm_utils.to_build = to_build; + alpm_utils.temporary_ignorepkgs = temporary_ignorepkgs; alpm_utils.overwrite_files = overwrite_files; alpm_utils.sysupgrade = false; if (alpm_utils.downloading_updates) { diff --git a/src/transaction-cli.vala b/src/transaction-cli.vala index 3dfffd57..d6b22677 100644 --- a/src/transaction-cli.vala +++ b/src/transaction-cli.vala @@ -22,6 +22,7 @@ namespace Pamac { bool downloading; string current_line; string current_action; + bool summary_shown; public TransactionCli (Database database) { Object (database: database); @@ -31,6 +32,7 @@ namespace Pamac { downloading = false; current_line = ""; current_action = ""; + summary_shown = false; // connect to signal emit_action.connect (print_action); emit_action_progress.connect (print_action_progress); @@ -238,9 +240,9 @@ namespace Pamac { } } - protected override bool ask_review_build_files () { + bool ask_user (string question) { // ask user confirmation - stdout.printf ("%s ? %s ", dgettext (null, "Review build files"), dgettext (null, "[y/N]")); + stdout.printf ("%s %s ", question, dgettext (null, "[y/N]")); char buf[32]; if (stdin.gets (buf) != null) { string ans = (string) buf; @@ -257,7 +259,13 @@ namespace Pamac { return false; } - protected override bool ask_confirmation (TransactionSummary summary) { + protected override bool ask_edit_build_files (TransactionSummary summary) { + show_summary (summary); + summary_shown = true; + return ask_user ("%s ?".printf (dgettext (null, "Edit build files"))); + } + + void show_summary (TransactionSummary summary) { uint64 dsize = 0; uint64 rsize = 0; int64 isize = 0; @@ -456,54 +464,68 @@ namespace Pamac { if (rsize > 0) { stdout.printf ("%s: %s\n", dgettext (null, "Total removed size"), format_size (rsize)); } - // ask user 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; + } + + protected override bool ask_commit (TransactionSummary summary) { + if (!summary_shown) { + show_summary (summary); + } + return ask_user ("%s ?".printf (dgettext (null, "Commit transaction"))); + } + + async void ask_view_diff (string pkgname) { + string diff_path = Path.build_path ("/", database.config.aur_build_dir, pkgname, "diff"); + var diff_file = File.new_for_path (diff_path); + if (diff_file.query_exists ()) { + if (ask_user ("%s ?".printf (dgettext (null, "View %s build files diff".printf (pkgname))))) { + string[] cmds = {"nano", "-S", "-w", "-v", diff_path}; + try { + var process = new Subprocess.newv (cmds, SubprocessFlags.STDIN_INHERIT); + yield process.wait_async (); + } catch (Error e) { + print ("Error: %s\n", e.message); } } } - return false; } - protected override async void review_build_files (string pkgname) { - stdout.printf (dgettext (null, "Review %s build files".printf (pkgname)) + "\n"); - Posix.sleep (1); - string pkgdir_name = Path.build_path ("/", database.config.aur_build_dir, "pamac-build", pkgname); + async bool edit_single_build_files (string pkgname) { string[] cmds = {"nano", "-S", "-w", "-i"}; - // diff - string diff_name = Path.build_path ("/", pkgdir_name, "diff"); - var diff_file = File.new_for_path (diff_name); - if (diff_file.query_exists ()) { - cmds += diff_name; + string[] files = yield get_build_files (pkgname); + foreach (unowned string file in files) { + cmds += file; } - // PKGBUILD - cmds += Path.build_path ("/", pkgdir_name, "PKGBUILD"); - // other file - var pkgdir = File.new_for_path (pkgdir_name); try { - FileEnumerator enumerator = yield pkgdir.enumerate_children_async ("standard::*", FileQueryInfoFlags.NONE); - FileInfo info; - while ((info = enumerator.next_file (null)) != null) { - unowned string filename = info.get_name (); - if (".install" in filename || ".patch" in filename) { - cmds += Path.build_path ("/", pkgdir_name, filename); - } - } var process = new Subprocess.newv (cmds, SubprocessFlags.STDIN_INHERIT); yield process.wait_async (); + if (process.get_if_exited ()) { + if (process.get_exit_status () == 0) { + return yield regenerate_srcinfo (pkgname); + } + } } catch (Error e) { print ("Error: %s\n", e.message); } - yield regenerate_srcinfo (pkgname); + return false; + } + + protected override async bool edit_build_files (string[] pkgnames) { + if (pkgnames.length == 1) { + yield ask_view_diff (pkgnames[0]); + return yield edit_single_build_files (pkgnames[0]); + } else { + bool success = true; + foreach (unowned string pkgname in pkgnames) { + yield ask_view_diff (pkgname); + if (ask_user ("%s ?".printf (dgettext (null, "Edit %s build files".printf (pkgname))))) { + success = yield edit_single_build_files (pkgname); + } + if (!success) { + break; + } + } + return success; + } } } } diff --git a/src/transaction-gtk.vala b/src/transaction-gtk.vala index df9d99db..1e16101b 100644 --- a/src/transaction-gtk.vala +++ b/src/transaction-gtk.vala @@ -34,7 +34,8 @@ namespace Pamac { public Gtk.ApplicationWindow? application_window { get; construct; } // ask_confirmation option public bool no_confirm_upgrade { get; set; } - bool review_build_files_answer; + bool summary_shown; + bool commit_transaction_answer; public TransactionGtk (Database database, Gtk.ApplicationWindow? application_window) { Object (database: database, application_window: application_window); @@ -75,6 +76,8 @@ namespace Pamac { build_files_notebook = new Gtk.Notebook (); build_files_notebook.visible = true; build_files_notebook.expand = true; + build_files_notebook.scrollable = true; + build_files_notebook.enable_popup = true; // connect to signal emit_action.connect (display_action); emit_action_progress.connect (display_action_progress); @@ -98,8 +101,10 @@ namespace Pamac { Notify.init (dgettext (null, "Package Manager")); // flags set_trans_flags (); + // ask_confirmation option no_confirm_upgrade = false; - review_build_files_answer = false; + summary_shown = false; + commit_transaction_answer = false; } void set_trans_flags () { @@ -230,30 +235,53 @@ namespace Pamac { return index; } - protected override bool ask_review_build_files () { - if (review_build_files_answer) { - review_build_files_answer = false; - return true; - } - return false; + protected override bool ask_edit_build_files (TransactionSummary summary) { + bool answer = false; + summary_shown = true; + int response = show_summary (summary); + if (response == Gtk.ResponseType.OK) { + // Commit + commit_transaction_answer = true; + } else if (response == Gtk.ResponseType.CANCEL) { + // Cancel transaction + commit_transaction_answer = false; + } else if (response == Gtk.ResponseType.REJECT) { + // Edit build files + answer = true; + } + return answer; } - protected override bool ask_confirmation (TransactionSummary summary) { - show_warnings (true); - uint must_confirm_length = summary.to_install.length () + protected override bool ask_commit (TransactionSummary summary) { + if (summary_shown) { + summary_shown = false; + return commit_transaction_answer; + } else { + uint must_confirm_length = summary.to_install.length () + summary.to_downgrade.length () + summary.to_reinstall.length () + summary.to_remove.length () + summary.to_build.length (); - if (no_confirm_upgrade - && must_confirm_length == 0 - && summary.to_upgrade.length () > 0) { - return true; + if (no_confirm_upgrade + && must_confirm_length == 0 + && summary.to_upgrade.length () > 0) { + return true; + } + summary_shown = true; + int response = show_summary (summary); + if (response == Gtk.ResponseType.OK) { + // Commit + return true; + } } + return false; + } + + int show_summary (TransactionSummary summary) { uint64 dsize = 0; transaction_summary.remove_all (); transaction_sum_dialog.sum_list.clear (); - transaction_sum_dialog.review_button.visible = false; + transaction_sum_dialog.edit_button.visible = false; var iter = Gtk.TreeIter (); if (summary.to_remove.length () > 0) { foreach (unowned Package infos in summary.to_remove) { @@ -295,7 +323,7 @@ namespace Pamac { transaction_sum_dialog.sum_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "To downgrade") + ":")); } if (summary.to_build.length () > 0) { - transaction_sum_dialog.review_button.visible = true; + transaction_sum_dialog.edit_button.visible = true; foreach (unowned AURPackage infos in summary.to_build) { transaction_summary.add (infos.name); transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, @@ -355,160 +383,196 @@ namespace Pamac { 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; } - var response = transaction_sum_dialog.run (); - if (response == Gtk.ResponseType.OK) { - transaction_sum_dialog.hide (); - return true; - } - if (response == Gtk.ResponseType.REJECT) { - review_build_files_answer = true; + if (transaction_summary.length == 0) { + // empty summary comes in case of transaction preparation failure + // with pkgs to build so we show warnings ans ask to edit build files + transaction_sum_dialog.edit_button.visible = true; + if (warning_textbuffer.len > 0) { + transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, + 0, Markup.escape_text (warning_textbuffer.str)); + warning_textbuffer = new StringBuilder (); + } else { + transaction_sum_dialog.sum_list.insert_with_values (out iter, -1, + 0, dgettext (null, "Failed to prepare transaction")); + } + } else { + show_warnings (true); } + int response = transaction_sum_dialog.run (); transaction_sum_dialog.hide (); - transaction_summary.remove_all (); - return false; + return response; } public void destroy_widget (Gtk.Widget widget) { widget.destroy (); } - protected override async void review_build_files (string pkgname) { - string action = dgettext (null, "Review %s build files".printf (pkgname)); - display_action (action); - // remove noteboook from manager_window properties stack - unowned Gtk.Stack? stack = build_files_notebook.get_parent () as Gtk.Stack; - if (stack != null) { - stack.remove (build_files_notebook); - } - // create dialog - 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 (action, - application_window, - flags); - dialog.icon_name = "system-software-install"; - unowned Gtk.Widget widget = dialog.add_button (dgettext (null, "_Close"), Gtk.ResponseType.CLOSE); - widget.margin_end = 6; - widget.can_focus = true; - widget.has_focus = true; - widget.can_default = true; - widget.has_default = true; - unowned Gtk.Box box = dialog.get_content_area (); - box.margin_bottom = 6; - build_files_notebook.margin = 6; - box.add (build_files_notebook); - dialog.default_width = 700; - dialog.default_height = 500; - // populate notebook - yield populate_build_files (pkgname, false, false); - // run - dialog.run (); - // re-add noteboook to manager_window properties stack - box.remove (build_files_notebook); - build_files_notebook.margin = 0; - if (stack != null) { - stack.add_named (build_files_notebook, "build_files"); + protected override async bool edit_build_files (string[] pkgnames) { + bool success = true; + foreach (unowned string pkgname in pkgnames) { + string action = dgettext (null, "Edit %s build files".printf (pkgname)); + display_action (action); + // remove noteboook from manager_window properties stack + unowned Gtk.Stack? stack = build_files_notebook.get_parent () as Gtk.Stack; + if (stack != null) { + stack.remove (build_files_notebook); + } + // create dialog + 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 (action, + application_window, + flags); + dialog.icon_name = "system-software-install"; + dialog.add_button (dgettext (null, "Save"), Gtk.ResponseType.CLOSE); + unowned Gtk.Widget widget = dialog.add_button (dgettext (null, "_Cancel"), Gtk.ResponseType.CANCEL); + widget.can_focus = true; + widget.has_focus = true; + widget.can_default = true; + widget.has_default = true; + unowned Gtk.Box box = dialog.get_content_area (); + box.margin_bottom = 6; + build_files_notebook.margin = 6; + box.add (build_files_notebook); + dialog.default_width = 700; + dialog.default_height = 500; + // populate notebook + success = yield populate_build_files (pkgname, false, false); + // run + int response = dialog.run (); + // re-add noteboook to manager_window properties stack + box.remove (build_files_notebook); + build_files_notebook.margin = 0; + if (stack != null) { + stack.add_named (build_files_notebook, "build_files"); + } + dialog.destroy (); + if (response == Gtk.ResponseType.CLOSE) { + // save modifications + success = yield save_build_files (pkgname); + } + if (!success) { + break; + } } - dialog.destroy (); - // save modifications - yield save_build_files (pkgname); + return success; } - async void create_build_files_tab (File parent, string filename) { - var file = parent.get_child (filename); - if (file.query_exists ()) { - try { - StringBuilder text = new StringBuilder (); - var fis = yield file.read_async (); - var dis = new DataInputStream (fis); - string line; - while ((line = yield dis.read_line_async ()) != null) { - text.append (line); - text.append ("\n"); - } - var scrolled_window = new Gtk.ScrolledWindow (null, null); - scrolled_window.visible = true; - var textview = new Gtk.TextView (); - textview.wrap_mode = Gtk.WrapMode.NONE; - textview.top_margin = 8; - textview.bottom_margin = 8; - textview.left_margin = 8; - textview.right_margin = 8; - textview.buffer.set_text (text.str, (int) text.len); + async bool create_build_files_tab (string filename, bool editable = true) { + var file = File.new_for_path (filename); + try { + StringBuilder text = new StringBuilder (); + var fis = yield file.read_async (); + var dis = new DataInputStream (fis); + string line; + while ((line = yield dis.read_line_async ()) != null) { + text.append (line); + text.append ("\n"); + } + var scrolled_window = new Gtk.ScrolledWindow (null, null); + scrolled_window.visible = true; + var textview = new Gtk.TextView (); + textview.visible = true; + textview.editable = editable; + textview.wrap_mode = Gtk.WrapMode.NONE; + textview.set_monospace (true); + textview.input_hints = Gtk.InputHints.NO_EMOJI; + textview.top_margin = 8; + textview.bottom_margin = 8; + textview.left_margin = 8; + textview.right_margin = 8; + textview.buffer.set_text (text.str, (int) text.len); + textview.buffer.set_modified (false); + if (editable) { Gtk.TextIter iter; textview.buffer.get_start_iter (out iter); textview.buffer.place_cursor (iter); - textview.visible = true; - scrolled_window.add (textview); - var label = new Gtk.Label (filename); - label.visible = true; - build_files_notebook.append_page (scrolled_window, label); - } catch (GLib.Error e) { - stderr.printf ("%s\n", e.message); + } else { + textview.cursor_visible = false; } + scrolled_window.add (textview); + var label = new Gtk.Label (file.get_basename ()); + label.visible = true; + build_files_notebook.append_page (scrolled_window, label); + } catch (GLib.Error e) { + stderr.printf ("%s\n", e.message); + return false; } + return true; } - public async void populate_build_files (string pkgname, bool clone, bool overwrite) { + public async bool populate_build_files (string pkgname, bool clone, bool overwrite) { build_files_notebook.foreach (destroy_widget); - File? clone_dir; if (clone) { - clone_dir = yield database.clone_build_files (pkgname, overwrite); - } else { - clone_dir = File.new_for_path (Path.build_path ("/", database.config.aur_build_dir, "pamac-build", pkgname)); + File? clone_dir = yield database.clone_build_files (pkgname, overwrite); + if (clone_dir == null) { + // error + return false; + } } - if (clone_dir != null) { - // diff - yield create_build_files_tab (clone_dir, "diff"); - // PKGBUILD - yield create_build_files_tab (clone_dir, "PKGBUILD"); - // other file - try { - FileEnumerator enumerator = yield clone_dir.enumerate_children_async ("standard::*", FileQueryInfoFlags.NONE); - FileInfo info; - while ((info = enumerator.next_file (null)) != null) { - string filename = info.get_name (); - if (".install" in filename || ".patch" in filename) { - yield create_build_files_tab (clone_dir, filename); - } + bool success = true; + string[] file_paths = yield get_build_files (pkgname); + foreach (unowned string path in file_paths) { + if ("PKGBUILD" in path) { + success = yield create_build_files_tab (path); + // add diff after PKGBUILD, do not failed if no diff + string diff_path = Path.build_path ("/", database.config.aur_build_dir, pkgname, "diff"); + var diff_file = File.new_for_path (diff_path); + if (diff_file.query_exists ()) { + success = yield create_build_files_tab (diff_path, false); } - } catch (Error e) { - print ("Error: %s\n", e.message); + } else { + // other file + success = yield create_build_files_tab (path); + } + if (!success) { + break; } } + return success; } - public async void save_build_files (string pkgname) { - string pkgdir_name = Path.build_path ("/", database.config.aur_build_dir, "pamac-build", pkgname); + public async bool save_build_files (string pkgname) { + bool success = true; int num_pages = build_files_notebook.get_n_pages (); int index = 0; while (index < num_pages) { Gtk.Widget child = build_files_notebook.get_nth_page (index); - string file_name = Path.build_path ("/", pkgdir_name, build_files_notebook.get_tab_label_text (child)); var scrolled_window = child as Gtk.ScrolledWindow; var textview = scrolled_window.get_child () as Gtk.TextView; - var file = File.new_for_path (file_name); - Gtk.TextIter start_iter; - Gtk.TextIter end_iter; - textview.buffer.get_start_iter (out start_iter); - textview.buffer.get_end_iter (out end_iter); - try { - // delete the file before rewrite it - yield file.delete_async (); - // creating a DataOutputStream to the file - var dos = new DataOutputStream (yield file.create_async (FileCreateFlags.REPLACE_DESTINATION)); - // writing a string to the stream - dos.put_string (textview.buffer.get_text (start_iter, end_iter, false)); - } catch (GLib.Error e) { - stderr.printf("%s\n", e.message); + if (textview.buffer.get_modified () == true) { + string pkgdir_name = Path.build_path ("/", database.config.aur_build_dir, pkgname); + string file_name = Path.build_path ("/", pkgdir_name, build_files_notebook.get_tab_label_text (child)); + var file = File.new_for_path (file_name); + Gtk.TextIter start_iter; + Gtk.TextIter end_iter; + textview.buffer.get_start_iter (out start_iter); + textview.buffer.get_end_iter (out end_iter); + try { + // delete the file before rewrite it + yield file.delete_async (); + // creating a DataOutputStream to the file + var dos = new DataOutputStream (yield file.create_async (FileCreateFlags.REPLACE_DESTINATION)); + // writing a string to the stream + dos.put_string (textview.buffer.get_text (start_iter, end_iter, false)); + if (build_files_notebook.get_tab_label_text (child) == "PKGBUILD") { + success = yield regenerate_srcinfo (pkgname); + } + } catch (GLib.Error e) { + stderr.printf("%s\n", e.message); + success = false; + } + } + if (!success) { + break; } index++; } - yield regenerate_srcinfo (pkgname); + return success; } void show_warnings (bool block) { diff --git a/src/transaction.vala b/src/transaction.vala index 14cd2c4e..a673e31b 100644 --- a/src/transaction.vala +++ b/src/transaction.vala @@ -47,7 +47,7 @@ namespace Pamac { GenericSet<string?> aur_desc_list; Queue<string> to_build_queue; string[] aur_pkgs_to_install; - GenericSet<string?> build_files_reviewed; + string[] aur_unresolvables; bool building; Cancellable build_cancellable; // download data @@ -113,11 +113,10 @@ namespace Pamac { temporary_ignorepkgs = {}; overwrite_files = {}; // building data - aurdb_path = "/tmp/pamac-aur"; + aurdb_path = "/tmp/pamac/aur-%s".printf (Environment.get_user_name ()); already_checked_aur_dep = new GenericSet<string?> (str_hash, str_equal); aur_desc_list = new GenericSet<string?> (str_hash, str_equal); to_build_queue = new Queue<string> (); - build_files_reviewed = new GenericSet<string?> (str_hash, str_equal); build_cancellable = new Cancellable (); building = false; // download data @@ -128,39 +127,82 @@ namespace Pamac { transaction_interface.quit_daemon (); } - protected virtual bool ask_confirmation (TransactionSummary summary) { + protected virtual bool ask_commit (TransactionSummary summary) { // no confirm return true; } - protected virtual bool ask_review_build_files () { - // no review + protected virtual bool ask_edit_build_files (TransactionSummary summary) { + // no edit return false; } - protected virtual async void review_build_files (string pkgname) { - // nothing + protected virtual async bool edit_build_files (string[] pkgnames) { + // success + return true; + } + + protected async string[] get_build_files (string pkgname) { + string pkgdir_name = Path.build_path ("/", database.config.aur_build_dir, pkgname); + string[] files = {}; + // PKGBUILD + files += Path.build_path ("/", pkgdir_name, "PKGBUILD"); + var srcinfo = File.new_for_path (Path.build_path ("/", pkgdir_name, ".SRCINFO")); + try { + // read .SRCINFO + var dis = new DataInputStream (srcinfo.read ()); + string line; + while ((line = yield dis.read_line_async ()) != null) { + if ("source = " in line) { + string source = line.split (" = ", 2)[1]; + if (!("://" in source)) { + string source_path = Path.build_path ("/", pkgdir_name, source); + var source_file = File.new_for_path (source_path); + if (source_file.query_exists ()) { + files += source_path; + } + } + } else if ("install = " in line) { + string install = line.split (" = ", 2)[1]; + string install_path = Path.build_path ("/", pkgdir_name, install); + var install_file = File.new_for_path (install_path); + if (install_file.query_exists ()) { + files += install_path; + } + } + } + } catch (GLib.Error e) { + stderr.printf("Error: %s\n", e.message); + } + return files; } - protected async void regenerate_srcinfo (string pkgname) { - string pkgdir_name = Path.build_path ("/", database.config.aur_build_dir, "pamac-build", pkgname); + protected async bool regenerate_srcinfo (string pkgname) { + string pkgdir_name = Path.build_path ("/", database.config.aur_build_dir, pkgname); // generate .SRCINFO var launcher = new SubprocessLauncher (SubprocessFlags.STDOUT_PIPE); launcher.set_cwd (pkgdir_name); + emit_action (dgettext (null, "Generating %s informations").printf (pkgname) + "..."); try { Subprocess process = launcher.spawnv ({"makepkg", "--printsrcinfo"}); yield process.wait_async (); - var dis = new DataInputStream (process.get_stdout_pipe ()); - var file = File.new_for_path (Path.build_path ("/", pkgdir_name, ".SRCINFO")); - // delete the file before rewrite it - yield file.delete_async (); - // creating a DataOutputStream to the file - var dos = new DataOutputStream (yield file.create_async (FileCreateFlags.REPLACE_DESTINATION)); - // writing makepkg output to .SRCINFO - yield dos.splice_async (dis, 0); + if (process.get_if_exited ()) { + if (process.get_exit_status () == 0) { + var dis = new DataInputStream (process.get_stdout_pipe ()); + var file = File.new_for_path (Path.build_path ("/", pkgdir_name, ".SRCINFO")); + // delete the file before rewrite it + yield file.delete_async (); + // creating a DataOutputStream to the file + var dos = new DataOutputStream (yield file.create_async (FileCreateFlags.REPLACE_DESTINATION)); + // writing makepkg output to .SRCINFO + yield dos.splice_async (dis, 0); + return true; + } + } } catch (Error e) { stderr.printf ("Error: %s\n", e.message); } + return false; } protected virtual int choose_provider (string depend, string[] providers) { @@ -275,171 +317,301 @@ namespace Pamac { downloading_updates_finished (); } - async void compute_aur_build_list () { + async bool compute_aur_build_list () { + string tmp_path = "/tmp/pamac"; try { + var file = GLib.File.new_for_path (tmp_path); + if (!file.query_exists ()) { + Process.spawn_command_line_sync ("mkdir -p %s".printf (tmp_path)); + Process.spawn_command_line_sync ("chmod a+w %s".printf (tmp_path)); + } Process.spawn_command_line_sync ("mkdir -p %s".printf (aurdb_path)); } catch (SpawnError e) { stderr.printf ("SpawnError: %s\n", e.message); } aur_desc_list.remove_all (); already_checked_aur_dep.remove_all (); - yield check_aur_dep_list (to_build); - // create a fake aur db - try { - var list = new StringBuilder (); - foreach (unowned string name_version in aur_desc_list) { - list.append (name_version); - list.append (" "); + bool success = yield check_aur_dep_list (to_build); + if (success) { + // create a fake aur db + try { + var list = new StringBuilder (); + foreach (unowned string name_version in aur_desc_list) { + list.append (name_version); + list.append (" "); + } + Process.spawn_command_line_sync ("rm -f %s/aur.db".printf (tmp_path)); + Process.spawn_command_line_sync ("bsdtar -cf %s/aur.db -C %s %s".printf (tmp_path, aurdb_path, list.str)); + } catch (SpawnError e) { + stderr.printf ("SpawnError: %s\n", e.message); + success = false; } - Process.spawn_command_line_sync ("rm -f %ssync/aur.db".printf (database.get_tmp_db_path ())); - Process.spawn_command_line_sync ("bsdtar -cf %ssync/aur.db -C %s %s".printf (database.get_tmp_db_path (), aurdb_path, list.str)); - } catch (SpawnError e) { - stderr.printf ("SpawnError: %s\n", e.message); } + return success; } - async void check_aur_dep_list (string[] pkgnames) { + async bool check_aur_dep_list (string[] pkgnames) { string[] dep_to_check = {}; - foreach (unowned string name in pkgnames) { + foreach (unowned string pkgname in pkgnames) { if (build_cancellable.is_cancelled ()) { - break; + return false; } string version = ""; string pkgbase = ""; string desc = ""; - string[] depends = {}; - string[] conflicts = {}; - string[] provides = {}; - string[] replaces = {}; - // clone build files - emit_action (dgettext (null, "Checking %s dependencies".printf (name)) + "..."); - File? clone_dir = yield database.clone_build_files (name, false); + string[] global_depends = {}; + string[] global_checkdepends = {}; + string[] global_makedepends = {}; + string[] global_conflicts = {}; + string[] global_provides = {}; + string[] global_replaces = {}; + File? clone_dir; + var aur_pkg = yield database.get_aur_pkg (pkgname); + if (aur_pkg.name == "") { + emit_error (dgettext (null, "target not found: %s").printf (pkgname), {}); + return false; + } else { + // clone build files + emit_action (dgettext (null, "Checking %s dependencies".printf (pkgname)) + "..."); + if (aur_pkg.name != aur_pkg.packagebase) { + // we have a split package + clone_dir = yield database.clone_build_files (aur_pkg.packagebase, false); + } else { + clone_dir = yield database.clone_build_files (aur_pkg.name, false); + } + } if (clone_dir == null) { // error - continue; + return false; } - // read .SRCINFO var srcinfo = clone_dir.get_child (".SRCINFO"); try { + // read .SRCINFO var dis = new DataInputStream (srcinfo.read ()); string line; - while ((line = dis.read_line ()) != null) { + string current_section = ""; + bool current_section_is_pkgbase = true; + string arch = Posix.utsname ().machine; + string[] pkgnames_found = {}; + var pkgnames_table = new HashTable<string, AURPackageDetailsStruct?> (str_hash, str_equal); + while ((line = yield dis.read_line_async ()) != null) { if ("pkgbase = " in line) { - pkgbase = line.split ("pkgbase = ", 2)[1]; + pkgbase = line.split (" = ", 2)[1]; } else if ("pkgdesc = " in line) { - desc = line.split ("pkgdesc = ", 2)[1]; + desc = line.split (" = ", 2)[1]; + if (!current_section_is_pkgbase) { + unowned AURPackageDetailsStruct? details_struct = pkgnames_table.get (current_section); + if (details_struct != null) { + details_struct.desc = desc; + } + } } else if ("pkgver = " in line) { version = line.split ("pkgver = ", 2)[1]; } else if ("pkgrel = " in line) { version += "-"; version += line.split ("pkgrel = ", 2)[1]; - // compute depends, makedepends and checkdepends in depends - } else if ("checkdepends = " in line) { - depends += line.split ("checkdepends = ", 2)[1]; - } else if ("makedepends = " in line) { - depends += line.split ("makedepends = ", 2)[1]; - } else if ("optdepends = " in line) { + } else if ("epoch = " in line) { + version = "%s:%s".printf (line.split (" = ", 2)[1], version); + // don't compute optdepends, it will be done by makepkg + } else if ("optdepends" in line) { // pass continue; - } else if ("depends = " in line) { - depends += line.split ("depends = ", 2)[1]; - } else if ("provides = " in line) { - provides += line.split ("provides = ", 2)[1]; - } else if ("conflicts = " in line) { - conflicts += line.split ("conflicts = ", 2)[1]; - } else if ("replaces = " in line) { - replaces += line.split ("replaces = ", 2)[1]; + // compute depends, makedepends and checkdepends: + // list name may contains arch, e.g. depends_x86_64 + // depends, provides, replaces and conflicts in pkgbase section are stored + // in order to be added after if the list in pkgname is empty, + // makedepends and checkdepends will be added in depends + } else if ("depends" in line) { + if ("depends = " in line || "depends_%s = ".printf (arch) in line) { + string depend = line.split (" = ", 2)[1]; + if (current_section_is_pkgbase){ + if ("checkdepends" in line) { + global_checkdepends += depend; + } else if ("makedepends" in line) { + global_makedepends += depend; + } else { + global_depends += depend; + } + } else { + unowned AURPackageDetailsStruct? details_struct = pkgnames_table.get (current_section); + if (details_struct != null) { + details_struct.depends += depend; + } + } + } + } else if ("provides" in line) { + if ("provides = " in line || "provides_%s = ".printf (arch) in line) { + string provide = line.split (" = ", 2)[1]; + if (current_section_is_pkgbase) { + global_provides += provide; + } else { + unowned AURPackageDetailsStruct? details_struct = pkgnames_table.get (current_section); + if (details_struct != null) { + details_struct.provides += provide; + } + } + } + } else if ("conflicts" in line) { + if ("conflicts = " in line || "conflicts_%s = ".printf (arch) in line) { + string conflict = line.split (" = ", 2)[1]; + if (current_section_is_pkgbase) { + global_conflicts += conflict; + } else { + unowned AURPackageDetailsStruct? details_struct = pkgnames_table.get (current_section); + if (details_struct != null) { + details_struct.conflicts += conflict; + } + } + } + } else if ("replaces" in line) { + if ("replaces = " in line || "replaces_%s = ".printf (arch) in line) { + string replace = line.split (" = ", 2)[1]; + if (current_section_is_pkgbase) { + global_replaces += replace; + } else { + unowned AURPackageDetailsStruct? details_struct = pkgnames_table.get (current_section); + if (details_struct != null) { + details_struct.replaces += replace; + } + } + } + } else if ("pkgname = " in line) { + string pkgname_found = line.split (" = ", 2)[1]; + current_section = pkgname_found; + current_section_is_pkgbase = false; + pkgnames_found += pkgname_found; + if (!pkgnames_table.contains (pkgname_found)) { + var details_struct = AURPackageDetailsStruct () { + name = pkgname_found, + version = version, + desc = desc, + packagebase = pkgbase + }; + pkgnames_table.insert (pkgname_found, (owned) details_struct); + } } } - // check deps - foreach (unowned string dep_string in depends) { - var pkg = database.find_installed_satisfier (dep_string); - if (pkg.name == "") { - pkg = database.find_sync_satisfier (dep_string); + // create fake aur db entries + foreach (unowned string pkgname_found in pkgnames_found) { + unowned AURPackageDetailsStruct? details_struct = pkgnames_table.get (pkgname_found); + // populate empty list will global ones + if (global_depends.length > 0 && details_struct.depends.length == 0) { + details_struct.depends = (owned) global_depends; + } + if (global_provides.length > 0 && details_struct.provides.length == 0) { + details_struct.provides = (owned) global_provides; + } + if (global_conflicts.length > 0 && details_struct.conflicts.length == 0) { + details_struct.conflicts = (owned) global_conflicts; + } + if (global_replaces.length > 0 && details_struct.replaces.length == 0) { + details_struct.replaces = (owned) global_replaces; + } + // add checkdepends and makedepends in depends + if (global_checkdepends.length > 0 ) { + foreach (unowned string depend in global_checkdepends) { + details_struct.depends += depend; + } + } + if (global_makedepends.length > 0 ) { + foreach (unowned string depend in global_makedepends) { + details_struct.depends += depend; + } } - if (pkg.name == "") { - string dep_name = Alpm.Depend.from_string (dep_string).name; - if (!(dep_name in already_checked_aur_dep)) { - already_checked_aur_dep.add (dep_name); - var aur_pkg = yield database.get_aur_pkg (dep_name); - if (aur_pkg.name != "") { - dep_to_check += (owned) dep_name; + // check deps + already_checked_aur_dep.add (pkgname_found); + foreach (unowned string dep_string in details_struct.depends) { + var pkg = database.find_installed_satisfier (dep_string); + if (pkg.name == "") { + pkg = database.find_sync_satisfier (dep_string); + } + if (pkg.name == "") { + string dep_name = Alpm.Depend.from_string (dep_string).name; + if (!(dep_name in already_checked_aur_dep)) { + already_checked_aur_dep.add (dep_name); + aur_pkg = yield database.get_aur_pkg (dep_name); + if (aur_pkg.name != "") { + dep_to_check += (owned) dep_name; + } } } } - } - // write desc file - string pkgdir = "%s-%s".printf (name, version); - string pkgdir_path = "%s/%s".printf (aurdb_path, pkgdir); - aur_desc_list.add (pkgdir); - var file = GLib.File.new_for_path (pkgdir_path); - // always recreate desc in case of .SRCINFO modifications - if (file.query_exists ()) { - Process.spawn_command_line_sync ("rm -rf %s".printf (pkgdir_path)); - } - file.make_directory (); - file = GLib.File.new_for_path ("%s/desc".printf (pkgdir_path)); - // creating a DataOutputStream to the file - var dos = new DataOutputStream (file.create (FileCreateFlags.REPLACE_DESTINATION)); - // fake filename - dos.put_string ("%FILENAME%\n" + "%s-%s-any.pkg.tar.xz\n\n".printf (name, version)); - // name - dos.put_string ("%NAME%\n%s\n\n".printf (name)); - // version - dos.put_string ("%VERSION%\n%s\n\n".printf (version)); - // base - dos.put_string ("%BASE%\n%s\n\n".printf (pkgbase)); - // desc - dos.put_string ("%DESC%\n%s\n\n".printf (desc)); - // version - dos.put_string ("%VERSION%\n%s\n\n".printf (version)); - // fake arch - dos.put_string ("%ARCH%\nany\n\n"); - // depends - if (depends.length > 0) { - dos.put_string ("%DEPENDS%\n"); - foreach (unowned string depend in depends) { - dos.put_string ("%s\n".printf (depend)); + // write desc file + string pkgdir = "%s-%s".printf (pkgname_found, details_struct.version); + string pkgdir_path = "%s/%s".printf (aurdb_path, pkgdir); + aur_desc_list.add (pkgdir); + var file = GLib.File.new_for_path (pkgdir_path); + if (!file.query_exists ()) { + file.make_directory (); } - dos.put_string ("\n"); - } - // conflicts - if (conflicts.length > 0) { - dos.put_string ("%CONFLICTS%\n"); - foreach (unowned string conflict in conflicts) { - dos.put_string ("%s\n".printf (conflict)); + file = GLib.File.new_for_path ("%s/desc".printf (pkgdir_path)); + // always recreate desc in case of .SRCINFO modifications + if (file.query_exists ()) { + yield file.delete_async (); } - dos.put_string ("\n"); - } - // provides - if (provides.length > 0) { - dos.put_string ("%PROVIDES%\n"); - foreach (unowned string provide in provides) { - dos.put_string ("%s\n".printf (provide)); + // creating a DataOutputStream to the file + var dos = new DataOutputStream (file.create (FileCreateFlags.REPLACE_DESTINATION)); + // fake filename + dos.put_string ("%FILENAME%\n" + "%s-%s-any.pkg.tar.xz\n\n".printf (pkgname_found, details_struct.version)); + // name + dos.put_string ("%NAME%\n%s\n\n".printf (pkgname_found)); + // version + dos.put_string ("%VERSION%\n%s\n\n".printf (details_struct.version)); + // base + dos.put_string ("%BASE%\n%s\n\n".printf (details_struct.packagebase)); + // desc + dos.put_string ("%DESC%\n%s\n\n".printf (details_struct.desc)); + // arch (double %% before ARCH to escape %A) + dos.put_string ("%%ARCH%\n%s\n\n".printf (arch)); + // depends + if (details_struct.depends.length > 0) { + dos.put_string ("%DEPENDS%\n"); + foreach (unowned string depend in details_struct.depends) { + dos.put_string ("%s\n".printf (depend)); + } + dos.put_string ("\n"); } - dos.put_string ("\n"); - } - // replaces - if (replaces.length > 0) { - dos.put_string ("%REPLACES%\n"); - foreach (unowned string replace in replaces) { - dos.put_string ("%s\n".printf (replace)); + // conflicts + if (details_struct.conflicts.length > 0) { + dos.put_string ("%CONFLICTS%\n"); + foreach (unowned string conflict in details_struct.conflicts) { + dos.put_string ("%s\n".printf (conflict)); + } + dos.put_string ("\n"); + } + // provides + if (details_struct.provides.length > 0) { + dos.put_string ("%PROVIDES%\n"); + foreach (unowned string provide in details_struct.provides) { + dos.put_string ("%s\n".printf (provide)); + } + dos.put_string ("\n"); + } + // replaces + if (details_struct.replaces.length > 0) { + dos.put_string ("%REPLACES%\n"); + foreach (unowned string replace in details_struct.replaces) { + dos.put_string ("%s\n".printf (replace)); + } + dos.put_string ("\n"); } - dos.put_string ("\n"); } } catch (GLib.Error e) { - GLib.stderr.printf("%s\n", e.message); + stderr.printf("Error: %s\n", e.message); + return false; } } + bool success = true; if (dep_to_check.length > 0) { - yield check_aur_dep_list (dep_to_check); + success = yield check_aur_dep_list (dep_to_check); } + return success; } void sysupgrade_real () { start_preparing (); // this will respond with trans_prepare_finished signal - transaction_interface.start_sysupgrade_prepare (enable_downgrade, temporary_ignorepkgs, to_build, overwrite_files); + transaction_interface.start_sysupgrade_prepare (enable_downgrade, to_build, temporary_ignorepkgs, overwrite_files); } public void start_sysupgrade (bool force_refresh, bool enable_downgrade, string[] temporary_ignorepkgs, string[] overwrite_files) { @@ -455,23 +627,26 @@ namespace Pamac { // set building to allow cancellation building = true; build_cancellable.reset (); - compute_aur_build_list.begin (() => { + compute_aur_build_list.begin ((obj, res) => { + bool success = compute_aur_build_list.end (res); building = false; - if (build_cancellable.is_cancelled ()) { + if (!success || build_cancellable.is_cancelled ()) { on_trans_prepare_finished (false); } - transaction_interface.start_trans_prepare (flags, to_install, to_remove, to_load, to_build, overwrite_files); + aur_unresolvables = {}; + transaction_interface.start_trans_prepare (flags, to_install, to_remove, to_load, to_build, temporary_ignorepkgs, overwrite_files); }); } else { - transaction_interface.start_trans_prepare (flags, to_install, to_remove, to_load, to_build, overwrite_files); + transaction_interface.start_trans_prepare (flags, to_install, to_remove, to_load, to_build, temporary_ignorepkgs, overwrite_files); } } - public void start (string[] to_install, string[] to_remove, string[] to_load, string[] to_build, string[] overwrite_files) { + public void start (string[] to_install, string[] to_remove, string[] to_load, string[] to_build, string[] temporary_ignorepkgs, string[] overwrite_files) { this.to_install = to_install; this.to_remove = to_remove; this.to_load = to_load; this.to_build = to_build; + this.temporary_ignorepkgs = temporary_ignorepkgs; this.overwrite_files = overwrite_files; emit_action (dgettext (null, "Preparing") + "..."); start_preparing (); @@ -517,7 +692,7 @@ namespace Pamac { build_cancellable.reset (); important_details_outpout (false); string [] built_pkgs = {}; - string pkgdir = Path.build_path ("/", database.config.aur_build_dir, "pamac-build", pkgname); + string pkgdir = Path.build_path ("/", database.config.aur_build_dir, pkgname); // building building = true; start_building (); @@ -739,6 +914,12 @@ namespace Pamac { transaction_interface.choose_provider (index); } + void on_emit_unresolvables (string[] unresolvables) { + foreach (unowned string unresolvable in unresolvables) { + aur_unresolvables += unresolvable; + } + } + void on_emit_progress (uint progress, string pkgname, uint percent, uint n_targets, uint current_target) { double fraction; switch (progress) { @@ -930,17 +1111,8 @@ namespace Pamac { } } - string[] get_build_files_to_review (string[] aur_pkgbases_to_build) { - string[] build_files_to_review = {}; - foreach (unowned string name in aur_pkgbases_to_build) { - if (!build_files_reviewed.contains (name)) { - build_files_to_review += name; - } - } - return build_files_to_review; - } - void on_trans_prepare_finished (bool success) { + stop_preparing (); if (success) { var summary_struct = transaction_interface.get_transaction_summary (); Type type = 0; @@ -964,14 +1136,16 @@ namespace Pamac { } else if (type != 0) { var summary = new TransactionSummary (summary_struct); if ((type & Type.BUILD) != 0) { - // ask to review build files - string[] build_files_to_review = get_build_files_to_review (summary_struct.aur_pkgbases_to_build); - if (build_files_to_review.length > 0) { - release (); - review_build_files_and_reprepare.begin ((owned) build_files_to_review); - return; + // ask to edit build files + if (summary_struct.aur_pkgbases_to_build.length > 0) { + if (ask_edit_build_files (summary)) { + release (); + edit_build_files_and_reprepare.begin (summary_struct.aur_pkgbases_to_build); + return; + } } // populate build queue + to_build_queue.clear (); foreach (unowned string name in summary_struct.aur_pkgbases_to_build) { to_build_queue.push_tail (name); } @@ -979,8 +1153,7 @@ namespace Pamac { foreach (unowned AURPackageStruct infos in summary_struct.to_build) { aur_pkgs_to_install += infos.name; } - stop_preparing (); - if (ask_confirmation (summary)) { + if (ask_commit (summary)) { if (type == Type.BUILD) { // there only AUR packages to build release (); @@ -988,23 +1161,15 @@ namespace Pamac { } else { start_commit (); } - } else if (ask_review_build_files ()) { - release (); - build_files_reviewed.remove_all (); - emit_script_output (""); - review_build_files_and_reprepare.begin (get_build_files_to_review (summary_struct.aur_pkgbases_to_build)); - return; } else { emit_action (dgettext (null, "Transaction cancelled") + "."); release (); to_build_queue.clear (); finish_transaction (false); } - } else if (ask_confirmation (summary)) { - stop_preparing (); + } else if (ask_commit (summary)) { start_commit (); } else { - stop_preparing (); emit_action (dgettext (null, "Transaction cancelled") + "."); release (); finish_transaction (false); @@ -1012,34 +1177,66 @@ namespace Pamac { } else { //var err = ErrorInfos (); //err.message = dgettext (null, "Nothing to do") + "\n"; - stop_preparing (); emit_action (dgettext (null, "Nothing to do") + "."); release (); finish_transaction (true); //handle_error (err); } + } else if (to_build.length > 0) { + check_aur_unresolvables_and_edit_build_files.begin (); } else { - stop_preparing (); handle_error (get_current_error ()); } } - async void review_build_files_and_reprepare (owned string[] build_files_to_review) { - // keep string during review_build_files - string[] build_files = (owned) build_files_to_review; - foreach (unowned string name in build_files) { - yield review_build_files (name); - build_files_reviewed.add (name); - } - emit_script_output (""); - // prepare again - if (sysupgrading) { - emit_action (dgettext (null, "Starting full system upgrade") + "..."); - sysupgrade_real (); + async void edit_build_files_and_reprepare (string[] pkgnames) { + // keep string during edit_build_files + string[] pkgnames_copy = pkgnames; + bool success = yield edit_build_files (pkgnames_copy); + if (success) { + emit_script_output (""); + // prepare again + if (sysupgrading) { + emit_action (dgettext (null, "Starting full system upgrade") + "..."); + sysupgrade_real (); + } else { + emit_action (dgettext (null, "Preparing") + "..."); + trans_prepare_real (); + } } else { - emit_action (dgettext (null, "Preparing") + "..."); - trans_prepare_real (); + if (ask_edit_build_files (new TransactionSummary (TransactionSummaryStruct ()))) { + edit_build_files_and_reprepare.begin (pkgnames_copy); + return; + } + var error = ErrorInfos () { + message = dgettext (null, "Failed to prepare transaction") + }; + handle_error (error); + } + } + + async void check_aur_unresolvables_and_edit_build_files () { + string[] aur_unresolvables_backup = aur_unresolvables; + aur_unresolvables = {}; + foreach (unowned string unresolvable in aur_unresolvables_backup) { + var aur_pkg = yield database.get_aur_pkg (unresolvable); + if (aur_pkg.name != "") { + aur_unresolvables += aur_pkg.name; + } + } + // also add other pkgs in to_build + foreach (unowned string name in to_build) { + if (!(name in aur_unresolvables)) { + aur_unresolvables += name; + } + } + if (aur_unresolvables.length > 0) { + if (ask_edit_build_files (new TransactionSummary (TransactionSummaryStruct ()))) { + edit_build_files_and_reprepare.begin (aur_unresolvables); + return; + } } + handle_error (get_current_error ()); } void launch_build_next_aur_package (bool authorized) { @@ -1054,7 +1251,6 @@ namespace Pamac { void on_trans_commit_finished (bool success) { if (success) { if (to_build_queue.get_length () != 0) { - build_files_reviewed.remove_all (); emit_script_output (""); get_authorization_finished.connect (launch_build_next_aur_package); start_get_authorization (); @@ -1104,6 +1300,7 @@ namespace Pamac { void connecting_signals () { transaction_interface.emit_event.connect (on_emit_event); transaction_interface.emit_providers.connect (on_emit_providers); + transaction_interface.emit_unresolvables.connect (on_emit_unresolvables); transaction_interface.emit_progress.connect (on_emit_progress); transaction_interface.emit_download.connect (on_emit_download); transaction_interface.emit_totaldownload.connect (on_emit_totaldownload); diff --git a/src/transaction_interface.vala b/src/transaction_interface.vala index aabf10e8..08976abf 100644 --- a/src/transaction_interface.vala +++ b/src/transaction_interface.vala @@ -30,8 +30,8 @@ namespace Pamac { public abstract void start_set_pkgreason (string pkgname, uint reason); public abstract void start_refresh (bool force); public abstract void start_downloading_updates (); - public abstract void start_sysupgrade_prepare (bool enable_downgrade, string[] temporary_ignorepkgs, string[] to_build, string[] overwrite_files); - public abstract void start_trans_prepare (int transflags, string[] to_install, string[] to_remove, string[] to_load, string[] to_build, string[] overwrite_files); + public abstract void start_sysupgrade_prepare (bool enable_downgrade, string[] to_build, string[] temporary_ignorepkgs, string[] overwrite_files); + public abstract void start_trans_prepare (int transflags, string[] to_install, string[] to_remove, string[] to_load, string[] to_build, string[] temporary_ignorepkgs, string[] overwrite_files); public abstract void choose_provider (int provider); public abstract TransactionSummaryStruct get_transaction_summary (); public abstract void start_trans_commit (); @@ -40,6 +40,7 @@ namespace Pamac { public abstract void quit_daemon (); 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_unresolvables (string[] unresolvables); 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); diff --git a/src/transaction_interface_daemon.vala b/src/transaction_interface_daemon.vala index 45f1965f..ca3a6e00 100644 --- a/src/transaction_interface_daemon.vala +++ b/src/transaction_interface_daemon.vala @@ -32,8 +32,8 @@ namespace Pamac { 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_downloading_updates () 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 start_sysupgrade_prepare (bool enable_downgrade, string[] to_build, string[] temporary_ignorepkgs, 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[] temporary_ignorepkgs, string[] overwrite_files) throws Error; public abstract void choose_provider (int provider) throws Error; public abstract TransactionSummaryStruct get_transaction_summary () throws Error; public abstract void start_trans_commit () throws Error; @@ -43,6 +43,7 @@ namespace Pamac { public abstract void quit () throws Error; 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_unresolvables (string[] unresolvables); 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); @@ -216,12 +217,12 @@ namespace Pamac { } void start_sysupgrade_prepare (bool enable_downgrade, - string[] temporary_ignorepkgs, string[] to_build, + string[] temporary_ignorepkgs, string[] overwrite_files) { try { // this will respond with trans_prepare_finished signal - system_daemon.start_sysupgrade_prepare (enable_downgrade, temporary_ignorepkgs, to_build, overwrite_files); + system_daemon.start_sysupgrade_prepare (enable_downgrade, to_build, temporary_ignorepkgs, overwrite_files); } catch (Error e) { stderr.printf ("start_sysupgrade_prepare: %s\n", e.message); } @@ -233,9 +234,10 @@ namespace Pamac { string[] to_remove, string[] to_load, string[] to_build, + string[] temporary_ignorepkgs, string[] overwrite_files) { try { - system_daemon.start_trans_prepare (flags, to_install, to_remove, to_load, to_build, overwrite_files); + system_daemon.start_trans_prepare (flags, to_install, to_remove, to_load, to_build, temporary_ignorepkgs, overwrite_files); } catch (Error e) { stderr.printf ("start_trans_prepare: %s\n", e.message); } @@ -297,6 +299,10 @@ namespace Pamac { } } + void on_emit_unresolvables (string[] unresolvables) { + emit_unresolvables (unresolvables); + } + void on_emit_progress (uint progress, string pkgname, uint percent, uint n_targets, uint current_target) { emit_progress (progress, pkgname, percent, n_targets, current_target); } @@ -342,6 +348,7 @@ namespace Pamac { void connecting_dbus_signals () { system_daemon.emit_event.connect (on_emit_event); system_daemon.emit_providers.connect (on_emit_providers); + system_daemon.emit_unresolvables.connect (on_emit_unresolvables); system_daemon.emit_progress.connect (on_emit_progress); system_daemon.emit_download.connect (on_emit_download); system_daemon.emit_totaldownload.connect (on_emit_totaldownload); diff --git a/src/transaction_interface_root.vala b/src/transaction_interface_root.vala index 31b54a26..d5cffe25 100644 --- a/src/transaction_interface_root.vala +++ b/src/transaction_interface_root.vala @@ -29,6 +29,9 @@ namespace Pamac { alpm_utils.emit_providers.connect ((depend, providers) => { emit_providers (depend, providers); }); + alpm_utils.emit_unresolvables.connect ((unresolvables) => { + emit_unresolvables (unresolvables); + }); alpm_utils.emit_progress.connect ((progress, pkgname, percent, n_targets, current_target) => { emit_progress (progress, pkgname, percent, n_targets, current_target); }); @@ -184,8 +187,8 @@ namespace Pamac { } public void start_sysupgrade_prepare (bool enable_downgrade, - string[] temporary_ignorepkgs, string[] to_build, + string[] temporary_ignorepkgs, string[] overwrite_files) { alpm_utils.enable_downgrade = enable_downgrade; alpm_utils.temporary_ignorepkgs = temporary_ignorepkgs; @@ -213,12 +216,14 @@ namespace Pamac { string[] to_remove, string[] to_load, string[] to_build, + string[] temporary_ignorepkgs, string[] overwrite_files) { alpm_utils.flags = flags; alpm_utils.to_install = to_install; alpm_utils.to_remove = to_remove; alpm_utils.to_load = to_load; alpm_utils.to_build = to_build; + alpm_utils.temporary_ignorepkgs = temporary_ignorepkgs; alpm_utils.overwrite_files = overwrite_files; alpm_utils.sysupgrade = false; if (alpm_utils.downloading_updates) { diff --git a/src/transaction_sum_dialog.vala b/src/transaction_sum_dialog.vala index c75fb4f3..7780f3ed 100644 --- a/src/transaction_sum_dialog.vala +++ b/src/transaction_sum_dialog.vala @@ -27,7 +27,7 @@ namespace Pamac { [GtkChild] Gtk.TreeView treeview; [GtkChild] - public Gtk.Button review_button; + public Gtk.Button edit_button; public Gtk.ListStore sum_list; -- GitLab