Commit c09096ef authored by guinux's avatar guinux

transaction process improvements

parent 4c401444
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
<property name="border_width">3</property> <property name="border_width">3</property>
<property name="title" translatable="yes">Transaction Summary</property> <property name="title" translatable="yes">Transaction Summary</property>
<property name="window_position">center-on-parent</property> <property name="window_position">center-on-parent</property>
<property name="default_width">600</property> <property name="default_width">700</property>
<property name="icon_name">system-software-install</property> <property name="icon_name">system-software-install</property>
<property name="type_hint">dialog</property> <property name="type_hint">dialog</property>
<property name="deletable">False</property> <property name="deletable">False</property>
...@@ -53,11 +53,23 @@ ...@@ -53,11 +53,23 @@
<property name="position">1</property> <property name="position">1</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkButton" id="review_button">
<property name="label" translatable="yes">Edit build files</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">2</property> <property name="position">2</property>
</packing> </packing>
</child> </child>
...@@ -152,6 +164,7 @@ ...@@ -152,6 +164,7 @@
<action-widgets> <action-widgets>
<action-widget response="-6">cancel_button</action-widget> <action-widget response="-6">cancel_button</action-widget>
<action-widget response="-5">apply_button</action-widget> <action-widget response="-5">apply_button</action-widget>
<action-widget response="-2">review_button</action-widget>
</action-widgets> </action-widgets>
</template> </template>
</interface> </interface>
...@@ -134,20 +134,19 @@ internal class AlpmConfig { ...@@ -134,20 +134,19 @@ internal class AlpmConfig {
} }
} }
public Alpm.Handle? get_handle (bool files_db = false, bool tmp_db = false, bool copy_dbs = true) { public Alpm.Handle? get_handle (bool files_db = false, bool tmp_db = false) {
Alpm.Errno error = 0; Alpm.Errno error = 0;
Alpm.Handle? handle = null; Alpm.Handle? handle = null;
if (tmp_db) { if (tmp_db) {
string tmp_dbpath = "/tmp/pamac-checkdbs"; string tmp_dbpath = "/tmp/pamac-checkdbs";
try { try {
if (! GLib.FileUtils.test (tmp_dbpath, GLib.FileTest.IS_DIR)) { var file = GLib.File.new_for_path (tmp_dbpath);
if (!file.query_exists ()) {
Process.spawn_command_line_sync ("mkdir -p %s/sync".printf (tmp_dbpath)); Process.spawn_command_line_sync ("mkdir -p %s/sync".printf (tmp_dbpath));
Process.spawn_command_line_sync ("ln -sf %slocal %s".printf (dbpath, tmp_dbpath));
Process.spawn_command_line_sync ("chmod -R 777 %s/sync".printf (tmp_dbpath)); Process.spawn_command_line_sync ("chmod -R 777 %s/sync".printf (tmp_dbpath));
if (copy_dbs) {
Process.spawn_command_line_sync ("bash -c 'cp -p %ssync/*.{db,files} %s/sync'".printf (dbpath, tmp_dbpath));
}
} }
Process.spawn_command_line_sync ("ln -sf %slocal %s".printf (dbpath, tmp_dbpath));
Process.spawn_command_line_sync ("cp -au %ssync %s".printf (dbpath, tmp_dbpath));
handle = new Alpm.Handle (rootdir, tmp_dbpath, out error); handle = new Alpm.Handle (rootdir, tmp_dbpath, out error);
if (error == Alpm.Errno.DB_VERSION) { if (error == Alpm.Errno.DB_VERSION) {
try { try {
......
...@@ -29,7 +29,6 @@ namespace Pamac { ...@@ -29,7 +29,6 @@ namespace Pamac {
internal Mutex provider_mutex; internal Mutex provider_mutex;
internal int? choosen_provider; internal int? choosen_provider;
internal bool force_refresh; internal bool force_refresh;
internal bool refreshed;
internal bool enable_downgrade; internal bool enable_downgrade;
internal int flags; internal int flags;
string[] to_syncfirst; string[] to_syncfirst;
...@@ -72,7 +71,6 @@ namespace Pamac { ...@@ -72,7 +71,6 @@ namespace Pamac {
refresh_handle (); refresh_handle ();
cancellable = new Cancellable (); cancellable = new Cancellable ();
curl = new Curl.Easy (); curl = new Curl.Easy ();
refreshed = false;
downloading_updates = false; downloading_updates = false;
Curl.global_init (Curl.GLOBAL_SSL); Curl.global_init (Curl.GLOBAL_SSL);
} }
...@@ -198,7 +196,6 @@ namespace Pamac { ...@@ -198,7 +196,6 @@ namespace Pamac {
if (cancellable.is_cancelled ()) { if (cancellable.is_cancelled ()) {
refresh_finished (false); refresh_finished (false);
} else if (success) { } else if (success) {
refreshed = true;
refresh_finished (true); refresh_finished (true);
} else { } else {
current_error.message = _("Failed to synchronize any databases"); current_error.message = _("Failed to synchronize any databases");
...@@ -281,7 +278,7 @@ namespace Pamac { ...@@ -281,7 +278,7 @@ namespace Pamac {
internal int download_updates () { internal int download_updates () {
downloading_updates = true; downloading_updates = true;
// use tmp handle // use tmp handle
var handle = alpm_config.get_handle (false, true, false); var handle = alpm_config.get_handle (false, true);
handle.fetchcb = (Alpm.FetchCallBack) cb_fetch; handle.fetchcb = (Alpm.FetchCallBack) cb_fetch;
cancellable.reset (); cancellable.reset ();
int success = handle.trans_init (Alpm.TransFlag.DOWNLOADONLY); int success = handle.trans_init (Alpm.TransFlag.DOWNLOADONLY);
...@@ -899,6 +896,14 @@ namespace Pamac { ...@@ -899,6 +896,14 @@ namespace Pamac {
} }
trans_release (); trans_release ();
if (success) { if (success) {
// remove syncfirsts from to_install
string[] to_install_backup = to_install;
to_install = {};
foreach (unowned string name in to_install_backup) {
if (!(name in to_syncfirst)) {
to_install += name;
}
}
success = trans_init (flags); success = trans_init (flags);
if (success && sysupgrade) { if (success && sysupgrade) {
success = trans_sysupgrade (); success = trans_sysupgrade ();
...@@ -929,7 +934,14 @@ namespace Pamac { ...@@ -929,7 +934,14 @@ namespace Pamac {
} }
if (success) { if (success) {
success = trans_prepare_real (); success = trans_prepare_real ();
} else { // continue if needed
if (success && (alpm_handle.trans_to_add ().length + alpm_handle.trans_to_remove ().length) == 0) {
trans_release ();
trans_commit_finished (success);
return;
}
}
if (!success) {
trans_release (); trans_release ();
} }
} }
......
...@@ -316,7 +316,7 @@ namespace Pamac { ...@@ -316,7 +316,7 @@ namespace Pamac {
i++; i++;
} }
if (!error) { if (!error) {
try_lock_and_run (start_refresh); try_lock_and_run (start_sysupgrade);
} }
} else { } else {
display_help (); display_help ();
...@@ -337,7 +337,6 @@ namespace Pamac { ...@@ -337,7 +337,6 @@ namespace Pamac {
transaction = new TransactionCli (database); transaction = new TransactionCli (database);
transaction.finished.connect (on_transaction_finished); transaction.finished.connect (on_transaction_finished);
transaction.sysupgrade_finished.connect (on_transaction_finished); transaction.sysupgrade_finished.connect (on_transaction_finished);
transaction.refresh_finished.connect (on_refresh_finished);
transaction.start_preparing.connect (() => { transaction.start_preparing.connect (() => {
trans_cancellable = true; trans_cancellable = true;
}); });
...@@ -844,7 +843,7 @@ namespace Pamac { ...@@ -844,7 +843,7 @@ namespace Pamac {
} }
} }
foreach (unowned string pkgname in pkgnames) { foreach (unowned string pkgname in pkgnames) {
var details = database.get_pkg_details (pkgname, ""); var details = database.get_pkg_details (pkgname, "", false);
if (details.name == "") { if (details.name == "") {
print_error (dgettext (null, "target not found: %s").printf (pkgname) + "\n"); print_error (dgettext (null, "target not found: %s").printf (pkgname) + "\n");
continue; continue;
...@@ -1650,29 +1649,19 @@ namespace Pamac { ...@@ -1650,29 +1649,19 @@ namespace Pamac {
} }
} }
void start_refresh () { void start_sysupgrade () {
if (Posix.geteuid () != 0) { if (Posix.geteuid () != 0) {
// let's time to pkttyagent to get registred // let's time to pkttyagent to get registred
Timeout.add (200, () => { Timeout.add (200, () => {
transaction.start_refresh (force_refresh); transaction.start_sysupgrade (force_refresh, enable_downgrade, temporary_ignorepkgs, overwrite_files);
return false; return false;
}); });
} else { } else {
transaction.start_refresh (force_refresh); transaction.start_sysupgrade (force_refresh, enable_downgrade, temporary_ignorepkgs, overwrite_files);
} }
loop.run (); loop.run ();
} }
void on_refresh_finished (bool success) {
if (success) {
transaction.start_sysupgrade (enable_downgrade, temporary_ignorepkgs, overwrite_files);
} else {
transaction.unlock ();
loop.quit ();
exit_status = 1;
}
}
void on_transaction_finished (bool success) { void on_transaction_finished (bool success) {
transaction.unlock (); transaction.unlock ();
loop.quit (); loop.quit ();
......
...@@ -28,6 +28,7 @@ namespace Pamac { ...@@ -28,6 +28,7 @@ namespace Pamac {
string locale; string locale;
public signal void get_updates_progress (uint percent); public signal void get_updates_progress (uint percent);
public signal void refreshed ();
public Config config { get; construct set; } public Config config { get; construct set; }
...@@ -75,6 +76,7 @@ namespace Pamac { ...@@ -75,6 +76,7 @@ namespace Pamac {
} else { } else {
files_handle = alpm_config.get_handle (true); files_handle = alpm_config.get_handle (true);
} }
refreshed ();
} }
public List<string> get_mirrors_countries () { public List<string> get_mirrors_countries () {
...@@ -852,7 +854,7 @@ namespace Pamac { ...@@ -852,7 +854,7 @@ namespace Pamac {
return optdeps; return optdeps;
} }
public PackageDetails get_pkg_details (string pkgname, string appname) { public PackageDetails get_pkg_details (string pkgname, string appname, bool use_sync_pkg) {
string name = ""; string name = "";
string app_name = ""; string app_name = "";
string version = ""; string version = "";
...@@ -881,7 +883,7 @@ namespace Pamac { ...@@ -881,7 +883,7 @@ namespace Pamac {
var details = PackageDetailsStruct (); var details = PackageDetailsStruct ();
unowned Alpm.Package? alpm_pkg = alpm_handle.localdb.get_pkg (pkgname); unowned Alpm.Package? alpm_pkg = alpm_handle.localdb.get_pkg (pkgname);
unowned Alpm.Package? sync_pkg = get_syncpkg (pkgname); unowned Alpm.Package? sync_pkg = get_syncpkg (pkgname);
if (alpm_pkg == null) { if (alpm_pkg == null || use_sync_pkg) {
alpm_pkg = sync_pkg; alpm_pkg = sync_pkg;
} else { } else {
installed_version = alpm_pkg.version; installed_version = alpm_pkg.version;
...@@ -1121,10 +1123,25 @@ namespace Pamac { ...@@ -1121,10 +1123,25 @@ namespace Pamac {
return version.str; return version.str;
} }
public async string clone_build_files (string pkgname, bool overwrite_files) { async int launch_subprocess (SubprocessLauncher launcher, string[] cmds) {
int status = 1;
try {
Subprocess process = launcher.spawnv (cmds);
yield process.wait_async ();
if (process.get_if_exited ()) {
status = process.get_exit_status ();
}
} catch (Error e) {
stderr.printf ("Error: %s\n", e.message);
}
return status;
}
public async File? clone_build_files (string pkgname, bool overwrite_files) {
int status = 1; int status = 1;
string builddir_name = Path.build_path ("/", config.aur_build_dir, "pamac-build"); string builddir_name = Path.build_path ("/", config.aur_build_dir, "pamac-build");
string[] cmds; string[] cmds;
var launcher = new SubprocessLauncher (SubprocessFlags.NONE);
var builddir = File.new_for_path (builddir_name); var builddir = File.new_for_path (builddir_name);
if (!builddir.query_exists ()) { if (!builddir.query_exists ()) {
try { try {
...@@ -1134,59 +1151,77 @@ namespace Pamac { ...@@ -1134,59 +1151,77 @@ namespace Pamac {
stderr.printf ("Error: %s\n", e.message); stderr.printf ("Error: %s\n", e.message);
} }
} }
string pkgdir_name = builddir_name + "/" + pkgname; var pkgdir = builddir.get_child (pkgname);
var pkgdir = File.new_for_path (pkgdir_name);
var launcher = new SubprocessLauncher (SubprocessFlags.NONE);
if (overwrite_files) {
try {
Process.spawn_command_line_sync ("rm -rf %s".printf (pkgdir_name));
} catch (Error e) {
stderr.printf ("Error: %s\n", e.message);
}
}
if (pkgdir.query_exists ()) { if (pkgdir.query_exists ()) {
var aur_pkg = yield get_aur_pkg (pkgname); if (overwrite_files) {
if (aur_pkg.version == get_srcinfo_version (pkgdir_name)) { launcher.set_cwd (builddir_name);
// up to date cmds = {"rm", "-rf %s".printf (pkgdir.get_path ())};
return pkgdir_name; yield launch_subprocess (launcher, cmds);
cmds = {"git", "clone", "-q", "--depth=1", "https://aur.archlinux.org/%s.git".printf (pkgname)};
} else { } else {
launcher.set_cwd (pkgdir_name); var aur_pkg = yield get_aur_pkg (pkgname);
cmds = {"git", "pull", "-q"}; if (aur_pkg.version == get_srcinfo_version (pkgdir.get_path ())) {
try { // up to date
Subprocess process = launcher.spawnv (cmds); return pkgdir;
yield process.wait_async (); }
if (process.get_if_exited ()) { // fetch modifications
status = process.get_exit_status (); launcher.set_cwd (pkgdir.get_path ());
} cmds = {"git", "fetch", "-q"};
if (status == 0) { status = yield launch_subprocess (launcher, cmds);
return pkgdir_name; // write diff file
} else { if (status == 0) {
Process.spawn_command_line_sync ("rm -rf %s".printf (pkgdir_name)); launcher.set_flags (SubprocessFlags.STDOUT_PIPE);
launcher.set_cwd (builddir_name); try {
cmds = {"git", "clone", "-q", "--depth=1", "https://aur.archlinux.org/%s.git".printf (pkgname)}; 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);
if (process.get_if_exited ()) {
status = process.get_exit_status ();
}
} catch (Error e) {
stderr.printf ("Error: %s\n", e.message);
} }
} catch (Error e) { launcher.set_flags (SubprocessFlags.NONE);
stderr.printf ("Error: %s\n", e.message); }
// merge modifications
if (status == 0) {
cmds = {"git", "merge", "-q"};
status = yield launch_subprocess (launcher, cmds);
}
if (status == 0) {
return pkgdir;
} else {
launcher.set_cwd (builddir_name);
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 { } else {
launcher.set_cwd (builddir_name); launcher.set_cwd (builddir_name);
cmds = {"git", "clone", "-q", "--depth=1", "https://aur.archlinux.org/%s.git".printf (pkgname)}; cmds = {"git", "clone", "-q", "--depth=1", "https://aur.archlinux.org/%s.git".printf (pkgname)};
} }
try { status = yield launch_subprocess (launcher, cmds);
Subprocess process = launcher.spawnv (cmds); if (status == 0) {
yield process.wait_async (); try {
Process.spawn_command_line_sync ("chmod --quiet -R ugo+w %s".printf (pkgdir_name)); Process.spawn_command_line_sync ("chmod --quiet -R ugo+w %s".printf (pkgdir.get_path ()));
if (process.get_if_exited ()) { } catch (Error e) {
status = process.get_exit_status (); stderr.printf ("Error: %s\n", e.message);
} }
} catch (Error e) {
stderr.printf ("Error: %s\n", e.message);
} }
if (status == 0) { if (status == 0) {
return pkgdir_name; return pkgdir;
} }
return ""; return null;
} }
public async AURPackage get_aur_pkg (string pkgname) { public async AURPackage get_aur_pkg (string pkgname) {
...@@ -1372,7 +1407,7 @@ namespace Pamac { ...@@ -1372,7 +1407,7 @@ namespace Pamac {
return get_aur_updates_real (yield aur_multiinfo (local_pkgs)); return get_aur_updates_real (yield aur_multiinfo (local_pkgs));
} }
public void refresh_files_dbs () { public async void refresh_tmp_files_dbs () {
var tmp_files_handle = alpm_config.get_handle (true, true); var tmp_files_handle = alpm_config.get_handle (true, true);
unowned Alpm.List<unowned Alpm.DB> syncdbs = tmp_files_handle.syncdbs; unowned Alpm.List<unowned Alpm.DB> syncdbs = tmp_files_handle.syncdbs;
while (syncdbs != null) { while (syncdbs != null) {
...@@ -1384,12 +1419,11 @@ namespace Pamac { ...@@ -1384,12 +1419,11 @@ namespace Pamac {
public async Updates get_updates () { public async Updates get_updates () {
// be sure we have the good updates // be sure we have the good updates
refresh (); alpm_config = new AlpmConfig ("/etc/pacman.conf");
var tmp_handle = alpm_config.get_handle (false, true);
var repos_updates = new List<Package> (); var repos_updates = new List<Package> ();
unowned Alpm.Package? pkg = null; unowned Alpm.Package? pkg = null;
unowned Alpm.Package? candidate = null; unowned Alpm.Package? candidate = null;
// use a tmp handle
var tmp_handle = alpm_config.get_handle (false, true);
// refresh tmp dbs // refresh tmp dbs
// count this step as 90% of the total // count this step as 90% of the total
get_updates_progress (0); get_updates_progress (0);
......
...@@ -39,8 +39,8 @@ namespace Pamac { ...@@ -39,8 +39,8 @@ namespace Pamac {
base.startup (); base.startup ();
important_details = false; important_details = false;
var pamac_config = new Config ("/etc/pamac.conf"); var config = new Config ("/etc/pamac.conf");
database = new Database (pamac_config); database = new Database (config);
// integrate progress box and term widget // integrate progress box and term widget
progress_dialog = new ProgressDialog (); progress_dialog = new ProgressDialog ();
transaction = new TransactionGtk (database, progress_dialog as Gtk.ApplicationWindow); transaction = new TransactionGtk (database, progress_dialog as Gtk.ApplicationWindow);
...@@ -151,6 +151,7 @@ namespace Pamac { ...@@ -151,6 +151,7 @@ namespace Pamac {
} }
void on_transaction_finished (bool success) { void on_transaction_finished (bool success) {
transaction.unlock ();
if (!success || important_details) { if (!success || important_details) {
progress_dialog.close_button.visible = true; progress_dialog.close_button.visible = true;
} else { } else {
......
This diff is collapsed.
...@@ -50,7 +50,7 @@ executable('pamac-system-daemon', ...@@ -50,7 +50,7 @@ executable('pamac-system-daemon',
libpamac = library('pamac', libpamac = library('pamac',
sources: [common_sources, 'error.vala', 'alpm_config.vala', 'aur.vala', 'database.vala', 'transaction_interface.vala', 'alpm_utils.vala', 'transaction_interface_root.vala', 'transaction_interface_daemon.vala', 'transaction.vala'], sources: [common_sources, 'error.vala', 'alpm_config.vala', 'aur.vala', 'database.vala', 'transaction_interface.vala', 'alpm_utils.vala', 'transaction_interface_root.vala', 'transaction_interface_daemon.vala', 'transaction.vala'],
dependencies: [gio, posix, math, json, appstream, libsoup, libalpm, libcurl], dependencies: [alpm_deps, math, json, appstream, libsoup, libcurl],
vala_args: [common_vala_args, alpm_vala_args, '--thread'], vala_args: [common_vala_args, alpm_vala_args, '--thread'],
c_args: [common_c_args, alpm_c_args], c_args: [common_c_args, alpm_c_args],
vala_gir: 'Pamac-1.0.gir', vala_gir: 'Pamac-1.0.gir',
......
...@@ -56,6 +56,7 @@ namespace Pamac { ...@@ -56,6 +56,7 @@ namespace Pamac {
public signal void emit_log (uint level, string msg); public signal void emit_log (uint level, string msg);
public signal void set_pkgreason_finished (); public signal void set_pkgreason_finished ();
public signal void refresh_finished (bool success); public signal void refresh_finished (bool success);
public signal void database_modified ();
public signal void downloading_updates_finished (); public signal void downloading_updates_finished ();
public signal void trans_prepare_finished (bool success); public signal void trans_prepare_finished (bool success);
public signal void trans_commit_finished (bool success); public signal void trans_commit_finished (bool success);
...@@ -76,7 +77,7 @@ namespace Pamac { ...@@ -76,7 +77,7 @@ namespace Pamac {
lockfile = GLib.File.new_for_path (alpm_utils.alpm_handle.lockfile); lockfile = GLib.File.new_for_path (alpm_utils.alpm_handle.lockfile);
check_old_lock (); check_old_lock ();
check_extern_lock (); check_extern_lock ();
Timeout.add (500, check_extern_lock); Timeout.add (200, check_extern_lock);
create_thread_pool (); create_thread_pool ();
refreshed = false; refreshed = false;
alpm_utils.emit_event.connect ((primary_event, secondary_event, details) => { alpm_utils.emit_event.connect ((primary_event, secondary_event, details) => {
...@@ -107,6 +108,7 @@ namespace Pamac { ...@@ -107,6 +108,7 @@ namespace Pamac {
trans_prepare_finished (success); trans_prepare_finished (success);
}); });
alpm_utils.trans_commit_finished.connect ((success) => { alpm_utils.trans_commit_finished.connect ((success) => {
database_modified ();
trans_commit_finished (success); trans_commit_finished (success);
}); });
} }
...@@ -209,6 +211,7 @@ namespace Pamac { ...@@ -209,6 +211,7 @@ namespace Pamac {
if (!lockfile.query_exists ()) { if (!lockfile.query_exists ()) {