Skip to content

Instantly share code, notes, and snippets.

@con-f-use
Last active November 25, 2020 18:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save con-f-use/d7c569c8e3908ffa95e28dd44142f377 to your computer and use it in GitHub Desktop.
Save con-f-use/d7c569c8e3908ffa95e28dd44142f377 to your computer and use it in GitHub Desktop.
mcomix3 nix package (WIP)
{ stdenv
, fetchFromGitHub
, python3
, python3Packages
, wrapGAppsHook
, gobject-introspection
, gtk3
, gdk-pixbuf
# Recommended Dependencies:
, unrar
, p7zip
, lhasa
, mupdf
}:
python3Packages.buildPythonApplication rec {
pname = "mcomix3";
version = "20201123";
# fetch from github because no official release on pypi/github and no build system
src = fetchFromGitHub {
repo = "${pname}";
owner = "multiSnow";
rev = "cdcb27533dc7ee2ebf7b0a8ab5ba10e61c0b8ff8";
sha256 = "0q9xgl60ryf7qmy5vgzgfry4rvw5j9rb4d1ilxmpjmvm7dd3fm2k";
};
nativeBuildInputs = [ wrapGAppsHook ];
propagatedBuildInputs = (with python3Packages; [ pillow pygobject3 pycairo ])
++ [ gobject-introspection gtk3 gdk-pixbuf ]
++ [ unrar p7zip lhasa mupdf ];
format = "other";
strictDeps = false;
preInstall = ''
libdir=$out/lib/${python3.libPrefix}/site-packages
mkdir -p $out/share/{icons/hicolor,man/man1,applications,metainfo,thumbnailers}
mkdir -p $out/bin $libdir
'';
installPhase = ''
runHook preInstall
${python3.executable} installer.py --srcdir=mcomix --target=$libdir
mv $libdir/mcomix/mcomixstarter.py $out/bin/mcomix3
mv $libdir/mcomix/comicthumb.py $out/bin/comicthump
mv $libdir/mcomix/mcomix/* $libdir/mcomix
runHook postInstall
'';
postInstall = ''
rmdir $libdir/mcomix/mcomix
cp man/* $out/share/man/man1/
cp -r mime/icons/* $out/share/icons/hicolor/
cp mime/*.desktop $out/share/applications/
cp mime/*.appdata.xml $out/share/metainfo/
cp mime/*.thumbnailer $out/share/thumbnailers/
for folder in $out/share/icons/hicolor/*; do
mkdir $folder/{apps,mimetypes}
mv $folder/*.png $folder/mimetypes
cp $folder/mimetypes/application-x-cbt.png $folder/mimetypes/application-x-cbr.png
cp $folder/mimetypes/application-x-cbt.png $folder/mimetypes/application-x-cbz.png
done
'';
# The tests seem to be broken upstream
#checkInputs = [ python3Packages.pytest ];
#checkPhase = ''
# HOME=$TMPDIR pytest
#'';
doCheck = true;
checkPhase = ''
$out/bin/comicthump --help > /dev/null
$out/bin/mcomix3 --help > /dev/null
'';
meta = with stdenv.lib; {
description = "Comic book reader and image viewer; python3 fork of mcomix";
longDescription = "User-friendly, customizable image viewer, specifically designed to handle comic books and manga supporting a variety of container formats (including CBR, CBZ, CB7, CBT, LHA and PDF)";
homepage = "https://github.com/multiSnow/mcomix3";
changelog = "https://github.com/multiSnow/mcomix3/blob/gtk3/ChangeLog";
license = licenses.gpl2Plus;
maintainers = with maintainers; [ confus ];
platforms = platforms.all;
};
}
@AndersonTorres
Copy link

Some comments:

  • version: if there is no such a thing as a clearly numbered release, use the format YYYYMMDD - the date of the GIT commit you are using to build. There is no need of "version+git", we don't do the things that way here.

  • usually the nativeBuildInputs and buildInputs comes right after src. The installPhase (and all the phases) comes after them, preferably right before meta.

    It doesn't change the final result, but it improves readability. It is like following a recipe: first the ingredients (inputs) then the procedure (phases).

    (Obviously Nix is not a procedural imperative language, but you get the idea.)

  • Use a short meta.description.

    The meta.description usually appears in the search commands, and it is useful that this description is short and concise. Something like Comic book reader and image viewer; python3 fork of mcomix

    If you think a longer descriptuon can be useful, you can write a more elaborated meta.longDescription. In this case, remember to keep it within the magic 80-character limit of the file.

  • license = licenses.gpl2Plus;

About the installPhase, I have some more caveats, but I will explain them later. For now we need to check if the expression works as desired.

@con-f-use
Copy link
Author

con-f-use commented Nov 24, 2020

Thanks for your comments @AndersonTorres. A couple of points.

There is no need of "version+git", we don't do the things that way here.

Are you sure? I've seen it in a couple of packages on nixpkgs, also there is a clear version in the changelog of the project but there is no release yet, partly because it is a fork.

usually the nativeBuildInputs and buildInputs comes right after src
Use a short meta.description

I will do it that way in the final version. For now it's a work in progress, so I didn't care too much, yet. But it's good you mentioned it, I will be sure to check before I make a PR.

I realize the install phase is rather lengthy. I just didn't know how to make it any shorter and still retain things like the desktop file, the icons and schemas correctly.

Still on my ToDo:

  • Application icon
  • Tests and checks using pytest

@AndersonTorres
Copy link

Are you sure? I've seen it in a couple of packages on nixpkgs

Ah, those idiosyncrasies in Nixpkgs are a mess.
The "pname+version" attributes are in a certain sense arbitrary, in that Nix has no built-in "update this expression" method and they are more cosmetical than semantically relevant.

Indeed, right now we are rewriting a huge bunch of files to the new pname-version convention, and that "how do we name the unstable git releases" is a hot topic.

There is no enforcement on these things, but some things help readability. In this sense, just stick to the "date" format for git releases

also there is a clear version in the changelog of the project but there is no release yet, partly because it is a fork.

If it is a fork of other project, then it is another project entirely. And, specifically, this project has no release and no tag (https://github.com/multiSnow/mcomix3/releases) we can use to build a package.

I just didn't know how to make it any shorter and still retain things like the desktop file, the icons and schemas correctly.

There is no problem on it per se. The upstream package doesn't use the traditional "configure, build, install" cycle, then we the packagers are to fill the gaps.


But the install phase can be split in three: preInstall, installPhase and postInstall.

The preInstall is mainly used to create the $out/ directory tree of the program.
The postInstall installs additional stuff that isn't installed automatically; generally some special files like pictures, icons, additional documentation etc.

The installPhase then uses the following format:

   installPhase = ''
     runHook preInstall
     automatic-install-stuff  # not needed if this doesn't exist
     runHook postInstall
   '';

@con-f-use
Copy link
Author

con-f-use commented Nov 24, 2020

Well, thanks for your time and the info, really valuable.

Do you have an idea as to what might be causing my (.comix-wrapped:34530): GLib-GIO-ERROR **: 13:58:20.170: No GSettings schemas are installed on the system problem. I found https://nixos.org/manual/nixpkgs/stable/#ssec-gnome-common-issues (first faq item) but that doesn't change the error message for me. So I know a gsettings schema is missing, but not which one or how to install it as a dependency. There is a gconfschema file in the git repo but I don't know enough about the inner workings of gnome to make something of it @AndersonTorres @worldofpeace

@AndersonTorres
Copy link

These gconf things are a mystery to me. Maybe other Nix hackers can help you way better than me.

@AndersonTorres
Copy link

    mv $out/bin/mcomixstarter.py $out/bin/comix
    mv $out/bin/comicthumb.py $out/bin/comicthump

Here I would suggest symlinking. If by some reason a hypothetical program calls the original names, they would remain in the same place.

   python installer.py --srcdir=mcomix

How this command works exactly? Can you make it point directly to the $out?

@con-f-use
Copy link
Author

Here I would suggest symlinking.

But then the wrapping for python and wrapGAppsHook is not applied to them. Or, can I the executables that should be wrapped, somehow?

How this command works exactly? Can you make it point directly to the $out?

Sadly not, because it creates the wrong folder structure.

@con-f-use
Copy link
Author

con-f-use commented Nov 25, 2020

I asked about the missing gsettings schemas in the NixOS Discord, but so far no takers. Will try in discourse, too.

Edit: strictDeps = false; as suggested in discourse seems to have done the trick. I think we can go to finalizing and then I'll make the PR @AndersonTorres, do you have any guidelines and useful tips for me regarding my first PR to nixpkgs and the cleanup of this expression? I'm trying to get the tests to work, but they might be broken upstream.

@AndersonTorres
Copy link

AndersonTorres commented Nov 25, 2020

But then the wrapping for python and wrapGAppsHook is not applied to them. Or, can I the executables that should be wrapped, somehow?

Why not? The symlinks aren't wrapped at the end of day, like files themselves?

Or even, can't you create the symlinks at the fixupPhase?

Also, "/bin/comix" is not recommended here. After all the original comix program still exists, even if abandoned. If by chance someone revives it, the names would clash.

@con-f-use
Copy link
Author

Why not? The symlinks aren't wrapped at the end of day, like files themselves?

But the files need to be wrapped and as my understanding goes, the wrapGAppsHook only wraps files in $out/bin/ and doesn't follow symlinks to wrapp their targets. Or am I wrong?

@AndersonTorres
Copy link

AndersonTorres commented Nov 25, 2020

As far as I remember, the wrapper

  1. renames the file to be wrapped to something like .fancy-file-wrapped (the dot is to hide it from the listings);
  2. creates a new fancy-file, containing a shell script that creates an environment (usually by setting relevant environment variables and options) and a call to .fancy-file-wrapped

What I am saying here is to create a symlink to (say) mcomixstarter.py after the wrapping, with the name mcomix3 (and the same to comicthumb), instead of renaming them.

@AndersonTorres
Copy link

do you have any guidelines and useful tips for me regarding my first PR to nixpkgs and the cleanup of this expression?

Well, I think I already said the most of things about it, including the cosmetical ones.

I'm trying to get the tests to work, but they might be broken upstream.

Maybe it can be a bad interaction with nixpkgs. But I don't know...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment