jjacky avatar jjacky committed 68244d7

added check for possible pacman/kalu conflict

Preferences, Upgrades: Check for pacman/kalu conflict (CheckPacmanConflict)
When enabled, kalu will check if there's an upgrade of pacman to be done, and if so if it is likely to prevent the sysupgrade due to kalu's dependency (i.e. if pacman's major or minor version number goes up, meaning probable changes in libalpm's API).
If so, an extra button will be featured on the notification, to show a message about this issue and how to perform the system upgrade.

Comments (0)

Files changed (7)

                     config->syncdbs_in_tooltip = (*value == '1');
                     debug ("config: syncdbs in tooltip: %d", config->syncdbs_in_tooltip);
                 }
+                else if (strcmp (key, "CheckPacmanConflict") == 0)
+                {
+                    config->check_pacman_conflict = (*value == '1');
+                    debug ("config: check for pacman/kalu conflict: %d",
+                           config->check_pacman_conflict);
+                }
                 else
                 {
                     add_error ("unknown option: %s", key);
     alpm_list_t     *cmdline_post;
     #endif
     gboolean         sane_sort_order;
+    gboolean         check_pacman_conflict;
     on_click_t       on_sgl_click;
     on_click_t       on_dbl_click;
     
 
 =over
 
+=item I<Check for pacman/kalu conflict>
+
+When showing the notification, kalu will check if there's an upgrade of pacman
+likely to prevent the system upgrade due to kalu's dependency to the current
+version of pacman (i.e. due to API changes in libalpm).
+
+If so, a button will be featured on the notification, to show a little message
+about the reason for such a conflict, and how to perform the system upgrade.
+
 =item I<Show a button "Upgrade system" on notifications (and on kalu's menu)>
 
 Whether or not notifications should feature a button "Upgrade system" and
 static void notify_updates (alpm_list_t *packages, check_t type, gchar *xml_news);
 static void kalu_check (gboolean is_auto);
 static void kalu_auto_check (void);
+static inline gboolean is_pacman_conflicting (alpm_list_t *packages);
 static void menu_check_cb (GtkMenuItem *item, gpointer data);
 static void menu_quit_cb (GtkMenuItem *item, gpointer data);
 static void icon_popup_cb (GtkStatusIcon *icon, guint button, guint activate_time, gpointer data);
     notification = new_notification (summary, text);
     if (type & CHECK_UPGRADES)
     {
+        if (config->check_pacman_conflict && is_pacman_conflicting (packages))
+        {
+            notify_notification_add_action (notification, "do_conflict_warn",
+                "Possible pacman/kalu conflict...",
+                (NotifyActionCallback) show_pacman_conflict,
+                NULL, NULL);
+        }
         if (config->action != UPGRADE_NO_ACTION)
         {
             notify_notification_add_action (notification, "do_updates",
     free (text);
 }
 
+static inline gboolean
+is_pacman_conflicting (alpm_list_t *packages)
+{
+    gboolean ret = FALSE;
+    alpm_list_t *i;
+    kalu_package_t *pkg;
+    char *s, *ss, *old, *new, *so, *sn;
+    
+    for (i = packages; i; i = alpm_list_next (i))
+    {
+        pkg = i->data;
+        if (strcmp ("pacman", pkg->name) == 0)
+        {
+            /* because we'll mess with it */
+            old = strdup (pkg->old_version);
+            /* locate begining of (major) version number (might have epoch: before) */
+            s = strchr (old, ':');
+            if (s)
+            {
+                so = s + 1;
+            }
+            else
+            {
+                so = old;
+            }
+            
+            s = strrchr (so, '-');
+            if (!s)
+            {
+                /* should not be possible */
+                free (old);
+                break;
+            }
+            *s = '.';
+            
+            /* because we'll mess with it */
+            new = strdup (pkg->new_version);
+            /* locate begining of (major) version number (might have epoch: before) */
+            s = strchr (new, ':');
+            if (s)
+            {
+                sn = s + 1;
+            }
+            else
+            {
+                sn = new;
+            }
+            
+            s = strrchr (sn, '-');
+            if (!s)
+            {
+                /* should not be possible */
+                free (old);
+                free (new);
+                break;
+            }
+            *s = '.';
+            
+            int nb = 0; /* to know which part (major/minor) we're dealing with */
+            while ((s = strchr (so, '.')) && (ss = strchr (sn, '.')))
+            {
+                *s = '\0';
+                *ss = '\0';
+                ++nb;
+                
+                /* if major or minor goes up, API changes is likely and kalu's
+                 * dependency will kick in */
+                if (atoi (sn) > atoi (so))
+                {
+                    ret = TRUE;
+                    break;
+                }
+                
+                /* if nb is 2 this was the minor number, past this we don't care */
+                if (nb == 2)
+                {
+                    break;
+                }
+                so = s + 1;
+                sn = ss + 1;
+            }
+            
+            free (old);
+            free (new);
+            break;
+        }
+    }
+    
+    return ret;
+}
+
 static void
 kalu_check_work (gboolean is_auto)
 {
     config->on_sgl_click = DO_CHECK;
     config->on_dbl_click = DO_SYSUPGRADE;
     config->sane_sort_order = TRUE;
+    config->check_pacman_conflict = TRUE;
     
     config->tpl_upgrades = calloc (1, sizeof (templates_t));
     config->tpl_upgrades->title = strdup ("$NB updates available (D: $DL; N: $NET)");
     gtk_widget_show (window);
     return TRUE;
 }
+
+void
+show_pacman_conflict ()
+{
+    GtkWidget     *window;
+    GtkWidget     *textview;
+    GtkTextBuffer *buffer;
+    const gchar   *text = "<h2>Possible pacman/kalu conflict</h2>"
+        "<p>The pending system upgrade is likely to fail due to kalu's dependency "
+        "on the current version of pacman. This is because the new pacman introduces "
+        "API changes in libalpm (on which kalu relies).</p>"
+        "<h2>How to upgrade?</h2>"
+        "<p>In order to upgrade your system, you will need to :"
+        "<br> <b>1.</b> Remove kalu (<pre>pacman -R kalu</pre>) This will <b>not</b> "
+        "remove your preferences, watched lists, etc"
+        "<br> <b>2.</b> Upgrade your system (<pre>pacman -Syu</pre>)"
+        "<br> <b>3.</b> Install a new version of kalu, compatible with the new "
+        "version of pacman.</p>"
+        "<p>If a new version of kalu for the new pacman isn't available on the "
+        "AUR yet, make sure to flag it as out-of-date.</p>"
+        ;
+    
+    new_window (FALSE, &window, &textview);
+    gtk_window_set_title (GTK_WINDOW (window), "Possible pacman/kalu conflict - kalu");
+    gtk_window_set_default_size (GTK_WINDOW (window), 600, 230);
+    buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview));
+    create_tags (buffer);
+    parse_to_buffer (buffer, text, (gsize) strlen (text));
+    gtk_widget_show (window);
+}
 gboolean
 show_history (GError **error);
 
+void
+show_pacman_conflict (void);
+
 #endif /* _KALU_NEWS_H */
 static GtkWidget *news_package_entry        = NULL;
 static GtkWidget *news_sep_entry            = NULL;
 /* Upgrades */
+static GtkWidget *check_pacman_conflict     = NULL;
 static GtkWidget *button_upg_action         = NULL;
 #ifndef DISABLE_UPDATER
 static GtkWidget *upg_action_combo          = NULL;
     new_config.checks_manual = type;
     
     /* Upgrades */
+    new_config.check_pacman_conflict = gtk_toggle_button_get_active (
+        GTK_TOGGLE_BUTTON (check_pacman_conflict));
+    add_to_conf ("CheckPacmanConflict = %d\n", new_config.check_pacman_conflict);
+    
     s = (char *) gtk_entry_get_text (GTK_ENTRY (cmdline_entry));
     if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button_upg_action)))
     {
     grid = gtk_grid_new ();
     lbl_page = gtk_label_new ("Upgrades");
     
+    /* CheckPacmanConflict */
+    check_pacman_conflict = gtk_check_button_new_with_label ("Check for pacman/kalu conflict");
+    gtk_widget_set_tooltip_text (check_pacman_conflict, 
+        "Check whether an upgrade of pacman is likely to fail due to kalu's dependency, "
+        "and if so adds a button on to notification to show a message about why "
+        "and how to upgrade.");
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_pacman_conflict),
+                                  config->check_pacman_conflict);
+    gtk_grid_attach (GTK_GRID (grid), check_pacman_conflict, 0, top, 4, 1);
+    gtk_widget_show (check_pacman_conflict);
+    
+    ++top;
     /* UpgradeAction */
     button_upg_action = gtk_check_button_new_with_label ("Show a button \"Upgrade system\" on notifications (and on kalu's menu)");
     gtk_widget_set_tooltip_text (button_upg_action, "Whether or not to show a button \"Upgrade system\" on notifications, as well as an item \"System upgrade\" on kalu's menu");
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.