launchpad.scm 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2019, 2020 Arun Isaac <arunisaac@systemreboot.net>
  3. ;;;
  4. ;;; This file is part of GNU Guix.
  5. ;;;
  6. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  7. ;;; under the terms of the GNU General Public License as published by
  8. ;;; the Free Software Foundation; either version 3 of the License, or (at
  9. ;;; your option) any later version.
  10. ;;;
  11. ;;; GNU Guix is distributed in the hope that it will be useful, but
  12. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. ;;; GNU General Public License for more details.
  15. ;;;
  16. ;;; You should have received a copy of the GNU General Public License
  17. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  18. (define-module (guix import launchpad)
  19. #:use-module (ice-9 match)
  20. #:use-module (srfi srfi-1)
  21. #:use-module (srfi srfi-26)
  22. #:use-module (web uri)
  23. #:use-module ((guix download) #:prefix download:)
  24. #:use-module (guix import json)
  25. #:use-module (guix packages)
  26. #:use-module (guix upstream)
  27. #:use-module (guix utils)
  28. #:export (%launchpad-updater))
  29. (define (find-extension url)
  30. "Return the extension of the archive e.g. '.tar.gz' given a URL, or
  31. false if none is recognized"
  32. (find (lambda (x) (string-suffix? x url))
  33. (list ".orig.tar.gz" ".tar.gz" ".tar.bz2" ".tar.xz"
  34. ".zip" ".tar" ".tgz" ".tbz" ".love")))
  35. (define (updated-launchpad-url old-package new-version)
  36. ;; Return a url for the OLD-PACKAGE with NEW-VERSION. If no source url in
  37. ;; the OLD-PACKAGE is a Launchpad url, then return false.
  38. (define (updated-url url)
  39. (and (string-prefix? "https://launchpad.net/" url)
  40. (let ((ext (or (find-extension url) ""))
  41. (name (package-name old-package))
  42. (version (package-version old-package))
  43. (repo (launchpad-repository url)))
  44. (cond
  45. ((< (length (string-split version #\.)) 2) #f)
  46. ((string=? (string-append "https://launchpad.net/"
  47. repo "/" (version-major+minor version)
  48. "/" version "/+download/" repo "-" version ext)
  49. url)
  50. (string-append "https://launchpad.net/"
  51. repo "/" (version-major+minor new-version)
  52. "/" new-version "/+download/" repo "-" new-version ext))
  53. ((string=? (string-append "https://launchpad.net/"
  54. repo "/" (version-major+minor version)
  55. "/" version "/+download/" repo "_" version ext)
  56. url)
  57. (string-append "https://launchpad.net/"
  58. repo "/" (version-major+minor new-version)
  59. "/" new-version "/+download/" repo "-" new-version ext))
  60. ((string=? (string-append "https://launchpad.net/"
  61. repo "/trunk/" version "/+download/"
  62. repo "-" version ext)
  63. url)
  64. (string-append "https://launchpad.net/"
  65. repo "/trunk/" new-version
  66. "/+download/" repo "-" new-version ext))
  67. ((string=? (string-append "https://launchpad.net/"
  68. repo "/trunk/" version "/+download/"
  69. repo "_" version ext)
  70. url)
  71. (string-append "https://launchpad.net/"
  72. repo "/trunk/" new-version
  73. "/+download/" repo "_" new-version ext))
  74. (#t #f))))) ; Some URLs are not recognised.
  75. (match (package-source old-package)
  76. ((? origin? origin)
  77. (let ((source-uri (origin-uri origin))
  78. (fetch-method (origin-method origin)))
  79. (and (eq? fetch-method download:url-fetch)
  80. (match source-uri
  81. ((? string?)
  82. (updated-url source-uri))
  83. ((source-uri ...)
  84. (any updated-url source-uri))))))
  85. (_ #f)))
  86. (define (launchpad-package? package)
  87. "Return true if PACKAGE is a package from Launchpad, else false."
  88. (->bool (updated-launchpad-url package "1.0.0")))
  89. (define (launchpad-repository url)
  90. "Return a string e.g. linuxdcpp of the name of the repository, from a string
  91. URL of the form
  92. 'https://launchpad.net/linuxdcpp/1.1/1.1.0/+download/linuxdcpp-1.1.0.tar.bz2'"
  93. (match (string-split (uri-path (string->uri url)) #\/)
  94. ((_ repo . rest) repo)))
  95. (define (latest-released-version package-name)
  96. "Return a string of the newest released version name given the PACKAGE-NAME,
  97. for example, 'linuxdcpp'. Return #f if there is no releases."
  98. (define (pre-release? x)
  99. ;; Versions containing anything other than digit characters and "." (for
  100. ;; example, "5.1.0-rc1") are assumed to be pre-releases.
  101. (not (string-every (char-set-union (char-set #\.)
  102. char-set:digit)
  103. (assoc-ref x "version"))))
  104. (assoc-ref
  105. (last (remove
  106. pre-release?
  107. (vector->list
  108. (assoc-ref (json-fetch
  109. (string-append "https://api.launchpad.net/1.0/"
  110. package-name "/releases"))
  111. "entries"))))
  112. "version"))
  113. (define (latest-release pkg)
  114. "Return an <upstream-source> for the latest release of PKG."
  115. (define (origin-github-uri origin)
  116. (match (origin-uri origin)
  117. ((? string? url) url) ; surely a Launchpad URL
  118. ((urls ...)
  119. (find (cut string-contains <> "launchpad.net") urls))))
  120. (let* ((source-uri (origin-github-uri (package-source pkg)))
  121. (name (package-name pkg))
  122. (newest-version (latest-released-version name)))
  123. (if newest-version
  124. (upstream-source
  125. (package name)
  126. (version newest-version)
  127. (urls (list (updated-launchpad-url pkg newest-version))))
  128. #f))) ; On Launchpad but no proper releases
  129. (define %launchpad-updater
  130. (upstream-updater
  131. (name 'launchpad)
  132. (description "Updater for Launchpad packages")
  133. (pred launchpad-package?)
  134. (latest latest-release)))