From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp2 ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms0.migadu.com with LMTPS id kCLFIzknUmHxngAAgWs5BA (envelope-from ) for ; Mon, 27 Sep 2021 22:19:05 +0200 Received: from aspmx1.migadu.com ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp2 with LMTPS id iNxdHzknUmHGGgAAB5/wlQ (envelope-from ) for ; Mon, 27 Sep 2021 20:19:05 +0000 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 136B020870 for ; Mon, 27 Sep 2021 22:19:05 +0200 (CEST) Received: from localhost ([::1]:34126 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mUx5c-0005Is-6y for larch@yhetil.org; Mon, 27 Sep 2021 16:19:04 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38716) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mUwyo-0003wC-IZ for guix-patches@gnu.org; Mon, 27 Sep 2021 16:12:04 -0400 Received: from debbugs.gnu.org ([209.51.188.43]:59639) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mUwyo-0001xG-BO for guix-patches@gnu.org; Mon, 27 Sep 2021 16:12:02 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1mUwyo-0003FV-6s for guix-patches@gnu.org; Mon, 27 Sep 2021 16:12:02 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#50854] [PATCH 1/2] import: pypi: Honor the 'upstream-name' package property. Resent-From: Xinglu Chen Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Mon, 27 Sep 2021 20:12:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 50854 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 50854@debbugs.gnu.org Received: via spool by 50854-submit@debbugs.gnu.org id=B50854.163277349812447 (code B ref 50854); Mon, 27 Sep 2021 20:12:02 +0000 Received: (at 50854) by debbugs.gnu.org; 27 Sep 2021 20:11:38 +0000 Received: from localhost ([127.0.0.1]:42948 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mUwyJ-0003ET-N3 for submit@debbugs.gnu.org; Mon, 27 Sep 2021 16:11:38 -0400 Received: from h87-96-130-155.cust.a3fiber.se ([87.96.130.155]:60122 helo=mail.yoctocell.xyz) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mUwyH-0003ED-4g for 50854@debbugs.gnu.org; Mon, 27 Sep 2021 16:11:30 -0400 From: Xinglu Chen DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=yoctocell.xyz; s=mail; t=1632773481; bh=AMD08MdRIDPBMKnVZNSvVlmQtS2LM7ZucuK20cHwnU0=; h=From:To:Subject:In-Reply-To:References:Date; b=FyDAFr53R24FpHFC5EJFkS9e0s/xnAUp1jeMFLMMiefzIOyrMxHQzcg2uKCKvkUvX GO6Z9tlP+0JFtIVhkSlf1Tpfnou3gpFMaGQqTBf9Z6dcg0ipOu6IzAFbGvjhpc0M63 owZwN3VdNTCMxaHg4H7y/ZFfvAjrtIhG05XkbRR0= In-Reply-To: References: Message-Id: <45f4a38589689ee3c640ff54618405a6eb7c4f40.1632772958.git.public@yoctocell.xyz> Date: Mon, 27 Sep 2021 22:11:20 +0200 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+larch=yhetil.org@gnu.org Sender: "Guix-patches" X-Migadu-Flow: FLOW_IN ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1632773945; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding:resent-cc: resent-from:resent-sender:resent-message-id:in-reply-to:in-reply-to: references:references:list-id:list-help:list-unsubscribe: list-subscribe:list-post:dkim-signature; bh=v4Nr4VZIJrwgvtpUZc0k871UDid68VsGT/m/Pk/6xZk=; b=LFbvErzuxe5h/zp7eB0y1NpRl3yTR6H3rwHpcU0cgDwbTxH+Kk38K9z8JUfxKb1b/4ry2U bL8eB6LT7bNR6/YW1x0u3/xlkuY/H2I7fGzkvMVhZ6x2T/vgzih4lioxugefhH+wcMQI+e eMwns2lsCZSGh5oRI97wEOCyfj+s7JOl4UmPR41sQwu4yQaDneEMF+SCcUd58KU/NyWQnx rzVP62h1d0IsTdefhHf88M9cXfUgrR/7/9L8dCaM8SWs/H4f0wlcPpHjDVEfjj/pKSMXjs mWEAwVcAgBhkNAFn1fy8XAPCa2FnFI9+dk0dymFe9ttZjOpOzZBWOd87+L7jXQ== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1632773945; a=rsa-sha256; cv=none; b=PVJe5LldBnMbw3l4Lg5LbASikmQD2y2mB6WwPaM0dF36IsLsHMo3Jf/dhVPNh4TyDWwMkf WpTPC3xcAmIaUwuZSeaAUjGT8qIg7eQVS+uftWqh4csFDwheR+A09+OOtb9gGJvtkz/hK8 rBwF3jpucxUC4EPG/YV62L6CmjVmzQz8if0s68ylUhb2YkhiprTtEI7hM49Mlt9Z8CKFp7 /l523UZVhE+mODwk1eM/l8pmp3AHNlQlj7PCg+FInOlrmzwEt2BdOnvxSI3lUrdtP/irQQ bFrMBpPCdQHc9C8KNXekI8lSOUG9ON0/KYq0TbDwPHk3QyElR6bdv5pqOVaPBA== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=yoctocell.xyz header.s=mail header.b=FyDAFr53; spf=pass (aspmx1.migadu.com: domain of guix-patches-bounces@gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=guix-patches-bounces@gnu.org X-Migadu-Spam-Score: -0.29 Authentication-Results: aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=yoctocell.xyz header.s=mail header.b=FyDAFr53; dmarc=fail reason="SPF not aligned (relaxed)" header.from=yoctocell.xyz (policy=none); spf=pass (aspmx1.migadu.com: domain of guix-patches-bounces@gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=guix-patches-bounces@gnu.org X-Migadu-Queue-Id: 136B020870 X-Spam-Score: -0.29 X-Migadu-Scanner: scn0.migadu.com X-TUID: m/Cdrz5/ydHt Previously, when a PyPI package had a =E2=80=9C-=E2=80=9D followed by one o= r more digits in its name, e.g., =E2=80=9CAV-98=E2=80=9D, the importer would interpret =E2= =80=9C98=E2=80=9D as the version of the package and thus mistake the =E2=80=9CAV-98=E2=80=9D package for the = =E2=80=9Cav=E2=80=9D package on PyPI. $ ./pre-inst-env guix refresh av-98 following redirection to `https://pypi.org/pypi/av/json'... /home/yoctocell/src/guix/gnu/packages/web-browsers.scm:914:13: av-98 woul= d be upgraded from 1.0.1 to 8.0.3 Setting the =E2=80=98upstream-name=E2=80=99 property to =E2=80=9CAV-98=E2= =80=9D would solve the problem. $ ./pre-inst-env guix refresh av-98 /home/yoctocell/src/guix/gnu/packages/web-browsers.scm:914:13: 1.0.1 is a= lready the latest version of av-98 * guix/import/pypi.scm (guix-package->pypi-name): Honor =E2=80=98upstream-n= ame=E2=80=99 property. (make-pypi-sexp): Set =E2=80=98upstream-name=E2=80=99 property when appropr= iate. * tests/pypi.scm (test-json): Rename to ... (test-json-1): ... this. (test-json-2): New variable ("guix-package->pypi-name, honor 'upstream-name'"): New test. ("pypi->guix-package, package name contains \"-\" followed by digits"): Likewise. --- guix/import/pypi.scm | 20 +++++--- tests/pypi.scm | 106 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 113 insertions(+), 13 deletions(-) diff --git a/guix/import/pypi.scm b/guix/import/pypi.scm index 6731d50891..b7859c8341 100644 --- a/guix/import/pypi.scm +++ b/guix/import/pypi.scm @@ -9,6 +9,7 @@ ;;; Copyright =C2=A9 2020 Lars-Dominik Braun ;;; Copyright =C2=A9 2020 Arun Isaac ;;; Copyright =C2=A9 2020 Martin Becze +;;; Copyright =C2=A9 2021 Xinglu Chen ;;; ;;; This file is part of GNU Guix. ;;; @@ -163,12 +164,13 @@ (define (url->pypi-name url) (hyphen-package-name->name+version (basename (file-sans-extension url)))) =20 - (match (and=3D> (package-source package) origin-uri) - ((? string? url) - (url->pypi-name url)) - ((lst ...) - (any url->pypi-name lst)) - (#f #f))) + (or (assoc-ref (package-properties package) 'upstream-name) + (match (and=3D> (package-source package) origin-uri) + ((? string? url) + (url->pypi-name url)) + ((lst ...) + (any url->pypi-name lst)) + (#f #f)))) =20 (define (wheel-url->extracted-directory wheel-url) (match (string-split (basename wheel-url) #\-) @@ -423,6 +425,11 @@ (define (make-pypi-sexp name version source-url wheel-= url home-page synopsis description license) "Return the `package' s-expression for a python package with the given N= AME, VERSION, SOURCE-URL, HOME-PAGE, SYNOPSIS, DESCRIPTION, and LICENSE." + (define (maybe-upstream-name name) + (if (string-match ".*\\-[0-9]+" (pk name)) + `((properties ,`'(("upstream-name" . ,name)))) + '())) +=20=20 (call-with-temporary-output-file (lambda (temp port) (and (url-fetch source-url temp) @@ -461,6 +468,7 @@ (define (make-pypi-sexp name version source-url wheel-u= rl home-page synopsis (sha256 (base32 ,(guix-hash-url temp))))) + ,@(maybe-upstream-name name) (build-system python-build-system) ,@(maybe-inputs required-inputs 'propagated-inputs) ,@(maybe-inputs native-inputs 'native-inputs) diff --git a/tests/pypi.scm b/tests/pypi.scm index f421d6d9df..70f4298a90 100644 --- a/tests/pypi.scm +++ b/tests/pypi.scm @@ -2,6 +2,7 @@ ;;; Copyright =C2=A9 2014 David Thompson ;;; Copyright =C2=A9 2016 Ricardo Wurmus ;;; Copyright =C2=A9 2019 Maxim Cournoyer +;;; Copyright =C2=A9 2021 Xinglu Chen ;;; ;;; This file is part of GNU Guix. ;;; @@ -29,7 +30,7 @@ (define-module (test-pypi) #:use-module (srfi srfi-64) #:use-module (ice-9 match)) =20 -(define test-json +(define test-json-1 "{ \"info\": { \"version\": \"1.0.0\", @@ -57,6 +58,34 @@ (define test-json } }") =20 +(define test-json-2 + "{ + \"info\": { + \"version\": \"1.0.0\", + \"name\": \"foo-99\", + \"license\": \"GNU LGPL\", + \"summary\": \"summary\", + \"home_page\": \"http://example.com\", + \"classifiers\": [], + \"download_url\": \"\" + }, + \"urls\": [], + \"releases\": { + \"1.0.0\": [ + { + \"url\": \"https://example.com/foo-99-1.0.0.egg\", + \"packagetype\": \"bdist_egg\" + }, { + \"url\": \"https://example.com/foo-99-1.0.0.tar.gz\", + \"packagetype\": \"sdist\" + }, { + \"url\": \"https://example.com/foo-99-1.0.0-py2.py3-none-any.whl\", + \"packagetype\": \"bdist_wheel\" + } + ] + } +}") + (define test-source-hash "") =20 @@ -147,6 +176,13 @@ (define test-metadata-with-extras-jedi "\ (uri (list "https://bitheap.org/cram/cram-0.7.tar.gz" (pypi-uri "cram" "0.7")))))))) =20 +(test-equal "guix-package->pypi-name, honor 'upstream-name'" + "bar-3" + (guix-package->pypi-name + (dummy-package "foo" + (properties + '((upstream-name . "bar-3")))))) + (test-equal "specification->requirement-name" '("Fizzy" "PickyThing" "SomethingWithMarker" "requests" "pip") (map specification->requirement-name test-specifications)) @@ -198,8 +234,8 @@ (define test-metadata-with-extras-jedi "\ (lambda (url . rest) (match url ("https://pypi.org/pypi/foo/json" - (values (open-input-string test-json) - (string-length test-json))) + (values (open-input-string test-json-1) + (string-length test-json-1))) ("https://example.com/foo-1.0.0-py2.py3-none-any.whl"= #f) (_ (error "Unexpected URL: " url))))) (match (pypi->guix-package "foo") @@ -264,8 +300,8 @@ (define test-metadata-with-extras-jedi "\ (lambda (url . rest) (match url ("https://pypi.org/pypi/foo/json" - (values (open-input-string test-json) - (string-length test-json))) + (values (open-input-string test-json-1) + (string-length test-json-1))) ("https://example.com/foo-1.0.0-py2.py3-none-any.whl" #= f) (_ (error "Unexpected URL: " url))))) ;; Not clearing the memoization cache here would mean return= ing the value @@ -317,8 +353,8 @@ (define test-metadata-with-extras-jedi "\ (lambda (url . rest) (match url ("https://pypi.org/pypi/foo/json" - (values (open-input-string test-json) - (string-length test-json))) + (values (open-input-string test-json-1) + (string-length test-json-1))) ("https://example.com/foo-1.0.0-py2.py3-none-any.whl" #= f) (_ (error "Unexpected URL: " url))))) ;; Not clearing the memoization cache here would mean return= ing the value @@ -345,4 +381,60 @@ (define test-metadata-with-extras-jedi "\ (x (pk 'fail x #f)))))) =20 +(test-assert "pypi->guix-package, package name contains \"-\" followed by = digits" + ;; Replace network resources with sample data. + (mock ((guix import utils) url-fetch + (lambda (url file-name) + (match url + ("https://example.com/foo-99-1.0.0.tar.gz" + (begin + ;; Unusual requires.txt location should still be found. + (mkdir-p "foo-99-1.0.0/src/bizarre.egg-info") + (with-output-to-file "foo-99-1.0.0/src/bizarre.egg-info/re= quires.txt" + (lambda () + (display test-requires.txt))) + (parameterize ((current-output-port (%make-void-port "rw+"= ))) + (system* "tar" "czvf" file-name "foo-99-1.0.0/")) + (delete-file-recursively "foo-99-1.0.0") + (set! test-source-hash + (call-with-input-file file-name port-sha256)))) + ("https://example.com/foo-99-1.0.0-py2.py3-none-any.whl" #f) + (_ (error "Unexpected URL: " url))))) + (mock ((guix http-client) http-fetch + (lambda (url . rest) + (match url + ("https://pypi.org/pypi/foo-99/json" + (values (open-input-string test-json-2) + (string-length test-json-2))) + ("https://example.com/foo-99-1.0.0-py2.py3-none-any.whl= " #f) + (_ (error "Unexpected URL: " url))))) + (match (pypi->guix-package "foo-99") + (('package + ('name "python-foo-99") + ('version "1.0.0") + ('source ('origin + ('method 'url-fetch) + ('uri ('pypi-uri "foo-99" 'version)) + ('sha256 + ('base32 + (? string? hash))))) + ('properties ('quote (("upstream-name" . "foo-99")))) + ('build-system 'python-build-system) + ('propagated-inputs + ('quasiquote + (("python-bar" ('unquote 'python-bar)) + ("python-foo" ('unquote 'python-foo))))) + ('native-inputs + ('quasiquote + (("python-pytest" ('unquote 'python-pytest))))) + ('home-page "http://example.com") + ('synopsis "summary") + ('description "summary") + ('license 'license:lgpl2.0)) + (string=3D? (bytevector->nix-base32-string + test-source-hash) + hash)) + (x + (pk 'fail x #f)))))) + (test-end "pypi") --=20 2.33.0