Subject: [bug#34283] [PATCH] Add: mypaint

From: Maxim Cournoyer <[email-masked]>
Date: Tue, 05 Feb 2019 00:52:52 -0500

Hello Yoshinori!

Yoshinori Arai <[email-masked]> writes:

> Hello,
>
> I made mypaint package from git version.
> libmypaint-git, mypaint-brushes-git may be conflict with gimp package.

In Guix, we can have multiple versions of the software without changing
its name (it's one of the advantages of a functional package manager
:-).  In general, we package the latest release available from
upstream, unless there is a good justification to do otherwise.

Was there a reason to prefer the git snapshots over normal releases of
mypaint, libmypaint and mypaint-brushes in Guix? I see that the latest
release for mypaint-brushes was released only a couple days ago (2.0.1);
unless there is a reason, it would be preferable to use this tagged
released rather than some random commit.

In this case, since it seems the only dependent of mypaint is Gimp and
since Gimp requires a specific version, (its configure.ac [0] mentions
mypaint-brusesh 1.3.0, although Arch seems to work around it [1]), I'd
go with a public variable named mypaint-brushes-2 for the new
definition, leaving the current one in (gnu packages gimp) alone, thus
not impacting Gimp. The name field of both packages should be the same,
though, so that a user of mypaint-brushes can select the version as in:

guix package -i mypaint-brushes@2

I'd also put the new package definitions at the current location (gnu
packages gimp) so that their different versions live in the same Guile
module.

[0]  https://gitlab.gnome.org/garyskeete/gimp/blob/GIMP_2_10_4/configure.ac#L73
[1]  https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=mypaint-brushes-git

> From c9d5b440a6affccd0852e8686482b64aaef06bea Mon Sep 17 00:00:00 2001
> From: Yoshinori Arai <[email-masked]>
> Date: Sat, 2 Feb 2019 13:23:33 +0900
> Subject: [PATCH] Add: mypaint
>
> ---
>  gnu/packages/mypaint.scm | 132 +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 132 insertions(+)
>  create mode 100644 gnu/packages/mypaint.scm
>
> diff --git a/gnu/packages/mypaint.scm b/gnu/packages/mypaint.scm
> new file mode 100644
> index 000000000..8c6edeffb
> --- /dev/null
> +++ b/gnu/packages/mypaint.scm
> @@ -0,0 +1,132 @@
> +(define-module (gnu packages mypaint)
> +  #:use-module ((guix licenses) #:prefix license:)
> +  #:use-module (guix utils)
> +  #:use-module (guix packages)
> +  #:use-module (guix git-download)
> +  #:use-module (guix build-system gnu)
> +  #:use-module (guix build-system python)
> +  #:use-module (gnu packages pkg-config)
> +  #:use-module (gnu packages autotools)
> +  #:use-module (gnu packages gettext)
> +  #:use-module (gnu packages glib)
> +  #:use-module (gnu packages swig)
> +  #:use-module (gnu packages gtk)
> +  #:use-module (gnu packages python)
> +  #:use-module (gnu packages python-xyz)
> +  #:use-module (gnu packages ghostscript)
> +  #:use-module (gnu packages gimp)
> +  #:use-module (gnu packages gnome)
> +  #:use-module (gnu packages web)
> +  #:use-module (gnu packages python))
> +
> +(define-public libmypaint-git
> +  (let ((commit "0c07191409bd257084d4ea7576deb832aac8868b")
> +        (revision "1"))
> +    (package
> +      (name "libmypaint-git")
> +      (version (git-version "2.0.0" revision commit))
> +      (source (origin
> +                (method git-fetch)
> +                (uri (git-reference
> +                      (url "https://github.com/mypaint/libmypaint.git")
> +                      (commit commit)))
> +                (file-name (git-file-name name version))
> +                (sha256
> +                 (base32
> +                  "0x5yacdj4bfm298ijv64igv06yjr401g6giln5wrdpv0pixg8ig3"))))
> +      ;;Using glib-or-gtk-build-system, I got error as follows.
> +      ;;configure.ac:243: error: possibly undefined macro: AM_GLIB_GNU_GETTEXT
> +      ;;If this token and others are legitimate, please use m4_pattern_allow.
> +      ;;See the Autoconf documentation.

This error disappears when we leave "glib" as an input. Apparently glib
defines autoconf M4 macros; to be found by the ACLOCAL_PATH path
specification, it must be made an explicit input.

> +      (build-system gnu-build-system)
> +      (native-inputs
> +       `(("intltool" ,intltool)
> +         ("libtool" ,libtool)
> +         ("automake" ,automake)
> +         ("autoconf" ,autoconf)
> +         ("python-2" ,python-2)  ;need to generate headers in autogen.sh
> +         ("pkg-config" ,pkg-config)))
> +      ;; As needed by 'libmypaint.pc'.
> +      (propagated-inputs
> +       `(("json-c" ,json-c)
> +         ("gobject-introspection" ,gobject-introspection)))
> +      (inputs
> +       `(("glib" ,glib)))
> +      (home-page "http://mypaint.org/")
> +      (synopsis "Brush library")
> +      (description "This library used by MyPaint and other painting programs use it too")
> +      (license license:isc))))

This should reuse the original libmypaint package definition through
inheritance. You'll find examples in the sources of Guix. This way, you
wouldn't need to duplicate the common fields (home page, description,
synopsis, etc.).

> +(define-public mypaint-brushes-git
> +  (let ((commit "769ec941054725a195e77d8c55080344e2ab77e4")
> +        (revision "1"))
> +    (package
> +      (name "mypaint-brushes-git")
> +      (version (git-version "2.0.0" revision commit))
> +      (source (origin
> +                (method git-fetch)
> +                (uri (git-reference
> +                      (url "https://github.com/mypaint/mypaint-brushes.git")
> +                      (commit commit)))
> +                (file-name (git-file-name name version))
> +                (sha256
> +                 (base32
> +                  "0viilmad809qg12xw11p1yv0lwbgjfkcv82g2avwzdaa6wy783pf"))))
> +      (build-system gnu-build-system)
> +      (native-inputs
> +       `(("autoconf" ,autoconf)
> +         ("automake" ,automake)))
> +      (home-page "http://mypaint.org/")
> +      (synopsis "Brushes for MyPaint")
> +      (description "Brushes used by MyPaint and other software using libmypaint")
> +      (license license:cc0))))

Same for inheritance. If something is wrong with the original synopsis
or description, it should be fixed in the original package
definitions. This package could use the recently released (9 days ago)
2.0.1 tagged version instead of this commit.

> +(define-public mypaint-git
> +  (let ((commit "57685af8dbd65719d7874bc501094bade85d94e7")
> +        (revision "1"))
> +    (package
> +      (name "mypaint-git")
> +      (version (git-version "2.0.0" revision commit))
> +      (source (origin
> +                (method git-fetch)
> +                (uri (git-reference
> +                      (url "https://github.com/mypaint/mypaint.git")
> +                      (commit commit)))
> +                (file-name (git-file-name name version))
> +                (sha256
> +                 (base32
> +                  "14dmnwma8gsfd5hv3cvwkzyd3v392h4g1zp7i38295cf39yf61y6"))))
> +      (build-system python-build-system)
> +      (arguments
> +       `(#:python ,python-2

Why is this needed? It otherwise seem to support Python 3. Is there an
upstream issue on their tracker which we could link to in a comment?

> +         #:phases
> +         (modify-phases %standard-phases
> +           (add-after 'unpack 'fix-for-buildconfig-and-test
> +             (lambda _
> +               (for-each make-file-writable (find-files "." ".*"))
> +               ;; FATAL: Cannot create cache dir '/homeless-shelter
> +               (setenv "HOME" "/tmp")))
> +           (replace 'install
> +             (lambda _
> +               (invoke "python" "setup.py" "managed_install"
> +                       (string-append "--prefix=" (assoc-ref %outputs "out"))))))))
> +      (native-inputs
> +       `(("pkg-config" ,pkg-config)
> +         ("lcms" ,lcms)
> +         ("libmypaint" ,libmypaint-git)
> +         ("mypaint-brushes" ,mypaint-brushes-git)))

mypaint-brushes should be an input (otherwise it could be lost after
garbage collection, and is referred to by config.py).

> +      (inputs
> +       `(("python2-pygobject" ,python2-pygobject)

This should go in the propagated-inputs (any run-time Python dependencies usually
must go there).

> +         ("swig" ,swig)

This can go to the native-inputs, as it is only used at build time.

> +         ("gettext" ,gettext-minimal)
> +         ("python2-numpy" ,python2-numpy)
> +         ("python2-pycairo" ,python2-pycairo)))

The Python dependencies should become propagated-inputs.

> +      (propagated-inputs
> +       `(("gtk+" ,gtk+)
> +         ("librsvg" ,librsvg)
> +         ("gdk-pixbuf" ,gdk-pixbuf+svg)))

It'd be nicer to apply the extra 2 phases from the
glib-or-gtk-build-system. There are examples of hybrid build systems,
such as emacs-pdf-tools.

> +      (home-page "http://mypaint.org/")
> +      (synopsis "Simple drawing an id painting program")
> +      (description "MyPaint is a fast, free, and easy graphics app
> +for digital painters.  MyPaint works best with a graphics tablet.")

There's no need to say "free" here, since everything is and must be in
Guix. Maybe, [...] with a tablet or similar input device.

> +      (license license:gpl2+))))

I managed to make it run a couple of times, but then it started
complaining about icons (even though I was adding the hicolor-icon-theme
to my test environment). I also tried running fc-cache -vf, but in
vain. Any ideas?

Thank you!

Maxim