2021-08-10 11:07:20 -04:00
|
|
|
|
;;; GNU Guix --- Functional package management for GNU
|
2022-01-05 09:07:48 -05:00
|
|
|
|
;;; Copyright © 2021, 2022 Maxime Devos <maximedevos@telenet.be>
|
2022-06-24 16:01:35 -04:00
|
|
|
|
;;; Copyright © 2022 Hartmut Goebel <h.goebel@crazy-compilers.com>
|
2021-08-10 11:07:20 -04:00
|
|
|
|
;;;
|
|
|
|
|
;;; This file is part of GNU Guix.
|
|
|
|
|
;;;
|
|
|
|
|
;;; GNU Guix is free software; you can redistribute it and/or modify it
|
|
|
|
|
;;; under the terms of the GNU General Public License as published by
|
|
|
|
|
;;; the Free Software Foundation; either version 3 of the License, or (at
|
|
|
|
|
;;; your option) any later version.
|
|
|
|
|
;;;
|
|
|
|
|
;;; GNU Guix is distributed in the hope that it will be useful, but
|
|
|
|
|
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
;;; GNU General Public License for more details.
|
|
|
|
|
;;;
|
|
|
|
|
;;; You should have received a copy of the GNU General Public License
|
|
|
|
|
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
(define-module (guix import minetest)
|
|
|
|
|
#:use-module (ice-9 match)
|
|
|
|
|
#:use-module (ice-9 threads)
|
|
|
|
|
#:use-module (ice-9 hash-table)
|
|
|
|
|
#:use-module (srfi srfi-1)
|
2023-04-07 12:11:21 -04:00
|
|
|
|
#:use-module (srfi srfi-34)
|
2022-06-24 16:01:35 -04:00
|
|
|
|
#:use-module (guix diagnostics)
|
import/minetest: Define an updater for mods on ContentDB.
Only detecting updates is currently supported. To actually
perform the uppdates, a patch like
<https://issues.guix.gnu.org/50072#4> is required.
* guix/import/minetest.scm
(version-style,minetest-package?,latest-minetest-release): New procedures.
(%minetest-updater): New updater.
* tests/minetest.scm
(upstream-source->sexp,expected-sexp,example-package): New procedure.
(test-release,test-no-release): New macro's.
("same version","new version (dotted)","new version (date)")
("new version (git -> dotted)","dotted->date","date->dotted")
("no commit informaton, no new release")
("minetest is not a minetest mod")
("technic is a minetest mod")
("upstream-name is required"): New tests.
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
2021-09-20 09:27:08 -04:00
|
|
|
|
#:use-module ((guix packages) #:prefix package:)
|
|
|
|
|
#:use-module (guix upstream)
|
2021-08-10 11:07:20 -04:00
|
|
|
|
#:use-module (guix i18n)
|
|
|
|
|
#:use-module (guix memoization)
|
|
|
|
|
#:use-module (guix serialization)
|
|
|
|
|
#:use-module (guix import utils)
|
|
|
|
|
#:use-module (guix import json)
|
|
|
|
|
#:use-module (json)
|
|
|
|
|
#:use-module (guix base32)
|
|
|
|
|
#:use-module (guix git)
|
import/minetest: Define an updater for mods on ContentDB.
Only detecting updates is currently supported. To actually
perform the uppdates, a patch like
<https://issues.guix.gnu.org/50072#4> is required.
* guix/import/minetest.scm
(version-style,minetest-package?,latest-minetest-release): New procedures.
(%minetest-updater): New updater.
* tests/minetest.scm
(upstream-source->sexp,expected-sexp,example-package): New procedure.
(test-release,test-no-release): New macro's.
("same version","new version (dotted)","new version (date)")
("new version (git -> dotted)","dotted->date","date->dotted")
("no commit informaton, no new release")
("minetest is not a minetest mod")
("technic is a minetest mod")
("upstream-name is required"): New tests.
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
2021-09-20 09:27:08 -04:00
|
|
|
|
#:use-module ((guix git-download) #:prefix download:)
|
2022-01-05 09:07:48 -05:00
|
|
|
|
#:use-module (guix hash)
|
2021-08-10 11:07:20 -04:00
|
|
|
|
#:use-module (guix store)
|
|
|
|
|
#:export (%default-sort-key
|
|
|
|
|
%contentdb-api
|
|
|
|
|
json->package
|
|
|
|
|
contentdb-fetch
|
|
|
|
|
elaborate-contentdb-name
|
import/minetest: Define an updater for mods on ContentDB.
Only detecting updates is currently supported. To actually
perform the uppdates, a patch like
<https://issues.guix.gnu.org/50072#4> is required.
* guix/import/minetest.scm
(version-style,minetest-package?,latest-minetest-release): New procedures.
(%minetest-updater): New updater.
* tests/minetest.scm
(upstream-source->sexp,expected-sexp,example-package): New procedure.
(test-release,test-no-release): New macro's.
("same version","new version (dotted)","new version (date)")
("new version (git -> dotted)","dotted->date","date->dotted")
("no commit informaton, no new release")
("minetest is not a minetest mod")
("technic is a minetest mod")
("upstream-name is required"): New tests.
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
2021-09-20 09:27:08 -04:00
|
|
|
|
minetest-package?
|
|
|
|
|
latest-minetest-release
|
2021-08-10 11:07:20 -04:00
|
|
|
|
minetest->guix-package
|
|
|
|
|
minetest-recursive-import
|
import/minetest: Define an updater for mods on ContentDB.
Only detecting updates is currently supported. To actually
perform the uppdates, a patch like
<https://issues.guix.gnu.org/50072#4> is required.
* guix/import/minetest.scm
(version-style,minetest-package?,latest-minetest-release): New procedures.
(%minetest-updater): New updater.
* tests/minetest.scm
(upstream-source->sexp,expected-sexp,example-package): New procedure.
(test-release,test-no-release): New macro's.
("same version","new version (dotted)","new version (date)")
("new version (git -> dotted)","dotted->date","date->dotted")
("no commit informaton, no new release")
("minetest is not a minetest mod")
("technic is a minetest mod")
("upstream-name is required"): New tests.
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
2021-09-20 09:27:08 -04:00
|
|
|
|
sort-packages
|
|
|
|
|
%minetest-updater))
|
2021-08-10 11:07:20 -04:00
|
|
|
|
|
|
|
|
|
;; The ContentDB API is documented at
|
|
|
|
|
;; <https://content.minetest.net>.
|
|
|
|
|
|
|
|
|
|
(define %contentdb-api
|
|
|
|
|
(make-parameter "https://content.minetest.net/api/"))
|
|
|
|
|
|
|
|
|
|
(define (string-or-false x)
|
|
|
|
|
(and (string? x) x))
|
|
|
|
|
|
|
|
|
|
(define (natural-or-false x)
|
|
|
|
|
(and (exact-integer? x) (>= x 0) x))
|
|
|
|
|
|
|
|
|
|
;; Descriptions on ContentDB use carriage returns, but Guix doesn't.
|
|
|
|
|
(define (delete-cr text)
|
|
|
|
|
(string-delete #\cr text))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
;;; JSON mappings
|
|
|
|
|
;;;
|
|
|
|
|
|
|
|
|
|
;; Minetest package.
|
|
|
|
|
;;
|
|
|
|
|
;; API endpoint: /packages/AUTHOR/NAME/
|
|
|
|
|
(define-json-mapping <package> make-package package?
|
|
|
|
|
json->package
|
|
|
|
|
(author package-author) ; string
|
|
|
|
|
(creation-date package-creation-date ; string
|
|
|
|
|
"created_at")
|
|
|
|
|
(downloads package-downloads) ; integer
|
|
|
|
|
(forums package-forums "forums" natural-or-false)
|
|
|
|
|
(issue-tracker package-issue-tracker "issue_tracker") ; string
|
|
|
|
|
(license package-license) ; string
|
|
|
|
|
(long-description package-long-description "long_description") ; string
|
|
|
|
|
(maintainers package-maintainers ; list of strings
|
|
|
|
|
"maintainers" vector->list)
|
|
|
|
|
(media-license package-media-license "media_license") ; string
|
|
|
|
|
(name package-name) ; string
|
|
|
|
|
(provides package-provides ; list of strings
|
|
|
|
|
"provides" vector->list)
|
|
|
|
|
(release package-release) ; integer
|
|
|
|
|
(repository package-repository "repo" string-or-false)
|
|
|
|
|
(score package-score) ; flonum
|
|
|
|
|
(screenshots package-screenshots "screenshots" vector->list) ; list of strings
|
|
|
|
|
(short-description package-short-description "short_description") ; string
|
|
|
|
|
(state package-state) ; string
|
|
|
|
|
(tags package-tags "tags" vector->list) ; list of strings
|
|
|
|
|
(thumbnail package-thumbnail) ; string
|
|
|
|
|
(title package-title) ; string
|
|
|
|
|
(type package-type) ; string
|
|
|
|
|
(url package-url) ; string
|
|
|
|
|
(website package-website "website" string-or-false))
|
|
|
|
|
|
|
|
|
|
(define-json-mapping <release> make-release release?
|
|
|
|
|
json->release
|
|
|
|
|
;; If present, a git commit identified by its hash
|
|
|
|
|
(commit release-commit "commit" string-or-false)
|
|
|
|
|
(downloads release-downloads) ; integer
|
|
|
|
|
(id release-id) ; integer
|
|
|
|
|
(max-minetest-version release-max-minetest-version string-or-false)
|
|
|
|
|
(min-minetest-version release-min-minetest-version string-or-false)
|
|
|
|
|
(release-date release-data) ; string
|
|
|
|
|
(title release-title) ; string
|
|
|
|
|
(url release-url)) ; string
|
|
|
|
|
|
|
|
|
|
(define-json-mapping <dependency> make-dependency dependency?
|
|
|
|
|
json->dependency
|
|
|
|
|
(optional? dependency-optional? "is_optional") ; bool
|
|
|
|
|
(name dependency-name) ; string
|
|
|
|
|
(packages dependency-packages "packages" vector->list)) ; list of strings
|
|
|
|
|
|
|
|
|
|
;; A structure returned by the /api/packages/?fmt=keys endpoint
|
|
|
|
|
(define-json-mapping <package-keys> make-package-keys package-keys?
|
|
|
|
|
json->package-keys
|
|
|
|
|
(author package-keys-author) ; string
|
|
|
|
|
(name package-keys-name) ; string
|
|
|
|
|
(type package-keys-type)) ; string
|
|
|
|
|
|
|
|
|
|
(define (package-mod? package)
|
|
|
|
|
"Is the ContentDB package PACKAGE a mod?"
|
|
|
|
|
;; ContentDB also has ‘games’ and ‘texture packs’.
|
|
|
|
|
(string=? (package-type package) "mod"))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
;;; Manipulating names of packages
|
|
|
|
|
;;;
|
|
|
|
|
;;; There are three kind of names:
|
|
|
|
|
;;;
|
|
|
|
|
;;; * names of guix packages, e.g. minetest-basic-materials.
|
|
|
|
|
;;; * names of mods on ContentDB, e.g. basic_materials
|
|
|
|
|
;;; * a combination of author and mod name on ContentDB, e.g. VanessaE/basic_materials
|
|
|
|
|
;;;
|
|
|
|
|
|
|
|
|
|
(define (%construct-full-name author name)
|
|
|
|
|
(string-append author "/" name))
|
|
|
|
|
|
|
|
|
|
(define (package-full-name package)
|
|
|
|
|
"Given a <package> object, return the corresponding AUTHOR/NAME string."
|
|
|
|
|
(%construct-full-name (package-author package) (package-name package)))
|
|
|
|
|
|
|
|
|
|
(define (package-keys-full-name package)
|
|
|
|
|
"Given a <package-keys> object, return the corresponding AUTHOR/NAME string."
|
|
|
|
|
(%construct-full-name (package-keys-author package)
|
|
|
|
|
(package-keys-name package)))
|
|
|
|
|
|
|
|
|
|
(define (contentdb->package-name author/name)
|
|
|
|
|
"Given the AUTHOR/NAME of a package on ContentDB, return a Guix-compliant
|
|
|
|
|
name for the package."
|
|
|
|
|
;; The author is not included, as the names of popular mods
|
|
|
|
|
;; tend to be unique.
|
|
|
|
|
(string-append "minetest-" (snake-case (author/name->name author/name))))
|
|
|
|
|
|
|
|
|
|
(define (author/name->name author/name)
|
|
|
|
|
"Extract NAME from the AUTHOR/NAME string, or raise an error if AUTHOR/NAME
|
|
|
|
|
is ill-formatted."
|
|
|
|
|
(match (string-split author/name #\/)
|
|
|
|
|
((author name)
|
|
|
|
|
(when (string-null? author)
|
|
|
|
|
(leave
|
|
|
|
|
(G_ "In ~a: author names must consist of at least a single character.~%")
|
|
|
|
|
author/name))
|
|
|
|
|
(when (string-null? name)
|
|
|
|
|
(leave
|
|
|
|
|
(G_ "In ~a: mod names must consist of at least a single character.~%")
|
|
|
|
|
author/name))
|
|
|
|
|
name)
|
|
|
|
|
((too many . components)
|
|
|
|
|
(leave
|
|
|
|
|
(G_ "In ~a: author names and mod names may not contain forward slashes.~%")
|
|
|
|
|
author/name))
|
|
|
|
|
((name)
|
|
|
|
|
(if (string-null? name)
|
|
|
|
|
(leave (G_ "mod names may not be empty.~%"))
|
|
|
|
|
(leave (G_ "The name of the author is missing in ~a.~%")
|
|
|
|
|
author/name)))))
|
|
|
|
|
|
|
|
|
|
(define* (elaborate-contentdb-name name #:key (sort %default-sort-key))
|
|
|
|
|
"If NAME is an AUTHOR/NAME string, return it. Otherwise, try to determine
|
|
|
|
|
the author and return an appropriate AUTHOR/NAME string. If that fails,
|
|
|
|
|
raise an exception."
|
|
|
|
|
(if (or (string-contains name "/") (string-null? name))
|
|
|
|
|
;; Call 'author/name->name' to verify that NAME seems reasonable
|
|
|
|
|
;; and raise an appropriate exception if it isn't.
|
|
|
|
|
(begin
|
|
|
|
|
(author/name->name name)
|
|
|
|
|
name)
|
|
|
|
|
(let* ((package-keys (contentdb-query-packages name #:sort sort))
|
|
|
|
|
(correctly-named
|
|
|
|
|
(filter (lambda (package-key)
|
|
|
|
|
(string=? name (package-keys-name package-key)))
|
|
|
|
|
package-keys)))
|
|
|
|
|
(match correctly-named
|
|
|
|
|
((one) (package-keys-full-name one))
|
|
|
|
|
((too . many)
|
2021-09-27 10:06:31 -04:00
|
|
|
|
(warning (G_ "~a is ambiguous, presuming ~a (other options include: ~a)~%")
|
2021-08-10 11:07:20 -04:00
|
|
|
|
name (package-keys-full-name too)
|
|
|
|
|
(map package-keys-full-name many))
|
|
|
|
|
(package-keys-full-name too))
|
|
|
|
|
(()
|
|
|
|
|
(leave (G_ "No mods with name ~a were found.~%") name))))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
;;; API endpoints
|
|
|
|
|
;;;
|
|
|
|
|
|
|
|
|
|
(define contentdb-fetch
|
|
|
|
|
(mlambda (author/name)
|
|
|
|
|
"Return a <package> record for package AUTHOR/NAME, or #f on failure."
|
|
|
|
|
(and=> (json-fetch
|
|
|
|
|
(string-append (%contentdb-api) "packages/" author/name "/"))
|
|
|
|
|
json->package)))
|
|
|
|
|
|
|
|
|
|
(define (contentdb-fetch-releases author/name)
|
|
|
|
|
"Return a list of <release> records for package NAME by AUTHOR, or #f
|
|
|
|
|
on failure."
|
|
|
|
|
(and=> (json-fetch (string-append (%contentdb-api) "packages/" author/name
|
|
|
|
|
"/releases/"))
|
|
|
|
|
(lambda (json)
|
|
|
|
|
(map json->release (vector->list json)))))
|
|
|
|
|
|
|
|
|
|
(define (latest-release author/name)
|
|
|
|
|
"Return the latest source release for package NAME by AUTHOR,
|
|
|
|
|
or #f if this package does not exist."
|
|
|
|
|
(and=> (contentdb-fetch-releases author/name)
|
|
|
|
|
car))
|
|
|
|
|
|
|
|
|
|
(define (contentdb-fetch-dependencies author/name)
|
|
|
|
|
"Return an alist of lists of <dependency> records for package NAME by AUTHOR
|
|
|
|
|
and possibly some other packages as well, or #f on failure."
|
|
|
|
|
(define url (string-append (%contentdb-api) "packages/" author/name
|
|
|
|
|
"/dependencies/"))
|
|
|
|
|
(and=> (json-fetch url)
|
|
|
|
|
(lambda (json)
|
|
|
|
|
(map (match-lambda
|
|
|
|
|
((key . value)
|
|
|
|
|
(cons key (map json->dependency (vector->list value)))))
|
|
|
|
|
json))))
|
|
|
|
|
|
|
|
|
|
(define* (contentdb-query-packages q #:key
|
|
|
|
|
(type "mod")
|
|
|
|
|
(limit 50)
|
|
|
|
|
(sort %default-sort-key)
|
|
|
|
|
(order "desc"))
|
|
|
|
|
"Search ContentDB for Q (a string). Sort by SORT, in ascending order
|
|
|
|
|
if ORDER is \"asc\" or descending order if ORDER is \"desc\". TYPE must
|
2021-09-27 10:06:31 -04:00
|
|
|
|
be \"mod\", \"game\" or \"txp\", restricting the search results to
|
2021-08-10 11:07:20 -04:00
|
|
|
|
respectively mods, games and texture packs. Limit to at most LIMIT
|
|
|
|
|
results. The return value is a list of <package-keys> records."
|
|
|
|
|
;; XXX does Guile have something for constructing (and, when necessary,
|
|
|
|
|
;; escaping) query strings?
|
|
|
|
|
(define url (string-append (%contentdb-api) "packages/?type=" type
|
|
|
|
|
"&q=" q "&fmt=keys"
|
|
|
|
|
"&limit=" (number->string limit)
|
|
|
|
|
"&order=" order
|
|
|
|
|
"&sort=" sort))
|
|
|
|
|
(let ((json (json-fetch url)))
|
|
|
|
|
(if json
|
|
|
|
|
(map json->package-keys (vector->list json))
|
|
|
|
|
(leave
|
|
|
|
|
(G_ "The package search API doesn't exist anymore.~%")))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;; XXX copied from (guix import elpa)
|
|
|
|
|
(define* (download-git-repository url ref)
|
|
|
|
|
"Fetch the given REF from the Git repository at URL."
|
|
|
|
|
(with-store store
|
|
|
|
|
(latest-repository-commit store url #:ref ref)))
|
|
|
|
|
|
|
|
|
|
(define (make-minetest-sexp author/name version repository commit
|
|
|
|
|
inputs home-page synopsis
|
|
|
|
|
description media-license license)
|
|
|
|
|
"Return a S-expression for the minetest package with the given author/NAME,
|
|
|
|
|
VERSION, REPOSITORY, COMMIT, INPUTS, HOME-PAGE, SYNOPSIS, DESCRIPTION,
|
|
|
|
|
MEDIA-LICENSE and LICENSE."
|
|
|
|
|
`(package
|
|
|
|
|
(name ,(contentdb->package-name author/name))
|
|
|
|
|
(version ,version)
|
|
|
|
|
(source
|
|
|
|
|
(origin
|
|
|
|
|
(method git-fetch)
|
|
|
|
|
(uri (git-reference
|
|
|
|
|
(url ,repository)
|
|
|
|
|
(commit ,commit)))
|
|
|
|
|
(sha256
|
|
|
|
|
(base32
|
|
|
|
|
;; The git commit is not always available.
|
|
|
|
|
,(and commit
|
|
|
|
|
(bytevector->nix-base32-string
|
2022-01-05 09:07:48 -05:00
|
|
|
|
(file-hash*
|
2021-08-10 11:07:20 -04:00
|
|
|
|
(download-git-repository repository
|
2022-01-05 09:07:48 -05:00
|
|
|
|
`(commit . ,commit))
|
|
|
|
|
;; 'download-git-repository' already filtered out the '.git'
|
|
|
|
|
;; directory.
|
|
|
|
|
#:select? (const #true)
|
|
|
|
|
#:recursive? #true)))))
|
2021-08-10 11:07:20 -04:00
|
|
|
|
(file-name (git-file-name name version))))
|
|
|
|
|
(build-system minetest-mod-build-system)
|
|
|
|
|
,@(maybe-propagated-inputs (map contentdb->package-name inputs))
|
|
|
|
|
(home-page ,home-page)
|
|
|
|
|
(synopsis ,(delete-cr synopsis))
|
2021-12-17 08:10:40 -05:00
|
|
|
|
(description ,(beautify-description (delete-cr description)))
|
2021-08-10 11:07:20 -04:00
|
|
|
|
(license ,(if (eq? media-license license)
|
|
|
|
|
license
|
|
|
|
|
`(list ,media-license ,license)))
|
|
|
|
|
;; The Minetest updater (not yet in Guix; it requires not-yet-submitted
|
|
|
|
|
;; patches to (guix upstream) that require some work) needs to know both
|
|
|
|
|
;; the author name and mod name for efficiency.
|
|
|
|
|
(properties ,(list 'quasiquote `((upstream-name . ,author/name))))))
|
|
|
|
|
|
|
|
|
|
(define (package-home-page package)
|
|
|
|
|
"Guess the home page of the ContentDB package PACKAGE.
|
|
|
|
|
|
|
|
|
|
In order of preference, try the 'website', the forum topic on the
|
|
|
|
|
official Minetest forum and the Git repository (if any)."
|
|
|
|
|
(define (topic->url-sexp topic)
|
|
|
|
|
;; 'minetest-topic' is a procedure defined in (gnu packages minetest)
|
|
|
|
|
`(minetest-topic ,topic))
|
|
|
|
|
(or (package-website package)
|
|
|
|
|
(and=> (package-forums package) topic->url-sexp)
|
|
|
|
|
(package-repository package)))
|
|
|
|
|
|
2021-09-07 07:24:24 -04:00
|
|
|
|
(define (release-version release)
|
|
|
|
|
"Guess the version of RELEASE from the release title."
|
|
|
|
|
(define title (release-title release))
|
|
|
|
|
(if (string-prefix? "v" title)
|
|
|
|
|
;; Remove "v" prefix from release titles like ‘v1.0.1’.
|
|
|
|
|
(substring title 1)
|
|
|
|
|
title))
|
|
|
|
|
|
import/minetest: Define an updater for mods on ContentDB.
Only detecting updates is currently supported. To actually
perform the uppdates, a patch like
<https://issues.guix.gnu.org/50072#4> is required.
* guix/import/minetest.scm
(version-style,minetest-package?,latest-minetest-release): New procedures.
(%minetest-updater): New updater.
* tests/minetest.scm
(upstream-source->sexp,expected-sexp,example-package): New procedure.
(test-release,test-no-release): New macro's.
("same version","new version (dotted)","new version (date)")
("new version (git -> dotted)","dotted->date","date->dotted")
("no commit informaton, no new release")
("minetest is not a minetest mod")
("technic is a minetest mod")
("upstream-name is required"): New tests.
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
2021-09-20 09:27:08 -04:00
|
|
|
|
(define (version-style version)
|
|
|
|
|
"Determine the kind of version number VERSION is -- a date, or a conventional
|
|
|
|
|
conventional version number."
|
|
|
|
|
(define dots? (->bool (string-index version #\.)))
|
|
|
|
|
(define hyphens? (->bool (string-index version #\-)))
|
|
|
|
|
(match (cons dots? hyphens?)
|
|
|
|
|
((#true . #false) 'regular) ; something like "0.1"
|
|
|
|
|
((#false . #false) 'regular) ; single component version number
|
|
|
|
|
((#true . #true) 'regular) ; result of 'git-version'
|
|
|
|
|
((#false . #true) 'date))) ; something like "2021-01-25"
|
|
|
|
|
|
2021-08-10 11:07:20 -04:00
|
|
|
|
;; If the default sort key is changed, make sure to modify 'show-help'
|
|
|
|
|
;; in (guix scripts import minetest) appropriately as well.
|
|
|
|
|
(define %default-sort-key "score")
|
|
|
|
|
|
|
|
|
|
(define* (sort-packages packages #:key (sort %default-sort-key))
|
|
|
|
|
"Sort PACKAGES by SORT, in descending order."
|
|
|
|
|
(define package->key
|
|
|
|
|
(match sort
|
|
|
|
|
("score" package-score)
|
|
|
|
|
("downloads" package-downloads)))
|
|
|
|
|
(define (greater x y)
|
|
|
|
|
(> (package->key x) (package->key y)))
|
|
|
|
|
(sort-list packages greater))
|
|
|
|
|
|
|
|
|
|
(define builtin-mod?
|
|
|
|
|
(let ((%builtin-mods
|
|
|
|
|
(alist->hash-table
|
|
|
|
|
(map (lambda (x) (cons x #t))
|
|
|
|
|
'("beds" "binoculars" "boats" "bones" "bucket" "butterflies"
|
|
|
|
|
"carts" "creative" "default" "doors" "dungeon_loot" "dye"
|
|
|
|
|
"env_sounds" "farming" "fire" "fireflies" "flowers"
|
|
|
|
|
"game_commands" "give_initial_stuff" "map" "mtg_craftguide"
|
|
|
|
|
"player_api" "screwdriver" "sethome" "sfinv" "spawn" "stairs"
|
|
|
|
|
"tnt" "vessels" "walls" "weather" "wool" "xpanes")))))
|
|
|
|
|
(lambda (mod)
|
|
|
|
|
"Is MOD provided by the default minetest subgame?"
|
|
|
|
|
(hash-ref %builtin-mods mod))))
|
|
|
|
|
|
|
|
|
|
(define* (important-dependencies dependencies author/name
|
|
|
|
|
#:key (sort %default-sort-key))
|
|
|
|
|
"Return the hard dependencies of AUTHOR/NAME in the association list
|
|
|
|
|
DEPENDENCIES as a list of AUTHOR/NAME strings."
|
|
|
|
|
(define dependency-list
|
|
|
|
|
(assoc-ref dependencies author/name))
|
2021-09-07 07:05:56 -04:00
|
|
|
|
;; A mod can have multiple dependencies implemented by the same mod,
|
|
|
|
|
;; so remove duplicate mod names.
|
|
|
|
|
(define (filter-deduplicate-map f list)
|
|
|
|
|
(delete-duplicates (filter-map f list)))
|
|
|
|
|
(filter-deduplicate-map
|
2021-08-10 11:07:20 -04:00
|
|
|
|
(lambda (dependency)
|
|
|
|
|
(and (not (dependency-optional? dependency))
|
|
|
|
|
(not (builtin-mod? (dependency-name dependency)))
|
|
|
|
|
;; The dependency information contains symbolic names
|
|
|
|
|
;; that can be ‘provided’ by multiple mods, so we need to choose one
|
|
|
|
|
;; of the implementations.
|
|
|
|
|
(let* ((implementations
|
|
|
|
|
(par-map contentdb-fetch (dependency-packages dependency)))
|
|
|
|
|
;; Fetching package information about the packages is racy:
|
|
|
|
|
;; some packages might be removed from ContentDB between the
|
|
|
|
|
;; construction of DEPENDENCIES and the call to
|
|
|
|
|
;; 'contentdb-fetch'. So filter out #f.
|
|
|
|
|
;;
|
|
|
|
|
;; Filter out ‘games’ that include the requested mod -- it's
|
|
|
|
|
;; the mod itself we want.
|
|
|
|
|
(mods (filter (lambda (p) (and=> p package-mod?))
|
|
|
|
|
implementations))
|
|
|
|
|
(sorted-mods (sort-packages mods #:sort sort)))
|
|
|
|
|
(match sorted-mods
|
|
|
|
|
((package) (package-full-name package))
|
|
|
|
|
((too . many)
|
|
|
|
|
(warning
|
|
|
|
|
(G_ "The dependency ~a of ~a has multiple different implementations ~a.~%")
|
|
|
|
|
(dependency-name dependency)
|
|
|
|
|
author/name
|
|
|
|
|
(map package-full-name sorted-mods))
|
|
|
|
|
(match sort
|
|
|
|
|
("score"
|
|
|
|
|
(warning
|
2022-05-28 20:00:00 -04:00
|
|
|
|
(G_ "The implementation with the highest score will be chosen!~%")))
|
2021-08-10 11:07:20 -04:00
|
|
|
|
("downloads"
|
|
|
|
|
(warning
|
2022-05-28 20:00:00 -04:00
|
|
|
|
(G_ "The implementation that has been downloaded the most will be chosen!~%"))))
|
2021-08-10 11:07:20 -04:00
|
|
|
|
(package-full-name too))
|
|
|
|
|
(()
|
|
|
|
|
(warning
|
|
|
|
|
(G_ "The dependency ~a of ~a does not have any implementation. It will be ignored!~%")
|
|
|
|
|
(dependency-name dependency) author/name)
|
|
|
|
|
#f)))))
|
|
|
|
|
dependency-list))
|
|
|
|
|
|
2022-11-27 05:12:32 -05:00
|
|
|
|
(define* (%minetest->guix-package author/name #:key (sort %default-sort-key)
|
|
|
|
|
#:allow-other-keys)
|
2021-08-10 11:07:20 -04:00
|
|
|
|
"Fetch the metadata for AUTHOR/NAME from https://content.minetest.net, and
|
|
|
|
|
return the 'package' S-expression corresponding to that package, or raise an
|
|
|
|
|
exception on failure. On success, also return the upstream dependencies as a
|
|
|
|
|
list of AUTHOR/NAME strings."
|
|
|
|
|
;; Call 'author/name->name' to verify that AUTHOR/NAME seems reasonable.
|
|
|
|
|
(author/name->name author/name)
|
|
|
|
|
(define package (contentdb-fetch author/name))
|
|
|
|
|
(unless package
|
|
|
|
|
(leave (G_ "no package metadata for ~a on ContentDB~%") author/name))
|
|
|
|
|
(define dependencies (contentdb-fetch-dependencies author/name))
|
|
|
|
|
(unless dependencies
|
|
|
|
|
(leave (G_ "no dependency information for ~a on ContentDB~%") author/name))
|
|
|
|
|
(define release (latest-release author/name))
|
|
|
|
|
(unless release
|
|
|
|
|
(leave (G_ "no release of ~a on ContentDB~%") author/name))
|
|
|
|
|
(define important-upstream-dependencies
|
|
|
|
|
(important-dependencies dependencies author/name #:sort sort))
|
|
|
|
|
(values (make-minetest-sexp author/name
|
2021-09-07 07:24:24 -04:00
|
|
|
|
(release-version release)
|
2021-08-10 11:07:20 -04:00
|
|
|
|
(package-repository package)
|
|
|
|
|
(release-commit release)
|
|
|
|
|
important-upstream-dependencies
|
|
|
|
|
(package-home-page package)
|
|
|
|
|
(package-short-description package)
|
|
|
|
|
(package-long-description package)
|
|
|
|
|
(spdx-string->license
|
|
|
|
|
(package-media-license package))
|
|
|
|
|
(spdx-string->license
|
|
|
|
|
(package-license package)))
|
|
|
|
|
important-upstream-dependencies))
|
|
|
|
|
|
|
|
|
|
(define minetest->guix-package
|
|
|
|
|
(memoize %minetest->guix-package))
|
|
|
|
|
|
|
|
|
|
(define* (minetest-recursive-import author/name #:key (sort %default-sort-key))
|
2022-11-27 05:12:32 -05:00
|
|
|
|
(define* (minetest->guix-package* author/name #:key version #:allow-other-keys)
|
2021-08-10 11:07:20 -04:00
|
|
|
|
(minetest->guix-package author/name #:sort sort))
|
|
|
|
|
(recursive-import author/name
|
|
|
|
|
#:repo->guix-package minetest->guix-package*
|
|
|
|
|
#:guix-name contentdb->package-name))
|
import/minetest: Define an updater for mods on ContentDB.
Only detecting updates is currently supported. To actually
perform the uppdates, a patch like
<https://issues.guix.gnu.org/50072#4> is required.
* guix/import/minetest.scm
(version-style,minetest-package?,latest-minetest-release): New procedures.
(%minetest-updater): New updater.
* tests/minetest.scm
(upstream-source->sexp,expected-sexp,example-package): New procedure.
(test-release,test-no-release): New macro's.
("same version","new version (dotted)","new version (date)")
("new version (git -> dotted)","dotted->date","date->dotted")
("no commit informaton, no new release")
("minetest is not a minetest mod")
("technic is a minetest mod")
("upstream-name is required"): New tests.
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
2021-09-20 09:27:08 -04:00
|
|
|
|
|
|
|
|
|
(define (minetest-package? pkg)
|
|
|
|
|
"Is PKG a Minetest mod on ContentDB?"
|
|
|
|
|
(and (string-prefix? "minetest-" (package:package-name pkg))
|
|
|
|
|
(assq-ref (package:package-properties pkg) 'upstream-name)))
|
|
|
|
|
|
2022-06-24 16:01:35 -04:00
|
|
|
|
(define* (latest-minetest-release pkg #:key (version #f))
|
import/minetest: Define an updater for mods on ContentDB.
Only detecting updates is currently supported. To actually
perform the uppdates, a patch like
<https://issues.guix.gnu.org/50072#4> is required.
* guix/import/minetest.scm
(version-style,minetest-package?,latest-minetest-release): New procedures.
(%minetest-updater): New updater.
* tests/minetest.scm
(upstream-source->sexp,expected-sexp,example-package): New procedure.
(test-release,test-no-release): New macro's.
("same version","new version (dotted)","new version (date)")
("new version (git -> dotted)","dotted->date","date->dotted")
("no commit informaton, no new release")
("minetest is not a minetest mod")
("technic is a minetest mod")
("upstream-name is required"): New tests.
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
2021-09-20 09:27:08 -04:00
|
|
|
|
"Return an <upstream-source> for the latest release of the package PKG,
|
|
|
|
|
or #false if the latest release couldn't be determined."
|
|
|
|
|
(define author/name
|
|
|
|
|
(assq-ref (package:package-properties pkg) 'upstream-name))
|
|
|
|
|
(define contentdb-package (contentdb-fetch author/name)) ; TODO warn if #f?
|
|
|
|
|
(define release (latest-release author/name))
|
|
|
|
|
(define source (package:package-source pkg))
|
2022-06-24 16:01:35 -04:00
|
|
|
|
|
|
|
|
|
(when version
|
2023-04-07 12:11:21 -04:00
|
|
|
|
(raise
|
2022-06-24 16:01:35 -04:00
|
|
|
|
(formatted-message
|
|
|
|
|
(G_ "~a updater doesn't support updating to a specific version, sorry.")
|
|
|
|
|
"minetest")))
|
import/minetest: Define an updater for mods on ContentDB.
Only detecting updates is currently supported. To actually
perform the uppdates, a patch like
<https://issues.guix.gnu.org/50072#4> is required.
* guix/import/minetest.scm
(version-style,minetest-package?,latest-minetest-release): New procedures.
(%minetest-updater): New updater.
* tests/minetest.scm
(upstream-source->sexp,expected-sexp,example-package): New procedure.
(test-release,test-no-release): New macro's.
("same version","new version (dotted)","new version (date)")
("new version (git -> dotted)","dotted->date","date->dotted")
("no commit informaton, no new release")
("minetest is not a minetest mod")
("technic is a minetest mod")
("upstream-name is required"): New tests.
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
2021-09-20 09:27:08 -04:00
|
|
|
|
(and contentdb-package release
|
|
|
|
|
(release-commit release) ; not always set
|
|
|
|
|
;; Only continue if both the old and new version number are both
|
|
|
|
|
;; dates or regular version numbers, as two different styles confuses
|
|
|
|
|
;; the logic for determining which version is newer.
|
|
|
|
|
(eq? (version-style (release-version release))
|
|
|
|
|
(version-style (package:package-version pkg)))
|
|
|
|
|
(upstream-source
|
|
|
|
|
(package (package:package-name pkg))
|
|
|
|
|
(version (release-version release))
|
2022-01-05 09:07:50 -05:00
|
|
|
|
(urls (download:git-reference
|
|
|
|
|
(url (package-repository contentdb-package))
|
|
|
|
|
(commit (release-commit release)))))))
|
import/minetest: Define an updater for mods on ContentDB.
Only detecting updates is currently supported. To actually
perform the uppdates, a patch like
<https://issues.guix.gnu.org/50072#4> is required.
* guix/import/minetest.scm
(version-style,minetest-package?,latest-minetest-release): New procedures.
(%minetest-updater): New updater.
* tests/minetest.scm
(upstream-source->sexp,expected-sexp,example-package): New procedure.
(test-release,test-no-release): New macro's.
("same version","new version (dotted)","new version (date)")
("new version (git -> dotted)","dotted->date","date->dotted")
("no commit informaton, no new release")
("minetest is not a minetest mod")
("technic is a minetest mod")
("upstream-name is required"): New tests.
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
2021-09-20 09:27:08 -04:00
|
|
|
|
|
|
|
|
|
(define %minetest-updater
|
|
|
|
|
(upstream-updater
|
|
|
|
|
(name 'minetest)
|
|
|
|
|
(description "Updater for Minetest packages on ContentDB")
|
|
|
|
|
(pred minetest-package?)
|
upstream-updater: Rename record field.
The next commits will make the functions, which are currently importing the
latest version of a package, change into importing the latest or a given
version of the package (for those updaters supporting specifying a version).
Thus the name ‘latest‘ is no longer appropriate.
* guix/upstream.scm (upstream-updater) Rename field [latest] to
[import]. (lookup-updater, package-latest-release) Adjust fieldname
accordingly.
* guix/gnu-maintenance.scm (%gnu-updater, %gnu-ftp-updater,
%savannah-updater, %sourceforge-updater, %xorg-updater,
%kernel.org-updater, %generic-html-updater),
guix/import/cpan.scm (%cpan-updater),
guix/import/cran.scm (%cran-updater, %bioconductor-updater),
guix/import/crate.scm (%crate-updater),
guix/import/egg.scm (%egg-updater),
guix/import/elpa.scm (%elpa-updater),
guix/import/gem.scm (%gem-updater),
guix/import/git.scm (%generic-git-updater),
guix/import/github.scm (%github-updater),
guix/import/gnome.scm (%gnome-updater),
guix/import/hackage.scm (%hackage-updater),
guix/import/hexpm.scm (%hexpm-updater),
guix/import/kde.scm (%kde-updater),
guix/import/launchpad.scm (%launchpad-updater),
guix/import/minetest.scm (%minetest-updater),
guix/import/opam.scm (%opam-updater),
guix/import/pypi.scm (%pypi-updater),
guix/import/stackage.scm (%stackage-updater),
tests/import-github.scm (found-sexp)
tests/transformations.scm ("options->transformation, with-latest"):
Adjust fieldname accordingly.
2022-08-27 07:05:33 -04:00
|
|
|
|
(import latest-minetest-release)))
|