gnu: Rename minetest to luanti.

* gnu/packages/luanti.scm: New file.
(luanti, luanti-server, luanti-topic, luanti-moreores, luanti-sound-api-core)
(luanti-basic-materials, luanti-coloredwood, luanti-ethereal)
(luanti-homedecor-modpack, luanti-mesecons, luanti-mineclone, luanti-mobs)
(luanti-mobs-animal, luanti-mobs-monster, luanti-pipeworks, luanti-technic)
(luanti-throwing, luanti-throwing-arrows, luanti-worldedit)
(luanti-unifieddyes, luanti-unified-inventory, luanti-advtrains)
(luanti-basic-trains, luanti-oneblock, luanti-wielded-light): New variables.
* gnu/packages/minetest.scm:
(minetest, minetest-server, minetest-topic, minetest-moreores)
(minetest-sound-api-core, minetest-basic-materials, minetest-coloredwood)
(minetest-ethereal, minetest-homedecor-modpack, minetest-mesecons)
(minetest-mineclone, minetest-mobs, minetest-mobs-animal)
(minetest-mobs-monster, minetest-pipeworks, minetest-technic)
(minetest-throwing, minetest-throwing-arrows, minetest-worldedit)
(minetest-unifieddyes, minetest-unified-inventory, minetest-advtrains)
(minetest-basic-trains, minetest-oneblock, minetest-wielded-light): Deprecate
in favor of the above.
(minetest-game): Move to…
* gnu/packages/luanti.scm (minetest-game): … here.
* gnu/local.mk (GNU_SYSTEM_MODULES): Register luanti.scm.
* guix/build-system/luanti.scm: New file.
(luanti-mod-build-system): New public variable.
* guix/build-system/minetest.scm (minetest-mod-build-system): Deprecate in
favor of luanti-mod-build-system.
* guix/build/luanti-build-system.scm: New file, renamed from…
* guix/build/minetest-build-system.scm: … this. Deprecate in favor of
luanti-build-system.
* guix/import/luanti.scm: New file, renamed from guix/import/minetest.scm.
(%contentdb-api): Switch to “https://content.luanti.org/api/”.
(luanti-package?, latest-luanti-release, luanti->guix-package)
(luanti-recursive-import, %luanti-updater): New public variables.
* guix/import/minetest.scm (minetest-package?, latest-minetest-release)
(minetest->guix-package, minetest-recursive-import, %minetest-updater):
Deprecate in favor of the luanti variants above.
* guix/scripts/import/luanti.scm: New file, renamed from
guix/scripts/import/minetest.scm.
(guix-import-luanti): New public variable.
* guix/scripts/import/minetest.scm (guix-import-minetest): Deprecate in favor
of guix-import-luanti.
* tests/minetest.scm: Rename to…
* tests/luanti.scm: … this.
* Makefile.am (MODULES, SCM_TESTS): Adjust accordingly.
* etc/teams.scm (games): Adjust accordingly.
* CODEOWNERS: Adjust accordingly.
This commit is contained in:
Liliana Marie Prikler 2025-06-29 15:20:47 +02:00
parent 464c3b6340
commit abbdfbb775
No known key found for this signature in database
GPG key ID: 442A84B8C70E2F87
16 changed files with 1954 additions and 1720 deletions

View file

@ -143,10 +143,10 @@ gnu/packages/firmware\.scm @guix/embedded
gnu/packages/emulators\.scm @guix/games
gnu/packages/games\.scm @guix/games
gnu/packages/game-development\.scm @guix/games
gnu/packages/minetest\.scm @guix/games
gnu/packages/luanti\.scm @guix/games
gnu/packages/esolangs\.scm @guix/games
gnu/packages/motti\.scm @guix/games
guix/build/minetest-build-system\.scm @guix/games
guix/build/luanti-build-system\.scm @guix/games
etc/teams/gnome @guix/gnome
gnu/packages/glib\.scm @guix/gnome

View file

@ -172,6 +172,7 @@ MODULES = \
guix/build-system/haskell.scm \
guix/build-system/julia.scm \
guix/build-system/linux-module.scm \
guix/build-system/luanti.scm \
guix/build-system/maven.scm \
guix/build-system/meson.scm \
guix/build-system/minetest.scm \
@ -238,6 +239,7 @@ MODULES = \
guix/build/gnu-build-system.scm \
guix/build/gnu-dist.scm \
guix/build/guile-build-system.scm \
guix/build/luanti-build-system.scm \
guix/build/maven-build-system.scm \
guix/build/minetest-build-system.scm \
guix/build/mix-build-system.scm \
@ -310,6 +312,7 @@ MODULES = \
guix/import/json.scm \
guix/import/kde.scm \
guix/import/launchpad.scm \
guix/import/luanti.scm \
guix/import/minetest.scm \
guix/import/nuget.scm \
guix/import/npm-binary.scm \
@ -366,6 +369,7 @@ MODULES = \
guix/scripts/import/hackage.scm \
guix/scripts/import/hexpm.scm \
guix/scripts/import/json.scm \
guix/scripts/import/luanti.scm \
guix/scripts/import/minetest.scm \
guix/scripts/import/npm-binary.scm \
guix/scripts/import/opam.scm \
@ -579,9 +583,9 @@ SCM_TESTS = \
tests/inferior.scm \
tests/ipfs.scm \
tests/lint.scm \
tests/luanti.scm \
tests/machine/hetzner.scm \
tests/machine/hetzner/http.scm \
tests/minetest.scm \
tests/modules.scm \
tests/monads.scm \
tests/nar.scm \

View file

@ -621,10 +621,10 @@ ecosystem."
#:scope (list "gnu/packages/emulators.scm"
"gnu/packages/games.scm"
"gnu/packages/game-development.scm"
"gnu/packages/minetest.scm"
"gnu/packages/luanti.scm"
"gnu/packages/esolangs.scm" ; granted, rather niche
"gnu/packages/motti.scm"
"guix/build/minetest-build-system.scm")))
"guix/build/luanti-build-system.scm")))
(define-team gnome
(team 'gnome

View file

@ -470,6 +470,7 @@ GNU_SYSTEM_MODULES = \
%D%/packages/loko.scm \
%D%/packages/lsof.scm \
%D%/packages/lua.scm \
%D%/packages/luanti.scm \
%D%/packages/lxde.scm \
%D%/packages/lxqt.scm \
%D%/packages/m4.scm \

857
gnu/packages/luanti.scm Normal file
View file

@ -0,0 +1,857 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2014, 2015, 2016 David Thompson <dthompson2@worcester.edu>
;;; Copyright © 2015 Andreas Enge <andreas@enge.fr>
;;; Copyright © 2018 Efraim Flashner <efraim@flashner.co.il>
;;; Copyright © 2015, 2019 Mark H Weaver <mhw@netris.org>
;;; Copyright © 2016, 2017, 2018, 2019 Kei Kebreau <kkebreau@posteo.net>
;;; Copyright © 2019 Marius Bakke <mbakke@fastmail.com>
;;; Copyright © 20192021 Tobias Geerinckx-Rice <me@tobias.gr>
;;; Copyright © 2021 Trevor Hass <thass@okstate.edu>
;;; Copyright © 2020, 2021, 2022, 2025 Liliana Marie Prikler <liliana.prikler@gmail.com>
;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
;;; Copyright © 2024 Jan Wielkiewicz <tona_kosmicznego_smiecia@interia.pl>
;;; 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 luanti)
#:use-module (gnu packages)
#:use-module (gnu packages audio)
#:use-module (gnu packages base)
#:use-module (gnu packages check)
#:use-module (gnu packages compression)
#:use-module (gnu packages curl)
#:use-module (gnu packages fontutils)
#:use-module (gnu packages gettext)
#:use-module (gnu packages gl)
#:use-module (gnu packages image)
#:use-module (gnu packages lua)
#:use-module (gnu packages multiprecision)
#:use-module (gnu packages ncurses)
#:use-module (gnu packages pkg-config)
#:use-module (gnu packages sdl)
#:use-module (gnu packages serialization)
#:use-module (gnu packages sqlite)
#:use-module (gnu packages xiph)
#:use-module (gnu packages xorg)
#:use-module (guix packages)
#:use-module (guix gexp)
#:use-module (guix git-download)
#:use-module (guix utils)
#:use-module (guix build-system cmake)
#:use-module (guix build-system copy)
#:use-module (guix build-system luanti)
#:use-module ((guix licenses) #:prefix license:))
(define-public luanti
(package
(name "luanti")
(version "5.12.0")
(source
(origin
(method git-fetch)
(uri (git-reference
(url "https://github.com/luanti-org/luanti")
(commit version)))
(file-name (git-file-name name version))
(sha256
(base32 "1l8kwy23p3gpk12nnhhq1lp4v0zj6kiygnmia043pdinmgzzd0xy"))
(modules '((guix build utils)
(srfi srfi-26)
(ice-9 ftw)))
;; Delete bundled libraries.
;; - Keep lib/sha256 because there's no good upstream, see:
;; https://github.com/openssl/openssl/blob/master/crypto/sha/sha512.c
;; "SHA512 low level APIs are deprecated for public use,
;; but still ok for internal use." Also asked MT devs on IRC for this.
;; - tiniergltf is intended for Luanti and diverged from upstream.
(snippet
'(let ((keep '("." ".." "sha256" "tiniergltf")))
(with-directory-excursion "lib"
(for-each delete-file-recursively
(scandir "." (negate (cut member <> keep)))))
;; IrrlichtMT includes
(delete-file-recursively "irr/include/KHR")
(delete-file-recursively "irr/src/vendor")
(substitute* "irr/src/COpenGLCommon.h"
(("\"vendor/gl.h\"") "<GL/gl.h>"))
;; Catch2
(substitute* "CMakeLists.txt"
(("add_subdirectory\\(lib/catch2\\)") "find_package(Catch2 3 REQUIRED)"))
(substitute* "src/catch.h"
(("catch_amalgamated.hpp") "catch2/catch_all.hpp"))
(substitute* "src/unittest/test_irr_rotation.cpp"
(("catch_amalgamated.hpp") "catch2/catch_all.hpp"))
(substitute* "src/unittest/test_irr_matrix4.cpp"
(("catch_amalgamated.hpp") "catch2/catch_all.hpp"))))))
(build-system cmake-build-system)
(arguments
(list
#:configure-flags
#~(list "-DENABLE_LTO=ON"
"-DENABLE_UPDATE_CHECKER=FALSE")
#:phases
#~(modify-phases %standard-phases
(delete 'check)
(add-after 'install 'check
(lambda* (#:key tests? #:allow-other-keys)
;; Thanks to our substitutions, the tests should also run
;; when invoked on the target outside of `guix build'.
(when tests?
(setenv "HOME" "/tmp")
(setenv "MINETEST_GAME_PATH"
(string-append (getcwd) "/../source/games"))
(invoke "../source/bin/luanti" "--run-unittests")
(invoke "../source/util/test_multiplayer.sh")))))))
(native-search-paths
(list (search-path-specification
(variable "MINETEST_GAME_PATH")
(files '("share/luanti/games")))
(search-path-specification
(variable "MINETEST_MOD_PATH")
(files '("share/luanti/mods")))))
(native-inputs (list catch2-3 pkg-config))
(inputs (list curl
freetype
gettext-minimal
gmp
jsoncpp
libjpeg-turbo
libpng
libogg
libvorbis
libxi
luajit
mesa
ncurses
openal
sdl2
sqlite
`(,zstd "lib")))
(outputs '("out" "debug"))
(synopsis "Voxel game engine")
(description
"Luanti is a voxel game engine that supports modding and game creation
using its Lua modding API. It allows playing a wide range of voxel-based
games, installing mods and texture packs. This package only provides the base
platform, users need to install games themselves (for example,
@code{luanti-game}), either through Guix, the built-in interface or other
sources.")
(home-page "https://www.luanti.org/")
(license license:lgpl2.1+)))
(define-public luanti-server
(package
(inherit luanti)
(name "luanti-server")
(arguments
(substitute-keyword-arguments (package-arguments luanti)
((#:configure-flags configure-flags)
#~(cons* "-DBUILD_CLIENT=FALSE"
"-DBUILD_SERVER=TRUE"
#$configure-flags))
((#:phases phases)
#~(modify-phases #$phases
(replace 'check
(lambda* (#:key tests? #:allow-other-keys)
(when tests?
(setenv "HOME" "/tmp")
(setenv "LUANTI_GAME_PATH"
(string-append (getcwd) "/../source/games"))
(invoke "../source/bin/luantiserver" "--run-unittests"))))))))
(inputs
(modify-inputs (package-inputs luanti)
(delete "libjpeg-turbo"
"libpng"
"libogg"
"libvorbis"
"libxxf86vm"
"mesa"
"openal")))
(synopsis "Infinite-world block sandbox game (server)")
(description
"Server for Luanti game engine and gaming platform. Allows hosting
Luanti games with multiplayer support. This package provides
@command{luantiserver} to run a Luanti server.")))
(define-public minetest-game
(let ((commit "0351c6691595c6eb88a1bea2383f6fae46a686ce")
(revision "1"))
(package
(name "luanti-game")
(version (git-version "0.0.0" revision commit))
(source
(origin
(method git-fetch)
(uri (git-reference
(url "https://github.com/luanti-org/minetest_game")
(commit commit)))
(file-name (git-file-name name version))
(sha256
(base32 "13l33ghnm1g3ka0ivxljzdga50x0iv0fzyd7pqm15ickfbkwbm0v"))))
(build-system copy-build-system)
(arguments
(list
#:install-plan #~'(("." "/share/luanti/games/minetest_game"))))
(synopsis "Ex-official game for Luanti game engine")
(description
"This package provides the Minetest Game - a game for the
Luanti game engine which used to be the official game for Luanti
(formerly Minetest). It is currently in maintenance mode and gets no
new features.")
(home-page "https://www.luanti.org/")
(license license:lgpl2.1+))))
;; This package is deprecated. "Minetest Game" is no longer the official game.
(define-public minetest-data
(deprecated-package "minetest-data" minetest-game))
(define-public (luanti-topic topic-id)
"Return an URL (as a string) pointing to the forum topic with
numeric identifier TOPIC-ID on the official Luanti forums."
(string-append "https://forum.luanti.net/viewtopic.php?t="
(number->string topic-id)))
(define-public luanti-moreores
(package
(name "luanti-moreores")
(version "2.1.0")
(source
(origin
(method git-fetch)
(uri (git-reference
(url "https://github.com/minetest-mods/moreores")
(commit (string-append "v" version))))
(sha256 (base32 "1chfqbc6bb27aacjc67j5l5wcdvmcsvk2rfmangipd7nwini3y34"))
(file-name (git-file-name name version))))
(build-system luanti-mod-build-system)
(home-page (luanti-topic 549))
(synopsis "Additional ore types, tools, swords, and rails for Luanti")
(description
"This Luanti mod adds new ore types to the game (mithril, silver) as well
as swords and tools made of different materials. It also adds copper rails.")
(license license:zlib)
(properties `((upstream-name . "Calinou/moreores")))))
(define-public luanti-sound-api-core
(package
(name "luanti-sound-api-core")
;; No tags, no releases. The author intended to let users use it as a
;; submodules for other projects.
;; https://github.com/mt-mods/basic_materials/issues/4
(version "2022-02-27")
(source
(origin
(method git-fetch)
(uri (git-reference
(url "https://github.com/mt-mods/sound_api_core")
(commit "6956e49e775f325116f8e0c643899c089c691e1e")))
(sha256
(base32 "1ys6g2skhkksa4cx9agxhsibj5js8z4y2q1ngis9ddr38p756pcy"))
(file-name (git-file-name name version))
(snippet
'(begin
(call-with-output-file "mod.conf"
(lambda (port)
(format port "\
name = sound_api_core")))))))
(build-system luanti-mod-build-system)
(propagated-inputs '())
(home-page "https://github.com/mt-mods/sound_api_core")
(synopsis "Core for game agnostic sounds")
(description
"This library can be used to get some specific sounds, whatever the game.")
(license license:expat)))
(define-public luanti-basic-materials
(package
(name "luanti-basic-materials")
;; Upstream uses dates as version numbers.
(version "2022-03-28")
(source
(origin
(method git-fetch)
(uri (git-reference
(url "https://github.com/mt-mods/basic_materials")
(commit "9d55f9916d20779ecbf93c7e95dae8adebd2079b")))
(sha256
(base32 "0nzx5mdw26mk2by14hxyvbqckgz8k67vlh2ch30skssvh4984bjw"))
(file-name (git-file-name name version))
(snippet
'(begin
(use-modules (guix build utils))
(substitute* "mod.conf"
(("optional_depends =")
"depends = sound_api_core
optional_depends ="))
(substitute* "nodes.lua"
(("basic_materials.modpath \\.\\. \"/sound_api_core/init.lua\"")
"minetest.get_modpath(\"sound_api_core\") .. \"/init.lua\""))))))
(build-system luanti-mod-build-system)
(propagated-inputs
;; basic_materials:silver_wire cannot be crafted without
;; moreores:silver_ingot.
(list luanti-moreores luanti-sound-api-core))
(home-page (luanti-topic 21000))
(synopsis "Some \"basic\" materials and items for other Luanti mods to use")
(description
"The Luanti 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 luanti-coloredwood
(package
(name "luanti-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 luanti-mod-build-system)
(propagated-inputs
(list luanti-unifieddyes))
(home-page (luanti-topic 2411))
(synopsis "Painted wood in Luanti")
(description
"This Luanti mod provides hundreds of colours of wood and fences to
Luanti, 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 luanti-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 "luanti-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 luanti-mod-build-system)
(home-page (luanti-topic 14638))
(synopsis "The Ethereal mod adds many new biomes to Luanti")
(description
"The Ethereal Luanti 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 luanti-homedecor-modpack
(package
(name "luanti-homedecor-modpack")
;; Upstream doesn't tag releases, so use the release title from
;; ContentDB as version.
(version "2022-05-18")
(source
(origin
(method git-fetch)
(uri (git-reference
(url "https://github.com/mt-mods/homedecor_modpack")
(commit "5ffdc26673169e05492141709fbb18e8fb6e5937")))
(sha256
(base32 "03pf254r3hnznklw7lf3q4rzqg0a1y4c9rjjhzssf1q7ai5pdrkn"))
(file-name (git-file-name name version))))
(build-system luanti-mod-build-system)
(propagated-inputs
(list luanti-basic-materials luanti-unifieddyes))
(home-page (luanti-topic 2041))
(synopsis "Home decor mod for Luanti")
(description
;; TRANSLATORS: homedecor is the name is the name of a Luanti mod
;; and should not be translated.
"The homedecor Luanti 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 luanti-mesecons
;; The release on ContentDB does not have its own version number.
(let ((commit "27c3c515b49af91c1dbc427f31a820722854eb24")
(revision "63"))
(package
(name "luanti-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 "1l0kwjj8ns8hv6z520g6ph5swknar336dbi5qr3dfsy18ydk1j92"))
(file-name (git-file-name name version))))
(build-system luanti-mod-build-system)
(home-page "https://mesecons.net")
(synopsis
"Digital circuitry for Luanti, including wires, buttons and lights")
(description
"Mesecons is a mod for Luanti 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.
(license (list license:lgpl3 license:cc-by-sa3.0))
(properties `((upstream-name . "Jeija/mesecons"))))))
(define-public luanti-mineclone
(package
(name "luanti-mineclone")
(version "0.80.1")
(source (origin
(method git-fetch)
(uri (git-reference
(url "https://git.minetest.land/MineClone2/MineClone2")
(commit version)))
(file-name (git-file-name name version))
(sha256
(base32
"0ndgzasjmj8397bb3y2aqalx9v72llwgvp9pv05mms3chpji2675"))))
(build-system copy-build-system)
(arguments
`(#:install-plan
'(("." "share/luanti/games/mineclone"))))
(synopsis "Minecraft clone based on Luanti engine")
(description
"MineClone is a Luanti subgame, that aims to recreate Minecraft as
closely as the engine allows.")
(home-page "https://content.luanti.net/packages/Wuzzy/mineclone2/")
(license license:gpl3+)))
(define-public luanti-mobs
(package
(name "luanti-mobs")
;; Upstream does not tag release, so use the ContentDB release
;; title instead.
(version "2021-12-12")
(source
(origin
(method git-fetch)
(uri (git-reference
(url "https://notabug.org/TenPlus1/mobs_redo")
(commit "6a4a02f3fbf1038c69e72aaafa52a1e7d6106da8")))
(sha256
(base32 "0vgv7jpm9v3dwq4l9jxdd5z14yq164w8kin1d05jfv3ck4hwlwvr"))
(file-name (git-file-name name version))))
(build-system luanti-mod-build-system)
(home-page (luanti-topic 9917))
(synopsis "Mob library for Luanti mods, for animals, monsters etc.")
(description
"This Luanti 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{luanti-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 luanti-mobs-animal
(package
(name "luanti-mobs-animal")
;; Upstream does not use version numbers, so use the release title
;; from ContentDB instead;
(version "2021-11-14")
(source
(origin
(method git-fetch)
(uri (git-reference
(url "https://notabug.org/TenPlus1/mobs_animal")
(commit "3e15456bce7779aa0dc09a8890f7b5180c1ac771")))
(sha256
(base32 "08686mj3jh8fsziqp878jpaj5267s4n6i86dr1gnxyxbsrjraqpn"))
(file-name (git-file-name name version))))
(build-system luanti-mod-build-system)
(propagated-inputs
(list luanti-mobs))
(home-page "https://notabug.org/TenPlus1/mobs_animal")
(synopsis "Add animals to Luanti")
(description
"This Luanti mod adds various animals to Luanti, 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 luanti-mobs-monster
(package
(name "luanti-mobs-monster")
;; Upstream does not use version numbers, so use the release title
;; from ContentDB instead;
(version "2022-12-10")
(source
(origin
(method git-fetch)
(uri (git-reference
(url "https://notabug.org/TenPlus1/mobs_monster")
(commit "1b197f9ae136179a764ef45824464b667ade52e6")))
(sha256
(base32 "15g8acrzvsiccxchfmgjhyf2lmkbrpdjqv3v7hmqz7xqypi8wm3h"))
(file-name (git-file-name name version))))
(build-system luanti-mod-build-system)
(propagated-inputs (list luanti-mobs))
(home-page "https://notabug.org/TenPlus1/mobs_monster")
(synopsis "Add monsters with Mobs Redo on luanti")
(description
"This Luanti mod adds many types of monsters to Luanti, that live on the
surface or deep underground.")
(license license:expat)
(properties `((upstream-name . "TenPlus1/mobs_monster")))))
(define-public luanti-pipeworks
(package
(name "luanti-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 luanti-mod-build-system)
(propagated-inputs
(list luanti-basic-materials))
(home-page (luanti-topic 2155))
(synopsis "Pipes, item-transport tubes and related devices for Luanti")
(description
"Pipeworks is a mod for Luanti 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 luanti-technic
(package
(name "luanti-technic")
;; Upstream doesn't keep version numbers, so use the release
;; date on ContentDB instead.
(version "2022-10-30")
(source
(origin
(method git-fetch)
(uri (git-reference
(url "https://github.com/minetest-mods/technic")
(commit "6a9dfec36f7265f9328fe378732417d9b57060b4")))
(sha256
(base32 "0ng1aklm02n2lbar345yf88g3alzvnh0m0s5rb2bcw2k5lib8468"))
(file-name (git-file-name name version))))
(build-system luanti-mod-build-system)
(propagated-inputs
(list luanti-pipeworks luanti-basic-materials))
(home-page (luanti-topic 2538))
(synopsis "Machinery and automation for Luanti")
(description
"This Luanti mod adds machinery and automation to Luanti.
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 luanti-throwing
;; The latest release on ContentDB is ahead of the latet
;; tagged commit.
(let ((commit "31f0cf5f868673dc82f24ddc432b45c9cd282d27")
(revision "0"))
(package
(name "luanti-throwing")
(version (git-version "1.1" revision commit))
(source
(origin
(method git-fetch)
(uri (git-reference
(url "https://github.com/minetest-mods/throwing")
(commit commit)))
(sha256
(base32 "1s5kkr6rxxv2dhbbjzv62gw1s617hnpjavw1v9fv11v3mgigdfjb"))
(file-name (git-file-name name version))))
(build-system luanti-mod-build-system)
(home-page (luanti-topic 16365))
(synopsis "API for throwing things in Luanti")
(description
"This Luanti 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{luanti-throwing-arrows} does.")
(license license:mpl2.0)
(properties `((upstream-name . "Palige/throwing"))))))
(define-public luanti-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 Luanti 5.4.0-dev.
(let ((commit "059cc897af0aebfbd2c54ac5588f2b842f44f159")
(revision "0"))
(package
(name "luanti-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 luanti-mod-build-system)
(propagated-inputs
(list luanti-throwing))
(home-page (luanti-topic 16365))
(synopsis "Arrows and bows for Luanti")
(description
;; TRANSLATORS: "throwing" is the name of a Luanti mod and should
;; not be translated.
"This mod adds arrows and bows to Luanti. It is a compatible
replacement for the throwing mod by PilzAdam that uses the throwing API.")
(license license:mpl2.0))))
(define-public luanti-worldedit
(package
(name "luanti-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 luanti-mod-build-system)
(home-page (luanti-topic 572))
(synopsis "In-game world editor for Luanti")
(description
"WorldEdit is a mod for Luanti. 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 luanti-unifieddyes
(package
(name "luanti-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 luanti-mod-build-system)
(propagated-inputs
(list luanti-basic-materials))
(home-page (luanti-topic 2178))
(synopsis
"Unified Dyes expands the standard dye set of Luanti to up to 256 colours")
(description "The purpose of this mod originally was to supply a complete
set of colours for Luanti mod authors to use for colourised nodes or
reference in recipes. Since the advent of the default dyes mod in the standard
Luanti 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 luanti-unified-inventory
(package
(name "luanti-unified-inventory")
;; Upstream doesn't keep version numbers, so use the release title
;; on ContentDB instead.
(version "2021-12-26")
(source
(origin
(method git-fetch)
(uri (git-reference
(url "https://github.com/minetest-mods/unified_inventory")
(commit "d6688872c84417d2f61d6f5e607aea39d78920aa")))
(sha256
(base32 "1rlw96s2yyxdbz0h9byayyx9nsbqdr4ric91w0k3dkjr71aj8a3b"))
(file-name (git-file-name name version))))
(build-system luanti-mod-build-system)
(home-page (luanti-topic 12767))
(synopsis "Replace the default inventory in Luanti and add a crafting guide")
(description
"The Unified Inventory Luanti 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")))))
(define-public luanti-advtrains
(package
(name "luanti-advtrains")
(version "2.4.1")
(source
(origin
(method git-fetch)
(uri (git-reference
(url "https://git.bananach.space/advtrains.git")
(commit (string-append "release-" version))))
(sha256
(base32 "1q2jj8181pjgsakl28xadv0z4sszq1lb5rpgj070wr0px6mp447p"))
(file-name (git-file-name name version))))
(build-system luanti-mod-build-system)
(home-page "https://advtrains.de/")
(synopsis "Adds good-looking, realistic trains with realistic rails")
(description
"This mod features realistic trains and various equipment for railways,
with a focus on automated train operation. This package contains no actual
trains, please use @code{luanti-basic-trains}.
Main features:
@itemize
@item
almost-realistic tracks with actual curves and switches;
@item
railway signals, controllable by various means;
@item
ATC: simple, command-like automatic train control;
@item
LuaATC: Powerful Lua-scripted automatic train operation (requires some
programming knowledge);
@item
an interlocking system, featuring track sections, routes and automatic
stopping before signals.
@end itemize")
(license (list license:cc-by-sa3.0 license:agpl3+))
(properties `((upstream-name . "orwell/advtrains")))))
(define-public luanti-basic-trains
(package
(name "luanti-basic-trains")
(version "1.0.1")
(source
(origin
(method git-fetch)
(uri (git-reference
(url "http://git.bananach.space/basic_trains.git/")
(commit
"d44c410f7c2a7202ee68b66fc50febae89e0c5dc")))
(sha256
(base32
"0vvzndj48kgdz2bfgivfm217sbmc2lmxpp2mispcy7byn4i26prx"))
(file-name (git-file-name name version))))
(build-system luanti-mod-build-system)
(propagated-inputs
(list luanti-advtrains))
(home-page
"http://advtrains.de/wiki/doku.php?id=usage:trains:basic_trains")
(synopsis "Collection of basic trains for the Advanced Trains mod")
(description
"This modpack contains the trains which were the ``default'' trains in
advtrains up to version 2.2.1.")
(license (list license:cc-by-sa3.0 license:agpl3+))
(properties `((upstream-name . "orwell/basic_trains")))))
(define-public luanti-oneblock
(package
(name "luanti-oneblock")
(version "2022-09-01")
(source (origin
(method git-fetch)
(uri (git-reference
(url "https://github.com/NO411/oneblock")
(commit "3582c825137e61b3d2ae3d60b8b9746acd6dfe3d")))
(sha256
(base32
"1pkdrj99qqwmz7c86w2mh081ynyxhiwv2rl01xjm1wfpazx5zhdg"))
(file-name (git-file-name name version))))
(build-system luanti-mod-build-system)
(home-page "https://github.com/NO411/oneblock")
(synopsis "Build your island in the sky with random items!")
(description
"This package provides an extension of the Luanti game that lets you
build your island in the sky. Every 30 seconds you will receive a random
block or item from the oneblock to expand the island!")
(license license:gpl3+)
(properties `((upstream-name . "NO11/oneblock")))))
(define-public luanti-wielded-light
(package
(name "luanti-wielded-light")
(version "2022-06-24")
(source (origin
(method git-fetch)
(uri (git-reference
(url "https://github.com/minetest-mods/wielded_light")
(commit "b5236562af9772dff8522fe2bda5b5f738e81b88")))
(sha256
(base32
"0m5rf8wkc9iq04xppjfva9d83qmhlnx8fibdbi2d3pkwwl6p2y5c"))
(file-name (git-file-name name version))))
(build-system luanti-mod-build-system)
(home-page (luanti-topic 19378))
(synopsis "Adds shining for wielded and dropped items")
(description
"With this Luanti extension, all bright nodes lighten the player
environment if wielded.")
(license license:gpl3+)
(properties `((upstream-name . "bell07/wielded_light")))))

View file

@ -24,834 +24,79 @@
;;;
;;; 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 (gnu packages)
#:use-module (gnu packages audio)
#:use-module (gnu packages base)
#:use-module (gnu packages check)
#:use-module (gnu packages compression)
#:use-module (gnu packages curl)
#:use-module (gnu packages fontutils)
#:use-module (gnu packages gettext)
#:use-module (gnu packages gl)
#:use-module (gnu packages image)
#:use-module (gnu packages lua)
#:use-module (gnu packages multiprecision)
#:use-module (gnu packages ncurses)
#:use-module (gnu packages pkg-config)
#:use-module (gnu packages sdl)
#:use-module (gnu packages serialization)
#:use-module (gnu packages sqlite)
#:use-module (gnu packages xiph)
#:use-module (gnu packages xorg)
#:use-module (guix packages)
#:use-module (guix gexp)
#:use-module (guix git-download)
#:use-module (guix utils)
#:use-module (guix build-system cmake)
#:use-module (guix build-system copy)
#:use-module (guix build-system minetest)
#:use-module ((guix licenses) #:prefix license:))
#:use-module (gnu packages luanti))
(define-public minetest
(package
(name "minetest")
(version "5.12.0")
(source
(origin
(method git-fetch)
(uri (git-reference
(url "https://github.com/luanti-org/luanti")
(commit version)))
(file-name (git-file-name name version))
(sha256
(base32 "1l8kwy23p3gpk12nnhhq1lp4v0zj6kiygnmia043pdinmgzzd0xy"))
(modules '((guix build utils)
(srfi srfi-26)
(ice-9 ftw)))
;; Delete bundled libraries.
;; - Keep lib/sha256 because there's no good upstream, see:
;; https://github.com/openssl/openssl/blob/master/crypto/sha/sha512.c
;; "SHA512 low level APIs are deprecated for public use,
;; but still ok for internal use." Also asked MT devs on IRC for this.
;; - tiniergltf is intended for Minetest and diverged from upstream.
(snippet
'(let ((keep '("." ".." "sha256" "tiniergltf")))
(with-directory-excursion "lib"
(for-each delete-file-recursively
(scandir "." (negate (cut member <> keep)))))
;; IrrlichtMT includes
(delete-file-recursively "irr/include/KHR")
(delete-file-recursively "irr/src/vendor")
(substitute* "irr/src/COpenGLCommon.h"
(("\"vendor/gl.h\"") "<GL/gl.h>"))
;; Catch2
(substitute* "CMakeLists.txt"
(("add_subdirectory\\(lib/catch2\\)") "find_package(Catch2 3 REQUIRED)"))
(substitute* "src/catch.h"
(("catch_amalgamated.hpp") "catch2/catch_all.hpp"))
(substitute* "src/unittest/test_irr_rotation.cpp"
(("catch_amalgamated.hpp") "catch2/catch_all.hpp"))
(substitute* "src/unittest/test_irr_matrix4.cpp"
(("catch_amalgamated.hpp") "catch2/catch_all.hpp"))))))
(build-system cmake-build-system)
(arguments
(list
#:configure-flags
#~(list "-DENABLE_LTO=ON"
"-DENABLE_UPDATE_CHECKER=FALSE")
#:phases
#~(modify-phases %standard-phases
(delete 'check)
(add-after 'install 'check
(lambda* (#:key tests? #:allow-other-keys)
;; Thanks to our substitutions, the tests should also run
;; when invoked on the target outside of `guix build'.
(when tests?
(setenv "HOME" "/tmp")
(setenv "MINETEST_GAME_PATH"
(string-append (getcwd) "/../source/games"))
(invoke "../source/bin/luanti" "--run-unittests")
(invoke "../source/util/test_multiplayer.sh")))))))
(native-search-paths
(list (search-path-specification
(variable "MINETEST_GAME_PATH")
(files '("share/minetest/games")))
(search-path-specification
(variable "MINETEST_MOD_PATH")
(files '("share/minetest/mods")))))
(native-inputs (list catch2-3 pkg-config))
(inputs (list curl
freetype
gettext-minimal
gmp
jsoncpp
libjpeg-turbo
libpng
libogg
libvorbis
libxi
luajit
mesa
ncurses
openal
sdl2
sqlite
`(,zstd "lib")))
(outputs '("out" "debug"))
(synopsis "Voxel game engine")
(description
"Luanti is a voxel game engine that supports modding and game creation
using its Lua modding API. It allows playing a wide range of voxel-based
games, installing mods and texture packs. This package only provides the base
platform, users need to install games themselves (for example,
@code{minetest-game}), either through Guix, the built-in interface or other
sources.")
(home-page "https://www.luanti.org/")
(license license:lgpl2.1+)))
(deprecated-package "minetest" luanti))
(define-public minetest-server
(package
(inherit minetest)
(name "minetest-server")
(arguments
(substitute-keyword-arguments (package-arguments minetest)
((#:configure-flags configure-flags)
#~(cons* "-DBUILD_CLIENT=FALSE"
"-DBUILD_SERVER=TRUE"
#$configure-flags))
((#:phases phases)
#~(modify-phases #$phases
(replace 'check
(lambda* (#:key tests? #:allow-other-keys)
(when tests?
(setenv "HOME" "/tmp")
(setenv "MINETEST_GAME_PATH"
(string-append (getcwd) "/../source/games"))
(invoke "../source/bin/luantiserver" "--run-unittests"))))))))
(inputs
(modify-inputs (package-inputs minetest)
(delete "libjpeg-turbo"
"libpng"
"libogg"
"libvorbis"
"libxxf86vm"
"mesa"
"openal")))
(synopsis "Infinite-world block sandbox game (server)")
(description
"Server for Luanti game engine and gaming platform. Allows hosting
Luanti games with multiplayer support. This package provides
@command{luantiserver} to run a Luanti server.")))
(define-public minetest-game
(let ((commit "0351c6691595c6eb88a1bea2383f6fae46a686ce")
(revision "1"))
(package
(name "minetest-game")
(version (git-version "0.0.0" revision commit))
(source
(origin
(method git-fetch)
(uri (git-reference
(url "https://github.com/luanti-org/minetest_game")
(commit commit)))
(file-name (git-file-name name version))
(sha256
(base32 "13l33ghnm1g3ka0ivxljzdga50x0iv0fzyd7pqm15ickfbkwbm0v"))))
(build-system copy-build-system)
(arguments
(list
#:install-plan #~'(("." "/share/minetest/games/minetest_game"))))
(synopsis "Ex-official game for Luanti game engine")
(description
"This package provides the Minetest Game - a game for the
Luanti game engine which used to be the official game for Luanti
(formerly Minetest). It is currently in maintenance mode and gets no
new features.")
(home-page "https://www.luanti.org/")
(license license:lgpl2.1+))))
;; This package is deprecated. "Minetest Game" is no longer the official game.
(define-public minetest-data
(deprecated-package "minetest-data" minetest-game))
(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)))
(deprecated-package "minetest-server" luanti-server))
(define-public minetest-moreores
(package
(name "minetest-moreores")
(version "2.1.0")
(source
(origin
(method git-fetch)
(uri (git-reference
(url "https://github.com/minetest-mods/moreores")
(commit (string-append "v" version))))
(sha256 (base32 "1chfqbc6bb27aacjc67j5l5wcdvmcsvk2rfmangipd7nwini3y34"))
(file-name (git-file-name name version))))
(build-system minetest-mod-build-system)
(home-page (minetest-topic 549))
(synopsis "Additional ore types, tools, swords, and rails for Minetest")
(description
"This Minetest mod adds new ore types to the game (mithril, silver) as well
as swords and tools made of different materials. It also adds copper rails.")
(license license:zlib)
(properties `((upstream-name . "Calinou/moreores")))))
(deprecated-package "minetest-moreores" luanti-moreores))
(define-public minetest-sound-api-core
(package
(name "minetest-sound-api-core")
;; No tags, no releases. The author intended to let users use it as a
;; submodules for other projects.
;; https://github.com/mt-mods/basic_materials/issues/4
(version "2022-02-27")
(source
(origin
(method git-fetch)
(uri (git-reference
(url "https://github.com/mt-mods/sound_api_core")
(commit "6956e49e775f325116f8e0c643899c089c691e1e")))
(sha256
(base32 "1ys6g2skhkksa4cx9agxhsibj5js8z4y2q1ngis9ddr38p756pcy"))
(file-name (git-file-name name version))
(snippet
'(begin
(call-with-output-file "mod.conf"
(lambda (port)
(format port "\
name = sound_api_core")))))))
(build-system minetest-mod-build-system)
(propagated-inputs '())
(home-page "https://github.com/mt-mods/sound_api_core")
(synopsis "Core for game agnostic sounds")
(description
"This library can be used to get some specific sounds, whatever the game.")
(license license:expat)))
(deprecated-package "minetest-sound-api-core" luanti-sound-api-core))
(define-public minetest-basic-materials
(package
(name "minetest-basic-materials")
;; Upstream uses dates as version numbers.
(version "2022-03-28")
(source
(origin
(method git-fetch)
(uri (git-reference
(url "https://github.com/mt-mods/basic_materials")
(commit "9d55f9916d20779ecbf93c7e95dae8adebd2079b")))
(sha256
(base32 "0nzx5mdw26mk2by14hxyvbqckgz8k67vlh2ch30skssvh4984bjw"))
(file-name (git-file-name name version))
(snippet
'(begin
(use-modules (guix build utils))
(substitute* "mod.conf"
(("optional_depends =")
"depends = sound_api_core
optional_depends ="))
(substitute* "nodes.lua"
(("basic_materials.modpath \\.\\. \"/sound_api_core/init.lua\"")
"minetest.get_modpath(\"sound_api_core\") .. \"/init.lua\""))))))
(build-system minetest-mod-build-system)
(propagated-inputs
;; basic_materials:silver_wire cannot be crafted without
;; moreores:silver_ingot.
(list minetest-moreores minetest-sound-api-core))
(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")))))
(deprecated-package "minetest-basic-materials" luanti-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
(list 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")))))
(deprecated-package "minetest-coloredwood" luanti-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"))))))
(deprecated-package "minetest-ethereal" luanti-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 "2022-05-18")
(source
(origin
(method git-fetch)
(uri (git-reference
(url "https://github.com/mt-mods/homedecor_modpack")
(commit "5ffdc26673169e05492141709fbb18e8fb6e5937")))
(sha256
(base32 "03pf254r3hnznklw7lf3q4rzqg0a1y4c9rjjhzssf1q7ai5pdrkn"))
(file-name (git-file-name name version))))
(build-system minetest-mod-build-system)
(propagated-inputs
(list minetest-basic-materials 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")))))
(deprecated-package "minetest-homedecor-modpack" luanti-homedecor-modpack))
(define-public minetest-mesecons
;; The release on ContentDB does not have its own version number.
(let ((commit "27c3c515b49af91c1dbc427f31a820722854eb24")
(revision "63"))
(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 "1l0kwjj8ns8hv6z520g6ph5swknar336dbi5qr3dfsy18ydk1j92"))
(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.
(license (list license:lgpl3 license:cc-by-sa3.0))
(properties `((upstream-name . "Jeija/mesecons"))))))
(deprecated-package "minetest-mesecons" luanti-mesecons))
(define-public minetest-mineclone
(package
(name "minetest-mineclone")
(version "0.80.1")
(source (origin
(method git-fetch)
(uri (git-reference
(url "https://git.minetest.land/MineClone2/MineClone2")
(commit version)))
(file-name (git-file-name name version))
(sha256
(base32
"0ndgzasjmj8397bb3y2aqalx9v72llwgvp9pv05mms3chpji2675"))))
(build-system copy-build-system)
(arguments
`(#:install-plan
'(("." "share/minetest/games/mineclone"))))
(synopsis "Minecraft clone based on Minetest engine")
(description
"MineClone is a Minetest subgame, that aims to recreate Minecraft as
closely as the engine allows.")
(home-page "https://content.minetest.net/packages/Wuzzy/mineclone2/")
(license license:gpl3+)))
(deprecated-package "minetest-mineclone" luanti-mineclone))
(define-public minetest-mobs
(package
(name "minetest-mobs")
;; Upstream does not tag release, so use the ContentDB release
;; title instead.
(version "2021-12-12")
(source
(origin
(method git-fetch)
(uri (git-reference
(url "https://notabug.org/TenPlus1/mobs_redo")
(commit "6a4a02f3fbf1038c69e72aaafa52a1e7d6106da8")))
(sha256
(base32 "0vgv7jpm9v3dwq4l9jxdd5z14yq164w8kin1d05jfv3ck4hwlwvr"))
(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")))))
(deprecated-package "minetest-mobs" luanti-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-11-14")
(source
(origin
(method git-fetch)
(uri (git-reference
(url "https://notabug.org/TenPlus1/mobs_animal")
(commit "3e15456bce7779aa0dc09a8890f7b5180c1ac771")))
(sha256
(base32 "08686mj3jh8fsziqp878jpaj5267s4n6i86dr1gnxyxbsrjraqpn"))
(file-name (git-file-name name version))))
(build-system minetest-mod-build-system)
(propagated-inputs
(list 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")))))
(deprecated-package "minetest-mobs-animal" luanti-mobs-animal))
(define-public minetest-mobs-monster
(package
(name "minetest-mobs-monster")
;; Upstream does not use version numbers, so use the release title
;; from ContentDB instead;
(version "2022-12-10")
(source
(origin
(method git-fetch)
(uri (git-reference
(url "https://notabug.org/TenPlus1/mobs_monster")
(commit "1b197f9ae136179a764ef45824464b667ade52e6")))
(sha256
(base32 "15g8acrzvsiccxchfmgjhyf2lmkbrpdjqv3v7hmqz7xqypi8wm3h"))
(file-name (git-file-name name version))))
(build-system minetest-mod-build-system)
(propagated-inputs (list minetest-mobs))
(home-page "https://notabug.org/TenPlus1/mobs_monster")
(synopsis "Add monsters with Mobs Redo on minetest")
(description
"This Minetest mod adds many types of monsters to Minetest, that live on the
surface or deep underground.")
(license license:expat)
(properties `((upstream-name . "TenPlus1/mobs_monster")))))
(deprecated-package "minetest-mobs-monster" luanti-mobs-monster))
(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
(list 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")))))
(deprecated-package "minetest-pipeworks" luanti-pipeworks))
(define-public minetest-technic
(package
(name "minetest-technic")
;; Upstream doesn't keep version numbers, so use the release
;; date on ContentDB instead.
(version "2022-10-30")
(source
(origin
(method git-fetch)
(uri (git-reference
(url "https://github.com/minetest-mods/technic")
(commit "6a9dfec36f7265f9328fe378732417d9b57060b4")))
(sha256
(base32 "0ng1aklm02n2lbar345yf88g3alzvnh0m0s5rb2bcw2k5lib8468"))
(file-name (git-file-name name version))))
(build-system minetest-mod-build-system)
(propagated-inputs
(list minetest-pipeworks 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")))))
(deprecated-package "minetest-technic" luanti-technic))
(define-public minetest-throwing
;; The latest release on ContentDB is ahead of the latet
;; tagged commit.
(let ((commit "31f0cf5f868673dc82f24ddc432b45c9cd282d27")
(revision "0"))
(package
(name "minetest-throwing")
(version (git-version "1.1" revision commit))
(source
(origin
(method git-fetch)
(uri (git-reference
(url "https://github.com/minetest-mods/throwing")
(commit commit)))
(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"))))))
(deprecated-package "minetest-throwing" luanti-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
(list 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))))
(deprecated-package "minetest-throwing-arrows" luanti-throwing-arrows))
(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")))))
(deprecated-package "minetest-worldedit" luanti-worldedit))
(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
(list 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")))))
(deprecated-package "minetest-unifieddyes" luanti-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-12-26")
(source
(origin
(method git-fetch)
(uri (git-reference
(url "https://github.com/minetest-mods/unified_inventory")
(commit "d6688872c84417d2f61d6f5e607aea39d78920aa")))
(sha256
(base32 "1rlw96s2yyxdbz0h9byayyx9nsbqdr4ric91w0k3dkjr71aj8a3b"))
(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")))))
(deprecated-package "minetest-unified-inventory" luanti-unified-inventory))
(define-public minetest-advtrains
(package
(name "minetest-advtrains")
(version "2.4.1")
(source
(origin
(method git-fetch)
(uri (git-reference
(url "https://git.bananach.space/advtrains.git")
(commit (string-append "release-" version))))
(sha256
(base32 "1q2jj8181pjgsakl28xadv0z4sszq1lb5rpgj070wr0px6mp447p"))
(file-name (git-file-name name version))))
(build-system minetest-mod-build-system)
(home-page "https://advtrains.de/")
(synopsis "Adds good-looking, realistic trains with realistic rails")
(description
"This mod features realistic trains and various equipment for railways,
with a focus on automated train operation. This package contains no actual
trains, please use @code{minetest-basic-trains}.
Main features:
@itemize
@item
almost-realistic tracks with actual curves and switches;
@item
railway signals, controllable by various means;
@item
ATC: simple, command-like automatic train control;
@item
LuaATC: Powerful Lua-scripted automatic train operation (requires some
programming knowledge);
@item
an interlocking system, featuring track sections, routes and automatic
stopping before signals.
@end itemize")
(license (list license:cc-by-sa3.0 license:agpl3+))
(properties `((upstream-name . "orwell/advtrains")))))
(deprecated-package "minetest-advtrains" luanti-advtrains))
(define-public minetest-basic-trains
(package
(name "minetest-basic-trains")
(version "1.0.1")
(source
(origin
(method git-fetch)
(uri (git-reference
(url "http://git.bananach.space/basic_trains.git/")
(commit
"d44c410f7c2a7202ee68b66fc50febae89e0c5dc")))
(sha256
(base32
"0vvzndj48kgdz2bfgivfm217sbmc2lmxpp2mispcy7byn4i26prx"))
(file-name (git-file-name name version))))
(build-system minetest-mod-build-system)
(propagated-inputs
(list minetest-advtrains))
(home-page
"http://advtrains.de/wiki/doku.php?id=usage:trains:basic_trains")
(synopsis "Collection of basic trains for the Advanced Trains mod")
(description
"This modpack contains the trains which were the ``default'' trains in
advtrains up to version 2.2.1.")
(license (list license:cc-by-sa3.0 license:agpl3+))
(properties `((upstream-name . "orwell/basic_trains")))))
(deprecated-package "minetest-basic-trains" luanti-basic-trains))
(define-public minetest-oneblock
(package
(name "minetest-oneblock")
(version "2022-09-01")
(source (origin
(method git-fetch)
(uri (git-reference
(url "https://github.com/NO411/oneblock")
(commit "3582c825137e61b3d2ae3d60b8b9746acd6dfe3d")))
(sha256
(base32
"1pkdrj99qqwmz7c86w2mh081ynyxhiwv2rl01xjm1wfpazx5zhdg"))
(file-name (git-file-name name version))))
(build-system minetest-mod-build-system)
(home-page "https://github.com/NO411/oneblock")
(synopsis "Build your island in the sky with random items!")
(description
"This package provides an extension of the Minetest game that lets you
build your island in the sky. Every 30 seconds you will receive a random
block or item from the oneblock to expand the island!")
(license license:gpl3+)
(properties `((upstream-name . "NO11/oneblock")))))
(deprecated-package "minetest-oneblock" luanti-oneblock))
(define-public minetest-wielded-light
(package
(name "minetest-wielded-light")
(version "2022-06-24")
(source (origin
(method git-fetch)
(uri (git-reference
(url "https://github.com/minetest-mods/wielded_light")
(commit "b5236562af9772dff8522fe2bda5b5f738e81b88")))
(sha256
(base32
"0m5rf8wkc9iq04xppjfva9d83qmhlnx8fibdbi2d3pkwwl6p2y5c"))
(file-name (git-file-name name version))))
(build-system minetest-mod-build-system)
(home-page (minetest-topic 19378))
(synopsis "Adds shining for wielded and dropped items")
(description
"With this Minetest extension, all bright nodes lighten the player
environment if wielded.")
(license license:gpl3+)
(properties `((upstream-name . "bell07/wielded_light")))))
(deprecated-package "minetest-wielded-light" luanti-wielded-light))

View file

@ -0,0 +1,104 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
;;; Copyright © 2025 Liliana Marie Prikler <liliana.prikler@gmail.com>
;;;
;;; 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 luanti)
#:use-module (guix build-system copy)
#:use-module (guix build-system gnu)
#:use-module (guix build-system)
#:use-module (guix utils)
#:export (luanti-mod-build-system))
;;
;; Build procedure for luanti 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-luanti)
(module-ref (resolve-interface '(gnu packages luanti)) 'luanti))
(define (default-luanti-game)
(module-ref (resolve-interface '(gnu packages luanti)) 'minetest-game))
(define (default-xvfb-run)
(module-ref (resolve-interface '(gnu packages xorg)) 'xvfb-run))
(define %luanti-build-system-modules
;; Build-side modules imported by default.
`((guix build luanti-build-system)
,@%copy-build-system-modules))
(define %default-modules
;; Modules in scope in the build-side environment.
'((guix build gnu-build-system)
(guix build luanti-build-system)
(guix build utils)))
(define (standard-luanti-packages)
"Return the list of (NAME PACKAGE OUTPUT) or (NAME PACKAGE) tuples of
standard packages used as implicit inputs of the Luanti build system."
`(("xvfb-run" ,(default-xvfb-run))
("optipng" ,(default-optipng))
("luanti" ,(default-luanti))
("luanti-game" ,(default-luanti-game))
,@(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
;; luanti-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 %luanti-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-luanti-packages))
native-inputs)))))
(define luanti-mod-build-system
(build-system
(name 'luanti-mod)
(description "The build system for Luanti mods")
(lower lower-mod)))
;;; luanti.scm ends here

View file

@ -1,5 +1,6 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
;;; Copyright © 2025 Liliana Marie Prikler <liliana.prikler@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
@ -17,87 +18,8 @@
;;; 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)
#:use-module (guix build-system luanti)
#:use-module (guix deprecation)
#: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 minetest)) 'minetest))
(define (default-minetest-game)
(module-ref (resolve-interface '(gnu packages minetest)) 'minetest-game))
(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))
("minetest-game" ,(default-minetest-game))
,@(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 here
(define-deprecated/alias minetest-mod-build-system luanti-mod-build-system)

View file

@ -0,0 +1,228 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
;;; Copyright © 2025 Liliana Marie Prikler <liliana.prikler@gmail.com>
;;;
;;; 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 luanti-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 (ice-9 exceptions)
#: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/luanti/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/luanti/luanti/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" "config.txt" "_config.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."
;; Luanti doesn't care about the directory names in "share/luanti/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 a 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 "luanti-" prefix is not informative, so strip it.
(file-name (if (string-prefix? "luanti-" file-name)
(substring file-name (string-length "luanti-"))
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 "-checkout")))
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")
;; Mods must have 'name' set in "mod.conf", so don't guess.
(read-mod-name "mod.conf"))
((file-exists? "modpack.conf")
;; While it is recommended to have 'name' set in 'modpack.conf',
;; it is optional, so guess a name if necessary.
(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* (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/luanti-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[[:space:]]*=[[:space:]]*([[:graph:]]+)[[:space:]]*$"))
(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 Luanti can find it.
(setenv "MINETEST_MOD_PATH"
(list->search-path-as-string
(cons
(string-append (assoc-ref outputs "out") "/share/luanti/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" "--" "luanti" "--info" "--world" "." "--go")
(format #t "Started Luanti with all mods loaded for testing~%")
;; Scan the output for error messages.
;; When the player has joined the server, stop luanti.
(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 ((has-errors? #f))
(match `(,(read-line port) ,has-errors?)
(((? error? line) _)
(display line)
(newline)
(loop #t))
(((? stop?) #f)
(kill pid SIGINT)
(close-port port)
(waitpid pid))
(((? eof-object?) #f)
(error "luanti didn't start"))
(((or (? stop?) (? eof-object?)) #t)
(error "luanti raised an error"))
(((? string? line) has-error?)
(display line)
(newline)
(loop has-error?))))))))
(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)))
;;; luanti-build-system.scm ends here

View file

@ -1,5 +1,6 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
;;; Copyright © 2025 Liliana Marie Prikler <liliana.prikler@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
@ -17,211 +18,10 @@
;;; 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 (ice-9 exceptions)
#: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))
#:use-module (guix build luanti-build-system)
#:use-module (guix deprecation)
#:re-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" "config.txt" "_config.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 a 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 "-checkout")))
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")
;; Mods must have 'name' set in "mod.conf", so don't guess.
(read-mod-name "mod.conf"))
((file-exists? "modpack.conf")
;; While it is recommended to have 'name' set in 'modpack.conf',
;; it is optional, so guess a name if necessary.
(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* (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[[:space:]]*=[[:space:]]*([[:graph:]]+)[[:space:]]*$"))
(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 ((has-errors? #f))
(match `(,(read-line port) ,has-errors?)
(((? error? line) _)
(display line)
(newline)
(loop #t))
(((? stop?) #f)
(kill pid SIGINT)
(close-port port)
(waitpid pid))
(((? eof-object?) #f)
(error "minetest didn't start"))
(((or (? stop?) (? eof-object?)) #t)
(error "minetest raised an error"))
(((? string? line) has-error?)
(display line)
(newline)
(loop has-error?))))))))
(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
(warn-about-deprecation '(guix build minetest-build-system) #f
#:replacement '(guix build luanti-build-system))

520
guix/import/luanti.scm Normal file
View file

@ -0,0 +1,520 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2021, 2022 Maxime Devos <maximedevos@telenet.be>
;;; Copyright © 2022 Hartmut Goebel <h.goebel@crazy-compilers.com>
;;; Copyright © 2025 Liliana Marie Prikler <liliana.prikler@gmail.com>
;;;
;;; 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 luanti)
#:use-module (ice-9 match)
#:use-module (ice-9 threads)
#:use-module (ice-9 hash-table)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-34)
#:use-module (guix diagnostics)
#:use-module ((guix packages) #:prefix package:)
#:use-module (guix upstream)
#:use-module (guix i18n)
#:use-module (guix memoization)
#:use-module (guix serialization)
#:use-module (guix import utils)
#:use-module (guix import json)
#:use-module (json)
#:use-module (guix base32)
#:use-module (guix git)
#:use-module ((guix git-download) #:prefix download:)
#:use-module (guix hash)
#:use-module (guix store)
#:export (%default-sort-key
%contentdb-api
json->package
contentdb-fetch
elaborate-contentdb-name
luanti-package?
latest-luanti-release
luanti->guix-package
luanti-recursive-import
sort-packages
%luanti-updater))
;; The ContentDB API is documented at
;; <https://content.luanti.net>.
(define %contentdb-api
(make-parameter "https://content.luanti.org/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
;;;
;; Luanti 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-luanti-version release-max-luanti-version string-or-false)
(min-luanti-version release-min-luanti-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. luanti-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 "luanti-" (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 ambiguous, 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 the 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)))
(define (make-luanti-sexp author/name version repository commit
inputs home-page synopsis
description media-license license)
"Return a S-expression for the luanti 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))
;; 'download-git-repository' already filtered out the '.git'
;; directory.
#:select? (const #true)
#:recursive? #true)))))
(file-name (git-file-name name version))))
(build-system luanti-mod-build-system)
,@(maybe-propagated-inputs (map contentdb->package-name inputs))
(home-page ,home-page)
(synopsis ,(delete-cr synopsis))
(description ,(beautify-description (delete-cr description)))
(license ,(if (eq? media-license license)
license
`(list ,media-license ,license)))
;; The Luanti 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 Luanti forum and the Git repository (if any)."
(define (topic->url-sexp topic)
;; 'luanti-topic' is a procedure defined in (gnu packages luanti)
`(luanti-topic ,topic))
(or (package-website package)
(and=> (package-forums package) topic->url-sexp)
(package-repository package)))
(define (release-version release)
"Guess the version of RELEASE from the release title."
(define title (release-title release))
(if (string-prefix? "v" title)
;; Remove "v" prefix from release titles like v1.0.1.
(substring title 1)
title))
(define (version-style version)
"Determine the kind of version number VERSION is -- a date, or a conventional
conventional version number."
(define dots? (->bool (string-index version #\.)))
(define hyphens? (->bool (string-index version #\-)))
(match (cons dots? hyphens?)
((#true . #false) 'regular) ; something like "0.1"
((#false . #false) 'regular) ; single component version number
((#true . #true) 'regular) ; result of 'git-version'
((#false . #true) 'date))) ; something like "2021-01-25"
;; If the default sort key is changed, make sure to modify 'show-help'
;; in (guix scripts import luanti) 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 luanti 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))
;; A mod can have multiple dependencies implemented by the same mod,
;; so remove duplicate mod names.
(define (filter-deduplicate-map f list)
(delete-duplicates (filter-map f list)))
(filter-deduplicate-map
(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 chosen!~%")))
("downloads"
(warning
(G_ "The implementation that has been downloaded the most will be chosen!~%"))))
(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* (%luanti->guix-package author/name #:key (sort %default-sort-key)
#:allow-other-keys)
"Fetch the metadata for AUTHOR/NAME from https://content.luanti.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-luanti-sexp author/name
(release-version release)
(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 luanti->guix-package
(memoize %luanti->guix-package))
(define* (luanti-recursive-import author/name #:key (sort %default-sort-key))
(define* (luanti->guix-package* author/name #:key version #:allow-other-keys)
(luanti->guix-package author/name #:sort sort))
(recursive-import author/name
#:repo->guix-package luanti->guix-package*
#:guix-name contentdb->package-name))
(define (luanti-package? pkg)
"Is PKG a Luanti mod on ContentDB?"
(and (string-prefix? "luanti-" (package:package-name pkg))
(assq-ref (package:package-properties pkg) 'upstream-name)))
(define* (latest-luanti-release pkg #:key version partial-version?)
"Return an <upstream-source> for the latest release of the package PKG,
or #false if the latest release couldn't be determined."
(define author/name
(assq-ref (package:package-properties pkg) 'upstream-name))
(define contentdb-package (contentdb-fetch author/name)) ; TODO warn if #f?
(define release (latest-release author/name))
(define source (package:package-source pkg))
(when version
(raise
(formatted-message
(G_ "~a updater doesn't support updating to a specific version, sorry.")
"luanti")))
(and contentdb-package release
(release-commit release) ; not always set
;; Only continue if both the old and new version number are both
;; dates or regular version numbers, as two different styles confuses
;; the logic for determining which version is newer.
(eq? (version-style (release-version release))
(version-style (package:package-version pkg)))
(upstream-source
(package (package:package-name pkg))
(version (release-version release))
(urls (download:git-reference
(url (package-repository contentdb-package))
(commit (release-commit release)))))))
(define %luanti-updater
(upstream-updater
(name 'luanti)
(description "Updater for Luanti packages on ContentDB")
(pred luanti-package?)
(import latest-luanti-release)))

View file

@ -1,6 +1,7 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2021, 2022 Maxime Devos <maximedevos@telenet.be>
;;; Copyright © 2022 Hartmut Goebel <h.goebel@crazy-compilers.com>
;;; Copyright © 2025 Liliana Marie Prikler <liliana.prikler@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
@ -18,502 +19,22 @@
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
(define-module (guix import minetest)
#:use-module (ice-9 match)
#:use-module (ice-9 threads)
#:use-module (ice-9 hash-table)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-34)
#:use-module (guix diagnostics)
#:use-module ((guix packages) #:prefix package:)
#:use-module (guix upstream)
#:use-module (guix i18n)
#:use-module (guix memoization)
#:use-module (guix serialization)
#:use-module (guix import utils)
#:use-module (guix import json)
#:use-module (json)
#:use-module (guix base32)
#:use-module (guix git)
#:use-module ((guix git-download) #:prefix download:)
#:use-module (guix hash)
#:use-module (guix store)
#:export (%default-sort-key
%contentdb-api
json->package
contentdb-fetch
elaborate-contentdb-name
minetest-package?
latest-minetest-release
minetest->guix-package
minetest-recursive-import
sort-packages
%minetest-updater))
#:use-module (guix deprecation)
#:use-module (guix import luanti)
#:re-export (%default-sort-key
%contentdb-api
json->package
contentdb-fetch
elaborate-contentdb-name
sort-packages)
#:export (minetest-package?
latest-minetest-release
minetest->guix-package
minetest-recursive-import
%minetest-updater))
;; 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 ambiguous, 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 the 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)))
(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))
;; 'download-git-repository' already filtered out the '.git'
;; directory.
#:select? (const #true)
#:recursive? #true)))))
(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 ,(beautify-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)))
(define (release-version release)
"Guess the version of RELEASE from the release title."
(define title (release-title release))
(if (string-prefix? "v" title)
;; Remove "v" prefix from release titles like v1.0.1.
(substring title 1)
title))
(define (version-style version)
"Determine the kind of version number VERSION is -- a date, or a conventional
conventional version number."
(define dots? (->bool (string-index version #\.)))
(define hyphens? (->bool (string-index version #\-)))
(match (cons dots? hyphens?)
((#true . #false) 'regular) ; something like "0.1"
((#false . #false) 'regular) ; single component version number
((#true . #true) 'regular) ; result of 'git-version'
((#false . #true) 'date))) ; something like "2021-01-25"
;; 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))
;; A mod can have multiple dependencies implemented by the same mod,
;; so remove duplicate mod names.
(define (filter-deduplicate-map f list)
(delete-duplicates (filter-map f list)))
(filter-deduplicate-map
(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 chosen!~%")))
("downloads"
(warning
(G_ "The implementation that has been downloaded the most will be chosen!~%"))))
(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)
#:allow-other-keys)
"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-version release)
(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 version #:allow-other-keys)
(minetest->guix-package author/name #:sort sort))
(recursive-import author/name
#:repo->guix-package minetest->guix-package*
#:guix-name contentdb->package-name))
(define (minetest-package? pkg)
"Is PKG a Minetest mod on ContentDB?"
(and (string-prefix? "minetest-" (package:package-name pkg))
(assq-ref (package:package-properties pkg) 'upstream-name)))
(define* (latest-minetest-release pkg #:key version partial-version?)
"Return an <upstream-source> for the latest release of the package PKG,
or #false if the latest release couldn't be determined."
(define author/name
(assq-ref (package:package-properties pkg) 'upstream-name))
(define contentdb-package (contentdb-fetch author/name)) ; TODO warn if #f?
(define release (latest-release author/name))
(define source (package:package-source pkg))
(when version
(raise
(formatted-message
(G_ "~a updater doesn't support updating to a specific version, sorry.")
"minetest")))
(and contentdb-package release
(release-commit release) ; not always set
;; Only continue if both the old and new version number are both
;; dates or regular version numbers, as two different styles confuses
;; the logic for determining which version is newer.
(eq? (version-style (release-version release))
(version-style (package:package-version pkg)))
(upstream-source
(package (package:package-name pkg))
(version (release-version release))
(urls (download:git-reference
(url (package-repository contentdb-package))
(commit (release-commit release)))))))
(define %minetest-updater
(upstream-updater
(name 'minetest)
(description "Updater for Minetest packages on ContentDB")
(pred minetest-package?)
(import latest-minetest-release)))
(define-deprecated/alias minetest-package? luanti-package?)
(define-deprecated/alias latest-minetest-release latest-luanti-release)
(define-deprecated/alias minetest->guix-package luanti->guix-package)
(define-deprecated/alias minetest-recursive-import luanti-recursive-import)
(define-deprecated/alias %minetest-updater %luanti-updater)

View file

@ -50,7 +50,8 @@
;; The list of all known importers. These are printed in order by SHOW-HELP, so
;; please keep this list alphabetically sorted!
(define importers '("composer" "cpan" "cran" "crate" "egg" "elm" "elpa"
"gem" "gnu" "go" "hackage" "hexpm" "json" "minetest"
"gem" "gnu" "go" "hackage" "hexpm" "json" "luanti"
"minetest" ; deprecated
"npm-binary" "nuget" "opam" "pypi" "stackage" "texlive"))
(define (resolve-importer name)

View file

@ -0,0 +1,118 @@
;;; 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>
;;; Copyright © 2025 Liliana Marie Prikler <liliana.prikler@gmail.com>
;;;
;;; 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 luanti)
#:use-module (guix ui)
#:use-module (guix utils)
#:use-module (guix scripts)
#:use-module (guix import luanti)
#: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-luanti))
;;;
;;; Command-line options.
;;;
(define %default-options
`((sort . ,%default-sort-key)))
(define (show-help)
(display (G_ "Usage: guix import luanti AUTHOR/NAME
Import and convert the Luanti 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 luanti")))
(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-luanti . 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
(luanti-recursive-import author/name #:sort sort))
;; Single import
(luanti->guix-package author/name #:sort sort)))))
(()
(leave (G_ "too few arguments~%")))
((many ...)
(leave (G_ "too many arguments~%"))))))

View file

@ -2,6 +2,7 @@
;;; Copyright © 2014 David Thompson <davet@gnu.org>
;;; Copyright © 2018 Ricardo Wurmus <rekado@elephly.net>
;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
;;; Copyright © 2025 Liliana Marie Prikler <liliana.prikler@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
@ -19,99 +20,11 @@
;;; 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)
#:use-module (guix scripts import luanti)
#:use-module (guix deprecation)
#: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~%"))))))
(warn-about-deprecation 'guix-import-minetest #f
#:replacement 'guix-import-luanti)
(apply guix-import-luanti args))

View file

@ -16,17 +16,17 @@
;;; 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 build-system minetest)
(define-module (test-luanti)
#:use-module (guix build-system luanti)
#:use-module (guix upstream)
#:use-module (guix memoization)
#:use-module (guix import minetest)
#:use-module (guix import luanti)
#:use-module (guix import utils)
#:use-module (guix tests)
#:use-module (guix packages)
#:use-module (guix git-download)
#:use-module ((gnu packages minetest)
#:select (minetest minetest-technic))
#:use-module ((gnu packages luanti)
#:select (luanti luanti-technic))
#:use-module ((gnu packages base)
#:select (hello))
#:use-module (json)
@ -40,7 +40,7 @@
;; Some procedures for populating a fake ContentDB server.
(define* (make-package-sexp #:key
(guix-name "minetest-foo")
(guix-name "luanti-foo")
;; This is not a proper version number but
;; ContentDB often does not include version
;; numbers.
@ -66,7 +66,7 @@
(sha256
(base32 #f))
(file-name (git-file-name name version))))
(build-system minetest-mod-build-system)
(build-system luanti-mod-build-system)
,@(maybe-propagated-inputs inputs)
(home-page ,home-page)
(synopsis ,synopsis)
@ -112,7 +112,7 @@
("thumbnail" . null)
("title" . "The name")
("type" . ,type)
("url" . ,(string-append "https://content.minetest.net/packages/"
("url" . ,(string-append "https://content.luanti.net/packages/"
author "/" name "/download/"))
("website" . ,website)))
@ -120,8 +120,8 @@
`#((("commit" . ,commit)
("downloads" . 469)
("id" . 8614)
("max_minetest_version" . null)
("min_minetest_version" . null)
("max_luanti_version" . null)
("min_luanti_version" . null)
("release_date" . "2021-07-25T01:10:23.207584")
("title" . ,title))))
@ -149,7 +149,7 @@
(define (call-with-packages thunk . argument-lists)
;; Don't reuse results from previous tests.
(invalidate-memoization! contentdb-fetch)
(invalidate-memoization! minetest->guix-package)
(invalidate-memoization! luanti->guix-package)
(define (scm->json-port scm)
(open-input-string (scm->json-string scm)))
(define (handle-package url requested-author requested-name . rest)
@ -215,10 +215,10 @@
(parameterize ((%contentdb-api "mock://api/"))
(thunk))))
(define* (minetest->guix-package* #:key (author "Author") (name "foo")
(define* (luanti->guix-package* #:key (author "Author") (name "foo")
(sort %default-sort-key)
#:allow-other-keys)
(minetest->guix-package (string-append author "/" name) #:sort sort))
(luanti->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,
@ -227,7 +227,7 @@ 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))
(apply luanti->guix-package* primary-arguments))
primary-arguments
secondary-arguments))
@ -247,14 +247,14 @@ during a dynamic extent where that package is available on ContentDB."
(apply make-package-sexp primary-arguments)
(imported-package-sexp* primary-arguments extra-arguments ...)))
(test-begin "minetest")
(test-begin "luanti")
;; Package names
(test-package "minetest->guix-package")
(test-package "minetest->guix-package, _ → - in package name"
(test-package "luanti->guix-package")
(test-package "luanti->guix-package, _ → - in package name"
#:name "foo_bar"
#:guix-name "minetest-foo-bar"
#:guix-name "luanti-foo-bar"
#:upstream-name "Author/foo_bar")
(test-equal "elaborate names, unambiguous"
@ -284,19 +284,19 @@ during a dynamic extent where that package is available on ContentDB."
;; Determining the home page
(test-package "minetest->guix-package, website is used as home page"
(test-package "luanti->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)
(test-package "luanti->guix-package, if absent, the forum is used"
#:home-page '(luanti-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"
(test-package "luanti->guix-package, if absent, the git repo is used"
#:home-page "https://github.com/luanti-mods/mesecons"
#:forums 'null
#:website 'null
#:repo "https://github.com/minetest-mods/mesecons")
(test-package "minetest->guix-package, all home page information absent"
#:repo "https://github.com/luanti-mods/mesecons")
(test-package "luanti->guix-package, all home page information absent"
#:home-page #f
#:forums 'null
#:website 'null
@ -316,55 +316,55 @@ during a dynamic extent where that package is available on ContentDB."
;; Dependencies
(test-package* "minetest->guix-package, unambiguous dependency"
(test-package* "luanti->guix-package, unambiguous dependency"
(list #:requirements '(("mesecons" #f
("Jeija/mesecons"
"some-modpack/containing-mese")))
#:inputs '("minetest-mesecons"))
#:inputs '("luanti-mesecons"))
(list #:author "Jeija" #:name "mesecons")
(list #:author "some-modpack" #:name "containing-mese" #:type "modpack"))
(test-package* "minetest->guix-package, ambiguous dependency (highest score)"
(test-package* "luanti->guix-package, ambiguous dependency (highest score)"
(list #:name "frobnicate"
#:guix-name "minetest-frobnicate"
#:guix-name "luanti-frobnicate"
#:upstream-name "Author/frobnicate"
#:requirements '(("frob" #f
("Author/foo" "Author/bar")))
;; #:sort "score" is the default
#:inputs '("minetest-bar"))
#:inputs '("luanti-bar"))
(list #:author "Author" #:name "foo" #:score 0)
(list #:author "Author" #:name "bar" #:score 9999))
(test-package* "minetest->guix-package, ambiguous dependency (most downloads)"
(test-package* "luanti->guix-package, ambiguous dependency (most downloads)"
(list #:name "frobnicate"
#:guix-name "minetest-frobnicate"
#:guix-name "luanti-frobnicate"
#:upstream-name "Author/frobnicate"
#:requirements '(("frob" #f
("Author/foo" "Author/bar")))
#:inputs '("minetest-bar")
#:inputs '("luanti-bar")
#:sort "downloads")
(list #:author "Author" #:name "foo" #:downloads 0)
(list #:author "Author" #:name "bar" #:downloads 9999))
(test-package "minetest->guix-package, optional dependency"
(test-package "luanti->guix-package, optional dependency"
#:requirements '(("mesecons" #t
("Jeija/mesecons"
"some-modpack/containing-mese")))
#:inputs '())
;; See e.g. 'orwell/basic_trains'
(test-package* "minetest->guix-package, multiple dependencies implemented by one mod"
(test-package* "luanti->guix-package, multiple dependencies implemented by one mod"
(list #:name "frobnicate"
#:guix-name "minetest-frobnicate"
#:guix-name "luanti-frobnicate"
#:upstream-name "Author/frobnicate"
#:requirements '(("frob" #f ("Author/frob"))
("frob_x" #f ("Author/frob")))
#:inputs '("minetest-frob"))
#:inputs '("luanti-frob"))
(list #:author "Author" #:name "frob"))
;; License
(test-package "minetest->guix-package, identical licenses"
(test-package "luanti->guix-package, identical licenses"
#:guix-license 'license:lgpl3+
#:license "LGPL-3.0-or-later"
#:media-license "LGPL-3.0-or-later")
@ -397,7 +397,7 @@ during a dynamic extent where that package is available on ContentDB."
(define* (expected-sexp #:key
(repo "https://example.org/foo.git")
(guix-name "minetest-foo")
(guix-name "luanti-foo")
(new-version "0.8")
(commit "44941798d222901b8f381b3210957d880b90a2fc")
#:allow-other-keys)
@ -410,7 +410,7 @@ during a dynamic extent where that package is available on ContentDB."
(commit "44941798d222901b8f381b3210957d880b90a2fc")
#:allow-other-keys)
(package
(name "minetest-foo")
(name "luanti-foo")
(version old-version)
(source
(if (eq? source 'auto)
@ -422,7 +422,7 @@ during a dynamic extent where that package is available on ContentDB."
(sha256 #f) ; not important for the following tests
(file-name (git-file-name name version)))
source))
(build-system minetest-mod-build-system)
(build-system luanti-mod-build-system)
(license #f)
(synopsis #f)
(description #f)
@ -434,7 +434,7 @@ during a dynamic extent where that package is available on ContentDB."
(expected-sexp . arguments)
(and=>
(call-with-packages
(cut latest-minetest-release (example-package . arguments))
(cut latest-luanti-release (example-package . arguments))
(list . arguments))
upstream-source->sexp)))
@ -442,7 +442,7 @@ during a dynamic extent where that package is available on ContentDB."
(test-equal test-case
#f
(call-with-packages
(cut latest-minetest-release (example-package . arguments))
(cut latest-luanti-release (example-package . arguments))
(list . arguments))))
(test-release "same version"
@ -474,25 +474,25 @@ during a dynamic extent where that package is available on ContentDB."
#:old-version "2014-11-07" #:title "0.8"
#:commit "c8855b991880897b2658dc90164e29c96e2aeb3a")
;; Don't let "guix refresh -t minetest" tell there are new versions
;; Don't let "guix refresh -t luanti" tell there are new versions
;; if Guix has insufficient information to actually perform the update,
;; when using --with-latest or "guix refresh -u".
(test-no-release "no commit information, no new release"
#:old-version "0.8" #:title "0.9.0" #:new-version "0.9.0"
#:commit #false)
(test-assert "minetest is not a minetest mod"
(not (minetest-package? minetest)))
(test-assert "GNU hello is not a minetest mod"
(not (minetest-package? hello)))
(test-assert "technic is a minetest mod"
(minetest-package? minetest-technic))
(test-assert "luanti is not a luanti mod"
(not (luanti-package? luanti)))
(test-assert "GNU hello is not a luanti mod"
(not (luanti-package? hello)))
(test-assert "technic is a luanti mod"
(luanti-package? luanti-technic))
(test-assert "upstream-name is required"
(not (minetest-package?
(package (inherit minetest-technic)
(not (luanti-package?
(package (inherit luanti-technic)
(properties '())))))
(test-end "minetest")
(test-end "luanti")
;;; Local Variables:
;;; eval: (put 'test-package* 'scheme-indent-function 1)