[PATCH 00/20] Add minetest mods

DoneSubmitted by Maxime Devos.
Details
3 participants
  • Leo Prikler
  • Maxime Devos
  • Andrew Ward
Owner
unassigned
Severity
normal
M
M
Maxime Devos wrote on 2 Aug 17:46 +0200
(address . guix-patches@gnu.org)
e186977b4c00c4b883a633186810d4a98b7f68d5.camel@telenet.be
Hi Guix,
This patch series adds a bunch of Minetest mods, but first,it patches Minetest such that the mods will actually be found.An importer for Minetest mods from ContentDB(https://content.minetest.net) is included as well.
I have verified:
* "guix lint" doesn't find any issues, except ‘no updated found for ...’ and some incorrect ‘... can be upgraded to’.
* the source code doesn't appear to contain any malware
* the license information
* "./pre-inst-env guix build ALL-THE-NEW-PACKAGES" succeeds
* "make check 'TESTS=tests/contentdb.scm'" succeeds
I've also constructed an environment (./pre-inst-env guix environment --ad-hoc)containing all the mods and minetest, started minetest, created a new world,enabled all the mods, and placed some random nodes and tried out "worldedit".This seems to work, but I did not yet try out every mod.
I also constructed an environment with only "minetest" and tried out thebuilt-in ContentDB installer. It still appears to work.
(The actual patches will be sent once debbugs gives me an issue number)
Maxime Devos (20): gnu: minetest: Respect --without-tests. gnu: minetest: Search for mods in MINETEST_MOD_PATH. gnu: minetest: New package module. build-system: Add 'minetest-mod-build-system'. build-system: minetest: Don't retain references to "bash-minimal". guix: Add ContentDB importer. gnu: Add minetest-mesecons. gnu: Add minetest-basic-materials. gnu: Add minetest-unifieddyes. gnu: Add minetest-pipeworks. gnu: Add minetest-coloredwood. gnu: Add minetest-ethereal. gnu: Add minetest-technic. gnu: Add minetest-throwing. gnu: Add minetest-throwing-arrows. gnu: Add minetest-unified-inventory. gnu: Add minetest-worldedit. gnu: Add minetest-mobs. gnu: Add minetest-mobs-animal. gnu: Add minetest-homedecor-modpack.
Makefile.am | 4 + doc/guix.texi | 32 ++ gnu/local.mk | 2 + gnu/packages/games.scm | 14 +- gnu/packages/minetest.scm | 423 ++++++++++++++++++ ...vironment-variable-MINETEST_MOD_PATH.patch | 115 +++++ guix/build-system/minetest.scm | 62 +++ guix/import/contentdb.scm | 310 +++++++++++++ guix/scripts/import.scm | 3 +- guix/scripts/import/contentdb.scm | 106 +++++ po/guix/POTFILES.in | 1 + tests/contentdb.scm | 227 ++++++++++ 12 files changed, 1293 insertions(+), 6 deletions(-) create mode 100644 gnu/packages/minetest.scm create mode 100644 gnu/packages/patches/Add-environment-variable-MINETEST_MOD_PATH.patch create mode 100644 guix/build-system/minetest.scm create mode 100644 guix/import/contentdb.scm create mode 100644 guix/scripts/import/contentdb.scm create mode 100644 tests/contentdb.scm
-----BEGIN PGP SIGNATURE-----
iI0EABYKADUWIQTB8z7iDFKP233XAR9J4+4iGRcl7gUCYQgTaxccbWF4aW1lZGV2b3NAdGVsZW5ldC5iZQAKCRBJ4+4iGRcl7sgiAP0SdZF6fOlA9dBKarATKOjmCQ0YplNBwoXkpyKYQzfWAgD/bgLjBSGyAl3rBqsPhmdugfpf+JrO4WDZNTWDqP8P+wc==YSTa-----END PGP SIGNATURE-----

M
M
Maxime Devos wrote on 2 Aug 17:50 +0200
[PATCH 01/20] gnu: minetest: Respect --without-tests.
(address . 49828@debbugs.gnu.org)(name . Maxime Devos)(address . maximedevos@telenet.be)
20210802155019.6122-1-maximedevos@telenet.be
* gnu/packages/games.scm (minetest)[arguments]<#:phases>{check}: Use 'tests?' instead of ',(%current-target-system)'. Remove trailing #t.--- gnu/packages/games.scm | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
Toggle diff (23 lines)diff --git a/gnu/packages/games.scm b/gnu/packages/games.scmindex 8c6b5523f1..3e7086b398 100644--- a/gnu/packages/games.scm+++ b/gnu/packages/games.scm@@ -3590,13 +3590,12 @@ match, cannon keep, and grave-itation pit.") (string-append (getcwd) "/games")) ; for check #t)) (replace 'check- (lambda _+ (lambda* (#:key tests? #:allow-other-keys) ;; Thanks to our substitutions, the tests should also run ;; when invoked on the target outside of `guix build'.- (unless ,(%current-target-system)+ (when tests? (setenv "HOME" "/tmp")- (invoke "src/minetest" "--run-unittests"))- #t)))))+ (invoke "src/minetest" "--run-unittests"))))))) (native-search-paths (list (search-path-specification (variable "MINETEST_SUBGAME_PATH")-- 2.32.0
M
M
Maxime Devos wrote on 2 Aug 17:50 +0200
[PATCH 02/20] gnu: minetest: Search for mods in MINETEST_MOD_PATH.
(address . 49828@debbugs.gnu.org)(name . Maxime Devos)(address . maximedevos@telenet.be)
20210802155019.6122-2-maximedevos@telenet.be
* gnu/packages/patches/Add-environment-variable-MINETEST_MOD_PATH.patch: New file.* gnu/packages/games.scm (minetest)[source]{patches}: Add it. (minetest)[native-search-paths]: Add "MINETEST_MOD_PATH".* gnu/local.mk (dist_patch_DATA): Add the patch.--- gnu/local.mk | 1 + gnu/packages/games.scm | 7 +- ...vironment-variable-MINETEST_MOD_PATH.patch | 115 ++++++++++++++++++ 3 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 gnu/packages/patches/Add-environment-variable-MINETEST_MOD_PATH.patch
Toggle diff (160 lines)diff --git a/gnu/local.mk b/gnu/local.mkindex c80a9af78c..d96d4e3dbc 100644--- a/gnu/local.mk+++ b/gnu/local.mk@@ -801,6 +801,7 @@ dist_patch_DATA = \ %D%/packages/patches/abseil-cpp-fix-gtest.patch \ %D%/packages/patches/abseil-cpp-fix-strerror_test.patch \ %D%/packages/patches/adb-add-libraries.patch \+ %D%/packages/patches/Add-environment-variable-MINETEST_MOD_PATH.patch \ %D%/packages/patches/aegis-constness-error.patch \ %D%/packages/patches/aegis-perl-tempdir1.patch \ %D%/packages/patches/aegis-perl-tempdir2.patch \diff --git a/gnu/packages/games.scm b/gnu/packages/games.scmindex 3e7086b398..2f3285c6ea 100644--- a/gnu/packages/games.scm+++ b/gnu/packages/games.scm@@ -3553,6 +3553,7 @@ match, cannon keep, and grave-itation pit.") (base32 "062ilb7s377q3hwfhl8q06vvcw2raydz5ljzlzwy2dmyzmdcndb8")) (modules '((guix build utils)))+ (patches (search-patches "Add-environment-variable-MINETEST_MOD_PATH.patch")) (snippet '(begin ;; Delete bundled libraries.@@ -3599,7 +3600,11 @@ match, cannon keep, and grave-itation pit.") (native-search-paths (list (search-path-specification (variable "MINETEST_SUBGAME_PATH")- (files '("share/minetest/games")))))+ (files '("share/minetest/games")))+ (search-path-specification+ (variable "MINETEST_MOD_PATH")+ (files '("share/minetest/mods"))+ (separator #f)))) (native-inputs `(("pkg-config" ,pkg-config))) (inputsdiff --git a/gnu/packages/patches/Add-environment-variable-MINETEST_MOD_PATH.patch b/gnu/packages/patches/Add-environment-variable-MINETEST_MOD_PATH.patchnew file mode 100644index 0000000000..8478a7bf72--- /dev/null+++ b/gnu/packages/patches/Add-environment-variable-MINETEST_MOD_PATH.patch@@ -0,0 +1,115 @@+From 6eb753c5bf67764890856cf23a67c0bf65973c16 Mon Sep 17 00:00:00 2001+From: Maxime Devos <maximedevos@telenet.be>+Date: Thu, 29 Jul 2021 22:24:50 +0200+Subject: [PATCH] Add environment variable MINETEST_MOD_PATH++This adds an environment variable MINETEST_MOD_PATH.+When it exists, Minetest will look there for mods+in addition to ~/.minetest/mods/.++This patch as-is is not yet ready for upstream, because:++ * the GUI will only display mods in MINETEST_MOD_PATH+ or mods in ~/.minetest/mods, it won't combine the two++ * the GUI for installing mods from ContentDB is disabled+ when MINETEST_MOD_PATH is set, because otherwise Minetest+ would try to install mods in the store.++ * MINETEST_MOD_PATH can only have a single component+---+ builtin/mainmenu/dlg_contentstore.lua | 7 ++++++++ src/content/subgames.cpp | 3 ++++ src/script/lua_api/l_mainmenu.cpp | 14 +++++++++++++-+ src/script/lua_api/l_mainmenu.h | 2 +++ 4 files changed, 25 insertions(+), 1 deletion(-)++diff --git a/builtin/mainmenu/dlg_contentstore.lua b/builtin/mainmenu/dlg_contentstore.lua+index 7096c9187..c4a2cbd18 100644+--- a/builtin/mainmenu/dlg_contentstore.lua++++ b/builtin/mainmenu/dlg_contentstore.lua+@@ -22,6 +22,13 @@ if not core.get_http_api then+ end+ return+ end++if core.mod_path_set() then++ function create_store_dlg()++ return messagebox("store",++ fgettext("Mods from ContentDB cannot be installed when mods from Guix are also installed"))++ end++ return++end+ + -- Unordered preserves the original order of the ContentDB API,+ -- before the package list is ordered based on installed state.+diff --git a/src/content/subgames.cpp b/src/content/subgames.cpp+index e9dc609b0..1809f189e 100644+--- a/src/content/subgames.cpp++++ b/src/content/subgames.cpp+@@ -110,6 +110,9 @@ SubgameSpec findSubgame(const std::string &id)+ std::set<std::string> mods_paths;+ if (!user_game)+ mods_paths.insert(share + DIR_DELIM + "mods");++ const char *env_mod_path = getenv("MINETEST_MOD_PATH");++ if (env_mod_path)++ mods_paths.insert(std::string(env_mod_path));+ if (user != share || user_game)+ mods_paths.insert(user + DIR_DELIM + "mods");+ +diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp+index ad00de1c4..737550c42 100644+--- a/src/script/lua_api/l_mainmenu.cpp++++ b/src/script/lua_api/l_mainmenu.cpp+@@ -495,9 +495,19 @@ int ModApiMainMenu::l_get_user_path(lua_State *L)+ /******************************************************************************/+ int ModApiMainMenu::l_get_modpath(lua_State *L)+ {++ const char *c_modpath = getenv("MINETEST_MOD_PATH");+ std::string modpath = fs::RemoveRelativePathComponents(+ porting::path_user + DIR_DELIM + "mods" + DIR_DELIM);+- lua_pushstring(L, modpath.c_str());++ if (c_modpath == NULL)++ c_modpath = modpath.c_str();++ lua_pushstring(L, c_modpath);++ return 1;++}++++/******************************************************************************/++int ModApiMainMenu::l_mod_path_set(lua_State *L)++{++ lua_pushboolean(L, NULL != getenv("MINETEST_MOD_PATH"));+ return 1;+ }+ +@@ -855,6 +865,7 @@ void ModApiMainMenu::Initialize(lua_State *L, int top)+ API_FCT(get_mapgen_names);+ API_FCT(get_user_path);+ API_FCT(get_modpath);++ API_FCT(mod_path_set);+ API_FCT(get_clientmodpath);+ API_FCT(get_gamepath);+ API_FCT(get_texturepath);+@@ -888,6 +899,7 @@ void ModApiMainMenu::InitializeAsync(lua_State *L, int top)+ API_FCT(get_mapgen_names);+ API_FCT(get_user_path);+ API_FCT(get_modpath);++ API_FCT(mod_path_set);+ API_FCT(get_clientmodpath);+ API_FCT(get_gamepath);+ API_FCT(get_texturepath);+diff --git a/src/script/lua_api/l_mainmenu.h b/src/script/lua_api/l_mainmenu.h+index ec2d20da2..719c26077 100644+--- a/src/script/lua_api/l_mainmenu.h++++ b/src/script/lua_api/l_mainmenu.h+@@ -112,6 +112,8 @@ class ModApiMainMenu: public ModApiBase+ + static int l_get_modpath(lua_State *L);+ ++ static int l_mod_path_set(lua_State *L);+++ static int l_get_clientmodpath(lua_State *L);+ + static int l_get_gamepath(lua_State *L);+-- +2.32.0+-- 2.32.0
M
M
Maxime Devos wrote on 2 Aug 17:50 +0200
[PATCH 03/20] gnu: minetest: New package module.
(address . 49828@debbugs.gnu.org)(name . Maxime Devos)(address . maximedevos@telenet.be)
20210802155019.6122-3-maximedevos@telenet.be
Aside from the 'minetest-topic' procedure which will be usedfor the 'home-page' field of some packages, this module iscurrently empty. The 'contentdb' importer defined in thefollowing patches will be used to populate this module.
* gnu/packages/minetest.scm: New file.* gnu/local.mk (GNU_SYSTEM_MODULES): Add it.--- gnu/local.mk | 1 + gnu/packages/minetest.scm | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 gnu/packages/minetest.scm
Toggle diff (46 lines)diff --git a/gnu/local.mk b/gnu/local.mkindex d96d4e3dbc..5de08b1b09 100644--- a/gnu/local.mk+++ b/gnu/local.mk@@ -383,6 +383,7 @@ GNU_SYSTEM_MODULES = \ %D%/packages/mercury.scm \ %D%/packages/mes.scm \ %D%/packages/messaging.scm \+ %D%/packages/minetest.scm \ %D%/packages/mingw.scm \ %D%/packages/microcom.scm \ %D%/packages/moe.scm \diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmnew file mode 100644index 0000000000..f8aca3005c--- /dev/null+++ b/gnu/packages/minetest.scm@@ -0,0 +1,26 @@+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>+;;; 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 (gnu packages minetest)+ #:use-module (guix packages)+ #:use-module (guix git-download)+ #:use-module (guix build-system minetest)+ #:use-module ((guix licenses) #:prefix license:))++(define-public (minetest-topic topic-id)+ "Return an URL (as a string) pointing to the forum topic with+numeric identifier TOPIC-ID on the official Minetest forums."+ (string-append "https://forum.minetest.net/viewtopic.php?t="+ (number->string topic-id)))-- 2.32.0
M
M
Maxime Devos wrote on 2 Aug 17:50 +0200
[PATCH 04/20] build-system: Add 'minetest-mod-build-system'.
(address . 49828@debbugs.gnu.org)(name . Maxime Devos)(address . maximedevos@telenet.be)
20210802155019.6122-4-maximedevos@telenet.be
* guix/build-system/minetest.scm: New module.* Makefile.am (MODULES): Add it.* doc/guix.texi (Build Systems): Document 'minetest-mod-build-system'.--- Makefile.am | 1 + doc/guix.texi | 7 +++++ guix/build-system/minetest.scm | 53 ++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 guix/build-system/minetest.scm
Toggle diff (91 lines)diff --git a/Makefile.am b/Makefile.amindex d5ec909213..f6fae09579 100644--- a/Makefile.am+++ b/Makefile.am@@ -141,6 +141,7 @@ MODULES = \ guix/build-system/go.scm \ guix/build-system/meson.scm \ guix/build-system/minify.scm \+ guix/build-system/minetest.scm \ guix/build-system/asdf.scm \ guix/build-system/copy.scm \ guix/build-system/glib-or-gtk.scm \diff --git a/doc/guix.texi b/doc/guix.texiindex b3c16e6507..43c248234d 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -7895,6 +7895,13 @@ declaration. Its default value is @code{(default-maven-plugins)} which is also exported. @end defvr +@defvr {Scheme Variable} minetest-mod-build-system+This variable is exported by @code{(guix build-system minetest)}. It+implements a build procedure for @uref{https://www.minetest.net, Minetest}+mods, which consists of copying lua code, images and other resources to+the location Minetest searches for mods.+@end defvr+ @defvr {Scheme Variable} minify-build-system This variable is exported by @code{(guix build-system minify)}. It implements a minification procedure for simple JavaScript packages.diff --git a/guix/build-system/minetest.scm b/guix/build-system/minetest.scmnew file mode 100644index 0000000000..29866ced6d--- /dev/null+++ b/guix/build-system/minetest.scm@@ -0,0 +1,53 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>+;;;+;;; 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 build-system minetest)+ #:use-module (guix build-system copy)+ #:use-module (guix build-system)+ #:export (minetest-mod-build-system))++;;+;; Build procedure for minetest mods. This is implemented as an extension+;; of ‘copy-build-system’.+;;+;; Code:++(define (guix-name->mod-name package-name)+ ;; The "minetest-" prefix is useless. Don't make it appear in the+ ;; ‘select mods’ menu when "modpack.conf" or "mod.conf" do not have+ ;; the "name" field set.+ (if (string-prefix? "minetest-" package-name)+ (substring package-name 9)+ package-name))++(define (lower-mod name . arguments)+ (define lower (build-system-lower copy-build-system))+ (apply lower+ name+ #:install-plan+ `'(("." ,(string-append "share/minetest/mods/"+ (guix-name->mod-name name))))+ arguments))++(define minetest-mod-build-system+ (build-system+ (name 'minetest-mod)+ (description "The build system for minetest mods")+ (lower lower-mod)))++;;; minetest.scm ends here-- 2.32.0
M
M
Maxime Devos wrote on 2 Aug 17:50 +0200
[PATCH 05/20] build-system: minetest: Don't retain references to "bash-minimal".
(address . 49828@debbugs.gnu.org)(name . Maxime Devos)(address . maximedevos@telenet.be)
20210802155019.6122-5-maximedevos@telenet.be
* guix/build-system/minetest.scm (%standard-phases): New variable. Delete "patch-source-shebangs" phase. (lower-mod): Set #:phases to value of new variable.--- guix/build-system/minetest.scm | 9 +++++++++ 1 file changed, 9 insertions(+)
Toggle diff (29 lines)diff --git a/guix/build-system/minetest.scm b/guix/build-system/minetest.scmindex 29866ced6d..993c5631eb 100644--- a/guix/build-system/minetest.scm+++ b/guix/build-system/minetest.scm@@ -35,6 +35,14 @@ (substring package-name 9) package-name)) +(define %standard-phases+ ;; The source code sometimes contains shell scripts which are used for+ ;; development but not at run time (e.g. listnodes.sh in+ ;; minetest-homedecor-modpack). Don't make them retain a reference+ ;; to bash-minimal.+ '(modify-phases (@ (guix build copy-build-system) %standard-phases)+ (delete 'patch-source-shebangs)))+ (define (lower-mod name . arguments) (define lower (build-system-lower copy-build-system)) (apply lower@@ -42,6 +50,7 @@ #:install-plan `'(("." ,(string-append "share/minetest/mods/" (guix-name->mod-name name))))+ #:phases %standard-phases arguments)) (define minetest-mod-build-system-- 2.32.0
M
M
Maxime Devos wrote on 2 Aug 17:50 +0200
[PATCH 09/20] gnu: Add minetest-unifieddyes.
(address . 49828@debbugs.gnu.org)(name . Maxime Devos)(address . maximedevos@telenet.be)
20210802155019.6122-9-maximedevos@telenet.be
* gnu/packages/minetest.scm (minetest-unifieddyes): New variable.--- gnu/packages/minetest.scm | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
Toggle diff (38 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex a97065ad4c..b845e5a2b3 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -83,3 +83,31 @@ with different rules and mechanics.") ;; correct the inconsistency: ;; <https://github.com/minetest-mods/mesecons/issues/575>. (license (list license:lgpl3+ license:cc-by-sa3.0)))))++(define-public minetest-unifieddyes+ (package+ (name "minetest-unifieddyes")+ ;; Upstream uses dates as version numbers.+ (version "2021-04-20-1")+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://gitlab.com/VanessaE/unifieddyes")+ (commit "ff3b2d30fa0df5c7181fdd401b989de6271c3bb3")))+ (sha256+ (base32+ "0rba9n192xcpmxwnq7ixb6mn32gkpic247j3w4mwinrqcyscacsv"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (propagated-inputs+ `(("minetest-basic-materials" ,minetest-basic-materials)))+ (home-page (minetest-topic 2178))+ (synopsis+ "Unified Dyes expands the standard dye set of Minetest to up to 256 colours")+ (description "The purpose of this mod originally was to supply a complete+set of colours for Minetest mod authors to use for colourised nodes or+reference in recipes. Since the advent of the default dyes mod in the standard+Minetest game, this mod has become an extension of the default mod an a library+for general colour handling.")+ (license license:gpl2+)))-- 2.32.0
M
M
Maxime Devos wrote on 2 Aug 17:50 +0200
[PATCH 08/20] gnu: Add minetest-basic-materials.
(address . 49828@debbugs.gnu.org)(name . Maxime Devos)(address . maximedevos@telenet.be)
20210802155019.6122-8-maximedevos@telenet.be
* gnu/packages/minetest.scm (minetest-basic-materials): New variable.--- gnu/packages/minetest.scm | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
Toggle diff (37 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex 72e04c4b33..a97065ad4c 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -25,6 +25,30 @@ numeric identifier TOPIC-ID on the official Minetest forums." (string-append "https://forum.minetest.net/viewtopic.php?t=" (number->string topic-id))) +(define-public minetest-basic-materials+ (package+ (name "minetest-basic-materials")+ ;; Upstream uses dates as version numbers.+ (version "2021-01-30")+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://gitlab.com/VanessaE/basic_materials.git")+ (commit "e72665b2ed98d7be115779a32d35e6d9ffa231bd")))+ (sha256+ (base32 "0v6l3lrjgshy4sccjhfhmfxc3gk0cdy73qb02i9wd2vw506v5asx"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (home-page (minetest-topic 21000))+ (synopsis "Some \"basic\" materials and items for other Minetest mods to use")+ (description+ "The Minetest mod \"basic_materials\" provides a small selection of+\"basic\" materials and items that other mods should use when possible -- things+like steel bars and chains, wire, plastic strips and sheets, and more.")+ (license+ (list license:cc-by-sa4.0 license:lgpl3))))+ (define-public minetest-mesecons ;; The release on ContentDB does not have its own version number. (let ((commit "db5879706d04d3480bc4863ce0c03fa73e5f10c7")-- 2.32.0
M
M
Maxime Devos wrote on 2 Aug 17:50 +0200
[PATCH 07/20] gnu: Add minetest-mesecons.
(address . 49828@debbugs.gnu.org)(name . Maxime Devos)(address . maximedevos@telenet.be)
20210802155019.6122-7-maximedevos@telenet.be
* gnu/packages/minetest.scm (minetest-mesecons): New variable.--- gnu/packages/minetest.scm | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+)
Toggle diff (45 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex f8aca3005c..72e04c4b33 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -24,3 +24,38 @@ numeric identifier TOPIC-ID on the official Minetest forums." (string-append "https://forum.minetest.net/viewtopic.php?t=" (number->string topic-id)))++(define-public minetest-mesecons+ ;; The release on ContentDB does not have its own version number.+ (let ((commit "db5879706d04d3480bc4863ce0c03fa73e5f10c7")+ (revision "0"))+ (package+ (name "minetest-mesecons")+ (version (git-version "1.2.1" revision commit))+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/minetest-mods/mesecons")+ (commit commit)))+ (sha256+ (base32 "04m9s9l3frw1lgki41hgvjsw2zkrvfv0sy750b6j12arzb3lv645"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (home-page "https://mesecons.net")+ (synopsis+ "Digital circuitry for Minetest, including wires, buttons and lights")+ (description+ "Mesecons is a mod for Minetest implementing various items related+to digital circuitry, such as wires, buttons, lights and programmable+controllers. Among other things, there are also pistons, solar panels,+pressure plates and note blocks.++Mesecons has a similar goal to Redstone in Minecraft, but works in its own way,+with different rules and mechanics.")+ ;; LGPL for code, CC-BY-SA for textures.+ ;; The README.md and COPYING.txt disagree about the "+" in license:lgpl3+.+ ;; For now, assume README.md is correct. Upstream has been asked to+ ;; correct the inconsistency:+ ;; <https://github.com/minetest-mods/mesecons/issues/575>.+ (license (list license:lgpl3+ license:cc-by-sa3.0)))))-- 2.32.0
M
M
Maxime Devos wrote on 2 Aug 17:50 +0200
[PATCH 10/20] gnu: Add minetest-pipeworks.
(address . 49828@debbugs.gnu.org)(name . Maxime Devos)(address . maximedevos@telenet.be)
20210802155019.6122-10-maximedevos@telenet.be
* gnu/packages/minetest.scm (minetest-pipeworks): New variable.--- gnu/packages/minetest.scm | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
Toggle diff (43 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex b845e5a2b3..a281eddea0 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -84,6 +84,36 @@ with different rules and mechanics.") ;; <https://github.com/minetest-mods/mesecons/issues/575>. (license (list license:lgpl3+ license:cc-by-sa3.0))))) +(define-public minetest-pipeworks+ (package+ (name "minetest-pipeworks")+ ;; Upstream uses dates as version numbers.+ (version "2021-04-14-1")+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://gitlab.com/VanessaE/pipeworks")+ (commit "db6d1bd9c109e1e543b97cc3fa8a11400da23bcd")))+ (sha256+ (base32 "1flhcnf17dn1v86kcg47a1n4cb0lybd11ncxrkxn3wmf10ibsrm0"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (propagated-inputs+ `(("minetest-basic-materials" ,minetest-basic-materials)))+ (home-page (minetest-topic 2155))+ (synopsis "Pipes, item-transport tubes and related devices for Minetest")+ (description+ "Pipeworks is a mod for Minetest implementing 3D pipes and tubes for+transporting liquids and items and some related devices. Pipes and tubes can+go horizontally or vertically. Item tubes can also be used for sorting items+and extracting items from chests or putting items in chests. Autocrafters can+automatically follow craft recipes to make new items and can be fed by item+tubes. Deployers can place items in the world as a player would. Node+breakers simulate a player punching a node.")+ ;; CC-BY-SA for textures, LGPL for code+ (license (list license:cc-by-sa4.0 license:lgpl3))))+ (define-public minetest-unifieddyes (package (name "minetest-unifieddyes")-- 2.32.0
M
M
Maxime Devos wrote on 2 Aug 17:50 +0200
[PATCH 13/20] gnu: Add minetest-technic.
(address . 49828@debbugs.gnu.org)(name . Maxime Devos)(address . maximedevos@telenet.be)
20210802155019.6122-13-maximedevos@telenet.be
* gnu/packages/minetest.scm (minetest-technic): New variable.--- gnu/packages/minetest.scm | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+)
Toggle diff (47 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex 12e15ee946..c901c5fcc7 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -169,6 +169,40 @@ breakers simulate a player punching a node.") ;; CC-BY-SA for textures, LGPL for code (license (list license:cc-by-sa4.0 license:lgpl3)))) +(define-public minetest-technic+ (package+ (name "minetest-technic")+ ;; Upstream doesn't keep version numbers, so use the release+ ;; date on ContentDB instead.+ (version "2021-04-15")+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/minetest-mods/technic")+ (commit "1c219487d3f4dd03c01ff9aa1f298c7c18c7e189")))+ (sha256+ (base32 "1k9hdgzp7jnhsk6rgrlrv1lr5xrmh8ln4wv6r25v6f0fwbyj57sf"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (propagated-inputs+ `(("minetest-pipeworks" ,minetest-pipeworks)+ ("minetest-basic-materials" ,minetest-basic-materials)))+ (home-page (minetest-topic 2538))+ (synopsis "Machinery and automation for Minetest")+ (description+ "This Minetest mod adds machinery and automation to Minetest.+It adds various ores that can be processed for constructing various+machinery, such as power generators, force field emitters, quarries+and a workshop for repairing tools. Most machines are electrically+powered.")+ ;; CC BY-SA 3.0: some texture+ ;; WTFPL: some textures+ ;; CC BY-SA3.0: some textures+ ;; CC BY-SA4.0: some sounds+ (license (list license:lgpl2.1+ license:cc-by-sa3.0 license:cc-by-sa4.0+ license:wtfpl2))))+ (define-public minetest-unifieddyes (package (name "minetest-unifieddyes")-- 2.32.0
M
M
Maxime Devos wrote on 2 Aug 17:50 +0200
[PATCH 11/20] gnu: Add minetest-coloredwood.
(address . 49828@debbugs.gnu.org)(name . Maxime Devos)(address . maximedevos@telenet.be)
20210802155019.6122-11-maximedevos@telenet.be
* gnu/packages/minetest.scm (minetest-coloredwood): New variable.--- gnu/packages/minetest.scm | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
Toggle diff (40 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex a281eddea0..fd2e78ade8 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -49,6 +49,33 @@ like steel bars and chains, wire, plastic strips and sheets, and more.") (license (list license:cc-by-sa4.0 license:lgpl3)))) +(define-public minetest-coloredwood+ (package+ (name "minetest-coloredwood")+ ;; Upstream uses dates as version numbers.+ (version "2021-04-14-1")+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://gitlab.com/VanessaE/coloredwood")+ (commit "be4df6fc889419155bed8638bbb752493e78cbd5")))+ (sha256+ (base32 "1swirfk6b4xfbiwv8adyw5yl2lyfpp8ymfipzq9ivyvmif8nl3ki"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (propagated-inputs+ `(("minetest-unifieddyes" ,minetest-unifieddyes)))+ (home-page (minetest-topic 2411))+ (synopsis "Painted wood in Minetest")+ (description+ "This Minetest mod provides hundreds of colours of wood and fences to+Minetest, using Unified Dyes. If the \"moreblocks\" mod is active,+coloured and cut wood shapes are provided as well.")+ (license+ ;; LGPL for code, CC-BY-SA for textures+ (list license:cc-by-sa4.0 license:lgpl3))))+ (define-public minetest-mesecons ;; The release on ContentDB does not have its own version number. (let ((commit "db5879706d04d3480bc4863ce0c03fa73e5f10c7")-- 2.32.0
M
M
Maxime Devos wrote on 2 Aug 17:50 +0200
[PATCH 14/20] gnu: Add minetest-throwing.
(address . 49828@debbugs.gnu.org)(name . Maxime Devos)(address . maximedevos@telenet.be)
20210802155019.6122-14-maximedevos@telenet.be
* gnu/packages/minetest.scm (minetest-throwing): New variable.--- gnu/packages/minetest.scm | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
Toggle diff (35 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex c901c5fcc7..25038a5f6b 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -203,6 +203,28 @@ powered.") (license (list license:lgpl2.1+ license:cc-by-sa3.0 license:cc-by-sa4.0 license:wtfpl2)))) +(define-public minetest-throwing+ (package+ (name "minetest-throwing")+ (version "2020-08-14")+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/minetest-mods/throwing")+ (commit "31f0cf5f868673dc82f24ddc432b45c9cd282d27")))+ (sha256+ (base32 "1s5kkr6rxxv2dhbbjzv62gw1s617hnpjavw1v9fv11v3mgigdfjb"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (home-page (minetest-topic 16365))+ (synopsis "API for throwing things in Minetest")+ (description+ "This Minetest mod provides an API for registering throwable things and+throwing things like arrows. However, this mod does not provide an actual+arrow and bow, but @code{minetest-throwing-arrows} does.")+ (license license:mpl2.0)))+ (define-public minetest-unifieddyes (package (name "minetest-unifieddyes")-- 2.32.0
M
M
Maxime Devos wrote on 2 Aug 17:50 +0200
[PATCH 16/20] gnu: Add minetest-unified-inventory.
(address . 49828@debbugs.gnu.org)(name . Maxime Devos)(address . maximedevos@telenet.be)
20210802155019.6122-16-maximedevos@telenet.be
* gnu/packages/minetest.scm (minetest-unified-inventory): New variable.--- gnu/packages/minetest.scm | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+)
Toggle diff (44 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex 6b792bf071..2c028e3e87 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -281,3 +281,37 @@ reference in recipes. Since the advent of the default dyes mod in the standard Minetest game, this mod has become an extension of the default mod an a library for general colour handling.") (license license:gpl2+)))++(define-public minetest-unified-inventory+ (package+ (name "minetest-unified-inventory")+ ;; Upstream doesn't keep version numbers, so use the release title+ ;; on ContentDB instead.+ (version "2021-03-25-1")+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/minetest-mods/unified_inventory")+ (commit "c044f5e3b08f0c68ab028d757b2fa63d9a1b0370")))+ (sha256+ (base32 "198g945gzbfl0kps46gwjw0c601l3b3wvn4c7dw8manskri1jr4g"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (home-page (minetest-topic 12767))+ (synopsis "Replace the default inventory in Minetest and add a crafting guide")+ (description+ "The Unified Inventory Minetest mod relaces the default survival an+creative inventory. It includes a node, item and tool browser, a crafting+guide, a trash and refill slot for creative mode, bags and waypoints for keeping+track of important locations.")+ ;; CC-BY: some textures and icons+ ;; CC-BY-SA: some textures and icons+ ;; LGLPL2.1+: code and some textures+ ;; GPL2+: some textures+ ;; GPL3: bags.lua+ ;; GFDL: some icons+ ;; public domain, CC0: some icons+ (license (list license:gpl3 license:gpl2+ license:lgpl2.1+ license:cc-by3.0+ license:cc-by4.0 license:cc-by-sa3.0 license:public-domain+ license:cc0 license:fdl1.2+))))-- 2.32.0
M
M
Maxime Devos wrote on 2 Aug 17:50 +0200
[PATCH 12/20] gnu: Add minetest-ethereal.
(address . 49828@debbugs.gnu.org)(name . Maxime Devos)(address . maximedevos@telenet.be)
20210802155019.6122-12-maximedevos@telenet.be
* gnu/packages/minetest.scm (minetest-ethereal): New variable.--- gnu/packages/minetest.scm | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-)
Toggle diff (51 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex fd2e78ade8..12e15ee946 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -76,6 +76,34 @@ coloured and cut wood shapes are provided as well.") ;; LGPL for code, CC-BY-SA for textures (list license:cc-by-sa4.0 license:lgpl3)))) +(define-public minetest-ethereal+ ;; ContentDB release 2021-07-28 is slightly ahead of the+ ;; initial version 1.29 -- i.e., some released changes have been+ ;; made to version 1.29 without a corresponding version bump.+ (let ((commit "7670c1da9274901f57f6682384af2b3bae005a86")+ (revision "0"))+ (package+ (name "minetest-ethereal")+ (version (git-version "1.29" revision commit))+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://notabug.org/TenPlus1/ethereal")+ (commit commit)))+ (sha256+ (base32 "1hal8bq4fydsip7s8rqz4vlaaqy9rhzxmryd0j2qnqm9286yjgkk"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (home-page (minetest-topic 14638))+ (synopsis "The Ethereal mod adds many new biomes to Minetest")+ (description+ "The Ethereal Minetest mod uses the v7 map generator to add many new+biomes to the world. It adds new trees, plants, food items, tweaks and some+special items, intending to make an interesting adventure.")+ ;; CC0: some textures+ (license (list license:cc0 license:expat)))))+ (define-public minetest-mesecons ;; The release on ContentDB does not have its own version number. (let ((commit "db5879706d04d3480bc4863ce0c03fa73e5f10c7")@@ -153,8 +181,7 @@ breakers simulate a player punching a node.") (url "https://gitlab.com/VanessaE/unifieddyes") (commit "ff3b2d30fa0df5c7181fdd401b989de6271c3bb3"))) (sha256- (base32- "0rba9n192xcpmxwnq7ixb6mn32gkpic247j3w4mwinrqcyscacsv"))+ (base32 "0rba9n192xcpmxwnq7ixb6mn32gkpic247j3w4mwinrqcyscacsv")) (file-name (git-file-name name version)))) (build-system minetest-mod-build-system) (propagated-inputs-- 2.32.0
M
M
Maxime Devos wrote on 2 Aug 17:50 +0200
[PATCH 17/20] gnu: Add minetest-worldedit.
(address . 49828@debbugs.gnu.org)(name . Maxime Devos)(address . maximedevos@telenet.be)
20210802155019.6122-17-maximedevos@telenet.be
* gnu/packages/minetest.scm (minetest-worldedit): New variable.--- gnu/packages/minetest.scm | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
Toggle diff (35 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex 2c028e3e87..0e16743823 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -255,6 +255,28 @@ arrow and bow, but @code{minetest-throwing-arrows} does.") replacement for the throwing mod by PilzAdam that uses the throwing API.") (license license:mpl2.0)))) +(define-public minetest-worldedit+ (package+ (name "minetest-worldedit")+ (version "1.3")+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/Uberi/Minetest-WorldEdit")+ (commit "2f26fb76459c587868199160b9d7b5d6d7852e50")))+ (sha256+ (base32 "0lsvihkixi2na1b0vmml9vwgs0g24hqqshl73ffhkzh6jsq4cagq"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (home-page (minetest-topic 572))+ (synopsis "In-game world editor for Minetest")+ (description+ "WorldEdit is a mod for Minetest. It allows for creating various+geometric shapes and copying regions. It can also export and import regions+to and from the file system.")+ (license license:agpl3)))+ (define-public minetest-unifieddyes (package (name "minetest-unifieddyes")-- 2.32.0
M
M
Maxime Devos wrote on 2 Aug 17:50 +0200
[PATCH 18/20] gnu: Add minetest-mobs.
(address . 49828@debbugs.gnu.org)(name . Maxime Devos)(address . maximedevos@telenet.be)
20210802155019.6122-18-maximedevos@telenet.be
* gnu/packages/minetest.scm (minetest-mobs): New variable.--- gnu/packages/minetest.scm | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
Toggle diff (41 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex 0e16743823..4910fa72bb 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -139,6 +139,34 @@ with different rules and mechanics.") ;; <https://github.com/minetest-mods/mesecons/issues/575>. (license (list license:lgpl3+ license:cc-by-sa3.0))))) +(define-public minetest-mobs+ (package+ (name "minetest-mobs")+ ;; Upstream does not tag release, so use the ContentDB release+ ;; title instead.+ (version "2021-07-22")+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://notabug.org/TenPlus1/mobs_redo")+ (commit "9f46182bb4b1a390f9a140bc2b443f3cda702332")))+ (sha256+ (base32 "026kqjis4lipgskjivb3jh9ris3iz80vy2q1jvgxhxmfghjjzp4j"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (home-page (minetest-topic 9917))+ (synopsis "Mob library for Minetest mods, for animals, monsters etc.")+ (description+ "This Minetest mod provides an API for adding mods (moving entities+like animals and monsters), but does not include any mobs itself. To actually+add some mobs, a mod like e.g. @code{mobs_animal} provided by the+@code{minetest-mobs-animal} package needs to be enabled.")+ ;; CC0: mob_swing.ogg+ ;; CC-BY 3.0: mob_spell.ogg+ ;; Expat: everything else+ (license (list license:expat license:cc0 license:cc-by3.0))))+ (define-public minetest-pipeworks (package (name "minetest-pipeworks")-- 2.32.0
M
M
Maxime Devos wrote on 2 Aug 17:50 +0200
[PATCH 19/20] gnu: Add minetest-mobs-animal.
(address . 49828@debbugs.gnu.org)(name . Maxime Devos)(address . maximedevos@telenet.be)
20210802155019.6122-19-maximedevos@telenet.be
* gnu/packages/minetest.scm (minetest-mobs-animal): New variable.--- gnu/packages/minetest.scm | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
Toggle diff (39 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex 4910fa72bb..fcc3648795 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -167,6 +167,32 @@ add some mobs, a mod like e.g. @code{mobs_animal} provided by the ;; Expat: everything else (license (list license:expat license:cc0 license:cc-by3.0)))) +(define-public minetest-mobs-animal+ (package+ (name "minetest-mobs-animal")+ ;; Upstream does not use version numbers, so use the release title+ ;; from ContentDB instead;+ (version "2021-07-24")+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://notabug.org/TenPlus1/mobs_animal")+ (commit "c2fa3e300c79c7dd80b6fe91a8b5082bb6b3d934")))+ (sha256+ (base32 "1j719f079ia9vjxrmjrcj8s6jvaz5kgs1r4dh66z8ql6s70kx7vh"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (propagated-inputs+ `(("minetest-mobs" ,minetest-mobs)))+ (home-page "https://notabug.org/TenPlus1/mobs_animal")+ (synopsis "Add animals to Minetest")+ (description+ "This Minetest mod adds various animals to Minetest, such as bees,+bunnies, chickens, cows, kittens, rats, sheep, warthogs, penguins and pandas.")+ ;; CC0: some textures and sounds+ (license (list license:cc0 license:expat))))+ (define-public minetest-pipeworks (package (name "minetest-pipeworks")-- 2.32.0
M
M
Maxime Devos wrote on 2 Aug 17:50 +0200
[PATCH 20/20] gnu: Add minetest-homedecor-modpack.
(address . 49828@debbugs.gnu.org)(name . Maxime Devos)(address . maximedevos@telenet.be)
20210802155019.6122-20-maximedevos@telenet.be
* gnu/packages/minetest.scm (minetest-homedecor-modpack): New variable.--- gnu/packages/minetest.scm | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
Toggle diff (43 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex fcc3648795..7c483acd0c 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -104,6 +104,36 @@ special items, intending to make an interesting adventure.") ;; CC0: some textures (license (list license:cc0 license:expat))))) +(define-public minetest-homedecor-modpack+ (package+ (name "minetest-homedecor-modpack")+ ;; Upstream doesn't tag releases, so use the release title from+ ;; ContentDB as version.+ (version "2021-03-27-1")+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://gitlab.com/VanessaE/homedecor_modpack")+ (commit "9ffe2b7d691133e1a067546574fbe7364fd02f32")))+ (sha256+ (base32 "1lfajqvc2adf9hqskghky4arccqzpjw4i9a01hv4qcckvivm04ag"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (propagated-inputs+ `(("minetest-basic-materials" ,minetest-basic-materials)+ ("minetest-unifieddyes" ,minetest-unifieddyes)))+ (home-page (minetest-topic 2041))+ (synopsis "Home decor mod for Minetest")+ (description+ ;; TRANSLATORS: ‘homedecor’ is the name is the name of a Minetest mod+ ;; and should not be translated.+ "The homedecor Minetest mod provides a large seleection of items that+might be found inside and around homes, such as sofas, chairs, tables, fences+and a variety of other stuff.")+ (license+ (list license:cc-by-sa4.0 license:lgpl3))))+ (define-public minetest-mesecons ;; The release on ContentDB does not have its own version number. (let ((commit "db5879706d04d3480bc4863ce0c03fa73e5f10c7")-- 2.32.0
M
M
Maxime Devos wrote on 2 Aug 17:50 +0200
[PATCH 06/20] guix: Add ContentDB importer.
(address . 49828@debbugs.gnu.org)(name . Maxime Devos)(address . maximedevos@telenet.be)
20210802155019.6122-6-maximedevos@telenet.be
* guix/import/contentdb.scm: New file.* guix/scripts/import/contentdb.scm: New file.* tests/contentdb.scm: New file.* Makefile.am (MODULES, SCM_TESTS): Register them.* po/guix/POTFILES.in: Likewise.* doc/guix.texi (Invoking guix import): Document it.--- Makefile.am | 3 + doc/guix.texi | 25 +++ guix/import/contentdb.scm | 310 ++++++++++++++++++++++++++++++ guix/scripts/import.scm | 3 +- guix/scripts/import/contentdb.scm | 106 ++++++++++ po/guix/POTFILES.in | 1 + tests/contentdb.scm | 227 ++++++++++++++++++++++ 7 files changed, 674 insertions(+), 1 deletion(-) create mode 100644 guix/import/contentdb.scm create mode 100644 guix/scripts/import/contentdb.scm create mode 100644 tests/contentdb.scm
Toggle diff (753 lines)diff --git a/Makefile.am b/Makefile.amindex f6fae09579..b9265c154d 100644--- a/Makefile.am+++ b/Makefile.am@@ -261,6 +261,7 @@ MODULES = \ guix/import/json.scm \ guix/import/kde.scm \ guix/import/launchpad.scm \+ guix/import/contentdb.scm \ guix/import/opam.scm \ guix/import/print.scm \ guix/import/pypi.scm \@@ -303,6 +304,7 @@ MODULES = \ guix/scripts/import/go.scm \ guix/scripts/import/hackage.scm \ guix/scripts/import/json.scm \+ guix/scripts/import/contentdb.scm \ guix/scripts/import/opam.scm \ guix/scripts/import/pypi.scm \ guix/scripts/import/stackage.scm \@@ -445,6 +447,7 @@ SCM_TESTS = \ tests/channels.scm \ tests/combinators.scm \ tests/containers.scm \+ tests/contentdb.scm \ tests/cpan.scm \ tests/cpio.scm \ tests/cran.scm \diff --git a/doc/guix.texi b/doc/guix.texiindex 43c248234d..d06c9b73c5 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -11313,6 +11313,31 @@ and generate package expressions for all those packages that are not yet in Guix. @end table +@item contentdb+@cindex ContentDB+Import metadata from @uref{https://content.minetest.net, ContentDB}.+Information is taken from the JSON-formatted metadata provided through+@uref{https://content.minetest.net/help/api/, ContentDB's API} and+includes most relevant information, including dependencies. There are+some caveats, however. The license information on ContentDB does not+distinguish between GPLvN-only and GPLvN-or-later. The commit id is+sometimes missing. The descriptions are in the Markdown format, but+Guix uses Texinfo instead. Texture packs and subgames are unsupported.++The command below imports metadata for the Mesecons mod by Jeija:++@example+guix import contentdb Jeija mesecons+@end example++@table @code+@item --recursive+@itemx -r+Traverse the dependency graph of the given upstream package recursively+and generate package expressions for all those packages that are not yet+in Guix.+@end table+ @item cpan @cindex CPAN Import metadata from @uref{https://www.metacpan.org/, MetaCPAN}.diff --git a/guix/import/contentdb.scm b/guix/import/contentdb.scmnew file mode 100644index 0000000000..1a36a09c92--- /dev/null+++ b/guix/import/contentdb.scm@@ -0,0 +1,310 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet;be>+;;;+;;; 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 contentdb)+ #:use-module (ice-9 match)+ #:use-module (ice-9 receive)+ #:use-module (srfi srfi-1)+ #:use-module (srfi srfi-2)+ #:use-module (srfi srfi-11)+ #:use-module (srfi srfi-26)+ #:use-module (guix utils)+ #:use-module (guix memoization)+ #:use-module (guix serialization)+ #:use-module (guix import utils)+ #:use-module (guix import json)+ #:use-module ((gcrypt hash) #:select (open-sha256-port port-sha256))+ #:use-module (json)+ #:use-module (guix base32)+ #:use-module (guix git)+ #:use-module (guix store)+ #:use-module ((guix licenses) #:prefix license:)+ #:export (%contentdb-api+ contentdb->guix-package+ contentdb-recursive-import))++;; 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))++;; 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) ; natural | #f+ (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) ; string | #f+ (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)) ; string | #f++(define-json-mapping <release> make-release release?+ json->release+ (commit release-commit "commit" string-or-false) ; string | #f+ (downloads release-downloads) ; integer+ (id release-id) ; integer+ (max-minetest-version release-max-minetest-version) ; string | #f+ (min-minetest-version release-min-minetest-version) ; string | #f+ (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") ; #t | #f+ (name dependency-name) ; string+ (packages dependency-packages "packages" vector->list)) ; list of strings++(define (contentdb-fetch author name)+ "Return a <package> record for package NAME by AUTHOR, 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->package-name name)+ "Given the 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 name)))++;; 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)))++;; XXX adapted from (guix scripts hash)+(define (file-hash file select? recursive?)+ ;; Compute the hash of FILE.+ (if recursive?+ (let-values (((port get-hash) (open-sha256-port)))+ (write-file file port #:select? select?)+ (force-output port)+ (get-hash))+ (call-with-input-file file port-sha256)))+;; XXX likewise.+(define (vcs-file? file stat)+ (case (stat:type stat)+ ((directory)+ (member (basename file) '(".bzr" ".git" ".hg" ".svn" "CVS")))+ ((regular)+ ;; Git sub-modules have a '.git' file that is a regular text file.+ (string=? (basename file) ".git"))+ (else+ #f)))++(define (make-minetest-sexp name version repository commit+ inputs home-page synopsis+ description media-license license)+ "Return a S-expression for the minetest package with the given NAME,+VERSION, REPOSITORY, COMMIT, INPUTS, HOME-PAGE, SYNOPSIS, DESCRIPTION,+MEDIA-LICENSE and LICENSE."+ `(package+ (name ,(contentdb->package-name name))+ (version ,version)+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url ,repository)+ (commit ,commit)))+ (sha256+ (base32+ ;; The commit id is not always available.+ ,(and commit+ (bytevector->nix-base32-string+ (file-hash+ (download-git-repository repository `(commit . ,commit))+ (negate vcs-file?) #t)))))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ ,@(maybe-propagated-inputs+ (map (compose contentdb->package-name cdr) inputs))+ (home-page ,home-page)+ (synopsis ,(delete-cr synopsis))+ (description ,(delete-cr description))+ (license ,(if (eq? media-license license)+ (license->symbol license)+ `(list ,(license->symbol media-license)+ ,(license->symbol license))))))++(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)))++(define (important-dependencies dependencies author name)+ (define dependency-list+ (assoc-ref dependencies (string-append author "/" name)))+ (filter-map+ (lambda (dependency)+ (and (not (dependency-optional? dependency))+ ;; "default" must be provided by the 'subgame' in use+ ;; and does not refer to a specific minetest mod.+ ;; "doors", "bucket" ... are provided by the default minetest+ ;; subgame.+ (not (member (dependency-name dependency)+ '("default" "doors" "beds" "bucket" "doors" "farming"+ "flowers" "stairs" "xpanes")))+ ;; Dependencies often have only one implementation.+ (let* ((/name (string-append "/" (dependency-name dependency)))+ (likewise-named-implementations+ (filter (cut string-suffix? /name <>)+ (dependency-packages dependency)))+ (implementation+ (and (not (null? likewise-named-implementations))+ (first likewise-named-implementations))))+ (and implementation+ (apply cons (string-split implementation #\/))))))+ dependency-list))++(define* (%contentdb->guix-package author name)+ "Fetch the metadata for NAME by AUTHOR from https://content.minetest.net, and+return the 'package' S-expression corresponding to that package, or #f on failure.+On success, also return the upstream dependencies as a list of+(AUTHOR . NAME) pairs."+ (and-let* ((package (contentdb-fetch author name))+ (dependencies (contentdb-fetch-dependencies author name))+ (release (latest-release author name)))+ (let ((important-upstream-dependencies+ (important-dependencies dependencies author name)))+ (values (make-minetest-sexp name+ (release-title release) ; version+ (package-repository package)+ (release-commit release)+ important-upstream-dependencies+ (package-home-page package)+ (package-short-description package)+ (package-long-description package)+ (string->license+ (package-media-license package))+ (string->license+ (package-license package)))+ important-upstream-dependencies))))++(define contentdb->guix-package+ (memoize %contentdb->guix-package))++(define (contentdb-recursive-import author name)+ ;; recursive-import expects upstream package names to be strings,+ ;; so do some conversions.+ (define (split-author/name author/name)+ (string-split author/name #\/))+ (define (author+name->author/name author+name)+ (string-append (car author+name) "/" (cdr author+name)))+ (define* (contentdb->guix-package* author/name #:key repo version)+ (receive (package . maybe-dependencies)+ (apply contentdb->guix-package (split-author/name author/name))+ (and package+ (receive (dependencies)+ (apply values maybe-dependencies)+ (values package+ (map author+name->author/name dependencies))))))+ (recursive-import (author+name->author/name (cons author name))+ #:repo->guix-package contentdb->guix-package*+ #:guix-name+ (lambda (author/name)+ (contentdb->package-name+ (second (split-author/name author/name))))))++;; A list of license names is available at+;; <https://content.minetest.net/api/licenses/>.+(define (string->license str)+ "Convert the string STR into a license object."+ (match str+ ("GPLv3" license:gpl3)+ ("GPLv2" license:gpl2)+ ("ISC" license:isc)+ ;; "MIT" means the Expat license on ContentDB,+ ;; see <https://github.com/minetest/contentdb/issues/326#issuecomment-890143784>.+ ("MIT" license:expat)+ ("CC BY-SA 3.0" license:cc-by-sa3.0)+ ("CC BY-SA 4.0" license:cc-by-sa4.0)+ ("LGPLv2.1" license:lgpl2.1)+ ("LGPLv3" license:lgpl3)+ ("MPL 2.0" license:mpl2.0)+ ("ZLib" license:zlib)+ ("Unlicense" license:unlicense)+ (_ #f)))diff --git a/guix/scripts/import.scm b/guix/scripts/import.scmindex f53d1ac1f4..015677e719 100644--- a/guix/scripts/import.scm+++ b/guix/scripts/import.scm@@ -77,7 +77,8 @@ rather than \\n." ;;; (define importers '("gnu" "pypi" "cpan" "hackage" "stackage" "egg" "elpa"- "gem" "go" "cran" "crate" "texlive" "json" "opam"))+ "gem" "go" "cran" "crate" "texlive" "json" "opam"+ "contentdb")) (define (resolve-importer name) (let ((module (resolve-interfacediff --git a/guix/scripts/import/contentdb.scm b/guix/scripts/import/contentdb.scmnew file mode 100644index 0000000000..4170fff950--- /dev/null+++ b/guix/scripts/import/contentdb.scm@@ -0,0 +1,106 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2014 David Thompson <davet@gnu.org>+;;; Copyright © 2018 Ricardo Wurmus <rekado@elephly.net>+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>+;;;+;;; 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 scripts import contentdb)+ #:use-module (guix ui)+ #:use-module (guix utils)+ #:use-module (guix scripts)+ #:use-module (guix import contentdb)+ #:use-module (guix import utils)+ #:use-module (guix scripts import)+ #:use-module (srfi srfi-1)+ #:use-module (srfi srfi-11)+ #:use-module (srfi srfi-37)+ #:use-module (ice-9 match)+ #:use-module (ice-9 format)+ #:export (guix-import-contentdb))++ +;;;+;;; Command-line options.+;;;++(define %default-options+ '())++(define (show-help)+ (display (G_ "Usage: guix import contentdb AUTHOR NAME+Import and convert the Minetest mod NAME by AUTHOR from ContentDB.\n"))+ (display (G_ "+ -h, --help display this help and exit"))+ (display (G_ "+ -r, --recursive import packages recursively"))+ (display (G_ "+ -V, --version display version information and exit"))+ (newline)+ (show-bug-report-information))++(define %options+ ;; Specification of the command-line options.+ (cons* (option '(#\h "help") #f #f+ (lambda args+ (show-help)+ (exit 0)))+ (option '(#\V "version") #f #f+ (lambda args+ (show-version-and-exit "guix import contentdb")))+ (option '(#\r "recursive") #f #f+ (lambda (opt name arg result)+ (alist-cons 'recursive #t result)))+ %standard-import-options))++ +;;;+;;; Entry point.+;;;++(define (guix-import-contentdb . args)+ (define (parse-options)+ ;; Return the alist of option values.+ (args-fold* args %options+ (lambda (opt name arg result)+ (leave (G_ "~A: unrecognized option~%") name))+ (lambda (arg result)+ (alist-cons 'argument arg result))+ %default-options))++ (let* ((opts (parse-options))+ (args (filter-map (match-lambda+ (('argument . value)+ value)+ (_ #f))+ (reverse opts))))+ (match args+ ((author name)+ (with-error-handling+ (if (assoc-ref opts 'recursive)+ ;; Recursive import+ (filter-map package->definition+ (contentdb-recursive-import author name))+ ;; Single import+ (let ((sexp (contentdb->guix-package author name)))+ (unless sexp+ (leave (G_ "failed to download meta-data for package '~a' by '~a'~%")+ name author))+ sexp))))+ (()+ (leave (G_ "too few arguments~%")))+ ((many ...)+ (leave (G_ "too many arguments~%"))))))diff --git a/po/guix/POTFILES.in b/po/guix/POTFILES.inindex a3bced1a8f..f25a7b4802 100644--- a/po/guix/POTFILES.in+++ b/po/guix/POTFILES.in@@ -60,6 +60,7 @@ guix/scripts/git.scm guix/scripts/git/authenticate.scm guix/scripts/hash.scm guix/scripts/import.scm+guix/scripts/import/contentdb.scm guix/scripts/import/cran.scm guix/scripts/import/elpa.scm guix/scripts/pull.scmdiff --git a/tests/contentdb.scm b/tests/contentdb.scmnew file mode 100644index 0000000000..1293ac40cf--- /dev/null+++ b/tests/contentdb.scm@@ -0,0 +1,227 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>+;;;+;;; 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 (test-contentdb)+ #:use-module (guix memoization)+ #:use-module (guix import contentdb)+ #:use-module (guix import utils)+ #:use-module (guix tests)+ #:use-module (json)+ #:use-module (ice-9 match)+ #:use-module (srfi srfi-1)+ #:use-module (srfi srfi-64))++ +;; Some procedures for populating a ‘fake’ ContentDB server.++(define* (make-package-sexp #:key+ (guix-name "minetest-foo")+ (home-page "https://example.org/foo")+ (repo "https://example.org/foo.git")+ (synopsis "synopsis")+ (guix-description "description")+ (guix-license '(list license:cc-by-sa4.0 license:lgpl3))+ (inputs '())+ #:allow-other-keys)+ `(package+ (name ,guix-name)+ ;; This is not a proper version number but ContentDB does not include+ ;; version numbers.+ (version "2021-07-25")+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url ,(and (not (eq? repo 'null)) repo))+ (commit #f)))+ (sha256+ (base32 #f))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ ,@(maybe-propagated-inputs inputs)+ (home-page ,home-page)+ (synopsis ,synopsis)+ (description ,guix-description)+ (license ,guix-license)))++(define* (make-package-json #:key+ (author "Author")+ (name "foo")+ (media-license "CC BY-SA 4.0")+ (license "LGPLv3")+ (short-description "synopsis")+ (long-description "description")+ (repo "https://example.org/foo.git")+ (website "https://example.org/foo")+ (forums 321)+ #:allow-other-keys)+ `(("author" . ,author)+ ("content_warnings" . #())+ ("created_at" . "2018-05-23T19:58:07.422108")+ ("downloads" . 123)+ ("forums" . ,forums)+ ("issue_tracker" . "https://example.org/foo/issues")+ ("license" . ,license)+ ("long_description" . ,long-description)+ ("maintainers" . #("maintainer"))+ ("media_license" . ,media-license)+ ("name" . ,name)+ ("provides" . #("stuff"))+ ("release" . 456)+ ("repo" . ,repo)+ ("score" . ,987.654)+ ("screenshots" . #())+ ("short_description" . ,short-description)+ ("state" . "APPROVED")+ ("tags" . #("some" "tags"))+ ("thumbnail" . null)+ ("title" . "The name")+ ("type" . "mod")+ ("url" . ,(string-append "https://content.minetest.net/packages/"+ author "/" name "/download/"))+ ("website" . ,website)))++(define* (make-releases-json #:key (commit #f) (title "") #:allow-other-keys)+ `#((("commit" . ,commit)+ ("downloads" . 469)+ ("id" . 8614)+ ("max_minetest_version" . null)+ ("min_minetest_version" . null)+ ("release_date" . "2021-07-25T01:10:23.207584")+ ("title" . "2021-07-25"))))++(define* (make-dependencies-json #:key (author "Author")+ (name "foo")+ (requirements '(("default" #f ())))+ #:allow-other-keys)+ `((,(string-append author "/" name)+ . ,(list->vector+ (map (match-lambda+ ((symbolic-name optional? implementations)+ `(("is_optional" . ,optional?)+ ("name" . ,symbolic-name)+ ("packages" . ,(list->vector implementations)))))+ requirements)))+ ("something/else" . #())))++(define (call-with-packages thunk . argument-lists)+ (mock ((guix http-client) http-fetch+ (lambda* (url #:key headers)+ (unless (string-prefix? "mock://api/packages/" url)+ (error "the URL ~a should not be used" url))+ (define resource+ (substring url (string-length "mock://api/packages/")))+ (define components (string-split resource #\/))+ (unless (>= (length components) 2)+ (error "the URL ~a should have an author and name component" url))+ (define requested-author (list-ref components 0))+ (define requested-name (list-ref components 1))+ (define rest (cddr components))+ (define relevant-argument-list+ (any (lambda (argument-list)+ (apply (lambda* (#:key (author "Author") (name "foo")+ #:allow-other-keys)+ (and (equal? requested-author author)+ (equal? requested-name name)+ argument-list))+ argument-list))+ argument-lists))+ (when (not relevant-argument-list)+ (error "the package ~a/~a should be irrelevant, but ~a is fetched"+ requested-author requested-name url))+ (define (scm->json-port scm)+ (open-input-string (scm->json-string scm)))+ (scm->json-port+ (apply (match rest+ (("") make-package-json)+ (("dependencies" "") make-dependencies-json)+ (("releases" "") make-releases-json)+ (_ (error "TODO ~a" rest)))+ relevant-argument-list))))+ (parameterize ((%contentdb-api "mock://api/"))+ (thunk))))++(define* (contentdb->guix-package* #:key (author "Author") (name "foo")+ #:allow-other-keys)+ (contentdb->guix-package author name))++(define (imported-package-sexp . extra-arguments)+ (call-with-packages+ (lambda ()+ ;; Don't reuse results from previous tests.+ (invalidate-memoization! contentdb->guix-package)+ (apply contentdb->guix-package* extra-arguments))+ extra-arguments))++(define-syntax-rule (test-package test-case . extra-arguments)+ (test-equal test-case+ (make-package-sexp . extra-arguments)+ (imported-package-sexp . extra-arguments)))++(test-begin "contentdb")++ +;; Package names+(test-package "contentdb->guix-package")+(test-package "contentdb->guix-package, _ → - in package name"+ #:name "foo_bar"+ #:guix-name "minetest-foo-bar")++ +;; Determining the home page+(test-package "contentdb->guix-package, website is used as home page"+ #:home-page "web://site"+ #:website "web://site")+(test-package "contentdb->guix-package, if absent, the forum is used"+ #:home-page '(minetest-topic 628)+ #:forums 628+ #:website 'null)+(test-package "contentdb->guix-package, if absent, the git repo is used"+ #:home-page "https://github.com/minetest-mods/mesecons"+ #:forums 'null+ #:website 'null+ #:repo "https://github.com/minetest-mods/mesecons")+(test-package "contentdb->guix-package, all home page information absent"+ #:home-page #f+ #:forums 'null+ #:website 'null+ #:repo 'null)++ ++;; Dependencies+(test-package "contentdb->guix-package, dependency"+ #:requirements '(("mesecons" #f+ ("Jeija/mesecons"+ "some-modpack/containing-mese")))+ #:inputs '("minetest-mesecons"))++(test-package "contentdb->guix-package, optional dependency"+ #:requirements '(("mesecons" #t+ ("Jeija/mesecons"+ "some-modpack/containing-mese")))+ #:inputs '())++ +;; License+(test-package "contentdb->guix-package, identical licenses"+ #:guix-license 'license:lgpl3+ #:license "LGPLv3"+ #:media-license "LGPLv3")++(test-end "contentdb")-- 2.32.0
M
M
Maxime Devos wrote on 2 Aug 17:50 +0200
[PATCH 15/20] gnu: Add minetest-throwing-arrows.
(address . 49828@debbugs.gnu.org)(name . Maxime Devos)(address . maximedevos@telenet.be)
20210802155019.6122-15-maximedevos@telenet.be
* gnu/packages/minetest.scm (minetest-throwing-arrows): New variable.--- gnu/packages/minetest.scm | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
Toggle diff (43 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex 25038a5f6b..6b792bf071 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -225,6 +225,36 @@ throwing things like arrows. However, this mod does not provide an actual arrow and bow, but @code{minetest-throwing-arrows} does.") (license license:mpl2.0))) +(define-public minetest-throwing-arrows+ ;; There is only one tagged commit (version 1.1),+ ;; there are no releases on ContentDB and the latest+ ;; commit has a compatibility fix for Minetest 5.4.0-dev.+ (let ((commit "059cc897af0aebfbd2c54ac5588f2b842f44f159")+ (revision "0"))+ (package+ (name "minetest-throwing-arrows")+ (version (git-version "1.1" revision commit))+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/minetest-mods/throwing_arrows")+ (commit commit)))+ (sha256+ (base32 "0m2pmccpfxn878zd00pmrpga2h6gknz4f3qprck0fq94mksmwqs3"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (propagated-inputs+ `(("minetest-throwing" ,minetest-throwing)))+ (home-page (minetest-topic 16365))+ (synopsis "Arrows and bows for Minetest")+ (description+ ;; TRANSLATORS: "throwing" is the name of a Minetest mod and should+ ;; not be translated.+ "This mod adds arrows and bows to Minetest. It is a compatible+replacement for the throwing mod by PilzAdam that uses the throwing API.")+ (license license:mpl2.0))))+ (define-public minetest-unifieddyes (package (name "minetest-unifieddyes")-- 2.32.0
L
L
Leo Prikler wrote on 2 Aug 19:14 +0200
Re: [PATCH 01/20] gnu: minetest: Respect --without-tests.
48cb75464f69573a09652853fff2581618b4f83a.camel@student.tugraz.at
Hi Maxime,
Am Montag, den 02.08.2021, 17:50 +0200 schrieb Maxime Devos:
Toggle quote (3 lines)> * gnu/packages/games.scm> (minetest)[arguments]<#:phases>{check}: Use 'tests?' instead> of ',(%current-target-system)'. Remove trailing #t.
For context, (%current-target-system) is used because tests only workin native builds. If this can't be reflected in the value of tests?,we should have both checks, imo.
Toggle quote (26 lines)> ---> gnu/packages/games.scm | 7 +++----> 1 file changed, 3 insertions(+), 4 deletions(-)> > diff --git a/gnu/packages/games.scm b/gnu/packages/games.scm> index 8c6b5523f1..3e7086b398 100644> --- a/gnu/packages/games.scm> +++ b/gnu/packages/games.scm> @@ -3590,13 +3590,12 @@ match, cannon keep, and grave-itation pit.")> (string-append (getcwd) "/games")) ; for check> #t))> (replace 'check> - (lambda _> + (lambda* (#:key tests? #:allow-other-keys)> ;; Thanks to our substitutions, the tests should also> run> ;; when invoked on the target outside of `guix build'.> - (unless ,(%current-target-system)> + (when tests?> (setenv "HOME" "/tmp")> - (invoke "src/minetest" "--run-unittests"))> - #t)))))> + (invoke "src/minetest" "--run-unittests")))))))> (native-search-paths> (list (search-path-specification> (variable "MINETEST_SUBGAME_PATH")
M
M
Maxime Devos wrote on 2 Aug 19:18 +0200
dd916a85f1e2e899f28d1b319d4ba1621f6af5a6.camel@telenet.be
Leo Prikler schreef op ma 02-08-2021 om 19:14 [+0200]:
Toggle quote (10 lines)> Hi Maxime,> > Am Montag, den 02.08.2021, 17:50 +0200 schrieb Maxime Devos:> > * gnu/packages/games.scm> > (minetest)[arguments]<#:phases>{check}: Use 'tests?' instead> > of ',(%current-target-system)'. Remove trailing #t.> For context, (%current-target-system) is used because tests only work> in native builds. If this can't be reflected in the value of tests?,> we should have both checks, imo.
'cmake-cross-build' sets '#:tests?' to #f by default, so I don't thinkboth checks are needed.
Greetings,Maxime.
-----BEGIN PGP SIGNATURE-----
iI0EABYKADUWIQTB8z7iDFKP233XAR9J4+4iGRcl7gUCYQgo+BccbWF4aW1lZGV2b3NAdGVsZW5ldC5iZQAKCRBJ4+4iGRcl7vyBAQDuG54PobZUCCFWmxu2H6nMJvUAz5QKHpGTgVmZtGiCrgEAyYr1FZpOYrAQZF4DYcnrypfCvRDsF4dKMmVwToI4OQs==9o2U-----END PGP SIGNATURE-----

L
L
Leo Prikler wrote on 2 Aug 19:22 +0200
3e901dfca163765a9a4ed93eedde53893a0ce364.camel@student.tugraz.at
Am Montag, den 02.08.2021, 19:18 +0200 schrieb Maxime Devos:
Toggle quote (13 lines)> Leo Prikler schreef op ma 02-08-2021 om 19:14 [+0200]:> > Hi Maxime,> > > > Am Montag, den 02.08.2021, 17:50 +0200 schrieb Maxime Devos:> > > * gnu/packages/games.scm> > > (minetest)[arguments]<#:phases>{check}: Use 'tests?' instead> > > of ',(%current-target-system)'. Remove trailing #t.> > For context, (%current-target-system) is used because tests only> > work in native builds. If this can't be reflected in the value of> > tests?, we should have both checks, imo.> > 'cmake-cross-build' sets '#:tests?' to #f by default, so I don't> think both checks are needed.
In that case nvm and thanks for clearing that up :)
L
L
Leo Prikler wrote on 2 Aug 19:28 +0200
Re: [PATCH 02/20] gnu: minetest: Search for mods in MINETEST_MOD_PATH.
87207455fefb91bb3e12fdb3209f28f11dab92e0.camel@student.tugraz.at
Hi Maxime,
Am Montag, den 02.08.2021, 17:50 +0200 schrieb Maxime Devos:
Toggle quote (85 lines)> * gnu/packages/patches/Add-environment-variable-> MINETEST_MOD_PATH.patch:> New file.> * gnu/packages/games.scm> (minetest)[source]{patches}: Add it.> (minetest)[native-search-paths]: Add "MINETEST_MOD_PATH".> * gnu/local.mk (dist_patch_DATA): Add the patch.> ---> gnu/local.mk | 1 +> gnu/packages/games.scm | 7 +-> ...vironment-variable-MINETEST_MOD_PATH.patch | 115> ++++++++++++++++++> 3 files changed, 122 insertions(+), 1 deletion(-)> create mode 100644 gnu/packages/patches/Add-environment-variable-> MINETEST_MOD_PATH.patch> > diff --git a/gnu/local.mk b/gnu/local.mk> index c80a9af78c..d96d4e3dbc 100644> --- a/gnu/local.mk> +++ b/gnu/local.mk> @@ -801,6 +801,7 @@ dist_patch_DATA = > \> %D%/packages/patches/abseil-cpp-fix-gtest.patch \> %D%/packages/patches/abseil-cpp-fix-strerror_test.patch \> %D%/packages/patches/adb-add-libraries.patch > \> + %D%/packages/patches/Add-environment-variable-> MINETEST_MOD_PATH.patch \> %D%/packages/patches/aegis-constness-error.patch \> %D%/packages/patches/aegis-perl-tempdir1.patch \> %D%/packages/patches/aegis-perl-tempdir2.patch \> diff --git a/gnu/packages/games.scm b/gnu/packages/games.scm> index 3e7086b398..2f3285c6ea 100644> --- a/gnu/packages/games.scm> +++ b/gnu/packages/games.scm> @@ -3553,6 +3553,7 @@ match, cannon keep, and grave-itation pit.")> (base32> "062ilb7s377q3hwfhl8q06vvcw2raydz5ljzlzwy2dmyzmdcndb> 8"))> (modules '((guix build utils)))> + (patches (search-patches "Add-environment-variable-> MINETEST_MOD_PATH.patch"))> (snippet> '(begin> ;; Delete bundled libraries.> @@ -3599,7 +3600,11 @@ match, cannon keep, and grave-itation pit.")> (native-search-paths> (list (search-path-specification> (variable "MINETEST_SUBGAME_PATH")> - (files '("share/minetest/games")))))> + (files '("share/minetest/games")))> + (search-path-specification> + (variable "MINETEST_MOD_PATH")> + (files '("share/minetest/mods"))> + (separator #f))))> (native-inputs> `(("pkg-config" ,pkg-config)))> (inputs> diff --git a/gnu/packages/patches/Add-environment-variable-> MINETEST_MOD_PATH.patch b/gnu/packages/patches/Add-environment-> variable-MINETEST_MOD_PATH.patch> new file mode 100644> index 0000000000..8478a7bf72> --- /dev/null> +++ b/gnu/packages/patches/Add-environment-variable-> MINETEST_MOD_PATH.patch> @@ -0,0 +1,115 @@> +From 6eb753c5bf67764890856cf23a67c0bf65973c16 Mon Sep 17 00:00:00> 2001> +From: Maxime Devos <maximedevos@telenet.be>> +Date: Thu, 29 Jul 2021 22:24:50 +0200> +Subject: [PATCH] Add environment variable MINETEST_MOD_PATH> +> +This adds an environment variable MINETEST_MOD_PATH.> +When it exists, Minetest will look there for mods> +in addition to ~/.minetest/mods/.> +> +This patch as-is is not yet ready for upstream, because:> +> + * the GUI will only display mods in MINETEST_MOD_PATH> + or mods in ~/.minetest/mods, it won't combine the two> +> + * the GUI for installing mods from ContentDB is disabled> + when MINETEST_MOD_PATH is set, because otherwise Minetest> + would try to install mods in the store.
These two are fine for a "Guix-only" patch, although I do think weshould still read ~/.minetest/mods for backwards compatibility.
Toggle quote (1 lines)> + * MINETEST_MOD_PATH can only have a single component
This one seems kinda arbitrary, though, and does not fit well withMINETEST_SUBGAME_PATH.
Toggle quote (38 lines)> +---> + builtin/mainmenu/dlg_contentstore.lua | 7 +++++++> + src/content/subgames.cpp | 3 +++> + src/script/lua_api/l_mainmenu.cpp | 14 +++++++++++++-> + src/script/lua_api/l_mainmenu.h | 2 ++> + 4 files changed, 25 insertions(+), 1 deletion(-)> +> +diff --git a/builtin/mainmenu/dlg_contentstore.lua> b/builtin/mainmenu/dlg_contentstore.lua> +index 7096c9187..c4a2cbd18 100644> +--- a/builtin/mainmenu/dlg_contentstore.lua> ++++ b/builtin/mainmenu/dlg_contentstore.lua> +@@ -22,6 +22,13 @@ if not core.get_http_api then> + end> + return> + end> ++if core.mod_path_set() then> ++ function create_store_dlg()> ++ return messagebox("store",> ++ fgettext("Mods from ContentDB cannot be> installed when mods from Guix are also installed"))> ++ end> ++ return> ++end> + > + -- Unordered preserves the original order of the ContentDB API,> + -- before the package list is ordered based on installed state.> +diff --git a/src/content/subgames.cpp b/src/content/subgames.cpp> +index e9dc609b0..1809f189e 100644> +--- a/src/content/subgames.cpp> ++++ b/src/content/subgames.cpp> +@@ -110,6 +110,9 @@ SubgameSpec findSubgame(const std::string &id)> + std::set<std::string> mods_paths;> + if (!user_game)> + mods_paths.insert(share + DIR_DELIM + "mods");> ++ const char *env_mod_path = getenv("MINETEST_MOD_PATH");> ++ if (env_mod_path)> ++ mods_paths.insert(std::string(env_mod_path));
Here, I would instead use an std::istringstream together withstd::getline(<>, <>, ':') to get the components of MINETEST_MOD_PATHand insert each of them. Either that or copy whatever is used forMINETEST_SUBGAME_PATH.
Toggle quote (67 lines)> + if (user != share || user_game)> + mods_paths.insert(user + DIR_DELIM + "mods");> + > +diff --git a/src/script/lua_api/l_mainmenu.cpp> b/src/script/lua_api/l_mainmenu.cpp> +index ad00de1c4..737550c42 100644> +--- a/src/script/lua_api/l_mainmenu.cpp> ++++ b/src/script/lua_api/l_mainmenu.cpp> +@@ -495,9 +495,19 @@ int ModApiMainMenu::l_get_user_path(lua_State> *L)> +> /********************************************************************> **********/> + int ModApiMainMenu::l_get_modpath(lua_State *L)> + {> ++ const char *c_modpath = getenv("MINETEST_MOD_PATH");> + std::string modpath = fs::RemoveRelativePathComponents(> + porting::path_user + DIR_DELIM + "mods" + DIR_DELIM);> +- lua_pushstring(L, modpath.c_str());> ++ if (c_modpath == NULL)> ++ c_modpath = modpath.c_str();> ++ lua_pushstring(L, c_modpath);> ++ return 1;> ++}> ++> ++/******************************************************************> ************/> ++int ModApiMainMenu::l_mod_path_set(lua_State *L)> ++{> ++ lua_pushboolean(L, NULL != getenv("MINETEST_MOD_PATH"));> + return 1;> + }> + > +@@ -855,6 +865,7 @@ void ModApiMainMenu::Initialize(lua_State *L,> int top)> + API_FCT(get_mapgen_names);> + API_FCT(get_user_path);> + API_FCT(get_modpath);> ++ API_FCT(mod_path_set);> + API_FCT(get_clientmodpath);> + API_FCT(get_gamepath);> + API_FCT(get_texturepath);> +@@ -888,6 +899,7 @@ void ModApiMainMenu::InitializeAsync(lua_State> *L, int top)> + API_FCT(get_mapgen_names);> + API_FCT(get_user_path);> + API_FCT(get_modpath);> ++ API_FCT(mod_path_set);> + API_FCT(get_clientmodpath);> + API_FCT(get_gamepath);> + API_FCT(get_texturepath);> +diff --git a/src/script/lua_api/l_mainmenu.h> b/src/script/lua_api/l_mainmenu.h> +index ec2d20da2..719c26077 100644> +--- a/src/script/lua_api/l_mainmenu.h> ++++ b/src/script/lua_api/l_mainmenu.h> +@@ -112,6 +112,8 @@ class ModApiMainMenu: public ModApiBase> + > + static int l_get_modpath(lua_State *L);> + > ++ static int l_mod_path_set(lua_State *L);> ++> + static int l_get_clientmodpath(lua_State *L);> + > + static int l_get_gamepath(lua_State *L);> +-- > +2.32.0
What are these modpaths used for? For mod installation or for queryingmod existence? If it's the former, you could leave them as-is, similarto how elpa stays enabled in Emacs.
Regards,
M
M
Maxime Devos wrote on 2 Aug 19:53 +0200
97f899a616812a0086a68ee97c36d1531e04c2e3.camel@telenet.be
Toggle quote (11 lines)> > +This patch as-is is not yet ready for upstream, because:> > +> > + * the GUI will only display mods in MINETEST_MOD_PATH> > + or mods in ~/.minetest/mods, it won't combine the two> > +> > + * the GUI for installing mods from ContentDB is disabled> > + when MINETEST_MOD_PATH is set, because otherwise Minetest> > + would try to install mods in the store.> These two are fine for a "Guix-only" patch, although I do think we> should still read ~/.minetest/mods for backwards compatibility.
~/.minetest/mods is still read when MINETEST_MOD_PATH is unset.MINETEST_MOD_PATH is only set when some mod is actually installed.So backwards compatibility should be ok.
Toggle quote (4 lines)> > + * MINETEST_MOD_PATH can only have a single component> This one seems kinda arbitrary, though, and does not fit well with> MINETEST_SUBGAME_PATH.
Yes, I know. I didn't know how to adjust pkgmgr.lua and dlg_contentstore.luato support multiple components, though I have an idea now to try.
Toggle quote (19 lines)> > + -- Unordered preserves the original order of the ContentDB API,> > + -- before the package list is ordered based on installed state.> > +diff --git a/src/content/subgames.cpp b/src/content/subgames.cpp> > +index e9dc609b0..1809f189e 100644> > +--- a/src/content/subgames.cpp> > ++++ b/src/content/subgames.cpp> > +@@ -110,6 +110,9 @@ SubgameSpec findSubgame(const std::string &id)> > + std::set<std::string> mods_paths;> > + if (!user_game)> > + mods_paths.insert(share + DIR_DELIM + "mods");> > ++ const char *env_mod_path = getenv("MINETEST_MOD_PATH");> > ++ if (env_mod_path)> > ++ mods_paths.insert(std::string(env_mod_path));
> Here, I would instead use an std::istringstream together with> std::getline(<>, <>, ':') to get the components of MINETEST_MOD_PATH> and insert each of them. Either that or copy whatever is used for> MINETEST_SUBGAME_PATH.
Minetest has a class 'Strfnd' supporting iteration. Using that,it should be easy to allow MINETEST_MOD_PATH to contain ":" seperators.However, the GUI client code (pkgmgr.lua)uses some other logic for determining which mods exists, and currently,that logic does not support ":" separators.
Toggle quote (69 lines)> > +diff --git a/src/script/lua_api/l_mainmenu.cpp> > b/src/script/lua_api/l_mainmenu.cpp> > +index ad00de1c4..737550c42 100644> > +--- a/src/script/lua_api/l_mainmenu.cpp> > ++++ b/src/script/lua_api/l_mainmenu.cpp> > +@@ -495,9 +495,19 @@ int ModApiMainMenu::l_get_user_path(lua_State> > *L)> > +> > /********************************************************************> > **********/> > + int ModApiMainMenu::l_get_modpath(lua_State *L)> > + {> > ++ const char *c_modpath = getenv("MINETEST_MOD_PATH");> > + std::string modpath = fs::RemoveRelativePathComponents(> > + porting::path_user + DIR_DELIM + "mods" + DIR_DELIM);> > +- lua_pushstring(L, modpath.c_str());> > ++ if (c_modpath == NULL)> > ++ c_modpath = modpath.c_str();> > ++ lua_pushstring(L, c_modpath);> > ++ return 1;> > ++}> > ++> > ++/******************************************************************> > ************/> > ++int ModApiMainMenu::l_mod_path_set(lua_State *L)> > ++{> > ++ lua_pushboolean(L, NULL != getenv("MINETEST_MOD_PATH"));> > + return 1;> > + }> > + > > +@@ -855,6 +865,7 @@ void ModApiMainMenu::Initialize(lua_State *L,> > int top)> > + API_FCT(get_mapgen_names);> > + API_FCT(get_user_path);> > + API_FCT(get_modpath);> > ++ API_FCT(mod_path_set);> > + API_FCT(get_clientmodpath);> > + API_FCT(get_gamepath);> > + API_FCT(get_texturepath);> > +@@ -888,6 +899,7 @@ void ModApiMainMenu::InitializeAsync(lua_State> > *L, int top)> > + API_FCT(get_mapgen_names);> > + API_FCT(get_user_path);> > + API_FCT(get_modpath);> > ++ API_FCT(mod_path_set);> > + API_FCT(get_clientmodpath);> > + API_FCT(get_gamepath);> > + API_FCT(get_texturepath);> > +diff --git a/src/script/lua_api/l_mainmenu.h> > b/src/script/lua_api/l_mainmenu.h> > +index ec2d20da2..719c26077 100644> > +--- a/src/script/lua_api/l_mainmenu.h> > ++++ b/src/script/lua_api/l_mainmenu.h> > +@@ -112,6 +112,8 @@ class ModApiMainMenu: public ModApiBase> > + > > + static int l_get_modpath(lua_State *L);> > + > > ++ static int l_mod_path_set(lua_State *L);> > ++> > + static int l_get_clientmodpath(lua_State *L);> > + > > + static int l_get_gamepath(lua_State *L);> > +-- > > +2.32.0
> What are these modpaths used for? For mod installation or for querying> mod existence? If it's the former, you could leave them as-is, similar> to how elpa stays enabled in Emacs.
It is only used by the GUI. The GUI looks in the directory returned by"get_modpath" for two things:
(1) to determine which mods exist (and to find their descriptions, their dependency list, screenshots ...). Only the mods that exist there can be enabled.
(2) to determine where mods must be installed when using Minetest's built-in installer.
Greetings,Maxime.
-----BEGIN PGP SIGNATURE-----
iI0EABYKADUWIQTB8z7iDFKP233XAR9J4+4iGRcl7gUCYQgxCxccbWF4aW1lZGV2b3NAdGVsZW5ldC5iZQAKCRBJ4+4iGRcl7lSKAQCBoMLuhHqfcmtrdC/q6tt0xpooZi9WrbtkA1Wh6ZCJCgEAkApax6ucUtN7lMKzpzbhrSXX6rOpnAIRwCbtTtBf9Aw==OLAf-----END PGP SIGNATURE-----

L
L
Leo Prikler wrote on 2 Aug 20:47 +0200
19c7cec42e57899c62ba6b4ff7f297a3e5bc2be4.camel@student.tugraz.at
Am Montag, den 02.08.2021, 19:53 +0200 schrieb Maxime Devos:
Toggle quote (14 lines)> > > +This patch as-is is not yet ready for upstream, because:> > > +> > > + * the GUI will only display mods in MINETEST_MOD_PATH> > > + or mods in ~/.minetest/mods, it won't combine the two> > > +> > > + * the GUI for installing mods from ContentDB is disabled> > > + when MINETEST_MOD_PATH is set, because otherwise Minetest> > > + would try to install mods in the store.> > These two are fine for a "Guix-only" patch, although I do think we> > should still read ~/.minetest/mods for backwards compatibility.> > ~/.minetest/mods is still read when MINETEST_MOD_PATH is unset.> MINETEST_MOD_PATH is only set when some mod is actually installed.> So backwards compatibility should be ok.
I mean in the sense of "have some mods in ~/.minetest/mods, that aren'tyet packaged in Guix and have the rest sit in the profile where theybelong". Not everyone will like the the import to manifest approachthat is needed while you're waiting for review.
Toggle quote (35 lines)> > > + * MINETEST_MOD_PATH can only have a single component> > This one seems kinda arbitrary, though, and does not fit well with> > MINETEST_SUBGAME_PATH.> > Yes, I know. I didn't know how to adjust pkgmgr.lua and> dlg_contentstore.lua> to support multiple components, though I have an idea now to try.> > > > + -- Unordered preserves the original order of the ContentDB API,> > > + -- before the package list is ordered based on installed state.> > > +diff --git a/src/content/subgames.cpp b/src/content/subgames.cpp> > > +index e9dc609b0..1809f189e 100644> > > +--- a/src/content/subgames.cpp> > > ++++ b/src/content/subgames.cpp> > > +@@ -110,6 +110,9 @@ SubgameSpec findSubgame(const std::string> > > &id)> > > + std::set<std::string> mods_paths;> > > + if (!user_game)> > > + mods_paths.insert(share + DIR_DELIM + "mods");> > > ++ const char *env_mod_path = getenv("MINETEST_MOD_PATH");> > > ++ if (env_mod_path)> > > ++ mods_paths.insert(std::string(env_mod_path));> > Here, I would instead use an std::istringstream together with> > std::getline(<>, <>, ':') to get the components of> > MINETEST_MOD_PATH> > and insert each of them. Either that or copy whatever is used for> > MINETEST_SUBGAME_PATH.> > Minetest has a class 'Strfnd' supporting iteration. Using that,> it should be easy to allow MINETEST_MOD_PATH to contain ":"> seperators.> However, the GUI client code (pkgmgr.lua)> uses some other logic for determining which mods exists, and> currently,> that logic does not support ":" separators.
Hmm, how important is the GUI side here? Can we sneek mods into it?
Toggle quote (84 lines)> > > +diff --git a/src/script/lua_api/l_mainmenu.cpp> > > b/src/script/lua_api/l_mainmenu.cpp> > > +index ad00de1c4..737550c42 100644> > > +--- a/src/script/lua_api/l_mainmenu.cpp> > > ++++ b/src/script/lua_api/l_mainmenu.cpp> > > +@@ -495,9 +495,19 @@ int> > > ModApiMainMenu::l_get_user_path(lua_State> > > *L)> > > +> > > /****************************************************************> > > ****> > > **********/> > > + int ModApiMainMenu::l_get_modpath(lua_State *L)> > > + {> > > ++ const char *c_modpath = getenv("MINETEST_MOD_PATH");> > > + std::string modpath = fs::RemoveRelativePathComponents(> > > + porting::path_user + DIR_DELIM + "mods" +> > > DIR_DELIM);> > > +- lua_pushstring(L, modpath.c_str());> > > ++ if (c_modpath == NULL)> > > ++ c_modpath = modpath.c_str();> > > ++ lua_pushstring(L, c_modpath);> > > ++ return 1;> > > ++}> > > ++> > > ++/**************************************************************> > > ****> > > ************/> > > ++int ModApiMainMenu::l_mod_path_set(lua_State *L)> > > ++{> > > ++ lua_pushboolean(L, NULL !=> > > getenv("MINETEST_MOD_PATH"));> > > + return 1;> > > + }> > > + > > > +@@ -855,6 +865,7 @@ void ModApiMainMenu::Initialize(lua_State> > > *L,> > > int top)> > > + API_FCT(get_mapgen_names);> > > + API_FCT(get_user_path);> > > + API_FCT(get_modpath);> > > ++ API_FCT(mod_path_set);> > > + API_FCT(get_clientmodpath);> > > + API_FCT(get_gamepath);> > > + API_FCT(get_texturepath);> > > +@@ -888,6 +899,7 @@ void> > > ModApiMainMenu::InitializeAsync(lua_State> > > *L, int top)> > > + API_FCT(get_mapgen_names);> > > + API_FCT(get_user_path);> > > + API_FCT(get_modpath);> > > ++ API_FCT(mod_path_set);> > > + API_FCT(get_clientmodpath);> > > + API_FCT(get_gamepath);> > > + API_FCT(get_texturepath);> > > +diff --git a/src/script/lua_api/l_mainmenu.h> > > b/src/script/lua_api/l_mainmenu.h> > > +index ec2d20da2..719c26077 100644> > > +--- a/src/script/lua_api/l_mainmenu.h> > > ++++ b/src/script/lua_api/l_mainmenu.h> > > +@@ -112,6 +112,8 @@ class ModApiMainMenu: public ModApiBase> > > + > > > + static int l_get_modpath(lua_State *L);> > > + > > > ++ static int l_mod_path_set(lua_State *L);> > > ++> > > + static int l_get_clientmodpath(lua_State *L);> > > + > > > + static int l_get_gamepath(lua_State *L);> > > +-- > > > +2.32.0> > What are these modpaths used for? For mod installation or for> > querying mod existence? If it's the former, you could leave them> > as-is, similar to how elpa stays enabled in Emacs.> > It is only used by the GUI. The GUI looks in the directory returned> by "get_modpath" for two things:> > (1) to determine which mods exist (and to find their descriptions, > their dependency list, screenshots ...). Only the mods that > exist there can be enabled.> > (2) to determine where mods must be installed when using Minetest's> built-in installer.
I see. Is this the same GUI for all parts or different GUIs? I thinkif we can handle the world creation parts, everything should be fine,no?
Regards,
L
L
Leo Prikler wrote on 3 Aug 11:17 +0200
Re: [PATCH 05/20] build-system: minetest: Don't retain references to "bash-minimal".
60c5062a7debff22cee27198c2548605fd7441e0.camel@student.tugraz.at
Hi,
I'd merge this and 04/20 into a single patch. 04/20 does of its owngive a good incentive as to why a new build system is to be used (thiscould instead be handled by the importer), with this phase added itmakes slightly more sense.
OTOH, perhaps we shouldn't install those shell scripts in the firstplace? Perhaps we can instead make the importer generate packagesbased directly on copy-build-system, in which those static strings arealready evaluated. WDYT?
Am Montag, den 02.08.2021, 17:50 +0200 schrieb Maxime Devos:
Toggle quote (39 lines)> * guix/build-system/minetest.scm> (%standard-phases): New variable. Delete "patch-source-shebangs"> phase.> (lower-mod): Set #:phases to value of new variable.> ---> guix/build-system/minetest.scm | 9 +++++++++> 1 file changed, 9 insertions(+)> > diff --git a/guix/build-system/minetest.scm b/guix/build-> system/minetest.scm> index 29866ced6d..993c5631eb 100644> --- a/guix/build-system/minetest.scm> +++ b/guix/build-system/minetest.scm> @@ -35,6 +35,14 @@> (substring package-name 9)> package-name))> > +(define %standard-phases> + ;; The source code sometimes contains shell scripts which are used> for> + ;; development but not at run time (e.g. listnodes.sh in> + ;; minetest-homedecor-modpack). Don't make them retain a> reference> + ;; to bash-minimal.> + '(modify-phases (@ (guix build copy-build-system) %standard-> phases)> + (delete 'patch-source-shebangs)))> +> (define (lower-mod name . arguments)> (define lower (build-system-lower copy-build-system))> (apply lower> @@ -42,6 +50,7 @@> #:install-plan> `'(("." ,(string-append "share/minetest/mods/"> (guix-name->mod-name name))))> + #:phases %standard-phases> arguments))> > (define minetest-mod-build-system
M
M
Maxime Devos wrote on 3 Aug 13:09 +0200
Re: [PATCH 02/20] gnu: minetest: Search for mods in MINETEST_MOD_PATH.
9cc691b6c242e31edcc1215d259eab9306715708.camel@telenet.be
Hi,
I've modified this patch such that:
* the GUI will display mods in MINETEST_MOD_PATH as well as mods in ~/.minetest/mods
* the built-in installer works even if MINETEST_MOD_PATH is set
* MINETEST_MOD_PATH can contain multiple components
Please tell if there are other issues
I'll look into the upstream procedure for submitting patches.
Leo Prikler schreef op ma 02-08-2021 om 20:47 [+0200]:
Toggle quote (20 lines)> Am Montag, den 02.08.2021, 19:53 +0200 schrieb Maxime Devos:> > > > +This patch as-is is not yet ready for upstream, because:> > > > +> > > > + * the GUI will only display mods in MINETEST_MOD_PATH> > > > + or mods in ~/.minetest/mods, it won't combine the two> > > > +> > > > + * the GUI for installing mods from ContentDB is disabled> > > > + when MINETEST_MOD_PATH is set, because otherwise Minetest> > > > + would try to install mods in the store.> > > These two are fine for a "Guix-only" patch, although I do think we> > > should still read ~/.minetest/mods for backwards compatibility.> > > > ~/.minetest/mods is still read when MINETEST_MOD_PATH is unset.> > MINETEST_MOD_PATH is only set when some mod is actually installed.> > So backwards compatibility should be ok.> I mean in the sense of "have some mods in ~/.minetest/mods, that aren't> yet packaged in Guix and have the rest sit in the profile where they> belong". Not everyone will like the the import to manifest approach> that is needed while you're waiting for review.
All three points should be addresed by the new patch.
Toggle quote (29 lines)> > > > + -- Unordered preserves the original order of the ContentDB API,> > > > + -- before the package list is ordered based on installed state.> > > > +diff --git a/src/content/subgames.cpp b/src/content/subgames.cpp> > > > +index e9dc609b0..1809f189e 100644> > > > +--- a/src/content/subgames.cpp> > > > ++++ b/src/content/subgames.cpp> > > > +@@ -110,6 +110,9 @@ SubgameSpec findSubgame(const std::string> > > > &id)> > > > + std::set<std::string> mods_paths;> > > > + if (!user_game)> > > > + mods_paths.insert(share + DIR_DELIM + "mods");> > > > ++ const char *env_mod_path = getenv("MINETEST_MOD_PATH");> > > > ++ if (env_mod_path)> > > > ++ mods_paths.insert(std::string(env_mod_path));> > > Here, I would instead use an std::istringstream together with> > > std::getline(<>, <>, ':') to get the components of> > > MINETEST_MOD_PATH> > > and insert each of them. Either that or copy whatever is used for> > > MINETEST_SUBGAME_PATH.> > > > Minetest has a class 'Strfnd' supporting iteration. Using that,> > it should be easy to allow MINETEST_MOD_PATH to contain ":"> > seperators.> > However, the GUI client code (pkgmgr.lua)> > uses some other logic for determining which mods exists, and> > currently,> > that logic does not support ":" separators.> Hmm, how important is the GUI side here? Can we sneek mods into it?
The GUI side is very important. All mods are disabled by default,and in the GUI you need to choose which mods to enable. If the GUIdoesn't know about the existence of the mod, then the mod cannot beenabled.
Toggle quote (13 lines)> > It is only used by the GUI. The GUI looks in the directory returned> > by "get_modpath" for two things:> > > > (1) to determine which mods exist (and to find their descriptions, > > their dependency list, screenshots ...). Only the mods that > > exist there can be enabled.> > > > (2) to determine where mods must be installed when using Minetest's> > built-in installer.> I see. Is this the same GUI for all parts or different GUIs? I think> if we can handle the world creation parts, everything should be fine,> no?
The ‘mod selecter’ (1) and installer (2) have separate graphical interfaces,but they use some common code 'pkgmgr.lua'. In the new patch, 'get_modpath()'(a string) is where mods should be installed by the built-in installer,and 'get_modpaths()' (a list of strings) is where mods can be found.Both interfaces work with the new patch.
Greetings,Maxime.
-----BEGIN PGP SIGNATURE-----
iI0EABYKADUWIQTB8z7iDFKP233XAR9J4+4iGRcl7gUCYQkj2xccbWF4aW1lZGV2b3NAdGVsZW5ldC5iZQAKCRBJ4+4iGRcl7mtAAQDGW+NY+YUBnMEwjmM9wq0EuDdzFzKLVcL/MrbshcqHRAEA93Na0s6Hd86yVCYA+0bfLnMfWmTspPKxulNfFIuv7gE==v97R-----END PGP SIGNATURE-----

M
M
Maxime Devos wrote on 3 Aug 13:10 +0200
52f3bab58e39a8d6cd9db175f2abf883008a69f0.camel@telenet.be
I forgot to attach the patch.
From e999b5ef71d393eddd5767a108a7bd864ff6ec50 Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sat, 31 Jul 2021 18:08:44 +0200Subject: [PATCH 02/20] gnu: minetest: Search for mods in MINETEST_MOD_PATH.
* gnu/packages/patches/Add-environment-variable-MINETEST_MOD_PATH.patch: New file.* gnu/packages/games.scm (minetest)[source]{patches}: Add it. (minetest)[native-search-paths]: Add "MINETEST_MOD_PATH".* gnu/local.mk (dist_patch_DATA): Add the patch.--- gnu/local.mk | 1 + gnu/packages/games.scm | 6 +- ...vironment-variable-MINETEST_MOD_PATH.patch | 162 ++++++++++++++++++ 3 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 gnu/packages/patches/Add-environment-variable-MINETEST_MOD_PATH.patch
Toggle diff (206 lines)diff --git a/gnu/local.mk b/gnu/local.mkindex c80a9af78c..d96d4e3dbc 100644--- a/gnu/local.mk+++ b/gnu/local.mk@@ -801,6 +801,7 @@ dist_patch_DATA = \ %D%/packages/patches/abseil-cpp-fix-gtest.patch \ %D%/packages/patches/abseil-cpp-fix-strerror_test.patch \ %D%/packages/patches/adb-add-libraries.patch \+ %D%/packages/patches/Add-environment-variable-MINETEST_MOD_PATH.patch \ %D%/packages/patches/aegis-constness-error.patch \ %D%/packages/patches/aegis-perl-tempdir1.patch \ %D%/packages/patches/aegis-perl-tempdir2.patch \diff --git a/gnu/packages/games.scm b/gnu/packages/games.scmindex 3e7086b398..6a30c53e32 100644--- a/gnu/packages/games.scm+++ b/gnu/packages/games.scm@@ -3553,6 +3553,7 @@ match, cannon keep, and grave-itation pit.") (base32 "062ilb7s377q3hwfhl8q06vvcw2raydz5ljzlzwy2dmyzmdcndb8")) (modules '((guix build utils)))+ (patches (search-patches "Add-environment-variable-MINETEST_MOD_PATH.patch")) (snippet '(begin ;; Delete bundled libraries.@@ -3599,7 +3600,10 @@ match, cannon keep, and grave-itation pit.") (native-search-paths (list (search-path-specification (variable "MINETEST_SUBGAME_PATH")- (files '("share/minetest/games")))))+ (files '("share/minetest/games")))+ (search-path-specification+ (variable "MINETEST_MOD_PATH")+ (files '("share/minetest/mods"))))) (native-inputs `(("pkg-config" ,pkg-config))) (inputsdiff --git a/gnu/packages/patches/Add-environment-variable-MINETEST_MOD_PATH.patch b/gnu/packages/patches/Add-environment-variable-MINETEST_MOD_PATH.patchnew file mode 100644index 0000000000..8d72c42bf9--- /dev/null+++ b/gnu/packages/patches/Add-environment-variable-MINETEST_MOD_PATH.patch@@ -0,0 +1,162 @@+From dccaae3aebedb5178201ba818b8264fdb9e5e832 Mon Sep 17 00:00:00 2001+From: Maxime Devos <maximedevos@telenet.be>+Date: Tue, 3 Aug 2021 01:00:23 +0200+Subject: [PATCH] Add environment variable MINETEST_MOD_PATH++This adds an environment variable MINETEST_MOD_PATH.+When it exists, Minetest will look there for mods+in addition to ~/.minetest/mods/. Mods can still be+installed to ~/.minetest/mods/ with the built-in installer.+---+ builtin/mainmenu/pkgmgr.lua | 7 +++----+ doc/menu_lua_api.txt | 8 +++++++-+ src/content/subgames.cpp | 11 ++++++++++++ src/script/lua_api/l_mainmenu.cpp | 31 ++++++++++++++++++++++++++++++++ src/script/lua_api/l_mainmenu.h | 2 +++ 5 files changed, 54 insertions(+), 5 deletions(-)++diff --git a/builtin/mainmenu/pkgmgr.lua b/builtin/mainmenu/pkgmgr.lua+index 787936e31..d8fba0ebe 100644+--- a/builtin/mainmenu/pkgmgr.lua++++ b/builtin/mainmenu/pkgmgr.lua+@@ -682,10 +682,9 @@ function pkgmgr.preparemodlist(data)+ local game_mods = {}+ + --read global mods+- local modpath = core.get_modpath()+-+- if modpath ~= nil and+- modpath ~= "" then++ local modpaths = core.get_modpaths()++ --XXX what was ‘modpath ~= ""’ and ‘modpath ~= nil’ for?++ for _,modpath in ipairs(modpaths) do+ get_mods(modpath,global_mods)+ end+ +diff --git a/doc/menu_lua_api.txt b/doc/menu_lua_api.txt+index b3975bc1d..132444b14 100644+--- a/doc/menu_lua_api.txt++++ b/doc/menu_lua_api.txt+@@ -218,7 +218,13 @@ Package - content which is downloadable from the content db, may or may not be i+ * returns path to global user data,+ the directory that contains user-provided mods, worlds, games, and texture packs.+ * core.get_modpath() (possible in async calls)+- * returns path to global modpath++ * returns path to global modpath, where mods can be installed++* core.get_modpaths() (possible in async calls)++ * returns list of paths to global modpaths, where mods have been installed++++ The difference with "core.get_modpath" is that no mods should be installed in these++ directories by Minetest -- they might be read-only.+++ * core.get_clientmodpath() (possible in async calls)+ * returns path to global client-side modpath+ * core.get_gamepath() (possible in async calls)+diff --git a/src/content/subgames.cpp b/src/content/subgames.cpp+index e9dc609b0..d73f95a1f 100644+--- a/src/content/subgames.cpp++++ b/src/content/subgames.cpp+@@ -61,6 +61,12 @@ std::string getSubgamePathEnv()+ return subgame_path ? std::string(subgame_path) : "";+ }+ ++std::string getModPathEnv()++{++ char *mod_path = getenv("MINETEST_MOD_PATH");++ return mod_path ? std::string(mod_path) : "";++}+++ SubgameSpec findSubgame(const std::string &id)+ {+ if (id.empty())+@@ -110,6 +116,11 @@ SubgameSpec findSubgame(const std::string &id)+ std::set<std::string> mods_paths;+ if (!user_game)+ mods_paths.insert(share + DIR_DELIM + "mods");++++ Strfnd mod_search_paths(getModPathEnv());++ while (!mod_search_paths.at_end())++ mods_paths.insert(mod_search_paths.next(PATH_DELIM));+++ if (user != share || user_game)+ mods_paths.insert(user + DIR_DELIM + "mods");+ +diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp+index 3e9709bde..c1647195f 100644+--- a/src/script/lua_api/l_mainmenu.cpp++++ b/src/script/lua_api/l_mainmenu.cpp+@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,+ #include "lua_api/l_internal.h"+ #include "common/c_content.h"+ #include "cpp_api/s_async.h"++#include "util/strfnd.h"+ #include "gui/guiEngine.h"+ #include "gui/guiMainMenu.h"+ #include "gui/guiKeyChangeMenu.h"+@@ -502,6 +503,34 @@ int ModApiMainMenu::l_get_modpath(lua_State *L)+ return 1;+ }+ ++/******************************************************************************/++int ModApiMainMenu::l_get_modpaths(lua_State *L)++{++ const char *c_modpath = getenv("MINETEST_MOD_PATH");++ if (c_modpath == NULL)++ c_modpath = "";++ int index = 1;++ lua_newtable(L);++ // XXX: for some reason, simply writing++ // Strfnd mod_search_paths (std::string(c_modpath));++ // leads to a compilation error:++ //++ // request for member ‘at_end’ in ‘mod_search_paths’, which is of++ // non-class type ‘Strfnd(std::__cxx11::string)++ // {aka BasicStrfnd<char>(std::__cxx11::basic_string<char>)}’++ std::string modpath = std::string(c_modpath);++ Strfnd mod_search_paths(modpath);++ while (!mod_search_paths.at_end()) {++ std::string component = mod_search_paths.next(PATH_DELIM);++ lua_pushstring(L, component.c_str());++ lua_rawseti(L, -2, index);++ index++;++ }++ ModApiMainMenu::l_get_modpath(L);++ lua_rawseti(L, -2, index);++ return 1;++}+++ /******************************************************************************/+ int ModApiMainMenu::l_get_clientmodpath(lua_State *L)+ {+@@ -949,6 +978,7 @@ void ModApiMainMenu::Initialize(lua_State *L, int top)+ API_FCT(get_mapgen_names);+ API_FCT(get_user_path);+ API_FCT(get_modpath);++ API_FCT(get_modpaths);+ API_FCT(get_clientmodpath);+ API_FCT(get_gamepath);+ API_FCT(get_texturepath);+@@ -983,6 +1013,7 @@ void ModApiMainMenu::InitializeAsync(lua_State *L, int top)+ API_FCT(get_mapgen_names);+ API_FCT(get_user_path);+ API_FCT(get_modpath);++ API_FCT(get_modpaths);+ API_FCT(get_clientmodpath);+ API_FCT(get_gamepath);+ API_FCT(get_texturepath);+diff --git a/src/script/lua_api/l_mainmenu.h b/src/script/lua_api/l_mainmenu.h+index 33ac9e721..a6a54a2cb 100644+--- a/src/script/lua_api/l_mainmenu.h++++ b/src/script/lua_api/l_mainmenu.h+@@ -112,6 +112,8 @@ class ModApiMainMenu: public ModApiBase+ + static int l_get_modpath(lua_State *L);+ ++ static int l_get_modpaths(lua_State *L);+++ static int l_get_clientmodpath(lua_State *L);+ + static int l_get_gamepath(lua_State *L);+-- +2.32.0+-- 2.32.0
-----BEGIN PGP SIGNATURE-----
iI0EABYKADUWIQTB8z7iDFKP233XAR9J4+4iGRcl7gUCYQkkIRccbWF4aW1lZGV2b3NAdGVsZW5ldC5iZQAKCRBJ4+4iGRcl7mlyAPsFn6nqWCEelOR1kN8D9OBNzKkVHnD6xNoYjUyHz511QQD9HUUvVSakqVCzG5pMtlfzNALIetgFFpOzmmxVcYjWrQk==uyPA-----END PGP SIGNATURE-----

L
L
Leo Prikler wrote on 3 Aug 13:54 +0200
b3837ab98faba2a7cbb8174e3a2b3daa04be9627.camel@student.tugraz.at
Hi,
Am Dienstag, den 03.08.2021, 13:10 +0200 schrieb Maxime Devos:
Toggle quote (2 lines)> (patches (search-patches "Add-environment-variable-> MINETEST_MOD_PATH.patch"))
This line is a bit long. Even if might look a little weird, I thinkit's better split in three.
Toggle quote (10 lines)> ++ // XXX: for some reason, simply writing> ++ // Strfnd mod_search_paths (std::string(c_modpath));> ++ // leads to a compilation error:> ++ //> ++ // request for member ‘at_end’ in ‘mod_search_paths’, which is> of> ++ // non-class type ‘Strfnd(std::__cxx11::string)> ++ // {aka BasicStrfnd<char>(std::__cxx11::basic_string<char>)}’> ++ std::string modpath = std::string(c_modpath);> ++ Strfnd mod_search_paths(modpath);
Try Strfnd mod_search_paths{modpath}. The normal bracket styleconfuses C++, because it can also be parsed as a function declaration.
Toggle quote (10 lines)> + * core.get_modpath() (possible in async calls)> +- * returns path to global modpath> ++ * returns path to global modpath, where mods can be installed> ++* core.get_modpaths() (possible in async calls)> ++ * returns list of paths to global modpaths, where mods have> been installed> ++> ++ The difference with "core.get_modpath" is that no mods should> be installed in these> ++ directories by Minetest -- they might be read-only.
This is a somewhat weird interface imo. I think core.get_modpathshould be the first element of core.get_modpaths and documented in thatway, so that any GUI that deals with "all known mods" needs to simplycall the latter, whereas any GUI that deals with installing cancomfortably use either the former or whatever Lua has for car. WDYT?
Otherwise LGTM.
M
M
Maxime Devos wrote on 3 Aug 13:59 +0200
Re: [PATCH 05/20] build-system: minetest: Don't retain references to "bash-minimal".
265c85f914757066aee6b6933ba58bf1abd2bc84.camel@telenet.be
Leo Prikler schreef op di 03-08-2021 om 11:17 [+0200]:
Toggle quote (7 lines)> Hi,> > I'd merge this and 04/20 into a single patch. 04/20 does of its own> give a good incentive as to why a new build system is to be used (this> could instead be handled by the importer), with this phase added it> makes slightly more sense.
As an argument for having a 'minetest-mod-build-system', considersome ways 'minetest-mod-build-system' could be improved in the future:
* a phase could be added to minimise PNG images (e.g. using 'optipng') * likewise, for lua code * some basic tests could be added (e.g. creating a new world and loading the mod, testing that Minetest doesn't raise an error during mod loading)
Also, having "#:install-plan '(("." "share/minetest/mods/the-mod-name"))"appear in every package definition seems rather repetitive to me.
The idea behind "04/20" and "05/20" being separate patches, is to startwith a basic "minetest-mod-build-system" and gradually improve it.The small improvements (currently only one, i.e., 05/20) could be reviewedseparately from each other and whether there should be a"minetest-mod-build-system" at all.
E.g., see attached a patch that sets #:allowed-references '(), ensuringnothing sneaks into the closure. Another change I'm thinking of, is includingonly "tar", "gzip" and the like as implicit inputs, and not "bash" or "coreutils",though that's probably useless if shebang patching has been disabled.
Toggle quote (5 lines)> OTOH, perhaps we shouldn't install those shell scripts in the first> place? Perhaps we can instead make the importer generate packages> based directly on copy-build-system, in which those static strings are> already evaluated. WDYT?
Directly using 'copy-build-system' makes it more difficult to make theimprovements listed above. I don't know what you mean with ‘in which thosestatic strings are already evaluated’ -- what are ‘those static strings’ here?
I suppose it is possible to exclude shell scripts from installation, butjust installing everything (and disabling shebang patching) seems simpler.
Greetings,Maxime.
From eef6cb11a923458cba50bbc4e6440c0b2f372da2 Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Tue, 3 Aug 2021 13:50:49 +0200Subject: [PATCH 1/2] build-system/copy: Support #:allowed-references.
* guix/build-system/copy.scm (copy-build): Add #:allowed-references argument. (copy-build)[canonicalize-reference]: New procedure.--- guix/build-system/copy.scm | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-)
Toggle diff (41 lines)diff --git a/guix/build-system/copy.scm b/guix/build-system/copy.scmindex d1bf8fb654..1cd0a95150 100644--- a/guix/build-system/copy.scm+++ b/guix/build-system/copy.scm@@ -92,8 +92,22 @@ (system (%current-system)) (imported-modules %copy-build-system-modules) (modules '((guix build copy-build-system)- (guix build utils))))+ (guix build utils)))+ allowed-references) "Build SOURCE using INSTALL-PLAN, and with INPUTS."+ ;; XXX: procedure copied from (guix build-system gnu)+ (define canonicalize-reference+ (match-lambda+ ((? package? p)+ (derivation->output-path (package-derivation store p system+ #:graft? #f)))+ (((? package? p) output)+ (derivation->output-path (package-derivation store p system+ #:graft? #f)+ output))+ ((? string? output)+ output)))+ (define builder `(begin (use-modules ,@modules)@@ -131,6 +145,10 @@ #:system system #:inputs inputs #:modules imported-modules+ #:allowed-references+ (and allowed-references+ (map canonicalize-reference+ allowed-references)) #:outputs outputs #:guile-for-build guile-for-build)) -- 2.32.0
From f383aa1c886701631f6ae924a93e13cdad2eaa59 Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Tue, 3 Aug 2021 13:52:37 +0200Subject: [PATCH 2/2] build-system/minetest: Don't let anything sneak into the closure.
* guix/build-system/minetest.scm (lower-mod): Set #:allowed-references to the empty list.--- guix/build-system/minetest.scm | 2 ++ 1 file changed, 2 insertions(+)
Toggle diff (15 lines)diff --git a/guix/build-system/minetest.scm b/guix/build-system/minetest.scmindex 993c5631eb..1d63e5ffcf 100644--- a/guix/build-system/minetest.scm+++ b/guix/build-system/minetest.scm@@ -51,6 +51,8 @@ `'(("." ,(string-append "share/minetest/mods/" (guix-name->mod-name name)))) #:phases %standard-phases+ ;; Ensure nothing sneaks into the closure.+ #:allowed-references '() arguments)) (define minetest-mod-build-system-- 2.32.0
-----BEGIN PGP SIGNATURE-----
iI0EABYKADUWIQTB8z7iDFKP233XAR9J4+4iGRcl7gUCYQkvlBccbWF4aW1lZGV2b3NAdGVsZW5ldC5iZQAKCRBJ4+4iGRcl7m0uAQDHvPNuKE0Kzqph1mQNRU+T4JHR4ugvCqtJRxebG0S91wD/VO97KSiom/jmERbObhUUGG+tcHsz9YDaSgDXgktMHwU==QwE9-----END PGP SIGNATURE-----

L
L
Leo Prikler wrote on 3 Aug 14:28 +0200
8d13a1057f368f47eef8da538c554a379892cacc.camel@student.tugraz.at
Hi,
Am Dienstag, den 03.08.2021, 13:59 +0200 schrieb Maxime Devos:
Toggle quote (21 lines)> Leo Prikler schreef op di 03-08-2021 om 11:17 [+0200]:> > Hi,> > > > I'd merge this and 04/20 into a single patch. 04/20 does of its> > own> > give a good incentive as to why a new build system is to be used> > (this> > could instead be handled by the importer), with this phase added it> > makes slightly more sense.> > As an argument for having a 'minetest-mod-build-system', consider> some ways 'minetest-mod-build-system' could be improved in the> future:> > * a phase could be added to minimise PNG images (e.g. using> 'optipng')> * likewise, for lua code> * some basic tests could be added (e.g. creating a new world and> loading the mod, testing that Minetest doesn't raise an error> during> mod loading)
Of course there's more that can be done here, but this just reaffirmsmy earlier point, that the build system on its own as it is in 04/20looks rather unfinished. I'd personally prefer introducing it as onewhole as it gives a bigger picture of the whole thing rather thandigging into every detail.
Toggle quote (3 lines)> Also, having "#:install-plan '(("." "share/minetest/mods/the-mod-> name"))"> appear in every package definition seems rather repetitive to me.
Perhaps, but it's not like there aren't other groups of things that canbe implemented trivially in terms of copy-build-system.
Toggle quote (7 lines)> The idea behind "04/20" and "05/20" being separate patches, is to> start> with a basic "minetest-mod-build-system" and gradually improve it.> The small improvements (currently only one, i.e., 05/20) could be> reviewed> separately from each other and whether there should be a> "minetest-mod-build-system" at all.
See above.
Toggle quote (7 lines)> E.g., see attached a patch that sets #:allowed-references '(),> ensuring> nothing sneaks into the closure. Another change I'm thinking of, is> including> only "tar", "gzip" and the like as implicit inputs, and not "bash" or> "coreutils",> though that's probably useless if shebang patching has been disabled.
IMO that patch should also be merged "as one" with the others.
Toggle quote (10 lines)> > OTOH, perhaps we shouldn't install those shell scripts in the first> > place? Perhaps we can instead make the importer generate packages> > based directly on copy-build-system, in which those static strings> > are> > already evaluated. WDYT?> > Directly using 'copy-build-system' makes it more difficult to make> the improvements listed above. I don't know what you mean with ‘in> which those static strings are already evaluated’ -- what are ‘those> static strings’ here?
‘Those static strings’ are exactly "the-mod-name" in
Toggle quote (1 lines)> #:install-plan '(("." "share/minetest/mods/the-mod-name"))
I'm still not quite convinced, that whatever improvements you seemthere to be can't be made by using a good enough include regexp.
Toggle quote (3 lines)> I suppose it is possible to exclude shell scripts from installation,> but just installing everything (and disabling shebang patching) seems> simpler.
Likewise leaving shell references in there and using plain copy-build-system would be simpler than making a new build system, wouldn't it? Idon't think that's a good reason not to make a proper install plan.
Greetings
M
M
Maxime Devos wrote on 5 Aug 13:01 +0200
7680df67d8be80c1d55771407256c28b76e0d836.camel@telenet.be
Hi,
The attached patch squashes "PATCH 04" and "PATCH 05" togetherand extends the build system. It now has an install plan only installingwhat's necessary (Lua code, PNG images, some configuration files ...),a 'check' build phase verifying Minetest can actually load the mod,and a 'minimise-png' phase minimising PNG images.
The mod name for ‘(("." "share/minetest/mods/the-mod-name"))’ can nowbe determined exactly in most cases (Minetest doesn't really care butthe directory name can appear in the GUI in some cases).
Greetings,Maxime.
From e21ef78f6fdfd6d3952b2cc4f0fb1fa8b59ae5e1 Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sat, 31 Jul 2021 13:52:39 +0200Subject: [PATCH] build-system: Add 'minetest-mod-build-system'.
* guix/build-system/minetest.scm: New module.* guix/build/minetest-build-system.scm: Likewise.* Makefile.am (MODULES): Add them.* doc/guix.texi (Build Systems): Document 'minetest-mod-build-system'.--- Makefile.am | 2 + doc/guix.texi | 8 + guix/build-system/minetest.scm | 87 +++++++++++ guix/build/minetest-build-system.scm | 220 +++++++++++++++++++++++++++ 4 files changed, 317 insertions(+) create mode 100644 guix/build-system/minetest.scm create mode 100644 guix/build/minetest-build-system.scm
Toggle diff (360 lines)diff --git a/Makefile.am b/Makefile.amindex d5ec909213..f4439ce93b 100644--- a/Makefile.am+++ b/Makefile.am@@ -141,6 +141,7 @@ MODULES = \ guix/build-system/go.scm \ guix/build-system/meson.scm \ guix/build-system/minify.scm \+ guix/build-system/minetest.scm \ guix/build-system/asdf.scm \ guix/build-system/copy.scm \ guix/build-system/glib-or-gtk.scm \@@ -203,6 +204,7 @@ MODULES = \ guix/build/gnu-dist.scm \ guix/build/guile-build-system.scm \ guix/build/maven-build-system.scm \+ guix/build/minetest-build-system.scm \ guix/build/node-build-system.scm \ guix/build/perl-build-system.scm \ guix/build/python-build-system.scm \diff --git a/doc/guix.texi b/doc/guix.texiindex b3c16e6507..f7dba4f293 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -7895,6 +7895,14 @@ declaration. Its default value is @code{(default-maven-plugins)} which is also exported. @end defvr +@defvr {Scheme Variable} minetest-mod-build-system+This variable is exported by @code{(guix build-system minetest)}. It+implements a build procedure for @uref{https://www.minetest.net, Minetest}+mods, which consists of copying lua code, images and other resources to+the location Minetest searches for mods. The build system also minimises+PNG images and verifies that Minetest can load the mod without errors.+@end defvr+ @defvr {Scheme Variable} minify-build-system This variable is exported by @code{(guix build-system minify)}. It implements a minification procedure for simple JavaScript packages.diff --git a/guix/build-system/minetest.scm b/guix/build-system/minetest.scmnew file mode 100644index 0000000000..e99cc411c9--- /dev/null+++ b/guix/build-system/minetest.scm@@ -0,0 +1,87 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>+;;;+;;; 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 build-system minetest)+ #:use-module (guix build-system copy)+ #:use-module (guix build-system gnu)+ #:use-module (guix build-system)+ #:use-module (guix utils)+ #:export (minetest-mod-build-system))++;;+;; Build procedure for minetest mods. This is implemented as an extension+;; of ‘copy-build-system’.+;;+;; Code:++;; Lazily resolve the bindings to avoid circular dependencies.+(define (default-optipng)+ ;; Lazily resolve the binding to avoid a circular dependency.+ (module-ref (resolve-interface '(gnu packages image)) 'optipng))++(define (default-minetest)+ (module-ref (resolve-interface '(gnu packages games)) 'minetest))++(define (default-xvfb-run)+ (module-ref (resolve-interface '(gnu packages xorg)) 'xvfb-run))++(define %minetest-build-system-modules+ ;; Build-side modules imported by default.+ `((guix build minetest-build-system)+ ,@%copy-build-system-modules))++(define %default-modules+ ;; Modules in scope in the build-side environment.+ '((guix build gnu-build-system)+ (guix build minetest-build-system)+ (guix build utils)))++(define (standard-minetest-packages)+ "Return the list of (NAME PACKAGE OUTPUT) or (NAME PACKAGE) tuples of+standard packages used as implicit inputs of the Minetest build system."+ `(("xvfb-run" ,(default-xvfb-run))+ ("optipng" ,(default-optipng))+ ("minetest" ,(default-minetest))+ ,@(filter (lambda (input)+ (member (car input)+ '("libc" "tar" "gzip" "bzip2" "xz" "locales")))+ (standard-packages))))++(define (lower-mod name . arguments)+ (define lower (build-system-lower gnu-build-system))+ (apply lower+ name+ #:imported-modules %minetest-build-system-modules+ #:modules %default-modules+ #:phases '%standard-phases+ #:implicit-inputs? #f+ ;; Mods are architecture-independent.+ #:target #f+ ;; Ensure nothing sneaks into the closure.+ #:allowed-references '()+ (substitute-keyword-arguments arguments+ ((#:native-inputs native-inputs '())+ (append native-inputs (standard-minetest-packages))))))++(define minetest-mod-build-system+ (build-system+ (name 'minetest-mod)+ (description "The build system for minetest mods")+ (lower lower-mod)))++;;; minetest.scm ends herediff --git a/guix/build/minetest-build-system.scm b/guix/build/minetest-build-system.scmnew file mode 100644index 0000000000..e0c11e91f6--- /dev/null+++ b/guix/build/minetest-build-system.scm@@ -0,0 +1,220 @@+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>+;;;+;;; 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 build minetest-build-system)+ #:use-module (guix build utils)+ #:use-module (srfi srfi-1)+ #:use-module (ice-9 format)+ #:use-module (ice-9 match)+ #:use-module (ice-9 rdelim)+ #:use-module (ice-9 receive)+ #:use-module (ice-9 regex)+ #:use-module ((guix build gnu-build-system) #:prefix gnu:)+ #:export (%standard-phases+ mod-install-plan minimise-png read-mod-name check))++(define (mod-install-plan mod-name)+ `(("." ,(string-append "share/minetest/mods/" mod-name)+ ;; Only install files that will actually be used at run time.+ ;; This can save a little disk space.+ ;;+ ;; See <https://github.com/minetest/minetest/blob/master/doc/lua_api.txt>+ ;; for an incomple list of files that can be found in mods.+ #:include ("mod.conf" "modpack.conf" "settingtypes.txt" "depends.txt"+ "description.txt")+ #:include-regexp (".lua$" ".png$" ".ogg$" ".obj$" ".b3d$" ".tr$"+ ".mts$"))))++(define* (guess-mod-name #:key inputs #:allow-other-keys)+ "Try to determine the name of the mod or modpack that is being built.+If it is unknown, make an educated guess."+ ;; Minetest doesn't care about the directory names in "share/minetest/mods"+ ;; so there is no technical problem if the directory names don't match+ ;; the mod names. The directory can appear in the GUI if the modpack+ ;; doesn't have the 'name' set though, so try to make the guess.+ (define (guess)+ (let* ((source (assoc-ref inputs "source"))+ (file-name (basename source))+ ;; The "minetest-" prefix is not informative, so strip it.+ (file-name (if (string-prefix? "minetest-" file-name)+ (substring file-name (string-length "minetest-"))+ file-name))+ ;; Strip "-checkout" suffixes of git checkouts.+ (file-name (if (string-suffix? "-checkout" file-name)+ (substring file-name+ 0+ (- (string-length file-name)+ (string-length "-minetest")))+ file-name))+ (first-dot (string-index file-name #\.))+ ;; If the source code is in an archive (.tar.gz, .zip, ...),+ ;; strip the extension.+ (file-name (if first-dot+ (substring file-name 0 first-dot)+ file-name)))+ (format (current-error-port)+ "warning: the modpack ~a did not set 'name' in 'modpack.conf'~%"+ file-name)+ file-name))+ (cond ((file-exists? "mod.conf")+ (read-mod-name "mod.conf"))+ ((file-exists? "modpack.conf")+ (read-mod-name "modpack.conf" guess))+ (#t (guess))))++(define* (install #:key inputs #:allow-other-keys #:rest arguments)+ (apply (@@ (guix build copy-build-system) install)+ #:install-plan (mod-install-plan (apply guess-mod-name arguments))+ arguments))++(define %png-magic-bytes+ ;; Magic bytes of PNG images, see ‘5.2 PNG signatures’ in+ ;; ‘Portable Network Graphics (PNG) Specification (Second Edition)’+ ;; on <https://www.w3.org/TR/PNG/>.+ #vu8(137 80 78 71 13 10 26 10))++(define png-file?+ ((@@ (guix build utils) file-header-match) %png-magic-bytes))++(define* (minimise-png #:key inputs native-inputs #:allow-other-keys)+ "Minimise PNG images found in the working directory."+ (define optipng (which "optipng"))+ (define (optimise image)+ (format #t "Optimising ~a~%" image)+ (make-file-writable (dirname image))+ (make-file-writable image)+ (define old-size (stat:size (stat image)))+ ;; The mod "technic" has a file "technic_music_player_top.png" that+ ;; actually is a JPEG file, see+ ;; <https://github.com/minetest-mods/technic/issues/590>.+ (if (png-file? image)+ (invoke optipng "-o4" "-quiet" image)+ (format #t "warning: skipping ~a because it's not actually a PNG image~%"+ image))+ (define new-size (stat:size (stat image)))+ (values old-size new-size))+ (define files (find-files "." ".png$"))+ (let loop ((total-old-size 0)+ (total-new-size 0)+ (images (find-files "." ".png$")))+ (cond ((pair? images)+ (receive (old-size new-size)+ (optimise (car images))+ (loop (+ total-old-size old-size)+ (+ total-new-size new-size)+ (cdr images))))+ ((= total-old-size 0)+ (format #t "There were no PNG images to minimisation."))+ (#t+ (format #t "Minimisation reduced size of images by ~,2f% (~,2f MiB to ~,2f MiB)~%"+ (* 100.0 (- 1 (/ total-new-size total-old-size)))+ (/ total-old-size (expt 1024 2))+ (/ total-new-size (expt 1024 2)))))))++(define name-regexp (make-regexp "^name[ ]*=(.+)$"))++(define* (read-mod-name mod.conf #:optional not-found)+ "Read the name of a mod from MOD.CONF. If MOD.CONF+does not have a name field and NOT-FOUND is #false, raise an+error. If NOT-FOUND is TRUE, call NOT-FOUND instead."+ (call-with-input-file mod.conf+ (lambda (port)+ (let loop ()+ (define line (read-line port))+ (if (eof-object? line)+ (if not-found+ (not-found)+ (error "~a does not have a 'name' field" mod.conf))+ (let ((match (regexp-exec name-regexp line)))+ (if (regexp-match? match)+ (string-trim-both (match:substring match 1) #\ )+ (loop))))))))++(define* (check #:key outputs tests? #:allow-other-keys)+ "Test whether the mod loads. The mod must first be installed first."+ (define (all-mod-names directories)+ (append-map+ (lambda (directory)+ (map read-mod-name (find-files directory "mod.conf")))+ directories))+ (when tests?+ (mkdir "guix_testworld")+ ;; Add the mod to the mod search path, such that Minetest can find it.+ (setenv "MINETEST_MOD_PATH"+ (list->search-path-as-string+ (cons+ (string-append (assoc-ref outputs "out") "/share/minetest/mods")+ (search-path-as-string->list+ (or (getenv "MINETEST_MOD_PATH") "")))+ ":"))+ (with-directory-excursion "guix_testworld"+ (setenv "HOME" (getcwd))+ ;; Create a world in which all mods are loaded.+ (call-with-output-file "world.mt"+ (lambda (port)+ (display+ "gameid = minetest+world_name = guix_testworld+backend = sqlite3+player_backend = sqlite3+auth_backend = sqlite3+" port)+ (for-each+ (lambda (mod)+ (format port "load_mod_~a = true~%" mod))+ (all-mod-names (search-path-as-string->list+ (getenv "MINETEST_MOD_PATH"))))))+ (receive (port pid)+ ((@@ (guix build utils) open-pipe-with-stderr)+ "xvfb-run" "--" "minetest" "--info" "--world" "." "--go")+ (format #t "Started Minetest with all mods loaded for testing~%")+ ;; Scan the output for error messages.+ ;; When the player has joined the server, stop minetest.+ (define (error? line)+ (and (string? line)+ (string-contains line ": ERROR[")))+ (define (stop? line)+ (and (string? line)+ (string-contains line "ACTION[Server]: singleplayer [127.0.0.1] joins game.")))+ (let loop ()+ (match (read-line port)+ ((? error? line)+ (error "minetest raised an error: ~a" line))+ ((? stop?)+ (kill pid SIGINT)+ (close-port port)+ (waitpid pid))+ ((? string? line)+ (display line)+ (newline)+ (loop))+ ((? eof-object?)+ (error "minetest didn't start"))))))))++(define %standard-phases+ (modify-phases gnu:%standard-phases+ (delete 'bootstrap)+ (delete 'configure)+ (add-before 'build 'minimise-png minimise-png)+ (delete 'build)+ (delete 'check)+ (replace 'install install)+ ;; The 'check' phase requires the mod to be installed,+ ;; so move the 'check' phase after the 'install' phase.+ (add-after 'install 'check check)))++;;; minetest-build-system.scm ends here-- 2.32.0
-----BEGIN PGP SIGNATURE-----
iI0EABYKADUWIQTB8z7iDFKP233XAR9J4+4iGRcl7gUCYQvFGxccbWF4aW1lZGV2b3NAdGVsZW5ldC5iZQAKCRBJ4+4iGRcl7qh7AP43aRW2aGQVMi002RcK/NdmRrgvEarxVF3D33D3+XD+ngEAgOGwjaft59kMY4JSBuv+pdB5qMaQ0fkxO/okTrhK+Ac==DEDF-----END PGP SIGNATURE-----

L
L
Leo Prikler wrote on 5 Aug 14:04 +0200
2a49c566e1ecc280db79bcda1e893547216dd83a.camel@student.tugraz.at
Hi,
Am Donnerstag, den 05.08.2021, 13:01 +0200 schrieb Maxime Devos:
Toggle quote (19 lines)> Hi,> > The attached patch squashes "PATCH 04" and "PATCH 05" together> and extends the build system. It now has an install plan only> installing> what's necessary (Lua code, PNG images, some configuration files> ...),> a 'check' build phase verifying Minetest can actually load the mod,> and a 'minimise-png' phase minimising PNG images.> > The mod name for ‘(("." "share/minetest/mods/the-mod-name"))’ can now> be determined exactly in most cases (Minetest doesn't really care but> the directory name can appear in the GUI in some cases).> > Greetings,> Maxime.
> +mods, which consists of copying lua code, images and other resources> to
s/lua/Lua/ :)
Toggle quote (5 lines)> +(define* (install #:key inputs #:allow-other-keys #:rest arguments)> + (apply (@@ (guix build copy-build-system) install)> + #:install-plan (mod-install-plan (apply guess-mod-name> arguments))> + arguments))
@@ is a code smell, as far as Guix is concerned. Rather import copy-build-system with the copy: prefix.
Toggle quote (2 lines)> +(define png-file?> + ((@@ (guix build utils) file-header-match) %png-magic-bytes))
Likewise import (guix build utils) directly.
Toggle quote (15 lines)> +(define (lower-mod name . arguments)> + (define lower (build-system-lower gnu-build-system))> + (apply lower> + name> + #:imported-modules %minetest-build-system-modules> + #:modules %default-modules> + #:phases '%standard-phases> + #:implicit-inputs? #f> + ;; Mods are architecture-independent.> + #:target #f> + ;; Ensure nothing sneaks into the closure.> + #:allowed-references '()> + (substitute-keyword-arguments arguments> + ((#:native-inputs native-inputs '())> + (append native-inputs (standard-minetest-packages))))))
This appears a little confusing. On first glance, it does not seem toallow overriding e.g. #:phases, but on a second look using `apply'together with shallowly substituted arguments would enable that. Theonly thing that's missing imo is that #:implicit-inputs? is nothonoured for (standard-minetest-packages) -- I think you might want torectify that.
Otherwise looks pretty good to me.
M
M
Maxime Devos wrote on 5 Aug 15:16 +0200
8a8699af5e530cff4bab22aad4e5fa1862ebffc7.camel@telenet.be
Leo Prikler schreef op do 05-08-2021 om 14:04 [+0200]:
Toggle quote (4 lines)> > +mods, which consists of copying lua code, images and other resources> > to> s/lua/Lua/ :)
Fixed.
Toggle quote (8 lines)> > +(define* (install #:key inputs #:allow-other-keys #:rest arguments)> > + (apply (@@ (guix build copy-build-system) install)> > + #:install-plan (mod-install-plan (apply guess-mod-name> > arguments))> > + arguments))> @@ is a code smell, as far as Guix is concerned. Rather import copy-> build-system with the copy: prefix.
'copy-build-system' does not export 'install', so I have to use '@@' here.Modifying 'copy-build-system' to export 'install' would presumably entaila many rebuilds.
Toggle quote (4 lines)> > +(define png-file?> > + ((@@ (guix build utils) file-header-match) %png-magic-bytes))> Likewise import (guix build utils) directly.
Likewise.
Toggle quote (20 lines)> > +(define (lower-mod name . arguments)> > + (define lower (build-system-lower gnu-build-system))> > + (apply lower> > + name> > + #:imported-modules %minetest-build-system-modules> > + #:modules %default-modules> > + #:phases '%standard-phases> > + #:implicit-inputs? #f> > + ;; Mods are architecture-independent.> > + #:target #f> > + ;; Ensure nothing sneaks into the closure.> > + #:allowed-references '()> > + (substitute-keyword-arguments arguments> > + ((#:native-inputs native-inputs '())> > + (append native-inputs (standard-minetest-packages))))))
> This appears a little confusing. On first glance, it does not seem to> allow overriding e.g. #:phases, but on a second look using `apply'> together with shallowly substituted arguments would enable that.
I modified the patch to move more things into 'substitute-keyword-arguments'to reduce confusion.
Toggle quote (5 lines)> The> only thing that's missing imo is that #:implicit-inputs? is not> honoured for (standard-minetest-packages) -- I think you might want to> rectify that.
I modified 'lower-mod' to _not_ add 'standard-minetest-packages' to'native-inputs' when #:implicit-inputs? is false, though I don't seewhy a package definition for a Minetest mod would do that.
I also found a spellig bug ("to minimisation" -> "to minimise") whichis now fixed.
btw, I submitted the "MINETEST_MOD_PATH" patch upstream, with your suggestionfor "{std::string(...)}" construction:https://github.com/minetest/minetest/pull/11515.
Greetings,Maxime.
From dbd9cf53d359b461c01176e3170ba0663ce9007c Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sat, 31 Jul 2021 13:52:39 +0200Subject: [PATCH] build-system: Add 'minetest-mod-build-system'.
* guix/build-system/minetest.scm: New module.* guix/build/minetest-build-system.scm: Likewise.* Makefile.am (MODULES): Add them.* doc/guix.texi (Build Systems): Document 'minetest-mod-build-system'.--- Makefile.am | 2 + doc/guix.texi | 8 + guix/build-system/minetest.scm | 99 ++++++++++++ guix/build/minetest-build-system.scm | 220 +++++++++++++++++++++++++++ 4 files changed, 329 insertions(+) create mode 100644 guix/build-system/minetest.scm create mode 100644 guix/build/minetest-build-system.scm
Toggle diff (372 lines)diff --git a/Makefile.am b/Makefile.amindex d5ec909213..f4439ce93b 100644--- a/Makefile.am+++ b/Makefile.am@@ -141,6 +141,7 @@ MODULES = \ guix/build-system/go.scm \ guix/build-system/meson.scm \ guix/build-system/minify.scm \+ guix/build-system/minetest.scm \ guix/build-system/asdf.scm \ guix/build-system/copy.scm \ guix/build-system/glib-or-gtk.scm \@@ -203,6 +204,7 @@ MODULES = \ guix/build/gnu-dist.scm \ guix/build/guile-build-system.scm \ guix/build/maven-build-system.scm \+ guix/build/minetest-build-system.scm \ guix/build/node-build-system.scm \ guix/build/perl-build-system.scm \ guix/build/python-build-system.scm \diff --git a/doc/guix.texi b/doc/guix.texiindex b3c16e6507..d44ecc2005 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -7895,6 +7895,14 @@ declaration. Its default value is @code{(default-maven-plugins)} which is also exported. @end defvr +@defvr {Scheme Variable} minetest-mod-build-system+This variable is exported by @code{(guix build-system minetest)}. It+implements a build procedure for @uref{https://www.minetest.net, Minetest}+mods, which consists of copying Lua code, images and other resources to+the location Minetest searches for mods. The build system also minimises+PNG images and verifies that Minetest can load the mod without errors.+@end defvr+ @defvr {Scheme Variable} minify-build-system This variable is exported by @code{(guix build-system minify)}. It implements a minification procedure for simple JavaScript packages.diff --git a/guix/build-system/minetest.scm b/guix/build-system/minetest.scmnew file mode 100644index 0000000000..98bcbc9e0c--- /dev/null+++ b/guix/build-system/minetest.scm@@ -0,0 +1,99 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>+;;;+;;; 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 build-system minetest)+ #:use-module (guix build-system copy)+ #:use-module (guix build-system gnu)+ #:use-module (guix build-system)+ #:use-module (guix utils)+ #:export (minetest-mod-build-system))++;;+;; Build procedure for minetest mods. This is implemented as an extension+;; of ‘copy-build-system’.+;;+;; Code:++;; Lazily resolve the bindings to avoid circular dependencies.+(define (default-optipng)+ ;; Lazily resolve the binding to avoid a circular dependency.+ (module-ref (resolve-interface '(gnu packages image)) 'optipng))++(define (default-minetest)+ (module-ref (resolve-interface '(gnu packages games)) 'minetest))++(define (default-xvfb-run)+ (module-ref (resolve-interface '(gnu packages xorg)) 'xvfb-run))++(define %minetest-build-system-modules+ ;; Build-side modules imported by default.+ `((guix build minetest-build-system)+ ,@%copy-build-system-modules))++(define %default-modules+ ;; Modules in scope in the build-side environment.+ '((guix build gnu-build-system)+ (guix build minetest-build-system)+ (guix build utils)))++(define (standard-minetest-packages)+ "Return the list of (NAME PACKAGE OUTPUT) or (NAME PACKAGE) tuples of+standard packages used as implicit inputs of the Minetest build system."+ `(("xvfb-run" ,(default-xvfb-run))+ ("optipng" ,(default-optipng))+ ("minetest" ,(default-minetest))+ ,@(filter (lambda (input)+ (member (car input)+ '("libc" "tar" "gzip" "bzip2" "xz" "locales")))+ (standard-packages))))++(define* (lower-mod name #:key (implicit-inputs? #t) #:allow-other-keys+ #:rest arguments)+ (define lower (build-system-lower gnu-build-system))+ (apply lower+ name+ (substitute-keyword-arguments arguments+ ;; minetest-mod-build-system adds implicit inputs by itself,+ ;; so don't let gnu-build-system add its own implicit inputs+ ;; as well.+ ((#:implicit-inputs? implicit-inputs? #t)+ #f)+ ((#:imported-modules imported-modules %minetest-build-system-modules)+ imported-modules)+ ((#:modules modules %default-modules)+ modules)+ ((#:phases phases '%standard-phases)+ phases)+ ;; Mods are architecture-independent.+ ((#:target target #f) #f)+ ;; Ensure nothing sneaks into the closure.+ ((#:allowed-references allowed-references '())+ allowed-references)+ ;; Add the implicit inputs.+ ((#:native-inputs native-inputs '())+ (if implicit-inputs?+ (append native-inputs (standard-minetest-packages))+ native-inputs)))))++(define minetest-mod-build-system+ (build-system+ (name 'minetest-mod)+ (description "The build system for minetest mods")+ (lower lower-mod)))++;;; minetest.scm ends herediff --git a/guix/build/minetest-build-system.scm b/guix/build/minetest-build-system.scmnew file mode 100644index 0000000000..e9eb491b1b--- /dev/null+++ b/guix/build/minetest-build-system.scm@@ -0,0 +1,220 @@+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>+;;;+;;; 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 build minetest-build-system)+ #:use-module (guix build utils)+ #:use-module (srfi srfi-1)+ #:use-module (ice-9 format)+ #:use-module (ice-9 match)+ #:use-module (ice-9 rdelim)+ #:use-module (ice-9 receive)+ #:use-module (ice-9 regex)+ #:use-module ((guix build gnu-build-system) #:prefix gnu:)+ #:export (%standard-phases+ mod-install-plan minimise-png read-mod-name check))++(define (mod-install-plan mod-name)+ `(("." ,(string-append "share/minetest/mods/" mod-name)+ ;; Only install files that will actually be used at run time.+ ;; This can save a little disk space.+ ;;+ ;; See <https://github.com/minetest/minetest/blob/master/doc/lua_api.txt>+ ;; for an incomple list of files that can be found in mods.+ #:include ("mod.conf" "modpack.conf" "settingtypes.txt" "depends.txt"+ "description.txt")+ #:include-regexp (".lua$" ".png$" ".ogg$" ".obj$" ".b3d$" ".tr$"+ ".mts$"))))++(define* (guess-mod-name #:key inputs #:allow-other-keys)+ "Try to determine the name of the mod or modpack that is being built.+If it is unknown, make an educated guess."+ ;; Minetest doesn't care about the directory names in "share/minetest/mods"+ ;; so there is no technical problem if the directory names don't match+ ;; the mod names. The directory can appear in the GUI if the modpack+ ;; doesn't have the 'name' set though, so try to make the guess.+ (define (guess)+ (let* ((source (assoc-ref inputs "source"))+ (file-name (basename source))+ ;; The "minetest-" prefix is not informative, so strip it.+ (file-name (if (string-prefix? "minetest-" file-name)+ (substring file-name (string-length "minetest-"))+ file-name))+ ;; Strip "-checkout" suffixes of git checkouts.+ (file-name (if (string-suffix? "-checkout" file-name)+ (substring file-name+ 0+ (- (string-length file-name)+ (string-length "-minetest")))+ file-name))+ (first-dot (string-index file-name #\.))+ ;; If the source code is in an archive (.tar.gz, .zip, ...),+ ;; strip the extension.+ (file-name (if first-dot+ (substring file-name 0 first-dot)+ file-name)))+ (format (current-error-port)+ "warning: the modpack ~a did not set 'name' in 'modpack.conf'~%"+ file-name)+ file-name))+ (cond ((file-exists? "mod.conf")+ (read-mod-name "mod.conf"))+ ((file-exists? "modpack.conf")+ (read-mod-name "modpack.conf" guess))+ (#t (guess))))++(define* (install #:key inputs #:allow-other-keys #:rest arguments)+ (apply (@@ (guix build copy-build-system) install)+ #:install-plan (mod-install-plan (apply guess-mod-name arguments))+ arguments))++(define %png-magic-bytes+ ;; Magic bytes of PNG images, see ‘5.2 PNG signatures’ in+ ;; ‘Portable Network Graphics (PNG) Specification (Second Edition)’+ ;; on <https://www.w3.org/TR/PNG/>.+ #vu8(137 80 78 71 13 10 26 10))++(define png-file?+ ((@@ (guix build utils) file-header-match) %png-magic-bytes))++(define* (minimise-png #:key inputs native-inputs #:allow-other-keys)+ "Minimise PNG images found in the working directory."+ (define optipng (which "optipng"))+ (define (optimise image)+ (format #t "Optimising ~a~%" image)+ (make-file-writable (dirname image))+ (make-file-writable image)+ (define old-size (stat:size (stat image)))+ ;; The mod "technic" has a file "technic_music_player_top.png" that+ ;; actually is a JPEG file, see+ ;; <https://github.com/minetest-mods/technic/issues/590>.+ (if (png-file? image)+ (invoke optipng "-o4" "-quiet" image)+ (format #t "warning: skipping ~a because it's not actually a PNG image~%"+ image))+ (define new-size (stat:size (stat image)))+ (values old-size new-size))+ (define files (find-files "." ".png$"))+ (let loop ((total-old-size 0)+ (total-new-size 0)+ (images (find-files "." ".png$")))+ (cond ((pair? images)+ (receive (old-size new-size)+ (optimise (car images))+ (loop (+ total-old-size old-size)+ (+ total-new-size new-size)+ (cdr images))))+ ((= total-old-size 0)+ (format #t "There were no PNG images to minimise."))+ (#t+ (format #t "Minimisation reduced size of images by ~,2f% (~,2f MiB to ~,2f MiB)~%"+ (* 100.0 (- 1 (/ total-new-size total-old-size)))+ (/ total-old-size (expt 1024 2))+ (/ total-new-size (expt 1024 2)))))))++(define name-regexp (make-regexp "^name[ ]*=(.+)$"))++(define* (read-mod-name mod.conf #:optional not-found)+ "Read the name of a mod from MOD.CONF. If MOD.CONF+does not have a name field and NOT-FOUND is #false, raise an+error. If NOT-FOUND is TRUE, call NOT-FOUND instead."+ (call-with-input-file mod.conf+ (lambda (port)+ (let loop ()+ (define line (read-line port))+ (if (eof-object? line)+ (if not-found+ (not-found)+ (error "~a does not have a 'name' field" mod.conf))+ (let ((match (regexp-exec name-regexp line)))+ (if (regexp-match? match)+ (string-trim-both (match:substring match 1) #\ )+ (loop))))))))++(define* (check #:key outputs tests? #:allow-other-keys)+ "Test whether the mod loads. The mod must first be installed first."+ (define (all-mod-names directories)+ (append-map+ (lambda (directory)+ (map read-mod-name (find-files directory "mod.conf")))+ directories))+ (when tests?+ (mkdir "guix_testworld")+ ;; Add the mod to the mod search path, such that Minetest can find it.+ (setenv "MINETEST_MOD_PATH"+ (list->search-path-as-string+ (cons+ (string-append (assoc-ref outputs "out") "/share/minetest/mods")+ (search-path-as-string->list+ (or (getenv "MINETEST_MOD_PATH") "")))+ ":"))+ (with-directory-excursion "guix_testworld"+ (setenv "HOME" (getcwd))+ ;; Create a world in which all mods are loaded.+ (call-with-output-file "world.mt"+ (lambda (port)+ (display+ "gameid = minetest+world_name = guix_testworld+backend = sqlite3+player_backend = sqlite3+auth_backend = sqlite3+" port)+ (for-each+ (lambda (mod)+ (format port "load_mod_~a = true~%" mod))+ (all-mod-names (search-path-as-string->list+ (getenv "MINETEST_MOD_PATH"))))))+ (receive (port pid)+ ((@@ (guix build utils) open-pipe-with-stderr)+ "xvfb-run" "--" "minetest" "--info" "--world" "." "--go")+ (format #t "Started Minetest with all mods loaded for testing~%")+ ;; Scan the output for error messages.+ ;; When the player has joined the server, stop minetest.+ (define (error? line)+ (and (string? line)+ (string-contains line ": ERROR[")))+ (define (stop? line)+ (and (string? line)+ (string-contains line "ACTION[Server]: singleplayer [127.0.0.1] joins game.")))+ (let loop ()+ (match (read-line port)+ ((? error? line)+ (error "minetest raised an error: ~a" line))+ ((? stop?)+ (kill pid SIGINT)+ (close-port port)+ (waitpid pid))+ ((? string? line)+ (display line)+ (newline)+ (loop))+ ((? eof-object?)+ (error "minetest didn't start"))))))))++(define %standard-phases+ (modify-phases gnu:%standard-phases+ (delete 'bootstrap)+ (delete 'configure)+ (add-before 'build 'minimise-png minimise-png)+ (delete 'build)+ (delete 'check)+ (replace 'install install)+ ;; The 'check' phase requires the mod to be installed,+ ;; so move the 'check' phase after the 'install' phase.+ (add-after 'install 'check check)))++;;; minetest-build-system.scm ends here-- 2.32.0
-----BEGIN PGP SIGNATURE-----
iI0EABYKADUWIQTB8z7iDFKP233XAR9J4+4iGRcl7gUCYQvkpBccbWF4aW1lZGV2b3NAdGVsZW5ldC5iZQAKCRBJ4+4iGRcl7hzrAP4pOr0s5FrCSmJecUOUWWaZkIRJ0nWWx385tCHjXpvrhgEA3W6VDonCeLCkYuSEwfZcSvRVnDTuPRNXyLKmm3RI9AA==1pgf-----END PGP SIGNATURE-----

L
L
Leo Prikler wrote on 5 Aug 15:42 +0200
1a63353207ea0cbccaaf3138d42148fe5a98da62.camel@student.tugraz.at
Am Donnerstag, den 05.08.2021, 15:16 +0200 schrieb Maxime Devos:
Toggle quote (15 lines)> [...]> > > +(define* (install #:key inputs #:allow-other-keys #:rest> > > arguments)> > > + (apply (@@ (guix build copy-build-system) install)> > > + #:install-plan (mod-install-plan (apply guess-mod-name> > > arguments))> > > + arguments))> > @@ is a code smell, as far as Guix is concerned. Rather import> > copy-build-system with the copy: prefix.> > 'copy-build-system' does not export 'install', so I have to use '@@'> here.> Modifying 'copy-build-system' to export 'install' would presumably> entail> a many rebuilds.
I think the thing that's usually done here is fetching through%standard-phases.I.e. (define copy:install (assoc-ref copy-build-system:%standard-phases 'install))
Toggle quote (5 lines)> > > +(define png-file?> > > + ((@@ (guix build utils) file-header-match) %png-magic-bytes))> > Likewise import (guix build utils) directly.> > Likewise.
In that case fine, but make a note to move the variable and procedureover to (guix build utils).
Toggle quote (23 lines)> > > +(define (lower-mod name . arguments)> > > + (define lower (build-system-lower gnu-build-system))> > > + (apply lower> > > + name> > > + #:imported-modules %minetest-build-system-modules> > > + #:modules %default-modules> > > + #:phases '%standard-phases> > > + #:implicit-inputs? #f> > > + ;; Mods are architecture-independent.> > > + #:target #f> > > + ;; Ensure nothing sneaks into the closure.> > > + #:allowed-references '()> > > + (substitute-keyword-arguments arguments> > > + ((#:native-inputs native-inputs '())> > > + (append native-inputs (standard-minetest-> > > packages))))))> > This appears a little confusing. On first glance, it does not seem> > to> > allow overriding e.g. #:phases, but on a second look using `apply'> > together with shallowly substituted arguments would enable that. > > I modified the patch to move more things into 'substitute-keyword-> arguments' to reduce confusion.
LGTM.
Toggle quote (12 lines)> > The> > only thing that's missing imo is that #:implicit-inputs? is not> > honoured for (standard-minetest-packages) -- I think you might want> > to> > rectify that.> > I modified 'lower-mod' to _not_ add 'standard-minetest-packages' to> 'native-inputs' when #:implicit-inputs? is false, though I don't see> why a package definition for a Minetest mod would do that.> > I also found a spellig bug ("to minimisation" -> "to minimise") which> is now fixed.
The new lower-mod mostly LGTM, but
Toggle quote (2 lines)> + ;; Mods are architecture-independent.> + ((#:target target #f) #f)
should be `target' imho. What if the mod e.g. actually builds a sharedobject and somehow uses Lua's very dynamic FFI to load it? (Even ifthat's not currently possible, it might be in the future). Setting itto #f by default OTOH sounds very reasonable to me.
Toggle quote (3 lines)> btw, I submitted the "MINETEST_MOD_PATH" patch upstream, with your> suggestion for "{std::string(...)}" construction:> <https://github.com/minetest/minetest/pull/11515>;.
Nice, perhaps in 5.5 we will be able to enjoy this out-of-the-box.
Greetings
M
M
Maxime Devos wrote on 5 Aug 16:41 +0200
c436498dbd7f7d83fe364156e73dfa7951fb95ed.camel@telenet.be
Leo Prikler schreef op do 05-08-2021 om 15:42 [+0200]:
Toggle quote (21 lines)> Am Donnerstag, den 05.08.2021, 15:16 +0200 schrieb Maxime Devos:> > [...]> > > > +(define* (install #:key inputs #:allow-other-keys #:rest> > > > arguments)> > > > + (apply (@@ (guix build copy-build-system) install)> > > > + #:install-plan (mod-install-plan (apply guess-mod-name> > > > arguments))> > > > + arguments))> > > @@ is a code smell, as far as Guix is concerned. Rather import> > > copy-build-system with the copy: prefix.> > > > 'copy-build-system' does not export 'install', so I have to use '@@'> > here.> > Modifying 'copy-build-system' to export 'install' would presumably> > entail> > a many rebuilds.> I think the thing that's usually done here is fetching through> %standard-phases.> I.e. (define copy:install (assoc-ref copy-build-system:%standard-phases > 'install))
Done.
Toggle quote (8 lines)> > > > +(define png-file?> > > > + ((@@ (guix build utils) file-header-match) %png-magic-bytes))> > > Likewise import (guix build utils) directly.> > > > Likewise.> In that case fine, but make a note to move the variable and procedure> over to (guix build utils).
I made a note.
Toggle quote (9 lines)> The new lower-mod mostly LGTM, but> > + ;; Mods are architecture-independent.> > + ((#:target target #f) #f)
> should be `target' imho. What if the mod e.g. actually builds a shared> object and somehow uses Lua's very dynamic FFI to load it? (Even if> that's not currently possible, it might be in the future). Setting it> to #f by default OTOH sounds very reasonable to me.
'target' is set by 'make-bag' in (guix build-system), so if the code aboveis made
((#:target target #f) target)
then #:target will always be set to some triplet. Mostly harmless, but abit a waste of disk space since this leads to (slightly) different derivationsdepending on the value of "target".
I don't think any mods use Lua's FFI, but some mods use 'os.execute',which takes a file name referring to an executable, which might need to beabsolutised in Guix, and therefore some mods are architecture-dependent.
It dropped the ((#:target target #f) #f). I noticed "#:implicit-cross-inputs?"wasn't set to #f. That has been corrected as well.
Greetings,Maxime.
From 93aa8e1976e762d30be70aef6d5c50b1d06ca4be Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sat, 31 Jul 2021 13:52:39 +0200Subject: [PATCH] build-system: Add 'minetest-mod-build-system'.
* guix/build-system/minetest.scm: New module.* guix/build/minetest-build-system.scm: Likewise.* Makefile.am (MODULES): Add them.* doc/guix.texi (Build Systems): Document 'minetest-mod-build-system'.--- Makefile.am | 2 + doc/guix.texi | 8 + guix/build-system/minetest.scm | 99 ++++++++++++ guix/build/minetest-build-system.scm | 225 +++++++++++++++++++++++++++ 4 files changed, 334 insertions(+) create mode 100644 guix/build-system/minetest.scm create mode 100644 guix/build/minetest-build-system.scm
Toggle diff (377 lines)diff --git a/Makefile.am b/Makefile.amindex d5ec909213..f4439ce93b 100644--- a/Makefile.am+++ b/Makefile.am@@ -141,6 +141,7 @@ MODULES = \ guix/build-system/go.scm \ guix/build-system/meson.scm \ guix/build-system/minify.scm \+ guix/build-system/minetest.scm \ guix/build-system/asdf.scm \ guix/build-system/copy.scm \ guix/build-system/glib-or-gtk.scm \@@ -203,6 +204,7 @@ MODULES = \ guix/build/gnu-dist.scm \ guix/build/guile-build-system.scm \ guix/build/maven-build-system.scm \+ guix/build/minetest-build-system.scm \ guix/build/node-build-system.scm \ guix/build/perl-build-system.scm \ guix/build/python-build-system.scm \diff --git a/doc/guix.texi b/doc/guix.texiindex b3c16e6507..d44ecc2005 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -7895,6 +7895,14 @@ declaration. Its default value is @code{(default-maven-plugins)} which is also exported. @end defvr +@defvr {Scheme Variable} minetest-mod-build-system+This variable is exported by @code{(guix build-system minetest)}. It+implements a build procedure for @uref{https://www.minetest.net, Minetest}+mods, which consists of copying Lua code, images and other resources to+the location Minetest searches for mods. The build system also minimises+PNG images and verifies that Minetest can load the mod without errors.+@end defvr+ @defvr {Scheme Variable} minify-build-system This variable is exported by @code{(guix build-system minify)}. It implements a minification procedure for simple JavaScript packages.diff --git a/guix/build-system/minetest.scm b/guix/build-system/minetest.scmnew file mode 100644index 0000000000..f33e97559d--- /dev/null+++ b/guix/build-system/minetest.scm@@ -0,0 +1,99 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>+;;;+;;; 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 build-system minetest)+ #:use-module (guix build-system copy)+ #:use-module (guix build-system gnu)+ #:use-module (guix build-system)+ #:use-module (guix utils)+ #:export (minetest-mod-build-system))++;;+;; Build procedure for minetest mods. This is implemented as an extension+;; of ‘copy-build-system’.+;;+;; Code:++;; Lazily resolve the bindings to avoid circular dependencies.+(define (default-optipng)+ ;; Lazily resolve the binding to avoid a circular dependency.+ (module-ref (resolve-interface '(gnu packages image)) 'optipng))++(define (default-minetest)+ (module-ref (resolve-interface '(gnu packages games)) 'minetest))++(define (default-xvfb-run)+ (module-ref (resolve-interface '(gnu packages xorg)) 'xvfb-run))++(define %minetest-build-system-modules+ ;; Build-side modules imported by default.+ `((guix build minetest-build-system)+ ,@%copy-build-system-modules))++(define %default-modules+ ;; Modules in scope in the build-side environment.+ '((guix build gnu-build-system)+ (guix build minetest-build-system)+ (guix build utils)))++(define (standard-minetest-packages)+ "Return the list of (NAME PACKAGE OUTPUT) or (NAME PACKAGE) tuples of+standard packages used as implicit inputs of the Minetest build system."+ `(("xvfb-run" ,(default-xvfb-run))+ ("optipng" ,(default-optipng))+ ("minetest" ,(default-minetest))+ ,@(filter (lambda (input)+ (member (car input)+ '("libc" "tar" "gzip" "bzip2" "xz" "locales")))+ (standard-packages))))++(define* (lower-mod name #:key (implicit-inputs? #t) #:allow-other-keys+ #:rest arguments)+ (define lower (build-system-lower gnu-build-system))+ (apply lower+ name+ (substitute-keyword-arguments arguments+ ;; minetest-mod-build-system adds implicit inputs by itself,+ ;; so don't let gnu-build-system add its own implicit inputs+ ;; as well.+ ((#:implicit-inputs? implicit-inputs? #t)+ #f)+ ((#:implicit-cross-inputs? implicit-cross-inputs? #t)+ #f)+ ((#:imported-modules imported-modules %minetest-build-system-modules)+ imported-modules)+ ((#:modules modules %default-modules)+ modules)+ ((#:phases phases '%standard-phases)+ phases)+ ;; Ensure nothing sneaks into the closure.+ ((#:allowed-references allowed-references '())+ allowed-references)+ ;; Add the implicit inputs.+ ((#:native-inputs native-inputs '())+ (if implicit-inputs?+ (append native-inputs (standard-minetest-packages))+ native-inputs)))))++(define minetest-mod-build-system+ (build-system+ (name 'minetest-mod)+ (description "The build system for minetest mods")+ (lower lower-mod)))++;;; minetest.scm ends herediff --git a/guix/build/minetest-build-system.scm b/guix/build/minetest-build-system.scmnew file mode 100644index 0000000000..b051d9c288--- /dev/null+++ b/guix/build/minetest-build-system.scm@@ -0,0 +1,225 @@+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>+;;;+;;; 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 build minetest-build-system)+ #:use-module (guix build utils)+ #:use-module (srfi srfi-1)+ #:use-module (ice-9 format)+ #:use-module (ice-9 match)+ #:use-module (ice-9 rdelim)+ #:use-module (ice-9 receive)+ #:use-module (ice-9 regex)+ #:use-module ((guix build gnu-build-system) #:prefix gnu:)+ #:use-module ((guix build copy-build-system) #:prefix copy:)+ #:export (%standard-phases+ mod-install-plan minimise-png read-mod-name check))++;; (guix build copy-build-system) does not export 'install'.+(define copy:install+ (assoc-ref copy:%standard-phases 'install))++(define (mod-install-plan mod-name)+ `(("." ,(string-append "share/minetest/mods/" mod-name)+ ;; Only install files that will actually be used at run time.+ ;; This can save a little disk space.+ ;;+ ;; See <https://github.com/minetest/minetest/blob/master/doc/lua_api.txt>+ ;; for an incomple list of files that can be found in mods.+ #:include ("mod.conf" "modpack.conf" "settingtypes.txt" "depends.txt"+ "description.txt")+ #:include-regexp (".lua$" ".png$" ".ogg$" ".obj$" ".b3d$" ".tr$"+ ".mts$"))))++(define* (guess-mod-name #:key inputs #:allow-other-keys)+ "Try to determine the name of the mod or modpack that is being built.+If it is unknown, make an educated guess."+ ;; Minetest doesn't care about the directory names in "share/minetest/mods"+ ;; so there is no technical problem if the directory names don't match+ ;; the mod names. The directory can appear in the GUI if the modpack+ ;; doesn't have the 'name' set though, so try to make the guess.+ (define (guess)+ (let* ((source (assoc-ref inputs "source"))+ (file-name (basename source))+ ;; The "minetest-" prefix is not informative, so strip it.+ (file-name (if (string-prefix? "minetest-" file-name)+ (substring file-name (string-length "minetest-"))+ file-name))+ ;; Strip "-checkout" suffixes of git checkouts.+ (file-name (if (string-suffix? "-checkout" file-name)+ (substring file-name+ 0+ (- (string-length file-name)+ (string-length "-minetest")))+ file-name))+ (first-dot (string-index file-name #\.))+ ;; If the source code is in an archive (.tar.gz, .zip, ...),+ ;; strip the extension.+ (file-name (if first-dot+ (substring file-name 0 first-dot)+ file-name)))+ (format (current-error-port)+ "warning: the modpack ~a did not set 'name' in 'modpack.conf'~%"+ file-name)+ file-name))+ (cond ((file-exists? "mod.conf")+ (read-mod-name "mod.conf"))+ ((file-exists? "modpack.conf")+ (read-mod-name "modpack.conf" guess))+ (#t (guess))))++(define* (install #:key inputs #:allow-other-keys #:rest arguments)+ (apply copy:install+ #:install-plan (mod-install-plan (apply guess-mod-name arguments))+ arguments))++(define %png-magic-bytes+ ;; Magic bytes of PNG images, see ‘5.2 PNG signatures’ in+ ;; ‘Portable Network Graphics (PNG) Specification (Second Edition)’+ ;; on <https://www.w3.org/TR/PNG/>.+ #vu8(137 80 78 71 13 10 26 10))++(define png-file?+ ((@@ (guix build utils) file-header-match) %png-magic-bytes))++(define* (minimise-png #:key inputs native-inputs #:allow-other-keys)+ "Minimise PNG images found in the working directory."+ (define optipng (which "optipng"))+ (define (optimise image)+ (format #t "Optimising ~a~%" image)+ (make-file-writable (dirname image))+ (make-file-writable image)+ (define old-size (stat:size (stat image)))+ ;; The mod "technic" has a file "technic_music_player_top.png" that+ ;; actually is a JPEG file, see+ ;; <https://github.com/minetest-mods/technic/issues/590>.+ (if (png-file? image)+ (invoke optipng "-o4" "-quiet" image)+ (format #t "warning: skipping ~a because it's not actually a PNG image~%"+ image))+ (define new-size (stat:size (stat image)))+ (values old-size new-size))+ (define files (find-files "." ".png$"))+ (let loop ((total-old-size 0)+ (total-new-size 0)+ (images (find-files "." ".png$")))+ (cond ((pair? images)+ (receive (old-size new-size)+ (optimise (car images))+ (loop (+ total-old-size old-size)+ (+ total-new-size new-size)+ (cdr images))))+ ((= total-old-size 0)+ (format #t "There were no PNG images to minimise."))+ (#t+ (format #t "Minimisation reduced size of images by ~,2f% (~,2f MiB to ~,2f MiB)~%"+ (* 100.0 (- 1 (/ total-new-size total-old-size)))+ (/ total-old-size (expt 1024 2))+ (/ total-new-size (expt 1024 2)))))))++(define name-regexp (make-regexp "^name[ ]*=(.+)$"))++(define* (read-mod-name mod.conf #:optional not-found)+ "Read the name of a mod from MOD.CONF. If MOD.CONF+does not have a name field and NOT-FOUND is #false, raise an+error. If NOT-FOUND is TRUE, call NOT-FOUND instead."+ (call-with-input-file mod.conf+ (lambda (port)+ (let loop ()+ (define line (read-line port))+ (if (eof-object? line)+ (if not-found+ (not-found)+ (error "~a does not have a 'name' field" mod.conf))+ (let ((match (regexp-exec name-regexp line)))+ (if (regexp-match? match)+ (string-trim-both (match:substring match 1) #\ )+ (loop))))))))++(define* (check #:key outputs tests? #:allow-other-keys)+ "Test whether the mod loads. The mod must first be installed first."+ (define (all-mod-names directories)+ (append-map+ (lambda (directory)+ (map read-mod-name (find-files directory "mod.conf")))+ directories))+ (when tests?+ (mkdir "guix_testworld")+ ;; Add the mod to the mod search path, such that Minetest can find it.+ (setenv "MINETEST_MOD_PATH"+ (list->search-path-as-string+ (cons+ (string-append (assoc-ref outputs "out") "/share/minetest/mods")+ (search-path-as-string->list+ (or (getenv "MINETEST_MOD_PATH") "")))+ ":"))+ (with-directory-excursion "guix_testworld"+ (setenv "HOME" (getcwd))+ ;; Create a world in which all mods are loaded.+ (call-with-output-file "world.mt"+ (lambda (port)+ (display+ "gameid = minetest+world_name = guix_testworld+backend = sqlite3+player_backend = sqlite3+auth_backend = sqlite3+" port)+ (for-each+ (lambda (mod)+ (format port "load_mod_~a = true~%" mod))+ (all-mod-names (search-path-as-string->list+ (getenv "MINETEST_MOD_PATH"))))))+ (receive (port pid)+ ((@@ (guix build utils) open-pipe-with-stderr)+ "xvfb-run" "--" "minetest" "--info" "--world" "." "--go")+ (format #t "Started Minetest with all mods loaded for testing~%")+ ;; Scan the output for error messages.+ ;; When the player has joined the server, stop minetest.+ (define (error? line)+ (and (string? line)+ (string-contains line ": ERROR[")))+ (define (stop? line)+ (and (string? line)+ (string-contains line "ACTION[Server]: singleplayer [127.0.0.1] joins game.")))+ (let loop ()+ (match (read-line port)+ ((? error? line)+ (error "minetest raised an error: ~a" line))+ ((? stop?)+ (kill pid SIGINT)+ (close-port port)+ (waitpid pid))+ ((? string? line)+ (display line)+ (newline)+ (loop))+ ((? eof-object?)+ (error "minetest didn't start"))))))))++(define %standard-phases+ (modify-phases gnu:%standard-phases+ (delete 'bootstrap)+ (delete 'configure)+ (add-before 'build 'minimise-png minimise-png)+ (delete 'build)+ (delete 'check)+ (replace 'install install)+ ;; The 'check' phase requires the mod to be installed,+ ;; so move the 'check' phase after the 'install' phase.+ (add-after 'install 'check check)))++;;; minetest-build-system.scm ends here-- 2.32.0
-----BEGIN PGP SIGNATURE-----
iI0EABYKADUWIQTB8z7iDFKP233XAR9J4+4iGRcl7gUCYQv4hRccbWF4aW1lZGV2b3NAdGVsZW5ldC5iZQAKCRBJ4+4iGRcl7qirAP4y0BJ+gayUfa13V0P/UyMnd2LZvpUoYbOnpIJEPrqFjAD/Q57U2qHY19AcYGpQxshSM5UxkPO1G9GA5qdifNDEoQA==I2NP-----END PGP SIGNATURE-----

A
A
Andrew Ward wrote on 5 Aug 14:46 +0200
[PATCH 00/20] Add minetest mods
(address . 49828@debbugs.gnu.org)
68444560-b887-4c0c-af36-7f8cc609eda9@email.android.com
Attachment: file
L
L
Leo Prikler wrote on 5 Aug 17:15 +0200
Re: [PATCH 05/20] build-system: minetest: Don't retain references to "bash-minimal".
96a038c941308c8ec427d4b37bb333b32a7d0204.camel@student.tugraz.at
Am Donnerstag, den 05.08.2021, 16:41 +0200 schrieb Maxime Devos:
Toggle quote (27 lines)> Leo Prikler schreef op do 05-08-2021 om 15:42 [+0200]:> > Am Donnerstag, den 05.08.2021, 15:16 +0200 schrieb Maxime Devos:> > > [...]> > > > > +(define* (install #:key inputs #:allow-other-keys #:rest> > > > > arguments)> > > > > + (apply (@@ (guix build copy-build-system) install)> > > > > + #:install-plan (mod-install-plan (apply guess-mod-> > > > > name> > > > > arguments))> > > > > + arguments))> > > > @@ is a code smell, as far as Guix is concerned. Rather import> > > > copy-build-system with the copy: prefix.> > > > > > 'copy-build-system' does not export 'install', so I have to use> > > '@@'> > > here.> > > Modifying 'copy-build-system' to export 'install' would> > > presumably> > > entail> > > a many rebuilds.> > I think the thing that's usually done here is fetching through> > %standard-phases.> > I.e. (define copy:install (assoc-ref copy-build-system:%standard-> > phases > > 'install))> > Done.
LGTM.
Toggle quote (11 lines)> > > > > +(define png-file?> > > > > + ((@@ (guix build utils) file-header-match) %png-magic-> > > > > bytes))> > > > Likewise import (guix build utils) directly.> > > > > > Likewise.> > In that case fine, but make a note to move the variable and> > procedure> > over to (guix build utils).> > I made a note.
I'm not seeing it, did you send the right file?
Toggle quote (19 lines)> > The new lower-mod mostly LGTM, but> > > + ;; Mods are architecture-independent.> > > + ((#:target target #f) #f)> > should be `target' imho. What if the mod e.g. actually builds a> > shared> > object and somehow uses Lua's very dynamic FFI to load it? (Even> > if> > that's not currently possible, it might be in the future). Setting> > it> > to #f by default OTOH sounds very reasonable to me.> > 'target' is set by 'make-bag' in (guix build-system), so if the code> above is made> > ((#:target target #f) target)> > then #:target will always be set to some triplet. Mostly harmless,> but a bit a waste of disk space since this leads to (slightly)> different derivations depending on the value of "target".
I think deduplication should take care of that, but yeah.
Toggle quote (7 lines)> I don't think any mods use Lua's FFI, but some mods use 'os.execute',> which takes a file name referring to an executable, which might need> to be absolutised in Guix, and therefore some mods are architecture-> dependent.> > It dropped the ((#:target target #f) #f). I noticed "#:implicit-> cross-inputs?" wasn't set to #f. That has been corrected as well.
Good catch.
Since my only remaining complaint is somewhat minor, you don't need toresend this patch; I'll have a look at the importer later (or maybesomeone else gets to do that in between), but I won't cover the packagedefinitions for the mods. If they work for you and you checked thelicenses, they're probably going to be fine.
Greetings
L
L
Leo Prikler wrote on 5 Aug 18:41 +0200
Re: [PATCH 06/20] guix: Add ContentDB importer.
74fcdc1aec1e92afec81c84930cff6ac831f72b1.camel@student.tugraz.at
Hi,
Am Montag, den 02.08.2021, 17:50 +0200 schrieb Maxime Devos:
Toggle quote (30 lines)> * guix/import/contentdb.scm: New file.> * guix/scripts/import/contentdb.scm: New file.> * tests/contentdb.scm: New file.> * Makefile.am (MODULES, SCM_TESTS): Register them.> * po/guix/POTFILES.in: Likewise.> * doc/guix.texi (Invoking guix import): Document it.> [...]> diff --git a/doc/guix.texi b/doc/guix.texi> index 43c248234d..d06c9b73c5 100644> --- a/doc/guix.texi> +++ b/doc/guix.texi> @@ -11313,6 +11313,31 @@ and generate package expressions for all> those packages that are not yet> in Guix.> @end table> > +@item contentdb> +@cindex ContentDB> +Import metadata from @uref{https://content.minetest.net, ContentDB}.> +Information is taken from the JSON-formatted metadata provided> through> +@uref{https://content.minetest.net/help/api/, ContentDB's API} and> +includes most relevant information, including dependencies. There> are> +some caveats, however. The license information on ContentDB does> not> +distinguish between GPLvN-only and GPLvN-or-later. The commit id is> +sometimes missing. The descriptions are in the Markdown format, but> +Guix uses Texinfo instead. Texture packs and subgames are> unsupported.
What is the "commit id"? Is it the hash? A tag? Anything thatresolves to a commit?
Also, since ContentDB sounds fairly generic (a database of content?),perhaps we ought to call this the "minetest" importer instead?
Toggle quote (28 lines)> [...]> +;; 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))> +> +;; 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) ;> natural | #f
This comment and some others like it seem to simply be repeatingalready present information. Is there a use for them? Should weinstead provide a third argument on every field to verify/enforce thetype?
Toggle quote (43 lines)> + (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) ;> string | #f> + (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)) ;> string | #f> +> +(define-json-mapping <release> make-release release?> + json->release> + (commit release-commit "commit" string-or-false) ;> string | #f> + (downloads release-downloads) ; integer> + (id release-id) ; integer> + (max-minetest-version release-max-minetest-version) ; string | #f> + (min-minetest-version release-min-minetest-version) ; string | #f> + (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") ; #t | #f
Also known as "boolean".
Toggle quote (11 lines)> + (name dependency-name) ; string> + (packages dependency-packages "packages" vector->list)) ; list of> strings> +> +(define (contentdb-fetch author name)> + "Return a <package> record for package NAME by AUTHOR, or #f on> failure."> + (and=> (json-fetch> + (string-append (%contentdb-api) "packages/" author "/"> name "/"))> + json->package))
Is there a reason for author and name to be separate keys? For me itmakes more sense to take AUTHOR/NAME as a singular search string fromusers and then perform queries based on that. If ContentDB allowssearching, we might also resolve NAME to a singular package wherepossible and otherwise error out, telling the user to choose one.
Toggle quote (29 lines)> [...]> +> +(define (important-dependencies dependencies author name)> + (define dependency-list> + (assoc-ref dependencies (string-append author "/" name)))> + (filter-map> + (lambda (dependency)> + (and (not (dependency-optional? dependency))> + ;; "default" must be provided by the 'subgame' in use> + ;; and does not refer to a specific minetest mod.> + ;; "doors", "bucket" ... are provided by the default> minetest> + ;; subgame.> + (not (member (dependency-name dependency)> + '("default" "doors" "beds" "bucket" "doors"> "farming"> + "flowers" "stairs" "xpanes")))> + ;; Dependencies often have only one implementation.> + (let* ((/name (string-append "/" (dependency-name> dependency)))> + (likewise-named-implementations> + (filter (cut string-suffix? /name <>)> + (dependency-packages dependency)))> + (implementation> + (and (not (null? likewise-named-implementations))> + (first likewise-named-implementations))))> + (and implementation> + (apply cons (string-split implementation #\/))))))> + dependency-list))
What exactly does the likewise-named-implementations bit do here?
Toggle quote (5 lines)> +(define (contentdb-recursive-import author name)> + ;; recursive-import expects upstream package names to be strings,> + ;; so do some conversions.> + (define (split-author/name author/name)> + (string-split author/name #\/))
+1 for my author/name splitting, as it's already required for recursiveimports.
Toggle quote (40 lines)> + (define (author+name->author/name author+name)> + (string-append (car author+name) "/" (cdr author+name)))> + (define* (contentdb->guix-package* author/name #:key repo version)> + (receive (package . maybe-dependencies)> + (apply contentdb->guix-package (split-author/name> author/name))> + (and package> + (receive (dependencies)> + (apply values maybe-dependencies)> + (values package> + (map author+name->author/name> dependencies))))))> + (recursive-import (author+name->author/name (cons author name))> + #:repo->guix-package contentdb->guix-package*> + #:guix-name> + (lambda (author/name)> + (contentdb->package-name> + (second (split-author/name author/name))))))> +> +;; A list of license names is available at> +;; <https://content.minetest.net/api/licenses/>;.> +(define (string->license str)> + "Convert the string STR into a license object."> + (match str> + ("GPLv3" license:gpl3)> + ("GPLv2" license:gpl2)> + ("ISC" license:isc)> + ;; "MIT" means the Expat license on ContentDB,> + ;; see <> https://github.com/minetest/contentdb/issues/326#issuecomment-890143784>> ;.> + ("MIT" license:expat)> + ("CC BY-SA 3.0" license:cc-by-sa3.0)> + ("CC BY-SA 4.0" license:cc-by-sa4.0)> + ("LGPLv2.1" license:lgpl2.1)> + ("LGPLv3" license:lgpl3)> + ("MPL 2.0" license:mpl2.0)> + ("ZLib" license:zlib)> + ("Unlicense" license:unlicense)> + (_ #f)))
The link mentions, that ContentDB now supports all SPDX identifiers. Do we have a SPDX->Guix converter lying around in some other importerthat we could use as default case here (especially w.r.t. "or later")
WDYT?
M
M
Maxime Devos wrote on 5 Aug 23:10 +0200
Re: [bug#49828] [PATCH 00/20] Add minetest mods
12b8c0746b9db7d9e744ad350aa8e1b37e80ad2a.camel@telenet.be
Hi,
Andrew Ward schreef op do 05-08-2021 om 13:46 [+0100]:
Toggle quote (7 lines)> Hi, I'm a Minetest core dev and the creator of ContentDB (the service the powers> the built-in mod/game/etc manager in Minetest).> > It's very annoying when distros include mods but then never update them.> It causes confusion with users, as mods change over time and there can be breakages.> So, I'd like to make sure that these packages are kept in sync with ContentDB.
When the mod is being ‘built’ in Guix, the 'check' phase will start Minetestwith a new world where the mod and its dependencies are activated. It is verifiedthere are no errors in the log. That should help with detecting breakage.It actually detected some breakage: ".mts" files were not being installed, leadingto errors at load time. This is fixed now.
To keep in sync, there is "guix refresh minetest-MODA minetest-MODB ..." whichcan automatically upgrade packages to the latest version. It currently doesn'tknow about ContentDB however, so it has to fall-back to the generic updaterswhich do not appear to work well with Minetest mods:
gnu/packages/minetest.scm:345:13: 1.3 is already the latest version of minetest-worldeditgnu/packages/minetest.scm:365:2: warning: no updater for minetest-unifieddyesgnu/packages/minetest.scm:173:2: warning: no updater for minetest-mobsgnu/packages/minetest.scm:143:13: minetest-mesecons would be upgraded from 1.2.1-0.db58797 to 2017.03.05 ^ this is actually a downgrade IIRCgnu/packages/minetest.scm:227:2: warning: no updater for minetest-pipeworks
Hopefully that can be improved in the future (maybe keep the "release date" inthe 'properties' field of the Guix package and use that to determine if an updateis available?).
Toggle quote (4 lines)> ContentDB also provides two other features: it only provides you with versions of> mods/games that support your Minetest version. It also handles dependencies, so I> hope this is set up correctly.
The ContentDB->guix importer handles dependencies. It reads the dependenciesfrom ContentDB (with the /api/packages/AUTHOR/NAME/dependencies/ API) andadds the hard dependencies to 'propagated-inputs', so "minetest-mobs-animal"has "minetest-mobs" in its 'propagated-inputs'. See also the 'check' phasementioned above.
Toggle quote (4 lines)> If you are disabling ContentDB completely, you should have the vast majority of mods,> games, and texture packs available - especially all the hard dependencies needed, as> not having these will cause load issues. Minetest is all about customisation.
In the original patch series I sent, ContentDB was indeed disabled completely whenguix-installed mods are present. But with the revised patch (using the MINETEST_MOD_PATHpatch I submitted https://github.com/minetest/minetest/pull/11515), this is nolonger the case --- ContentDB and Guix can be used together.
I tested installing mods with both Minetest's built-in installer and guix. They canbe used together.
Toggle quote (4 lines)> I recommend adding a button and core.open_url call to the guix dialog that replaces> the content store. It should link to a page describing how to install mods using guix,> and how to allow use of ContentDB again if the user desires
ContentDB and mods installed with guix can be used together with the revised patches.It would be useful though to add some kind of dialog or something, telling the userthat mods can be installed with guix, and how to do so.
Toggle quote (2 lines)> Anyway, sorry for being critical - it's great to see more distro support and integration
Greetings,Maxime (aka maximed aka emixa-d).
-----BEGIN PGP SIGNATURE-----
iI0EABYKADUWIQTB8z7iDFKP233XAR9J4+4iGRcl7gUCYQxT1RccbWF4aW1lZGV2b3NAdGVsZW5ldC5iZQAKCRBJ4+4iGRcl7hH5AP0abbCPcvJAOeEqQE8r094M/CTBAGxqiqRcFjgawb1FPAEAxgjkosWm1zDCZ8tDT6YfodqUe9zrSmNo0jtY156Vugo==dI9n-----END PGP SIGNATURE-----

M
M
Maxime Devos wrote on 7 Aug 20:31 +0200
Re: [PATCH 06/20] guix: Add ContentDB importer.
e534dbff9977126289db0c0eb6cb1281613a877b.camel@telenet.be
Leo Prikler schreef op do 05-08-2021 om 18:41 [+0200]:
Toggle quote (31 lines)> Hi,> > Am Montag, den 02.08.2021, 17:50 +0200 schrieb Maxime Devos:> > * guix/import/contentdb.scm: New file.> > * guix/scripts/import/contentdb.scm: New file.> > * tests/contentdb.scm: New file.> > * Makefile.am (MODULES, SCM_TESTS): Register them.> > * po/guix/POTFILES.in: Likewise.> > * doc/guix.texi (Invoking guix import): Document it.> > [...]> > diff --git a/doc/guix.texi b/doc/guix.texi> > index 43c248234d..d06c9b73c5 100644> > --- a/doc/guix.texi> > +++ b/doc/guix.texi> > @@ -11313,6 +11313,31 @@ and generate package expressions for all> > those packages that are not yet> > in Guix.> > @end table> > > > +@item contentdb> > +@cindex ContentDB> > +Import metadata from @uref{https://content.minetest.net, ContentDB}.> > +Information is taken from the JSON-formatted metadata provided> > through> > +@uref{https://content.minetest.net/help/api/, ContentDB's API} and> > +includes most relevant information, including dependencies. There> > are> > +some caveats, however. The license information on ContentDB does> > not> > +distinguish between GPLvN-only and GPLvN-or-later.
ContentDB uses SPDX license identifiers now, and distinguishes betweenGPL-N-only and GPL-N-or-later, so I adjusted the documentation appropriately.
Toggle quote (7 lines)> > The commit id is> > +sometimes missing. The descriptions are in the Markdown format, but> > +Guix uses Texinfo instead. Texture packs and subgames are> > unsupported.> What is the "commit id"? Is it the hash? A tag? Anything that> resolves to a commit?
It's the SHA-1 of the Git commit. I changes this to ‘the commit's SHA-1’.
Toggle quote (3 lines)> Also, since ContentDB sounds fairly generic (a database of content?),> perhaps we ought to call this the "minetest" importer instead?
Technically, minetest has another mod repository as well:https://bower.minetest.org/. It's unmoderated though, andhttps://content.minetest.net has some moderation and seems more‘official’ (it's integrated in Minetest itself). I replaced(guix import contentdb) with (guix import minetest), likewisefor (guix script import minetest) and tests/minetest.scm.
Toggle quote (16 lines)> > +;; 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) ;> > natural | #f> This comment and some others like it seem to simply be repeating> already present information. Is there a use for them? Should we> instead provide a third argument on every field to verify/enforce the> type?
I first added the ‘; natural-or-false’. I only added the procedure"natural-false" later. Indeed, ‘; natural-or-false’ is redundant.I removed the redundant ones in the revised patch.
I don't think there is need to verify types for each field.Most aren't used by Guix. If a type check would fail, that wouldpresumably mean the type check guix is incorrect (or not up-to-date).Except for perhaps a backtrace, ill-typed fields are harmless.
Toggle quote (11 lines)> > +(define (contentdb-fetch author name)> > + "Return a <package> record for package NAME by AUTHOR, or #f on> > failure."> > + (and=> (json-fetch> > + (string-append (%contentdb-api) "packages/" author "/"> > name "/"))> > + json->package))> Is there a reason for author and name to be separate keys? For me it> makes more sense to take AUTHOR/NAME as a singular search string from> users and then perform queries based on that.
Not really actually, AUTHOR tends to go togehter with NAME except forsome exceptions. I modified the code such that AUTHOR/NAME is a singlestring. It simplified code somewhat.
Toggle quote (4 lines)> If ContentDB allows> searching, we might also resolve NAME to a singular package where> possible and otherwise error out, telling the user to choose one.
ContentDB allows searching. I wrote some a procedure 'elaborate-contentdb-name'used by (guix scripts import contentdb) that resolves "mesecons" to "Jeija/mesecons",using the search API and added some tests. If there are multiple candidates,the one with the highest ‘score’ is choosen (alternatively, --sort=downloads canbe used instead).
Toggle quote (16 lines)> > +(define (important-dependencies dependencies author name)> > + (define dependency-list> > + (assoc-ref dependencies (string-append author "/" name)))> > + (filter-map> > + (lambda (dependency)> > + (and (not (dependency-optional? dependency))> > + ;; "default" must be provided by the 'subgame' in use> > + ;; and does not refer to a specific minetest mod.> > + ;; "doors", "bucket" ... are provided by the default> > minetest> > + ;; subgame.> > + (not (member (dependency-name dependency)> > + '("default" "doors" "beds" "bucket" "doors"> > "farming"> > + "flowers" "stairs" "xpanes")))
I tested this some more, and it appears that some mods depend on "dyes",which is part of the default Minetest game, so I added all the modsprovided by the default (sub?)game. The list began looking a littlelong, so I replaced it with a hash table.
Toggle quote (14 lines)> > + ;; Dependencies often have only one implementation.> > + (let* ((/name (string-append "/" (dependency-name> > dependency)))> > + (likewise-named-implementations> > + (filter (cut string-suffix? /name <>)> > + (dependency-packages dependency)))> > + (implementation> > + (and (not (null? likewise-named-implementations))> > + (first likewise-named-implementations))))> > + (and implementation> > + (apply cons (string-split implementation #\/))))))> > + dependency-list))> What exactly does the likewise-named-implementations bit do here?
The list returned by 'dependency-packages' not only contains the modwe need, but possibly also various ‘subgames’ that include that mod.Filtering on '/name' filters out these subgames we don't need.
Also, theoretically another mod could implement the same interface.The filtering would filter out the alternative implementations.
Anyway, I changes the implementation a bit. It now explicitelyfilters out ‘subgames’ and ‘texture packs’ using the ‘package-mod?’procedure. The resulting list tends to consist of only a singleelement. If it consists of multiple, the one with the highest score(or the one with the highest download count, depending on --sort)will be choosen (and a warning is printed).
Toggle quote (8 lines)> > +;; A list of license names is available at> > +;; <https://content.minetest.net/api/licenses/>;;.> > +(define (string->license str)> > + "Convert the string STR into a license object." [...]> The link mentions, that ContentDB now supports all SPDX identifiers. > Do we have a SPDX->Guix converter lying around in some other importer> that we could use as default case here (especially w.r.t. "or later")
There's a a converter in (guix import utils): spdx-string->license.The old license identifiers appear to be removed, now only SPDX informationis available. I modified the code to use spdx->string-license and removedstring->license.
It turns out it does not recognise GPL-N-only and GPL-N-or-later,so I added a patch ‘import/utils: Recognise GPL-3.0-or-later and friends.’.
I tried implementing "guix refresh -t minetest ...". It seems to work, butrequires some changes to (guix upstream) that needs some more work, so I left itout of the revised patch set. The refresher needs to know the author name(or perform extra HTTP requests), so I added 'upstream-name' the package properties.
The revised patch series is attached. It can also be found athttps://notabug.org/maximed/guix-gnunet/src/minetest-2. It includesthe latest MINETEST_MOD_PATH patch. I'll make the patch to export more things in(guix build utils) later (for core-updates).
reetings,Maxime.
From 292dce14ea4811f1554965d83af5e33687cd00b7 Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sat, 31 Jul 2021 14:50:32 +0200Subject: [PATCH 01/20] gnu: minetest: Respect --without-tests.
* gnu/packages/games.scm (minetest)[arguments]<#:phases>{check}: Use 'tests?' instead of ',(%current-target-system)'. Remove trailing #t.--- gnu/packages/games.scm | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
Toggle diff (23 lines)diff --git a/gnu/packages/games.scm b/gnu/packages/games.scmindex 8c6b5523f1..3e7086b398 100644--- a/gnu/packages/games.scm+++ b/gnu/packages/games.scm@@ -3590,13 +3590,12 @@ match, cannon keep, and grave-itation pit.") (string-append (getcwd) "/games")) ; for check #t)) (replace 'check- (lambda _+ (lambda* (#:key tests? #:allow-other-keys) ;; Thanks to our substitutions, the tests should also run ;; when invoked on the target outside of `guix build'.- (unless ,(%current-target-system)+ (when tests? (setenv "HOME" "/tmp")- (invoke "src/minetest" "--run-unittests"))- #t)))))+ (invoke "src/minetest" "--run-unittests"))))))) (native-search-paths (list (search-path-specification (variable "MINETEST_SUBGAME_PATH")-- 2.32.0
From 54222f167107e36cb76f93c551aaee0659d17b40 Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sat, 31 Jul 2021 18:08:44 +0200Subject: [PATCH 02/20] gnu: minetest: Search for mods in MINETEST_MOD_PATH.
* gnu/packages/patches/Add-environment-variable-MINETEST_MOD_PATH.patch: New file.* gnu/packages/games.scm (minetest)[source]{patches}: Add it. (minetest)[native-search-paths]: Add "MINETEST_MOD_PATH".* gnu/local.mk (dist_patch_DATA): Add the patch.--- gnu/local.mk | 1 + gnu/packages/games.scm | 8 +- ...vironment-variable-MINETEST_MOD_PATH.patch | 156 ++++++++++++++++++ 3 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 gnu/packages/patches/Add-environment-variable-MINETEST_MOD_PATH.patch
Toggle diff (202 lines)diff --git a/gnu/local.mk b/gnu/local.mkindex c80a9af78c..d96d4e3dbc 100644--- a/gnu/local.mk+++ b/gnu/local.mk@@ -801,6 +801,7 @@ dist_patch_DATA = \ %D%/packages/patches/abseil-cpp-fix-gtest.patch \ %D%/packages/patches/abseil-cpp-fix-strerror_test.patch \ %D%/packages/patches/adb-add-libraries.patch \+ %D%/packages/patches/Add-environment-variable-MINETEST_MOD_PATH.patch \ %D%/packages/patches/aegis-constness-error.patch \ %D%/packages/patches/aegis-perl-tempdir1.patch \ %D%/packages/patches/aegis-perl-tempdir2.patch \diff --git a/gnu/packages/games.scm b/gnu/packages/games.scmindex 3e7086b398..48d46a0379 100644--- a/gnu/packages/games.scm+++ b/gnu/packages/games.scm@@ -3553,6 +3553,9 @@ match, cannon keep, and grave-itation pit.") (base32 "062ilb7s377q3hwfhl8q06vvcw2raydz5ljzlzwy2dmyzmdcndb8")) (modules '((guix build utils)))+ (patches+ (search-patches+ "Add-environment-variable-MINETEST_MOD_PATH.patch")) (snippet '(begin ;; Delete bundled libraries.@@ -3599,7 +3602,10 @@ match, cannon keep, and grave-itation pit.") (native-search-paths (list (search-path-specification (variable "MINETEST_SUBGAME_PATH")- (files '("share/minetest/games")))))+ (files '("share/minetest/games")))+ (search-path-specification+ (variable "MINETEST_MOD_PATH")+ (files '("share/minetest/mods"))))) (native-inputs `(("pkg-config" ,pkg-config))) (inputsdiff --git a/gnu/packages/patches/Add-environment-variable-MINETEST_MOD_PATH.patch b/gnu/packages/patches/Add-environment-variable-MINETEST_MOD_PATH.patchnew file mode 100644index 0000000000..a74034a2c5--- /dev/null+++ b/gnu/packages/patches/Add-environment-variable-MINETEST_MOD_PATH.patch@@ -0,0 +1,156 @@+From d10ea2ad7efc2364a8a2007b4c6d3e85511e2f84 Mon Sep 17 00:00:00 2001+From: Maxime Devos <maximedevos@telenet.be>+Date: Tue, 3 Aug 2021 01:00:23 +0200+Subject: [PATCH] Add environment variable MINETEST_MOD_PATH++This adds an environment variable MINETEST_MOD_PATH.+When it exists, Minetest will look there for mods+in addition to ~/.minetest/mods/. Mods can still be+installed to ~/.minetest/mods/ with the built-in installer.++With thanks to Leo Prikler.+---+ builtin/mainmenu/pkgmgr.lua | 7 +++----+ doc/menu_lua_api.txt | 8 +++++++-+ src/content/subgames.cpp | 11 ++++++++++++ src/script/lua_api/l_mainmenu.cpp | 23 ++++++++++++++++++++++++ src/script/lua_api/l_mainmenu.h | 2 +++ 5 files changed, 46 insertions(+), 5 deletions(-)++diff --git a/builtin/mainmenu/pkgmgr.lua b/builtin/mainmenu/pkgmgr.lua+index 787936e31..d8fba0ebe 100644+--- a/builtin/mainmenu/pkgmgr.lua++++ b/builtin/mainmenu/pkgmgr.lua+@@ -682,10 +682,9 @@ function pkgmgr.preparemodlist(data)+ local game_mods = {}+ + --read global mods+- local modpath = core.get_modpath()+-+- if modpath ~= nil and+- modpath ~= "" then++ local modpaths = core.get_modpaths()++ --XXX what was ‘modpath ~= ""’ and ‘modpath ~= nil’ for?++ for _,modpath in ipairs(modpaths) do+ get_mods(modpath,global_mods)+ end+ +diff --git a/doc/menu_lua_api.txt b/doc/menu_lua_api.txt+index b3975bc1d..132444b14 100644+--- a/doc/menu_lua_api.txt++++ b/doc/menu_lua_api.txt+@@ -218,7 +218,13 @@ Package - content which is downloadable from the content db, may or may not be i+ * returns path to global user data,+ the directory that contains user-provided mods, worlds, games, and texture packs.+ * core.get_modpath() (possible in async calls)+- * returns path to global modpath++ * returns path to global modpath, where mods can be installed++* core.get_modpaths() (possible in async calls)++ * returns list of paths to global modpaths, where mods have been installed++++ The difference with "core.get_modpath" is that no mods should be installed in these++ directories by Minetest -- they might be read-only.+++ * core.get_clientmodpath() (possible in async calls)+ * returns path to global client-side modpath+ * core.get_gamepath() (possible in async calls)+diff --git a/src/content/subgames.cpp b/src/content/subgames.cpp+index e9dc609b0..d73f95a1f 100644+--- a/src/content/subgames.cpp++++ b/src/content/subgames.cpp+@@ -61,6 +61,12 @@ std::string getSubgamePathEnv()+ return subgame_path ? std::string(subgame_path) : "";+ }+ ++std::string getModPathEnv()++{++ char *mod_path = getenv("MINETEST_MOD_PATH");++ return mod_path ? std::string(mod_path) : "";++}+++ SubgameSpec findSubgame(const std::string &id)+ {+ if (id.empty())+@@ -110,6 +116,11 @@ SubgameSpec findSubgame(const std::string &id)+ std::set<std::string> mods_paths;+ if (!user_game)+ mods_paths.insert(share + DIR_DELIM + "mods");++++ Strfnd mod_search_paths(getModPathEnv());++ while (!mod_search_paths.at_end())++ mods_paths.insert(mod_search_paths.next(PATH_DELIM));+++ if (user != share || user_game)+ mods_paths.insert(user + DIR_DELIM + "mods");+ +diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp+index 3e9709bde..903ac3a22 100644+--- a/src/script/lua_api/l_mainmenu.cpp++++ b/src/script/lua_api/l_mainmenu.cpp+@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,+ #include "lua_api/l_internal.h"+ #include "common/c_content.h"+ #include "cpp_api/s_async.h"++#include "util/strfnd.h"+ #include "gui/guiEngine.h"+ #include "gui/guiMainMenu.h"+ #include "gui/guiKeyChangeMenu.h"+@@ -502,6 +503,26 @@ int ModApiMainMenu::l_get_modpath(lua_State *L)+ return 1;+ }+ ++/******************************************************************************/++int ModApiMainMenu::l_get_modpaths(lua_State *L)++{++ const char *c_modpath = getenv("MINETEST_MOD_PATH");++ if (c_modpath == NULL)++ c_modpath = "";++ int index = 1;++ lua_newtable(L);++ Strfnd mod_search_paths{std::string(c_modpath)};++ while (!mod_search_paths.at_end()) {++ std::string component = mod_search_paths.next(PATH_DELIM);++ lua_pushstring(L, component.c_str());++ lua_rawseti(L, -2, index);++ index++;++ }++ ModApiMainMenu::l_get_modpath(L);++ lua_rawseti(L, -2, index);++ return 1;++}+++ /******************************************************************************/+ int ModApiMainMenu::l_get_clientmodpath(lua_State *L)+ {+@@ -949,6 +970,7 @@ void ModApiMainMenu::Initialize(lua_State *L, int top)+ API_FCT(get_mapgen_names);+ API_FCT(get_user_path);+ API_FCT(get_modpath);++ API_FCT(get_modpaths);+ API_FCT(get_clientmodpath);+ API_FCT(get_gamepath);+ API_FCT(get_texturepath);+@@ -983,6 +1005,7 @@ void ModApiMainMenu::InitializeAsync(lua_State *L, int top)+ API_FCT(get_mapgen_names);+ API_FCT(get_user_path);+ API_FCT(get_modpath);++ API_FCT(get_modpaths);+ API_FCT(get_clientmodpath);+ API_FCT(get_gamepath);+ API_FCT(get_texturepath);+diff --git a/src/script/lua_api/l_mainmenu.h b/src/script/lua_api/l_mainmenu.h+index 33ac9e721..a6a54a2cb 100644+--- a/src/script/lua_api/l_mainmenu.h++++ b/src/script/lua_api/l_mainmenu.h+@@ -112,6 +112,8 @@ class ModApiMainMenu: public ModApiBase+ + static int l_get_modpath(lua_State *L);+ ++ static int l_get_modpaths(lua_State *L);+++ static int l_get_clientmodpath(lua_State *L);+ + static int l_get_gamepath(lua_State *L);+-- +2.32.0+-- 2.32.0
From f5148ad853b113db84634912c3eaa936d689eb22 Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sat, 31 Jul 2021 18:32:50 +0200Subject: [PATCH 03/20] gnu: minetest: New package module.
Aside from the 'minetest-topic' procedure which will be usedfor the 'home-page' field of some packages, this module iscurrently empty. The 'contentdb' importer defined in thefollowing patches will be used to populate this module.
* gnu/packages/minetest.scm: New file.* gnu/local.mk (GNU_SYSTEM_MODULES): Add it.--- gnu/local.mk | 1 + gnu/packages/minetest.scm | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 gnu/packages/minetest.scm
Toggle diff (46 lines)diff --git a/gnu/local.mk b/gnu/local.mkindex d96d4e3dbc..5de08b1b09 100644--- a/gnu/local.mk+++ b/gnu/local.mk@@ -383,6 +383,7 @@ GNU_SYSTEM_MODULES = \ %D%/packages/mercury.scm \ %D%/packages/mes.scm \ %D%/packages/messaging.scm \+ %D%/packages/minetest.scm \ %D%/packages/mingw.scm \ %D%/packages/microcom.scm \ %D%/packages/moe.scm \diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmnew file mode 100644index 0000000000..f8aca3005c--- /dev/null+++ b/gnu/packages/minetest.scm@@ -0,0 +1,26 @@+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>+;;; 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 (gnu packages minetest)+ #:use-module (guix packages)+ #:use-module (guix git-download)+ #:use-module (guix build-system minetest)+ #:use-module ((guix licenses) #:prefix license:))++(define-public (minetest-topic topic-id)+ "Return an URL (as a string) pointing to the forum topic with+numeric identifier TOPIC-ID on the official Minetest forums."+ (string-append "https://forum.minetest.net/viewtopic.php?t="+ (number->string topic-id)))-- 2.32.0
From 93aa8e1976e762d30be70aef6d5c50b1d06ca4be Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sat, 31 Jul 2021 13:52:39 +0200Subject: [PATCH 04/20] build-system: Add 'minetest-mod-build-system'.
* guix/build-system/minetest.scm: New module.* guix/build/minetest-build-system.scm: Likewise.* Makefile.am (MODULES): Add them.* doc/guix.texi (Build Systems): Document 'minetest-mod-build-system'.--- Makefile.am | 2 + doc/guix.texi | 8 + guix/build-system/minetest.scm | 99 ++++++++++++ guix/build/minetest-build-system.scm | 225 +++++++++++++++++++++++++++ 4 files changed, 334 insertions(+) create mode 100644 guix/build-system/minetest.scm create mode 100644 guix/build/minetest-build-system.scm
Toggle diff (377 lines)diff --git a/Makefile.am b/Makefile.amindex d5ec909213..f4439ce93b 100644--- a/Makefile.am+++ b/Makefile.am@@ -141,6 +141,7 @@ MODULES = \ guix/build-system/go.scm \ guix/build-system/meson.scm \ guix/build-system/minify.scm \+ guix/build-system/minetest.scm \ guix/build-system/asdf.scm \ guix/build-system/copy.scm \ guix/build-system/glib-or-gtk.scm \@@ -203,6 +204,7 @@ MODULES = \ guix/build/gnu-dist.scm \ guix/build/guile-build-system.scm \ guix/build/maven-build-system.scm \+ guix/build/minetest-build-system.scm \ guix/build/node-build-system.scm \ guix/build/perl-build-system.scm \ guix/build/python-build-system.scm \diff --git a/doc/guix.texi b/doc/guix.texiindex b3c16e6507..d44ecc2005 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -7895,6 +7895,14 @@ declaration. Its default value is @code{(default-maven-plugins)} which is also exported. @end defvr +@defvr {Scheme Variable} minetest-mod-build-system+This variable is exported by @code{(guix build-system minetest)}. It+implements a build procedure for @uref{https://www.minetest.net, Minetest}+mods, which consists of copying Lua code, images and other resources to+the location Minetest searches for mods. The build system also minimises+PNG images and verifies that Minetest can load the mod without errors.+@end defvr+ @defvr {Scheme Variable} minify-build-system This variable is exported by @code{(guix build-system minify)}. It implements a minification procedure for simple JavaScript packages.diff --git a/guix/build-system/minetest.scm b/guix/build-system/minetest.scmnew file mode 100644index 0000000000..f33e97559d--- /dev/null+++ b/guix/build-system/minetest.scm@@ -0,0 +1,99 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>+;;;+;;; 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 build-system minetest)+ #:use-module (guix build-system copy)+ #:use-module (guix build-system gnu)+ #:use-module (guix build-system)+ #:use-module (guix utils)+ #:export (minetest-mod-build-system))++;;+;; Build procedure for minetest mods. This is implemented as an extension+;; of ‘copy-build-system’.+;;+;; Code:++;; Lazily resolve the bindings to avoid circular dependencies.+(define (default-optipng)+ ;; Lazily resolve the binding to avoid a circular dependency.+ (module-ref (resolve-interface '(gnu packages image)) 'optipng))++(define (default-minetest)+ (module-ref (resolve-interface '(gnu packages games)) 'minetest))++(define (default-xvfb-run)+ (module-ref (resolve-interface '(gnu packages xorg)) 'xvfb-run))++(define %minetest-build-system-modules+ ;; Build-side modules imported by default.+ `((guix build minetest-build-system)+ ,@%copy-build-system-modules))++(define %default-modules+ ;; Modules in scope in the build-side environment.+ '((guix build gnu-build-system)+ (guix build minetest-build-system)+ (guix build utils)))++(define (standard-minetest-packages)+ "Return the list of (NAME PACKAGE OUTPUT) or (NAME PACKAGE) tuples of+standard packages used as implicit inputs of the Minetest build system."+ `(("xvfb-run" ,(default-xvfb-run))+ ("optipng" ,(default-optipng))+ ("minetest" ,(default-minetest))+ ,@(filter (lambda (input)+ (member (car input)+ '("libc" "tar" "gzip" "bzip2" "xz" "locales")))+ (standard-packages))))++(define* (lower-mod name #:key (implicit-inputs? #t) #:allow-other-keys+ #:rest arguments)+ (define lower (build-system-lower gnu-build-system))+ (apply lower+ name+ (substitute-keyword-arguments arguments+ ;; minetest-mod-build-system adds implicit inputs by itself,+ ;; so don't let gnu-build-system add its own implicit inputs+ ;; as well.+ ((#:implicit-inputs? implicit-inputs? #t)+ #f)+ ((#:implicit-cross-inputs? implicit-cross-inputs? #t)+ #f)+ ((#:imported-modules imported-modules %minetest-build-system-modules)+ imported-modules)+ ((#:modules modules %default-modules)+ modules)+ ((#:phases phases '%standard-phases)+ phases)+ ;; Ensure nothing sneaks into the closure.+ ((#:allowed-references allowed-references '())+ allowed-references)+ ;; Add the implicit inputs.+ ((#:native-inputs native-inputs '())+ (if implicit-inputs?+ (append native-inputs (standard-minetest-packages))+ native-inputs)))))++(define minetest-mod-build-system+ (build-system+ (name 'minetest-mod)+ (description "The build system for minetest mods")+ (lower lower-mod)))++;;; minetest.scm ends herediff --git a/guix/build/minetest-build-system.scm b/guix/build/minetest-build-system.scmnew file mode 100644index 0000000000..b051d9c288--- /dev/null+++ b/guix/build/minetest-build-system.scm@@ -0,0 +1,225 @@+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>+;;;+;;; 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 build minetest-build-system)+ #:use-module (guix build utils)+ #:use-module (srfi srfi-1)+ #:use-module (ice-9 format)+ #:use-module (ice-9 match)+ #:use-module (ice-9 rdelim)+ #:use-module (ice-9 receive)+ #:use-module (ice-9 regex)+ #:use-module ((guix build gnu-build-system) #:prefix gnu:)+ #:use-module ((guix build copy-build-system) #:prefix copy:)+ #:export (%standard-phases+ mod-install-plan minimise-png read-mod-name check))++;; (guix build copy-build-system) does not export 'install'.+(define copy:install+ (assoc-ref copy:%standard-phases 'install))++(define (mod-install-plan mod-name)+ `(("." ,(string-append "share/minetest/mods/" mod-name)+ ;; Only install files that will actually be used at run time.+ ;; This can save a little disk space.+ ;;+ ;; See <https://github.com/minetest/minetest/blob/master/doc/lua_api.txt>+ ;; for an incomple list of files that can be found in mods.+ #:include ("mod.conf" "modpack.conf" "settingtypes.txt" "depends.txt"+ "description.txt")+ #:include-regexp (".lua$" ".png$" ".ogg$" ".obj$" ".b3d$" ".tr$"+ ".mts$"))))++(define* (guess-mod-name #:key inputs #:allow-other-keys)+ "Try to determine the name of the mod or modpack that is being built.+If it is unknown, make an educated guess."+ ;; Minetest doesn't care about the directory names in "share/minetest/mods"+ ;; so there is no technical problem if the directory names don't match+ ;; the mod names. The directory can appear in the GUI if the modpack+ ;; doesn't have the 'name' set though, so try to make the guess.+ (define (guess)+ (let* ((source (assoc-ref inputs "source"))+ (file-name (basename source))+ ;; The "minetest-" prefix is not informative, so strip it.+ (file-name (if (string-prefix? "minetest-" file-name)+ (substring file-name (string-length "minetest-"))+ file-name))+ ;; Strip "-checkout" suffixes of git checkouts.+ (file-name (if (string-suffix? "-checkout" file-name)+ (substring file-name+ 0+ (- (string-length file-name)+ (string-length "-minetest")))+ file-name))+ (first-dot (string-index file-name #\.))+ ;; If the source code is in an archive (.tar.gz, .zip, ...),+ ;; strip the extension.+ (file-name (if first-dot+ (substring file-name 0 first-dot)+ file-name)))+ (format (current-error-port)+ "warning: the modpack ~a did not set 'name' in 'modpack.conf'~%"+ file-name)+ file-name))+ (cond ((file-exists? "mod.conf")+ (read-mod-name "mod.conf"))+ ((file-exists? "modpack.conf")+ (read-mod-name "modpack.conf" guess))+ (#t (guess))))++(define* (install #:key inputs #:allow-other-keys #:rest arguments)+ (apply copy:install+ #:install-plan (mod-install-plan (apply guess-mod-name arguments))+ arguments))++(define %png-magic-bytes+ ;; Magic bytes of PNG images, see ‘5.2 PNG signatures’ in+ ;; ‘Portable Network Graphics (PNG) Specification (Second Edition)’+ ;; on <https://www.w3.org/TR/PNG/>.+ #vu8(137 80 78 71 13 10 26 10))++(define png-file?+ ((@@ (guix build utils) file-header-match) %png-magic-bytes))++(define* (minimise-png #:key inputs native-inputs #:allow-other-keys)+ "Minimise PNG images found in the working directory."+ (define optipng (which "optipng"))+ (define (optimise image)+ (format #t "Optimising ~a~%" image)+ (make-file-writable (dirname image))+ (make-file-writable image)+ (define old-size (stat:size (stat image)))+ ;; The mod "technic" has a file "technic_music_player_top.png" that+ ;; actually is a JPEG file, see+ ;; <https://github.com/minetest-mods/technic/issues/590>.+ (if (png-file? image)+ (invoke optipng "-o4" "-quiet" image)+ (format #t "warning: skipping ~a because it's not actually a PNG image~%"+ image))+ (define new-size (stat:size (stat image)))+ (values old-size new-size))+ (define files (find-files "." ".png$"))+ (let loop ((total-old-size 0)+ (total-new-size 0)+ (images (find-files "." ".png$")))+ (cond ((pair? images)+ (receive (old-size new-size)+ (optimise (car images))+ (loop (+ total-old-size old-size)+ (+ total-new-size new-size)+ (cdr images))))+ ((= total-old-size 0)+ (format #t "There were no PNG images to minimise."))+ (#t+ (format #t "Minimisation reduced size of images by ~,2f% (~,2f MiB to ~,2f MiB)~%"+ (* 100.0 (- 1 (/ total-new-size total-old-size)))+ (/ total-old-size (expt 1024 2))+ (/ total-new-size (expt 1024 2)))))))++(define name-regexp (make-regexp "^name[ ]*=(.+)$"))++(define* (read-mod-name mod.conf #:optional not-found)+ "Read the name of a mod from MOD.CONF. If MOD.CONF+does not have a name field and NOT-FOUND is #false, raise an+error. If NOT-FOUND is TRUE, call NOT-FOUND instead."+ (call-with-input-file mod.conf+ (lambda (port)+ (let loop ()+ (define line (read-line port))+ (if (eof-object? line)+ (if not-found+ (not-found)+ (error "~a does not have a 'name' field" mod.conf))+ (let ((match (regexp-exec name-regexp line)))+ (if (regexp-match? match)+ (string-trim-both (match:substring match 1) #\ )+ (loop))))))))++(define* (check #:key outputs tests? #:allow-other-keys)+ "Test whether the mod loads. The mod must first be installed first."+ (define (all-mod-names directories)+ (append-map+ (lambda (directory)+ (map read-mod-name (find-files directory "mod.conf")))+ directories))+ (when tests?+ (mkdir "guix_testworld")+ ;; Add the mod to the mod search path, such that Minetest can find it.+ (setenv "MINETEST_MOD_PATH"+ (list->search-path-as-string+ (cons+ (string-append (assoc-ref outputs "out") "/share/minetest/mods")+ (search-path-as-string->list+ (or (getenv "MINETEST_MOD_PATH") "")))+ ":"))+ (with-directory-excursion "guix_testworld"+ (setenv "HOME" (getcwd))+ ;; Create a world in which all mods are loaded.+ (call-with-output-file "world.mt"+ (lambda (port)+ (display+ "gameid = minetest+world_name = guix_testworld+backend = sqlite3+player_backend = sqlite3+auth_backend = sqlite3+" port)+ (for-each+ (lambda (mod)+ (format port "load_mod_~a = true~%" mod))+ (all-mod-names (search-path-as-string->list+ (getenv "MINETEST_MOD_PATH"))))))+ (receive (port pid)+ ((@@ (guix build utils) open-pipe-with-stderr)+ "xvfb-run" "--" "minetest" "--info" "--world" "." "--go")+ (format #t "Started Minetest with all mods loaded for testing~%")+ ;; Scan the output for error messages.+ ;; When the player has joined the server, stop minetest.+ (define (error? line)+ (and (string? line)+ (string-contains line ": ERROR[")))+ (define (stop? line)+ (and (string? line)+ (string-contains line "ACTION[Server]: singleplayer [127.0.0.1] joins game.")))+ (let loop ()+ (match (read-line port)+ ((? error? line)+ (error "minetest raised an error: ~a" line))+ ((? stop?)+ (kill pid SIGINT)+ (close-port port)+ (waitpid pid))+ ((? string? line)+ (display line)+ (newline)+ (loop))+ ((? eof-object?)+ (error "minetest didn't start"))))))))++(define %standard-phases+ (modify-phases gnu:%standard-phases+ (delete 'bootstrap)+ (delete 'configure)+ (add-before 'build 'minimise-png minimise-png)+ (delete 'build)+ (delete 'check)+ (replace 'install install)+ ;; The 'check' phase requires the mod to be installed,+ ;; so move the 'check' phase after the 'install' phase.+ (add-after 'install 'check check)))++;;; minetest-build-system.scm ends here-- 2.32.0
From 9858d43e51cdfdbf4ca022399469d99f437bf596 Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Thu, 5 Aug 2021 21:00:41 +0200Subject: [PATCH 05/20] import/utils: Recognise GPL-3.0-or-later and friends.
* guix/import/utils.scm (spdx-string->license): Recognise GPL-N-only and GPL-N-or-later. Likewise for LGPL and AGPL.--- guix/import/utils.scm | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
Toggle diff (57 lines)diff --git a/guix/import/utils.scm b/guix/import/utils.scmindex d817318a91..d1b8076ddd 100644--- a/guix/import/utils.scm+++ b/guix/import/utils.scm@@ -133,8 +133,14 @@ of the string VERSION is replaced by the symbol 'version." ;; Please update guix/licenses.scm when modifying ;; this list to avoid mismatches. (match str+ ;; "GPL-N+" has been deprecated in favour of "GPL-N-or-later".+ ;; "GPL-N" has been deprecated in favour of "GPL-N-only"+ ;; or "GPL-N-or-later" as appropriate. Likewise for LGPL+ ;; and AGPL ("AGPL-1.0" 'license:agpl1) ("AGPL-3.0" 'license:agpl3)+ ("AGPL-3.0-only" 'license:agpl3)+ ("AGPL-3.0-or-later" 'license:agpl3+) ("Apache-1.1" 'license:asl1.1) ("Apache-2.0" 'license:asl2.0) ("BSL-1.0" 'license:boost1.0)@@ -161,11 +167,17 @@ of the string VERSION is replaced by the symbol 'version." ("GFDL-1.3" 'license:fdl1.3+) ("Giftware" 'license:giftware) ("GPL-1.0" 'license:gpl1)+ ("GPL-1.0-only" 'license:gpl1) ("GPL-1.0+" 'license:gpl1+)+ ("GPL-1.0-or-later" 'license:gpl1+) ("GPL-2.0" 'license:gpl2)+ ("GPL-2.0-only" 'license:gpl2) ("GPL-2.0+" 'license:gpl2+)+ ("GPL-2.0-or-later" 'license:gpl2+) ("GPL-3.0" 'license:gpl3)+ ("GPL-3.0-only" 'license:gpl3) ("GPL-3.0+" 'license:gpl3+)+ ("GPL-3.0-or-later" 'license:gpl3+) ("ISC" 'license:isc) ("IJG" 'license:ijg) ("Imlib2" 'license:imlib2)@@ -173,11 +185,17 @@ of the string VERSION is replaced by the symbol 'version." ("IPL-1.0" 'license:ibmpl1.0) ("LAL-1.3" 'license:lal1.3) ("LGPL-2.0" 'license:lgpl2.0)+ ("LGPL-2.0-only" 'license:lgpl2.0) ("LGPL-2.0+" 'license:lgpl2.0+)+ ("LGPL-2.0-or-later" 'license:lgpl2.0+) ("LGPL-2.1" 'license:lgpl2.1)+ ("LGPL-2.1-only" 'license:lgpl2.1) ("LGPL-2.1+" 'license:lgpl2.1+)+ ("LGPL-2.1-or-later" 'license:lgpl2.1+) ("LGPL-3.0" 'license:lgpl3)+ ("LGPL-3.0-only" 'license:lgpl3) ("LGPL-3.0+" 'license:lgpl3+)+ ("LGPL-3.0-or-later" 'license:lgpl3+) ("MPL-1.0" 'license:mpl1.0) ("MPL-1.1" 'license:mpl1.1) ("MPL-2.0" 'license:mpl2.0)-- 2.32.0
From 1ea774e7ff007e60cf612f4f74f656be3de9f1f3 Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sat, 31 Jul 2021 14:44:11 +0200Subject: [PATCH 06/20] guix: Add ContentDB importer.
* guix/import/contentdb.scm: New file.* guix/scripts/import/contentdb.scm: New file.* tests/contentdb.scm: New file.* Makefile.am (MODULES, SCM_TESTS): Register them.* po/guix/POTFILES.in: Likewise.* doc/guix.texi (Invoking guix import): Document it.--- Makefile.am | 3 + doc/guix.texi | 32 +++ guix/import/minetest.scm | 467 +++++++++++++++++++++++++++++++ guix/scripts/import.scm | 3 +- guix/scripts/import/minetest.scm | 117 ++++++++ po/guix/POTFILES.in | 1 + tests/minetest.scm | 355 +++++++++++++++++++++++ 7 files changed, 977 insertions(+), 1 deletion(-) create mode 100644 guix/import/minetest.scm create mode 100644 guix/scripts/import/minetest.scm create mode 100644 tests/minetest.scm
Toggle diff (1056 lines)diff --git a/Makefile.am b/Makefile.amindex f4439ce93b..6243583616 100644--- a/Makefile.am+++ b/Makefile.am@@ -262,6 +262,7 @@ MODULES = \ guix/import/json.scm \ guix/import/kde.scm \ guix/import/launchpad.scm \+ guix/import/minetest.scm \ guix/import/opam.scm \ guix/import/print.scm \ guix/import/pypi.scm \@@ -304,6 +305,7 @@ MODULES = \ guix/scripts/import/go.scm \ guix/scripts/import/hackage.scm \ guix/scripts/import/json.scm \+ guix/scripts/import/minetest.scm \ guix/scripts/import/opam.scm \ guix/scripts/import/pypi.scm \ guix/scripts/import/stackage.scm \@@ -470,6 +472,7 @@ SCM_TESTS = \ tests/import-utils.scm \ tests/inferior.scm \ tests/lint.scm \+ tests/minetest.scm \ tests/modules.scm \ tests/monads.scm \ tests/nar.scm \diff --git a/doc/guix.texi b/doc/guix.texiindex d44ecc2005..47861047eb 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -11314,6 +11314,38 @@ and generate package expressions for all those packages that are not yet in Guix. @end table +@item contentdb+@cindex minetest+@cindex ContentDB+Import metadata from @uref{https://content.minetest.net, ContentDB}.+Information is taken from the JSON-formatted metadata provided through+@uref{https://content.minetest.net/help/api/, ContentDB's API} and+includes most relevant information, including dependencies. There are+some caveats, however. The license information is often incomplete.+The commit's SHA-1 is sometimes missing. The descriptions are in the+Markdown format, but Guix uses Texinfo instead. Texture packs and+subgames are unsupported.++The command below imports metadata for the Mesecons mod by Jeija:++@example+guix import minetest Jeija/mesecons+@end example++The author name can also be left out:++@example+guix import minetest mesecons+@end example++@table @code+@item --recursive+@itemx -r+Traverse the dependency graph of the given upstream package recursively+and generate package expressions for all those packages that are not yet+in Guix.+@end table+ @item cpan @cindex CPAN Import metadata from @uref{https://www.metacpan.org/, MetaCPAN}.diff --git a/guix/import/minetest.scm b/guix/import/minetest.scmnew file mode 100644index 0000000000..5728f4613a--- /dev/null+++ b/guix/import/minetest.scm@@ -0,0 +1,467 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>+;;;+;;; 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 receive)+ #:use-module (ice-9 threads)+ #:use-module (ice-9 hash-table)+ #:use-module (srfi srfi-1)+ #:use-module (srfi srfi-2)+ #:use-module (srfi srfi-11)+ #:use-module (srfi srfi-26)+ #:use-module (guix utils)+ #:use-module (guix ui)+ #:use-module (guix i18n)+ #:use-module (guix memoization)+ #:use-module (guix serialization)+ #:use-module (guix import utils)+ #:use-module (guix import json)+ #:use-module ((gcrypt hash) #:select (open-sha256-port port-sha256))+ #:use-module (json)+ #:use-module (guix base32)+ #:use-module (guix git)+ #:use-module (guix store)+ #:export (%default-sort-key+ %contentdb-api+ json->package+ contentdb-fetch+ elaborate-contentdb-name+ minetest->guix-package+ minetest-recursive-import+ sort-packages))++;; 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 (package-author/name package)+ "Given a <package> object, return the corresponding AUTHOR/NAME string."+ (string-append (package-author package) "/" (package-name package)))++(define (package/keys-author/name package)+ "Given a <package/keys> object, return the corresponding AUTHOR/NAME string."+ (string-append (package/keys-author package)+ "/" (package/keys-name package)))++(define (contentdb->package-name name)+ "Given the 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 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-author/name one))+ ((too . many)+ (warning (G_ "~a is ambigious, presuming ~a (other options include: ~a)~%")+ name (package/keys-author/name too)+ (map package/keys-author/name many))+ (package/keys-author/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+be \"mod\", \"game\" or \"txp\", restricting thes search results to+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)))++;; XXX adapted from (guix scripts hash)+(define (file-hash file select? recursive?)+ ;; Compute the hash of FILE.+ (if recursive?+ (let-values (((port get-hash) (open-sha256-port)))+ (write-file file port #:select? select?)+ (force-output port)+ (get-hash))+ (call-with-input-file file port-sha256)))+;; XXX likewise.+(define (vcs-file? file stat)+ (case (stat:type stat)+ ((directory)+ (member (basename file) '(".bzr" ".git" ".hg" ".svn" "CVS")))+ ((regular)+ ;; Git sub-modules have a '.git' file that is a regular text file.+ (string=? (basename file) ".git"))+ (else+ #f)))++(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->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+ (file-hash+ (download-git-repository repository `(commit . ,commit))+ (negate vcs-file?) #t)))))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ ,@(maybe-propagated-inputs+ (map (compose contentdb->package-name author/name->name) inputs))+ (home-page ,home-page)+ (synopsis ,(delete-cr synopsis))+ (description ,(delete-cr description))+ (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)))++;; 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))+ (filter-map+ (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-author/name package))+ ((too . many)+ (warning+ (G_ "The dependency ~a of ~a has multiple different implementations ~a.~%")+ (dependency-name dependency)+ author/name+ (map package-author/name sorted-mods))+ (match sort+ ("score"+ (warning+ (G_ "The implementation with the highest score will be choosen!~%")))+ ("downloads"+ (warning+ (G_ "The implementation that has been downloaded the most will be choosen!~%"))))+ (package-author/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))++(define* (%minetest->guix-package author/name #:key (sort %default-sort-key))+ "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+ (release-title release) ; version+ (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))+ (define* (minetest->guix-package* author/name #:key repo version)+ (minetest->guix-package author/name #:sort sort))+ (recursive-import author/name+ #:repo->guix-package minetest->guix-package*+ #:guix-name+ (compose contentdb->package-name author/name->name)))diff --git a/guix/scripts/import.scm b/guix/scripts/import.scmindex f53d1ac1f4..b369a362d0 100644--- a/guix/scripts/import.scm+++ b/guix/scripts/import.scm@@ -77,7 +77,8 @@ rather than \\n." ;;; (define importers '("gnu" "pypi" "cpan" "hackage" "stackage" "egg" "elpa"- "gem" "go" "cran" "crate" "texlive" "json" "opam"))+ "gem" "go" "cran" "crate" "texlive" "json" "opam"+ "minetest")) (define (resolve-importer name) (let ((module (resolve-interfacediff --git a/guix/scripts/import/minetest.scm b/guix/scripts/import/minetest.scmnew file mode 100644index 0000000000..5f204d90fc--- /dev/null+++ b/guix/scripts/import/minetest.scm@@ -0,0 +1,117 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2014 David Thompson <davet@gnu.org>+;;; Copyright © 2018 Ricardo Wurmus <rekado@elephly.net>+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>+;;;+;;; 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 scripts import minetest)+ #:use-module (guix ui)+ #:use-module (guix utils)+ #:use-module (guix scripts)+ #:use-module (guix import minetest)+ #:use-module (guix import utils)+ #:use-module (guix scripts import)+ #:use-module (srfi srfi-1)+ #:use-module (srfi srfi-11)+ #:use-module (srfi srfi-37)+ #:use-module (ice-9 match)+ #:use-module (ice-9 format)+ #:export (guix-import-minetest))++ +;;;+;;; Command-line options.+;;;++(define %default-options+ `((sort . ,%default-sort-key)))++(define (show-help)+ (display (G_ "Usage: guix import minetest AUTHOR/NAME+Import and convert the Minetest mod NAME by AUTHOR from ContentDB.\n"))+ (display (G_ "+ -h, --help display this help and exit"))+ (display (G_ "+ -r, --recursive import packages recursively"))+ (display (G_ "+ -V, --version display version information and exit"))+ (display (G_ "+ --sort=KEY when choosing between multiple implementations,+ choose the one with the highest value for KEY+ (one of \"score\" (standard) or \"downloads\")"))+ (newline)+ (show-bug-report-information))++(define (verify-sort-order sort)+ "Verify SORT can be used to sort mods by."+ (unless (member sort '("score" "downloads" "reviews"))+ (leave (G_ "~a: not a valid key to sort by~%") sort))+ sort)++(define %options+ ;; Specification of the command-line options.+ (cons* (option '(#\h "help") #f #f+ (lambda args+ (show-help)+ (exit 0)))+ (option '(#\V "version") #f #f+ (lambda args+ (show-version-and-exit "guix import minetest")))+ (option '(#\r "recursive") #f #f+ (lambda (opt name arg result)+ (alist-cons 'recursive #t result)))+ (option '("sort") #t #f+ (lambda (opt name arg result)+ (alist-cons 'sort (verify-sort-order arg) result)))+ %standard-import-options))++ +;;;+;;; Entry point.+;;;++(define (guix-import-minetest . args)+ (define (parse-options)+ ;; Return the alist of option values.+ (args-fold* args %options+ (lambda (opt name arg result)+ (leave (G_ "~A: unrecognized option~%") name))+ (lambda (arg result)+ (alist-cons 'argument arg result))+ %default-options))++ (let* ((opts (parse-options))+ (args (filter-map (match-lambda+ (('argument . value)+ value)+ (_ #f))+ (reverse opts))))+ (match args+ ((name)+ (with-error-handling+ (let* ((sort (assoc-ref opts 'sort))+ (author/name (elaborate-contentdb-name name #:sort sort)))+ (if (assoc-ref opts 'recursive)+ ;; Recursive import+ (filter-map package->definition+ (minetest-recursive-import author/name #:sort sort))+ ;; Single import+ (minetest->guix-package author/name #:sort sort)))))+ (()+ (leave (G_ "too few arguments~%")))+ ((many ...)+ (leave (G_ "too many arguments~%"))))))diff --git a/po/guix/POTFILES.in b/po/guix/POTFILES.inindex a3bced1a8f..f25a7b4802 100644--- a/po/guix/POTFILES.in+++ b/po/guix/POTFILES.in@@ -60,6 +60,7 @@ guix/scripts/git.scm guix/scripts/git/authenticate.scm guix/scripts/hash.scm guix/scripts/import.scm+guix/scripts/import/contentdb.scm guix/scripts/import/cran.scm guix/scripts/import/elpa.scm guix/scripts/pull.scmdiff --git a/tests/minetest.scm b/tests/minetest.scmnew file mode 100644index 0000000000..1ef202c0fd--- /dev/null+++ b/tests/minetest.scm@@ -0,0 +1,355 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>+;;;+;;; 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 (test-minetest)+ #:use-module (guix memoization)+ #:use-module (guix import minetest)+ #:use-module (guix import utils)+ #:use-module (guix tests)+ #:use-module (json)+ #:use-module (ice-9 match)+ #:use-module (srfi srfi-1)+ #:use-module (srfi srfi-26)+ #:use-module (srfi srfi-34)+ #:use-module (srfi srfi-64))++ +;; Some procedures for populating a ‘fake’ ContentDB server.++(define* (make-package-sexp #:key+ (guix-name "minetest-foo")+ (home-page "https://example.org/foo")+ (repo "https://example.org/foo.git")+ (synopsis "synopsis")+ (guix-description "description")+ (guix-license+ '(list license:cc-by-sa4.0 license:lgpl3+))+ (inputs '())+ (upstream-name "Author/foo")+ #:allow-other-keys)+ `(package+ (name ,guix-name)+ ;; This is not a proper version number but ContentDB does not include+ ;; version numbers.+ (version "2021-07-25")+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url ,(and (not (eq? repo 'null)) repo))+ (commit #f)))+ (sha256+ (base32 #f))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ ,@(maybe-propagated-inputs inputs)+ (home-page ,home-page)+ (synopsis ,synopsis)+ (description ,guix-description)+ (license ,guix-license)+ (properties+ ,(list 'quasiquote+ `((upstream-name . ,upstream-name))))))++(define* (make-package-json #:key+ (author "Author")+ (name "foo")+ (media-license "CC-BY-SA-4.0")+ (license "LGPL-3.0-or-later")+ (short-description "synopsis")+ (long-description "description")+ (repo "https://example.org/foo.git")+ (website "https://example.org/foo")+ (forums 321)+ (score 987.654)+ (downloads 123)+ (type "mod")+ #:allow-other-keys)+ `(("author" . ,author)+ ("content_warnings" . #())+ ("created_at" . "2018-05-23T19:58:07.422108")+ ("downloads" . ,downloads)+ ("forums" . ,forums)+ ("issue_tracker" . "https://example.org/foo/issues")+ ("license" . ,license)+ ("long_description" . ,long-description)+ ("maintainers" . #("maintainer"))+ ("media_license" . ,media-license)+ ("name" . ,name)+ ("provides" . #("stuff"))+ ("release" . 456)+ ("repo" . ,repo)+ ("score" . ,score)+ ("screenshots" . #())+ ("short_description" . ,short-description)+ ("state" . "APPROVED")+ ("tags" . #("some" "tags"))+ ("thumbnail" . null)+ ("title" . "The name")+ ("type" . ,type)+ ("url" . ,(string-append "https://content.minetest.net/packages/"+ author "/" name "/download/"))+ ("website" . ,website)))++(define* (make-releases-json #:key (commit #f) (title "") #:allow-other-keys)+ `#((("commit" . ,commit)+ ("downloads" . 469)+ ("id" . 8614)+ ("max_minetest_version" . null)+ ("min_minetest_version" . null)+ ("release_date" . "2021-07-25T01:10:23.207584")+ ("title" . "2021-07-25"))))++(define* (make-dependencies-json #:key (author "Author")+ (name "foo")+ (requirements '(("default" #f ())))+ #:allow-other-keys)+ `((,(string-append author "/" name)+ . ,(list->vector+ (map (match-lambda+ ((symbolic-name optional? implementations)+ `(("is_optional" . ,optional?)+ ("name" . ,symbolic-name)+ ("packages" . ,(list->vector implementations)))))+ requirements)))+ ("something/else" . #())))++(define* (make-packages/keys-json #:key (author "Author")+ (name "Name")+ (type "mod"))+ `(("author" . ,author)+ ("name" . ,name)+ ("type" . ,type)))++(define (call-with-packages thunk . argument-lists)+ ;; Don't reuse results from previous tests.+ (invalidate-memoization! contentdb-fetch)+ (invalidate-memoization! minetest->guix-package)+ (define (scm->json-port scm)+ (open-input-string (scm->json-string scm)))+ (define (handle-package url requested-author requested-name . rest)+ (define relevant-argument-list+ (any (lambda (argument-list)+ (apply (lambda* (#:key (author "Author") (name "foo")+ #:allow-other-keys)+ (and (equal? requested-author author)+ (equal? requested-name name)+ argument-list))+ argument-list))+ argument-lists))+ (when (not relevant-argument-list)+ (error "the package ~a/~a should be irrelevant, but ~a is fetched"+ requested-author requested-name url))+ (scm->json-port+ (apply (match rest+ (("") make-package-json)+ (("dependencies" "") make-dependencies-json)+ (("releases" "") make-releases-json)+ (_ (error "TODO ~a" rest)))+ relevant-argument-list)))+ (define (handle-mod-search sort)+ ;; Produce search results, sorted by SORT in descending order.+ (define arguments->key+ (match sort+ ("score" (lambda* (#:key (score 987.654) #:allow-other-keys)+ score))+ ("downloads" (lambda* (#:key (downloads 123) #:allow-other-keys)+ downloads))))+ (define argument-list->key (cut apply arguments->key <>))+ (define (greater x y)+ (> (argument-list->key x) (argument-list->key y)))+ (define sorted-argument-lists (sort-list argument-lists greater))+ (define* (arguments->json #:key (author "Author") (name "Foo") (type "mod")+ #:allow-other-keys)+ (and (string=? type "mod")+ `(("author" . ,author)+ ("name" . ,name)+ ("type" . ,type))))+ (define argument-list->json (cut apply arguments->json <>))+ (scm->json-port+ (list->vector (filter-map argument-list->json sorted-argument-lists))))+ (mock ((guix http-client) http-fetch+ (lambda* (url #:key headers)+ (unless (string-prefix? "mock://api/packages/" url)+ (error "the URL ~a should not be used" url))+ (define resource+ (substring url (string-length "mock://api/packages/")))+ (define components (string-split resource #\/))+ (match components+ ((author name . rest)+ (apply handle-package url author name rest))+ (((? (cut string-prefix? "?type=mod&q=" <>) query))+ (handle-mod-search+ (cond ((string-contains query "sort=score") "score")+ ((string-contains query "sort=downloads") "downloads")+ (#t (error "search query ~a has unknown sort key"+ query)))))+ (_+ (error "the URL ~a should have an author and name component"+ url)))))+ (parameterize ((%contentdb-api "mock://api/"))+ (thunk))))++(define* (minetest->guix-package* #:key (author "Author") (name "foo")+ (sort %default-sort-key)+ #:allow-other-keys)+ (minetest->guix-package (string-append author "/" name) #:sort sort))++(define (imported-package-sexp* primary-arguments . secondary-arguments)+ "Ask the importer to import a package specified by PRIMARY-ARGUMENTS,+during a dynamic where that package and the packages specified by+SECONDARY-ARGUMENTS are available on ContentDB."+ (apply call-with-packages+ (lambda ()+ ;; The memoization cache is reset by call-with-packages+ (apply minetest->guix-package* primary-arguments))+ primary-arguments+ secondary-arguments))++(define (imported-package-sexp . extra-arguments)+ "Ask the importer to import a package specified by EXTRA-ARGUMENTS,+during a dynamic extent where that package is available on ContentDB."+ (imported-package-sexp* extra-arguments))++(define-syntax-rule (test-package test-case . extra-arguments)+ (test-equal test-case+ (make-package-sexp . extra-arguments)+ (imported-package-sexp . extra-arguments)))++(define-syntax-rule (test-package* test-case primary-arguments extra-arguments+ ...)+ (test-equal test-case+ (apply make-package-sexp primary-arguments)+ (imported-package-sexp* primary-arguments extra-arguments ...)))++(test-begin "minetest")++ +;; Package names+(test-package "minetest->guix-package")+(test-package "minetest->guix-package, _ → - in package name"+ #:name "foo_bar"+ #:guix-name "minetest-foo-bar"+ #:upstream-name "Author/foo_bar")++(test-equal "elaborate names, unambigious"+ "Jeija/mesecons"+ (call-with-packages+ (cut elaborate-contentdb-name "mesecons")+ '(#:name "mesecons" #:author "Jeija")+ '(#:name "something" #:author "else")))++(test-equal "elaborate name, ambigious (highest score)"+ "Jeija/mesecons"+ (call-with-packages+ ;; #:sort "score" is the default+ (cut elaborate-contentdb-name "mesecons")+ '(#:name "mesecons" #:author "Jeijc" #:score 777)+ '(#:name "mesecons" #:author "Jeijb" #:score 888)+ '(#:name "mesecons" #:author "Jeija" #:score 999)))+++(test-equal "elaborate name, ambigious (most downloads)"+ "Jeija/mesecons"+ (call-with-packages+ (cut elaborate-contentdb-name "mesecons" #:sort "downloads")+ '(#:name "mesecons" #:author "Jeijc" #:downloads 777)+ '(#:name "mesecons" #:author "Jeijb" #:downloads 888)+ '(#:name "mesecons" #:author "Jeija" #:downloads 999)))++ +;; Determining the home page+(test-package "minetest->guix-package, website is used as home page"+ #:home-page "web://site"+ #:website "web://site")+(test-package "minetest->guix-package, if absent, the forum is used"+ #:home-page '(minetest-topic 628)+ #:forums 628+ #:website 'null)+(test-package "minetest->guix-package, if absent, the git repo is used"+ #:home-page "https://github.com/minetest-mods/mesecons"+ #:forums 'null+ #:website 'null+ #:repo "https://github.com/minetest-mods/mesecons")+(test-package "minetest->guix-package, all home page information absent"+ #:home-page #f+ #:forums 'null+ #:website 'null+ #:repo 'null)++ ++;; Dependencies+(test-package* "minetest->guix-package, unambigious dependency"+ (list #:requirements '(("mesecons" #f+ ("Jeija/mesecons"+ "some-modpack/containing-mese")))+ #:inputs '("minetest-mesecons"))+ (list #:author "Jeija" #:name "mesecons")+ (list #:author "some-modpack" #:name "containing-mese" #:type "modpack"))++(test-package* "minetest->guix-package, ambigious dependency (highest score)"+ (list #:name "frobnicate"+ #:guix-name "minetest-frobnicate"+ #:upstream-name "Author/frobnicate"+ #:requirements '(("frob" #f+ ("Author/foo" "Author/bar")))+ ;; #:sort "score" is the default+ #:inputs '("minetest-bar"))+ (list #:author "Author" #:name "foo" #:score 0)+ (list #:author "Author" #:name "bar" #:score 9999))++(test-package* "minetest->guix-package, ambigious dependency (most downloads)"+ (list #:name "frobnicate"+ #:guix-name "minetest-frobnicate"+ #:upstream-name "Author/frobnicate"+ #:requirements '(("frob" #f+ ("Author/foo" "Author/bar")))+ #:inputs '("minetest-bar")+ #:sort "downloads")+ (list #:author "Author" #:name "foo" #:downloads 0)+ (list #:author "Author" #:name "bar" #:downloads 9999))++(test-package "minetest->guix-package, optional dependency"+ #:requirements '(("mesecons" #t+ ("Jeija/mesecons"+ "some-modpack/containing-mese")))+ #:inputs '())++ +;; License+(test-package "minetest->guix-package, identical licenses"+ #:guix-license 'license:lgpl3++ #:license "LGPL-3.0-or-later"+ #:media-license "LGPL-3.0-or-later")++;; Sorting+(let* ((make-package+ (lambda arguments+ (json->package (apply make-package-json arguments))))+ (x (make-package #:score 0))+ (y (make-package #:score 1))+ (z (make-package #:score 2)))+ (test-equal "sort-packages, already sorted"+ (list z y x)+ (sort-packages (list z y x)))+ (test-equal "sort-packages, reverse"+ (list z y x)+ (sort-packages (list x y z))))++(test-end "minetest")-- 2.32.0
From c0a76311be73aef41096f3e52ca329cf2fd2950f Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sat, 31 Jul 2021 20:00:45 +0200Subject: [PATCH 07/20] gnu: Add minetest-mesecons.
* gnu/packages/minetest.scm (minetest-mesecons): New variable.--- gnu/packages/minetest.scm | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+)
Toggle diff (46 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex f8aca3005c..d99efa4625 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -24,3 +24,39 @@ numeric identifier TOPIC-ID on the official Minetest forums." (string-append "https://forum.minetest.net/viewtopic.php?t=" (number->string topic-id)))++(define-public minetest-mesecons+ ;; The release on ContentDB does not have its own version number.+ (let ((commit "db5879706d04d3480bc4863ce0c03fa73e5f10c7")+ (revision "0"))+ (package+ (name "minetest-mesecons")+ (version (git-version "1.2.1" revision commit))+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/minetest-mods/mesecons")+ (commit commit)))+ (sha256+ (base32 "04m9s9l3frw1lgki41hgvjsw2zkrvfv0sy750b6j12arzb3lv645"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (home-page "https://mesecons.net")+ (synopsis+ "Digital circuitry for Minetest, including wires, buttons and lights")+ (description+ "Mesecons is a mod for Minetest implementing various items related+to digital circuitry, such as wires, buttons, lights and programmable+controllers. Among other things, there are also pistons, solar panels,+pressure plates and note blocks.++Mesecons has a similar goal to Redstone in Minecraft, but works in its own way,+with different rules and mechanics.")+ ;; LGPL for code, CC-BY-SA for textures.+ ;; The README.md and COPYING.txt disagree about the "+" in license:lgpl3+.+ ;; For now, assume README.md is correct. Upstream has been asked to+ ;; correct the inconsistency:+ ;; <https://github.com/minetest-mods/mesecons/issues/575>.+ (license (list license:lgpl3+ license:cc-by-sa3.0))+ (properties `((upstream-name . "Jeija/mesecons"))))))-- 2.32.0
From fdf99927d0dd0090fe66f04e9a6e7e68f882f2e0 Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sat, 31 Jul 2021 20:23:50 +0200Subject: [PATCH 08/20] gnu: Add minetest-basic-materials.
* gnu/packages/minetest.scm (minetest-basic-materials): New variable.--- gnu/packages/minetest.scm | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
Toggle diff (38 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex d99efa4625..97d4d3c9ac 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -25,6 +25,31 @@ numeric identifier TOPIC-ID on the official Minetest forums." (string-append "https://forum.minetest.net/viewtopic.php?t=" (number->string topic-id))) +(define-public minetest-basic-materials+ (package+ (name "minetest-basic-materials")+ ;; Upstream uses dates as version numbers.+ (version "2021-01-30")+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://gitlab.com/VanessaE/basic_materials.git")+ (commit "e72665b2ed98d7be115779a32d35e6d9ffa231bd")))+ (sha256+ (base32 "0v6l3lrjgshy4sccjhfhmfxc3gk0cdy73qb02i9wd2vw506v5asx"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (home-page (minetest-topic 21000))+ (synopsis "Some \"basic\" materials and items for other Minetest mods to use")+ (description+ "The Minetest mod \"basic_materials\" provides a small selection of+\"basic\" materials and items that other mods should use when possible -- things+like steel bars and chains, wire, plastic strips and sheets, and more.")+ (license+ (list license:cc-by-sa4.0 license:lgpl3))+ (properties `((upstream-name . "VanessaE/basic_materials")))))+ (define-public minetest-mesecons ;; The release on ContentDB does not have its own version number. (let ((commit "db5879706d04d3480bc4863ce0c03fa73e5f10c7")-- 2.32.0
From 6ea28df67b5402634b14867ce334a2b9764e6d40 Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sat, 31 Jul 2021 20:40:24 +0200Subject: [PATCH 09/20] gnu: Add minetest-unifieddyes.
* gnu/packages/minetest.scm (minetest-unifieddyes): New variable.--- gnu/packages/minetest.scm | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
Toggle diff (39 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex 97d4d3c9ac..8b9eb30a6a 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -85,3 +85,32 @@ with different rules and mechanics.") ;; <https://github.com/minetest-mods/mesecons/issues/575>. (license (list license:lgpl3+ license:cc-by-sa3.0)) (properties `((upstream-name . "Jeija/mesecons"))))))++(define-public minetest-unifieddyes+ (package+ (name "minetest-unifieddyes")+ ;; Upstream uses dates as version numbers.+ (version "2021-04-20-1")+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://gitlab.com/VanessaE/unifieddyes")+ (commit "ff3b2d30fa0df5c7181fdd401b989de6271c3bb3")))+ (sha256+ (base32+ "0rba9n192xcpmxwnq7ixb6mn32gkpic247j3w4mwinrqcyscacsv"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (propagated-inputs+ `(("minetest-basic-materials" ,minetest-basic-materials)))+ (home-page (minetest-topic 2178))+ (synopsis+ "Unified Dyes expands the standard dye set of Minetest to up to 256 colours")+ (description "The purpose of this mod originally was to supply a complete+set of colours for Minetest mod authors to use for colourised nodes or+reference in recipes. Since the advent of the default dyes mod in the standard+Minetest game, this mod has become an extension of the default mod an a library+for general colour handling.")+ (license license:gpl2+)+ (properties `((upstream-name . "VanessaE/unifieddyes")))))-- 2.32.0
From 799bf39bb88a16d09a8473a43ea458fa98df86ae Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sat, 31 Jul 2021 23:39:02 +0200Subject: [PATCH 10/20] gnu: Add minetest-pipeworks.
* gnu/packages/minetest.scm (minetest-pipeworks): New variable.--- gnu/packages/minetest.scm | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+)
Toggle diff (44 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex 8b9eb30a6a..782166daef 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -86,6 +86,37 @@ with different rules and mechanics.") (license (list license:lgpl3+ license:cc-by-sa3.0)) (properties `((upstream-name . "Jeija/mesecons")))))) +(define-public minetest-pipeworks+ (package+ (name "minetest-pipeworks")+ ;; Upstream uses dates as version numbers.+ (version "2021-04-14-1")+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://gitlab.com/VanessaE/pipeworks")+ (commit "db6d1bd9c109e1e543b97cc3fa8a11400da23bcd")))+ (sha256+ (base32 "1flhcnf17dn1v86kcg47a1n4cb0lybd11ncxrkxn3wmf10ibsrm0"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (propagated-inputs+ `(("minetest-basic-materials" ,minetest-basic-materials)))+ (home-page (minetest-topic 2155))+ (synopsis "Pipes, item-transport tubes and related devices for Minetest")+ (description+ "Pipeworks is a mod for Minetest implementing 3D pipes and tubes for+transporting liquids and items and some related devices. Pipes and tubes can+go horizontally or vertically. Item tubes can also be used for sorting items+and extracting items from chests or putting items in chests. Autocrafters can+automatically follow craft recipes to make new items and can be fed by item+tubes. Deployers can place items in the world as a player would. Node+breakers simulate a player punching a node.")+ ;; CC-BY-SA for textures, LGPL for code+ (license (list license:cc-by-sa4.0 license:lgpl3))+ (properties `((upstream-name . "VanessaE/pipeworks")))))+ (define-public minetest-unifieddyes (package (name "minetest-unifieddyes")-- 2.32.0
From 93deef7431a986c41b085aa107055b0348a8ed8f Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sun, 1 Aug 2021 00:50:12 +0200Subject: [PATCH 11/20] gnu: Add minetest-coloredwood.
* gnu/packages/minetest.scm (minetest-coloredwood): New variable.--- gnu/packages/minetest.scm | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
Toggle diff (41 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex 782166daef..4c542c6061 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -50,6 +50,34 @@ like steel bars and chains, wire, plastic strips and sheets, and more.") (list license:cc-by-sa4.0 license:lgpl3)) (properties `((upstream-name . "VanessaE/basic_materials"))))) +(define-public minetest-coloredwood+ (package+ (name "minetest-coloredwood")+ ;; Upstream uses dates as version numbers.+ (version "2021-04-14-1")+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://gitlab.com/VanessaE/coloredwood")+ (commit "be4df6fc889419155bed8638bbb752493e78cbd5")))+ (sha256+ (base32 "1swirfk6b4xfbiwv8adyw5yl2lyfpp8ymfipzq9ivyvmif8nl3ki"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (propagated-inputs+ `(("minetest-unifieddyes" ,minetest-unifieddyes)))+ (home-page (minetest-topic 2411))+ (synopsis "Painted wood in Minetest")+ (description+ "This Minetest mod provides hundreds of colours of wood and fences to+Minetest, using Unified Dyes. If the \"moreblocks\" mod is active,+coloured and cut wood shapes are provided as well.")+ (license+ ;; LGPL for code, CC-BY-SA for textures+ (list license:cc-by-sa4.0 license:lgpl3))+ (properties `((upstream-name . "VanessaE/coloredwood")))))+ (define-public minetest-mesecons ;; The release on ContentDB does not have its own version number. (let ((commit "db5879706d04d3480bc4863ce0c03fa73e5f10c7")-- 2.32.0
From 42b3daf2756e5eb3f7890b9a43fea90bdff4ba91 Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sun, 1 Aug 2021 01:24:48 +0200Subject: [PATCH 12/20] gnu: Add minetest-ethereal.
* gnu/packages/minetest.scm (minetest-ethereal): New variable.--- gnu/packages/minetest.scm | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-)
Toggle diff (52 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex 4c542c6061..a1aa90276d 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -78,6 +78,35 @@ coloured and cut wood shapes are provided as well.") (list license:cc-by-sa4.0 license:lgpl3)) (properties `((upstream-name . "VanessaE/coloredwood"))))) +(define-public minetest-ethereal+ ;; ContentDB release 2021-07-28 is slightly ahead of the+ ;; initial version 1.29 -- i.e., some released changes have been+ ;; made to version 1.29 without a corresponding version bump.+ (let ((commit "7670c1da9274901f57f6682384af2b3bae005a86")+ (revision "0"))+ (package+ (name "minetest-ethereal")+ (version (git-version "1.29" revision commit))+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://notabug.org/TenPlus1/ethereal")+ (commit commit)))+ (sha256+ (base32 "1hal8bq4fydsip7s8rqz4vlaaqy9rhzxmryd0j2qnqm9286yjgkk"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (home-page (minetest-topic 14638))+ (synopsis "The Ethereal mod adds many new biomes to Minetest")+ (description+ "The Ethereal Minetest mod uses the v7 map generator to add many new+biomes to the world. It adds new trees, plants, food items, tweaks and some+special items, intending to make an interesting adventure.")+ ;; CC0: some textures+ (license (list license:cc0 license:expat))+ (properties `((upstream-name . "TenPlus1/ethereal"))))))+ (define-public minetest-mesecons ;; The release on ContentDB does not have its own version number. (let ((commit "db5879706d04d3480bc4863ce0c03fa73e5f10c7")@@ -157,8 +186,7 @@ breakers simulate a player punching a node.") (url "https://gitlab.com/VanessaE/unifieddyes") (commit "ff3b2d30fa0df5c7181fdd401b989de6271c3bb3"))) (sha256- (base32- "0rba9n192xcpmxwnq7ixb6mn32gkpic247j3w4mwinrqcyscacsv"))+ (base32 "0rba9n192xcpmxwnq7ixb6mn32gkpic247j3w4mwinrqcyscacsv")) (file-name (git-file-name name version)))) (build-system minetest-mod-build-system) (propagated-inputs-- 2.32.0
From e8b540369b51ce74c3f9e83179a7a17f17c21117 Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sun, 1 Aug 2021 13:40:56 +0200Subject: [PATCH 13/20] gnu: Add minetest-technic.
* gnu/packages/minetest.scm (minetest-technic): New variable.--- gnu/packages/minetest.scm | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+)
Toggle diff (48 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex a1aa90276d..bb914f32b4 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -174,6 +174,41 @@ breakers simulate a player punching a node.") (license (list license:cc-by-sa4.0 license:lgpl3)) (properties `((upstream-name . "VanessaE/pipeworks"))))) +(define-public minetest-technic+ (package+ (name "minetest-technic")+ ;; Upstream doesn't keep version numbers, so use the release+ ;; date on ContentDB instead.+ (version "2021-04-15")+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/minetest-mods/technic")+ (commit "1c219487d3f4dd03c01ff9aa1f298c7c18c7e189")))+ (sha256+ (base32 "1k9hdgzp7jnhsk6rgrlrv1lr5xrmh8ln4wv6r25v6f0fwbyj57sf"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (propagated-inputs+ `(("minetest-pipeworks" ,minetest-pipeworks)+ ("minetest-basic-materials" ,minetest-basic-materials)))+ (home-page (minetest-topic 2538))+ (synopsis "Machinery and automation for Minetest")+ (description+ "This Minetest mod adds machinery and automation to Minetest.+It adds various ores that can be processed for constructing various+machinery, such as power generators, force field emitters, quarries+and a workshop for repairing tools. Most machines are electrically+powered.")+ ;; CC BY-SA 3.0: some texture+ ;; WTFPL: some textures+ ;; CC BY-SA3.0: some textures+ ;; CC BY-SA4.0: some sounds+ (license (list license:lgpl2.1+ license:cc-by-sa3.0 license:cc-by-sa4.0+ license:wtfpl2))+ (properties `((upstream-name . "RealBadAngel/technic")))))+ (define-public minetest-unifieddyes (package (name "minetest-unifieddyes")-- 2.32.0
From 9f2a20d664fb8d280f49db9ca46247de8242f53b Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sun, 1 Aug 2021 14:16:27 +0200Subject: [PATCH 14/20] gnu: Add minetest-throwing.
* gnu/packages/minetest.scm (minetest-throwing): New variable.--- gnu/packages/minetest.scm | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
Toggle diff (36 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex bb914f32b4..1444ddf4d8 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -209,6 +209,29 @@ powered.") license:wtfpl2)) (properties `((upstream-name . "RealBadAngel/technic"))))) +(define-public minetest-throwing+ (package+ (name "minetest-throwing")+ (version "2020-08-14")+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/minetest-mods/throwing")+ (commit "31f0cf5f868673dc82f24ddc432b45c9cd282d27")))+ (sha256+ (base32 "1s5kkr6rxxv2dhbbjzv62gw1s617hnpjavw1v9fv11v3mgigdfjb"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (home-page (minetest-topic 16365))+ (synopsis "API for throwing things in Minetest")+ (description+ "This Minetest mod provides an API for registering throwable things and+throwing things like arrows. However, this mod does not provide an actual+arrow and bow, but @code{minetest-throwing-arrows} does.")+ (license license:mpl2.0)+ (properties `((upstream-name . "Palige/throwing")))))+ (define-public minetest-unifieddyes (package (name "minetest-unifieddyes")-- 2.32.0
From f1477ba3edb9729b63041863611704af1621bf29 Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sun, 1 Aug 2021 14:34:12 +0200Subject: [PATCH 15/20] gnu: Add minetest-throwing-arrows.
* gnu/packages/minetest.scm (minetest-throwing-arrows): New variable.--- gnu/packages/minetest.scm | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
Toggle diff (43 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex 1444ddf4d8..6183367101 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -232,6 +232,36 @@ arrow and bow, but @code{minetest-throwing-arrows} does.") (license license:mpl2.0) (properties `((upstream-name . "Palige/throwing"))))) +(define-public minetest-throwing-arrows+ ;; There is only one tagged commit (version 1.1),+ ;; there are no releases on ContentDB and the latest+ ;; commit has a compatibility fix for Minetest 5.4.0-dev.+ (let ((commit "059cc897af0aebfbd2c54ac5588f2b842f44f159")+ (revision "0"))+ (package+ (name "minetest-throwing-arrows")+ (version (git-version "1.1" revision commit))+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/minetest-mods/throwing_arrows")+ (commit commit)))+ (sha256+ (base32 "0m2pmccpfxn878zd00pmrpga2h6gknz4f3qprck0fq94mksmwqs3"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (propagated-inputs+ `(("minetest-throwing" ,minetest-throwing)))+ (home-page (minetest-topic 16365))+ (synopsis "Arrows and bows for Minetest")+ (description+ ;; TRANSLATORS: "throwing" is the name of a Minetest mod and should+ ;; not be translated.+ "This mod adds arrows and bows to Minetest. It is a compatible+replacement for the throwing mod by PilzAdam that uses the throwing API.")+ (license license:mpl2.0))))+ (define-public minetest-unifieddyes (package (name "minetest-unifieddyes")-- 2.32.0
From 7188ac29a73be4f15df9977ce75b1dd60d837e44 Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sun, 1 Aug 2021 17:39:36 +0200Subject: [PATCH 16/20] gnu: Add minetest-unified-inventory.
* gnu/packages/minetest.scm (minetest-unified-inventory): New variable.--- gnu/packages/minetest.scm | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+)
Toggle diff (45 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex 6183367101..042f710c85 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -289,3 +289,38 @@ Minetest game, this mod has become an extension of the default mod an a library for general colour handling.") (license license:gpl2+) (properties `((upstream-name . "VanessaE/unifieddyes")))))++(define-public minetest-unified-inventory+ (package+ (name "minetest-unified-inventory")+ ;; Upstream doesn't keep version numbers, so use the release title+ ;; on ContentDB instead.+ (version "2021-03-25-1")+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/minetest-mods/unified_inventory")+ (commit "c044f5e3b08f0c68ab028d757b2fa63d9a1b0370")))+ (sha256+ (base32 "198g945gzbfl0kps46gwjw0c601l3b3wvn4c7dw8manskri1jr4g"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (home-page (minetest-topic 12767))+ (synopsis "Replace the default inventory in Minetest and add a crafting guide")+ (description+ "The Unified Inventory Minetest mod relaces the default survival an+creative inventory. It includes a node, item and tool browser, a crafting+guide, a trash and refill slot for creative mode, bags and waypoints for keeping+track of important locations.")+ ;; CC-BY: some textures and icons+ ;; CC-BY-SA: some textures and icons+ ;; LGLPL2.1+: code and some textures+ ;; GPL2+: some textures+ ;; GPL3: bags.lua+ ;; GFDL: some icons+ ;; public domain, CC0: some icons+ (license (list license:gpl3 license:gpl2+ license:lgpl2.1+ license:cc-by3.0+ license:cc-by4.0 license:cc-by-sa3.0 license:public-domain+ license:cc0 license:fdl1.2+))+ (properties `((upstream-name . "RealBadAngel/unified_inventory")))))-- 2.32.0
From 664aa8de09e10b4699eb1e5ea95bde3b51ca2f36 Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sun, 1 Aug 2021 17:58:24 +0200Subject: [PATCH 17/20] gnu: Add minetest-worldedit.
* gnu/packages/minetest.scm (minetest-worldedit): New variable.--- gnu/packages/minetest.scm | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
Toggle diff (36 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex 042f710c85..f26e7e0ff3 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -262,6 +262,29 @@ arrow and bow, but @code{minetest-throwing-arrows} does.") replacement for the throwing mod by PilzAdam that uses the throwing API.") (license license:mpl2.0)))) +(define-public minetest-worldedit+ (package+ (name "minetest-worldedit")+ (version "1.3")+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://github.com/Uberi/Minetest-WorldEdit")+ (commit "2f26fb76459c587868199160b9d7b5d6d7852e50")))+ (sha256+ (base32 "0lsvihkixi2na1b0vmml9vwgs0g24hqqshl73ffhkzh6jsq4cagq"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (home-page (minetest-topic 572))+ (synopsis "In-game world editor for Minetest")+ (description+ "WorldEdit is a mod for Minetest. It allows for creating various+geometric shapes and copying regions. It can also export and import regions+to and from the file system.")+ (license license:agpl3)+ (properties `((upstream-name . "sfan5/worldedit")))))+ (define-public minetest-unifieddyes (package (name "minetest-unifieddyes")-- 2.32.0
From 3d2a67158927e10bd2a8169b8199bb6de118c844 Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sun, 1 Aug 2021 18:53:54 +0200Subject: [PATCH 18/20] gnu: Add minetest-mobs.
* gnu/packages/minetest.scm (minetest-mobs): New variable.--- gnu/packages/minetest.scm | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
Toggle diff (42 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex f26e7e0ff3..2a7bd0081e 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -143,6 +143,35 @@ with different rules and mechanics.") (license (list license:lgpl3+ license:cc-by-sa3.0)) (properties `((upstream-name . "Jeija/mesecons")))))) +(define-public minetest-mobs+ (package+ (name "minetest-mobs")+ ;; Upstream does not tag release, so use the ContentDB release+ ;; title instead.+ (version "2021-07-22")+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://notabug.org/TenPlus1/mobs_redo")+ (commit "9f46182bb4b1a390f9a140bc2b443f3cda702332")))+ (sha256+ (base32 "026kqjis4lipgskjivb3jh9ris3iz80vy2q1jvgxhxmfghjjzp4j"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (home-page (minetest-topic 9917))+ (synopsis "Mob library for Minetest mods, for animals, monsters etc.")+ (description+ "This Minetest mod provides an API for adding mods (moving entities+like animals and monsters), but does not include any mobs itself. To actually+add some mobs, a mod like e.g. @code{mobs_animal} provided by the+@code{minetest-mobs-animal} package needs to be enabled.")+ ;; CC0: mob_swing.ogg+ ;; CC-BY 3.0: mob_spell.ogg+ ;; Expat: everything else+ (license (list license:expat license:cc0 license:cc-by3.0))+ (properties `((upstream-name . "TenPlus1/mobs")))))+ (define-public minetest-pipeworks (package (name "minetest-pipeworks")-- 2.32.0
From f7d9cd92bf9eb5043332c1d0ba915b6923c60cc1 Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sun, 1 Aug 2021 19:43:47 +0200Subject: [PATCH 19/20] gnu: Add minetest-mobs-animal.
* gnu/packages/minetest.scm (minetest-mobs-animal): New variable.--- gnu/packages/minetest.scm | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
Toggle diff (40 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex 2a7bd0081e..f49e0080f2 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -172,6 +172,33 @@ add some mobs, a mod like e.g. @code{mobs_animal} provided by the (license (list license:expat license:cc0 license:cc-by3.0)) (properties `((upstream-name . "TenPlus1/mobs"))))) +(define-public minetest-mobs-animal+ (package+ (name "minetest-mobs-animal")+ ;; Upstream does not use version numbers, so use the release title+ ;; from ContentDB instead;+ (version "2021-07-24")+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://notabug.org/TenPlus1/mobs_animal")+ (commit "c2fa3e300c79c7dd80b6fe91a8b5082bb6b3d934")))+ (sha256+ (base32 "1j719f079ia9vjxrmjrcj8s6jvaz5kgs1r4dh66z8ql6s70kx7vh"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (propagated-inputs+ `(("minetest-mobs" ,minetest-mobs)))+ (home-page "https://notabug.org/TenPlus1/mobs_animal")+ (synopsis "Add animals to Minetest")+ (description+ "This Minetest mod adds various animals to Minetest, such as bees,+bunnies, chickens, cows, kittens, rats, sheep, warthogs, penguins and pandas.")+ ;; CC0: some textures and sounds+ (license (list license:cc0 license:expat))+ (properties `((upstream-name . "TenPlus1/mobs_animal")))))+ (define-public minetest-pipeworks (package (name "minetest-pipeworks")-- 2.32.0
From 33e15111c00d9988d8123a674930a27b61e891b3 Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sun, 1 Aug 2021 20:03:07 +0200Subject: [PATCH 20/20] gnu: Add minetest-homedecor-modpack.
* gnu/packages/minetest.scm (minetest-homedecor-modpack): New variable.--- gnu/packages/minetest.scm | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+)
Toggle diff (44 lines)diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmindex f49e0080f2..ca9d0ac720 100644--- a/gnu/packages/minetest.scm+++ b/gnu/packages/minetest.scm@@ -107,6 +107,37 @@ special items, intending to make an interesting adventure.") (license (list license:cc0 license:expat)) (properties `((upstream-name . "TenPlus1/ethereal")))))) +(define-public minetest-homedecor-modpack+ (package+ (name "minetest-homedecor-modpack")+ ;; Upstream doesn't tag releases, so use the release title from+ ;; ContentDB as version.+ (version "2021-03-27-1")+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url "https://gitlab.com/VanessaE/homedecor_modpack")+ (commit "9ffe2b7d691133e1a067546574fbe7364fd02f32")))+ (sha256+ (base32 "1lfajqvc2adf9hqskghky4arccqzpjw4i9a01hv4qcckvivm04ag"))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ (propagated-inputs+ `(("minetest-basic-materials" ,minetest-basic-materials)+ ("minetest-unifieddyes" ,minetest-unifieddyes)))+ (home-page (minetest-topic 2041))+ (synopsis "Home decor mod for Minetest")+ (description+ ;; TRANSLATORS: ‘homedecor’ is the name is the name of a Minetest mod+ ;; and should not be translated.+ "The homedecor Minetest mod provides a large seleection of items that+might be found inside and around homes, such as sofas, chairs, tables, fences+and a variety of other stuff.")+ (license+ (list license:cc-by-sa4.0 license:lgpl3))+ (properties `((upstream-name . "VanessaE/homedecor_modpack")))))+ (define-public minetest-mesecons ;; The release on ContentDB does not have its own version number. (let ((commit "db5879706d04d3480bc4863ce0c03fa73e5f10c7")-- 2.32.0
-----BEGIN PGP SIGNATURE-----
iI0EABYKADUWIQTB8z7iDFKP233XAR9J4+4iGRcl7gUCYQ7RVxccbWF4aW1lZGV2b3NAdGVsZW5ldC5iZQAKCRBJ4+4iGRcl7lB6AP9q6y2qYdE9Jo/Gz10XE5UJDWnJkEOhlYigZZ/LlOzoQQD/RKIFuQBEofHGgdtrtonUPrIDTqmiS1eDHWClPy47UQk==Le0m-----END PGP SIGNATURE-----

L
L
Leo Prikler wrote on 7 Aug 21:47 +0200
190b2e2c5da797a8c0e70f53de3e221861ce3b89.camel@student.tugraz.at
Hi,
Am Samstag, den 07.08.2021, 20:31 +0200 schrieb Maxime Devos:
Toggle quote (4 lines)> [...]> ContentDB uses SPDX license identifiers now, and distinguishes> between GPL-N-only and GPL-N-or-later, so I adjusted the> documentation appropriately.
Nice.
Toggle quote (10 lines)> > > The commit id is> > > +sometimes missing. The descriptions are in the Markdown format,> > > but> > > +Guix uses Texinfo instead. Texture packs and subgames are> > > unsupported.> > What is the "commit id"? Is it the hash? A tag? Anything that> > resolves to a commit?> > It's the SHA-1 of the Git commit. I changes this to ‘the commit's> SHA-1’.
We usually call it the hash around here :)
Toggle quote (10 lines)> > Also, since ContentDB sounds fairly generic (a database of> > content?),> > perhaps we ought to call this the "minetest" importer instead?> > Technically, minetest has another mod repository as well:> <https://bower.minetest.org/>;. It's unmoderated though, and> <https://content.minetest.net> has some moderation and seems more> ‘official’ (it's integrated in Minetest itself). I replaced> (guix import contentdb) with (guix import minetest), likewise> for (guix script import minetest) and tests/minetest.scm.
If we get more of these we could label them like elpa repos, but Idon't think we'll get many third party repos with ContentDB existing.
Toggle quote (25 lines)> > > +;; 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) ;> > > natural | #f> > This comment and some others like it seem to simply be repeating> > already present information. Is there a use for them? Should we> > instead provide a third argument on every field to verify/enforce> > the> > type?> > I first added the ‘; natural-or-false’. I only added the procedure> "natural-false" later. Indeed, ‘; natural-or-false’ is redundant.> I removed the redundant ones in the revised patch.> > I don't think there is need to verify types for each field.> Most aren't used by Guix. If a type check would fail, that would> presumably mean the type check guix is incorrect (or not up-to-date).> Except for perhaps a backtrace, ill-typed fields are harmless.
Fair enough, gratuitous redundancy is the bigger issue here.
Toggle quote (7 lines)> [...]> ContentDB allows searching. I wrote some a procedure 'elaborate-> contentdb-name' used by (guix scripts import contentdb) that resolves> "mesecons" to "Jeija/mesecons", using the search API and added some> tests. If there are multiple candidates, the one with the highest> ‘score’ is choosen (alternatively, --sort=downloads can be used> instead).
Sounds good to me.
Toggle quote (52 lines)> > > +(define (important-dependencies dependencies author name)> > > + (define dependency-list> > > + (assoc-ref dependencies (string-append author "/" name)))> > > + (filter-map> > > + (lambda (dependency)> > > + (and (not (dependency-optional? dependency))> > > + ;; "default" must be provided by the 'subgame' in use> > > + ;; and does not refer to a specific minetest mod.> > > + ;; "doors", "bucket" ... are provided by the default> > > minetest> > > + ;; subgame.> > > + (not (member (dependency-name dependency)> > > + '("default" "doors" "beds" "bucket"> > > "doors"> > > "farming"> > > + "flowers" "stairs" "xpanes")))> > I tested this some more, and it appears that some mods depend on> "dyes",> which is part of the default Minetest game, so I added all the mods> provided by the default (sub?)game. The list began looking a little> long, so I replaced it with a hash table.> > > > + ;; Dependencies often have only one implementation.> > > + (let* ((/name (string-append "/" (dependency-name> > > dependency)))> > > + (likewise-named-implementations> > > + (filter (cut string-suffix? /name <>)> > > + (dependency-packages dependency)))> > > + (implementation> > > + (and (not (null? likewise-named-> > > implementations))> > > + (first likewise-named-implementations))))> > > + (and implementation> > > + (apply cons (string-split implementation> > > #\/))))))> > > + dependency-list))> > What exactly does the likewise-named-implementations bit do here?> > The list returned by 'dependency-packages' not only contains the mod> we need, but possibly also various ‘subgames’ that include that mod.> Filtering on '/name' filters out these subgames we don't need.> > Also, theoretically another mod could implement the same interface.> The filtering would filter out the alternative implementations.> > Anyway, I changes the implementation a bit. It now explicitely> filters out ‘subgames’ and ‘texture packs’ using the ‘package-mod?’> procedure. The resulting list tends to consist of only a single> element. If it consists of multiple, the one with the highest score> (or the one with the highest download count, depending on --sort)> will be choosen (and a warning is printed).
Sounds good.
Toggle quote (15 lines)> > > +;; A list of license names is available at> > > +;; <https://content.minetest.net/api/licenses/>;;;.> > > +(define (string->license str)> > > + "Convert the string STR into a license object." [...]> > The link mentions, that ContentDB now supports all SPDX> > identifiers. > > Do we have a SPDX->Guix converter lying around in some other> > importer> > that we could use as default case here (especially w.r.t. "or> > later")> > There's a a converter in (guix import utils): spdx-string->license.> The old license identifiers appear to be removed, now only SPDX> information is available. I modified the code to use spdx->string-> license and removed string->license.
Nice.
Toggle quote (3 lines)> It turns out it does not recognise GPL-N-only and GPL-N-or-later,> so I added a patch ‘import/utils: Recognise GPL-3.0-or-later and> friends.’.
Said patch LGTM.
Toggle quote (5 lines)> I tried implementing "guix refresh -t minetest ...". It seems to> work, but requires some changes to (guix upstream) that needs some> more work, so I left it out of the revised patch set. The refresher> needs to know the author name (or perform extra HTTP requests), so I> added 'upstream-name' the package properties.
Could we somehow define a (minetest-uri) procedure that can be suppliedto (guix download)? Somehow Minetest must get the package toinstallations across operating systems, so surely there's some downloadlink somewhere.
Toggle quote (4 lines)> The revised patch series is attached. It can also be found at> <https://notabug.org/maximed/guix-gnunet/src/minetest-2>;. It> includes the latest MINETEST_MOD_PATH patch. I'll make the patch to> export more things in (guix build utils) later (for core-updates).
For the rest of this, I'll only look over 06/20 v2. I'll assume youdid nothing naughty to 01..04.
Toggle quote (6 lines)> +;; 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
Not sure about this slash, as it typically specifies extension of somesort. Perhaps just naming this package-keys would be better?
Toggle quote (11 lines)> +(define (package-author/name package)> + "Given a <package> object, return the corresponding AUTHOR/NAME> string."> + (string-append (package-author package) "/" (package-name> package)))> +> +(define (package/keys-author/name package)> + "Given a <package/keys> object, return the corresponding> AUTHOR/NAME string."> + (string-append (package/keys-author package)> + "/" (package/keys-name package)))
I think it's probably be better to merge this into a single procedurecalled "package-full-name", "package-unique-name" or "package-id"(whichever you prefer naming-wise), which handles both cases.
Toggle quote (7 lines)> +(define (contentdb->package-name name)> + "Given the 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 name)))
I'd at least add an option to generate full names instead, for cases inwhich as before we warn about non-uniqueness. Though actually, thiscomment is a little misleading as the actual stripping happens...
Toggle quote (2 lines)> + (name ,(contentdb->package-name (author/name->name> author/name)))
here.
Toggle quote (13 lines)> +(define* (make-package-sexp #:key> + (guix-name "minetest-foo")> + (home-page "https://example.org/foo")> + (repo "https://example.org/foo.git")> + (synopsis "synopsis")> + (guix-description "description")> + (guix-license> + '(list license:cc-by-sa4.0> license:lgpl3+))> + (inputs '())> + (upstream-name "Author/foo")> + #:allow-other-keys)> + [...]
As noted above, this procedure would be somewhat simplified if we coulddefine a (mintest-uri).
Regards
M
M
Maxime Devos wrote on 9 Aug 22:00 +0200
Re: [PATCH 06/20] guix: Add ContentDB importer. (XXX Don't send yet)
9e75e458ab823e627b221218542f800105748c2a.camel@telenet.be
Hi,
Leo Prikler schreef op za 07-08-2021 om 21:47 [+0200]:
Toggle quote (12 lines)> > > > The commit id is> > > > +sometimes missing. The descriptions are in the Markdown format,> > > > but> > > > +Guix uses Texinfo instead. Texture packs and subgames are> > > > unsupported.> > > What is the "commit id"? Is it the hash? A tag? Anything that> > > resolves to a commit?> > > > It's the SHA-1 of the Git commit. I changes this to ‘the commit's> > SHA-1’.> We usually call it the hash around here :)
I adjusted the documentation to call it ‘the commit hash’.
Toggle quote (10 lines)> > I tried implementing "guix refresh -t minetest ...". It seems to> > work, but requires some changes to (guix upstream) that needs some> > more work, so I left it out of the revised patch set. The refresher> > needs to know the author name (or perform extra HTTP requests), so I> > added 'upstream-name' the package properties.> Could we somehow define a (minetest-uri) procedure that can be supplied> to (guix download)? Somehow Minetest must get the package to> installations across operating systems, so surely there's some download> link somewhere.
What is this 'minetest-uri' supposed to do? I assume it would be aprocedure like 'pypi-uri', 'cran-uri', 'crate-uri', which takes apackage name, the version and should return an URL string pointing toa tarball.
That would be possible. ContentDB allows for downloading zips:
https://github.com/minetest/contentdb/blob/master/docs/minetest_client.md#downloading-and-installing
The URL would look like: /packages/<author>/<name>/releases/<release>/download/.Here, <release> is a the ‘release id’, which is an integer (e.g. 4209). Itis _not_ the version number, but it is monotonically increasing.
There are some problems however:
* Old archives are sometimes deleted.
TenPlus1/ethereal was added to ContentDB on 2018-02-23, but it only has a single release on ContentDB, from 2021-07-28 https://content.minetest.net/packages/TenPlus1/ethereal/releases/. Likewise for TenPlus1/bakedclay, TenPlus1/wine, TenPlus1/bees.
Most other mods still have the old archives though (e.g., Jeija/mesecons, sfan5/worldedit, PilzAdam/nether). The mods by TenPlus1 seems to be an exception.
* The version number is not included in the download URL, the release id is. So IIUC, update-package-source in (guix upstream) would still need to be adjusted somewhat to support Minetest packages.
+(define* (make-package-sexp #:key
Toggle quote (16 lines)> > + (guix-name "minetest-foo")> > + (home-page "https://example.org/foo")> > + (repo "https://example.org/foo.git")> > + (synopsis "synopsis")> > + (guix-description "description")> > + (guix-license> > + '(list license:cc-by-sa4.0> > license:lgpl3+))> > + (inputs '())> > + (upstream-name "Author/foo")> > + #:allow-other-keys)> > + [...]> As noted above, this procedure would be somewhat simplified if we could> define a (mintest-uri).>
I don't see how a 'minetest-uri' would simplify the definition of'make-package-sexp'. Using 'minetest-uri' would avoid the needto specify the commit, but 'minetest-uri' needs a release id anyway,so no simplification there.
I guess it would avoid the 'download-git-repository' procedureand 'vcs-file?', but see two points above. Also, 'latest-repository-commit'returns a store path, which does not include the '.git' directory,so 'vcs-file?' isn't necessary, so I removed 'vcs-file?'.
Toggle quote (16 lines)> > The revised patch series is attached. It can also be found at> > <https://notabug.org/maximed/guix-gnunet/src/minetest-2>;;. It> > includes the latest MINETEST_MOD_PATH patch. I'll make the patch to> > export more things in (guix build utils) later (for core-updates).> For the rest of this, I'll only look over 06/20 v2. I'll assume you> did nothing naughty to 01..04.> > > +;; 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> Not sure about this slash, as it typically specifies extension of some> sort. Perhaps just naming this package-keys would be better?
Done.
Toggle quote (15 lines)> > +(define (package-author/name package)> > + "Given a <package> object, return the corresponding AUTHOR/NAME> > string."> > + (string-append (package-author package) "/" (package-name> > package)))> > +> > +(define (package/keys-author/name package)> > + "Given a <package/keys> object, return the corresponding> > AUTHOR/NAME string."> > + (string-append (package/keys-author package)> > + "/" (package/keys-name package)))> I think it's probably be better to merge this into a single procedure> called "package-full-name", "package-unique-name" or "package-id"> (whichever you prefer naming-wise), which handles both cases.
I like the name 'package-full-name'. <package> and <package-keys>are rather different structures and used in different contexts though,so I kept package-full-name and package-keys-full-name separate.
FWIW, I added a procedure
(define (%construct-full-name author name) (string-append author "/" name))
used by 'package-full-name' and 'package-keys-full-name'.
Toggle quote (14 lines)> > +(define (contentdb->package-name name)> > + "Given the 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 name)))> I'd at least add an option to generate full names instead, for cases in> which as before we warn about non-uniqueness. Though actually, this> comment is a little misleading as the actual stripping happens...> > + (name ,(contentdb->package-name (author/name->name> > author/name)))> here
ContentDB has a policy of requiring mod names to be unique in order tobe a ‘approved’, so I don't think name conflict will be a problem inpractice. If full names were generated, keep in mind that dependencieswould need to use the full names a well. I couldn't find any modswith name conflicts. I would just emit a warning for now.
contentdb->package-name was always used together with 'author/name->name',so I modified contentdb->package-name to call author/name->name as youseem to suggest. It maked the code a little simpler.
Thanks,Maxime.
From 39d869370e7a286fb30a06512c08fd3399d92d4f Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sat, 31 Jul 2021 14:44:11 +0200Subject: [PATCH] guix: Add ContentDB importer.
* guix/import/contentdb.scm: New file.* guix/scripts/import/contentdb.scm: New file.* tests/contentdb.scm: New file.* Makefile.am (MODULES, SCM_TESTS): Register them.* po/guix/POTFILES.in: Likewise.* doc/guix.texi (Invoking guix import): Document it.--- Makefile.am | 3 + doc/guix.texi | 32 +++ guix/import/minetest.scm | 456 +++++++++++++++++++++++++++++++ guix/scripts/import.scm | 3 +- guix/scripts/import/minetest.scm | 117 ++++++++ po/guix/POTFILES.in | 1 + tests/minetest.scm | 355 ++++++++++++++++++++++++ 7 files changed, 966 insertions(+), 1 deletion(-) create mode 100644 guix/import/minetest.scm create mode 100644 guix/scripts/import/minetest.scm create mode 100644 tests/minetest.scm
Toggle diff (1045 lines)diff --git a/Makefile.am b/Makefile.amindex f4439ce93b..6243583616 100644--- a/Makefile.am+++ b/Makefile.am@@ -262,6 +262,7 @@ MODULES = \ guix/import/json.scm \ guix/import/kde.scm \ guix/import/launchpad.scm \+ guix/import/minetest.scm \ guix/import/opam.scm \ guix/import/print.scm \ guix/import/pypi.scm \@@ -304,6 +305,7 @@ MODULES = \ guix/scripts/import/go.scm \ guix/scripts/import/hackage.scm \ guix/scripts/import/json.scm \+ guix/scripts/import/minetest.scm \ guix/scripts/import/opam.scm \ guix/scripts/import/pypi.scm \ guix/scripts/import/stackage.scm \@@ -470,6 +472,7 @@ SCM_TESTS = \ tests/import-utils.scm \ tests/inferior.scm \ tests/lint.scm \+ tests/minetest.scm \ tests/modules.scm \ tests/monads.scm \ tests/nar.scm \diff --git a/doc/guix.texi b/doc/guix.texiindex d44ecc2005..854e282b38 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -11314,6 +11314,38 @@ and generate package expressions for all those packages that are not yet in Guix. @end table +@item contentdb+@cindex minetest+@cindex ContentDB+Import metadata from @uref{https://content.minetest.net, ContentDB}.+Information is taken from the JSON-formatted metadata provided through+@uref{https://content.minetest.net/help/api/, ContentDB's API} and+includes most relevant information, including dependencies. There are+some caveats, however. The license information is often incomplete.+The commit hash is sometimes missing. The descriptions are in the+Markdown format, but Guix uses Texinfo instead. Texture packs and+subgames are unsupported.++The command below imports metadata for the Mesecons mod by Jeija:++@example+guix import minetest Jeija/mesecons+@end example++The author name can also be left out:++@example+guix import minetest mesecons+@end example++@table @code+@item --recursive+@itemx -r+Traverse the dependency graph of the given upstream package recursively+and generate package expressions for all those packages that are not yet+in Guix.+@end table+ @item cpan @cindex CPAN Import metadata from @uref{https://www.metacpan.org/, MetaCPAN}.diff --git a/guix/import/minetest.scm b/guix/import/minetest.scmnew file mode 100644index 0000000000..e1f8487b75--- /dev/null+++ b/guix/import/minetest.scm@@ -0,0 +1,456 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>+;;;+;;; 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 receive)+ #:use-module (ice-9 threads)+ #:use-module (ice-9 hash-table)+ #:use-module (srfi srfi-1)+ #:use-module (srfi srfi-2)+ #:use-module (srfi srfi-11)+ #:use-module (srfi srfi-26)+ #:use-module (guix utils)+ #:use-module (guix ui)+ #:use-module (guix i18n)+ #:use-module (guix memoization)+ #:use-module (guix serialization)+ #:use-module (guix import utils)+ #:use-module (guix import json)+ #:use-module ((gcrypt hash) #:select (open-sha256-port port-sha256))+ #:use-module (json)+ #:use-module (guix base32)+ #:use-module (guix git)+ #:use-module (guix store)+ #:export (%default-sort-key+ %contentdb-api+ json->package+ contentdb-fetch+ elaborate-contentdb-name+ minetest->guix-package+ minetest-recursive-import+ sort-packages))++;; 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)+ (warning (G_ "~a is ambigious, presuming ~a (other options include: ~a)~%")+ 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+be \"mod\", \"game\" or \"txp\", restricting thes search results to+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)))++;; XXX adapted from (guix scripts hash)+(define (file-hash file)+ "Compute the hash of FILE."+ (let-values (((port get-hash) (open-sha256-port)))+ (write-file file port)+ (force-output port)+ (get-hash)))++(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+ (file-hash+ (download-git-repository repository+ `(commit . ,commit)))))))+ (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))+ (description ,(delete-cr description))+ (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)))++;; 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))+ (filter-map+ (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+ (G_ "The implementation with the highest score will be choosen!~%")))+ ("downloads"+ (warning+ (G_ "The implementation that has been downloaded the most will be choosen!~%"))))+ (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))++(define* (%minetest->guix-package author/name #:key (sort %default-sort-key))+ "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+ (release-title release) ; version+ (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))+ (define* (minetest->guix-package* author/name #:key repo version)+ (minetest->guix-package author/name #:sort sort))+ (recursive-import author/name+ #:repo->guix-package minetest->guix-package*+ #:guix-name contentdb->package-name))diff --git a/guix/scripts/import.scm b/guix/scripts/import.scmindex f53d1ac1f4..b369a362d0 100644--- a/guix/scripts/import.scm+++ b/guix/scripts/import.scm@@ -77,7 +77,8 @@ rather than \\n." ;;; (define importers '("gnu" "pypi" "cpan" "hackage" "stackage" "egg" "elpa"- "gem" "go" "cran" "crate" "texlive" "json" "opam"))+ "gem" "go" "cran" "crate" "texlive" "json" "opam"+ "minetest")) (define (resolve-importer name) (let ((module (resolve-interfacediff --git a/guix/scripts/import/minetest.scm b/guix/scripts/import/minetest.scmnew file mode 100644index 0000000000..5f204d90fc--- /dev/null+++ b/guix/scripts/import/minetest.scm@@ -0,0 +1,117 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2014 David Thompson <davet@gnu.org>+;;; Copyright © 2018 Ricardo Wurmus <rekado@elephly.net>+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>+;;;+;;; 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 scripts import minetest)+ #:use-module (guix ui)+ #:use-module (guix utils)+ #:use-module (guix scripts)+ #:use-module (guix import minetest)+ #:use-module (guix import utils)+ #:use-module (guix scripts import)+ #:use-module (srfi srfi-1)+ #:use-module (srfi srfi-11)+ #:use-module (srfi srfi-37)+ #:use-module (ice-9 match)+ #:use-module (ice-9 format)+ #:export (guix-import-minetest))++ +;;;+;;; Command-line options.+;;;++(define %default-options+ `((sort . ,%default-sort-key)))++(define (show-help)+ (display (G_ "Usage: guix import minetest AUTHOR/NAME+Import and convert the Minetest mod NAME by AUTHOR from ContentDB.\n"))+ (display (G_ "+ -h, --help display this help and exit"))+ (display (G_ "+ -r, --recursive import packages recursively"))+ (display (G_ "+ -V, --version display version information and exit"))+ (display (G_ "+ --sort=KEY when choosing between multiple implementations,+ choose the one with the highest value for KEY+ (one of \"score\" (standard) or \"downloads\")"))+ (newline)+ (show-bug-report-information))++(define (verify-sort-order sort)+ "Verify SORT can be used to sort mods by."+ (unless (member sort '("score" "downloads" "reviews"))+ (leave (G_ "~a: not a valid key to sort by~%") sort))+ sort)++(define %options+ ;; Specification of the command-line options.+ (cons* (option '(#\h "help") #f #f+ (lambda args+ (show-help)+ (exit 0)))+ (option '(#\V "version") #f #f+ (lambda args+ (show-version-and-exit "guix import minetest")))+ (option '(#\r "recursive") #f #f+ (lambda (opt name arg result)+ (alist-cons 'recursive #t result)))+ (option '("sort") #t #f+ (lambda (opt name arg result)+ (alist-cons 'sort (verify-sort-order arg) result)))+ %standard-import-options))++ +;;;+;;; Entry point.+;;;++(define (guix-import-minetest . args)+ (define (parse-options)+ ;; Return the alist of option values.+ (args-fold* args %options+ (lambda (opt name arg result)+ (leave (G_ "~A: unrecognized option~%") name))+ (lambda (arg result)+ (alist-cons 'argument arg result))+ %default-options))++ (let* ((opts (parse-options))+ (args (filter-map (match-lambda+ (('argument . value)+ value)+ (_ #f))+ (reverse opts))))+ (match args+ ((name)+ (with-error-handling+ (let* ((sort (assoc-ref opts 'sort))+ (author/name (elaborate-contentdb-name name #:sort sort)))+ (if (assoc-ref opts 'recursive)+ ;; Recursive import+ (filter-map package->definition+ (minetest-recursive-import author/name #:sort sort))+ ;; Single import+ (minetest->guix-package author/name #:sort sort)))))+ (()+ (leave (G_ "too few arguments~%")))+ ((many ...)+ (leave (G_ "too many arguments~%"))))))diff --git a/po/guix/POTFILES.in b/po/guix/POTFILES.inindex a3bced1a8f..f25a7b4802 100644--- a/po/guix/POTFILES.in+++ b/po/guix/POTFILES.in@@ -60,6 +60,7 @@ guix/scripts/git.scm guix/scripts/git/authenticate.scm guix/scripts/hash.scm guix/scripts/import.scm+guix/scripts/import/contentdb.scm guix/scripts/import/cran.scm guix/scripts/import/elpa.scm guix/scripts/pull.scmdiff --git a/tests/minetest.scm b/tests/minetest.scmnew file mode 100644index 0000000000..6ae476fe5f--- /dev/null+++ b/tests/minetest.scm@@ -0,0 +1,355 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>+;;;+;;; 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 (test-minetest)+ #:use-module (guix memoization)+ #:use-module (guix import minetest)+ #:use-module (guix import utils)+ #:use-module (guix tests)+ #:use-module (json)+ #:use-module (ice-9 match)+ #:use-module (srfi srfi-1)+ #:use-module (srfi srfi-26)+ #:use-module (srfi srfi-34)+ #:use-module (srfi srfi-64))++ +;; Some procedures for populating a ‘fake’ ContentDB server.++(define* (make-package-sexp #:key+ (guix-name "minetest-foo")+ (home-page "https://example.org/foo")+ (repo "https://example.org/foo.git")+ (synopsis "synopsis")+ (guix-description "description")+ (guix-license+ '(list license:cc-by-sa4.0 license:lgpl3+))+ (inputs '())+ (upstream-name "Author/foo")+ #:allow-other-keys)+ `(package+ (name ,guix-name)+ ;; This is not a proper version number but ContentDB does not include+ ;; version numbers.+ (version "2021-07-25")+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url ,(and (not (eq? repo 'null)) repo))+ (commit #f)))+ (sha256+ (base32 #f))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ ,@(maybe-propagated-inputs inputs)+ (home-page ,home-page)+ (synopsis ,synopsis)+ (description ,guix-description)+ (license ,guix-license)+ (properties+ ,(list 'quasiquote+ `((upstream-name . ,upstream-name))))))++(define* (make-package-json #:key+ (author "Author")+ (name "foo")+ (media-license "CC-BY-SA-4.0")+ (license "LGPL-3.0-or-later")+ (short-description "synopsis")+ (long-description "description")+ (repo "https://example.org/foo.git")+ (website "https://example.org/foo")+ (forums 321)+ (score 987.654)+ (downloads 123)+ (type "mod")+ #:allow-other-keys)+ `(("author" . ,author)+ ("content_warnings" . #())+ ("created_at" . "2018-05-23T19:58:07.422108")+ ("downloads" . ,downloads)+ ("forums" . ,forums)+ ("issue_tracker" . "https://example.org/foo/issues")+ ("license" . ,license)+ ("long_description" . ,long-description)+ ("maintainers" . #("maintainer"))+ ("media_license" . ,media-license)+ ("name" . ,name)+ ("provides" . #("stuff"))+ ("release" . 456)+ ("repo" . ,repo)+ ("score" . ,score)+ ("screenshots" . #())+ ("short_description" . ,short-description)+ ("state" . "APPROVED")+ ("tags" . #("some" "tags"))+ ("thumbnail" . null)+ ("title" . "The name")+ ("type" . ,type)+ ("url" . ,(string-append "https://content.minetest.net/packages/"+ author "/" name "/download/"))+ ("website" . ,website)))++(define* (make-releases-json #:key (commit #f) (title "") #:allow-other-keys)+ `#((("commit" . ,commit)+ ("downloads" . 469)+ ("id" . 8614)+ ("max_minetest_version" . null)+ ("min_minetest_version" . null)+ ("release_date" . "2021-07-25T01:10:23.207584")+ ("title" . "2021-07-25"))))++(define* (make-dependencies-json #:key (author "Author")+ (name "foo")+ (requirements '(("default" #f ())))+ #:allow-other-keys)+ `((,(string-append author "/" name)+ . ,(list->vector+ (map (match-lambda+ ((symbolic-name optional? implementations)+ `(("is_optional" . ,optional?)+ ("name" . ,symbolic-name)+ ("packages" . ,(list->vector implementations)))))+ requirements)))+ ("something/else" . #())))++(define* (make-packages-keys-json #:key (author "Author")+ (name "Name")+ (type "mod"))+ `(("author" . ,author)+ ("name" . ,name)+ ("type" . ,type)))++(define (call-with-packages thunk . argument-lists)+ ;; Don't reuse results from previous tests.+ (invalidate-memoization! contentdb-fetch)+ (invalidate-memoization! minetest->guix-package)+ (define (scm->json-port scm)+ (open-input-string (scm->json-string scm)))+ (define (handle-package url requested-author requested-name . rest)+ (define relevant-argument-list+ (any (lambda (argument-list)+ (apply (lambda* (#:key (author "Author") (name "foo")+ #:allow-other-keys)+ (and (equal? requested-author author)+ (equal? requested-name name)+ argument-list))+ argument-list))+ argument-lists))+ (when (not relevant-argument-list)+ (error "the package ~a/~a should be irrelevant, but ~a is fetched"+ requested-author requested-name url))+ (scm->json-port+ (apply (match rest+ (("") make-package-json)+ (("dependencies" "") make-dependencies-json)+ (("releases" "") make-releases-json)+ (_ (error "TODO ~a" rest)))+ relevant-argument-list)))+ (define (handle-mod-search sort)+ ;; Produce search results, sorted by SORT in descending order.+ (define arguments->key+ (match sort+ ("score" (lambda* (#:key (score 987.654) #:allow-other-keys)+ score))+ ("downloads" (lambda* (#:key (downloads 123) #:allow-other-keys)+ downloads))))+ (define argument-list->key (cut apply arguments->key <>))+ (define (greater x y)+ (> (argument-list->key x) (argument-list->key y)))+ (define sorted-argument-lists (sort-list argument-lists greater))+ (define* (arguments->json #:key (author "Author") (name "Foo") (type "mod")+ #:allow-other-keys)+ (and (string=? type "mod")+ `(("author" . ,author)+ ("name" . ,name)+ ("type" . ,type))))+ (define argument-list->json (cut apply arguments->json <>))+ (scm->json-port+ (list->vector (filter-map argument-list->json sorted-argument-lists))))+ (mock ((guix http-client) http-fetch+ (lambda* (url #:key headers)+ (unless (string-prefix? "mock://api/packages/" url)+ (error "the URL ~a should not be used" url))+ (define resource+ (substring url (string-length "mock://api/packages/")))+ (define components (string-split resource #\/))+ (match components+ ((author name . rest)+ (apply handle-package url author name rest))+ (((? (cut string-prefix? "?type=mod&q=" <>) query))+ (handle-mod-search+ (cond ((string-contains query "sort=score") "score")+ ((string-contains query "sort=downloads") "downloads")+ (#t (error "search query ~a has unknown sort key"+ query)))))+ (_+ (error "the URL ~a should have an author and name component"+ url)))))+ (parameterize ((%contentdb-api "mock://api/"))+ (thunk))))++(define* (minetest->guix-package* #:key (author "Author") (name "foo")+ (sort %default-sort-key)+ #:allow-other-keys)+ (minetest->guix-package (string-append author "/" name) #:sort sort))++(define (imported-package-sexp* primary-arguments . secondary-arguments)+ "Ask the importer to import a package specified by PRIMARY-ARGUMENTS,+during a dynamic where that package and the packages specified by+SECONDARY-ARGUMENTS are available on ContentDB."+ (apply call-with-packages+ (lambda ()+ ;; The memoization cache is reset by call-with-packages+ (apply minetest->guix-package* primary-arguments))+ primary-arguments+ secondary-arguments))++(define (imported-package-sexp . extra-arguments)+ "Ask the importer to import a package specified by EXTRA-ARGUMENTS,+during a dynamic extent where that package is available on ContentDB."+ (imported-package-sexp* extra-arguments))++(define-syntax-rule (test-package test-case . extra-arguments)+ (test-equal test-case+ (make-package-sexp . extra-arguments)+ (imported-package-sexp . extra-arguments)))++(define-syntax-rule (test-package* test-case primary-arguments extra-arguments+ ...)+ (test-equal test-case+ (apply make-package-sexp primary-arguments)+ (imported-package-sexp* primary-arguments extra-arguments ...)))++(test-begin "minetest")++ +;; Package names+(test-package "minetest->guix-package")+(test-package "minetest->guix-package, _ → - in package name"+ #:name "foo_bar"+ #:guix-name "minetest-foo-bar"+ #:upstream-name "Author/foo_bar")++(test-equal "elaborate names, unambigious"+ "Jeija/mesecons"+ (call-with-packages+ (cut elaborate-contentdb-name "mesecons")+ '(#:name "mesecons" #:author "Jeija")+ '(#:name "something" #:author "else")))++(test-equal "elaborate name, ambigious (highest score)"+ "Jeija/mesecons"+ (call-with-packages+ ;; #:sort "score" is the default+ (cut elaborate-contentdb-name "mesecons")+ '(#:name "mesecons" #:author "Jeijc" #:score 777)+ '(#:name "mesecons" #:author "Jeijb" #:score 888)+ '(#:name "mesecons" #:author "Jeija" #:score 999)))+++(test-equal "elaborate name, ambigious (most downloads)"+ "Jeija/mesecons"+ (call-with-packages+ (cut elaborate-contentdb-name "mesecons" #:sort "downloads")+ '(#:name "mesecons" #:author "Jeijc" #:downloads 777)+ '(#:name "mesecons" #:author "Jeijb" #:downloads 888)+ '(#:name "mesecons" #:author "Jeija" #:downloads 999)))++ +;; Determining the home page+(test-package "minetest->guix-package, website is used as home page"+ #:home-page "web://site"+ #:website "web://site")+(test-package "minetest->guix-package, if absent, the forum is used"+ #:home-page '(minetest-topic 628)+ #:forums 628+ #:website 'null)+(test-package "minetest->guix-package, if absent, the git repo is used"+ #:home-page "https://github.com/minetest-mods/mesecons"+ #:forums 'null+ #:website 'null+ #:repo "https://github.com/minetest-mods/mesecons")+(test-package "minetest->guix-package, all home page information absent"+ #:home-page #f+ #:forums 'null+ #:website 'null+ #:repo 'null)++ ++;; Dependencies+(test-package* "minetest->guix-package, unambigious dependency"+ (list #:requirements '(("mesecons" #f+ ("Jeija/mesecons"+ "some-modpack/containing-mese")))+ #:inputs '("minetest-mesecons"))+ (list #:author "Jeija" #:name "mesecons")+ (list #:author "some-modpack" #:name "containing-mese" #:type "modpack"))++(test-package* "minetest->guix-package, ambigious dependency (highest score)"+ (list #:name "frobnicate"+ #:guix-name "minetest-frobnicate"+ #:upstream-name "Author/frobnicate"+ #:requirements '(("frob" #f+ ("Author/foo" "Author/bar")))+ ;; #:sort "score" is the default+ #:inputs '("minetest-bar"))+ (list #:author "Author" #:name "foo" #:score 0)+ (list #:author "Author" #:name "bar" #:score 9999))++(test-package* "minetest->guix-package, ambigious dependency (most downloads)"+ (list #:name "frobnicate"+ #:guix-name "minetest-frobnicate"+ #:upstream-name "Author/frobnicate"+ #:requirements '(("frob" #f+ ("Author/foo" "Author/bar")))+ #:inputs '("minetest-bar")+ #:sort "downloads")+ (list #:author "Author" #:name "foo" #:downloads 0)+ (list #:author "Author" #:name "bar" #:downloads 9999))++(test-package "minetest->guix-package, optional dependency"+ #:requirements '(("mesecons" #t+ ("Jeija/mesecons"+ "some-modpack/containing-mese")))+ #:inputs '())++ +;; License+(test-package "minetest->guix-package, identical licenses"+ #:guix-license 'license:lgpl3++ #:license "LGPL-3.0-or-later"+ #:media-license "LGPL-3.0-or-later")++;; Sorting+(let* ((make-package+ (lambda arguments+ (json->package (apply make-package-json arguments))))+ (x (make-package #:score 0))+ (y (make-package #:score 1))+ (z (make-package #:score 2)))+ (test-equal "sort-packages, already sorted"+ (list z y x)+ (sort-packages (list z y x)))+ (test-equal "sort-packages, reverse"+ (list z y x)+ (sort-packages (list x y z))))++(test-end "minetest")-- 2.32.0
-----BEGIN PGP SIGNATURE-----
iI0EABYKADUWIQTB8z7iDFKP233XAR9J4+4iGRcl7gUCYRGJcxccbWF4aW1lZGV2b3NAdGVsZW5ldC5iZQAKCRBJ4+4iGRcl7tj+AP47AjnwF/YJKIyF8UwjSijeWoLyUgJMnWD1gOdJTtmW1gEAkTYIuELe4Sjp8txanA28UGwpIXzbSUI+PcWi2J+pHAc==xaNN-----END PGP SIGNATURE-----

M
M
Maxime Devos wrote on 9 Aug 22:04 +0200
Re: [bug#49828] [PATCH 06/20] guix: Add ContentDB importer. (XXX Don't send yet)
0268533d28206bace4f6d4364a12c22f10e67f5e.camel@telenet.be
Don't mind the subject line, I actually meant to sent thisbut forgot to remove ‘XXX Don't send yet’.
-----BEGIN PGP SIGNATURE-----
iI0EABYKADUWIQTB8z7iDFKP233XAR9J4+4iGRcl7gUCYRGKMBccbWF4aW1lZGV2b3NAdGVsZW5ldC5iZQAKCRBJ4+4iGRcl7kMoAP94ECG4SvyHowxAznsvWzJpDybyOlGSmiy6a0ztOTpAyQEAsQeHQpz1ULSYRQB5tBuGjT+brhKtglwHcAWfcxPelAg==eUav-----END PGP SIGNATURE-----

L
L
Leo Prikler wrote on 9 Aug 23:45 +0200
Re: [PATCH 06/20] guix: Add ContentDB importer. (XXX Yes send now)
16898c13929d873249c1873bc2b74d4bea07040b.camel@student.tugraz.at
Hi,
Am Montag, den 09.08.2021, 22:00 +0200 schrieb Maxime Devos:
Toggle quote (52 lines)> [...]> The URL would look like:> /packages/<author>/<name>/releases/<release>/download/.> Here, <release> is a the ‘release id’, which is an integer (e.g.> 4209). It is _not_ the version number, but it is monotonically> increasing.> > There are some problems however:> > * Old archives are sometimes deleted.> > TenPlus1/ethereal was added to ContentDB on 2018-02-23, but it > only has a single release on ContentDB, from 2021-07-28> [...]> Likewise for TenPlus1/bakedclay, TenPlus1/wine, TenPlus1/bees.> > Most other mods still have the old archives though (e.g., > Jeija/mesecons, sfan5/worldedit, PilzAdam/nether). The mods by > TenPlus1 seems to be an exception.> > * The version number is not included in the download URL, the > release id is.> So IIUC, update-package-source in (guix upstream) would still > need to be adjusted somewhat to support Minetest packages.> > +(define* (make-package-sexp #:key> > > + (guix-name "minetest-foo")> > > + (home-page "https://example.org/foo"> > > )> > > + (repo "https://example.org/foo.git")> > > + (synopsis "synopsis")> > > + (guix-description "description")> > > + (guix-license> > > + '(list license:cc-by-sa4.0> > > license:lgpl3+))> > > + (inputs '())> > > + (upstream-name "Author/foo")> > > + #:allow-other-keys)> > > + [...]> > As noted above, this procedure would be somewhat simplified if we> > could define a (mintest-uri).> > > > I don't see how a 'minetest-uri' would simplify the definition of> 'make-package-sexp'. Using 'minetest-uri' would avoid the need> to specify the commit, but 'minetest-uri' needs a release id anyway,> so no simplification there.> > I guess it would avoid the 'download-git-repository' procedure> and 'vcs-file?', but see two points above. Also, 'latest-repository-> commit' returns a store path, which does not include the '.git'> directory, so 'vcs-file?' isn't necessary, so I removed 'vcs-file?'.
In other words, taking minetest-uri as is currently doesn't seem toogood of an idea. Does the plain git/vcs updater work for thosepackages then? I assume at least some of the packages should be taggedproperly in git, are they not?
Toggle quote (12 lines)> [...]> I like the name 'package-full-name'. <package> and <package-keys> > are rather different structures and used in different contexts> though, so I kept package-full-name and package-keys-full-name> separate.> > FWIW, I added a procedure> > (define (%construct-full-name author name)> (string-append author "/" name))> > used by 'package-full-name' and 'package-keys-full-name'.
Sounds good to me.
Toggle quote (23 lines)> > > +(define (contentdb->package-name name)> > > + "Given the 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 name)))> > I'd at least add an option to generate full names instead, for> > cases in> > which as before we warn about non-uniqueness. Though actually,> > this> > comment is a little misleading as the actual stripping happens...> > > + (name ,(contentdb->package-name (author/name->name> > > author/name)))> > here> > ContentDB has a policy of requiring mod names to be unique in order> to be a ‘approved’, so I don't think name conflict will be a problem> in practice. If full names were generated, keep in mind that> dependencies would need to use the full names a well. I couldn't> find any mods with name conflicts. I would just emit a warning for> now.
Fair enough, if that requirement is actually enforced by ContentDB,that's good. It does make the AUTHOR/NAME URI syntax look a bit weirdtho.
Toggle quote (3 lines)> contentdb->package-name was always used together with 'author/name-> >name', so I modified contentdb->package-name to call author/name-> >name as you seem to suggest. It maked the code a little simpler.
Well, that's one way of resolving this issue, another would have beento move the comment to where it makes sense.
All in all, I think I'm rather content with this patch now, but I havea final nitpick w.r.t the updater. "upstream-name" is a weird name fora property that will supposedly be used by only one updater (and evenif different updaters were to use it, would not each one have slightlydifferent, but perhaps sometimes overlapping expectations for thatfield?) I think a better solution would be to set home-page to theContentDB page, assuming that is acceptable. If not, perhaps having a"refresh-url" that is well defined over all refreshers and supersedeshome-page if specified might be a more appropriate solution.
WDYT?
M
M
Maxime Devos wrote on 10 Aug 13:02 +0200
Re: [PATCH 06/20] guix: Add ContentDB importer.
c754f97a29f31dc4724cd38fc61fee3cca734d71.camel@telenet.be
Hi,
I re-ran "./pre-inst-env guix build [all-minetest-mods]" and it turnsout "minetest-unified-inventory" retains a reference to the correspondinggit checkout. Using 'strip-store-file-name' instead of 'basename'in 'guess-mod-name' in ‘build-system: Add 'minetest-mod-build-system'’fixed this.
Leo Prikler schreef op ma 09-08-2021 om 23:45 [+0200]:
Toggle quote (8 lines)> Hi,> > [...]> In other words, taking minetest-uri as is currently doesn't seem too> good of an idea. Does the plain git/vcs updater work for those> packages then? I assume at least some of the packages should be tagged> properly in git, are they not?
FWIW, there is no git/vcs updater, but there is a GitHub updater(a git updater looking at tags in a git repository if the packageorigin uses the git-fetch method could be written though).
The GitHub updater could theoretically work, but look at the output:
./pre-inst-env guix refresh minetest-{unified-inventory,unifieddyes,worldedit,throwing-arrows,throwing,technic,pipeworks,mobs-animal,mobs,mesecons,homedecor-modpack,ethereal,coloredwood,basic-materials}
gnu/packages/minetest.scm:29:2: warning: no updater for minetest-basic-materialsgnu/packages/minetest.scm:54:2: warning: no updater for minetest-coloredwoodgnu/packages/minetest.scm:87:4: warning: no updater for minetest-etherealgnu/packages/minetest.scm:111:2: warning: no updater for minetest-homedecor-modpackgnu/packages/minetest.scm:147:13: minetest-mesecons would be upgraded from 1.2.1-0.db58797 to 2017.03.05gnu/packages/minetest.scm:178:2: warning: no updater for minetest-mobsgnu/packages/minetest.scm:207:2: warning: no updater for minetest-mobs-animalgnu/packages/minetest.scm:234:2: warning: no updater for minetest-pipeworksgnu/packages/minetest.scm:265:2: warning: 'github' updater failed to determine available releases for minetest-technicgnu/packages/minetest.scm:302:13: warning: 2020-08-14 is greater than the latest known version of minetest-throwing (1.1)gnu/packages/minetest.scm:330:15: warning: 1.1-0.059cc89 is greater than the latest known version of minetest-throwing-arrows (1.1)gnu/packages/minetest.scm:355:13: 1.3 is already the latest version of minetest-worldeditgnu/packages/minetest.scm:376:2: warning: no updater for minetest-unifieddyesgnu/packages/minetest.scm:408:13: minetest-unified-inventory would be upgraded from 2021-03-25-1 to 20180810
Apparently, the git repos of minetest mods often don't keep version numbers,or aren't on github, or uses multiple version schemes simultanuously(x.y[.z] version numbers + dates) ... "minetest-worldedit" is properlytagged though. For the other cases, an updater for ContentDB packagesmay be required.
I modified the definition of 'minetest-throwing' to use "1.1" as 'version'(the commit remains the same).
Toggle quote (10 lines)> All in all, I think I'm rather content with this patch now, but I have> a final nitpick w.r.t the updater. "upstream-name" is a weird name for> a property that will supposedly be used by only one updater (and even> if different updaters were to use it, would not each one have slightly> different, but perhaps sometimes overlapping expectations for that> field?) I think a better solution would be to set home-page to the> ContentDB page, assuming that is acceptable. If not, perhaps having a> "refresh-url" that is well defined over all refreshers and supersedes> home-page if specified might be a more appropriate solution.
'upstream-name' is used by the refresher of "egg", "cpan" and "opam".I searched for "package-properties" in (guix import ...), and the onlypackage property used by refreshers in 'upstream-name'. So usinganything other than 'upstream-name' for Minetest would be unusual.
The documentation of "guix refresh" mentions:
Sometimes the upstream name differs from the package name used inGuix, and ‘guix refresh’ needs a little help. Most updaters honor the‘upstream-name’ property in package definitions, which can be used tothat effect:
(define-public network-manager (package (name "network-manager") ;; ... (properties '((upstream-name . "NetworkManager")))))
So using a different package property than 'upstream-name' wouldbe unexpected.
I assume 'refresh-url' would be"https://content.minetest.net/api/packages/AUTHOR/NAME"for minetestpackages, "https://github.com/ocaml/opam-repository/packages/NAME"for opam packages? That seems rather verbose though, and everyrefresher would have a different idea of how to fetch the packagedescription from the URL and interpret it, so this doesn't seemto be an improvement over 'upstream-name' to me.
About pointing the home page to content.minetest.net: that wouldwork for the refresher, but the ContentDB page isn't really thehome page, not unlike how the pypi page for python packages isn'tthe home page. Likewise for opam and ocaml. Compare
https://content.minetest.net/packages/Jeija/mesecons/
with https://mesecons.net/,which one seems more ‘homey’? I'dsay the latter is the home page.
The revised patch series is attached. Only‘build-system: Add 'minetest-mod-build-system'’ and ‘gnu: Add minetest-throwing’have been changed. It can also be found athttps://notabug.org/maximed/guix-gnunet/src/minetest-3.
Greetings,Maxime.
From 292dce14ea4811f1554965d83af5e33687cd00b7 Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sat, 31 Jul 2021 14:50:32 +0200Subject: [PATCH 01/20] gnu: minetest: Respect --without-tests.
* gnu/packages/games.scm (minetest)[arguments]<#:phases>{check}: Use 'tests?' instead of ',(%current-target-system)'. Remove trailing #t.--- gnu/packages/games.scm | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
Toggle diff (23 lines)diff --git a/gnu/packages/games.scm b/gnu/packages/games.scmindex 8c6b5523f1..3e7086b398 100644--- a/gnu/packages/games.scm+++ b/gnu/packages/games.scm@@ -3590,13 +3590,12 @@ match, cannon keep, and grave-itation pit.") (string-append (getcwd) "/games")) ; for check #t)) (replace 'check- (lambda _+ (lambda* (#:key tests? #:allow-other-keys) ;; Thanks to our substitutions, the tests should also run ;; when invoked on the target outside of `guix build'.- (unless ,(%current-target-system)+ (when tests? (setenv "HOME" "/tmp")- (invoke "src/minetest" "--run-unittests"))- #t)))))+ (invoke "src/minetest" "--run-unittests"))))))) (native-search-paths (list (search-path-specification (variable "MINETEST_SUBGAME_PATH")-- 2.32.0
From 54222f167107e36cb76f93c551aaee0659d17b40 Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sat, 31 Jul 2021 18:08:44 +0200Subject: [PATCH 02/20] gnu: minetest: Search for mods in MINETEST_MOD_PATH.
* gnu/packages/patches/Add-environment-variable-MINETEST_MOD_PATH.patch: New file.* gnu/packages/games.scm (minetest)[source]{patches}: Add it. (minetest)[native-search-paths]: Add "MINETEST_MOD_PATH".* gnu/local.mk (dist_patch_DATA): Add the patch.--- gnu/local.mk | 1 + gnu/packages/games.scm | 8 +- ...vironment-variable-MINETEST_MOD_PATH.patch | 156 ++++++++++++++++++ 3 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 gnu/packages/patches/Add-environment-variable-MINETEST_MOD_PATH.patch
Toggle diff (202 lines)diff --git a/gnu/local.mk b/gnu/local.mkindex c80a9af78c..d96d4e3dbc 100644--- a/gnu/local.mk+++ b/gnu/local.mk@@ -801,6 +801,7 @@ dist_patch_DATA = \ %D%/packages/patches/abseil-cpp-fix-gtest.patch \ %D%/packages/patches/abseil-cpp-fix-strerror_test.patch \ %D%/packages/patches/adb-add-libraries.patch \+ %D%/packages/patches/Add-environment-variable-MINETEST_MOD_PATH.patch \ %D%/packages/patches/aegis-constness-error.patch \ %D%/packages/patches/aegis-perl-tempdir1.patch \ %D%/packages/patches/aegis-perl-tempdir2.patch \diff --git a/gnu/packages/games.scm b/gnu/packages/games.scmindex 3e7086b398..48d46a0379 100644--- a/gnu/packages/games.scm+++ b/gnu/packages/games.scm@@ -3553,6 +3553,9 @@ match, cannon keep, and grave-itation pit.") (base32 "062ilb7s377q3hwfhl8q06vvcw2raydz5ljzlzwy2dmyzmdcndb8")) (modules '((guix build utils)))+ (patches+ (search-patches+ "Add-environment-variable-MINETEST_MOD_PATH.patch")) (snippet '(begin ;; Delete bundled libraries.@@ -3599,7 +3602,10 @@ match, cannon keep, and grave-itation pit.") (native-search-paths (list (search-path-specification (variable "MINETEST_SUBGAME_PATH")- (files '("share/minetest/games")))))+ (files '("share/minetest/games")))+ (search-path-specification+ (variable "MINETEST_MOD_PATH")+ (files '("share/minetest/mods"))))) (native-inputs `(("pkg-config" ,pkg-config))) (inputsdiff --git a/gnu/packages/patches/Add-environment-variable-MINETEST_MOD_PATH.patch b/gnu/packages/patches/Add-environment-variable-MINETEST_MOD_PATH.patchnew file mode 100644index 0000000000..a74034a2c5--- /dev/null+++ b/gnu/packages/patches/Add-environment-variable-MINETEST_MOD_PATH.patch@@ -0,0 +1,156 @@+From d10ea2ad7efc2364a8a2007b4c6d3e85511e2f84 Mon Sep 17 00:00:00 2001+From: Maxime Devos <maximedevos@telenet.be>+Date: Tue, 3 Aug 2021 01:00:23 +0200+Subject: [PATCH] Add environment variable MINETEST_MOD_PATH++This adds an environment variable MINETEST_MOD_PATH.+When it exists, Minetest will look there for mods+in addition to ~/.minetest/mods/. Mods can still be+installed to ~/.minetest/mods/ with the built-in installer.++With thanks to Leo Prikler.+---+ builtin/mainmenu/pkgmgr.lua | 7 +++----+ doc/menu_lua_api.txt | 8 +++++++-+ src/content/subgames.cpp | 11 ++++++++++++ src/script/lua_api/l_mainmenu.cpp | 23 ++++++++++++++++++++++++ src/script/lua_api/l_mainmenu.h | 2 +++ 5 files changed, 46 insertions(+), 5 deletions(-)++diff --git a/builtin/mainmenu/pkgmgr.lua b/builtin/mainmenu/pkgmgr.lua+index 787936e31..d8fba0ebe 100644+--- a/builtin/mainmenu/pkgmgr.lua++++ b/builtin/mainmenu/pkgmgr.lua+@@ -682,10 +682,9 @@ function pkgmgr.preparemodlist(data)+ local game_mods = {}+ + --read global mods+- local modpath = core.get_modpath()+-+- if modpath ~= nil and+- modpath ~= "" then++ local modpaths = core.get_modpaths()++ --XXX what was ‘modpath ~= ""’ and ‘modpath ~= nil’ for?++ for _,modpath in ipairs(modpaths) do+ get_mods(modpath,global_mods)+ end+ +diff --git a/doc/menu_lua_api.txt b/doc/menu_lua_api.txt+index b3975bc1d..132444b14 100644+--- a/doc/menu_lua_api.txt++++ b/doc/menu_lua_api.txt+@@ -218,7 +218,13 @@ Package - content which is downloadable from the content db, may or may not be i+ * returns path to global user data,+ the directory that contains user-provided mods, worlds, games, and texture packs.+ * core.get_modpath() (possible in async calls)+- * returns path to global modpath++ * returns path to global modpath, where mods can be installed++* core.get_modpaths() (possible in async calls)++ * returns list of paths to global modpaths, where mods have been installed++++ The difference with "core.get_modpath" is that no mods should be installed in these++ directories by Minetest -- they might be read-only.+++ * core.get_clientmodpath() (possible in async calls)+ * returns path to global client-side modpath+ * core.get_gamepath() (possible in async calls)+diff --git a/src/content/subgames.cpp b/src/content/subgames.cpp+index e9dc609b0..d73f95a1f 100644+--- a/src/content/subgames.cpp++++ b/src/content/subgames.cpp+@@ -61,6 +61,12 @@ std::string getSubgamePathEnv()+ return subgame_path ? std::string(subgame_path) : "";+ }+ ++std::string getModPathEnv()++{++ char *mod_path = getenv("MINETEST_MOD_PATH");++ return mod_path ? std::string(mod_path) : "";++}+++ SubgameSpec findSubgame(const std::string &id)+ {+ if (id.empty())+@@ -110,6 +116,11 @@ SubgameSpec findSubgame(const std::string &id)+ std::set<std::string> mods_paths;+ if (!user_game)+ mods_paths.insert(share + DIR_DELIM + "mods");++++ Strfnd mod_search_paths(getModPathEnv());++ while (!mod_search_paths.at_end())++ mods_paths.insert(mod_search_paths.next(PATH_DELIM));+++ if (user != share || user_game)+ mods_paths.insert(user + DIR_DELIM + "mods");+ +diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp+index 3e9709bde..903ac3a22 100644+--- a/src/script/lua_api/l_mainmenu.cpp++++ b/src/script/lua_api/l_mainmenu.cpp+@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,+ #include "lua_api/l_internal.h"+ #include "common/c_content.h"+ #include "cpp_api/s_async.h"++#include "util/strfnd.h"+ #include "gui/guiEngine.h"+ #include "gui/guiMainMenu.h"+ #include "gui/guiKeyChangeMenu.h"+@@ -502,6 +503,26 @@ int ModApiMainMenu::l_get_modpath(lua_State *L)+ return 1;+ }+ ++/******************************************************************************/++int ModApiMainMenu::l_get_modpaths(lua_State *L)++{++ const char *c_modpath = getenv("MINETEST_MOD_PATH");++ if (c_modpath == NULL)++ c_modpath = "";++ int index = 1;++ lua_newtable(L);++ Strfnd mod_search_paths{std::string(c_modpath)};++ while (!mod_search_paths.at_end()) {++ std::string component = mod_search_paths.next(PATH_DELIM);++ lua_pushstring(L, component.c_str());++ lua_rawseti(L, -2, index);++ index++;++ }++ ModApiMainMenu::l_get_modpath(L);++ lua_rawseti(L, -2, index);++ return 1;++}+++ /******************************************************************************/+ int ModApiMainMenu::l_get_clientmodpath(lua_State *L)+ {+@@ -949,6 +970,7 @@ void ModApiMainMenu::Initialize(lua_State *L, int top)+ API_FCT(get_mapgen_names);+ API_FCT(get_user_path);+ API_FCT(get_modpath);++ API_FCT(get_modpaths);+ API_FCT(get_clientmodpath);+ API_FCT(get_gamepath);+ API_FCT(get_texturepath);+@@ -983,6 +1005,7 @@ void ModApiMainMenu::InitializeAsync(lua_State *L, int top)+ API_FCT(get_mapgen_names);+ API_FCT(get_user_path);+ API_FCT(get_modpath);++ API_FCT(get_modpaths);+ API_FCT(get_clientmodpath);+ API_FCT(get_gamepath);+ API_FCT(get_texturepath);+diff --git a/src/script/lua_api/l_mainmenu.h b/src/script/lua_api/l_mainmenu.h+index 33ac9e721..a6a54a2cb 100644+--- a/src/script/lua_api/l_mainmenu.h++++ b/src/script/lua_api/l_mainmenu.h+@@ -112,6 +112,8 @@ class ModApiMainMenu: public ModApiBase+ + static int l_get_modpath(lua_State *L);+ ++ static int l_get_modpaths(lua_State *L);+++ static int l_get_clientmodpath(lua_State *L);+ + static int l_get_gamepath(lua_State *L);+-- +2.32.0+-- 2.32.0
From f5148ad853b113db84634912c3eaa936d689eb22 Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sat, 31 Jul 2021 18:32:50 +0200Subject: [PATCH 03/20] gnu: minetest: New package module.
Aside from the 'minetest-topic' procedure which will be usedfor the 'home-page' field of some packages, this module iscurrently empty. The 'contentdb' importer defined in thefollowing patches will be used to populate this module.
* gnu/packages/minetest.scm: New file.* gnu/local.mk (GNU_SYSTEM_MODULES): Add it.--- gnu/local.mk | 1 + gnu/packages/minetest.scm | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 gnu/packages/minetest.scm
Toggle diff (46 lines)diff --git a/gnu/local.mk b/gnu/local.mkindex d96d4e3dbc..5de08b1b09 100644--- a/gnu/local.mk+++ b/gnu/local.mk@@ -383,6 +383,7 @@ GNU_SYSTEM_MODULES = \ %D%/packages/mercury.scm \ %D%/packages/mes.scm \ %D%/packages/messaging.scm \+ %D%/packages/minetest.scm \ %D%/packages/mingw.scm \ %D%/packages/microcom.scm \ %D%/packages/moe.scm \diff --git a/gnu/packages/minetest.scm b/gnu/packages/minetest.scmnew file mode 100644index 0000000000..f8aca3005c--- /dev/null+++ b/gnu/packages/minetest.scm@@ -0,0 +1,26 @@+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>+;;; 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 (gnu packages minetest)+ #:use-module (guix packages)+ #:use-module (guix git-download)+ #:use-module (guix build-system minetest)+ #:use-module ((guix licenses) #:prefix license:))++(define-public (minetest-topic topic-id)+ "Return an URL (as a string) pointing to the forum topic with+numeric identifier TOPIC-ID on the official Minetest forums."+ (string-append "https://forum.minetest.net/viewtopic.php?t="+ (number->string topic-id)))-- 2.32.0
From 545499de52c6869df498b0df5d5b403d05448fe3 Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sat, 31 Jul 2021 13:52:39 +0200Subject: [PATCH 04/20] build-system: Add 'minetest-mod-build-system'.
* guix/build-system/minetest.scm: New module.* guix/build/minetest-build-system.scm: Likewise.* Makefile.am (MODULES): Add them.* doc/guix.texi (Build Systems): Document 'minetest-mod-build-system'.--- Makefile.am | 2 + doc/guix.texi | 8 + guix/build-system/minetest.scm | 99 ++++++++++++ guix/build/minetest-build-system.scm | 226 +++++++++++++++++++++++++++ 4 files changed, 335 insertions(+) create mode 100644 guix/build-system/minetest.scm create mode 100644 guix/build/minetest-build-system.scm
Toggle diff (378 lines)diff --git a/Makefile.am b/Makefile.amindex d5ec909213..f4439ce93b 100644--- a/Makefile.am+++ b/Makefile.am@@ -141,6 +141,7 @@ MODULES = \ guix/build-system/go.scm \ guix/build-system/meson.scm \ guix/build-system/minify.scm \+ guix/build-system/minetest.scm \ guix/build-system/asdf.scm \ guix/build-system/copy.scm \ guix/build-system/glib-or-gtk.scm \@@ -203,6 +204,7 @@ MODULES = \ guix/build/gnu-dist.scm \ guix/build/guile-build-system.scm \ guix/build/maven-build-system.scm \+ guix/build/minetest-build-system.scm \ guix/build/node-build-system.scm \ guix/build/perl-build-system.scm \ guix/build/python-build-system.scm \diff --git a/doc/guix.texi b/doc/guix.texiindex b3c16e6507..d44ecc2005 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -7895,6 +7895,14 @@ declaration. Its default value is @code{(default-maven-plugins)} which is also exported. @end defvr +@defvr {Scheme Variable} minetest-mod-build-system+This variable is exported by @code{(guix build-system minetest)}. It+implements a build procedure for @uref{https://www.minetest.net, Minetest}+mods, which consists of copying Lua code, images and other resources to+the location Minetest searches for mods. The build system also minimises+PNG images and verifies that Minetest can load the mod without errors.+@end defvr+ @defvr {Scheme Variable} minify-build-system This variable is exported by @code{(guix build-system minify)}. It implements a minification procedure for simple JavaScript packages.diff --git a/guix/build-system/minetest.scm b/guix/build-system/minetest.scmnew file mode 100644index 0000000000..f33e97559d--- /dev/null+++ b/guix/build-system/minetest.scm@@ -0,0 +1,99 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>+;;;+;;; 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 build-system minetest)+ #:use-module (guix build-system copy)+ #:use-module (guix build-system gnu)+ #:use-module (guix build-system)+ #:use-module (guix utils)+ #:export (minetest-mod-build-system))++;;+;; Build procedure for minetest mods. This is implemented as an extension+;; of ‘copy-build-system’.+;;+;; Code:++;; Lazily resolve the bindings to avoid circular dependencies.+(define (default-optipng)+ ;; Lazily resolve the binding to avoid a circular dependency.+ (module-ref (resolve-interface '(gnu packages image)) 'optipng))++(define (default-minetest)+ (module-ref (resolve-interface '(gnu packages games)) 'minetest))++(define (default-xvfb-run)+ (module-ref (resolve-interface '(gnu packages xorg)) 'xvfb-run))++(define %minetest-build-system-modules+ ;; Build-side modules imported by default.+ `((guix build minetest-build-system)+ ,@%copy-build-system-modules))++(define %default-modules+ ;; Modules in scope in the build-side environment.+ '((guix build gnu-build-system)+ (guix build minetest-build-system)+ (guix build utils)))++(define (standard-minetest-packages)+ "Return the list of (NAME PACKAGE OUTPUT) or (NAME PACKAGE) tuples of+standard packages used as implicit inputs of the Minetest build system."+ `(("xvfb-run" ,(default-xvfb-run))+ ("optipng" ,(default-optipng))+ ("minetest" ,(default-minetest))+ ,@(filter (lambda (input)+ (member (car input)+ '("libc" "tar" "gzip" "bzip2" "xz" "locales")))+ (standard-packages))))++(define* (lower-mod name #:key (implicit-inputs? #t) #:allow-other-keys+ #:rest arguments)+ (define lower (build-system-lower gnu-build-system))+ (apply lower+ name+ (substitute-keyword-arguments arguments+ ;; minetest-mod-build-system adds implicit inputs by itself,+ ;; so don't let gnu-build-system add its own implicit inputs+ ;; as well.+ ((#:implicit-inputs? implicit-inputs? #t)+ #f)+ ((#:implicit-cross-inputs? implicit-cross-inputs? #t)+ #f)+ ((#:imported-modules imported-modules %minetest-build-system-modules)+ imported-modules)+ ((#:modules modules %default-modules)+ modules)+ ((#:phases phases '%standard-phases)+ phases)+ ;; Ensure nothing sneaks into the closure.+ ((#:allowed-references allowed-references '())+ allowed-references)+ ;; Add the implicit inputs.+ ((#:native-inputs native-inputs '())+ (if implicit-inputs?+ (append native-inputs (standard-minetest-packages))+ native-inputs)))))++(define minetest-mod-build-system+ (build-system+ (name 'minetest-mod)+ (description "The build system for minetest mods")+ (lower lower-mod)))++;;; minetest.scm ends herediff --git a/guix/build/minetest-build-system.scm b/guix/build/minetest-build-system.scmnew file mode 100644index 0000000000..4968d3f560--- /dev/null+++ b/guix/build/minetest-build-system.scm@@ -0,0 +1,226 @@+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>+;;;+;;; 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 build minetest-build-system)+ #:use-module (guix build utils)+ #:use-module (srfi srfi-1)+ #:use-module (ice-9 format)+ #:use-module (ice-9 match)+ #:use-module (ice-9 rdelim)+ #:use-module (ice-9 receive)+ #:use-module (ice-9 regex)+ #:use-module ((guix build gnu-build-system) #:prefix gnu:)+ #:use-module ((guix build copy-build-system) #:prefix copy:)+ #:export (%standard-phases+ mod-install-plan minimise-png read-mod-name check))++;; (guix build copy-build-system) does not export 'install'.+(define copy:install+ (assoc-ref copy:%standard-phases 'install))++(define (mod-install-plan mod-name)+ `(("." ,(string-append "share/minetest/mods/" mod-name)+ ;; Only install files that will actually be used at run time.+ ;; This can save a little disk space.+ ;;+ ;; See <https://github.com/minetest/minetest/blob/master/doc/lua_api.txt>+ ;; for an incomple list of files that can be found in mods.+ #:include ("mod.conf" "modpack.conf" "settingtypes.txt" "depends.txt"+ "description.txt")+ #:include-regexp (".lua$" ".png$" ".ogg$" ".obj$" ".b3d$" ".tr$"+ ".mts$"))))++(define* (guess-mod-name #:key inputs #:allow-other-keys)+ "Try to determine the name of the mod or modpack that is being built.+If it is unknown, make an educated guess."+ ;; Minetest doesn't care about the directory names in "share/minetest/mods"+ ;; so there is no technical problem if the directory names don't match+ ;; the mod names. The directory can appear in the GUI if the modpack+ ;; doesn't have the 'name' set though, so try to make the guess.+ (define (guess)+ (let* ((source (assoc-ref inputs "source"))+ ;; Don't retain a reference to the store.+ (file-name (strip-store-file-name source))+ ;; The "minetest-" prefix is not informative, so strip it.+ (file-name (if (string-prefix? "minetest-" file-name)+ (substring file-name (string-length "minetest-"))+ file-name))+ ;; Strip "-checkout" suffixes of git checkouts.+ (file-name (if (string-suffix? "-checkout" file-name)+ (substring file-name+ 0+ (- (string-length file-name)+ (string-length "-minetest")))+ file-name))+ (first-dot (string-index file-name #\.))+ ;; If the source code is in an archive (.tar.gz, .zip, ...),+ ;; strip the extension.+ (file-name (if first-dot+ (substring file-name 0 first-dot)+ file-name)))+ (format (current-error-port)+ "warning: the modpack ~a did not set 'name' in 'modpack.conf'~%"+ file-name)+ file-name))+ (cond ((file-exists? "mod.conf")+ (read-mod-name "mod.conf"))+ ((file-exists? "modpack.conf")+ (read-mod-name "modpack.conf" guess))+ (#t (guess))))++(define* (install #:key inputs #:allow-other-keys #:rest arguments)+ (apply copy:install+ #:install-plan (mod-install-plan (apply guess-mod-name arguments))+ arguments))++(define %png-magic-bytes+ ;; Magic bytes of PNG images, see ‘5.2 PNG signatures’ in+ ;; ‘Portable Network Graphics (PNG) Specification (Second Edition)’+ ;; on <https://www.w3.org/TR/PNG/>.+ #vu8(137 80 78 71 13 10 26 10))++(define png-file?+ ((@@ (guix build utils) file-header-match) %png-magic-bytes))++(define* (minimise-png #:key inputs native-inputs #:allow-other-keys)+ "Minimise PNG images found in the working directory."+ (define optipng (which "optipng"))+ (define (optimise image)+ (format #t "Optimising ~a~%" image)+ (make-file-writable (dirname image))+ (make-file-writable image)+ (define old-size (stat:size (stat image)))+ ;; The mod "technic" has a file "technic_music_player_top.png" that+ ;; actually is a JPEG file, see+ ;; <https://github.com/minetest-mods/technic/issues/590>.+ (if (png-file? image)+ (invoke optipng "-o4" "-quiet" image)+ (format #t "warning: skipping ~a because it's not actually a PNG image~%"+ image))+ (define new-size (stat:size (stat image)))+ (values old-size new-size))+ (define files (find-files "." ".png$"))+ (let loop ((total-old-size 0)+ (total-new-size 0)+ (images (find-files "." ".png$")))+ (cond ((pair? images)+ (receive (old-size new-size)+ (optimise (car images))+ (loop (+ total-old-size old-size)+ (+ total-new-size new-size)+ (cdr images))))+ ((= total-old-size 0)+ (format #t "There were no PNG images to minimise."))+ (#t+ (format #t "Minimisation reduced size of images by ~,2f% (~,2f MiB to ~,2f MiB)~%"+ (* 100.0 (- 1 (/ total-new-size total-old-size)))+ (/ total-old-size (expt 1024 2))+ (/ total-new-size (expt 1024 2)))))))++(define name-regexp (make-regexp "^name[ ]*=(.+)$"))++(define* (read-mod-name mod.conf #:optional not-found)+ "Read the name of a mod from MOD.CONF. If MOD.CONF+does not have a name field and NOT-FOUND is #false, raise an+error. If NOT-FOUND is TRUE, call NOT-FOUND instead."+ (call-with-input-file mod.conf+ (lambda (port)+ (let loop ()+ (define line (read-line port))+ (if (eof-object? line)+ (if not-found+ (not-found)+ (error "~a does not have a 'name' field" mod.conf))+ (let ((match (regexp-exec name-regexp line)))+ (if (regexp-match? match)+ (string-trim-both (match:substring match 1) #\ )+ (loop))))))))++(define* (check #:key outputs tests? #:allow-other-keys)+ "Test whether the mod loads. The mod must first be installed first."+ (define (all-mod-names directories)+ (append-map+ (lambda (directory)+ (map read-mod-name (find-files directory "mod.conf")))+ directories))+ (when tests?+ (mkdir "guix_testworld")+ ;; Add the mod to the mod search path, such that Minetest can find it.+ (setenv "MINETEST_MOD_PATH"+ (list->search-path-as-string+ (cons+ (string-append (assoc-ref outputs "out") "/share/minetest/mods")+ (search-path-as-string->list+ (or (getenv "MINETEST_MOD_PATH") "")))+ ":"))+ (with-directory-excursion "guix_testworld"+ (setenv "HOME" (getcwd))+ ;; Create a world in which all mods are loaded.+ (call-with-output-file "world.mt"+ (lambda (port)+ (display+ "gameid = minetest+world_name = guix_testworld+backend = sqlite3+player_backend = sqlite3+auth_backend = sqlite3+" port)+ (for-each+ (lambda (mod)+ (format port "load_mod_~a = true~%" mod))+ (all-mod-names (search-path-as-string->list+ (getenv "MINETEST_MOD_PATH"))))))+ (receive (port pid)+ ((@@ (guix build utils) open-pipe-with-stderr)+ "xvfb-run" "--" "minetest" "--info" "--world" "." "--go")+ (format #t "Started Minetest with all mods loaded for testing~%")+ ;; Scan the output for error messages.+ ;; When the player has joined the server, stop minetest.+ (define (error? line)+ (and (string? line)+ (string-contains line ": ERROR[")))+ (define (stop? line)+ (and (string? line)+ (string-contains line "ACTION[Server]: singleplayer [127.0.0.1] joins game.")))+ (let loop ()+ (match (read-line port)+ ((? error? line)+ (error "minetest raised an error: ~a" line))+ ((? stop?)+ (kill pid SIGINT)+ (close-port port)+ (waitpid pid))+ ((? string? line)+ (display line)+ (newline)+ (loop))+ ((? eof-object?)+ (error "minetest didn't start"))))))))++(define %standard-phases+ (modify-phases gnu:%standard-phases+ (delete 'bootstrap)+ (delete 'configure)+ (add-before 'build 'minimise-png minimise-png)+ (delete 'build)+ (delete 'check)+ (replace 'install install)+ ;; The 'check' phase requires the mod to be installed,+ ;; so move the 'check' phase after the 'install' phase.+ (add-after 'install 'check check)))++;;; minetest-build-system.scm ends here-- 2.32.0
From 8cf2245d9ecdd6f8dd65d5bf2b9bf6532511ca5b Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Thu, 5 Aug 2021 21:00:41 +0200Subject: [PATCH 05/20] import/utils: Recognise GPL-3.0-or-later and friends.
* guix/import/utils.scm (spdx-string->license): Recognise GPL-N-only and GPL-N-or-later. Likewise for LGPL and AGPL.--- guix/import/utils.scm | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
Toggle diff (57 lines)diff --git a/guix/import/utils.scm b/guix/import/utils.scmindex d817318a91..d1b8076ddd 100644--- a/guix/import/utils.scm+++ b/guix/import/utils.scm@@ -133,8 +133,14 @@ of the string VERSION is replaced by the symbol 'version." ;; Please update guix/licenses.scm when modifying ;; this list to avoid mismatches. (match str+ ;; "GPL-N+" has been deprecated in favour of "GPL-N-or-later".+ ;; "GPL-N" has been deprecated in favour of "GPL-N-only"+ ;; or "GPL-N-or-later" as appropriate. Likewise for LGPL+ ;; and AGPL ("AGPL-1.0" 'license:agpl1) ("AGPL-3.0" 'license:agpl3)+ ("AGPL-3.0-only" 'license:agpl3)+ ("AGPL-3.0-or-later" 'license:agpl3+) ("Apache-1.1" 'license:asl1.1) ("Apache-2.0" 'license:asl2.0) ("BSL-1.0" 'license:boost1.0)@@ -161,11 +167,17 @@ of the string VERSION is replaced by the symbol 'version." ("GFDL-1.3" 'license:fdl1.3+) ("Giftware" 'license:giftware) ("GPL-1.0" 'license:gpl1)+ ("GPL-1.0-only" 'license:gpl1) ("GPL-1.0+" 'license:gpl1+)+ ("GPL-1.0-or-later" 'license:gpl1+) ("GPL-2.0" 'license:gpl2)+ ("GPL-2.0-only" 'license:gpl2) ("GPL-2.0+" 'license:gpl2+)+ ("GPL-2.0-or-later" 'license:gpl2+) ("GPL-3.0" 'license:gpl3)+ ("GPL-3.0-only" 'license:gpl3) ("GPL-3.0+" 'license:gpl3+)+ ("GPL-3.0-or-later" 'license:gpl3+) ("ISC" 'license:isc) ("IJG" 'license:ijg) ("Imlib2" 'license:imlib2)@@ -173,11 +185,17 @@ of the string VERSION is replaced by the symbol 'version." ("IPL-1.0" 'license:ibmpl1.0) ("LAL-1.3" 'license:lal1.3) ("LGPL-2.0" 'license:lgpl2.0)+ ("LGPL-2.0-only" 'license:lgpl2.0) ("LGPL-2.0+" 'license:lgpl2.0+)+ ("LGPL-2.0-or-later" 'license:lgpl2.0+) ("LGPL-2.1" 'license:lgpl2.1)+ ("LGPL-2.1-only" 'license:lgpl2.1) ("LGPL-2.1+" 'license:lgpl2.1+)+ ("LGPL-2.1-or-later" 'license:lgpl2.1+) ("LGPL-3.0" 'license:lgpl3)+ ("LGPL-3.0-only" 'license:lgpl3) ("LGPL-3.0+" 'license:lgpl3+)+ ("LGPL-3.0-or-later" 'license:lgpl3+) ("MPL-1.0" 'license:mpl1.0) ("MPL-1.1" 'license:mpl1.1) ("MPL-2.0" 'license:mpl2.0)-- 2.32.0
From 65614c021ad33f4116d631a7e24a356d9236803b Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sat, 31 Jul 2021 14:44:11 +0200Subject: [PATCH 06/20] guix: Add ContentDB importer.
* guix/import/contentdb.scm: New file.* guix/scripts/import/contentdb.scm: New file.* tests/contentdb.scm: New file.* Makefile.am (MODULES, SCM_TESTS): Register them.* po/guix/POTFILES.in: Likewise.* doc/guix.texi (Invoking guix import): Document it.--- Makefile.am | 3 + doc/guix.texi | 32 +++ guix/import/minetest.scm | 456 +++++++++++++++++++++++++++++++ guix/scripts/import.scm | 3 +- guix/scripts/import/minetest.scm | 117 ++++++++ po/guix/POTFILES.in | 1 + tests/minetest.scm | 355 ++++++++++++++++++++++++ 7 files changed, 966 insertions(+), 1 deletion(-) create mode 100644 guix/import/minetest.scm create mode 100644 guix/scripts/import/minetest.scm create mode 100644 tests/minetest.scm
Toggle diff (1045 lines)diff --git a/Makefile.am b/Makefile.amindex f4439ce93b..6243583616 100644--- a/Makefile.am+++ b/Makefile.am@@ -262,6 +262,7 @@ MODULES = \ guix/import/json.scm \ guix/import/kde.scm \ guix/import/launchpad.scm \+ guix/import/minetest.scm \ guix/import/opam.scm \ guix/import/print.scm \ guix/import/pypi.scm \@@ -304,6 +305,7 @@ MODULES = \ guix/scripts/import/go.scm \ guix/scripts/import/hackage.scm \ guix/scripts/import/json.scm \+ guix/scripts/import/minetest.scm \ guix/scripts/import/opam.scm \ guix/scripts/import/pypi.scm \ guix/scripts/import/stackage.scm \@@ -470,6 +472,7 @@ SCM_TESTS = \ tests/import-utils.scm \ tests/inferior.scm \ tests/lint.scm \+ tests/minetest.scm \ tests/modules.scm \ tests/monads.scm \ tests/nar.scm \diff --git a/doc/guix.texi b/doc/guix.texiindex d44ecc2005..854e282b38 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -11314,6 +11314,38 @@ and generate package expressions for all those packages that are not yet in Guix. @end table +@item contentdb+@cindex minetest+@cindex ContentDB+Import metadata from @uref{https://content.minetest.net, ContentDB}.+Information is taken from the JSON-formatted metadata provided through+@uref{https://content.minetest.net/help/api/, ContentDB's API} and+includes most relevant information, including dependencies. There are+some caveats, however. The license information is often incomplete.+The commit hash is sometimes missing. The descriptions are in the+Markdown format, but Guix uses Texinfo instead. Texture packs and+subgames are unsupported.++The command below imports metadata for the Mesecons mod by Jeija:++@example+guix import minetest Jeija/mesecons+@end example++The author name can also be left out:++@example+guix import minetest mesecons+@end example++@table @code+@item --recursive+@itemx -r+Traverse the dependency graph of the given upstream package recursively+and generate package expressions for all those packages that are not yet+in Guix.+@end table+ @item cpan @cindex CPAN Import metadata from @uref{https://www.metacpan.org/, MetaCPAN}.diff --git a/guix/import/minetest.scm b/guix/import/minetest.scmnew file mode 100644index 0000000000..e1f8487b75--- /dev/null+++ b/guix/import/minetest.scm@@ -0,0 +1,456 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>+;;;+;;; 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 receive)+ #:use-module (ice-9 threads)+ #:use-module (ice-9 hash-table)+ #:use-module (srfi srfi-1)+ #:use-module (srfi srfi-2)+ #:use-module (srfi srfi-11)+ #:use-module (srfi srfi-26)+ #:use-module (guix utils)+ #:use-module (guix ui)+ #:use-module (guix i18n)+ #:use-module (guix memoization)+ #:use-module (guix serialization)+ #:use-module (guix import utils)+ #:use-module (guix import json)+ #:use-module ((gcrypt hash) #:select (open-sha256-port port-sha256))+ #:use-module (json)+ #:use-module (guix base32)+ #:use-module (guix git)+ #:use-module (guix store)+ #:export (%default-sort-key+ %contentdb-api+ json->package+ contentdb-fetch+ elaborate-contentdb-name+ minetest->guix-package+ minetest-recursive-import+ sort-packages))++;; 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)+ (warning (G_ "~a is ambigious, presuming ~a (other options include: ~a)~%")+ 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+be \"mod\", \"game\" or \"txp\", restricting thes search results to+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)))++;; XXX adapted from (guix scripts hash)+(define (file-hash file)+ "Compute the hash of FILE."+ (let-values (((port get-hash) (open-sha256-port)))+ (write-file file port)+ (force-output port)+ (get-hash)))++(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+ (file-hash+ (download-git-repository repository+ `(commit . ,commit)))))))+ (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))+ (description ,(delete-cr description))+ (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)))++;; 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))+ (filter-map+ (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+ (G_ "The implementation with the highest score will be choosen!~%")))+ ("downloads"+ (warning+ (G_ "The implementation that has been downloaded the most will be choosen!~%"))))+ (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))++(define* (%minetest->guix-package author/name #:key (sort %default-sort-key))+ "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+ (release-title release) ; version+ (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))+ (define* (minetest->guix-package* author/name #:key repo version)+ (minetest->guix-package author/name #:sort sort))+ (recursive-import author/name+ #:repo->guix-package minetest->guix-package*+ #:guix-name contentdb->package-name))diff --git a/guix/scripts/import.scm b/guix/scripts/import.scmindex f53d1ac1f4..b369a362d0 100644--- a/guix/scripts/import.scm+++ b/guix/scripts/import.scm@@ -77,7 +77,8 @@ rather than \\n." ;;; (define importers '("gnu" "pypi" "cpan" "hackage" "stackage" "egg" "elpa"- "gem" "go" "cran" "crate" "texlive" "json" "opam"))+ "gem" "go" "cran" "crate" "texlive" "json" "opam"+ "minetest")) (define (resolve-importer name) (let ((module (resolve-interfacediff --git a/guix/scripts/import/minetest.scm b/guix/scripts/import/minetest.scmnew file mode 100644index 0000000000..5f204d90fc--- /dev/null+++ b/guix/scripts/import/minetest.scm@@ -0,0 +1,117 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2014 David Thompson <davet@gnu.org>+;;; Copyright © 2018 Ricardo Wurmus <rekado@elephly.net>+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>+;;;+;;; 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 scripts import minetest)+ #:use-module (guix ui)+ #:use-module (guix utils)+ #:use-module (guix scripts)+ #:use-module (guix import minetest)+ #:use-module (guix import utils)+ #:use-module (guix scripts import)+ #:use-module (srfi srfi-1)+ #:use-module (srfi srfi-11)+ #:use-module (srfi srfi-37)+ #:use-module (ice-9 match)+ #:use-module (ice-9 format)+ #:export (guix-import-minetest))++ +;;;+;;; Command-line options.+;;;++(define %default-options+ `((sort . ,%default-sort-key)))++(define (show-help)+ (display (G_ "Usage: guix import minetest AUTHOR/NAME+Import and convert the Minetest mod NAME by AUTHOR from ContentDB.\n"))+ (display (G_ "+ -h, --help display this help and exit"))+ (display (G_ "+ -r, --recursive import packages recursively"))+ (display (G_ "+ -V, --version display version information and exit"))+ (display (G_ "+ --sort=KEY when choosing between multiple implementations,+ choose the one with the highest value for KEY+ (one of \"score\" (standard) or \"downloads\")"))+ (newline)+ (show-bug-report-information))++(define (verify-sort-order sort)+ "Verify SORT can be used to sort mods by."+ (unless (member sort '("score" "downloads" "reviews"))+ (leave (G_ "~a: not a valid key to sort by~%") sort))+ sort)++(define %options+ ;; Specification of the command-line options.+ (cons* (option '(#\h "help") #f #f+ (lambda args+ (show-help)+ (exit 0)))+ (option '(#\V "version") #f #f+ (lambda args+ (show-version-and-exit "guix import minetest")))+ (option '(#\r "recursive") #f #f+ (lambda (opt name arg result)+ (alist-cons 'recursive #t result)))+ (option '("sort") #t #f+ (lambda (opt name arg result)+ (alist-cons 'sort (verify-sort-order arg) result)))+ %standard-import-options))++ +;;;+;;; Entry point.+;;;++(define (guix-import-minetest . args)+ (define (parse-options)+ ;; Return the alist of option values.+ (args-fold* args %options+ (lambda (opt name arg result)+ (leave (G_ "~A: unrecognized option~%") name))+ (lambda (arg result)+ (alist-cons 'argument arg result))+ %default-options))++ (let* ((opts (parse-options))+ (args (filter-map (match-lambda+ (('argument . value)+ value)+ (_ #f))+ (reverse opts))))+ (match args+ ((name)+ (with-error-handling+ (let* ((sort (assoc-ref opts 'sort))+ (author/name (elaborate-contentdb-name name #:sort sort)))+ (if (assoc-ref opts 'recursive)+ ;; Recursive import+ (filter-map package->definition+ (minetest-recursive-import author/name #:sort sort))+ ;; Single import+ (minetest->guix-package author/name #:sort sort)))))+ (()+ (leave (G_ "too few arguments~%")))+ ((many ...)+ (leave (G_ "too many arguments~%"))))))diff --git a/po/guix/POTFILES.in b/po/guix/POTFILES.inindex a3bced1a8f..f25a7b4802 100644--- a/po/guix/POTFILES.in+++ b/po/guix/POTFILES.in@@ -60,6 +60,7 @@ guix/scripts/git.scm guix/scripts/git/authenticate.scm guix/scripts/hash.scm guix/scripts/import.scm+guix/scripts/import/contentdb.scm guix/scripts/import/cran.scm guix/scripts/import/elpa.scm guix/scripts/pull.scmdiff --git a/tests/minetest.scm b/tests/minetest.scmnew file mode 100644index 0000000000..6ae476fe5f--- /dev/null+++ b/tests/minetest.scm@@ -0,0 +1,355 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>+;;;+;;; 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 (test-minetest)+ #:use-module (guix memoization)+ #:use-module (guix import minetest)+ #:use-module (guix import utils)+ #:use-module (guix tests)+ #:use-module (json)+ #:use-module (ice-9 match)+ #:use-module (srfi srfi-1)+ #:use-module (srfi srfi-26)+ #:use-module (srfi srfi-34)+ #:use-module (srfi srfi-64))++ +;; Some procedures for populating a ‘fake’ ContentDB server.++(define* (make-package-sexp #:key+ (guix-name "minetest-foo")+ (home-page "https://example.org/foo")+ (repo "https://example.org/foo.git")+ (synopsis "synopsis")+ (guix-description "description")+ (guix-license+ '(list license:cc-by-sa4.0 license:lgpl3+))+ (inputs '())+ (upstream-name "Author/foo")+ #:allow-other-keys)+ `(package+ (name ,guix-name)+ ;; This is not a proper version number but ContentDB does not include+ ;; version numbers.+ (version "2021-07-25")+ (source+ (origin+ (method git-fetch)+ (uri (git-reference+ (url ,(and (not (eq? repo 'null)) repo))+ (commit #f)))+ (sha256+ (base32 #f))+ (file-name (git-file-name name version))))+ (build-system minetest-mod-build-system)+ ,@(maybe-propagated-inputs inputs)+ (home-page ,home-page)+ (synopsis ,synopsis)+ (description ,guix-description)+ (license ,guix-license)+ (properties+ ,(list 'quasiquote+ `((upstream-name . ,upstream-name))))))++(define* (make-package-json #:key+ (author "Author")+ (name "foo")+ (media-license "CC-BY-SA-4.0")+ (license "LGPL-3.0-or-later")+ (short-description "synopsis")+ (long-description "description")+ (repo "https://example.org/foo.git")+ (website "https://example.org/foo")+ (forums 321)+ (score 987.654)+ (downloads 123)+ (type "mod")+ #:allow-other-keys)+ `(("author" . ,author)+ ("content_warnings" . #())+ ("created_at" . "2018-05-23T19:58:07.422108")+ ("downloads" . ,downloads)+ ("forums" . ,forums)+ ("issue_tracker" . "https://example.org/foo/issues")+ ("license" . ,license)+ ("long_description" . ,long-description)+ ("maintainers" . #("maintainer"))+ ("media_license" . ,media-license)+ ("name" . ,name)+ ("provides" . #("stuff"))+ ("release" . 456)+ ("repo" . ,repo)+ ("score" . ,score)+ ("screenshots" . #())+ ("short_description" . ,short-description)+ ("state" . "APPROVED")+ ("tags" . #("some" "tags"))+ ("thumbnail" . null)+ ("title" . "The name")+ ("type" . ,type)+ ("url" . ,(string-append "https://content.minetest.net/packages/"+ author "/" name "/download/"))+ ("website" . ,website)))++(define* (make-releases-json #:key (commit #f) (title "") #:allow-other-keys)+ `#((("commit" . ,commit)+ ("downloads" . 469)+ ("id" . 8614)+ ("max_minetest_version" . null)+ ("min_minetest_version" . null)+ ("release_date" . "2021-07-25T01:10:23.207584")+ ("title" . "2021-07-25"))))++(define* (make-dependencies-json #:key (author "Author")+ (name "foo")+ (requirements '(("default" #f ())))+ #:allow-other-keys)+ `((,(string-append author "/" name)+ . ,(list->vector+ (map (match-lambda+ ((symbolic-name optional? implementations)+ `(("is_optional" . ,optional?)+ ("name" . ,symbolic-name)+ ("packages" . ,(list->vector implementations)))))+ requirements)))+ ("something/else" . #())))++(define* (make-packages-keys-json #:key (author "Author")+ (name "Name")+ (type "mod"))+ `(("author" . ,author)+ ("name" . ,name)+ ("type" . ,type)))++(define (call-with-packages thunk . argument-lists)+ ;; Don't reuse results from previous tests.+ (invalidate-memoization! contentdb-fetch)+ (invalidate-memoization! minetest->guix-package)+ (define (scm->json-port scm)+ (open-input-string (scm->json-string scm)))+ (define (handle-package url requested-author requested-name . rest)+ (define relevant-argument-list+ (any (lambda (argument-list)+ (apply (lambda* (#:key (author "Author") (name "foo")+ #:allow-other-keys)+ (and (equal? requested-author author)+ (equal? requested-name name)+ argument-list))+ argument-list))+ argument-lists))+ (when (not relevant-argument-list)+ (error "the package ~a/~a should be irrelevant, but ~a is fetched"+ requested-author requested-name url))+ (scm->json-port+ (apply (match rest+ (("") make-package-json)+ (("dependencies" "") make-dependencies-json)+ (("releases" "") make-releases-json)+ (_ (error "TODO ~a" rest)))+ relevant-argument-list)))+ (define (handle-mod-search sort)+ ;; Produce search results, sorted by SORT in descending order.+ (define arguments->key+ (match sort+ ("score" (lambda* (#:key (score 987.654) #:allow-other-keys)+ score))+ ("downloads" (lambda* (#:key (downloads 123) #:allow-other-keys)+ downloads))))+ (define argument-list->key (cut apply arguments->key <>))+ (define (greater x y)+ (> (argument-list->key x) (argument-list->key y)))+ (define sorted-argument-lists (sort-list argument-lists greater))+ (define* (arguments->json #:key (author "Author") (name "Foo") (type "mod")+ #:allow-other-keys)+ (and (string=? type "mod")+ `(("author" . ,author)+ ("name" . ,name)+ ("type" . ,type))))+ (define argument-list->json (cut apply arguments->json <>))+ (scm->json-port+ (list->vector (filter-map argument-list->json sorted-argument-lists))))+ (mock ((guix http-client) http-fetch+ (lambda* (url #:key headers)+ (unless (string-prefix? "mock://api/packages/" url)+ (error "the URL ~a should not be used" url))+ (define resource+ (substring url (string-length "mock://api/packages/")))+ (define components (string-split resource #\/))+ (match components+ ((author name . rest)+ (apply handle-package url author name rest))+ (((? (cut string-prefix? "?type=mod&q=" <>) query))+ (handle-mod-search+ (cond ((string-contains query "sort=score") "score")+ ((string-contains query "sort=downloads") "downloads")+ (#t (error "search query ~a has unknown sort key"+ query)))))+ (_+ (error "the URL ~a should have an author and name component"+ url)))))+ (parameterize ((%contentdb-api "mock://api/"))+ (thunk))))++(define* (minetest->guix-package* #:key (author "Author") (name "foo")+ (sort %default-sort-key)+ #:allow-other-keys)+ (minetest->guix-package (string-append author "/" name) #:sort sort))++(define (imported-package-sexp* primary-arguments . secondary-arguments)+ "Ask the importer to import a package specified by PRIMARY-ARGUMENTS,+during a dynamic where that package and the packages specified by+SECONDARY-ARGUMENTS are available on ContentDB."+ (apply call-with-packages+ (lambda ()+ ;; The memoization cache is reset by call-with-packages+ (apply minetest->guix-package* primary-arguments))+ primary-arguments+ secondary-arguments))++(define (imported-package-sexp . extra-arguments)+ "Ask the importer to import a package specified by EXTRA-ARGUMENTS,+during a dynamic extent where that package is available on ContentDB."+ (imported-package-sexp* extra-arguments))++(define-syntax-rule (test-package test-case . extra-arguments)+ (test-equal test-case+ (make-package-sexp . extra-arguments)+ (imported-package-sexp . extra-arguments)))++(define-syntax-rule (test-package* test-case primary-arguments extra-arguments+ ...)+ (test-equal test-case+ (apply make-package-sexp primary-arguments)+ (imported-package-sexp* primary-arguments extra-arguments ...)))++(test-begin "minetest")++ +;; Package names+(test-package "minetest->guix-package")+(test-package "minetest->guix-package, _ → - in package name"+ #:name "foo_bar"+ #:guix-name "minetest-foo-bar"+ #:upstream-name "Author/foo_bar")++(test-equal "elaborate names, unambigious"+ "Jeija/mesecons"+ (call-with-packages+ (cut elaborate-contentdb-name "mesecons")+ '(#:name "mesecons" #:author "Jeija")+ '(#:name "something" #:author "else")))++(test-equal "elaborate name, ambigious (highest score)"+ "Jeija/mesecons"+ (call-with-packages+ ;; #:sort "score" is the default+ (cut elaborate-contentdb-name "mesecons")+ '(#:name "mesecons" #:author "Jeijc" #:score 777)+ '(#:name "mesecons" #:author "Jeijb" #:score 888)+ '(#:name "mesecons" #:author "Jeija" #:score 999)))+++(test-equal "elaborate name, ambigious (most downloads)"+ "Jeija/mesecons"+ (call-with-packages+ (cut elaborate-contentdb-name "mesecons" #:sort "downloads")+ '(#:name "mesecons" #:author "Jeijc" #:downloads 777)+ '(#:name "mesecons" #:author "Jeijb" #:downloads 888)+ '(#:name "mesecons" #:author "Jeija" #:downloads 999)))++ +;; Determining the home page+(test-package "minetest->guix-package, website is used as home page"+ #:home-page "web://site"+ #:website "web://site")+(test-package "minetest->guix-package, if absent, the forum is used"+ #:home-page '(minetest-topic 628)+ #:forums 628+ #:website 'null)+(test-package "minetest->guix-package, if absent, the git repo is used"+ #:home-page "https://github.com/minetest-mods/mesecons"+ #:forums 'null+ #:website 'null+ #:repo "https://github.com/minetest-mods/mesecons")+(test-package "minetest->guix-package, all home page information absent"+ #:home-page #f+ #:forums 'null+ #:website 'null+ #:repo 'null)++ ++;; Dependencies+(test-package* "minetest->guix-package, unambigious dependency"+ (list #:requirements '(("mesecons" #f+ ("Jeija/mesecons"+ "some-modpack/containing-mese")))+ #:inputs '("minetest-mesecons"))+ (list #:author "Jeija" #:name "mesecons")+ (list #:author "some-modpack" #:name "containing-mese" #:type "modpack"))++(test-package* "minetest->guix-package, ambigious dependency (highest score)"+ (list #:name "frobnicate"+ #:guix-name "minetest-frobnicate"+ #:upstream-name "Author/frobnicate"+ #:requirements '(("frob" #f+ ("Author/foo" "Author/bar")))+ ;; #:sort "score" is the default+ #:inputs '("minetest-bar"))+ (list #:author "Author" #:name "foo" #:score 0)+ (list #:author "Author" #:name "bar" #:score 9999))++(test-package* "minetest->guix-package, ambigious dependency (most downloads)"+ (list #:name "frobnicate"+ #:guix-name "minetest-frobnicate"+ #:upstream-name "Author/frobnicate"+ #:requirements '(("frob" #f+ ("Author/foo" "Author/bar")))+ #:inputs '("minetest-bar")+ #:sort "downloads")+ (list #:author "Author" #:name "foo" #:downloads 0)+ (list #:author "Author" #:name "bar" #:downloads 9999))++(test-package "minetest->guix-package, optional dependency"+ #:requirements '(("mesecons" #t+ ("Jeija/mesecons"+ "some-modpack/containing-mese")))+ #:inputs '())++ +;; License+(test-package "minetest->guix-package, identical licenses"+ #:guix-license 'license:lgpl3++ #:license "LGPL-3.0-or-later"+ #:media-license "LGPL-3.0-or-later")++;; Sorting+(let* ((make-package+ (lambda arguments+ (json->package (apply make-package-json arguments))))+ (x (make-package #:score 0))+ (y (make-package #:score 1))+ (z (make-package #:score 2)))+ (test-equal "sort-packages, already sorted"+ (list z y x)+ (sort-packages (list z y x)))+ (test-equal "sort-packages, reverse"+ (list z y x)+ (sort-packages (list x y z))))++(test-end "minetest")-- 2.32.0
From eab75f7b436f6fd069262462841080bf692851d0 Mon Sep 17 00:00:00 2001From: Maxime Devos <maximedevos@telenet.be>Date: Sat, 31 Jul 2021 20:00:45 +0200Subject: [PATCH 07/20] gnu: Add minetest-mesecons.
* gnu/packages/minetest.scm (minet