[aur-dev] [PATCH] Track providers in the official repositories

Lukas Fleischer lfleischer at archlinux.org
Wed Oct 21 20:06:56 UTC 2015


Maintain a list of virtual provisions of packages from the official
binary package repositories. The list can be updated using the aurblup
script, e.g. via a cronjob.

This allows for adding proper links to package dependencies: If an AUR
package depends on a package from the official repositories (or on a
name provided by a package from the official repositories), add a link
to the corresponding archweb package details page. If an AUR package
depends on another AUR package (or on a name provided by another AUR
package), add a link to the corresponding aurweb package details page.
Otherwise, just display the name and do not add a link at all.

Fixes FS#46549.

Signed-off-by: Lukas Fleischer <lfleischer at archlinux.org>
---
 schema/aur-schema.sql    | 10 ++++++++
 scripts/aurblup.py       | 13 ++++++++++
 upgrading/4.2.0.txt      | 11 +++++++++
 web/lib/pkgfuncs.inc.php | 64 ++++++++++++++++++++++++++++++++++++------------
 4 files changed, 82 insertions(+), 16 deletions(-)
 create mode 100644 upgrading/4.2.0.txt

diff --git a/schema/aur-schema.sql b/schema/aur-schema.sql
index 53dc468..0a0c806 100644
--- a/schema/aur-schema.sql
+++ b/schema/aur-schema.sql
@@ -301,6 +301,16 @@ CREATE TABLE PackageBlacklist (
 	UNIQUE (Name)
 ) ENGINE = InnoDB;
 
+-- Providers in the official repositories
+--
+CREATE TABLE OfficialProviders (
+	ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
+	Name VARCHAR(64) NOT NULL,
+	Provides VARCHAR(64) NOT NULL,
+	PRIMARY KEY (ID)
+) ENGINE = InnoDB;
+CREATE UNIQUE INDEX ProviderNameProvides ON OfficialProviders (Name, Provides);
+
 -- Define package request types
 --
 CREATE TABLE RequestTypes (
diff --git a/scripts/aurblup.py b/scripts/aurblup.py
index d6d0c3c..5397528 100755
--- a/scripts/aurblup.py
+++ b/scripts/aurblup.py
@@ -18,6 +18,7 @@ sync_dbs = config.get('aurblup', 'sync-dbs').split(' ')
 servers = config.get('aurblup', 'servers').split(' ')
 
 blacklist = set()
+providers = set()
 
 h = pyalpm.Handle("/", db_path)
 for sync_db in sync_dbs:
@@ -30,6 +31,8 @@ for sync_db in sync_dbs:
     for pkg in repo.pkgcache:
         blacklist.add(pkg.name)
         [blacklist.add(x) for x in pkg.replaces]
+        providers.add((pkg.name, pkg.name))
+        [providers.add((pkg.name, x)) for x in pkg.provides]
 
 db = mysql.connector.connect(host=aur_db_host, user=aur_db_user,
                              passwd=aur_db_pass, db=aur_db_name,
@@ -44,5 +47,15 @@ for pkg in blacklist.difference(oldblacklist):
 for pkg in oldblacklist.difference(blacklist):
     cur.execute("DELETE FROM PackageBlacklist WHERE Name = %s", [pkg])
 
+cur.execute("SELECT Name, Provides FROM OfficialProviders")
+oldproviders = set(cur.fetchall())
+
+for pkg, provides in providers.difference(oldproviders):
+    cur.execute("INSERT INTO OfficialProviders (Name, Provides) "
+                "VALUES (%s, %s)", [pkg, provides])
+for pkg, provides in oldproviders.difference(providers):
+    cur.execute("DELETE FROM OfficialProviders "
+                "WHERE Name = %s AND Provides = %s", [pkg, provides])
+
 db.commit()
 db.close()
diff --git a/upgrading/4.2.0.txt b/upgrading/4.2.0.txt
new file mode 100644
index 0000000..37cbeae
--- /dev/null
+++ b/upgrading/4.2.0.txt
@@ -0,0 +1,11 @@
+1. Add a new table to store providers from official packages:
+
+----
+CREATE TABLE OfficialProviders (
+	ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
+	Name VARCHAR(64) NOT NULL,
+	Provides VARCHAR(64) NOT NULL,
+	PRIMARY KEY (ID)
+) ENGINE = InnoDB;
+CREATE UNIQUE INDEX ProviderNameProvides ON OfficialProviders (Name, Provides);
+----
diff --git a/web/lib/pkgfuncs.inc.php b/web/lib/pkgfuncs.inc.php
index 66bc249..717085d 100644
--- a/web/lib/pkgfuncs.inc.php
+++ b/web/lib/pkgfuncs.inc.php
@@ -168,6 +168,9 @@ function pkg_providers($name) {
 	$q.= "INNER JOIN RelationTypes rt ON rt.ID = pr.RelTypeID ";
 	$q.= "WHERE rt.Name = 'provides' ";
 	$q.= "AND pr.RelName = " . $dbh->quote($name);
+	$q.= "UNION ";
+	$q.= "SELECT 0, Name FROM OfficialProviders ";
+	$q.= "WHERE Provides = " . $dbh->quote($name);
 	$result = $dbh->query($q);
 
 	if (!$result) {
@@ -281,6 +284,29 @@ function pkg_deplink_annotation($type, $arch, $desc=false) {
 }
 
 /**
+ * Get the HTML code to display a package provider link
+ *
+ * @param string $name The name of the provider
+ * @param bool $official True if the package is in the official repositories
+ *
+ * @return string The HTML code of the link to display
+ */
+function pkg_provider_link($name, $official) {
+	$link = '<a href="';
+	if ($official) {
+		$link .= 'https://www.archlinux.org/packages/?q=' .
+			urlencode($name);
+	} else {
+		$link .= htmlspecialchars(get_pkg_uri($name), ENT_QUOTES);
+	}
+	$link .= '" title="' . __('View packages details for') . ' ';
+	$link .= htmlspecialchars($name) . '">';
+	$link .= htmlspecialchars($name) . '</a>';
+
+	return $link;
+}
+
+/**
  * Get the HTML code to display a package dependency link
  *
  * @param string $name The name of the dependency
@@ -312,31 +338,37 @@ function pkg_depend_link($name, $type, $cond, $arch, $pkg_id) {
 		$providers = pkg_providers($name);
 	}
 
+	$link = htmlspecialchars($name);
+	foreach ($providers as $provider) {
+		if ($provider[1] == $name) {
+			$is_official = ($provider[0] == 0);
+			$name = $provider[1];
+			$link = pkg_provider_link($name, $is_official);
+			break;
+		}
+	}
+	$link .= ' ' . htmlspecialchars($cond);
+
+	foreach ($providers as $key => $provider) {
+		if ($provider[1] == $name) {
+			unset($providers[$key]);
+		}
+	}
+
 	if (count($providers) > 0) {
-		$link = htmlspecialchars($name) . ' ';
 		$link .= '<span class="virtual-dep">(';
 		foreach ($providers as $provider) {
+			$is_official = ($provider[0] == 0);
 			$name = $provider[1];
-			$link .= '<a href="';
-			$link .= htmlspecialchars(get_pkg_uri($name), ENT_QUOTES);
-			$link .= '" title="' . __('View packages details for') .' ' . htmlspecialchars($name) . '">';
-			$link .= htmlspecialchars($name) . '</a>, ';
+			$link .= pkg_provider_link($name, $is_official) . ', ';
 		}
 		$link = substr($link, 0, -2);
 		$link .= ')</span>';
-	} else {
-		$link = '<a href="';
-		if (is_null($pkg_id)) {
-			$link .= 'https://www.archlinux.org/packages/?q=' . urlencode($name);
-		} else {
-			$link .= htmlspecialchars(get_pkg_uri($name), ENT_QUOTES);
-		}
-		$link .= '" title="' . __('View packages details for') .' ' . htmlspecialchars($name) . '">';
-		$link .= htmlspecialchars($name) . '</a>';
-		$link .= htmlspecialchars($cond);
 	}
 
-	return $link . pkg_deplink_annotation($type, $arch, $desc);
+	$link .= pkg_deplink_annotation($type, $arch, $desc);
+
+	return $link;
 }
 
 /**
-- 
2.6.1


More information about the aur-dev mailing list